@mcp-b/embedded-agent 1.2.5-beta.1 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +212 -43
- package/dist/jsx.d.ts +45 -0
- package/dist/styles/globals.css +2 -2
- package/dist/styles.d.ts +2 -0
- package/dist/web-component-standalone.css +37 -0
- package/dist/web-component-standalone.css.map +1 -0
- package/dist/web-component-standalone.iife.js +119188 -146
- package/dist/web-component-standalone.iife.js.map +1 -0
- package/dist/web-component.d.ts +38 -59
- package/dist/web-component.d.ts.map +1 -1
- package/dist/web-component.js +10510 -8735
- package/dist/web-component.js.map +1 -1
- package/package.json +70 -42
- package/dist/index.d.ts +0 -136
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -9441
- package/dist/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-component.js","names":["GESTURE_CONFIG","dragActivationDistance","swipe","minDistance","minVelocity","velocityOnlyThreshold","const","PILL_CONTAINER_SIZES","collapsed","width","min","vw","max","height","hovered","composing","active","expanded","clampSize","config","AUTO_COLLAPSE_TIMEOUT_MS","COMPOSER_MAX_CHARS","PILL_BORDER_RADIUS","pill","rounded","inner","small","PILL_SPACING","xs","sm","md","lg","xl","PILL_MAX_HEIGHTS","tools","mobile","desktop","summary","composer","MAX_PROMPT_BUBBLES","UI_TIMING","hoverDebounce","collapseDelay","copyFeedback","KEYBOARD_VISIBILITY_THRESHOLD_PX","KEYBOARD_GAP_PX","DRAG_OPACITY","dragging","normal","FULL_SCREEN_CONFIG","maxWidth","widthPercent","heightPercent","padding","PINCH_GESTURE_CONFIG","threshold","minInitialDistance","ARIA_IDS","pillTitle","pillDescription","liveRegion","ARIA_LABELS","openAssistant","closeAssistant","endVoiceSession","dragHandle","sendMessage","voiceInput","expandFullScreen","collapseFullScreen","WEBMCP_PRODUCTION_API_BASE","MCP_MAX_RECONNECT_ATTEMPTS","MCP_BASE_RECONNECT_DELAY_MS","MCP_MAX_RECONNECT_DELAY_MS","MCP_TAB_CONNECT_DELAY_MS","AUDIO_FREQUENCY_BINS","REALTIME_DEFAULT_MODEL","REALTIME_DEFAULT_VOICE","REALTIME_DEFAULT_API_URL","AUDIO_VISUALIZATION_INTERVAL_MS","RESPONSE_REQUEST_DELAY_MS","TOOL_CALL_DISPLAY_DURATION_MS","TOOL_CALL_ERROR_DISPLAY_DURATION_MS","VOICE_ACTIONS_RETENTION_MS","VOICE_SUMMARY_RETENTION_MS","VOICE_APPROVAL_TIMEOUT_MS","VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS","VOICE_APPROVAL_KEYWORDS","approve","deny","VOICE_TOOL_RESULT_MESSAGES","handled","sessionEnded","WAVEFORM_HISTORY_SIZE","WAVEFORM_UPDATE_RATE_MS","WEBSOCKET_OPEN","DEBUG_LOGGING_ENABLED","window","__WEBMCP_DEBUG__","debugLog","component","message","data","isDebugEnabled","undefined","console","log","clsx","twMerge","ClassValue","cn","inputs","c","_c","memo","ReactMarkdown","remarkGfm","cn","FC","HTMLAttributes","Components","PillMarkdownProps","content","className","compact","ElementProps","HTMLElement","PillMarkdown","t0","$","t1","t2","t3","t4","t5","t6","t7","t8","cn_","props","t9","cn__0","props_0","t10","cn__1","props_1","t11","cn__2","props_2","t12","cn__3","props_3","t13","cn__4","props_4","t14","cn__5","props_5","cn__7","props_7","cn__8","props_8","isInline","includes","cn__9","props_9","h1","h2","h3","p","a","ul","ol","li","_temp","blockquote","code","pre","hr","_temp2","strong","_temp3","em","_temp4","components","Symbol","for","t15","t16","displayName","cn__6","props_6","cn__10","props_10","cn__11","props_11","cn__12","props_12","c","_c","useThread","AlertCircle","Check","CheckCircle2","Copy","useCallback","useMemo","useState","UI_TIMING","cn","PillMarkdown","FC","ReactNode","SummaryBlockProps","summary","isSuccess","isError","actions","QuickAction","className","isFullScreen","label","onClick","variant","SummaryBlock","t0","$","t1","undefined","copied","setCopied","t2","navigator","clipboard","writeText","setTimeout","copyFeedback","handleCopy","t3","t4","e","stopPropagation","t5","Symbol","for","t6","t7","t8","t9","t10","t11","t12","t13","t14","t15","length","map","_temp","t16","TextPart","type","text","useLatestSummary","messages","_temp2","bb0","lastAssistantMessage","reverse","find","_temp3","textParts","content","filter","_temp4","lastText","at","m","role","thread","WelcomeMessage","ThreadContent","empty","running","complete","_temp5","lastMessage","isRunning","status","action","i","e_0","humanizeToolName","name","progressive","words","replace","toLowerCase","split","length","verb","progressiveVerb","endsWith","slice","charAt","toUpperCase","join","formatArgs","args","Record","entries","Object","map","key","value","displayValue","JSON","stringify","TOOL_DENIED_MESSAGE","formatToolDenialWithReason","reason","useThread","useMemo","humanizeToolName","ToolCallMetadata","Action","id","label","toolName","status","args","result","error","startedAt","duration","sourceId","wasAborted","ToolCallPart","type","toolCallId","artifact","isError","isToolCallMetadata","a","Record","useActions","$","_c","messages","_temp","t0","bb0","length","t1","Symbol","for","actions","message","role","part","content","toolPart","isComplete","undefined","hasError","requiresAction","metadata","push","String","thread","useCurrentAction","find","_temp2","useRecentActions","limit","filter","_temp3","slice","useLastCompletedAction","completed","_temp4","at","TabClientTransport","SSEClientTransport","StreamableHTTPClientTransport","MCPSourceConfig","Transport","TransportType","createMCPTransport","config","transportType","type","targetOrigin","window","location","origin","channelId","serverUrl","URL","url","headers","Record","Accept","customHeaders","authToken","Authorization","transportOptions","requestInit","shouldFallbackToSSE","error","Error","message","includes","calculateReconnectDelay","attempt","baseDelay","maxDelay","Math","min","pow","Client","PromptListChangedNotificationSchema","ToolListChangedNotificationSchema","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","MCP_TAB_CONNECT_DELAY_MS","createMCPTransport","CallToolResult","GetPromptResult","MCPSource","MCPSourceConfig","Prompt","Resource","ResourceTemplate","ToolWithSource","Transport","ReactNode","SOURCE_LOCAL","SOURCE_REMOTE","SourceState","Omit","client","transport","resources","resourceTemplates","prompts","InflightToolCall","toolName","sourceId","abortController","AbortController","MCPToolsContextValue","tools","sources","Map","addSource","id","config","Promise","removeSource","getSource","isConnected","callTool","name","args","Record","callToolOnSource","getPrompt","MCPToolsContext","MCPToolsProviderProps","children","autoConnectLocal","onToolsChange","onPromptsChange","MCPToolsProvider","sourcesRef","inflightCallsRef","callIdCounterRef","forceUpdate","toolsList","setToolsList","promptsList","setPromptsList","abortOrphanedCalls","currentTools","currentToolNames","Set","map","t","current","forEach","call","callId","has","console","warn","abort","Error","delete","rebuildTools","allTools","source","tool","push","_sourceId","rebuildPrompts","allPrompts","prompt","getPublicSource","state","error","sourceState","set","version","connect","listTools","listPrompts","err","setNotificationHandler","updated","String","get","close","undefined","abortPromise","_","reject","signal","aborted","reason","addEventListener","once","result","race","arguments","content","type","const","text","message","isError","find","values","hasPrompt","some","p","publicSources","timer","setTimeout","clearTimeout","inflightCalls","clear","catch","value","useMCPTools","context","useOptionalMCPTools","ThreadAssistantMessage","ThreadRuntime","PendingToolCallInfo","messageId","toolCallId","toolName","args","Record","getPendingToolCalls","threadRuntime","messages","getState","result","msg","role","assistantMsg","status","type","part","content","undefined","push","id","getPendingToolCallsByName","filter","tc","resolvePendingToolCall","messageRuntime","getMessageById","messageState","hasPendingPart","some","partRuntime","getMessagePartByToolCallId","addToolResult","error","Error","message","resolveAllPendingToolCallsByName","pendingCalls","resolved","call","resolveAllPendingToolCalls","createContext","useCallback","useContext","useEffect","useMemo","useState","Tool","ToolApprovalMode","ToolApprovalSettings","ReactNode","STORAGE_KEY","DEFAULT_MODE","ToolApprovalContextValue","setMode","mode","toggleMode","requiresApproval","tool","isDestructive","ToolApprovalContext","ToolApprovalProviderProps","children","defaultMode","disablePersistence","onModeChange","checkIsDestructive","annotations","readOnlyHint","destructiveHint","ToolApprovalProvider","setModeState","stored","localStorage","getItem","setItem","newMode","value","useToolApproval","context","Error","useOptionalToolApproval","debugLog","AudioAnalyzer","audioContext","AudioContext","analyser","AnalyserNode","source","MediaStreamAudioSourceNode","dataArray","Uint8Array","ArrayBuffer","animationId","initialize","stream","MediaStream","Promise","audioTracks","getAudioTracks","streamId","id","length","trackInfo","map","t","label","enabled","muted","readyState","state","resume","err","console","warn","createAnalyser","fftSize","smoothingTimeConstant","createMediaStreamSource","connect","bufferLength","frequencyBinCount","sampleRate","contextState","getAudioLevel","getByteFrequencyData","sum","i","average","Math","min","getFrequencyData","bins","Array","fill","result","samplesPerBin","floor","j","push","startAnalysis","callback","level","frequencies","analyze","requestAnimationFrame","stopAnalysis","cancelAnimationFrame","destroy","disconnect","close","EventCallback","IEventEmitter","EventEmitter","listeners","Map","Set","on","event","callback","has","set","get","add","off","delete","emit","data","forEach","error","console","removeAllListeners","clear","listenerCount","size","RESPONSE_REQUEST_DELAY_MS","EventEmitter","ToolManager","FunctionCall","RealtimeMessage","ResponseOutputItem","type","status","name","call_id","arguments","isCompletedFunctionCall","item","MessageHandler","isProcessingResponse","pendingFunctionCalls","Set","responseRequestTimer","ReturnType","setTimeout","hasRequestedResponse","constructor","toolManager","eventEmitter","handleMessage","data","dataChannel","RTCDataChannel","Promise","msg","JSON","parse","error","console","handleResponseCreated","handleResponseDone","handleFunctionCallArguments","handleSpeechEvents","handleAudioEvents","handleTranscriptEvents","handleUserTranscript","handleError","handleSessionEvents","_msg","outputItems","extractResponseOutput","response","hasFunctionCalls","some","length","functionCalls","filter","map","functionCall","has","add","executeFunctionCall","warn","size","requestResponseIfNeeded","r","Record","Array","isArray","output","eventType","emit","log","hasAudio","delta","eventMap","text","transcript","clearTimeout","result","executeToolCall","readyState","stringify","success","send","undefined","sendToolError","String","delete","errorResponse","reset","clear","jsonrepair","FunctionCall","OpenAITool","ToolExecutionResult","RegisteredTool","name","description","inputSchema","Record","ToolExecutor","args","Promise","ToolManager","tools","executor","lastSentToolSignature","setTools","setExecutor","resetSession","console","log","getToolSignature","map","t","sort","join","hasToolsChanged","currentSignature","markToolsSent","formatToolsForOpenAI","builtInTools","type","parameters","properties","required","registeredTools","tool","const","validateToolSchema","schema","result","validateNestedSchemas","Object","entries","filter","prop","p","optional","nullable","key","validated","value","propType","items","warn","executeToolCall","functionCall","arguments","argsString","executeListTools","error","success","repaired","JSON","parse","slice","data","String","toolList","count","length","message","getChangesSummary","added","removed","total","prevTools","split","Boolean","currTools","prevSet","Set","currSet","has","debugLog","REALTIME_DEFAULT_API_URL","REALTIME_DEFAULT_MODEL","REALTIME_DEFAULT_VOICE","RealtimeConfig","RealtimeSession","EphemeralTokenResponse","client_secret","value","hasClientSecret","response","secret","WebRTCManager","tokenEndpoint","constructor","createSession","config","Promise","model","voice","apiUrl","ephemeralKey","getEphemeralToken","pc","RTCPeerConnection","audioElement","createAudioElement","remoteStream","MediaStream","ontrack","e","streams","srcObject","streamId","id","tracks","getTracks","length","localStream","getUserMedia","map","t","kind","enabled","muted","readyState","forEach","track","addTrack","dataChannel","createDataChannel","offer","createOffer","setLocalDescription","sdp","Error","answer","connectToOpenAI","setRemoteDescription","cleanup","stop","remove","close","fetch","method","headers","body","JSON","stringify","ok","errorText","text","console","error","statusText","data","json","HTMLAudioElement","document","createElement","autoplay","style","display","appendChild","navigator","mediaDevices","audio","echoCancellation","noiseSuppression","autoGainControl","baseUrl","RTCSessionDescriptionInit","Authorization","answerSdp","type","const","AUDIO_FREQUENCY_BINS","AUDIO_VISUALIZATION_INTERVAL_MS","debugLog","AudioAnalyzer","EventEmitter","MessageHandler","ToolManager","WebRTCManager","RegisteredTool","ToolExecutor","EventCallback","RealtimeConfig","RealtimeSession","SessionConfig","EMPTY_FREQUENCY_TEMPLATE","Object","freeze","Array","fill","createZeroFrequencyArray","OpenAIRealtimeService","session","webrtcManager","toolManager","messageHandler","eventEmitter","muted","lastState","localAnalyzer","remoteAnalyzer","visualizationInterval","ReturnType","setInterval","sessionStartTime","onToolsChangedCallback","constructor","tokenEndpoint","setTools","tools","isSessionActive","updateSessionTools","setToolExecutor","executor","setExecutor","onToolsChanged","callback","startSession","config","Promise","stopSession","Date","now","emitSessionState","createSession","setupDataChannel","dataChannel","setupPeerConnectionMonitoring","pc","localStream","initializeLocalAnalyzer","remoteStream","initializeRemoteAnalyzer","originalOntrack","ontrack","e","call","streams","console","warn","error","handleSessionError","durationSeconds","Math","floor","clearInterval","destroy","cleanup","reset","resetSession","sendUserMessage","text","Error","message","type","item","role","content","send","JSON","stringify","readyState","getLocalStream","MediaStream","getRemoteStream","toggleMute","audioElement","isMuted","pauseAudio","pause","resumeAudio","play","catch","on","event","off","getSessionStatus","state","isActive","RTCDataChannel","addEventListener","configureSession","MessageEvent","handleMessage","data","emit","RTCPeerConnection","connectionState","iceConnectionState","formatToolsForOpenAI","markToolsSent","sessionConfig","modalities","instructions","getSessionInstructions","voice","tool_choice","turn_detection","threshold","prefix_padding_ms","silence_duration_ms","input_audio_transcription","model","sessionUpdate","changesSummary","getChangesSummary","log","total","added","length","slice","join","removed","String","stream","clonedStream","getAudioTracks","map","t","clone","initialize","startAudioVisualization","logCounter","micLevel","getAudioLevel","micFrequency","getFrequencyData","speakerLevel","speakerFrequency","mic","toFixed","speaker","extra","Record","payload","RealtimeConfig","model","voice","apiUrl","tokenEndpoint","RealtimeSession","pc","RTCPeerConnection","dataChannel","RTCDataChannel","audioElement","HTMLAudioElement","localStream","MediaStream","remoteStream","cleanup","OpenAITool","type","name","description","parameters","properties","Record","required","SessionConfig","modalities","instructions","tools","tool_choice","turn_detection","threshold","prefix_padding_ms","silence_duration_ms","input_audio_transcription","FunctionCall","arguments","call_id","status","ConversationItem","role","content","output","RealtimeMessage","key","ToolExecutionResult","success","data","error","EventCallback","IEventEmitter","on","event","callback","off","emit","AudioLevelData","micLevel","micFrequency","speakerLevel","speakerFrequency","TranscriptData","text","isDone","ToolCallData","toolName","VoiceModeState","isActive","isConnecting","isMuted","isError","connectionState","audioLevel","transcript","toolCall","SessionStateEventData","state","durationSeconds","UserTranscriptEventData","AssistantTranscriptEventData","delta","ToolCallStartedEventData","ToolCallCompletedEventData","NestedErrorObject","code","message","param","event_id","ErrorEventData","isSessionStateEventData","d","includes","isUserTranscriptEventData","isAssistantTranscriptEventData","undefined","isToolCallStartedEventData","isToolCallCompletedEventData","isErrorEventData","hasError","extractErrorMessage","nestedError","isAudioLevelData","Array","isArray","useCallback","useEffect","useMemo","useRef","useState","TOOL_CALL_DISPLAY_DURATION_MS","TOOL_CALL_ERROR_DISPLAY_DURATION_MS","extractErrorMessage","isAssistantTranscriptEventData","isAudioLevelData","isErrorEventData","isSessionStateEventData","isToolCallCompletedEventData","isToolCallStartedEventData","isUserTranscriptEventData","OpenAIRealtimeService","AudioLevelData","RealtimeConfig","RegisteredTool","ToolCallData","ToolExecutor","TranscriptData","VoiceModeState","UseVoiceModeOptions","tokenEndpoint","tools","toolExecutor","onConnect","onDisconnect","durationSeconds","onError","error","onUserTranscript","text","onAssistantTranscript","UseVoiceModeReturn","startSession","config","Promise","stopSession","toggleMute","muted","sendMessage","pauseAudio","resumeAudio","useVoiceMode","options","$","_c","isActive","setIsActive","isConnecting","setIsConnecting","isMuted","setIsMuted","isError","setIsError","connectionState","setConnectionState","audioLevel","setAudioLevel","transcript","setTranscript","toolCall","setToolCall","setError","serviceRef","onConnectRef","onDisconnectRef","onErrorRef","onUserTranscriptRef","onAssistantTranscriptRef","t0","t1","current","t2","getService","t3","t4","service","setTools","t5","t6","service_0","setToolExecutor","t7","t8","service_1","handleSessionState","data","console","warn","state","handleAudioLevel","data_0","handleUserTranscript","data_1","type","isDone","handleAssistantTranscript","data_2","delta","prev","handleAssistantTranscriptDone","data_3","text_0","handleToolCallStarted","data_4","status","toolName","name","handleToolCallCompleted","data_5","setTimeout","undefined","handleError","data_6","errorMsg","on","off","t9","service_2","t10","err","errorMsg_0","Error","message","service_3","t11","service_4","newMuted","t12","text_1","service_5","isSessionActive","sendUserMessage","t13","service_6","t14","service_7","t15","createContext","useContext","useMemo","useVoiceMode","ReactNode","UseVoiceModeReturn","RegisteredTool","ToolExecutor","VoiceModeContextValue","isSupported","VoiceModeContext","VoiceModeProviderProps","children","tokenEndpoint","tools","toolExecutor","onConnect","onDisconnect","durationSeconds","onError","error","onUserTranscript","text","onAssistantTranscript","checkVoiceModeSupport","window","RTCPeerConnection","navigator","mediaDevices","getUserMedia","VoiceModeProvider","t0","$","_c","t1","voiceMode","t2","Symbol","for","t3","value","t4","useVoiceModeContext","context","Error","useOptionalVoiceModeContext","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS","VOICE_APPROVAL_TIMEOUT_MS","FC","ReactNode","VoicePendingApproval","callId","toolName","args","Record","timestamp","VoiceToolApprovalContextValue","pendingApproval","approve","deny","timeoutRemaining","isWaitingForApproval","requestApproval","Promise","clearPendingApproval","VoiceToolApprovalContext","VoiceToolApprovalProviderProps","children","timeout","onTimeout","onApprove","onDeny","VoiceToolApprovalProvider","setPendingApproval","setTimeoutRemaining","resolveRef","approved","timeoutIdRef","ReturnType","setTimeout","countdownIdRef","setInterval","onTimeoutRef","onApproveRef","onDenyRef","current","clearTimers","clearTimeout","clearInterval","resolveApproval","reason","resolve","Date","now","timeoutSeconds","Math","ceil","prev","value","useVoiceToolApproval","context","Error","useOptionalVoiceToolApproval","useThread","useThreadRuntime","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","VOICE_TOOL_RESULT_MESSAGES","TOOL_DENIED_MESSAGE","getPendingToolCallsByName","resolveAllPendingToolCalls","resolveAllPendingToolCallsByName","resolvePendingToolCall","useOptionalMCPTools","useOptionalToolApproval","useOptionalVoiceModeContext","VoiceModeProvider","useOptionalVoiceToolApproval","VoiceToolApprovalProvider","ToolCallMetadata","ToolWithSource","FC","MutableRefObject","ReactNode","RegisteredTool","ToolExecutor","VoiceToolCallData","toolCallId","toolName","args","Record","result","isError","artifact","AddToolCallToThread","data","VoiceMessageMetadata","source","voiceSessionId","timestamp","VoiceThreadContextValue","isActive","isConnecting","isMuted","isSupported","error","sessionId","start","Promise","stop","toggleMute","muted","sendMessage","text","pauseAudio","resumeAudio","audioLevel","micLevel","speakerLevel","transcript","type","isDone","toolCall","status","VoiceThreadContext","generateSessionId","Date","now","Math","random","toString","slice","convertToRegisteredTool","tool","name","description","inputSchema","properties","VoiceThreadBridgeProps","children","tokenEndpoint","onConnect","onDisconnect","durationSeconds","onError","VoiceThreadIntegrator","setSessionId","id","addToolCallRef","threadRuntime","voiceMode","lastUserTranscriptRef","lastAssistantTranscriptRef","wasActiveRef","onConnectRef","onDisconnectRef","onErrorRef","current","console","warn","append","role","content","argsText","JSON","stringify","metadata","custom","addUserMessage","trim","addAssistantMessage","newSessionId","sessionEnded","ApprovalAwareVoiceBridge","voiceTools","t0","$","_c","mcpTools","toolApproval","voiceToolApproval","threadMessages","_temp","t1","Symbol","for","Map","pendingVoiceResolutions","t2","callTool","Error","tools","find","t_0","t","needsApproval","requiresApproval","callId","approved","requestApproval","resultMessage","handled","resolvedNow","queue","get","push","set","textContent","_temp2","toolExecutor","t3","size","queue_0","entries","freshQueue","filter","t4","length","delete","pendingCalls","queueIndex","call","result_0","messageId","t5","t6","t7","VoiceThreadBridge","map","VoiceThreadContextProvider","bb0","undefined","startSession","stopSession","contextValue","useVoiceThread","context","useOptionalVoiceThread","useIsVoiceActive","messages","c","useThread","useMemo","useLatestSummary","useActions","useCurrentAction","useLastCompletedAction","useRecentActions","useOptionalMCPTools","useOptionalVoiceThread","CallToolResult","Prompt","ToolWithSource","GetPromptResult","Action","AgentVoice","isActive","isConnecting","isError","isMuted","isSupported","error","sessionId","audioLevel","micLevel","speakerLevel","transcript","type","text","isDone","start","Promise","stop","toggleMute","muted","sendMessage","AgentTools","list","call","name","args","Record","prompts","getPrompt","AgentMessage","id","role","content","status","metadata","AgentState","messages","isRunning","hasMessages","actions","currentAction","recentActions","lastCompletedAction","summary","voice","tools","isVoiceActive","useAgent","$","_c","threadMessages","_temp","_temp2","voiceThread","mcpContext","length","t0","bb0","t1","bb1","t2","t3","callTool","t4","thread_0","thread","createContext","useCallback","useContext","useMemo","useRef","useState","FC","ReactNode","PillMode","Position","x","y","AgentUIState","isOpen","userMode","position","hasUnread","isVoiceActive","isFullScreen","AgentUIContextValue","setOpen","open","toggleOpen","setUserMode","mode","setPosition","resetPosition","markRead","markUnread","setVoiceActive","active","collapse","expand","enterFullScreen","exitFullScreen","toggleFullScreen","AgentUIContext","DEFAULT_POSITION","AgentUIProviderProps","children","defaultOpen","defaultMode","onOpenChange","onModeChange","AgentUIProvider","setIsOpenState","setUserModeState","setPositionState","setHasUnread","setIsVoiceActiveState","setIsFullScreen","onOpenChangeRef","onModeChangeRef","current","prev","next","pos","value","useAgentUI","context","Error","useOptionalAgentUI","usePillMode","useHasUnread","c","_c","useCallback","useEffect","useState","KEYBOARD_VISIBILITY_THRESHOLD_PX","KeyboardState","isKeyboardVisible","keyboardHeight","visibleHeight","useKeyboardAware","$","t0","Symbol","for","window","innerHeight","state","setState","t1","visualViewport","windowHeight","viewportHeight","height","heightDiff","updateKeyboardState","t2","t3","visualViewport_0","addEventListener","removeEventListener","getKeyboardOffset","additionalOffset","c","_c","useEffect","useState","useMobileDetect","$","isMobile","setIsMobile","isTouchDevice","setIsTouchDevice","isCoarsePointer","setIsCoarsePointer","t0","t1","Symbol","for","hasTouch","window","navigator","maxTouchPoints","hoverNone","matchMedia","pointerCoarse","updateState","matches","handleHoverChange","handlePointerChange","addEventListener","removeEventListener","t2","checkIsMobileSSR","useThread","useThreadRuntime","useMemo","ThreadAssistantMessage","PendingToolCallInfo","PendingToolCall","usePendingToolCalls","$","_c","messages","_temp","result","msg","role","assistantMsg","status","type","part","content","undefined","push","messageId","id","toolCallId","toolName","args","Record","t","useHasPendingToolCalls","_temp2","t0","bb0","c","_c","useCallback","useRef","PINCH_GESTURE_CONFIG","TouchEvent","ReactTouchEvent","PinchGestureOptions","onPinchOut","onPinchIn","enabled","threshold","PinchState","initialDistance","lastDistance","isActive","TouchPoint","clientX","clientY","getTouchDistance","touch1","touch2","dx","dy","Math","sqrt","usePinchGesture","t0","$","t1","t2","undefined","t3","Symbol","for","stateRef","t4","e","touches","length","distance","minInitialDistance","current","handleTouchStart","t5","e_0","currentDistance","handleTouchMove","t6","e_1","scaleDelta","handleTouchEnd","t7","handlers","onTouchStart","onTouchMove","onTouchEnd","c","_c","useThread","Camera","FileText","Loader2","MousePointer","Navigation","PenLine","Search","Trash2","Wrench","useMemo","humanizeToolName","cn","LucideIcon","FC","getToolIcon","toolName","name","toLowerCase","includes","ActivityState","type","label","icon","toolNames","streamingText","useActivityState","$","messages","_temp","isRunning","_temp2","t0","bb0","lastAssistantMessage","reverse","find","_temp3","t1","Symbol","for","runningToolNames","lastText","part","content","toolPart","status","push","textPart","text","length","t2","m","role","thread_0","thread","ActivityIndicatorProps","className","ActivityIndicator","activity","Icon","isSpinning","t3","t4","t5","t6","slice","map","_temp4","t7","i","ToolIcon","Shield","ShieldOff","cn","useOptionalToolApproval","FC","ApprovalModeToggleProps","className","ApprovalModeToggle","t0","$","_c","toolApproval","mode","toggleMode","isAskMode","t1","t2","t3","t4","t5","ApprovalModeIndicator","c","_c","AlertCircle","CheckCircle2","Circle","Loader2","cn","FC","Action","CurrentActivityProps","currentAction","recentActions","showRecent","className","CurrentActivity","t0","$","t1","t2","t3","undefined","t4","t5","status","label","t6","length","map","_temp","t7","ActionStatusIconProps","size","ActionStatusIcon","sizeClass","IdleIndicator","Symbol","for","action","id","useAssistantTool","ToolResponse","useMCPTools","useOptionalToolApproval","CallToolResult","ToolCallMetadata","ToolWithSource","ReadonlyJSONValue","FC","formatToolResult","result","textContent","content","map","c","type","text","JSON","stringify","join","ToolBridge","tool","callTool","name","args","Record","Promise","t0","$","_c","t1","description","t2","inputSchema","t3","t4","_sourceId","startedAt","Date","now","isError","wasAborted","some","_temp","metadata_0","duration","sourceId","artifact","metadata","t5","error","console","Error","message","String","toolName","parameters","execute","DestructiveToolBridge","MCPToolRegistry","tools","toolApproval","needsApproval","requiresApproval","includes","c","_c","AlertTriangle","Check","Loader2","X","motion","formatArgs","humanizeToolName","cn","FC","ReactNode","ToolApprovalCardProps","toolName","description","args","Record","timeoutRemaining","isExecuting","onApprove","onDeny","className","headerAddon","subtitle","countdownVariants","pulse","scale","transition","duration","repeat","Infinity","ToolApprovalCard","t0","$","t1","undefined","t2","humanName","t3","Object","keys","length","hasArgs","t4","formattedArgs","t5","t6","Symbol","for","t7","t8","t9","t10","t11","t12","t13","t14","useThreadRuntime","Loader2","useState","usePendingToolCalls","TOOL_DENIED_MESSAGE","resolveAllPendingToolCalls","cn","useMCPTools","formatToolResult","ToolApprovalCard","FC","ElicitationButtonBarProps","className","ElicitationButtonBar","isExecuting","setIsExecuting","pendingToolCalls","threadRuntime","callTool","tools","length","firstTool","toolDescription","find","t","name","toolName","description","getPartRuntime","messageRuntime","getMessageById","messageId","hasPendingPart","getState","content","some","part","type","toolCallId","result","undefined","getMessagePartByToolCallId","error","Error","message","handleAccept","toolResult","args","partRuntime","addToolResult","errorMessage","String","handleDeny","cancelRun","c","_c","ComposerPrimitive","ThreadPrimitive","useComposer","useComposerRuntime","Mic","Send","Square","useCallback","useRef","useMobileDetect","COMPOSER_MAX_CHARS","cn","FC","PillComposerProps","placeholder","showVoiceButton","isVoiceActive","onVoiceToggle","showCharCount","className","isEliciting","onElicitationSubmit","reason","isVoiceMode","onVoiceSend","text","CharacterCount","$","composer","_temp","charCount","length","isOver","remaining","t0","t1","t2","PillComposer","t3","t4","t5","t6","undefined","isMobile","inputRef","composerRuntime","effectivePlaceholder","t7","current","blur","handleSubmit","t8","getState","trim","setText","handleElicitationSubmit","t9","text_0","handleVoiceSend","t10","e","key","shiftKey","preventDefault","handleKeyDown","t11","t12","t13","Symbol","for","touchAction","t14","t15","_temp2","t16","t17","t18","t19","t20","t21","e_0","stopPropagation","c","_c","useEffect","useRef","useAriaHidden","isActive","containerRef","$","t0","Symbol","for","Map","modifiedElementsRef","t1","t2","current","forEach","_temp","clear","container","dialogRoot","parentElement","document","body","bodyChildren","Array","from","children","child","tagName","originalValue_0","getAttribute","set","originalValue","setAttribute","_temp2","originalValue_1","element_0","element","removeAttribute","c","_c","useCallback","useEffect","useRef","FOCUSABLE_SELECTOR","join","UseFocusTrapOptions","isActive","onEscape","autoFocus","returnFocus","skipInputFocusReturn","UseFocusTrapReturn","containerRef","React","RefObject","HTMLDivElement","storeTrigger","useFocusTrap","t0","$","t1","t2","t3","undefined","triggerRef","previouslyFocusedRef","t4","Symbol","for","current","document","activeElement","HTMLElement","t5","Array","from","querySelectorAll","getFocusableElements","t6","t7","timeoutId","setTimeout","focusableElements","length","focus","clearTimeout","isConnected","isInputElement","tagName","blur","isInputElement_0","t8","t9","handleKeyDown","event","key","preventDefault","focusableElements_0","firstElement","lastElement","shiftKey","contains","addEventListener","removeEventListener","t10","AnimatePresence","motion","useReducedMotion","useCallback","useEffect","useRef","useState","useAriaHidden","useFocusTrap","useMobileDetect","ARIA_IDS","ARIA_LABELS","clampSize","FULL_SCREEN_CONFIG","PILL_BORDER_RADIUS","PILL_CONTAINER_SIZES","UI_TIMING","cn","Variants","FC","ReactNode","PillMode","PillContainerProps","mode","children","onModeChange","isFullScreen","className","sizeSpring","type","const","stiffness","damping","mass","fullScreenTween","duration","ease","reducedMotionTransition","sizes","containerVariants","Record","width","height","padding","borderRadius","collapsed","pill","hovered","composing","rounded","active","expanded","fullScreenVariant","widthPercent","maxWidth","heightPercent","contentVariants","hidden","opacity","visible","transition","delay","exit","hintVariants","barVariants","idle","scaleX","hover","PillContainer","isHovered","setIsHovered","hoverTimeoutRef","NodeJS","Timeout","prefersReducedMotion","wasFullScreenRef","isTransitioningFullScreen","current","isMobile","isDialogActive","containerRef","focusTrapRef","storeTrigger","isActive","onEscape","autoFocus","returnFocus","skipInputFocusReturn","prevModeRef","wasCollapsedOrHovered","isNowDialog","handleMouseEnter","clearTimeout","setTimeout","hoverDebounce","handleMouseLeave","collapseDelay","handleClick","handleFocus","handleBlur","handleKeyDown","e","KeyboardEvent","isShortcut","ctrlKey","metaKey","shiftKey","key","toLowerCase","isEscape","preventDefault","window","addEventListener","removeEventListener","showContent","currentVariant","isDialogMode","setContainerRef","node","HTMLDivElement","glassClassName","undefined","pillTitle","openAssistant","background","backgroundSize","Slot","cva","React","cn","VariantProps","ButtonProps","ComponentProps","buttonVariants","asChild","variants","variant","default","destructive","outline","secondary","ghost","link","size","sm","lg","icon","defaultVariants","Button","t0","$","_c","className","props","t1","undefined","Comp","t2","t3","c","_c","AlertCircle","AlertTriangle","Check","ChevronDownIcon","ChevronUpIcon","X","useCallback","useEffect","useState","formatArgs","humanizeToolName","TOOL_DENIED_MESSAGE","cn","useMCPTools","Button","formatToolResult","getToolIcon","ToolCallMessagePartComponent","ApprovedResult","approved","result","isApprovedResult","isDeniedResult","hasStatusError","status","type","error","RunningToolDisplay","React","FC","toolName","t0","$","t1","ToolIcon","t2","t3","t4","t5","ApprovalDialog","toolDescription","inputArgs","Record","onApprove","onDeny","isExecuting","isHovered","setIsHovered","Symbol","for","t6","t7","t8","t9","t10","Object","keys","length","t11","t12","t13","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","t24","t25","CompletedToolDisplay","argsText","isExpanded","setIsExpanded","undefined","JSON","stringify","ErrorToolDisplay","DeniedToolDisplay","UnifiedToolFallback","toolCallId","_toolCallId","args","addResult","callTool","tools","setIsExecuting","showApprovalDialog","setShowApprovalDialog","parsedArgs","parse","e","console","warn","find","t","name","description","handleApprove","toolResult","errorMessage","Error","message","String","handleDeny","statusType","isPendingApproval","timer","setTimeout","clearTimeout","displayResult","c","_c","MessagePrimitive","ThreadPrimitive","UnifiedToolFallback","FC","PillMessageContent","$","t0","Symbol","for","UserMessage","_temp","AssistantMessage","PillAssistantMessage","Text","_temp2","tools","Fallback","c","_c","AlertTriangle","ChevronDown","useEffect","useRef","useState","useActions","cn","PillMessageContent","FC","PillToolsSectionProps","defaultCollapsed","className","isFullScreen","forceCollapsed","PillToolsSection","t0","$","t1","t2","t3","undefined","initialCollapsed","isCollapsed","setIsCollapsed","lastUserCollapsed","wasForceCollapsed","actions","t4","filter","_temp","completedCount","length","t5","_temp2","runningCount","t6","_temp3","pendingCount","totalCount","t7","t8","current","t10","t9","t11","t12","next","t13","Symbol","for","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","t24","touchAction","_temp4","t25","a","status","a_0","a_1","e","stopPropagation","useEffect","useRef","cn","HTMLAttributes","LiveWaveformProps","HTMLDivElement","active","processing","barWidth","barGap","barRadius","barColor","fadeEdges","fadeWidth","height","sensitivity","smoothingTimeConstant","mode","manualAudioLevel","LiveWaveform","t0","$","_c","className","props","t1","t10","t2","t3","t4","t5","t6","t7","t8","t9","undefined","canvasRef","containerRef","t11","Symbol","for","historyRef","lastUpdateRef","processingAnimationRef","t12","lastActiveDataRef","transitionProgressRef","t13","staticBarsRef","needsRedrawRef","gradientCacheRef","lastWidthRef","heightStyle","t14","t15","canvas","current","container","resizeObserver","ResizeObserver","rect","getBoundingClientRect","dpr","window","devicePixelRatio","width","style","ctx","getContext","scale","observe","disconnect","t16","t17","time","animateProcessing","Math","min","processingData","barCount","floor","halfCount","i","normalizedPosition","centerWeight","abs","wave1","sin","wave2","wave3","cos","combinedWave","processingValue","finalValue","length","lastDataIndex","lastValue","push","max","i_0","normalizedPosition_0","centerWeight_0","wave1_0","wave2_0","wave3_0","combinedWave_0","processingValue_0","finalValue_0","lastDataIndex_0","lastValue_0","requestAnimationFrame","cancelAnimationFrame","hasData","fadeProgress","fadeToIdle","map","value","value_0","t18","t19","canvas_0","ctx_0","rafId","animate","currentTime","rect_0","level","barCount_0","halfCount_0","newBars","i_1","distanceFromCenter","value_1","i_2","distanceFromCenter_0","value_2","shift","clearRect","computedBarColor","getComputedStyle","color","step","barCount_1","centerY","dataToRender","i_3","value_3","x","barHeight","y","fillStyle","globalAlpha","beginPath","roundRect","fill","fillRect","i_4","dataIndex","value_4","x_0","barHeight_0","y_0","gradient","createLinearGradient","fadePercent","addColorStop","globalCompositeOperation","t20","t21","t22","t23","t24","t25","c","_c","Pause","AnimatePresence","motion","useEffect","useState","cn","useOptionalMCPTools","useOptionalVoiceThread","useOptionalVoiceToolApproval","ToolApprovalCard","FC","approvalBarVariants","hidden","opacity","height","y","visible","transition","type","const","stiffness","damping","exit","duration","PillVoiceApprovalBarProps","className","PillVoiceApprovalBar","t0","$","voiceThread","voiceApproval","mcpTools","isExecuting","setIsExecuting","t1","pendingApproval","pauseAudio","resumeAudio","t2","t3","timeoutRemaining","approve","deny","t4","tools","toolName","find","t","name","description","toolDescription","hasArgs","Object","keys","args","length","formattedArgs","undefined","t5","handleApprove","t6","handleDeny","t7","t8","Symbol","for","t9","t10","c","_c","useThreadRuntime","Mic","MicOff","PhoneOff","AnimatePresence","motion","useCallback","cn","useOptionalVoiceThread","useOptionalVoiceToolApproval","LiveWaveform","PillComposer","PillVoiceApprovalBar","FC","ToolBorderStatus","PillVoiceProps","onEnd","compact","className","voiceVariants","hidden","opacity","scale","y","visible","transition","type","const","stiffness","damping","exit","duration","buttonVariants","idle","hover","tap","transcriptVariants","height","voiceToolCallToBorderStatus","toolCall","status","error","PillVoice","t0","$","t1","undefined","voiceThread","voiceToolApproval","threadRuntime","t2","clearPendingApproval","stop","handleEnd","t3","toggleMute","handleToggleMute","t4","text","trimmed","trim","sessionId","metadata","custom","source","voiceSessionId","timestamp","Date","now","append","role","content","sendMessage","handleVoiceSend","isActive","isConnecting","isError","isMuted","audioLevel","transcript","isWaitingForApproval","micLevel","speakerLevel","t5","t6","t7","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17","t18","Symbol","for","t19","t20","t21","t22","t23","t24","t25","t26","t27","t28","t29","t30","t31","t32","t33","t34","t35","t36","t37","t38","t39","t40","t41","t42","t43","repeat","Infinity","toolName","t44","t45","isDone","t46","t47","t48","t49","t50","t51","delay","t52","t53","useVoiceBorderStatus","X","AnimatePresence","motion","useCallback","useState","useMobileDetect","MAX_PROMPT_BUBBLES","cn","Prompt","Variants","FC","MouseEvent","PromptBadgeProps","prompts","onSelect","prompt","className","STAGGER_DELAY","STAGGER_DELAY_INITIAL","STAGGER_DELAY_EXIT","containerVariants","hidden","opacity","visible","transition","staggerChildren","delayChildren","exit","staggerDirection","bubbleVariants","y","scale","type","stiffness","damping","duration","bubbleStyles","dismissBadgeBaseStyles","PromptBadge","t0","$","_c","isDismissed","setIsDismissed","isMobile","t1","handleSelect","t2","Symbol","for","e","stopPropagation","handleDismiss","length","T0","T1","t10","t11","t12","t13","t14","t3","t4","t5","t6","t7","t8","t9","visiblePrompts","slice","t15","t16","t17","dismissBadgeStyles","div","map","prompt_0","index","isMiddleBubble","name","description","AnimatePresence","motion","useCallback","useRef","cn","Prompt","FC","PromptSuggestionsProps","prompts","onSelect","prompt","className","PromptSuggestions","t0","$","_c","scrollRef","t1","handleClick","length","t2","t3","t4","Symbol","for","opacity","height","t5","t6","t7","touchAction","t8","t9","prompt_0","index","name","scale","type","stiffness","damping","delay","description","map","_temp","t10","e","stopPropagation","c","_c","useThread","useMemo","cn","PillMarkdown","FC","TextPart","type","text","useStreamingText","$","messages","_temp","isRunning","_temp2","t0","bb0","lastAssistantMessage","reverse","find","_temp3","textParts","content","filter","_temp4","lastText","at","trim","length","part","m","role","thread_0","thread","StreamingResponseProps","maxHeight","className","isFullScreen","StreamingResponse","t1","t2","undefined","streamingText","t3","t4","t5","t6","t7","Symbol","for","t8","t9","c","_c","AnimatePresence","motion","useEffect","useRef","useState","cn","FC","ReactNode","ToolBorderStatus","ToolStatusBorderProps","status","children","className","borderRadius","borderVariants","idle","opacity","scale","calling","transition","duration","error","shakeAnimation","x","ease","const","ToolStatusBorder","t0","$","t1","undefined","effectiveStatus","t2","t3","t4","t5","t6","t7","t8","useToolBorderStatus","hasRunningAction","lastActionStatus","setStatus","timeoutRef","current","clearTimeout","setTimeout","ThreadPrimitive","useComposerRuntime","useThreadRuntime","Expand","GripHorizontal","Minimize","X","AnimatePresence","motion","useDragControls","useCallback","useEffect","useMemo","useRef","useState","useAgent","useOptionalAgentUI","useKeyboardAware","useMobileDetect","useHasPendingToolCalls","usePendingToolCalls","usePinchGesture","ARIA_LABELS","AUTO_COLLAPSE_TIMEOUT_MS","debugLog","DRAG_OPACITY","GESTURE_CONFIG","KEYBOARD_GAP_PX","PILL_BORDER_RADIUS","formatToolDenialWithReason","resolvePendingToolCall","cn","ActivityIndicator","ApprovalModeIndicator","IdleIndicator","ElicitationButtonBar","PillComposer","PillContainer","PillToolsSection","PillVoice","useVoiceBorderStatus","PromptBadge","PromptSuggestions","StreamingResponse","SummaryBlock","WelcomeMessage","ToolStatusBorder","useToolBorderStatus","Prompt","FC","PillMode","PillPosition","AgentPillProps","position","showVoiceButton","isVoiceActive","onVoiceToggle","autoCollapse","className","AgentPill","agent","messages","isRunning","hasMessages","currentAction","lastCompletedAction","summary","voice","tools","agentVoiceActive","hasPendingApprovalRaw","pendingToolCalls","threadRuntime","hasPendingApproval","setHasPendingApproval","timer","setTimeout","clearTimeout","agentUI","userMode","setUserMode","hasUnread","markRead","markUnread","dragPosition","x","y","setDragPosition","setPosition","resetPosition","isFullScreen","enterFullScreen","exitFullScreen","dragControls","constraintsRef","HTMLDivElement","autoCollapseTimeoutRef","NodeJS","Timeout","lastMessageCountRef","isKeyboardVisible","keyboardHeight","isMobile","prompts","getPrompt","composerRuntime","handleDragEnd","_","info","offset","velocity","dragDistance","Math","sqrt","isExpanded","swipeDistance","swipeVelocity","swipe","isAggressiveSwipe","minDistance","minVelocity","velocityOnlyThreshold","dragActivationDistance","currentCount","length","current","voiceBorderStatus","isVoiceModeActive","textBorderStatus","status","borderStatus","mode","handleModeChange","newMode","handleCollapse","handleVoiceToggle","isActive","isConnecting","stop","start","handlePromptSelect","prompt","result","name","userMessage","find","m","role","content","textContent","type","text","setText","send","err","handleElicitationDeny","reason","firstTool","message","messageId","toolCallId","borderRadius","pill","rounded","handlers","pinchHandlers","onPinchOut","onPinchIn","enabled","isComposerReady","setComposerReady","handleKeyDown","e","KeyboardEvent","key","preventDefault","window","addEventListener","removeEventListener","scale","opacity","dragging","stiffness","damping","touchAction","dragHandle","collapseFullScreen","expandFullScreen","endVoiceSession","closeAssistant","error","duration","isSupported","c","_c","useEffect","useRef","useState","createPortal","FC","ReactNode","ShadowRootProps","children","styles","className","mode","ShadowRoot","t0","$","t1","undefined","hostRef","portalContainer","setPortalContainer","t2","t3","host","current","shadow","shadowRoot","attachShadow","styleElement","querySelector","document","createElement","setAttribute","insertBefore","firstChild","textContent","container","appendChild","t4","t5","AssistantRuntimeProvider","AssistantChatTransport","useChatRuntime","lastAssistantMessageIsCompleteWithToolCalls","useMemo","MCPToolRegistry","WEBMCP_PRODUCTION_API_BASE","MCPToolsProvider","ToolApprovalProvider","VoiceThreadBridge","AgentUIProvider","ToolApprovalMode","ToolWithSource","FC","ReactNode","PillMode","AgentProviderProps","children","apiBase","tokenEndpoint","autoConnectLocal","defaultOpen","defaultMode","defaultApprovalMode","onToolsChange","tools","onVoiceError","error","onVoiceConnect","onVoiceDisconnect","duration","onOpenChange","open","onModeChange","mode","onApprovalModeChange","AgentRuntimeProps","AgentRuntime","t0","$","_c","resolvedApiBase","chatApi","t1","api","transport","t2","sendAutomaticallyWhen","_temp","runtime","resolvedTokenEndpoint","t3","Symbol","for","t4","t5","AgentProvider","undefined","t6","t7","messages","WEBMCP_STYLES","WEBMCP_SHADOW_STYLES","injectStyles","document","styleId","getElementById","style","createElement","id","textContent","head","appendChild","getShadowStyles","r2wc","AgentPill","ShadowRoot","AgentProvider","injectStyles","WEBMCP_SHADOW_STYLES","WEBMCP_PRODUCTION_API_BASE","FC","getDefaultApiBase","useLocalApi","window","location","origin","DevModeConfig","anthropicApiKey","openaiApiKey","EmbeddedAgentProps","appId","devMode","disableShadowDOM","EmbeddedAgent","t0","$","_c","t1","undefined","apiBase","console","debug","mode","shadowDOM","voiceEnabled","t2","t3","t4","agentContent","t5","WebMCPAgentElement","Parameters","props","registerWebMCPAgent","tagName","customElements","get","define"],"sources":["../src/lib/constants.ts","../src/lib/utils.ts","../src/components/pill/PillMarkdown.tsx","../src/components/pill/SummaryBlock.tsx","../src/lib/format.ts","../src/hooks/useActions.ts","../src/lib/mcp-transport.ts","../src/providers/MCPToolsProvider.tsx","../src/lib/thread-utils.ts","../src/providers/ToolApprovalProvider.tsx","../src/services/realtime/audio-analyzer.ts","../src/services/realtime/event-emitter.ts","../src/services/realtime/message-handler.ts","../src/services/realtime/tool-manager.ts","../src/services/realtime/webrtc-manager.ts","../src/services/realtime/openai-realtime-service.ts","../src/services/realtime/types.ts","../src/hooks/useVoiceMode.ts","../src/providers/VoiceModeProvider.tsx","../src/providers/VoiceToolApprovalProvider.tsx","../src/providers/VoiceThreadBridge.tsx","../src/core/hooks/useAgent.ts","../src/core/providers/AgentUIProvider.tsx","../src/hooks/useKeyboardAware.ts","../src/hooks/useMobileDetect.ts","../src/hooks/usePendingToolCalls.ts","../src/hooks/usePinchGesture.ts","../src/components/pill/ActivityIndicator.tsx","../src/components/pill/ApprovalModeToggle.tsx","../src/components/pill/CurrentActivity.tsx","../src/components/MCPToolRegistry.tsx","../src/components/pill/ToolApprovalCard.tsx","../src/components/pill/ElicitationButtonBar.tsx","../src/components/pill/PillComposer.tsx","../src/hooks/useAriaHidden.ts","../src/hooks/useFocusTrap.ts","../src/components/pill/PillContainer.tsx","../src/components/button.tsx","../src/components/UnifiedToolFallback.tsx","../src/components/pill/PillMessageContent.tsx","../src/components/pill/PillToolsSection.tsx","../src/components/live-waveform.tsx","../src/components/pill/PillVoiceApprovalBar.tsx","../src/components/pill/PillVoice.tsx","../src/components/pill/PromptBadge.tsx","../src/components/pill/PromptSuggestions.tsx","../src/components/pill/StreamingResponse.tsx","../src/components/pill/ToolStatusBorder.tsx","../src/components/pill/AgentPill.tsx","../src/components/ShadowRoot.tsx","../src/core/providers/AgentProvider.tsx","../src/generated/inline-styles.ts","../src/web-component.tsx"],"sourcesContent":["/**\n * Shared Constants\n *\n * Centralized location for all magic numbers, timeouts, and configuration values.\n * Having these in one place makes the codebase more maintainable and easier to tune.\n */\n\n// ============================================================================\n// Mobile UX Constants\n// ============================================================================\n\n/**\n * Gesture configuration for touch interactions.\n *\n * Mobile swipe-to-dismiss requires an AGGRESSIVE upward swipe to prevent\n * accidental dismisses while allowing intentional quick swipes.\n */\nexport const GESTURE_CONFIG = {\n\t/** Minimum drag distance (px) before it counts as a drag (prevents tap interference) */\n\tdragActivationDistance: 15,\n\n\t/** Swipe-to-dismiss thresholds (mobile only) */\n\tswipe: {\n\t\t/** Must swipe at least this far (px) AND this fast to dismiss */\n\t\tminDistance: 100,\n\t\t/** Minimum velocity (px/s) required with minDistance */\n\t\tminVelocity: 800,\n\t\t/** OR swipe this fast (px/s) regardless of distance for quick flicks */\n\t\tvelocityOnlyThreshold: 1200,\n\t},\n} as const\n\n/**\n * Container sizing for different pill modes.\n * Uses CSS clamp() for fluid responsive sizing.\n *\n * Format: { min, preferred (vw), max }\n *\n * WCAG 2.5.8 (Level AA): Touch targets must be at least 24x24 CSS pixels\n * WCAG 2.5.5 (Level AAA): Touch targets should be at least 44x44 CSS pixels\n * We use 24px minimum for collapsed state to meet AA compliance.\n */\nexport const PILL_CONTAINER_SIZES = {\n\tcollapsed: { width: { min: 44, vw: 12, max: 56 }, height: { min: 24, vw: 6, max: 28 } },\n\thovered: { width: { min: 160, vw: 45, max: 180 }, height: { min: 36, vw: 9, max: 40 } },\n\tcomposing: { width: { min: 260, vw: 80, max: 340 } },\n\tactive: { width: { min: 260, vw: 80, max: 340 } },\n\texpanded: { width: { min: 280, vw: 85, max: 400 } },\n} as const\n\n/** Helper to generate CSS clamp() string from sizing config */\nexport function clampSize(config: { min: number; vw: number; max: number }): string {\n\treturn `clamp(${config.min}px, ${config.vw}vw, ${config.max}px)`\n}\n\n/** Auto-collapse timeout in milliseconds (inactivity before pill collapses) */\nexport const AUTO_COLLAPSE_TIMEOUT_MS = 30000\n\n/** Maximum character limit for composer input */\nexport const COMPOSER_MAX_CHARS = 4000\n\n/** Border radius values for pill states */\nexport const PILL_BORDER_RADIUS = {\n\t/** Pill shape (collapsed/hovered) */\n\tpill: '9999px',\n\t/** Rounded rectangle (expanded states) */\n\trounded: '16px',\n\t/** Inner elements (cards, buttons, etc.) */\n\tinner: '10px',\n\t/** Small elements (chips, badges) */\n\tsmall: '6px',\n} as const\n\n/**\n * Spacing scale for consistent padding/margins.\n * Uses a compact scale optimized for mobile information density.\n * Values in pixels - use with template literals: `${PILL_SPACING.sm}px`\n */\nexport const PILL_SPACING = {\n\t/** Extra small: 4px - minimal gaps */\n\txs: 4,\n\t/** Small: 6px - tight spacing */\n\tsm: 6,\n\t/** Medium: 8px - default spacing */\n\tmd: 8,\n\t/** Large: 10px - section spacing */\n\tlg: 10,\n\t/** Extra large: 12px - container padding */\n\txl: 12,\n} as const\n\n/**\n * Max heights for scrollable sections.\n * Mobile-first values (larger on mobile for easier touch scrolling).\n */\nexport const PILL_MAX_HEIGHTS = {\n\t/** Tools section: 160px mobile, 128px desktop */\n\ttools: { mobile: 160, desktop: 128 },\n\t/** Summary block: 128px mobile, 96px desktop */\n\tsummary: { mobile: 128, desktop: 96 },\n\t/** Composer input: 120px mobile, 96px desktop */\n\tcomposer: { mobile: 120, desktop: 96 },\n} as const\n\n/** Maximum number of prompt bubbles to show above collapsed pill */\nexport const MAX_PROMPT_BUBBLES = 3\n\n/** Debounce/delay values in milliseconds */\nexport const UI_TIMING = {\n\t/** Hover debounce before expanding */\n\thoverDebounce: 100,\n\t/** Delay before collapsing after mouse leave */\n\tcollapseDelay: 50,\n\t/** Copy button feedback duration */\n\tcopyFeedback: 2000,\n} as const\n\n/** Minimum height difference (px) to consider keyboard visible (avoids browser chrome false positives) */\nexport const KEYBOARD_VISIBILITY_THRESHOLD_PX = 100\n\n/** Gap (px) between pill and keyboard when keyboard is visible */\nexport const KEYBOARD_GAP_PX = 16\n\n/**\n * Drag interaction opacity configuration.\n * Lower opacity allows seeing content underneath while dragging (useful for mobile).\n */\nexport const DRAG_OPACITY = {\n\t/** Opacity while actively dragging (0.3 = mostly transparent to see underlying content) */\n\tdragging: 0.3,\n\t/** Normal opacity when not dragging */\n\tnormal: 1,\n} as const\n\n// ============================================================================\n// Full-Screen Mode Constants\n// ============================================================================\n\n/**\n * Full-screen mode sizing configuration.\n * Uses viewport units for responsive full-screen layout.\n */\nexport const FULL_SCREEN_CONFIG = {\n\t/** Maximum width of full-screen container */\n\tmaxWidth: '640px',\n\t/** Width as percentage of viewport */\n\twidthPercent: 95,\n\t/** Height as percentage of viewport */\n\theightPercent: 85,\n\t/** Padding inside the container */\n\tpadding: 16,\n} as const\n\n/**\n * Pinch gesture configuration for two-finger expand/collapse.\n */\nexport const PINCH_GESTURE_CONFIG = {\n\t/** Minimum scale change to trigger expand/collapse (30% = 0.3) */\n\tthreshold: 0.3,\n\t/** Minimum distance between fingers to start tracking (px) */\n\tminInitialDistance: 50,\n} as const\n\n// ============================================================================\n// Accessibility Constants\n// ============================================================================\n\n/** ARIA label IDs for accessibility */\nexport const ARIA_IDS = {\n\t/** ID for the pill dialog title (used with aria-labelledby) */\n\tpillTitle: 'agent-pill-title',\n\t/** ID for the pill dialog description (used with aria-describedby) */\n\tpillDescription: 'agent-pill-description',\n\t/** ID for the live region announcements */\n\tliveRegion: 'agent-pill-live-region',\n} as const\n\n/** ARIA labels for various UI elements */\nexport const ARIA_LABELS = {\n\topenAssistant: 'Open assistant',\n\tcloseAssistant: 'Close assistant',\n\tendVoiceSession: 'End voice session',\n\tdragHandle: 'Drag to reposition',\n\tsendMessage: 'Send message',\n\tvoiceInput: 'Start voice input',\n\texpandFullScreen: 'Expand to full screen',\n\tcollapseFullScreen: 'Collapse from full screen',\n} as const\n\n// ============================================================================\n// API Configuration\n// ============================================================================\n\n/** Production API base URL for WebMCP chat and token server */\nexport const WEBMCP_PRODUCTION_API_BASE = 'https://webmcp-agent-playground.alexmnahas.workers.dev'\n\n// ============================================================================\n// MCP Connection Constants\n// ============================================================================\n\n/** Maximum number of reconnection attempts before giving up */\nexport const MCP_MAX_RECONNECT_ATTEMPTS = 5\n\n/** Base delay in milliseconds for exponential backoff reconnection */\nexport const MCP_BASE_RECONNECT_DELAY_MS = 1000\n\n/** Maximum reconnect delay in milliseconds (caps exponential backoff) */\nexport const MCP_MAX_RECONNECT_DELAY_MS = 30000\n\n/** Delay before auto-connecting to tab-based MCP sources (allows server initialization) */\nexport const MCP_TAB_CONNECT_DELAY_MS = 100\n\n// ============================================================================\n// Voice Mode / Realtime API Constants\n// ============================================================================\n\n/** Number of frequency bins for audio visualization */\nexport const AUDIO_FREQUENCY_BINS = 32\n\n/** Default OpenAI Realtime model */\nexport const REALTIME_DEFAULT_MODEL = 'gpt-realtime'\n\n/** Default voice for OpenAI Realtime */\nexport const REALTIME_DEFAULT_VOICE = 'echo'\n\n/** Default OpenAI Realtime API URL */\nexport const REALTIME_DEFAULT_API_URL = 'https://api.openai.com/v1/realtime'\n\n/** Interval in milliseconds for audio visualization updates (~60fps) */\nexport const AUDIO_VISUALIZATION_INTERVAL_MS = 16\n\n/** Delay in milliseconds before requesting response after tool execution */\nexport const RESPONSE_REQUEST_DELAY_MS = 150\n\n/** Duration to show completed tool calls before clearing (success) */\nexport const TOOL_CALL_DISPLAY_DURATION_MS = 1500\n\n/** Duration to show failed tool calls before clearing (error) */\nexport const TOOL_CALL_ERROR_DISPLAY_DURATION_MS = 3000\n\n/** Duration to retain voice actions after session ends (for display) */\nexport const VOICE_ACTIONS_RETENTION_MS = 3000\n\n/** Duration to retain voice summary after session ends */\nexport const VOICE_SUMMARY_RETENTION_MS = 30000\n\n// ============================================================================\n// Voice Tool Approval Constants\n// ============================================================================\n\n/** Timeout before auto-deny when waiting for voice approval (30 seconds) */\nexport const VOICE_APPROVAL_TIMEOUT_MS = 30000\n\n/** Interval for countdown timer updates */\nexport const VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS = 1000\n\n/**\n * Keywords that trigger approval or denial.\n * Uses word boundary matching for safety (prevents \"yesterday\" matching \"yes\").\n */\nexport const VOICE_APPROVAL_KEYWORDS = {\n\tapprove: ['approve', 'yes', 'confirm', 'allow', 'go ahead', 'do it', 'proceed'],\n\tdeny: ['deny', 'no', 'cancel', 'stop', 'reject', \"don't\", 'dont'],\n} as const\n\n/**\n * Tool result messages for voice mode approvals.\n * Used when syncing voice approval results to the thread.\n */\nexport const VOICE_TOOL_RESULT_MESSAGES = {\n\t/** Message when tool was approved and executed in voice mode */\n\thandled: '[Handled in voice mode]',\n\t/** Message when voice session ended with pending approvals */\n\tsessionEnded: '[Voice session ended]',\n} as const\n\n// ============================================================================\n// Waveform Visualization Constants\n// ============================================================================\n\n/** Default history size for scrolling waveform mode */\nexport const WAVEFORM_HISTORY_SIZE = 60\n\n/** Update rate in milliseconds for waveform visualization */\nexport const WAVEFORM_UPDATE_RATE_MS = 30\n\n// ============================================================================\n// WebSocket States (for type-safe comparisons)\n// ============================================================================\n\n/** WebSocket OPEN state value */\nexport const WEBSOCKET_OPEN = 1\n\n// ============================================================================\n// Logging Configuration\n// ============================================================================\n\n/**\n * Enable debug logging for development.\n * Can be enabled by setting window.__WEBMCP_DEBUG__ = true in the browser console.\n * In production builds, this defaults to false.\n */\nexport const DEBUG_LOGGING_ENABLED =\n\ttypeof window !== 'undefined' &&\n\t(window as { __WEBMCP_DEBUG__?: boolean }).__WEBMCP_DEBUG__ === true\n\n/**\n * Conditional debug logger that only logs when DEBUG_LOGGING_ENABLED is true.\n * Can be enabled at runtime by setting window.__WEBMCP_DEBUG__ = true\n *\n * @param component - The component or service name for the log prefix\n * @param message - The log message\n * @param data - Optional data to include in the log\n */\nexport function debugLog(component: string, message: string, data?: unknown): void {\n\t// Check the flag at runtime to allow enabling after page load\n\tconst isDebugEnabled =\n\t\ttypeof window !== 'undefined' &&\n\t\t(window as { __WEBMCP_DEBUG__?: boolean }).__WEBMCP_DEBUG__ === true\n\n\tif (isDebugEnabled) {\n\t\tif (data !== undefined) {\n\t\t\tconsole.log(`[${component}] ${message}`, data)\n\t\t} else {\n\t\t\tconsole.log(`[${component}] ${message}`)\n\t\t}\n\t}\n}\n","import { clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nimport type { ClassValue } from 'clsx'\n\n/**\n * Merges Tailwind CSS classes with proper precedence handling.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]): string {\n\treturn twMerge(clsx(inputs))\n}\n","'use client'\n\n/**\n * Markdown renderer for pill components.\n * Uses the same styling as the main MarkdownText but accepts content as a prop.\n */\nimport { memo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\n\nimport { cn } from '../../lib/utils'\n\nimport type { FC, HTMLAttributes } from 'react'\nimport type { Components } from 'react-markdown'\n\ninterface PillMarkdownProps {\n\tcontent: string\n\tclassName?: string\n\t/** Compact mode uses smaller text and tighter spacing */\n\tcompact?: boolean\n}\n\ntype ElementProps = HTMLAttributes<HTMLElement>\n\n/**\n * Markdown component for rendering content within pill UI.\n * Supports GitHub-flavored markdown with compact styling option.\n */\nexport const PillMarkdown: FC<PillMarkdownProps> = memo(({ content, className, compact }) => {\n\tconst components: Components = {\n\t\th1: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<h1\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-h1 mb-3 scroll-m-20 font-extrabold tracking-tight last:mb-0',\n\t\t\t\t\tcompact ? 'text-base' : 'text-lg',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\th2: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<h2\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-h2 mt-3 mb-2 scroll-m-20 font-semibold tracking-tight first:mt-0 last:mb-0',\n\t\t\t\t\tcompact ? 'text-sm' : 'text-base',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\th3: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<h3\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-h3 mt-2 mb-1 scroll-m-20 font-semibold tracking-tight first:mt-0 last:mb-0',\n\t\t\t\t\tcompact ? 'text-sm' : 'text-[15px]',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\tp: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<p\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-p leading-relaxed first:mt-0 last:mb-0',\n\t\t\t\t\tcompact ? 'text-xs my-1' : 'text-sm my-2',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\ta: ({ className: cn_, ...props }: HTMLAttributes<HTMLAnchorElement>) => (\n\t\t\t<a\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-a font-medium text-primary underline underline-offset-4 hover:text-primary/80',\n\t\t\t\t\tcompact ? 'text-xs' : 'text-sm',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\tul: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<ul\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-ul ml-4 list-disc [&>li]:mt-0.5',\n\t\t\t\t\tcompact ? 'text-xs my-1' : 'text-sm my-2',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\tol: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<ol\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-ol ml-4 list-decimal [&>li]:mt-0.5',\n\t\t\t\t\tcompact ? 'text-xs my-1' : 'text-sm my-2',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\tli: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<li className={cn('aui-md-li', cn_)} {...props} />\n\t\t),\n\t\tblockquote: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<blockquote\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-blockquote border-l-2 border-white/20 pl-3 italic text-white/70',\n\t\t\t\t\tcompact ? 'text-xs' : 'text-sm',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\tcode: ({ className: cn_, ...props }: ElementProps) => {\n\t\t\t// Check if this is inline code (no language class)\n\t\t\tconst isInline = !cn_?.includes('language-')\n\t\t\tif (isInline) {\n\t\t\t\treturn (\n\t\t\t\t\t<code\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'aui-md-inline-code rounded bg-white/10 px-1 py-0.5 font-mono',\n\t\t\t\t\t\t\tcompact ? 'text-[10px]' : 'text-xs',\n\t\t\t\t\t\t\tcn_\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<code\n\t\t\t\t\tclassName={cn('aui-md-code block font-mono', compact ? 'text-[10px]' : 'text-xs', cn_)}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t)\n\t\t},\n\t\tpre: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<pre\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'aui-md-pre overflow-x-auto rounded-lg bg-black/30 p-2 my-2',\n\t\t\t\t\tcompact ? 'text-[10px]' : 'text-xs',\n\t\t\t\t\tcn_\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t),\n\t\thr: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<hr className={cn('aui-md-hr my-2 border-white/10', cn_)} {...props} />\n\t\t),\n\t\tstrong: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<strong className={cn('aui-md-strong font-semibold', cn_)} {...props} />\n\t\t),\n\t\tem: ({ className: cn_, ...props }: ElementProps) => (\n\t\t\t<em className={cn('aui-md-em italic', cn_)} {...props} />\n\t\t),\n\t}\n\n\treturn (\n\t\t<div className={cn('aui-md pill-markdown', compact && 'pill-markdown-compact', className)}>\n\t\t\t<ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>\n\t\t\t\t{content}\n\t\t\t</ReactMarkdown>\n\t\t</div>\n\t)\n})\n\nPillMarkdown.displayName = 'PillMarkdown'\n","'use client'\n\nimport { useThread } from '@assistant-ui/react'\nimport { AlertCircle, Check, CheckCircle2, Copy } from 'lucide-react'\nimport { useCallback, useMemo, useState } from 'react'\n\nimport { UI_TIMING } from '../../lib/constants'\nimport { cn } from '../../lib/utils'\nimport { PillMarkdown } from './PillMarkdown'\n\nimport type { FC, ReactNode } from 'react'\n\ninterface SummaryBlockProps {\n\tsummary: string\n\tisSuccess?: boolean\n\tisError?: boolean\n\tactions?: QuickAction[]\n\tclassName?: string\n\t/** Full-screen mode - larger text, no height constraints (parent handles scrolling) */\n\tisFullScreen?: boolean\n}\n\ninterface QuickAction {\n\tlabel: string\n\tonClick: () => void\n\tvariant?: 'primary' | 'secondary'\n}\n\n/**\n * Summary block showing the agent's synthesized output.\n * Displayed after task completion instead of token streaming.\n * Uses compact styling with max-height and scrolling for long responses.\n */\nexport const SummaryBlock: FC<SummaryBlockProps> = ({\n\tsummary,\n\tisSuccess,\n\tisError,\n\tactions,\n\tclassName,\n\tisFullScreen = false,\n}) => {\n\tconst [copied, setCopied] = useState(false)\n\n\tconst handleCopy = useCallback(async () => {\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(summary)\n\t\t\tsetCopied(true)\n\t\t\tsetTimeout(() => setCopied(false), UI_TIMING.copyFeedback)\n\t\t} catch {\n\t\t\t// Ignore clipboard errors\n\t\t}\n\t}, [summary])\n\n\treturn (\n\t\t<div className={cn('rounded-lg p-2 relative group', 'bg-white/5', className)}>\n\t\t\t{/* Copy button - visible on touch, appears on hover for desktop */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={(e) => {\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\tvoid handleCopy()\n\t\t\t\t}}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'absolute top-1.5 right-1.5 z-10',\n\t\t\t\t\t'p-1.5 sm:p-1 rounded',\n\t\t\t\t\t// On touch devices: always slightly visible. On hover devices: hidden until hover\n\t\t\t\t\t'opacity-50 sm:opacity-0 sm:group-hover:opacity-100',\n\t\t\t\t\t'hover:bg-white/10 active:bg-white/15',\n\t\t\t\t\t'text-white/40 hover:text-white/60',\n\t\t\t\t\t'transition-all duration-150'\n\t\t\t\t)}\n\t\t\t\taria-label={copied ? 'Copied!' : 'Copy response'}\n\t\t\t>\n\t\t\t\t{copied ? (\n\t\t\t\t\t<Check className=\"h-3.5 w-3.5 sm:h-3 sm:w-3 text-white/70\" />\n\t\t\t\t) : (\n\t\t\t\t\t<Copy className=\"h-3.5 w-3.5 sm:h-3 sm:w-3\" />\n\t\t\t\t)}\n\t\t\t</button>\n\n\t\t\t{/* Status header - compact */}\n\t\t\t{(isSuccess || isError) && (\n\t\t\t\t<div className=\"flex items-center gap-1.5 mb-1.5\">\n\t\t\t\t\t{isSuccess && <CheckCircle2 className=\"h-3.5 w-3.5 text-white/60\" />}\n\t\t\t\t\t{isError && <AlertCircle className=\"h-3.5 w-3.5 text-white/60\" />}\n\t\t\t\t\t<span className=\"text-[11px] font-medium text-white/70\">\n\t\t\t\t\t\t{isSuccess ? 'Done' : 'Error'}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Summary content - no height limit when full-screen (parent handles scrolling) */}\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'overflow-y-auto scrollbar-thin scroll-touch',\n\t\t\t\t\t!isFullScreen && 'max-h-32 sm:max-h-24'\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<PillMarkdown content={summary} className=\"text-white/80\" compact={!isFullScreen} />\n\t\t\t</div>\n\n\t\t\t{/* Quick actions - compact */}\n\t\t\t{actions && actions.length > 0 && (\n\t\t\t\t<div className=\"flex flex-wrap gap-1.5 mt-2 pt-1.5 border-t border-white/5\">\n\t\t\t\t\t{actions.map((action, i) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\taction.onClick()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'px-2 py-1 rounded text-[11px] font-medium',\n\t\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\t\taction.variant === 'primary'\n\t\t\t\t\t\t\t\t\t? 'bg-white/90 text-slate-900 hover:bg-white'\n\t\t\t\t\t\t\t\t\t: 'bg-white/10 text-white/70 hover:bg-white/15'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\ninterface TextPart {\n\ttype: 'text'\n\ttext: string\n}\n\n/**\n * Hook to get the latest summary from the thread\n * Returns the last text content from the last assistant message\n */\nexport function useLatestSummary(): string | null {\n\t// Use selector pattern to get messages reactively\n\tconst messages = useThread((thread) => thread.messages)\n\n\treturn useMemo(() => {\n\t\tif (!messages || messages.length === 0) return null\n\n\t\tconst lastAssistantMessage = [...messages].reverse().find((m) => m.role === 'assistant')\n\n\t\tif (!lastAssistantMessage) return null\n\n\t\t// Get the last text content\n\t\tconst textParts = lastAssistantMessage.content.filter((c): c is TextPart => c.type === 'text')\n\t\tconst lastText = textParts.at(-1)\n\n\t\tif (!lastText) return null\n\n\t\treturn lastText.text\n\t}, [messages])\n}\n\n/**\n * Welcome message for empty state\n */\nexport const WelcomeMessage: FC<{ className?: string }> = ({ className }) => {\n\treturn (\n\t\t<div className={cn('text-center py-4', className)}>\n\t\t\t<h3 className=\"text-lg font-semibold text-white mb-1\">Hello!</h3>\n\t\t\t<p className=\"text-sm text-white/60\">How can I help you today?</p>\n\t\t</div>\n\t)\n}\n\n/**\n * Wrapper for conditional content based on thread state\n */\nexport const ThreadContent: FC<{\n\tempty: ReactNode\n\trunning: ReactNode\n\tcomplete: ReactNode\n}> = ({ empty, running, complete }) => {\n\t// Use selector pattern to get messages reactively\n\tconst messages = useThread((thread) => thread.messages)\n\n\tif (!messages || messages.length === 0) {\n\t\treturn <>{empty}</>\n\t}\n\n\t// Check if currently running (last message is assistant and incomplete)\n\tconst lastMessage = messages.at(-1)\n\t// Status is an object with a type property, not a string\n\tconst isRunning = lastMessage?.role === 'assistant' && lastMessage.status?.type !== 'complete'\n\n\tif (isRunning) {\n\t\treturn <>{running}</>\n\t}\n\n\treturn <>{complete}</>\n}\n","/**\n * Formatting utilities for tool display\n *\n * Shared helpers for formatting tool names and arguments across components.\n */\n\n/**\n * Humanize tool name for display\n * Converts snake_case and camelCase to readable text.\n *\n * @param name - The tool name to humanize\n * @param progressive - If true, converts verb to progressive tense (e.g., \"searching\")\n *\n * @example\n * humanizeToolName('get_current_time') // 'Get current time'\n * humanizeToolName('deleteNote') // 'Delete note'\n * humanizeToolName('search_files', true) // 'Searching files'\n */\nexport function humanizeToolName(name: string, progressive = false): string {\n\t// Convert camelCase or snake_case to words\n\tconst words = name\n\t\t.replace(/([a-z])([A-Z])/g, '$1 $2')\n\t\t.replace(/_/g, ' ')\n\t\t.toLowerCase()\n\t\t.split(' ')\n\n\tif (words.length === 0) return name\n\n\tif (progressive) {\n\t\t// Make first word progressive (e.g., \"search\" -> \"Searching\")\n\t\tconst verb = words[0]\n\t\tconst progressiveVerb = verb.endsWith('e') ? verb.slice(0, -1) + 'ing' : verb + 'ing'\n\t\twords[0] = progressiveVerb.charAt(0).toUpperCase() + progressiveVerb.slice(1)\n\t} else {\n\t\t// Just capitalize first word\n\t\twords[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1)\n\t}\n\n\treturn words.join(' ')\n}\n\n/**\n * Format tool arguments for display\n * Truncates long strings and formats objects as JSON\n *\n * @example\n * formatArgs({ name: 'test', count: 5 }) // 'name: \"test\"\\ncount: 5'\n */\nexport function formatArgs(args: Record<string, unknown>): string {\n\tconst entries = Object.entries(args)\n\tif (entries.length === 0) return 'No arguments'\n\n\treturn entries\n\t\t.map(([key, value]) => {\n\t\t\tconst displayValue =\n\t\t\t\ttypeof value === 'string'\n\t\t\t\t\t? value.length > 50\n\t\t\t\t\t\t? `\"${value.slice(0, 50)}...\"`\n\t\t\t\t\t\t: `\"${value}\"`\n\t\t\t\t\t: JSON.stringify(value)\n\t\t\treturn `${key}: ${displayValue}`\n\t\t})\n\t\t.join('\\n')\n}\n\n/**\n * Denial message constant\n * Used when user denies a tool execution\n */\nexport const TOOL_DENIED_MESSAGE = 'Tool execution denied by user'\n\n/**\n * Format a denial message with a user-provided reason.\n * Used when user wants to tell the agent what to do differently.\n *\n * @param reason - The user's feedback explaining what to do differently\n * @returns Formatted denial message with reason\n */\nexport function formatToolDenialWithReason(reason: string): string {\n\treturn `Tool denied: ${reason}`\n}\n","import { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport { humanizeToolName } from '../lib/format'\n\nimport type { ToolCallMetadata } from '@mcp-b/cloud-mirror-types'\n\n/**\n * Represents a single action derived from a tool call.\n * Metadata (timing, source) is extracted from thread artifacts.\n */\nexport interface Action {\n\tid: string\n\tlabel: string\n\ttoolName: string\n\tstatus: 'running' | 'pending' | 'success' | 'error'\n\targs?: unknown\n\tresult?: unknown\n\terror?: string\n\t/** Timestamp when the tool call started (ms since epoch) */\n\tstartedAt?: number\n\t/** Duration of the tool call in milliseconds */\n\tduration?: number\n\t/** Source ID of the MCP server that handled the call */\n\tsourceId?: string\n\t/** Whether the tool call was aborted (e.g., tool removed during execution) */\n\twasAborted?: boolean\n}\n\ninterface ToolCallPart {\n\ttype: 'tool-call'\n\ttoolCallId: string\n\ttoolName: string\n\targs: unknown\n\tresult?: unknown\n\t// Status from assistant-ui\n\tstatus?: {\n\t\ttype: 'running' | 'complete' | 'incomplete' | 'requires-action'\n\t\terror?: unknown\n\t}\n\t/** Artifact containing ToolCallMetadata (timing, source info) */\n\tartifact?: unknown\n\tisError?: boolean\n}\n\n/**\n * Type guard to check if an artifact is ToolCallMetadata\n */\nfunction isToolCallMetadata(artifact: unknown): artifact is ToolCallMetadata {\n\tif (!artifact || typeof artifact !== 'object') return false\n\tconst a = artifact as Record<string, unknown>\n\treturn (\n\t\ttypeof a.startedAt === 'number' &&\n\t\ttypeof a.duration === 'number' &&\n\t\ttypeof a.sourceId === 'string'\n\t)\n}\n\n/**\n * Hook to derive actions from the current thread's tool calls\n *\n * Actions are a view of tool calls - not separate state.\n * This maintains compatibility with assistant-ui's data model.\n *\n * Metadata (timing, source info) is extracted from the artifact field\n * which is populated by MCPToolRegistry during tool execution.\n */\nexport function useActions(): Action[] {\n\t// Use selector pattern to get messages reactively\n\tconst messages = useThread((thread) => thread.messages)\n\n\treturn useMemo(() => {\n\t\tif (!messages || messages.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\tconst actions: Action[] = []\n\n\t\tfor (const message of messages) {\n\t\t\tif (message.role !== 'assistant') continue\n\n\t\t\tfor (const part of message.content) {\n\t\t\t\tif (part.type !== 'tool-call') continue\n\n\t\t\t\tconst toolPart = part as ToolCallPart\n\t\t\t\tconst isComplete = toolPart.result !== undefined\n\t\t\t\tconst hasError =\n\t\t\t\t\ttoolPart.isError === true ||\n\t\t\t\t\t(toolPart.result &&\n\t\t\t\t\t\ttypeof toolPart.result === 'object' &&\n\t\t\t\t\t\t'error' in (toolPart.result as Record<string, unknown>))\n\n\t\t\t\t// Check for requires-action status (HITL pattern)\n\t\t\t\tconst requiresAction = toolPart.status?.type === 'requires-action'\n\n\t\t\t\tlet status: Action['status']\n\t\t\t\tif (hasError) {\n\t\t\t\t\tstatus = 'error'\n\t\t\t\t} else if (isComplete) {\n\t\t\t\t\tstatus = 'success'\n\t\t\t\t} else if (requiresAction) {\n\t\t\t\t\tstatus = 'pending' // Waiting for user approval\n\t\t\t\t} else {\n\t\t\t\t\tstatus = 'running'\n\t\t\t\t}\n\n\t\t\t\t// Extract metadata from artifact if available\n\t\t\t\tconst metadata = isToolCallMetadata(toolPart.artifact) ? toolPart.artifact : undefined\n\n\t\t\t\tactions.push({\n\t\t\t\t\tid: toolPart.toolCallId,\n\t\t\t\t\ttoolName: toolPart.toolName,\n\t\t\t\t\tlabel: humanizeToolName(toolPart.toolName, status === 'running'),\n\t\t\t\t\tstatus,\n\t\t\t\t\targs: toolPart.args,\n\t\t\t\t\tresult: toolPart.result,\n\t\t\t\t\terror: hasError ? String((toolPart.result as Record<string, unknown>).error) : undefined,\n\t\t\t\t\t// Populate from artifact metadata\n\t\t\t\t\tstartedAt: metadata?.startedAt,\n\t\t\t\t\tduration: metadata?.duration,\n\t\t\t\t\tsourceId: metadata?.sourceId,\n\t\t\t\t\twasAborted: metadata?.wasAborted,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn actions\n\t}, [messages])\n}\n\n/**\n * Hook to get the current running action (if any)\n */\nexport function useCurrentAction(): Action | null {\n\tconst actions = useActions()\n\treturn actions.find((a) => a.status === 'running') ?? null\n}\n\n/**\n * Hook to get recently completed actions\n */\nexport function useRecentActions(limit = 3): Action[] {\n\tconst actions = useActions()\n\treturn actions.filter((a) => a.status === 'success' || a.status === 'error').slice(-limit)\n}\n\n/**\n * Hook to get the last completed action (success or error)\n */\nexport function useLastCompletedAction(): Action | null {\n\tconst actions = useActions()\n\tconst completed = actions.filter((a) => a.status === 'success' || a.status === 'error')\n\treturn completed.at(-1) ?? null\n}\n","/**\n * MCP Transport Utilities\n *\n * Shared transport creation logic for MCP sources.\n * This eliminates duplication between MCPToolsProvider and useMCPSource.\n */\nimport { TabClientTransport } from '@mcp-b/transports'\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\n\nimport type { MCPSourceConfig } from '@mcp-b/cloud-mirror-types'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\n\n/**\n * Transport type options for HTTP-based connections\n */\nexport type TransportType = 'http' | 'sse'\n\n/**\n * Creates the appropriate MCP transport based on source configuration.\n *\n * @param config - The MCP source configuration\n * @param transportType - For HTTP sources, specifies whether to use HTTP or SSE transport\n * @returns A configured MCP Transport instance\n *\n * @example Tab-based transport (same-tab or iframe)\n * ```ts\n * const transport = createMCPTransport({ type: 'tab' })\n * ```\n *\n * @example HTTP transport with auth\n * ```ts\n * const transport = createMCPTransport({\n * type: 'http',\n * url: 'https://example.com/mcp',\n * authToken: 'secret'\n * }, 'http')\n * ```\n */\nexport function createMCPTransport(\n\tconfig: MCPSourceConfig,\n\ttransportType: TransportType = 'http'\n): Transport {\n\tif (config.type === 'tab') {\n\t\treturn new TabClientTransport({\n\t\t\ttargetOrigin: config.targetOrigin ?? window.location.origin,\n\t\t\tchannelId: config.channelId ?? 'mcp-default',\n\t\t})\n\t}\n\n\t// HTTP/SSE transport configuration\n\tconst serverUrl = new URL(config.url)\n\tconst headers: Record<string, string> = {\n\t\tAccept: 'application/json, text/event-stream',\n\t\t...(config.customHeaders ?? {}),\n\t}\n\n\tif (config.authToken) {\n\t\theaders.Authorization = `Bearer ${config.authToken}`\n\t}\n\n\tconst transportOptions = {\n\t\trequestInit: { headers },\n\t}\n\n\tif (transportType === 'sse') {\n\t\treturn new SSEClientTransport(serverUrl, transportOptions)\n\t}\n\n\treturn new StreamableHTTPClientTransport(serverUrl, transportOptions)\n}\n\n/**\n * Check if an error indicates we should try SSE fallback.\n *\n * This handles cases where HTTP streaming isn't supported (404/405) or\n * when the connection fails due to CORS/network issues.\n *\n * @param error - The error from the failed HTTP connection\n * @returns true if the error suggests trying SSE transport instead\n */\nexport function shouldFallbackToSSE(error: Error): boolean {\n\tconst message = error.message\n\treturn (\n\t\tmessage.includes('404') ||\n\t\tmessage.includes('Not Found') ||\n\t\tmessage.includes('405') ||\n\t\tmessage.includes('Method Not Allowed') ||\n\t\tmessage === 'Failed to fetch' || // Chrome CORS\n\t\tmessage === 'NetworkError when attempting to fetch resource.' || // Firefox\n\t\tmessage === 'Load failed' // Safari\n\t)\n}\n\n/**\n * Calculate exponential backoff delay for reconnection attempts.\n *\n * @param attempt - The current attempt number (0-based)\n * @param baseDelay - Base delay in milliseconds\n * @param maxDelay - Maximum delay cap in milliseconds\n * @returns The calculated delay in milliseconds\n */\nexport function calculateReconnectDelay(\n\tattempt: number,\n\tbaseDelay: number,\n\tmaxDelay: number\n): number {\n\treturn Math.min(baseDelay * Math.pow(2, attempt), maxDelay)\n}\n","/**\n * MCP Tools Provider\n *\n * Simplified provider for managing tools from multiple MCP sources.\n * Sources can be tab-based (same-tab, iframes) or HTTP-based (remote servers).\n *\n * @example Basic usage\n * ```tsx\n * <MCPToolsProvider>\n * <App />\n * </MCPToolsProvider>\n * ```\n *\n * @example Using the hook\n * ```tsx\n * const { tools, addSource, callTool } = useMCPTools()\n * await addSource('remote', { type: 'http', url: 'http://localhost:8888/mcp' })\n * ```\n */\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport {\n\tPromptListChangedNotificationSchema,\n\tToolListChangedNotificationSchema,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { MCP_TAB_CONNECT_DELAY_MS } from '../lib/constants'\nimport { createMCPTransport } from '../lib/mcp-transport'\n\nimport type {\n\tCallToolResult,\n\tGetPromptResult,\n\tMCPSource,\n\tMCPSourceConfig,\n\tPrompt,\n\tResource,\n\tResourceTemplate,\n\tToolWithSource,\n} from '@mcp-b/cloud-mirror-types'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport type { ReactNode } from 'react'\n\n/** Well-known source IDs */\nexport const SOURCE_LOCAL = 'local'\nexport const SOURCE_REMOTE = 'remote'\n\n/** Internal source state with client reference */\ninterface SourceState extends Omit<MCPSource, 'resources' | 'resourceTemplates' | 'prompts'> {\n\tclient: Client | null\n\ttransport: Transport | null\n\tresources: Resource[]\n\tresourceTemplates: ResourceTemplate[]\n\tprompts: Prompt[]\n}\n\n/**\n * Tracks an in-flight tool call with its abort controller.\n *\n * Note: Aborting a call only affects the caller side (the promise race).\n * The underlying tool execution in the MCP server/handler may continue\n * to completion - this is a limitation of the MCP protocol which doesn't\n * support cancellation. The abort ensures the caller gets a timely error\n * response rather than waiting for a tool that's no longer relevant.\n */\ninterface InflightToolCall {\n\t/** The tool name being called */\n\ttoolName: string\n\t/** The source ID the tool belongs to */\n\tsourceId: string\n\t/** Abort controller to cancel the call */\n\tabortController: AbortController\n}\n\n/**\n * MCP Tools Context Value\n */\nexport interface MCPToolsContextValue {\n\t/** All tools from all sources, tagged with _sourceId */\n\ttools: ToolWithSource[]\n\n\t/** All prompts from all sources */\n\tprompts: Prompt[]\n\n\t/** All sources and their states */\n\tsources: Map<string, MCPSource>\n\n\t/** Add a new source */\n\taddSource: (id: string, config: MCPSourceConfig) => Promise<void>\n\n\t/** Remove a source */\n\tremoveSource: (id: string) => Promise<void>\n\n\t/** Get a specific source */\n\tgetSource: (id: string) => MCPSource | undefined\n\n\t/** Check if a source is connected */\n\tisConnected: (id: string) => boolean\n\n\t/** Call a tool (auto-routes based on tool name lookup) */\n\tcallTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\n\t/** Call a tool on a specific source */\n\tcallToolOnSource: (\n\t\tsourceId: string,\n\t\tname: string,\n\t\targs: Record<string, unknown>\n\t) => Promise<CallToolResult>\n\n\t/** Get a prompt's expanded content (auto-routes based on prompt name lookup) */\n\tgetPrompt: (name: string, args?: Record<string, string>) => Promise<GetPromptResult>\n}\n\nconst MCPToolsContext = createContext<MCPToolsContextValue | null>(null)\n\nexport interface MCPToolsProviderProps {\n\tchildren: ReactNode\n\t/** Auto-connect to same-tab source on mount (default: true) */\n\tautoConnectLocal?: boolean\n\t/** Callback when tools change */\n\tonToolsChange?: (tools: ToolWithSource[]) => void\n\t/** Callback when prompts change */\n\tonPromptsChange?: (prompts: Prompt[]) => void\n}\n\nexport function MCPToolsProvider({\n\tchildren,\n\tautoConnectLocal = true,\n\tonToolsChange,\n\tonPromptsChange,\n}: MCPToolsProviderProps) {\n\t// Sources map (internal state with client references)\n\tconst sourcesRef = useRef<Map<string, SourceState>>(new Map())\n\n\t// Track in-flight tool calls for abort handling\n\tconst inflightCallsRef = useRef<Map<string, InflightToolCall>>(new Map())\n\n\t// Counter for generating unique call IDs\n\tconst callIdCounterRef = useRef(0)\n\n\t// Trigger re-renders when sources change\n\tconst [, forceUpdate] = useState({})\n\n\t// Derived tools list\n\tconst [toolsList, setToolsList] = useState<ToolWithSource[]>([])\n\n\t// Derived prompts list\n\tconst [promptsList, setPromptsList] = useState<Prompt[]>([])\n\n\t/**\n\t * Abort in-flight tool calls for tools that are no longer available.\n\t * Called after the tool list changes to clean up orphaned calls.\n\t */\n\tconst abortOrphanedCalls = useCallback((currentTools: ToolWithSource[]) => {\n\t\tconst currentToolNames = new Set(currentTools.map((t) => t.name))\n\n\t\tinflightCallsRef.current.forEach((call, callId) => {\n\t\t\tif (!currentToolNames.has(call.toolName)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[MCPToolsProvider] Aborting orphaned tool call: ${call.toolName} (call ID: ${callId})`\n\t\t\t\t)\n\t\t\t\tcall.abortController.abort(new Error(`Tool '${call.toolName}' is no longer available`))\n\t\t\t\tinflightCallsRef.current.delete(callId)\n\t\t\t}\n\t\t})\n\t}, [])\n\n\t/**\n\t * Rebuild tools list from all sources\n\t */\n\tconst rebuildTools = useCallback(() => {\n\t\tconst allTools: ToolWithSource[] = []\n\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tsource.tools.forEach((tool) => {\n\t\t\t\tallTools.push({\n\t\t\t\t\t...tool,\n\t\t\t\t\t_sourceId: source.id,\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\t// Abort any in-flight calls for tools that are no longer in the list\n\t\tabortOrphanedCalls(allTools)\n\n\t\tsetToolsList(allTools)\n\t}, [abortOrphanedCalls])\n\n\t/**\n\t * Rebuild prompts list from all sources\n\t */\n\tconst rebuildPrompts = useCallback(() => {\n\t\tconst allPrompts: Prompt[] = []\n\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tsource.prompts.forEach((prompt) => {\n\t\t\t\tallPrompts.push(prompt)\n\t\t\t})\n\t\t})\n\n\t\tsetPromptsList(allPrompts)\n\t}, [])\n\n\t/**\n\t * Get public source state (without client reference)\n\t */\n\tconst getPublicSource = useCallback((source: SourceState): MCPSource => {\n\t\treturn {\n\t\t\tid: source.id,\n\t\t\tconfig: source.config,\n\t\t\tstate: source.state,\n\t\t\terror: source.error,\n\t\t\ttools: source.tools,\n\t\t\tresources: source.resources,\n\t\t\tresourceTemplates: source.resourceTemplates,\n\t\t\tprompts: source.prompts,\n\t\t}\n\t}, [])\n\n\t/**\n\t * Add a new source\n\t */\n\tconst addSource = useCallback(\n\t\tasync (id: string, config: MCPSourceConfig): Promise<void> => {\n\t\t\t// Remove existing source if any\n\t\t\tif (sourcesRef.current.has(id)) {\n\t\t\t\tawait removeSource(id)\n\t\t\t}\n\n\t\t\t// Create initial state\n\t\t\tconst sourceState: SourceState = {\n\t\t\t\tid,\n\t\t\t\tconfig,\n\t\t\t\tstate: 'connecting',\n\t\t\t\terror: null,\n\t\t\t\ttools: [],\n\t\t\t\tresources: [],\n\t\t\t\tresourceTemplates: [],\n\t\t\t\tprompts: [],\n\t\t\t\tclient: null,\n\t\t\t\ttransport: null,\n\t\t\t}\n\n\t\t\tsourcesRef.current.set(id, sourceState)\n\t\t\tforceUpdate({})\n\n\t\t\ttry {\n\t\t\t\t// Create client and transport\n\t\t\t\tconst client = new Client({\n\t\t\t\t\tname: `MCP-Source-${id}`,\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t})\n\n\t\t\t\tconst transport = createMCPTransport(config)\n\n\t\t\t\t// Connect\n\t\t\t\tawait client.connect(transport)\n\n\t\t\t\t// Update state with client\n\t\t\t\tsourceState.client = client\n\t\t\t\tsourceState.transport = transport\n\n\t\t\t\t// Get initial tools and prompts\n\t\t\t\tconst { tools } = await client.listTools()\n\t\t\t\tsourceState.tools = tools\n\n\t\t\t\t// Get initial prompts (wrapped in try-catch as some servers may not support prompts)\n\t\t\t\ttry {\n\t\t\t\t\tconst { prompts } = await client.listPrompts()\n\t\t\t\t\tsourceState.prompts = prompts\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.warn(`[MCPToolsProvider:${id}] Server does not support prompts:`, err)\n\t\t\t\t\tsourceState.prompts = []\n\t\t\t\t}\n\n\t\t\t\tsourceState.state = 'connected'\n\n\t\t\t\t// Listen for tool updates\n\t\t\t\tclient.setNotificationHandler(ToolListChangedNotificationSchema, async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst updated = await client.listTools()\n\t\t\t\t\t\tsourceState.tools = updated.tools\n\t\t\t\t\t\trebuildTools()\n\t\t\t\t\t\tforceUpdate({})\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Failed to update tools:`, err)\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\t// Listen for prompt updates\n\t\t\t\tclient.setNotificationHandler(PromptListChangedNotificationSchema, async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst updated = await client.listPrompts()\n\t\t\t\t\t\tsourceState.prompts = updated.prompts\n\t\t\t\t\t\trebuildPrompts()\n\t\t\t\t\t\tforceUpdate({})\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Failed to update prompts:`, err)\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\trebuildTools()\n\t\t\t\trebuildPrompts()\n\t\t\t\tforceUpdate({})\n\t\t\t} catch (err) {\n\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err))\n\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Connection failed:`, error)\n\n\t\t\t\tsourceState.state = 'error'\n\t\t\t\tsourceState.error = error\n\t\t\t\tforceUpdate({})\n\t\t\t}\n\t\t},\n\t\t[rebuildTools, rebuildPrompts]\n\t)\n\n\t/**\n\t * Remove a source\n\t */\n\tconst removeSource = useCallback(\n\t\tasync (id: string): Promise<void> => {\n\t\t\tconst source = sourcesRef.current.get(id)\n\t\t\tif (!source) return\n\n\t\t\t// Close client and transport\n\t\t\tif (source.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.client.close()\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Error closing client:`, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (source.transport) {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.transport.close()\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Error closing transport:`, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsourcesRef.current.delete(id)\n\t\t\trebuildTools()\n\t\t\trebuildPrompts()\n\t\t\tforceUpdate({})\n\t\t},\n\t\t[rebuildTools, rebuildPrompts]\n\t)\n\n\t/**\n\t * Get a source by ID\n\t */\n\tconst getSource = useCallback(\n\t\t(id: string): MCPSource | undefined => {\n\t\t\tconst source = sourcesRef.current.get(id)\n\t\t\treturn source ? getPublicSource(source) : undefined\n\t\t},\n\t\t[getPublicSource]\n\t)\n\n\t/**\n\t * Check if a source is connected\n\t */\n\tconst isConnected = useCallback((id: string): boolean => {\n\t\tconst source = sourcesRef.current.get(id)\n\t\treturn source?.state === 'connected'\n\t}, [])\n\n\t/**\n\t * Call a tool on a specific source with in-flight tracking and abort support.\n\t * If the tool is removed while the call is in progress, the call will be aborted.\n\t */\n\tconst callToolOnSource = useCallback(\n\t\tasync (\n\t\t\tsourceId: string,\n\t\t\tname: string,\n\t\t\targs: Record<string, unknown>\n\t\t): Promise<CallToolResult> => {\n\t\t\tconst source = sourcesRef.current.get(sourceId)\n\t\t\tif (!source?.client) {\n\t\t\t\tthrow new Error(`Source '${sourceId}' not connected`)\n\t\t\t}\n\n\t\t\t// Generate unique call ID and create abort controller\n\t\t\tconst callId = `${sourceId}-${name}-${++callIdCounterRef.current}`\n\t\t\tconst abortController = new AbortController()\n\n\t\t\t// Register in-flight call\n\t\t\tinflightCallsRef.current.set(callId, {\n\t\t\t\ttoolName: name,\n\t\t\t\tsourceId,\n\t\t\t\tabortController,\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\t// Create a promise that rejects when aborted\n\t\t\t\tconst abortPromise = new Promise<never>((_, reject) => {\n\t\t\t\t\tconst signal = abortController.signal\n\n\t\t\t\t\t// Handle already-aborted signal (race condition prevention)\n\t\t\t\t\tif (signal.aborted) {\n\t\t\t\t\t\treject(signal.reason || new Error(`Tool '${name}' call was aborted`))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// Use { once: true } to auto-cleanup the listener\n\t\t\t\t\tsignal.addEventListener(\n\t\t\t\t\t\t'abort',\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\treject(signal.reason || new Error(`Tool '${name}' call was aborted`))\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ once: true }\n\t\t\t\t\t)\n\t\t\t\t})\n\n\t\t\t\t// Race between the actual tool call and the abort signal\n\t\t\t\tconst result = await Promise.race([\n\t\t\t\t\tsource.client.callTool({ name, arguments: args }),\n\t\t\t\t\tabortPromise,\n\t\t\t\t])\n\n\t\t\t\treturn result as CallToolResult\n\t\t\t} catch (error) {\n\t\t\t\t// Check if this was an abort\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\t// Return an error result for aborted calls\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\t\t\ttext: `Tool call aborted: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\t// Clean up the in-flight tracking\n\t\t\t\tinflightCallsRef.current.delete(callId)\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\t/**\n\t * Call a tool (auto-routes based on tool name)\n\t */\n\tconst callTool = useCallback(\n\t\tasync (name: string, args: Record<string, unknown>): Promise<CallToolResult> => {\n\t\t\t// Find which source has this tool\n\t\t\tconst tool = toolsList.find((t) => t.name === name)\n\t\t\tif (!tool) {\n\t\t\t\tthrow new Error(`Tool '${name}' not found`)\n\t\t\t}\n\n\t\t\treturn callToolOnSource(tool._sourceId, name, args)\n\t\t},\n\t\t[toolsList, callToolOnSource]\n\t)\n\n\t/**\n\t * Get a prompt's expanded content (auto-routes based on prompt name)\n\t */\n\tconst getPrompt = useCallback(\n\t\tasync (name: string, args?: Record<string, string>): Promise<GetPromptResult> => {\n\t\t\t// Find which source has this prompt\n\t\t\tfor (const source of sourcesRef.current.values()) {\n\t\t\t\tconst hasPrompt = source.prompts.some((p) => p.name === name)\n\t\t\t\tif (hasPrompt && source.client) {\n\t\t\t\t\treturn (await source.client.getPrompt({ name, arguments: args })) as GetPromptResult\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(`Prompt '${name}' not found`)\n\t\t},\n\t\t[]\n\t)\n\n\t/**\n\t * Get sources map for context (public view).\n\t *\n\t * Note: This useMemo reads from sourcesRef but depends on toolsList/promptsList.\n\t * This is intentional - toolsList and promptsList are derived from sourcesRef,\n\t * so when they change, it means sourcesRef has changed and we need to rebuild\n\t * the public view. This avoids exposing sourcesRef as a dependency while still\n\t * triggering recomputation when source data changes.\n\t */\n\tconst sources = useMemo(() => {\n\t\tconst publicSources = new Map<string, MCPSource>()\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tpublicSources.set(source.id, getPublicSource(source))\n\t\t})\n\t\treturn publicSources\n\t}, [toolsList, promptsList, getPublicSource])\n\n\t// Auto-connect to local source on mount\n\tuseEffect(() => {\n\t\tif (autoConnectLocal) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tvoid addSource(SOURCE_LOCAL, { type: 'tab' })\n\t\t\t}, MCP_TAB_CONNECT_DELAY_MS)\n\t\t\treturn () => clearTimeout(timer)\n\t\t}\n\t}, [autoConnectLocal, addSource])\n\n\t// Notify on tools change\n\tuseEffect(() => {\n\t\tonToolsChange?.(toolsList)\n\t}, [toolsList, onToolsChange])\n\n\t// Notify on prompts change\n\tuseEffect(() => {\n\t\tonPromptsChange?.(promptsList)\n\t}, [promptsList, onPromptsChange])\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\tconst sources = sourcesRef\n\t\tconst inflightCalls = inflightCallsRef\n\t\treturn () => {\n\t\t\t// Abort all in-flight tool calls\n\t\t\t// Note: We iterate first, then clear - don't mutate during iteration\n\t\t\tinflightCalls.current.forEach((call) => {\n\t\t\t\tcall.abortController.abort(new Error('Provider unmounted'))\n\t\t\t})\n\t\t\tinflightCalls.current.clear()\n\n\t\t\t// Close all source connections\n\t\t\tsources.current.forEach((source) => {\n\t\t\t\tif (source.client) {\n\t\t\t\t\tvoid source.client.close().catch(console.error)\n\t\t\t\t}\n\t\t\t\tif (source.transport) {\n\t\t\t\t\tvoid source.transport.close().catch(console.error)\n\t\t\t\t}\n\t\t\t})\n\t\t\tsources.current.clear()\n\t\t}\n\t}, [])\n\n\tconst value = useMemo<MCPToolsContextValue>(\n\t\t() => ({\n\t\t\ttools: toolsList,\n\t\t\tprompts: promptsList,\n\t\t\tsources,\n\t\t\taddSource,\n\t\t\tremoveSource,\n\t\t\tgetSource,\n\t\t\tisConnected,\n\t\t\tcallTool,\n\t\t\tcallToolOnSource,\n\t\t\tgetPrompt,\n\t\t}),\n\t\t[\n\t\t\ttoolsList,\n\t\t\tpromptsList,\n\t\t\tsources,\n\t\t\taddSource,\n\t\t\tremoveSource,\n\t\t\tgetSource,\n\t\t\tisConnected,\n\t\t\tcallTool,\n\t\t\tcallToolOnSource,\n\t\t\tgetPrompt,\n\t\t]\n\t)\n\n\treturn <MCPToolsContext.Provider value={value}>{children}</MCPToolsContext.Provider>\n}\n\n/**\n * Hook to access MCP Tools context\n */\nexport function useMCPTools(): MCPToolsContextValue {\n\tconst context = useContext(MCPToolsContext)\n\tif (!context) {\n\t\tthrow new Error('useMCPTools must be used within an MCPToolsProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access MCP Tools context\n */\nexport function useOptionalMCPTools(): MCPToolsContextValue | null {\n\treturn useContext(MCPToolsContext)\n}\n","/**\n * Thread Utilities\n *\n * Shared utilities for working with assistant-ui thread state.\n * These functions provide a non-reactive way to query and modify thread state,\n * suitable for use in callbacks and effects.\n *\n * For reactive hooks, see usePendingToolCalls.ts which wraps these utilities.\n */\n\nimport type { ThreadAssistantMessage, ThreadRuntime } from '@assistant-ui/react'\n\n/**\n * Information about a pending tool call that requires user approval\n */\nexport interface PendingToolCallInfo {\n\tmessageId: string\n\ttoolCallId: string\n\ttoolName: string\n\targs: Record<string, unknown>\n}\n\n/**\n * Find all pending tool calls in a thread.\n *\n * This is a non-reactive utility for use in callbacks.\n * For reactive state, use usePendingToolCalls() hook instead.\n *\n * @param threadRuntime - The thread runtime to query\n * @returns Array of pending tool calls with their metadata\n */\nexport function getPendingToolCalls(threadRuntime: ThreadRuntime): PendingToolCallInfo[] {\n\tconst messages = threadRuntime.getState().messages\n\tconst result: PendingToolCallInfo[] = []\n\n\tfor (const msg of messages) {\n\t\t// Only assistant messages can have tool calls\n\t\tif (msg.role !== 'assistant') continue\n\n\t\t// Cast to assistant message to access status\n\t\tconst assistantMsg = msg as ThreadAssistantMessage\n\n\t\t// Only process messages waiting for tool results\n\t\tif (assistantMsg.status?.type !== 'requires-action') continue\n\n\t\t// Find tool-call parts without results\n\t\tfor (const part of assistantMsg.content) {\n\t\t\tif (part.type !== 'tool-call') continue\n\t\t\tif (part.result !== undefined) continue\n\n\t\t\tresult.push({\n\t\t\t\tmessageId: msg.id,\n\t\t\t\ttoolCallId: part.toolCallId,\n\t\t\t\ttoolName: part.toolName,\n\t\t\t\targs: (part.args as Record<string, unknown>) ?? {},\n\t\t\t})\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Find pending tool calls matching a specific tool name.\n *\n * @param threadRuntime - The thread runtime to query\n * @param toolName - The tool name to filter by\n * @returns Array of matching pending tool calls\n */\nexport function getPendingToolCallsByName(\n\tthreadRuntime: ThreadRuntime,\n\ttoolName: string\n): PendingToolCallInfo[] {\n\treturn getPendingToolCalls(threadRuntime).filter((tc) => tc.toolName === toolName)\n}\n\n/**\n * Resolve a pending tool call by adding a result.\n *\n * @param threadRuntime - The thread runtime\n * @param messageId - The message ID containing the tool call\n * @param toolCallId - The specific tool call ID to resolve\n * @param result - The result string to add\n * @returns true if resolved successfully, false if tool call not found\n */\nexport function resolvePendingToolCall(\n\tthreadRuntime: ThreadRuntime,\n\tmessageId: string,\n\ttoolCallId: string,\n\tresult: string\n): boolean {\n\tconst messageRuntime = threadRuntime.getMessageById(messageId)\n\tif (!messageRuntime) {\n\t\treturn false\n\t}\n\n\tconst messageState = messageRuntime.getState()\n\tconst hasPendingPart = messageState.content.some(\n\t\t(part) =>\n\t\t\tpart.type === 'tool-call' && part.toolCallId === toolCallId && part.result === undefined\n\t)\n\tif (!hasPendingPart) {\n\t\treturn false\n\t}\n\n\ttry {\n\t\tconst partRuntime = messageRuntime.getMessagePartByToolCallId(toolCallId)\n\t\tpartRuntime.addToolResult(result)\n\t\treturn true\n\t} catch (error) {\n\t\t// Message parts can disappear between the state check and runtime lookup when voice-mode\n\t\t// threads race with the assistant-ui runtime. Treat it as a no-op so we don't crash voice mode.\n\t\tif (error instanceof Error && error.message === 'Entry not available in the store') {\n\t\t\treturn false\n\t\t}\n\t\tthrow error\n\t}\n}\n\n/**\n * Resolve all pending tool calls matching a tool name.\n *\n * @param threadRuntime - The thread runtime\n * @param toolName - The tool name to match\n * @param result - The result string to add to all matches\n * @returns Number of tool calls resolved\n */\nexport function resolveAllPendingToolCallsByName(\n\tthreadRuntime: ThreadRuntime,\n\ttoolName: string,\n\tresult: string\n): number {\n\tconst pendingCalls = getPendingToolCallsByName(threadRuntime, toolName)\n\tlet resolved = 0\n\n\tfor (const call of pendingCalls) {\n\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\tresolved++\n\t\t}\n\t}\n\n\treturn resolved\n}\n\n/**\n * Resolve all pending tool calls in the thread.\n *\n * @param threadRuntime - The thread runtime\n * @param result - The result string to add to all pending calls\n * @returns Number of tool calls resolved\n */\nexport function resolveAllPendingToolCalls(threadRuntime: ThreadRuntime, result: string): number {\n\tconst pendingCalls = getPendingToolCalls(threadRuntime)\n\tlet resolved = 0\n\n\tfor (const call of pendingCalls) {\n\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\tresolved++\n\t\t}\n\t}\n\n\treturn resolved\n}\n","/**\n * Tool Approval Provider\n *\n * Manages user preferences for destructive tool approval.\n * When mode is 'ask', tools with destructiveHint: true require user confirmation.\n * When mode is 'auto', all tools execute immediately.\n *\n * @example\n * ```tsx\n * <ToolApprovalProvider>\n * <App />\n * </ToolApprovalProvider>\n *\n * // In a component:\n * const { mode, setMode, requiresApproval } = useToolApproval()\n * ```\n */\nimport { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'\n\nimport type { Tool, ToolApprovalMode, ToolApprovalSettings } from '@mcp-b/cloud-mirror-types'\nimport type { ReactNode } from 'react'\n\nconst STORAGE_KEY = 'webmcp-tool-approval-mode'\nconst DEFAULT_MODE: ToolApprovalMode = 'ask'\n\n/**\n * Tool Approval Context Value\n */\nexport interface ToolApprovalContextValue extends ToolApprovalSettings {\n\t/** Set the approval mode */\n\tsetMode: (mode: ToolApprovalMode) => void\n\t/** Toggle between 'auto' and 'ask' modes */\n\ttoggleMode: () => void\n\t/** Check if a specific tool requires approval based on its annotations */\n\trequiresApproval: (tool: Tool) => boolean\n\t/** Check if a tool is considered destructive based on its annotations */\n\tisDestructive: (tool: Tool) => boolean\n}\n\nconst ToolApprovalContext = createContext<ToolApprovalContextValue | null>(null)\n\nexport interface ToolApprovalProviderProps {\n\tchildren: ReactNode\n\t/** Initial mode (overrides stored preference) */\n\tdefaultMode?: ToolApprovalMode\n\t/** Disable localStorage persistence */\n\tdisablePersistence?: boolean\n\t/** Callback when mode changes */\n\tonModeChange?: (mode: ToolApprovalMode) => void\n}\n\n/**\n * Check if a tool is destructive based on MCP annotations.\n *\n * A tool is considered destructive if:\n * - It has destructiveHint: true explicitly set, OR\n * - It is NOT read-only (readOnlyHint is false or undefined) AND destructiveHint is not false\n *\n * This follows the MCP spec where destructiveHint defaults to true for non-read-only tools.\n */\nfunction checkIsDestructive(tool: Tool): boolean {\n\tconst annotations = tool.annotations\n\n\t// If no annotations, default to destructive (MCP spec default)\n\tif (!annotations) {\n\t\treturn true\n\t}\n\n\t// If explicitly marked as read-only, it's not destructive\n\tif (annotations.readOnlyHint === true) {\n\t\treturn false\n\t}\n\n\t// If destructiveHint is explicitly set, use that value\n\tif (typeof annotations.destructiveHint === 'boolean') {\n\t\treturn annotations.destructiveHint\n\t}\n\n\t// Default: non-read-only tools are considered potentially destructive\n\treturn true\n}\n\nexport function ToolApprovalProvider({\n\tchildren,\n\tdefaultMode,\n\tdisablePersistence = false,\n\tonModeChange,\n}: ToolApprovalProviderProps) {\n\t// Initialize mode from storage or default\n\tconst [mode, setModeState] = useState<ToolApprovalMode>(() => {\n\t\tif (defaultMode) return defaultMode\n\t\tif (disablePersistence) return DEFAULT_MODE\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem(STORAGE_KEY)\n\t\t\tif (stored === 'auto' || stored === 'ask') {\n\t\t\t\treturn stored\n\t\t\t}\n\t\t} catch {\n\t\t\t// localStorage not available\n\t\t}\n\t\treturn DEFAULT_MODE\n\t})\n\n\t// Persist mode changes\n\tuseEffect(() => {\n\t\tif (disablePersistence) return\n\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_KEY, mode)\n\t\t} catch {\n\t\t\t// localStorage not available\n\t\t}\n\t}, [mode, disablePersistence])\n\n\t// Set mode with callback\n\tconst setMode = useCallback(\n\t\t(newMode: ToolApprovalMode) => {\n\t\t\tsetModeState(newMode)\n\t\t\tonModeChange?.(newMode)\n\t\t},\n\t\t[onModeChange]\n\t)\n\n\t// Toggle between modes\n\tconst toggleMode = useCallback(() => {\n\t\tsetMode(mode === 'auto' ? 'ask' : 'auto')\n\t}, [mode, setMode])\n\n\t// Check if a tool is destructive\n\tconst isDestructive = useCallback((tool: Tool): boolean => {\n\t\treturn checkIsDestructive(tool)\n\t}, [])\n\n\t// Check if a tool requires approval (destructive + ask mode)\n\tconst requiresApproval = useCallback(\n\t\t(tool: Tool): boolean => {\n\t\t\tif (mode === 'auto') return false\n\t\t\treturn isDestructive(tool)\n\t\t},\n\t\t[mode, isDestructive]\n\t)\n\n\tconst value = useMemo<ToolApprovalContextValue>(\n\t\t() => ({\n\t\t\tmode,\n\t\t\tsetMode,\n\t\t\ttoggleMode,\n\t\t\trequiresApproval,\n\t\t\tisDestructive,\n\t\t}),\n\t\t[mode, setMode, toggleMode, requiresApproval, isDestructive]\n\t)\n\n\treturn <ToolApprovalContext.Provider value={value}>{children}</ToolApprovalContext.Provider>\n}\n\n/**\n * Hook to access tool approval settings\n */\nexport function useToolApproval(): ToolApprovalContextValue {\n\tconst context = useContext(ToolApprovalContext)\n\tif (!context) {\n\t\tthrow new Error('useToolApproval must be used within a ToolApprovalProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access tool approval settings\n */\nexport function useOptionalToolApproval(): ToolApprovalContextValue | null {\n\treturn useContext(ToolApprovalContext)\n}\n","import { debugLog } from '../../lib/constants'\n\n/**\n * Audio analyzer for processing microphone and speaker audio streams.\n * Uses Web Audio API to analyze audio levels and frequency data.\n */\nexport class AudioAnalyzer {\n\tprivate audioContext: AudioContext | null = null\n\tprivate analyser: AnalyserNode | null = null\n\tprivate source: MediaStreamAudioSourceNode | null = null\n\tprivate dataArray: Uint8Array<ArrayBuffer> | null = null\n\tprivate animationId: number | null = null\n\n\t/**\n\t * Initialize the audio analyzer with a media stream\n\t * @param stream - MediaStream to analyze (typically from microphone or speaker)\n\t */\n\tasync initialize(stream: MediaStream): Promise<void> {\n\t\t// Log stream info for debugging\n\t\tconst audioTracks = stream.getAudioTracks()\n\t\tdebugLog('AudioAnalyzer', 'Initializing with stream', {\n\t\t\tstreamId: stream.id,\n\t\t\taudioTracks: audioTracks.length,\n\t\t\ttrackInfo: audioTracks.map((t) => ({\n\t\t\t\tid: t.id,\n\t\t\t\tlabel: t.label,\n\t\t\t\tenabled: t.enabled,\n\t\t\t\tmuted: t.muted,\n\t\t\t\treadyState: t.readyState,\n\t\t\t})),\n\t\t})\n\n\t\tthis.audioContext = new AudioContext()\n\t\tdebugLog('AudioAnalyzer', `AudioContext created, initial state: ${this.audioContext.state}`)\n\n\t\t// Always try to resume - some browsers need this regardless of reported state\n\t\ttry {\n\t\t\tawait this.audioContext.resume()\n\t\t\tdebugLog('AudioAnalyzer', `AudioContext after resume: ${this.audioContext.state}`)\n\t\t} catch (err) {\n\t\t\tconsole.warn('[AudioAnalyzer] Failed to resume AudioContext:', err)\n\t\t}\n\n\t\tthis.analyser = this.audioContext.createAnalyser()\n\t\tthis.analyser.fftSize = 256\n\t\tthis.analyser.smoothingTimeConstant = 0.8\n\n\t\tthis.source = this.audioContext.createMediaStreamSource(stream)\n\t\tthis.source.connect(this.analyser)\n\n\t\tconst bufferLength = this.analyser.frequencyBinCount\n\t\tthis.dataArray = new Uint8Array(new ArrayBuffer(bufferLength))\n\n\t\tdebugLog('AudioAnalyzer', 'Setup complete', {\n\t\t\tsampleRate: this.audioContext.sampleRate,\n\t\t\tfrequencyBinCount: bufferLength,\n\t\t\tcontextState: this.audioContext.state,\n\t\t})\n\t}\n\n\tgetAudioLevel(): number {\n\t\tif (!this.analyser || !this.dataArray) return 0\n\n\t\tthis.analyser.getByteFrequencyData(this.dataArray)\n\n\t\t// Calculate average volume\n\t\tlet sum = 0\n\t\tfor (let i = 0; i < this.dataArray.length; i++) {\n\t\t\tsum += this.dataArray[i]\n\t\t}\n\t\tconst average = sum / this.dataArray.length\n\n\t\t// Normalize to 0-1 range\n\t\treturn Math.min(1, average / 128)\n\t}\n\n\tgetFrequencyData(bins = 16): number[] {\n\t\tif (!this.analyser || !this.dataArray) return new Array(bins).fill(0)\n\n\t\tthis.analyser.getByteFrequencyData(this.dataArray)\n\n\t\tconst result: number[] = []\n\t\tconst samplesPerBin = Math.floor(this.dataArray.length / bins)\n\n\t\tfor (let i = 0; i < bins; i++) {\n\t\t\tlet sum = 0\n\t\t\tfor (let j = 0; j < samplesPerBin; j++) {\n\t\t\t\tsum += this.dataArray[i * samplesPerBin + j]\n\t\t\t}\n\t\t\t// Normalize to 0-1 range\n\t\t\tresult.push(Math.min(1, sum / samplesPerBin / 255))\n\t\t}\n\n\t\treturn result\n\t}\n\n\tstartAnalysis(callback: (level: number, frequencies: number[]) => void): void {\n\t\tconst analyze = () => {\n\t\t\tconst level = this.getAudioLevel()\n\t\t\tconst frequencies = this.getFrequencyData()\n\t\t\tcallback(level, frequencies)\n\t\t\tthis.animationId = requestAnimationFrame(analyze)\n\t\t}\n\t\tanalyze()\n\t}\n\n\tstopAnalysis(): void {\n\t\tif (this.animationId !== null) {\n\t\t\tcancelAnimationFrame(this.animationId)\n\t\t\tthis.animationId = null\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.stopAnalysis()\n\n\t\tif (this.source) {\n\t\t\tthis.source.disconnect()\n\t\t\tthis.source = null\n\t\t}\n\n\t\tif (this.analyser) {\n\t\t\tthis.analyser.disconnect()\n\t\t\tthis.analyser = null\n\t\t}\n\n\t\tif (this.audioContext) {\n\t\t\tvoid this.audioContext.close()\n\t\t\tthis.audioContext = null\n\t\t}\n\n\t\tthis.dataArray = null\n\t}\n}\n","import type { EventCallback, IEventEmitter } from './types'\n\nexport class EventEmitter implements IEventEmitter {\n\tprivate listeners = new Map<string, Set<EventCallback>>()\n\n\ton(event: string, callback: EventCallback): void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set())\n\t\t}\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tlisteners.add(callback)\n\t\t}\n\t}\n\n\toff(event: string, callback: EventCallback): void {\n\t\tthis.listeners.get(event)?.delete(callback)\n\t}\n\n\temit(event: string, data: unknown): void {\n\t\tthis.listeners.get(event)?.forEach((callback) => {\n\t\t\ttry {\n\t\t\t\tcallback(data)\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`Error in event listener for ${event}:`, error)\n\t\t\t}\n\t\t})\n\t}\n\n\tremoveAllListeners(event?: string): void {\n\t\tif (event) {\n\t\t\tthis.listeners.delete(event)\n\t\t} else {\n\t\t\tthis.listeners.clear()\n\t\t}\n\t}\n\n\tlistenerCount(event: string): number {\n\t\treturn this.listeners.get(event)?.size || 0\n\t}\n}\n","import { RESPONSE_REQUEST_DELAY_MS } from '../../lib/constants'\n\nimport type { EventEmitter } from './event-emitter'\nimport type { ToolManager } from './tool-manager'\nimport type { FunctionCall, RealtimeMessage } from './types'\n\n/**\n * Type for response output items from OpenAI Realtime API\n */\ninterface ResponseOutputItem {\n\ttype: string\n\tstatus?: string\n\tname?: string\n\tcall_id?: string\n\targuments?: string\n}\n\n/**\n * Type guard to check if an output item is a completed function call\n */\nfunction isCompletedFunctionCall(item: ResponseOutputItem): item is ResponseOutputItem & {\n\tname: string\n\tcall_id: string\n\targuments: string\n} {\n\treturn (\n\t\titem.type === 'function_call' &&\n\t\titem.status === 'completed' &&\n\t\ttypeof item.name === 'string' &&\n\t\ttypeof item.call_id === 'string'\n\t)\n}\n\nexport class MessageHandler {\n\tprivate isProcessingResponse = false\n\tprivate pendingFunctionCalls = new Set<string>()\n\tprivate responseRequestTimer: ReturnType<typeof setTimeout> | null = null\n\tprivate hasRequestedResponse = false\n\n\tconstructor(\n\t\tprivate toolManager: ToolManager,\n\t\tprivate eventEmitter: EventEmitter\n\t) {}\n\n\tasync handleMessage(data: string, dataChannel: RTCDataChannel): Promise<void> {\n\t\tlet msg: RealtimeMessage\n\n\t\ttry {\n\t\t\tmsg = JSON.parse(data) as RealtimeMessage\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to parse realtime message:', error)\n\t\t\treturn\n\t\t}\n\n\t\t// Log all incoming events for debugging\n\t\t// Route message to appropriate handler\n\t\tswitch (msg.type) {\n\t\t\tcase 'response.created':\n\t\t\t\tthis.handleResponseCreated(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'response.done':\n\t\t\t\tawait this.handleResponseDone(msg, dataChannel)\n\t\t\t\tbreak\n\n\t\t\tcase 'response.function_call_arguments.done':\n\t\t\t\tthis.handleFunctionCallArguments()\n\t\t\t\tbreak\n\n\t\t\tcase 'input_audio_buffer.speech_started':\n\t\t\tcase 'input_audio_buffer.speech_stopped':\n\t\t\t\tthis.handleSpeechEvents(msg)\n\t\t\t\tbreak\n\n\t\t\t// GA API: response.output_audio events\n\t\t\tcase 'response.output_audio.delta':\n\t\t\tcase 'response.output_audio.done':\n\t\t\t\tthis.handleAudioEvents(msg)\n\t\t\t\tbreak\n\n\t\t\t// GA API: response.output_audio_transcript and response.output_text events\n\t\t\tcase 'response.output_audio_transcript.delta':\n\t\t\tcase 'response.output_audio_transcript.done':\n\t\t\tcase 'response.output_text.delta':\n\t\t\tcase 'response.output_text.done':\n\t\t\t\tthis.handleTranscriptEvents(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'conversation.item.input_audio_transcription.completed':\n\t\t\t\tthis.handleUserTranscript(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'error':\n\t\t\t\tthis.handleError(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'session.created':\n\t\t\tcase 'session.updated':\n\t\t\t\tthis.handleSessionEvents(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'conversation.item.created':\n\t\t\tcase 'input_audio_buffer.committed':\n\t\t\t\t// Log only, no action needed\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate handleResponseCreated(_msg: RealtimeMessage): void {\n\t\tthis.isProcessingResponse = true\n\t\tthis.hasRequestedResponse = false\n\t}\n\n\tprivate async handleResponseDone(\n\t\tmsg: RealtimeMessage,\n\t\tdataChannel: RTCDataChannel\n\t): Promise<void> {\n\t\t// Safely extract response output with proper type checking\n\t\tconst outputItems = this.extractResponseOutput(msg.response)\n\n\t\t// Check if there are function calls to process\n\t\tconst hasFunctionCalls = outputItems.some(isCompletedFunctionCall)\n\n\t\t// Only set isProcessingResponse to false if there are no function calls\n\t\tif (!hasFunctionCalls) {\n\t\t\tthis.isProcessingResponse = false\n\t\t\tthis.hasRequestedResponse = false\n\t\t}\n\n\t\t// Process any function calls in the response\n\t\tif (outputItems.length > 0) {\n\t\t\t// Extract function calls with proper type narrowing\n\t\t\tconst functionCalls: FunctionCall[] = outputItems\n\t\t\t\t.filter(isCompletedFunctionCall)\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tname: item.name,\n\t\t\t\t\tcall_id: item.call_id,\n\t\t\t\t\targuments: item.arguments ?? '',\n\t\t\t\t}))\n\n\t\t\tfor (const functionCall of functionCalls) {\n\t\t\t\tif (!this.pendingFunctionCalls.has(functionCall.call_id)) {\n\t\t\t\t\tthis.pendingFunctionCalls.add(functionCall.call_id)\n\t\t\t\t\tawait this.executeFunctionCall(functionCall, dataChannel)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[MessageHandler] Skipping duplicate function call: ${functionCall.name} (${functionCall.call_id})`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// After all function calls are processed, check if we need to request a response\n\t\t\tif (functionCalls.length > 0 && this.pendingFunctionCalls.size === 0) {\n\t\t\t\tthis.requestResponseIfNeeded(dataChannel)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Safely extract response output array from response object\n\t */\n\tprivate extractResponseOutput(response: unknown): ResponseOutputItem[] {\n\t\tif (!response || typeof response !== 'object') {\n\t\t\treturn []\n\t\t}\n\n\t\tconst r = response as Record<string, unknown>\n\t\tif (!Array.isArray(r.output)) {\n\t\t\treturn []\n\t\t}\n\n\t\t// Filter to only valid output items\n\t\treturn r.output.filter(\n\t\t\t(item): item is ResponseOutputItem =>\n\t\t\t\titem !== null &&\n\t\t\t\ttypeof item === 'object' &&\n\t\t\t\ttypeof (item as ResponseOutputItem).type === 'string'\n\t\t)\n\t}\n\n\tprivate handleFunctionCallArguments(): void {\n\t\t// Function call arguments are being accumulated\n\t\t// Actual execution happens in handleResponseDone\n\t}\n\n\tprivate handleSpeechEvents(msg: RealtimeMessage): void {\n\t\tconst eventType =\n\t\t\tmsg.type === 'input_audio_buffer.speech_started' ? 'speech_started' : 'speech_stopped'\n\t\tthis.eventEmitter.emit(eventType, msg)\n\t}\n\n\tprivate handleAudioEvents(msg: RealtimeMessage): void {\n\t\tconst eventType = msg.type === 'response.output_audio.delta' ? 'audio_started' : 'audio_stopped'\n\t\tconsole.log(`[MessageHandler] Assistant ${eventType}`, {\n\t\t\ttype: msg.type,\n\t\t\thasAudio: !!(msg as { delta?: unknown }).delta,\n\t\t})\n\t\tthis.eventEmitter.emit(eventType, msg)\n\t}\n\n\tprivate handleTranscriptEvents(msg: RealtimeMessage): void {\n\t\t// GA API event name mappings\n\t\tconst eventMap: Record<string, string> = {\n\t\t\t'response.output_audio_transcript.delta': 'assistant_transcript',\n\t\t\t'response.output_audio_transcript.done': 'assistant_transcript_done',\n\t\t\t'response.output_text.delta': 'text',\n\t\t\t'response.output_text.done': 'text_done',\n\t\t}\n\n\t\tconst eventType = eventMap[msg.type]\n\t\tif (eventType) {\n\t\t\tthis.eventEmitter.emit(eventType, msg)\n\t\t}\n\t}\n\n\tprivate handleUserTranscript(msg: RealtimeMessage): void {\n\t\tthis.eventEmitter.emit('user_transcript_done', { text: msg.transcript })\n\t}\n\n\tprivate handleSessionEvents(_msg: RealtimeMessage): void {\n\t\t// Session events are handled but no action is needed at this time\n\t}\n\n\tprivate handleError(msg: RealtimeMessage): void {\n\t\tconsole.error('Realtime API error:', msg)\n\t\tthis.eventEmitter.emit('error', msg)\n\t\tthis.isProcessingResponse = false\n\t\tthis.hasRequestedResponse = false\n\n\t\t// Clear any pending response timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\t}\n\n\tprivate async executeFunctionCall(\n\t\tfunctionCall: FunctionCall,\n\t\tdataChannel: RTCDataChannel\n\t): Promise<void> {\n\t\tconst { name, call_id } = functionCall\n\n\t\ttry {\n\t\t\t// Emit start event\n\t\t\tthis.eventEmitter.emit('tool_call_started', { name })\n\n\t\t\t// Execute tool\n\t\t\tconst result = await this.toolManager.executeToolCall(functionCall)\n\n\t\t\t// Check if data channel is still open before sending\n\t\t\tif (dataChannel.readyState !== 'open') {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[MessageHandler] Cannot send tool result for ${name}: DataChannel is ${dataChannel.readyState}`\n\t\t\t\t)\n\t\t\t\tthis.eventEmitter.emit('tool_call_completed', {\n\t\t\t\t\tname,\n\t\t\t\t\terror: 'DataChannel closed during tool execution',\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Send result back\n\t\t\tconst response = {\n\t\t\t\ttype: 'conversation.item.create',\n\t\t\t\titem: {\n\t\t\t\t\ttype: 'function_call_output',\n\t\t\t\t\tcall_id: call_id,\n\t\t\t\t\toutput: JSON.stringify(\n\t\t\t\t\t\tresult.success\n\t\t\t\t\t\t\t? result.data\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\terror: result.error,\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tdataChannel.send(JSON.stringify(response))\n\n\t\t\t// Emit completion event\n\t\t\tthis.eventEmitter.emit('tool_call_completed', {\n\t\t\t\tname,\n\t\t\t\terror: result.success ? undefined : result.error,\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tconsole.error(`[MessageHandler] Tool execution failed for ${name}:`, error)\n\t\t\tthis.sendToolError(call_id, String(error), dataChannel)\n\t\t} finally {\n\t\t\tthis.pendingFunctionCalls.delete(call_id)\n\n\t\t\t// After removing this function call, check if all are complete\n\t\t\tif (this.pendingFunctionCalls.size === 0) {\n\t\t\t\t// All function calls are done, now we can request a response\n\t\t\t\tthis.isProcessingResponse = false\n\t\t\t\tthis.hasRequestedResponse = false\n\t\t\t\tthis.requestResponseIfNeeded(dataChannel)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendToolError(call_id: string, error: string, dataChannel: RTCDataChannel): void {\n\t\t// Check if data channel is still open before sending error\n\t\tif (dataChannel.readyState !== 'open') {\n\t\t\tconsole.error(\n\t\t\t\t`[MessageHandler] Cannot send tool error: DataChannel is ${dataChannel.readyState}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\tconst errorResponse = {\n\t\t\ttype: 'conversation.item.create',\n\t\t\titem: {\n\t\t\t\ttype: 'function_call_output',\n\t\t\t\tcall_id: call_id,\n\t\t\t\toutput: JSON.stringify({ error, success: false }),\n\t\t\t},\n\t\t}\n\n\t\tdataChannel.send(JSON.stringify(errorResponse))\n\t}\n\n\tprivate requestResponseIfNeeded(dataChannel: RTCDataChannel): void {\n\t\t// Clear any existing timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\n\t\t// Set a new timer to request response (delay prevents race conditions)\n\t\tthis.responseRequestTimer = setTimeout(() => {\n\t\t\tif (\n\t\t\t\t!this.isProcessingResponse &&\n\t\t\t\t!this.hasRequestedResponse &&\n\t\t\t\tdataChannel.readyState === 'open' &&\n\t\t\t\tthis.pendingFunctionCalls.size === 0\n\t\t\t) {\n\t\t\t\tthis.hasRequestedResponse = true\n\t\t\t\tthis.isProcessingResponse = true\n\t\t\t\tdataChannel.send(JSON.stringify({ type: 'response.create' }))\n\t\t\t}\n\t\t\tthis.responseRequestTimer = null\n\t\t}, RESPONSE_REQUEST_DELAY_MS)\n\t}\n\n\treset(): void {\n\t\tthis.isProcessingResponse = false\n\t\tthis.hasRequestedResponse = false\n\t\tthis.pendingFunctionCalls.clear()\n\n\t\t// Clear any pending response timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\t}\n}\n","import { jsonrepair } from 'jsonrepair'\n\nimport type { FunctionCall, OpenAITool, ToolExecutionResult } from './types'\n\nexport interface RegisteredTool {\n\tname: string\n\tdescription: string\n\tinputSchema?: Record<string, unknown>\n}\n\nexport type ToolExecutor = (name: string, args: Record<string, unknown>) => Promise<unknown>\n\nexport class ToolManager {\n\tprivate tools: RegisteredTool[] = []\n\tprivate executor: ToolExecutor | null = null\n\tprivate lastSentToolSignature = ''\n\n\tsetTools(tools: RegisteredTool[]): void {\n\t\tthis.tools = tools\n\t}\n\n\tsetExecutor(executor: ToolExecutor): void {\n\t\tthis.executor = executor\n\t}\n\n\tresetSession(): void {\n\t\tconsole.log('[ToolManager] resetSession called (lastSentToolSignature preserved)')\n\t}\n\n\tprivate getToolSignature(tools: RegisteredTool[]): string {\n\t\treturn tools\n\t\t\t.map((t) => t.name)\n\t\t\t.sort()\n\t\t\t.join('|')\n\t}\n\n\thasToolsChanged(): boolean {\n\t\tconst currentSignature = this.getToolSignature(this.tools)\n\t\treturn currentSignature !== this.lastSentToolSignature\n\t}\n\n\tmarkToolsSent(): void {\n\t\tthis.lastSentToolSignature = this.getToolSignature(this.tools)\n\t}\n\n\tformatToolsForOpenAI(): OpenAITool[] {\n\t\t// Built-in tools\n\t\tconst builtInTools: OpenAITool[] = [\n\t\t\t{\n\t\t\t\ttype: 'function',\n\t\t\t\tname: 'list_available_tools',\n\t\t\t\tdescription:\n\t\t\t\t\t'List all currently available tools that can be called. Use this when you need to know what tools are available or when the user asks about available capabilities.',\n\t\t\t\tparameters: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {},\n\t\t\t\t\trequired: [],\n\t\t\t\t},\n\t\t\t},\n\t\t]\n\n\t\t// Registered tools\n\t\tconst registeredTools = this.tools.map((tool) => ({\n\t\t\ttype: 'function' as const,\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description || `Execute ${tool.name} action`,\n\t\t\tparameters: this.validateToolSchema(tool.inputSchema),\n\t\t}))\n\n\t\treturn [...builtInTools, ...registeredTools]\n\t}\n\n\tprivate validateToolSchema(schema: Record<string, unknown> | undefined): {\n\t\ttype: string\n\t\tproperties?: Record<string, unknown>\n\t\trequired?: string[]\n\t} {\n\t\tif (!schema) {\n\t\t\treturn { type: 'object', properties: {}, required: [] }\n\t\t}\n\n\t\tconst result: {\n\t\t\ttype: string\n\t\t\tproperties?: Record<string, unknown>\n\t\t\trequired?: string[]\n\t\t} = { type: 'object', ...schema }\n\n\t\tif (result.type === 'object') {\n\t\t\tresult.properties = (result.properties as Record<string, unknown>) || {}\n\n\t\t\t// Validate and fix nested schemas (especially arrays missing 'items')\n\t\t\tresult.properties = this.validateNestedSchemas(result.properties)\n\n\t\t\t// Generate required array if not present\n\t\t\tif (!result.required && result.properties) {\n\t\t\t\tresult.required = Object.entries(result.properties)\n\t\t\t\t\t.filter(([, prop]) => {\n\t\t\t\t\t\tif (prop && typeof prop === 'object') {\n\t\t\t\t\t\t\tconst p = prop as { optional?: boolean; nullable?: boolean; type?: string }\n\t\t\t\t\t\t\treturn !p.optional && !p.nullable && p.type !== 'null'\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false\n\t\t\t\t\t})\n\t\t\t\t\t.map(([key]) => key)\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Recursively validate nested schemas, ensuring array types have 'items'.\n\t * The OpenAI Realtime API requires array schemas to have an 'items' field.\n\t */\n\tprivate validateNestedSchemas(properties: Record<string, unknown>): Record<string, unknown> {\n\t\tconst validated: Record<string, unknown> = {}\n\n\t\tfor (const [key, value] of Object.entries(properties)) {\n\t\t\tif (!value || typeof value !== 'object') {\n\t\t\t\tvalidated[key] = value\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst prop = value as Record<string, unknown>\n\t\t\tconst propType = prop.type as string | undefined\n\n\t\t\tif (propType === 'array') {\n\t\t\t\t// Ensure array schemas have 'items' - required by OpenAI Realtime API\n\t\t\t\tif (!prop.items) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[ToolManager] Array property '${key}' missing 'items' - adding default string items`\n\t\t\t\t\t)\n\t\t\t\t\tvalidated[key] = {\n\t\t\t\t\t\t...prop,\n\t\t\t\t\t\titems: { type: 'string' },\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof prop.items === 'object') {\n\t\t\t\t\t// Recursively validate items schema\n\t\t\t\t\tconst items = prop.items as Record<string, unknown>\n\t\t\t\t\tif (items.type === 'object' && items.properties) {\n\t\t\t\t\t\tvalidated[key] = {\n\t\t\t\t\t\t\t...prop,\n\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t...items,\n\t\t\t\t\t\t\t\tproperties: this.validateNestedSchemas(items.properties as Record<string, unknown>),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalidated[key] = prop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalidated[key] = prop\n\t\t\t\t}\n\t\t\t} else if (propType === 'object' && prop.properties) {\n\t\t\t\t// Recursively validate nested object properties\n\t\t\t\tvalidated[key] = {\n\t\t\t\t\t...prop,\n\t\t\t\t\tproperties: this.validateNestedSchemas(prop.properties as Record<string, unknown>),\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvalidated[key] = prop\n\t\t\t}\n\t\t}\n\n\t\treturn validated\n\t}\n\n\tasync executeToolCall(functionCall: FunctionCall): Promise<ToolExecutionResult> {\n\t\tconst { name, arguments: argsString } = functionCall\n\n\t\t// Handle built-in tools\n\t\tif (name === 'list_available_tools') {\n\t\t\treturn this.executeListTools()\n\t\t}\n\n\t\t// Check if executor is set\n\t\tif (!this.executor) {\n\t\t\tconsole.error('[ToolManager] Tool executor not configured')\n\t\t\treturn { success: false, error: 'Tool executor not configured' }\n\t\t}\n\n\t\t// Parse arguments - use jsonrepair to handle malformed JSON from OpenAI\n\t\tlet args: Record<string, unknown>\n\t\ttry {\n\t\t\tconst repaired = argsString ? jsonrepair(argsString) : '{}'\n\t\t\targs = JSON.parse(repaired) as Record<string, unknown>\n\t\t} catch (error) {\n\t\t\tconsole.error('[ToolManager] Failed to parse arguments:', error)\n\t\t\tconsole.error('[ToolManager] Raw argsString:', argsString?.slice(0, 200))\n\t\t\treturn { success: false, error: 'Invalid arguments format' }\n\t\t}\n\n\t\t// Execute via the executor - it handles tool lookup from the current MCP context\n\t\t// Note: We intentionally don't verify the tool exists in this.tools first because\n\t\t// the executor has access to the latest tool list via React context/closure, which\n\t\t// may be more up-to-date than our cached copy (avoiding stale closure issues).\n\t\t// The executor will throw if the tool is not found.\n\t\ttry {\n\t\t\tconst result = await this.executor(name, args)\n\t\t\treturn { success: true, data: result }\n\t\t} catch (error) {\n\t\t\tconsole.error(`[ToolManager] Tool execution error for ${name}:`, error)\n\t\t\treturn { success: false, error: String(error) }\n\t\t}\n\t}\n\n\tprivate executeListTools(): ToolExecutionResult {\n\t\tconst toolList = this.tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description || 'No description available',\n\t\t\tparameters: tool.inputSchema || {},\n\t\t}))\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\ttools: toolList,\n\t\t\t\tcount: toolList.length,\n\t\t\t\tmessage:\n\t\t\t\t\ttoolList.length > 0\n\t\t\t\t\t\t? `Found ${toolList.length} available tools`\n\t\t\t\t\t\t: 'No tools currently available',\n\t\t\t},\n\t\t}\n\t}\n\n\tgetChangesSummary(): { added: string[]; removed: string[]; total: number } | null {\n\t\tif (!this.hasToolsChanged()) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst prevTools = this.lastSentToolSignature.split('|').filter(Boolean)\n\t\tconst currTools = this.tools.map((t) => t.name)\n\n\t\tconst prevSet = new Set(prevTools)\n\t\tconst currSet = new Set(currTools)\n\n\t\tconst added = currTools.filter((name) => !prevSet.has(name))\n\t\tconst removed = prevTools.filter((name) => !currSet.has(name))\n\n\t\treturn {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\ttotal: this.tools.length,\n\t\t}\n\t}\n}\n","import {\n\tdebugLog,\n\tREALTIME_DEFAULT_API_URL,\n\tREALTIME_DEFAULT_MODEL,\n\tREALTIME_DEFAULT_VOICE,\n} from '../../lib/constants'\n\nimport type { RealtimeConfig, RealtimeSession } from './types'\n\ninterface EphemeralTokenResponse {\n\tclient_secret?: {\n\t\tvalue?: string\n\t}\n}\n\nfunction hasClientSecret(response: unknown): response is {\n\tclient_secret: { value: string }\n} {\n\tif (!response || typeof response !== 'object') {\n\t\treturn false\n\t}\n\tconst secret = (response as EphemeralTokenResponse).client_secret\n\treturn typeof secret?.value === 'string'\n}\n\nexport class WebRTCManager {\n\tprivate tokenEndpoint: string\n\n\tconstructor(tokenEndpoint: string) {\n\t\tthis.tokenEndpoint = tokenEndpoint\n\t}\n\n\tasync createSession(config: RealtimeConfig = {}): Promise<RealtimeSession> {\n\t\tconst model = config.model || REALTIME_DEFAULT_MODEL\n\t\tconst voice = config.voice || REALTIME_DEFAULT_VOICE\n\t\tconst apiUrl = config.apiUrl || REALTIME_DEFAULT_API_URL\n\n\t\t// Get ephemeral token from our backend\n\t\tconst ephemeralKey = await this.getEphemeralToken(model, voice)\n\n\t\t// Create peer connection\n\t\tconst pc = new RTCPeerConnection()\n\n\t\t// Set up audio playback\n\t\tconst audioElement = this.createAudioElement()\n\t\t// Track streams\n\t\tlet remoteStream: MediaStream | null = null\n\t\tpc.ontrack = (e) => {\n\t\t\tremoteStream = e.streams[0]\n\t\t\taudioElement.srcObject = remoteStream\n\t\t\tdebugLog('WebRTC', 'Remote audio stream received and connected to audio element', {\n\t\t\t\tstreamId: remoteStream.id,\n\t\t\t\ttracks: remoteStream.getTracks().length,\n\t\t\t})\n\t\t}\n\n\t\t// Add microphone\n\t\tconst localStream = await this.getUserMedia()\n\t\tdebugLog('WebRTC', 'Local microphone stream acquired', {\n\t\t\tstreamId: localStream.id,\n\t\t\ttracks: localStream.getTracks().map((t) => ({\n\t\t\t\tkind: t.kind,\n\t\t\t\tenabled: t.enabled,\n\t\t\t\tmuted: t.muted,\n\t\t\t\treadyState: t.readyState,\n\t\t\t})),\n\t\t})\n\n\t\tlocalStream.getTracks().forEach((track) => {\n\t\t\tpc.addTrack(track, localStream)\n\t\t})\n\n\t\t// Create data channel for events\n\t\tconst dataChannel = pc.createDataChannel('oai-events')\n\n\t\t// Create offer and establish connection\n\t\tconst offer = await pc.createOffer()\n\t\tawait pc.setLocalDescription(offer)\n\n\t\t// Connect to OpenAI\n\t\tif (!offer.sdp) {\n\t\t\tthrow new Error('Failed to create offer SDP')\n\t\t}\n\t\tconst answer = await this.connectToOpenAI(apiUrl, model, offer.sdp, ephemeralKey)\n\t\tawait pc.setRemoteDescription(answer)\n\n\t\t// Create cleanup function\n\t\tconst cleanup = () => {\n\t\t\tlocalStream.getTracks().forEach((track) => {\n\t\t\t\ttrack.stop()\n\t\t\t})\n\t\t\taudioElement.remove()\n\t\t\tdataChannel.close()\n\t\t\tpc.close()\n\t\t}\n\n\t\treturn {\n\t\t\tpc,\n\t\t\tdataChannel,\n\t\t\taudioElement,\n\t\t\tlocalStream,\n\t\t\tremoteStream,\n\t\t\tcleanup,\n\t\t}\n\t}\n\n\tprivate async getEphemeralToken(model: string, voice: string): Promise<string> {\n\t\tconst response = await fetch(this.tokenEndpoint, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t},\n\t\t\tbody: JSON.stringify({ model, voice }),\n\t\t})\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text()\n\t\t\tconsole.error('Failed to get ephemeral token:', errorText)\n\t\t\tthrow new Error(`Failed to get ephemeral token: ${response.statusText}`)\n\t\t}\n\n\t\tconst data: unknown = await response.json()\n\n\t\tif (!hasClientSecret(data)) {\n\t\t\tthrow new Error('Invalid token response format')\n\t\t}\n\n\t\treturn data.client_secret.value\n\t}\n\n\tprivate createAudioElement(): HTMLAudioElement {\n\t\tconst audioElement = document.createElement('audio')\n\t\taudioElement.autoplay = true\n\t\taudioElement.style.display = 'none'\n\t\tdocument.body.appendChild(audioElement)\n\t\treturn audioElement\n\t}\n\n\tprivate async getUserMedia(): Promise<MediaStream> {\n\t\ttry {\n\t\t\treturn await navigator.mediaDevices.getUserMedia({\n\t\t\t\taudio: {\n\t\t\t\t\techoCancellation: true,\n\t\t\t\t\tnoiseSuppression: true,\n\t\t\t\t\tautoGainControl: true,\n\t\t\t\t},\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to access microphone: ${error}`)\n\t\t}\n\t}\n\n\tprivate async connectToOpenAI(\n\t\tbaseUrl: string,\n\t\tmodel: string,\n\t\tsdp: string,\n\t\tephemeralKey: string\n\t): Promise<RTCSessionDescriptionInit> {\n\t\tconst response = await fetch(`${baseUrl}?model=${model}`, {\n\t\t\tmethod: 'POST',\n\t\t\tbody: sdp,\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${ephemeralKey}`,\n\t\t\t\t'Content-Type': 'application/sdp',\n\t\t\t},\n\t\t})\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to establish WebRTC connection: ${response.statusText}`)\n\t\t}\n\n\t\tconst answerSdp = await response.text()\n\t\treturn {\n\t\t\ttype: 'answer' as const,\n\t\t\tsdp: answerSdp,\n\t\t}\n\t}\n}\n","import {\n\tAUDIO_FREQUENCY_BINS,\n\tAUDIO_VISUALIZATION_INTERVAL_MS,\n\tdebugLog,\n} from '../../lib/constants'\nimport { AudioAnalyzer } from './audio-analyzer'\nimport { EventEmitter } from './event-emitter'\nimport { MessageHandler } from './message-handler'\nimport { ToolManager } from './tool-manager'\nimport { WebRTCManager } from './webrtc-manager'\n\nimport type { RegisteredTool, ToolExecutor } from './tool-manager'\nimport type { EventCallback, RealtimeConfig, RealtimeSession, SessionConfig } from './types'\n\n/** Pre-allocated zero frequency array for performance */\nconst EMPTY_FREQUENCY_TEMPLATE = Object.freeze(new Array(AUDIO_FREQUENCY_BINS).fill(0))\nconst createZeroFrequencyArray = (): number[] => [...EMPTY_FREQUENCY_TEMPLATE]\n\n/**\n * OpenAI Realtime API Service\n *\n * Manages voice conversations with OpenAI's Realtime API,\n * including WebRTC connections, tool integration, and message handling.\n */\nexport class OpenAIRealtimeService {\n\tprivate session: RealtimeSession | null = null\n\tprivate webrtcManager: WebRTCManager\n\tprivate toolManager: ToolManager\n\tprivate messageHandler: MessageHandler\n\tprivate eventEmitter: EventEmitter\n\tprivate muted = false\n\tprivate lastState: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n\tprivate localAnalyzer: AudioAnalyzer | null = null\n\tprivate remoteAnalyzer: AudioAnalyzer | null = null\n\tprivate visualizationInterval: ReturnType<typeof setInterval> | null = null\n\tprivate sessionStartTime: number | null = null\n\tprivate onToolsChangedCallback: (() => void) | null = null\n\n\tconstructor(tokenEndpoint: string) {\n\t\tthis.webrtcManager = new WebRTCManager(tokenEndpoint)\n\t\tthis.toolManager = new ToolManager()\n\t\tthis.eventEmitter = new EventEmitter()\n\t\tthis.messageHandler = new MessageHandler(this.toolManager, this.eventEmitter)\n\t}\n\n\t/**\n\t * Set the tools available for the voice session\n\t */\n\tsetTools(tools: RegisteredTool[]): void {\n\t\tthis.toolManager.setTools(tools)\n\t\tif (this.isSessionActive()) {\n\t\t\tthis.updateSessionTools()\n\t\t}\n\t}\n\n\t/**\n\t * Set the tool executor function\n\t */\n\tsetToolExecutor(executor: ToolExecutor): void {\n\t\tthis.toolManager.setExecutor(executor)\n\t}\n\n\t/**\n\t * Register callback for when tools change\n\t */\n\tonToolsChanged(callback: () => void): void {\n\t\tthis.onToolsChangedCallback = callback\n\t}\n\n\t/**\n\t * Start a new realtime session\n\t */\n\tasync startSession(config: RealtimeConfig = {}): Promise<RealtimeSession> {\n\t\ttry {\n\t\t\t// Clean up existing session\n\t\t\tif (this.session) {\n\t\t\t\tthis.stopSession()\n\t\t\t}\n\n\t\t\tthis.muted = false\n\t\t\tthis.sessionStartTime = Date.now()\n\t\t\tthis.emitSessionState('connecting')\n\n\t\t\t// Create new WebRTC session\n\t\t\tthis.session = await this.webrtcManager.createSession(config)\n\n\t\t\t// Setup data channel handlers\n\t\t\tthis.setupDataChannel(this.session.dataChannel)\n\n\t\t\t// Monitor peer connection state\n\t\t\tthis.setupPeerConnectionMonitoring(this.session.pc)\n\n\t\t\tif (this.session.localStream) {\n\t\t\t\tawait this.initializeLocalAnalyzer(this.session.localStream)\n\t\t\t}\n\n\t\t\tif (this.session.remoteStream) {\n\t\t\t\tvoid this.initializeRemoteAnalyzer(this.session.remoteStream)\n\t\t\t}\n\n\t\t\t// Update session reference for remote stream\n\t\t\tconst originalOntrack = this.session.pc.ontrack\n\t\t\tconst session = this.session\n\t\t\tthis.session.pc.ontrack = (e) => {\n\t\t\t\tif (originalOntrack) originalOntrack.call(session.pc, e)\n\t\t\t\tif (this.session) {\n\t\t\t\t\tthis.session.remoteStream = e.streams[0]\n\t\t\t\t}\n\n\t\t\t\tconst remoteStream = e.streams[0]\n\t\t\t\tif (!remoteStream) {\n\t\t\t\t\tconsole.warn('[OpenAIRealtimeService] Received ontrack event without stream')\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvoid this.initializeRemoteAnalyzer(remoteStream)\n\t\t\t}\n\n\t\t\treturn this.session\n\t\t} catch (error) {\n\t\t\tthis.handleSessionError(error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Stop the current session\n\t */\n\tstopSession(): void {\n\t\t// Calculate session duration for usage tracking\n\t\tlet durationSeconds = 0\n\t\tif (this.sessionStartTime) {\n\t\t\tdurationSeconds = Math.floor((Date.now() - this.sessionStartTime) / 1000)\n\t\t}\n\n\t\tif (this.visualizationInterval) {\n\t\t\tclearInterval(this.visualizationInterval)\n\t\t\tthis.visualizationInterval = null\n\t\t}\n\n\t\tif (this.localAnalyzer) {\n\t\t\tthis.localAnalyzer.destroy()\n\t\t\tthis.localAnalyzer = null\n\t\t}\n\n\t\tif (this.remoteAnalyzer) {\n\t\t\tthis.remoteAnalyzer.destroy()\n\t\t\tthis.remoteAnalyzer = null\n\t\t}\n\t\tif (this.session) {\n\t\t\tthis.session.cleanup()\n\t\t\tthis.session = null\n\t\t}\n\t\tthis.messageHandler.reset()\n\t\tthis.toolManager.resetSession()\n\n\t\t// Emit disconnected state with session duration\n\t\tthis.muted = false\n\t\tthis.emitSessionState('disconnected', { durationSeconds })\n\n\t\t// Reset session start time\n\t\tthis.sessionStartTime = null\n\t}\n\n\t/**\n\t * Send a text message to the assistant\n\t */\n\tsendUserMessage(text: string): void {\n\t\tif (!this.isSessionActive()) {\n\t\t\tthrow new Error('No active session')\n\t\t}\n\n\t\tconst message = {\n\t\t\ttype: 'conversation.item.create',\n\t\t\titem: {\n\t\t\t\ttype: 'message',\n\t\t\t\trole: 'user',\n\t\t\t\tcontent: [{ type: 'input_text', text }],\n\t\t\t},\n\t\t}\n\n\t\tif (!this.session) {\n\t\t\tthrow new Error('Session is not active')\n\t\t}\n\t\tthis.session.dataChannel.send(JSON.stringify(message))\n\t\tthis.session.dataChannel.send(JSON.stringify({ type: 'response.create' }))\n\t}\n\n\t/**\n\t * Check if session is active\n\t */\n\tisSessionActive(): boolean {\n\t\treturn this.session !== null && this.session.dataChannel.readyState === 'open'\n\t}\n\n\t/**\n\t * Get the local audio stream\n\t */\n\tgetLocalStream(): MediaStream | null {\n\t\treturn this.session?.localStream || null\n\t}\n\n\t/**\n\t * Get the remote audio stream\n\t */\n\tgetRemoteStream(): MediaStream | null {\n\t\treturn this.session?.remoteStream || null\n\t}\n\n\t/**\n\t * Toggle audio mute\n\t */\n\ttoggleMute(muted: boolean): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.muted = muted\n\t\t}\n\t\tthis.muted = muted\n\t\tthis.emitSessionState(this.lastState, { isMuted: this.muted })\n\t}\n\n\t/**\n\t * Pause audio playback (for approval flow)\n\t * This pauses the audio element without stopping the WebRTC stream.\n\t */\n\tpauseAudio(): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.pause()\n\t\t}\n\t}\n\n\t/**\n\t * Resume audio playback (after approval flow)\n\t */\n\tresumeAudio(): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.play().catch((error) => {\n\t\t\t\t// Handle autoplay restrictions gracefully\n\t\t\t\tconsole.warn('[OpenAIRealtimeService] Failed to resume audio:', error)\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Event handling\n\t */\n\ton(event: string, callback: EventCallback): void {\n\t\tthis.eventEmitter.on(event, callback)\n\t}\n\n\toff(event: string, callback: EventCallback): void {\n\t\tthis.eventEmitter.off(event, callback)\n\t}\n\n\tgetSessionStatus(): {\n\t\tstate: 'connecting' | 'connected' | 'disconnected' | 'error'\n\t\tisActive: boolean\n\t\tisMuted: boolean\n\t} {\n\t\treturn {\n\t\t\tstate: this.lastState,\n\t\t\tisActive: this.lastState === 'connected',\n\t\t\tisMuted: this.muted,\n\t\t}\n\t}\n\n\t/**\n\t * Private methods\n\t */\n\tprivate setupDataChannel(dataChannel: RTCDataChannel): void {\n\t\t// Configure session when channel opens\n\t\tdataChannel.addEventListener('open', () => {\n\t\t\tthis.configureSession(dataChannel)\n\t\t\tthis.muted = false\n\t\t\tthis.emitSessionState('connected')\n\t\t})\n\n\t\t// Handle incoming messages\n\t\tdataChannel.addEventListener('message', (event: MessageEvent<string>) => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.messageHandler.handleMessage(event.data, dataChannel)\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Error handling message:', error)\n\t\t\t\t}\n\t\t\t})()\n\t\t})\n\n\t\t// Handle errors\n\t\tdataChannel.addEventListener('error', (error) => {\n\t\t\tconsole.error('DataChannel error:', error)\n\t\t\tthis.eventEmitter.emit('error', { type: 'datachannel_error', error })\n\t\t})\n\n\t\t// Handle close\n\t\tdataChannel.addEventListener('close', () => {\n\t\t\tthis.messageHandler.reset()\n\t\t\tthis.eventEmitter.emit('session_closed', {})\n\t\t})\n\t}\n\n\tprivate setupPeerConnectionMonitoring(pc: RTCPeerConnection): void {\n\t\t// Monitor connection state changes\n\t\tpc.addEventListener('connectionstatechange', () => {\n\t\t\tif (pc.connectionState === 'failed' || pc.connectionState === 'disconnected') {\n\t\t\t\tconsole.error('Peer connection failed or disconnected')\n\t\t\t\tthis.messageHandler.reset()\n\t\t\t\tthis.eventEmitter.emit('error', {\n\t\t\t\t\ttype: 'connection_error',\n\t\t\t\t\tmessage: `Connection ${pc.connectionState}`,\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\t// Monitor ICE connection state\n\t\tpc.addEventListener('iceconnectionstatechange', () => {\n\t\t\tif (pc.iceConnectionState === 'failed' || pc.iceConnectionState === 'disconnected') {\n\t\t\t\tconsole.error('ICE connection failed or disconnected')\n\t\t\t}\n\t\t})\n\n\t\t// Monitor signaling state\n\t\tpc.addEventListener('signalingstatechange', () => {})\n\t}\n\n\tprivate configureSession(dataChannel: RTCDataChannel): void {\n\t\t// Reset per-session state\n\t\tthis.toolManager.resetSession()\n\n\t\t// Get initial tools\n\t\tconst tools = this.toolManager.formatToolsForOpenAI()\n\t\t// Mark tools as sent\n\t\tthis.toolManager.markToolsSent()\n\n\t\tconst sessionConfig: SessionConfig = {\n\t\t\tmodalities: ['text', 'audio'],\n\t\t\tinstructions: this.getSessionInstructions(),\n\t\t\tvoice: 'echo',\n\t\t\ttools: tools,\n\t\t\ttool_choice: 'auto',\n\t\t\tturn_detection: {\n\t\t\t\ttype: 'server_vad',\n\t\t\t\tthreshold: 0.5,\n\t\t\t\tprefix_padding_ms: 300,\n\t\t\t\tsilence_duration_ms: 500,\n\t\t\t},\n\t\t\tinput_audio_transcription: {\n\t\t\t\tmodel: 'whisper-1',\n\t\t\t},\n\t\t}\n\n\t\tconst sessionUpdate = {\n\t\t\ttype: 'session.update',\n\t\t\tsession: sessionConfig,\n\t\t}\n\n\t\tdataChannel.send(JSON.stringify(sessionUpdate))\n\t}\n\n\tprivate updateSessionTools(): void {\n\t\tif (!this.session) {\n\t\t\tconsole.warn('[OpenAIRealtimeService] Cannot update tools: no active session')\n\t\t\treturn\n\t\t}\n\n\t\tif (this.session.dataChannel.readyState !== 'open') {\n\t\t\tconsole.warn(\n\t\t\t\t`[OpenAIRealtimeService] Cannot update tools: DataChannel is ${this.session.dataChannel.readyState}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\t// Check if tools have actually changed\n\t\tconst changesSummary = this.toolManager.getChangesSummary()\n\t\tif (!changesSummary) {\n\t\t\treturn\n\t\t}\n\n\t\t// Get the full tool list\n\t\tconst tools = this.toolManager.formatToolsForOpenAI()\n\n\t\tconsole.log(\n\t\t\t'[OpenAIRealtimeService] Sending tool update to OpenAI:',\n\t\t\t`${changesSummary.total} total tools,`,\n\t\t\tchangesSummary.added.length > 0\n\t\t\t\t? `+${changesSummary.added.length} added (${changesSummary.added.slice(0, 3).join(', ')}${changesSummary.added.length > 3 ? '...' : ''})`\n\t\t\t\t: '',\n\t\t\tchangesSummary.removed.length > 0 ? `-${changesSummary.removed.length} removed` : ''\n\t\t)\n\n\t\t// Mark tools as sent\n\t\tthis.toolManager.markToolsSent()\n\n\t\tconst sessionUpdate = {\n\t\t\ttype: 'session.update',\n\t\t\tsession: {\n\t\t\t\ttools: tools,\n\t\t\t\ttool_choice: 'auto',\n\t\t\t},\n\t\t}\n\n\t\tthis.session.dataChannel.send(JSON.stringify(sessionUpdate))\n\t}\n\n\tprivate getSessionInstructions(): string {\n\t\treturn `You are a helpful assistant with access to tools.\n Use the available tools to help users with their tasks.\n You can use the list_available_tools function to see what tools are currently available.\n Be concise and helpful in your responses.`\n\t}\n\n\tprivate handleSessionError(error: unknown): void {\n\t\tconsole.error('Session error:', error)\n\t\tthis.emitSessionState('error', {\n\t\t\ttype: 'session_error',\n\t\t\terror: String(error),\n\t\t})\n\t\tthis.stopSession()\n\t}\n\n\tprivate async initializeLocalAnalyzer(stream: MediaStream): Promise<void> {\n\t\tif (this.localAnalyzer) {\n\t\t\tthis.localAnalyzer.destroy()\n\t\t}\n\n\t\tthis.localAnalyzer = new AudioAnalyzer()\n\t\ttry {\n\t\t\t// Clone the stream to avoid conflicts with WebRTC which consumes the original\n\t\t\tconst clonedStream = new MediaStream(stream.getAudioTracks().map((t) => t.clone()))\n\t\t\tawait this.localAnalyzer.initialize(clonedStream)\n\t\t\tthis.startAudioVisualization()\n\t\t} catch (error) {\n\t\t\tconsole.error('[OpenAIRealtimeService] Failed to initialize local audio analyzer', error)\n\t\t\tif (this.localAnalyzer) {\n\t\t\t\tthis.localAnalyzer.destroy()\n\t\t\t\tthis.localAnalyzer = null\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async initializeRemoteAnalyzer(stream: MediaStream): Promise<void> {\n\t\tif (this.remoteAnalyzer) {\n\t\t\tthis.remoteAnalyzer.destroy()\n\t\t}\n\n\t\tthis.remoteAnalyzer = new AudioAnalyzer()\n\t\ttry {\n\t\t\t// Clone the stream to avoid conflicts with WebRTC\n\t\t\tconst clonedStream = new MediaStream(stream.getAudioTracks().map((t) => t.clone()))\n\t\t\tawait this.remoteAnalyzer.initialize(clonedStream)\n\t\t\tthis.startAudioVisualization()\n\t\t} catch (error) {\n\t\t\tconsole.error('[OpenAIRealtimeService] Failed to initialize remote audio analyzer', error)\n\t\t\tif (this.remoteAnalyzer) {\n\t\t\t\tthis.remoteAnalyzer.destroy()\n\t\t\t\tthis.remoteAnalyzer = null\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startAudioVisualization(): void {\n\t\tif (!this.localAnalyzer && !this.remoteAnalyzer) {\n\t\t\tdebugLog('OpenAIRealtimeService', 'Audio visualization not started: no analyzers ready')\n\t\t\treturn\n\t\t}\n\n\t\tif (this.visualizationInterval) {\n\t\t\tclearInterval(this.visualizationInterval)\n\t\t}\n\n\t\tlet logCounter = 0\n\t\tthis.visualizationInterval = setInterval(() => {\n\t\t\tconst micLevel = this.localAnalyzer?.getAudioLevel() ?? 0\n\t\t\tconst micFrequency =\n\t\t\t\tthis.localAnalyzer?.getFrequencyData(AUDIO_FREQUENCY_BINS) ?? createZeroFrequencyArray()\n\t\t\tconst speakerLevel = this.remoteAnalyzer?.getAudioLevel() ?? 0\n\t\t\tconst speakerFrequency =\n\t\t\t\tthis.remoteAnalyzer?.getFrequencyData(AUDIO_FREQUENCY_BINS) ?? createZeroFrequencyArray()\n\n\t\t\t// Log audio levels periodically for debugging (every ~1 second)\n\t\t\tlogCounter++\n\t\t\tif (logCounter % 60 === 0) {\n\t\t\t\tdebugLog('OpenAIRealtimeService', 'Audio levels', {\n\t\t\t\t\tmic: micLevel.toFixed(3),\n\t\t\t\t\tspeaker: speakerLevel.toFixed(3),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis.eventEmitter.emit('audio_level', {\n\t\t\t\tmicLevel,\n\t\t\t\tmicFrequency,\n\t\t\t\tspeakerLevel,\n\t\t\t\tspeakerFrequency,\n\t\t\t})\n\t\t}, AUDIO_VISUALIZATION_INTERVAL_MS)\n\t}\n\n\tprivate emitSessionState(\n\t\tstate: 'connecting' | 'connected' | 'disconnected' | 'error',\n\t\textra: Record<string, unknown> = {}\n\t): void {\n\t\tthis.lastState = state\n\t\tconst payload = {\n\t\t\tstate,\n\t\t\tisActive: state === 'connected',\n\t\t\tisMuted: this.muted,\n\t\t\t...extra,\n\t\t}\n\n\t\tthis.eventEmitter.emit('session_state', payload)\n\n\t\tswitch (state) {\n\t\t\tcase 'connecting':\n\t\t\t\tthis.eventEmitter.emit('session_connecting', payload)\n\t\t\t\tbreak\n\t\t\tcase 'connected':\n\t\t\t\tthis.eventEmitter.emit('session_connected', payload)\n\t\t\t\tbreak\n\t\t\tcase 'disconnected':\n\t\t\t\tthis.eventEmitter.emit('session_closed', payload)\n\t\t\t\tbreak\n\t\t\tcase 'error':\n\t\t\t\tthis.eventEmitter.emit('error', payload)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Re-export types for convenience\nexport type { RealtimeConfig, RealtimeSession } from './types'\n","/**\n * Types for OpenAI Realtime API integration\n */\n\nexport interface RealtimeConfig {\n\tmodel?: string\n\tvoice?: string\n\tapiUrl?: string\n\ttokenEndpoint?: string\n}\n\nexport interface RealtimeSession {\n\tpc: RTCPeerConnection\n\tdataChannel: RTCDataChannel\n\taudioElement: HTMLAudioElement\n\tlocalStream: MediaStream | null\n\tremoteStream: MediaStream | null\n\tcleanup: () => void\n}\n\nexport interface OpenAITool {\n\ttype: 'function'\n\tname: string\n\tdescription: string\n\tparameters: {\n\t\ttype: string\n\t\tproperties?: Record<string, unknown>\n\t\trequired?: string[]\n\t}\n}\n\nexport interface SessionConfig {\n\tmodalities: string[]\n\tinstructions: string\n\tvoice?: string\n\ttools: OpenAITool[]\n\ttool_choice: string\n\tturn_detection: {\n\t\ttype: string\n\t\tthreshold: number\n\t\tprefix_padding_ms: number\n\t\tsilence_duration_ms: number\n\t}\n\tinput_audio_transcription?: {\n\t\tmodel: string\n\t}\n}\n\nexport interface FunctionCall {\n\tname: string\n\targuments: string\n\tcall_id: string\n\ttype?: string\n\tstatus?: string\n}\n\nexport interface ConversationItem {\n\ttype: string\n\trole?: string\n\tcontent?: unknown[]\n\tcall_id?: string\n\toutput?: string\n}\n\nexport interface RealtimeMessage {\n\ttype: string\n\t[key: string]: unknown\n}\n\nexport interface ToolExecutionResult {\n\tsuccess: boolean\n\tdata?: unknown\n\terror?: string\n}\n\nexport type EventCallback = (data: unknown) => void\n\nexport interface IEventEmitter {\n\ton(event: string, callback: EventCallback): void\n\toff(event: string, callback: EventCallback): void\n\temit(event: string, data: unknown): void\n}\n\nexport interface AudioLevelData {\n\tmicLevel: number\n\tmicFrequency: number[]\n\tspeakerLevel: number\n\tspeakerFrequency: number[]\n}\n\nexport interface TranscriptData {\n\ttype: 'user' | 'assistant'\n\ttext: string\n\tisDone: boolean\n}\n\nexport interface ToolCallData {\n\tstatus: 'started' | 'completed'\n\ttoolName: string\n\terror?: string\n}\n\nexport interface VoiceModeState {\n\tisActive: boolean\n\tisConnecting: boolean\n\tisMuted: boolean\n\tisError: boolean\n\tconnectionState: string\n\taudioLevel?: AudioLevelData\n\ttranscript?: TranscriptData\n\ttoolCall?: ToolCallData\n\terror?: string\n}\n\n// ============================================================================\n// Event Data Types - For type-safe event handling\n// ============================================================================\n\n/**\n * Session state event data from the realtime service\n */\nexport interface SessionStateEventData {\n\tstate: 'connecting' | 'connected' | 'disconnected' | 'error'\n\tisActive: boolean\n\tisMuted: boolean\n\tdurationSeconds?: number\n}\n\n/**\n * User transcript event data\n */\nexport interface UserTranscriptEventData {\n\ttext: string\n}\n\n/**\n * Assistant transcript streaming event data\n */\nexport interface AssistantTranscriptEventData {\n\tdelta?: string\n\ttranscript?: string\n}\n\n/**\n * Tool call started event data\n */\nexport interface ToolCallStartedEventData {\n\tname: string\n}\n\n/**\n * Tool call completed event data\n */\nexport interface ToolCallCompletedEventData {\n\tname: string\n\terror?: string\n}\n\n/**\n * Nested error object from OpenAI Realtime API\n */\nexport interface NestedErrorObject {\n\tcode?: string\n\tmessage?: string\n\tparam?: string\n\tevent_id?: string | null\n\ttype?: string\n}\n\n/**\n * Error event data\n * The 'error' field can be either a string or a nested error object from OpenAI\n */\nexport interface ErrorEventData {\n\terror?: string | NestedErrorObject\n\tmessage?: string\n\ttype?: string\n}\n\n// ============================================================================\n// Type Guards - Runtime type checking for event data\n// ============================================================================\n\n/**\n * Type guard for SessionStateEventData\n */\nexport function isSessionStateEventData(data: unknown): data is SessionStateEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn (\n\t\ttypeof d.state === 'string' &&\n\t\t['connecting', 'connected', 'disconnected', 'error'].includes(d.state) &&\n\t\ttypeof d.isActive === 'boolean' &&\n\t\ttypeof d.isMuted === 'boolean'\n\t)\n}\n\n/**\n * Type guard for UserTranscriptEventData\n */\nexport function isUserTranscriptEventData(data: unknown): data is UserTranscriptEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.text === 'string'\n}\n\n/**\n * Type guard for AssistantTranscriptEventData\n */\nexport function isAssistantTranscriptEventData(\n\tdata: unknown\n): data is AssistantTranscriptEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn d.delta === undefined || typeof d.delta === 'string'\n}\n\n/**\n * Type guard for ToolCallStartedEventData\n */\nexport function isToolCallStartedEventData(data: unknown): data is ToolCallStartedEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.name === 'string'\n}\n\n/**\n * Type guard for ToolCallCompletedEventData\n */\nexport function isToolCallCompletedEventData(data: unknown): data is ToolCallCompletedEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.name === 'string'\n}\n\n/**\n * Type guard for ErrorEventData\n */\nexport function isErrorEventData(data: unknown): data is ErrorEventData {\n\tif (!data || typeof data !== 'object') return false\n\t// Error events must have at least one of these fields\n\tconst d = data as Record<string, unknown>\n\t// error can be a string OR an object with a message\n\tconst hasError = typeof d.error === 'string' || (typeof d.error === 'object' && d.error !== null)\n\treturn hasError || typeof d.message === 'string' || typeof d.type === 'string'\n}\n\n/**\n * Extract a string error message from ErrorEventData.\n * Handles both string errors and nested error objects from OpenAI Realtime API.\n */\nexport function extractErrorMessage(data: ErrorEventData): string {\n\t// Handle nested error object (OpenAI Realtime API format)\n\tif (data.error && typeof data.error === 'object') {\n\t\tconst nestedError = data.error as NestedErrorObject\n\t\treturn nestedError.message || nestedError.code || 'Unknown error'\n\t}\n\n\t// Handle string error\n\tif (typeof data.error === 'string') {\n\t\treturn data.error\n\t}\n\n\t// Fallback to message field\n\tif (typeof data.message === 'string') {\n\t\treturn data.message\n\t}\n\n\treturn 'Unknown error'\n}\n\n/**\n * Type guard for AudioLevelData\n */\nexport function isAudioLevelData(data: unknown): data is AudioLevelData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn (\n\t\ttypeof d.micLevel === 'number' &&\n\t\tArray.isArray(d.micFrequency) &&\n\t\ttypeof d.speakerLevel === 'number' &&\n\t\tArray.isArray(d.speakerFrequency)\n\t)\n}\n","/**\n * Voice Mode Hook\n *\n * Manages OpenAI Realtime API voice sessions with WebRTC.\n * Provides audio level streaming, transcript events, and tool call tracking.\n *\n * @example Basic usage\n * ```tsx\n * const {\n * isActive,\n * startSession,\n * stopSession,\n * toggleMute\n * } = useVoiceMode({\n * tokenEndpoint: '/api/realtime/session'\n * })\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport {\n\tTOOL_CALL_DISPLAY_DURATION_MS,\n\tTOOL_CALL_ERROR_DISPLAY_DURATION_MS,\n} from '../lib/constants'\nimport {\n\textractErrorMessage,\n\tisAssistantTranscriptEventData,\n\tisAudioLevelData,\n\tisErrorEventData,\n\tisSessionStateEventData,\n\tisToolCallCompletedEventData,\n\tisToolCallStartedEventData,\n\tisUserTranscriptEventData,\n\tOpenAIRealtimeService,\n} from '../services/realtime'\n\nimport type {\n\tAudioLevelData,\n\tRealtimeConfig,\n\tRegisteredTool,\n\tToolCallData,\n\tToolExecutor,\n\tTranscriptData,\n\tVoiceModeState,\n} from '../services/realtime'\n\nexport interface UseVoiceModeOptions {\n\t/** Endpoint to get ephemeral tokens from */\n\ttokenEndpoint: string\n\t/** Tools available for the voice session */\n\ttools?: RegisteredTool[]\n\t/** Tool executor function */\n\ttoolExecutor?: ToolExecutor\n\t/** Callback when session connects */\n\tonConnect?: () => void\n\t/** Callback when session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when error occurs */\n\tonError?: (error: string) => void\n\t/** Callback when user transcript is complete */\n\tonUserTranscript?: (text: string) => void\n\t/** Callback when assistant transcript is complete */\n\tonAssistantTranscript?: (text: string) => void\n}\n\nexport interface UseVoiceModeReturn extends VoiceModeState {\n\t/** Start voice session */\n\tstartSession: (config?: RealtimeConfig) => Promise<void>\n\t/** Stop voice session */\n\tstopSession: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send text message while in voice mode */\n\tsendMessage: (text: string) => void\n\t/** Pause audio playback (for approval flow) */\n\tpauseAudio: () => void\n\t/** Resume audio playback (after approval flow) */\n\tresumeAudio: () => void\n}\n\nexport function useVoiceMode(options: UseVoiceModeOptions): UseVoiceModeReturn {\n\tconst {\n\t\ttokenEndpoint,\n\t\ttools,\n\t\ttoolExecutor,\n\t\tonConnect,\n\t\tonDisconnect,\n\t\tonError,\n\t\tonUserTranscript,\n\t\tonAssistantTranscript,\n\t} = options\n\n\t// State\n\tconst [isActive, setIsActive] = useState(false)\n\tconst [isConnecting, setIsConnecting] = useState(false)\n\tconst [isMuted, setIsMuted] = useState(false)\n\tconst [isError, setIsError] = useState(false)\n\tconst [connectionState, setConnectionState] = useState('disconnected')\n\tconst [audioLevel, setAudioLevel] = useState<AudioLevelData | undefined>()\n\tconst [transcript, setTranscript] = useState<TranscriptData | undefined>()\n\tconst [toolCall, setToolCall] = useState<ToolCallData | undefined>()\n\tconst [error, setError] = useState<string | undefined>()\n\n\t// Service ref\n\tconst serviceRef = useRef<OpenAIRealtimeService | null>(null)\n\n\t// Callbacks refs to avoid stale closures\n\tconst onConnectRef = useRef(onConnect)\n\tconst onDisconnectRef = useRef(onDisconnect)\n\tconst onErrorRef = useRef(onError)\n\tconst onUserTranscriptRef = useRef(onUserTranscript)\n\tconst onAssistantTranscriptRef = useRef(onAssistantTranscript)\n\n\tuseEffect(() => {\n\t\tonConnectRef.current = onConnect\n\t\tonDisconnectRef.current = onDisconnect\n\t\tonErrorRef.current = onError\n\t\tonUserTranscriptRef.current = onUserTranscript\n\t\tonAssistantTranscriptRef.current = onAssistantTranscript\n\t}, [onConnect, onDisconnect, onError, onUserTranscript, onAssistantTranscript])\n\n\t// Get or create service instance\n\tconst getService = useCallback(() => {\n\t\tif (!serviceRef.current) {\n\t\t\tserviceRef.current = new OpenAIRealtimeService(tokenEndpoint)\n\t\t}\n\t\treturn serviceRef.current\n\t}, [tokenEndpoint])\n\n\t// Update tools when they change\n\tuseEffect(() => {\n\t\tif (tools) {\n\t\t\tconst service = getService()\n\t\t\tservice.setTools(tools)\n\t\t}\n\t}, [tools, getService])\n\n\t// Update tool executor when it changes\n\tuseEffect(() => {\n\t\tif (toolExecutor) {\n\t\t\tconst service = getService()\n\t\t\tservice.setToolExecutor(toolExecutor)\n\t\t}\n\t}, [toolExecutor, getService])\n\n\t// Set up event listeners\n\tuseEffect(() => {\n\t\tconst service = getService()\n\n\t\t// Session state handler - uses type guard for safe access\n\t\tconst handleSessionState = (data: unknown) => {\n\t\t\tif (!isSessionStateEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid session state event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tsetConnectionState(data.state)\n\t\t\tsetIsActive(data.isActive)\n\t\t\tsetIsMuted(data.isMuted)\n\t\t\tsetIsConnecting(data.state === 'connecting')\n\t\t\tsetIsError(data.state === 'error')\n\n\t\t\tif (data.state === 'connected') {\n\t\t\t\tonConnectRef.current?.()\n\t\t\t} else if (data.state === 'disconnected') {\n\t\t\t\tonDisconnectRef.current?.(data.durationSeconds ?? 0)\n\t\t\t}\n\t\t}\n\n\t\t// Audio level handler - uses type guard for safe access\n\t\tconst handleAudioLevel = (data: unknown) => {\n\t\t\tif (isAudioLevelData(data)) {\n\t\t\t\tsetAudioLevel(data)\n\t\t\t}\n\t\t}\n\n\t\t// User transcript handler - uses type guard for safe access\n\t\tconst handleUserTranscript = (data: unknown) => {\n\t\t\tif (!isUserTranscriptEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid user transcript event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetTranscript({ type: 'user', text: data.text, isDone: true })\n\t\t\tonUserTranscriptRef.current?.(data.text)\n\t\t}\n\n\t\t// Assistant transcript handler (streaming) - uses type guard for safe access\n\t\tconst handleAssistantTranscript = (data: unknown) => {\n\t\t\tif (!isAssistantTranscriptEventData(data)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst text = data.delta || data.transcript || ''\n\t\t\tsetTranscript((prev) => ({\n\t\t\t\ttype: 'assistant',\n\t\t\t\ttext: prev?.type === 'assistant' ? prev.text + text : text,\n\t\t\t\tisDone: false,\n\t\t\t}))\n\t\t}\n\n\t\t// Assistant transcript done handler - uses type guard for safe access\n\t\tconst handleAssistantTranscriptDone = (data: unknown) => {\n\t\t\tif (!isAssistantTranscriptEventData(data)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst text = data.transcript || ''\n\t\t\tsetTranscript({ type: 'assistant', text, isDone: true })\n\t\t\tonAssistantTranscriptRef.current?.(text)\n\t\t}\n\n\t\t// Tool call started handler - uses type guard for safe access\n\t\tconst handleToolCallStarted = (data: unknown) => {\n\t\t\tif (!isToolCallStartedEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid tool call started event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetToolCall({ status: 'started', toolName: data.name })\n\t\t}\n\n\t\t// Tool call completed handler - uses type guard for safe access\n\t\tconst handleToolCallCompleted = (data: unknown) => {\n\t\t\tif (!isToolCallCompletedEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid tool call completed event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetToolCall({ status: 'completed', toolName: data.name, error: data.error })\n\n\t\t\t// Clear tool call after a delay (longer for errors)\n\t\t\tsetTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tsetToolCall(undefined)\n\t\t\t\t},\n\t\t\t\tdata.error ? TOOL_CALL_ERROR_DISPLAY_DURATION_MS : TOOL_CALL_DISPLAY_DURATION_MS\n\t\t\t)\n\t\t}\n\n\t\t// Error handler - uses type guard for safe access\n\t\tconst handleError = (data: unknown) => {\n\t\t\tif (!isErrorEventData(data)) {\n\t\t\t\tsetError('Unknown error')\n\t\t\t\tsetIsError(true)\n\t\t\t\tonErrorRef.current?.('Unknown error')\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Use extractErrorMessage to handle both string and nested object errors\n\t\t\tconst errorMsg = extractErrorMessage(data)\n\t\t\tsetError(errorMsg)\n\t\t\tsetIsError(true)\n\t\t\tonErrorRef.current?.(errorMsg)\n\t\t}\n\n\t\t// Register listeners\n\t\tservice.on('session_state', handleSessionState)\n\t\tservice.on('audio_level', handleAudioLevel)\n\t\tservice.on('user_transcript_done', handleUserTranscript)\n\t\tservice.on('assistant_transcript', handleAssistantTranscript)\n\t\tservice.on('assistant_transcript_done', handleAssistantTranscriptDone)\n\t\tservice.on('tool_call_started', handleToolCallStarted)\n\t\tservice.on('tool_call_completed', handleToolCallCompleted)\n\t\tservice.on('error', handleError)\n\n\t\t// Cleanup\n\t\treturn () => {\n\t\t\tservice.off('session_state', handleSessionState)\n\t\t\tservice.off('audio_level', handleAudioLevel)\n\t\t\tservice.off('user_transcript_done', handleUserTranscript)\n\t\t\tservice.off('assistant_transcript', handleAssistantTranscript)\n\t\t\tservice.off('assistant_transcript_done', handleAssistantTranscriptDone)\n\t\t\tservice.off('tool_call_started', handleToolCallStarted)\n\t\t\tservice.off('tool_call_completed', handleToolCallCompleted)\n\t\t\tservice.off('error', handleError)\n\t\t}\n\t}, [getService])\n\n\t// Start session\n\tconst startSession = useCallback(\n\t\tasync (config?: RealtimeConfig) => {\n\t\t\ttry {\n\t\t\t\tsetIsConnecting(true)\n\t\t\t\tsetIsError(false)\n\t\t\t\tsetError(undefined)\n\n\t\t\t\tconst service = getService()\n\t\t\t\tawait service.startSession(config)\n\t\t\t} catch (err) {\n\t\t\t\tsetIsConnecting(false)\n\t\t\t\tsetIsError(true)\n\t\t\t\tconst errorMsg = err instanceof Error ? err.message : 'Failed to start session'\n\t\t\t\tsetError(errorMsg)\n\t\t\t\tonErrorRef.current?.(errorMsg)\n\t\t\t}\n\t\t},\n\t\t[getService]\n\t)\n\n\t// Stop session\n\tconst stopSession = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.stopSession()\n\t\tsetAudioLevel(undefined)\n\t\tsetTranscript(undefined)\n\t\tsetToolCall(undefined)\n\t}, [getService])\n\n\t// Toggle mute\n\tconst toggleMute = useCallback(\n\t\t(muted?: boolean) => {\n\t\t\tconst service = getService()\n\t\t\tconst newMuted = muted !== undefined ? muted : !isMuted\n\t\t\tservice.toggleMute(newMuted)\n\t\t\tsetIsMuted(newMuted)\n\t\t},\n\t\t[getService, isMuted]\n\t)\n\n\t// Send message\n\tconst sendMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tconst service = getService()\n\t\t\tif (service.isSessionActive()) {\n\t\t\t\tservice.sendUserMessage(text)\n\t\t\t}\n\t\t},\n\t\t[getService]\n\t)\n\n\t// Pause audio (for approval flow)\n\tconst pauseAudio = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.pauseAudio()\n\t}, [getService])\n\n\t// Resume audio (after approval flow)\n\tconst resumeAudio = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.resumeAudio()\n\t}, [getService])\n\n\t// Memoize return value\n\treturn useMemo(\n\t\t() => ({\n\t\t\tisActive,\n\t\t\tisConnecting,\n\t\t\tisMuted,\n\t\t\tisError,\n\t\t\tconnectionState,\n\t\t\taudioLevel,\n\t\t\ttranscript,\n\t\t\ttoolCall,\n\t\t\terror,\n\t\t\tstartSession,\n\t\t\tstopSession,\n\t\t\ttoggleMute,\n\t\t\tsendMessage,\n\t\t\tpauseAudio,\n\t\t\tresumeAudio,\n\t\t}),\n\t\t[\n\t\t\tisActive,\n\t\t\tisConnecting,\n\t\t\tisMuted,\n\t\t\tisError,\n\t\t\tconnectionState,\n\t\t\taudioLevel,\n\t\t\ttranscript,\n\t\t\ttoolCall,\n\t\t\terror,\n\t\t\tstartSession,\n\t\t\tstopSession,\n\t\t\ttoggleMute,\n\t\t\tsendMessage,\n\t\t\tpauseAudio,\n\t\t\tresumeAudio,\n\t\t]\n\t)\n}\n","import { createContext, useContext, useMemo } from 'react'\n\nimport { useVoiceMode } from '../hooks/useVoiceMode'\n\nimport type { ReactNode } from 'react'\nimport type { UseVoiceModeReturn } from '../hooks/useVoiceMode'\nimport type { RegisteredTool, ToolExecutor } from '../services/realtime'\n\n/**\n * Voice Mode Provider\n *\n * Provides voice mode state and controls to the component tree.\n */\n\nexport interface VoiceModeContextValue extends UseVoiceModeReturn {\n\tisSupported: boolean\n}\n\nconst VoiceModeContext = createContext<VoiceModeContextValue | null>(null)\n\nexport interface VoiceModeProviderProps {\n\tchildren: ReactNode\n\t/** Backend endpoint for ephemeral tokens */\n\ttokenEndpoint: string\n\t/** Tools available for voice mode */\n\ttools?: RegisteredTool[]\n\t/** Tool executor function */\n\ttoolExecutor?: ToolExecutor\n\t/** Callback when session connects */\n\tonConnect?: () => void\n\t/** Callback when session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when error occurs */\n\tonError?: (error: string) => void\n\t/** Callback when user transcript is complete */\n\tonUserTranscript?: (text: string) => void\n\t/** Callback when assistant transcript is complete */\n\tonAssistantTranscript?: (text: string) => void\n}\n\n/**\n * Check if the browser supports WebRTC and getUserMedia\n */\nfunction checkVoiceModeSupport(): boolean {\n\treturn !!(\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.RTCPeerConnection &&\n\t\tnavigator.mediaDevices?.getUserMedia\n\t)\n}\n\nexport function VoiceModeProvider({\n\tchildren,\n\ttokenEndpoint,\n\ttools,\n\ttoolExecutor,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n\tonUserTranscript,\n\tonAssistantTranscript,\n}: VoiceModeProviderProps) {\n\tconst voiceMode = useVoiceMode({\n\t\ttokenEndpoint,\n\t\ttools,\n\t\ttoolExecutor,\n\t\tonConnect,\n\t\tonDisconnect,\n\t\tonError,\n\t\tonUserTranscript,\n\t\tonAssistantTranscript,\n\t})\n\n\tconst isSupported = useMemo(() => checkVoiceModeSupport(), [])\n\n\tconst value = useMemo(\n\t\t() => ({\n\t\t\t...voiceMode,\n\t\t\tisSupported,\n\t\t}),\n\t\t[voiceMode, isSupported]\n\t)\n\n\treturn <VoiceModeContext.Provider value={value}>{children}</VoiceModeContext.Provider>\n}\n\n/**\n * Hook to access voice mode context\n */\nexport function useVoiceModeContext(): VoiceModeContextValue {\n\tconst context = useContext(VoiceModeContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceModeContext must be used within a VoiceModeProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice mode context (returns null if not in provider)\n */\nexport function useOptionalVoiceModeContext(): VoiceModeContextValue | null {\n\treturn useContext(VoiceModeContext)\n}\n","/**\n * Voice Tool Approval Provider\n *\n * Manages tool approval state for voice mode. When a destructive tool is called\n * during a voice session, this provider pauses execution and waits for the user\n * to approve or deny (via voice keywords or button tap).\n *\n * Key features:\n * - 30-second timeout with auto-deny (safe default)\n * - Support for both voice keyword detection and button tap\n * - Single pending approval at a time (voice mode is sequential)\n *\n * @example\n * ```tsx\n * <VoiceToolApprovalProvider>\n * <VoiceMode />\n * </VoiceToolApprovalProvider>\n *\n * // In a component:\n * const { pendingApproval, approve, deny, requestApproval } = useVoiceToolApproval()\n * ```\n */\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS, VOICE_APPROVAL_TIMEOUT_MS } from '../lib/constants'\n\nimport type { FC, ReactNode } from 'react'\n\n/**\n * Pending approval request\n */\nexport interface VoicePendingApproval {\n\t/** Unique call ID from OpenAI Realtime */\n\tcallId: string\n\t/** Name of the tool being requested */\n\ttoolName: string\n\t/** Arguments passed to the tool */\n\targs: Record<string, unknown>\n\t/** Timestamp when approval was requested */\n\ttimestamp: number\n}\n\n/**\n * Voice Tool Approval Context Value\n */\nexport interface VoiceToolApprovalContextValue {\n\t/** Current pending approval (null if none) */\n\tpendingApproval: VoicePendingApproval | null\n\t/** Approve the current pending tool call */\n\tapprove: () => void\n\t/** Deny the current pending tool call */\n\tdeny: () => void\n\t/** Seconds remaining before auto-deny */\n\ttimeoutRemaining: number\n\t/** Whether we're currently waiting for approval */\n\tisWaitingForApproval: boolean\n\t/**\n\t * Request approval for a tool call.\n\t * Returns a Promise that resolves to true (approved) or false (denied/timeout).\n\t */\n\trequestApproval: (\n\t\tcallId: string,\n\t\ttoolName: string,\n\t\targs: Record<string, unknown>\n\t) => Promise<boolean>\n\t/** Clear any pending approval without resolving (e.g., when voice session ends) */\n\tclearPendingApproval: () => void\n}\n\nconst VoiceToolApprovalContext = createContext<VoiceToolApprovalContextValue | null>(null)\n\nexport interface VoiceToolApprovalProviderProps {\n\tchildren: ReactNode\n\t/** Custom timeout in milliseconds (defaults to VOICE_APPROVAL_TIMEOUT_MS) */\n\ttimeout?: number\n\t/** Callback when approval times out */\n\tonTimeout?: (toolName: string) => void\n\t/** Callback when user approves */\n\tonApprove?: (toolName: string) => void\n\t/** Callback when user denies */\n\tonDeny?: (toolName: string) => void\n}\n\n/**\n * Provider for voice mode tool approval.\n *\n * Wraps voice mode components to enable approval workflow for destructive tools.\n */\nexport const VoiceToolApprovalProvider: FC<VoiceToolApprovalProviderProps> = ({\n\tchildren,\n\ttimeout = VOICE_APPROVAL_TIMEOUT_MS,\n\tonTimeout,\n\tonApprove,\n\tonDeny,\n}) => {\n\t// Current pending approval\n\tconst [pendingApproval, setPendingApproval] = useState<VoicePendingApproval | null>(null)\n\n\t// Time remaining for countdown\n\tconst [timeoutRemaining, setTimeoutRemaining] = useState(0)\n\n\t// Refs for the resolve function and timeout\n\tconst resolveRef = useRef<((approved: boolean) => void) | null>(null)\n\tconst timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\tconst countdownIdRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n\t// Callback refs to avoid stale closures\n\tconst onTimeoutRef = useRef(onTimeout)\n\tconst onApproveRef = useRef(onApprove)\n\tconst onDenyRef = useRef(onDeny)\n\tonTimeoutRef.current = onTimeout\n\tonApproveRef.current = onApprove\n\tonDenyRef.current = onDeny\n\n\t/**\n\t * Clear all timers\n\t */\n\tconst clearTimers = useCallback(() => {\n\t\tif (timeoutIdRef.current) {\n\t\t\tclearTimeout(timeoutIdRef.current)\n\t\t\ttimeoutIdRef.current = null\n\t\t}\n\t\tif (countdownIdRef.current) {\n\t\t\tclearInterval(countdownIdRef.current)\n\t\t\tcountdownIdRef.current = null\n\t\t}\n\t}, [])\n\n\t/**\n\t * Resolve the pending approval and clean up\n\t */\n\tconst resolveApproval = useCallback(\n\t\t(approved: boolean, reason: 'approve' | 'deny' | 'timeout' = approved ? 'approve' : 'deny') => {\n\t\t\tconst toolName = pendingApproval?.toolName\n\n\t\t\t// Resolve the promise\n\t\t\tif (resolveRef.current) {\n\t\t\t\tresolveRef.current(approved)\n\t\t\t\tresolveRef.current = null\n\t\t\t}\n\n\t\t\t// Clear state\n\t\t\tclearTimers()\n\t\t\tsetPendingApproval(null)\n\t\t\tsetTimeoutRemaining(0)\n\n\t\t\t// Fire callbacks\n\t\t\tif (toolName) {\n\t\t\t\tif (reason === 'timeout') {\n\t\t\t\t\tonTimeoutRef.current?.(toolName)\n\t\t\t\t} else if (reason === 'approve') {\n\t\t\t\t\tonApproveRef.current?.(toolName)\n\t\t\t\t} else {\n\t\t\t\t\tonDenyRef.current?.(toolName)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[pendingApproval?.toolName, clearTimers]\n\t)\n\n\t/**\n\t * Approve the current pending tool call\n\t */\n\tconst approve = useCallback(() => {\n\t\tif (pendingApproval) {\n\t\t\tresolveApproval(true, 'approve')\n\t\t}\n\t}, [pendingApproval, resolveApproval])\n\n\t/**\n\t * Deny the current pending tool call\n\t */\n\tconst deny = useCallback(() => {\n\t\tif (pendingApproval) {\n\t\t\tresolveApproval(false, 'deny')\n\t\t}\n\t}, [pendingApproval, resolveApproval])\n\n\t/**\n\t * Clear pending approval without resolving (for cleanup)\n\t */\n\tconst clearPendingApproval = useCallback(() => {\n\t\tif (resolveRef.current) {\n\t\t\tresolveRef.current(false)\n\t\t\tresolveRef.current = null\n\t\t}\n\t\tclearTimers()\n\t\tsetPendingApproval(null)\n\t\tsetTimeoutRemaining(0)\n\t}, [clearTimers])\n\n\t/**\n\t * Request approval for a tool call.\n\t * Returns a Promise that resolves when the user approves/denies or timeout occurs.\n\t */\n\tconst requestApproval = useCallback(\n\t\t(callId: string, toolName: string, args: Record<string, unknown>): Promise<boolean> => {\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\t// If there's already a pending approval, deny it first\n\t\t\t\tif (resolveRef.current) {\n\t\t\t\t\tresolveRef.current(false)\n\t\t\t\t}\n\t\t\t\tclearTimers()\n\n\t\t\t\t// Store the resolve function\n\t\t\t\tresolveRef.current = resolve\n\n\t\t\t\t// Set pending approval state\n\t\t\t\tsetPendingApproval({\n\t\t\t\t\tcallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\targs,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t})\n\n\t\t\t\t// Set initial timeout remaining\n\t\t\t\tconst timeoutSeconds = Math.ceil(timeout / 1000)\n\t\t\t\tsetTimeoutRemaining(timeoutSeconds)\n\n\t\t\t\t// Start countdown interval\n\t\t\t\tcountdownIdRef.current = setInterval(() => {\n\t\t\t\t\tsetTimeoutRemaining((prev) => {\n\t\t\t\t\t\tif (prev <= 1) {\n\t\t\t\t\t\t\treturn 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn prev - 1\n\t\t\t\t\t})\n\t\t\t\t}, VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS)\n\n\t\t\t\t// Set auto-deny timeout\n\t\t\t\ttimeoutIdRef.current = setTimeout(() => {\n\t\t\t\t\t// Auto-deny on timeout\n\t\t\t\t\tif (resolveRef.current) {\n\t\t\t\t\t\tresolveRef.current(false)\n\t\t\t\t\t\tresolveRef.current = null\n\t\t\t\t\t}\n\t\t\t\t\tclearTimers()\n\t\t\t\t\tsetPendingApproval(null)\n\t\t\t\t\tsetTimeoutRemaining(0)\n\t\t\t\t\tonTimeoutRef.current?.(toolName)\n\t\t\t\t}, timeout)\n\t\t\t})\n\t\t},\n\t\t[timeout, clearTimers]\n\t)\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclearTimers()\n\t\t\tif (resolveRef.current) {\n\t\t\t\tresolveRef.current(false)\n\t\t\t\tresolveRef.current = null\n\t\t\t}\n\t\t}\n\t}, [clearTimers])\n\n\tconst value = useMemo<VoiceToolApprovalContextValue>(\n\t\t() => ({\n\t\t\tpendingApproval,\n\t\t\tapprove,\n\t\t\tdeny,\n\t\t\ttimeoutRemaining,\n\t\t\tisWaitingForApproval: pendingApproval !== null,\n\t\t\trequestApproval,\n\t\t\tclearPendingApproval,\n\t\t}),\n\t\t[pendingApproval, approve, deny, timeoutRemaining, requestApproval, clearPendingApproval]\n\t)\n\n\treturn (\n\t\t<VoiceToolApprovalContext.Provider value={value}>{children}</VoiceToolApprovalContext.Provider>\n\t)\n}\n\n/**\n * Hook to access voice tool approval context.\n * @throws Error if used outside VoiceToolApprovalProvider\n */\nexport function useVoiceToolApproval(): VoiceToolApprovalContextValue {\n\tconst context = useContext(VoiceToolApprovalContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceToolApproval must be used within a VoiceToolApprovalProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice tool approval context.\n * Returns null if not within provider.\n */\nexport function useOptionalVoiceToolApproval(): VoiceToolApprovalContextValue | null {\n\treturn useContext(VoiceToolApprovalContext)\n}\n","/**\n * VoiceThreadBridge\n *\n * Bridges voice mode events to the assistant-ui thread.\n * When voice transcripts and tool calls occur, they are pushed into the thread\n * as real messages, making assistant-ui the single source of truth.\n *\n * This replaces the separate voice state tracking (useVoiceActions, useVoiceSummary)\n * with unified thread state.\n *\n * Voice messages are tagged with metadata to distinguish them from text messages:\n * - metadata.source: 'voice'\n * - metadata.voiceSessionId: unique session identifier\n *\n * Tool calls from voice mode are also added to the thread with full metadata\n * (timing, source attribution) matching the text mode behavior.\n */\n\nimport { useThread, useThreadRuntime } from '@assistant-ui/react'\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { VOICE_TOOL_RESULT_MESSAGES } from '../lib/constants'\nimport { TOOL_DENIED_MESSAGE } from '../lib/format'\nimport {\n\tgetPendingToolCallsByName,\n\tresolveAllPendingToolCalls,\n\tresolveAllPendingToolCallsByName,\n\tresolvePendingToolCall,\n} from '../lib/thread-utils'\nimport { useOptionalMCPTools } from './MCPToolsProvider'\nimport { useOptionalToolApproval } from './ToolApprovalProvider'\nimport { useOptionalVoiceModeContext, VoiceModeProvider } from './VoiceModeProvider'\nimport {\n\tuseOptionalVoiceToolApproval,\n\tVoiceToolApprovalProvider,\n} from './VoiceToolApprovalProvider'\n\nimport type { ToolCallMetadata, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { FC, MutableRefObject, ReactNode } from 'react'\nimport type { RegisteredTool, ToolExecutor } from '../services/realtime'\n\n/**\n * Data needed to add a voice tool call to the thread\n */\ninterface VoiceToolCallData {\n\ttoolCallId: string\n\ttoolName: string\n\targs: Record<string, unknown>\n\tresult: string\n\tisError: boolean\n\tartifact: ToolCallMetadata\n}\n\n/**\n * Callback type for adding tool calls to thread\n */\ntype AddToolCallToThread = (data: VoiceToolCallData) => void\n\n/**\n * Voice session metadata attached to messages\n */\nexport interface VoiceMessageMetadata {\n\tsource: 'voice'\n\tvoiceSessionId: string\n\ttimestamp: number\n}\n\n/**\n * Voice thread context - provides voice controls and current session info\n */\nexport interface VoiceThreadContextValue {\n\t/** Whether a voice session is active */\n\tisActive: boolean\n\t/** Whether voice is connecting */\n\tisConnecting: boolean\n\t/** Whether there's a voice error */\n\tisError: boolean\n\t/** Whether microphone is muted */\n\tisMuted: boolean\n\t/** Whether voice mode is supported in this browser */\n\tisSupported: boolean\n\t/** Current error message */\n\terror?: string\n\t/** Current voice session ID (null if no active session) */\n\tsessionId: string | null\n\t/** Start a voice session */\n\tstart: () => Promise<void>\n\t/** Stop the voice session */\n\tstop: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send a text message in voice mode */\n\tsendMessage: (text: string) => void\n\t/** Pause audio playback (for approval flow) */\n\tpauseAudio: () => void\n\t/** Resume audio playback (after approval flow) */\n\tresumeAudio: () => void\n\t/** Audio level data for visualization */\n\taudioLevel?: {\n\t\tmicLevel: number\n\t\tspeakerLevel: number\n\t}\n\t/** Current transcript being spoken */\n\ttranscript?: {\n\t\ttype: 'user' | 'assistant'\n\t\ttext: string\n\t\tisDone: boolean\n\t}\n\t/** Current tool call being executed */\n\ttoolCall?: {\n\t\tstatus: 'started' | 'completed'\n\t\ttoolName: string\n\t\terror?: string\n\t}\n}\n\nconst VoiceThreadContext = createContext<VoiceThreadContextValue | null>(null)\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n\treturn `voice-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Convert MCP tools to the format expected by the voice service\n */\nfunction convertToRegisteredTool(tool: ToolWithSource): RegisteredTool {\n\treturn {\n\t\tname: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tinputSchema: (tool.inputSchema ?? { type: 'object', properties: {} }) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>,\n\t}\n}\n\nexport interface VoiceThreadBridgeProps {\n\tchildren: ReactNode\n\t/** Token endpoint for voice sessions */\n\ttokenEndpoint: string\n\t/** Callback when voice session connects */\n\tonConnect?: () => void\n\t/** Callback when voice session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when voice error occurs */\n\tonError?: (error: string) => void\n}\n\n/**\n * Internal component that bridges voice events to the thread.\n * Must be used inside both VoiceModeProvider and AssistantRuntimeProvider.\n */\nconst VoiceThreadIntegrator: FC<{\n\tchildren: ReactNode\n\tsessionId: string | null\n\tsetSessionId: (id: string | null) => void\n\taddToolCallRef: MutableRefObject<AddToolCallToThread | null>\n\tonConnect?: () => void\n\tonDisconnect?: (durationSeconds: number) => void\n\tonError?: (error: string) => void\n}> = ({ children, sessionId, setSessionId, addToolCallRef, onConnect, onDisconnect, onError }) => {\n\tconst threadRuntime = useThreadRuntime()\n\tconst voiceMode = useOptionalVoiceModeContext()\n\n\t// Track last transcript to detect changes\n\tconst lastUserTranscriptRef = useRef<string>('')\n\tconst lastAssistantTranscriptRef = useRef<string>('')\n\tconst wasActiveRef = useRef(false)\n\n\t// Refs for callbacks\n\tconst onConnectRef = useRef(onConnect)\n\tconst onDisconnectRef = useRef(onDisconnect)\n\tconst onErrorRef = useRef(onError)\n\tonConnectRef.current = onConnect\n\tonDisconnectRef.current = onDisconnect\n\tonErrorRef.current = onError\n\n\t/**\n\t * Set up the callback for adding tool calls to thread.\n\t * This is called by toolExecutor when a voice tool call completes.\n\t */\n\tuseEffect(() => {\n\t\taddToolCallRef.current = (data: VoiceToolCallData) => {\n\t\t\tif (!sessionId) {\n\t\t\t\tconsole.warn('[VoiceThreadIntegrator] Cannot add tool call - no active session')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Append complete tool-call message to thread\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool-call',\n\t\t\t\t\t\ttoolCallId: data.toolCallId,\n\t\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\t\targs: data.args,\n\t\t\t\t\t\targsText: JSON.stringify(data.args),\n\t\t\t\t\t\tresult: data.result,\n\t\t\t\t\t\tisError: data.isError,\n\t\t\t\t\t\tartifact: data.artifact,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tmetadata: {\n\t\t\t\t\tcustom: {\n\t\t\t\t\t\tsource: 'voice',\n\t\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t} as any)\n\t\t}\n\n\t\treturn () => {\n\t\t\taddToolCallRef.current = null\n\t\t}\n\t}, [threadRuntime, sessionId, addToolCallRef])\n\n\t/**\n\t * Add a user message to the thread (from voice transcript)\n\t */\n\tconst addUserMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tif (!sessionId || !text.trim()) return\n\n\t\t\t// Use custom metadata for voice messages\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst metadata: any = {\n\t\t\t\tcustom: {\n\t\t\t\t\tsource: 'voice',\n\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'user',\n\t\t\t\tcontent: [{ type: 'text', text }],\n\t\t\t\tmetadata,\n\t\t\t})\n\t\t},\n\t\t[threadRuntime, sessionId]\n\t)\n\n\t/**\n\t * Add an assistant message to the thread (from voice transcript)\n\t */\n\tconst addAssistantMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tif (!sessionId || !text.trim()) return\n\n\t\t\t// Use custom metadata for voice messages\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst metadata: any = {\n\t\t\t\tcustom: {\n\t\t\t\t\tsource: 'voice',\n\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: [{ type: 'text', text }],\n\t\t\t\tmetadata,\n\t\t\t})\n\t\t},\n\t\t[threadRuntime, sessionId]\n\t)\n\n\t// Track session state changes\n\tuseEffect(() => {\n\t\tif (!voiceMode) return\n\n\t\tconst isActive = voiceMode.isActive || voiceMode.isConnecting\n\n\t\t// Session just started\n\t\tif (!wasActiveRef.current && isActive && !sessionId) {\n\t\t\tconst newSessionId = generateSessionId()\n\t\t\tsetSessionId(newSessionId)\n\t\t}\n\n\t\t// Session just connected\n\t\tif (!wasActiveRef.current && voiceMode.isActive) {\n\t\t\tonConnectRef.current?.()\n\t\t}\n\n\t\t// Session just ended\n\t\tif (wasActiveRef.current && !isActive) {\n\t\t\t// Add final assistant message if we have one\n\t\t\t// CRITICAL: Clear refs immediately after use to prevent race condition with transcript effect\n\t\t\t// Both effects can fire in the same render cycle, causing duplicate message IDs\n\t\t\tif (lastAssistantTranscriptRef.current) {\n\t\t\t\taddAssistantMessage(lastAssistantTranscriptRef.current)\n\t\t\t\tlastAssistantTranscriptRef.current = ''\n\t\t\t}\n\t\t\tlastUserTranscriptRef.current = ''\n\n\t\t\t// Clear any remaining pending thread elicitations to prevent duplicate approval UI\n\t\t\tresolveAllPendingToolCalls(threadRuntime, VOICE_TOOL_RESULT_MESSAGES.sessionEnded)\n\n\t\t\t// Clear session\n\t\t\tsetSessionId(null)\n\n\t\t\t// Notify disconnect (duration is not easily available here, use 0)\n\t\t\tonDisconnectRef.current?.(0)\n\t\t}\n\n\t\twasActiveRef.current = isActive\n\t}, [\n\t\tvoiceMode?.isActive,\n\t\tvoiceMode?.isConnecting,\n\t\tsessionId,\n\t\tsetSessionId,\n\t\taddAssistantMessage,\n\t\tthreadRuntime,\n\t])\n\n\t// Track transcript changes and push to thread\n\tuseEffect(() => {\n\t\tif (!voiceMode?.transcript || !sessionId) return\n\n\t\tconst { type, text, isDone } = voiceMode.transcript\n\n\t\tif (type === 'user' && isDone && text !== lastUserTranscriptRef.current) {\n\t\t\t// If we had a pending assistant message, add it first to maintain order\n\t\t\tif (lastAssistantTranscriptRef.current) {\n\t\t\t\taddAssistantMessage(lastAssistantTranscriptRef.current)\n\t\t\t\tlastAssistantTranscriptRef.current = ''\n\t\t\t}\n\n\t\t\t// User finished speaking - add to thread\n\t\t\taddUserMessage(text)\n\t\t\tlastUserTranscriptRef.current = text\n\t\t} else if (type === 'assistant' && isDone && text !== lastAssistantTranscriptRef.current) {\n\t\t\t// Store assistant transcript - we'll add it to thread when:\n\t\t\t// 1. User speaks next (to maintain conversation order)\n\t\t\t// 2. Session ends\n\t\t\tlastAssistantTranscriptRef.current = text\n\t\t}\n\t}, [voiceMode?.transcript, sessionId, addUserMessage, addAssistantMessage])\n\n\t// Track errors\n\tuseEffect(() => {\n\t\tif (voiceMode?.isError && voiceMode?.error) {\n\t\t\tonErrorRef.current?.(voiceMode.error)\n\t\t}\n\t}, [voiceMode?.isError, voiceMode?.error])\n\n\treturn <>{children}</>\n}\n\n/**\n * Inner component that creates the approval-aware tool executor.\n * Must be inside VoiceToolApprovalProvider to access the approval context.\n */\nconst ApprovalAwareVoiceBridge: FC<{\n\tchildren: ReactNode\n\ttokenEndpoint: string\n\tvoiceTools: RegisteredTool[]\n\tsessionId: string | null\n\tsetSessionId: (id: string | null) => void\n\taddToolCallRef: MutableRefObject<AddToolCallToThread | null>\n\tonConnect?: () => void\n\tonDisconnect?: (durationSeconds: number) => void\n\tonError?: (error: string) => void\n}> = ({\n\tchildren,\n\ttokenEndpoint,\n\tvoiceTools,\n\tsessionId,\n\tsetSessionId,\n\taddToolCallRef,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst mcpTools = useOptionalMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\tconst voiceToolApproval = useOptionalVoiceToolApproval()\n\tconst threadRuntime = useThreadRuntime()\n\tconst threadMessages = useThread((t) => t.messages)\n\n\t// Track voice approval decisions keyed by tool name with a queue of decisions\n\t// so multiple approvals for the same tool don't collide when replaying.\n\tconst pendingVoiceResolutions = useRef<Map<string, Array<{ result: string; timestamp: number }>>>(\n\t\tnew Map()\n\t)\n\tconst VOICE_RESOLUTION_TTL_MS = 30_000\n\n\t// Tool executor that routes to MCP with approval checking\n\tconst toolExecutor: ToolExecutor = useCallback(\n\t\tasync (name: string, args: Record<string, unknown>) => {\n\t\t\tif (!mcpTools?.callTool) {\n\t\t\t\tthrow new Error('MCP tools not available')\n\t\t\t}\n\n\t\t\t// Check if tool requires approval\n\t\t\tconst tool = mcpTools.tools.find((t) => t.name === name)\n\t\t\tconst needsApproval = tool && toolApproval?.requiresApproval(tool)\n\n\t\t\tif (needsApproval && voiceToolApproval) {\n\t\t\t\t// Generate a call ID for this approval request\n\t\t\t\tconst callId = `voice-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n\n\t\t\t\t// Request approval and wait for response\n\t\t\t\tconst approved = await voiceToolApproval.requestApproval(callId, name, args)\n\n\t\t\t\t// Sync voice approval to thread to prevent duplicate approval UI in text mode\n\t\t\t\tconst resultMessage = approved ? VOICE_TOOL_RESULT_MESSAGES.handled : TOOL_DENIED_MESSAGE\n\t\t\t\tconst resolvedNow = resolveAllPendingToolCallsByName(threadRuntime, name, resultMessage)\n\n\t\t\t\t// If nothing was resolved (pending call hasn't reached the thread yet), remember it\n\t\t\t\t// so we can auto-resolve when the pending tool-call message appears.\n\t\t\t\tif (resolvedNow === 0) {\n\t\t\t\t\tconst queue = pendingVoiceResolutions.current.get(name) ?? []\n\t\t\t\t\tqueue.push({ result: resultMessage, timestamp: Date.now() })\n\t\t\t\t\tpendingVoiceResolutions.current.set(name, queue)\n\t\t\t\t}\n\n\t\t\t\tif (!approved) {\n\t\t\t\t\t// User denied or timeout - return denial message\n\t\t\t\t\treturn TOOL_DENIED_MESSAGE\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Execute the tool\n\t\t\tconst result = await mcpTools.callTool(name, args)\n\n\t\t\t// Extract text content from MCP result\n\t\t\tconst textContent = result.content?.find(\n\t\t\t\t(c: { type: string; text?: string }): c is { type: 'text'; text: string } =>\n\t\t\t\t\tc.type === 'text'\n\t\t\t)\n\t\t\treturn textContent?.text ?? JSON.stringify(result)\n\t\t},\n\t\t[mcpTools, toolApproval, voiceToolApproval, threadRuntime]\n\t)\n\n\t// Apply queued voice approvals once the thread emits matching pending tool calls.\n\tuseEffect(() => {\n\t\tif (pendingVoiceResolutions.current.size === 0) return\n\n\t\tconst now = Date.now()\n\t\tfor (const [toolName, queue] of [...pendingVoiceResolutions.current.entries()]) {\n\t\t\tconst freshQueue = queue.filter(({ timestamp }) => now - timestamp <= VOICE_RESOLUTION_TTL_MS)\n\t\t\tif (freshQueue.length === 0) {\n\t\t\t\tpendingVoiceResolutions.current.delete(toolName)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst pendingCalls = getPendingToolCallsByName(threadRuntime, toolName)\n\n\t\t\t// Resolve approvals in FIFO order against pending calls\n\t\t\tlet queueIndex = 0\n\t\t\tfor (const call of pendingCalls) {\n\t\t\t\tif (queueIndex >= freshQueue.length) break\n\t\t\t\tconst { result } = freshQueue[queueIndex]\n\t\t\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\t\t\tqueueIndex++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (queueIndex >= freshQueue.length) {\n\t\t\t\tpendingVoiceResolutions.current.delete(toolName)\n\t\t\t} else {\n\t\t\t\tpendingVoiceResolutions.current.set(toolName, freshQueue.slice(queueIndex))\n\t\t\t}\n\t\t}\n\t}, [threadMessages, threadRuntime])\n\n\treturn (\n\t\t<VoiceModeProvider tokenEndpoint={tokenEndpoint} tools={voiceTools} toolExecutor={toolExecutor}>\n\t\t\t<VoiceThreadIntegrator\n\t\t\t\tsessionId={sessionId}\n\t\t\t\tsetSessionId={setSessionId}\n\t\t\t\taddToolCallRef={addToolCallRef}\n\t\t\t\tonConnect={onConnect}\n\t\t\t\tonDisconnect={onDisconnect}\n\t\t\t\tonError={onError}\n\t\t\t>\n\t\t\t\t<VoiceThreadContextProvider sessionId={sessionId}>{children}</VoiceThreadContextProvider>\n\t\t\t</VoiceThreadIntegrator>\n\t\t</VoiceModeProvider>\n\t)\n}\n\n/**\n * Bridge component that integrates voice mode with the assistant-ui thread.\n *\n * When voice events occur:\n * 1. User transcripts are added as user messages to the thread\n * 2. Assistant transcripts are added as assistant messages\n * 3. Tool calls are added as tool-call parts with full metadata (timing, source)\n * This ensures the thread is the single source of truth for all conversation history,\n * including tool calls from voice mode with the same metadata as text mode.\n *\n * Voice tool approval:\n * When a destructive tool is called during voice mode, the VoiceToolApprovalProvider\n * pauses execution and shows an approval UI. User can approve via voice keywords\n * (\"approve\", \"yes\") or by tapping buttons.\n */\nexport const VoiceThreadBridge: FC<VoiceThreadBridgeProps> = ({\n\tchildren,\n\ttokenEndpoint,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst mcpTools = useOptionalMCPTools()\n\n\t// Session ID managed at this level so it persists across voice mode restarts\n\tconst [sessionId, setSessionId] = useState<string | null>(null)\n\n\t// Ref for adding tool calls to thread (set by VoiceThreadIntegrator)\n\tconst addToolCallRef = useRef<AddToolCallToThread | null>(null)\n\n\t// Convert MCP tools for voice mode\n\tconst voiceTools = useMemo<RegisteredTool[]>(() => {\n\t\tif (!mcpTools?.tools) return []\n\t\treturn mcpTools.tools.map(convertToRegisteredTool)\n\t}, [mcpTools?.tools])\n\n\treturn (\n\t\t<VoiceToolApprovalProvider>\n\t\t\t<ApprovalAwareVoiceBridge\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tvoiceTools={voiceTools}\n\t\t\t\tsessionId={sessionId}\n\t\t\t\tsetSessionId={setSessionId}\n\t\t\t\taddToolCallRef={addToolCallRef}\n\t\t\t\tonConnect={onConnect}\n\t\t\t\tonDisconnect={onDisconnect}\n\t\t\t\tonError={onError}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</ApprovalAwareVoiceBridge>\n\t\t</VoiceToolApprovalProvider>\n\t)\n}\n\n/**\n * Internal provider that exposes voice thread context\n */\nconst VoiceThreadContextProvider: FC<{ children: ReactNode; sessionId: string | null }> = ({\n\tchildren,\n\tsessionId,\n}) => {\n\tconst voiceMode = useOptionalVoiceModeContext()\n\n\t// Build context value from voice mode\n\tconst contextValue = useMemo<VoiceThreadContextValue | null>(() => {\n\t\tif (!voiceMode) return null\n\n\t\treturn {\n\t\t\tisActive: voiceMode.isActive,\n\t\t\tisConnecting: voiceMode.isConnecting,\n\t\t\tisError: voiceMode.isError,\n\t\t\tisMuted: voiceMode.isMuted,\n\t\t\tisSupported: voiceMode.isSupported,\n\t\t\terror: voiceMode.error,\n\t\t\tsessionId,\n\t\t\taudioLevel: voiceMode.audioLevel\n\t\t\t\t? {\n\t\t\t\t\t\tmicLevel: voiceMode.audioLevel.micLevel,\n\t\t\t\t\t\tspeakerLevel: voiceMode.audioLevel.speakerLevel,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\ttranscript: voiceMode.transcript\n\t\t\t\t? {\n\t\t\t\t\t\ttype: voiceMode.transcript.type,\n\t\t\t\t\t\ttext: voiceMode.transcript.text,\n\t\t\t\t\t\tisDone: voiceMode.transcript.isDone,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\ttoolCall: voiceMode.toolCall\n\t\t\t\t? {\n\t\t\t\t\t\tstatus: voiceMode.toolCall.status,\n\t\t\t\t\t\ttoolName: voiceMode.toolCall.toolName,\n\t\t\t\t\t\terror: voiceMode.toolCall.error,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tstart: voiceMode.startSession,\n\t\t\tstop: voiceMode.stopSession,\n\t\t\ttoggleMute: voiceMode.toggleMute,\n\t\t\tsendMessage: voiceMode.sendMessage,\n\t\t\tpauseAudio: voiceMode.pauseAudio,\n\t\t\tresumeAudio: voiceMode.resumeAudio,\n\t\t}\n\t}, [voiceMode, sessionId])\n\n\tif (!contextValue) {\n\t\treturn <>{children}</>\n\t}\n\n\treturn <VoiceThreadContext.Provider value={contextValue}>{children}</VoiceThreadContext.Provider>\n}\n\n/**\n * Hook to access voice thread controls\n * @throws Error if used outside VoiceThreadBridge\n */\nexport function useVoiceThread(): VoiceThreadContextValue {\n\tconst context = useContext(VoiceThreadContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceThread must be used within a VoiceThreadBridge')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice thread controls\n */\nexport function useOptionalVoiceThread(): VoiceThreadContextValue | null {\n\treturn useContext(VoiceThreadContext)\n}\n\n/**\n * Hook to check if voice mode is available and active\n */\nexport function useIsVoiceActive(): boolean {\n\tconst context = useOptionalVoiceThread()\n\treturn context?.isActive ?? false\n}\n","/**\n * useAgent - Unified Agent Hook\n *\n * The main hook for accessing agent state and capabilities.\n * This is a thin facade over assistant-ui's thread state.\n *\n * Thread state (messages, actions) comes from @assistant-ui/react.\n * Voice transcripts and tool calls are also stored in the thread\n * (via VoiceThreadBridge), making assistant-ui the single source of truth.\n *\n * @example Basic usage\n * ```tsx\n * function MyComponent() {\n * const agent = useAgent()\n *\n * return (\n * <div>\n * {agent.isRunning && <p>Processing...</p>}\n * {agent.messages.map(m => <Message key={m.id} {...m} />)}\n * {agent.voice?.isActive && <p>Voice active</p>}\n * </div>\n * )\n * }\n * ```\n */\n\nimport { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport { useLatestSummary } from '../../components/pill/SummaryBlock'\nimport {\n\tuseActions,\n\tuseCurrentAction,\n\tuseLastCompletedAction,\n\tuseRecentActions,\n} from '../../hooks/useActions'\nimport { useOptionalMCPTools } from '../../providers/MCPToolsProvider'\nimport { useOptionalVoiceThread } from '../../providers/VoiceThreadBridge'\n\nimport type { CallToolResult, Prompt, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { Action } from '../../hooks/useActions'\n\n/**\n * Voice mode state and controls\n */\nexport interface AgentVoice {\n\t/** Whether voice session is active */\n\tisActive: boolean\n\t/** Whether voice is connecting */\n\tisConnecting: boolean\n\t/** Whether there's an error */\n\tisError: boolean\n\t/** Whether microphone is muted */\n\tisMuted: boolean\n\t/** Whether voice mode is supported */\n\tisSupported: boolean\n\t/** Current error message */\n\terror?: string\n\t/** Current voice session ID */\n\tsessionId: string | null\n\t/** Audio level for visualization */\n\taudioLevel?: { micLevel: number; speakerLevel: number }\n\t/** Current transcript being spoken */\n\ttranscript?: { type: 'user' | 'assistant'; text: string; isDone: boolean }\n\t/** Start voice session */\n\tstart: () => Promise<void>\n\t/** Stop voice session */\n\tstop: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send text message while in voice mode */\n\tsendMessage: (text: string) => void\n}\n\n/**\n * MCP tools state and controls\n */\nexport interface AgentTools {\n\t/** All available tools */\n\tlist: ToolWithSource[]\n\t/** Call a tool by name */\n\tcall: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\t/** Available prompts */\n\tprompts: Prompt[]\n\t/** Get expanded prompt content */\n\tgetPrompt: ((name: string) => Promise<GetPromptResult>) | undefined\n}\n\n/**\n * Thread message type (simplified for external consumers)\n */\nexport interface AgentMessage {\n\tid: string\n\trole: 'user' | 'assistant' | 'system'\n\tcontent: readonly unknown[]\n\tstatus?: { type: string }\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tmetadata?: Record<string, any>\n}\n\n/**\n * Agent state and controls returned by useAgent\n */\nexport interface AgentState {\n\t// Thread state (from assistant-ui - single source of truth)\n\t/** All messages in the thread (includes both text and voice messages) */\n\tmessages: readonly AgentMessage[]\n\t/** Whether the agent is currently processing */\n\tisRunning: boolean\n\t/** Whether thread has any messages */\n\thasMessages: boolean\n\n\t// Actions (derived from thread messages - both text and voice)\n\t/** All actions derived from tool calls in the thread */\n\tactions: Action[]\n\t/** Currently running action (if any) */\n\tcurrentAction: Action | null\n\t/** Recently completed actions */\n\trecentActions: Action[]\n\t/** Last completed action (success or error) */\n\tlastCompletedAction: Action | null\n\n\t// Summary (derived from last assistant message)\n\t/** Summary text from the last assistant message */\n\tsummary: string | null\n\n\t// Voice mode (null if not configured)\n\tvoice: AgentVoice | null\n\n\t// MCP tools (null if not in MCP context)\n\ttools: AgentTools | null\n\n\t// Derived state\n\t/** Whether voice mode is currently active */\n\tisVoiceActive: boolean\n}\n\n/**\n * Main agent hook - provides unified access to all agent capabilities\n *\n * This is a thin facade over assistant-ui. All thread state comes from\n * the assistant-ui runtime, including voice messages (which are pushed\n * into the thread by VoiceThreadBridge).\n */\nexport function useAgent(): AgentState {\n\t// Thread state from assistant-ui (single source of truth)\n\tconst threadMessages = useThread((thread) => thread.messages)\n\tconst isRunning = useThread((thread) => thread.isRunning)\n\n\t// Actions derived from thread messages (includes both text and voice tool calls)\n\tconst actions = useActions()\n\tconst currentAction = useCurrentAction()\n\tconst recentActions = useRecentActions(3)\n\tconst lastCompletedAction = useLastCompletedAction()\n\n\t// Summary from last assistant message\n\tconst summary = useLatestSummary()\n\n\t// Voice controls from VoiceThreadBridge\n\tconst voiceThread = useOptionalVoiceThread()\n\n\t// MCP tools (optional - may not be in MCP context)\n\tconst mcpContext = useOptionalMCPTools()\n\n\t// Derived: is voice active\n\tconst isVoiceActive = !!(\n\t\tvoiceThread?.isActive ||\n\t\tvoiceThread?.isConnecting ||\n\t\tvoiceThread?.isError\n\t)\n\n\t// Has messages\n\tconst hasMessages = (threadMessages?.length ?? 0) > 0\n\n\t// Build voice interface\n\tconst voice: AgentVoice | null = useMemo(() => {\n\t\tif (!voiceThread) return null\n\n\t\treturn {\n\t\t\tisActive: voiceThread.isActive,\n\t\t\tisConnecting: voiceThread.isConnecting,\n\t\t\tisError: voiceThread.isError,\n\t\t\tisMuted: voiceThread.isMuted,\n\t\t\tisSupported: voiceThread.isSupported,\n\t\t\terror: voiceThread.error,\n\t\t\tsessionId: voiceThread.sessionId,\n\t\t\taudioLevel: voiceThread.audioLevel,\n\t\t\ttranscript: voiceThread.transcript,\n\t\t\tstart: voiceThread.start,\n\t\t\tstop: voiceThread.stop,\n\t\t\ttoggleMute: voiceThread.toggleMute,\n\t\t\tsendMessage: voiceThread.sendMessage,\n\t\t}\n\t}, [voiceThread])\n\n\t// Build tools interface\n\tconst tools: AgentTools | null = useMemo(() => {\n\t\tif (!mcpContext) return null\n\n\t\treturn {\n\t\t\tlist: mcpContext.tools,\n\t\t\tcall: mcpContext.callTool,\n\t\t\tprompts: mcpContext.prompts ?? [],\n\t\t\tgetPrompt: mcpContext.getPrompt,\n\t\t}\n\t}, [mcpContext])\n\n\t// Build the full agent state\n\treturn useMemo<AgentState>(\n\t\t() => ({\n\t\t\t// Thread (single source of truth)\n\t\t\tmessages: (threadMessages ?? []) as readonly AgentMessage[],\n\t\t\tisRunning,\n\t\t\thasMessages,\n\n\t\t\t// Actions (derived from thread)\n\t\t\tactions,\n\t\t\tcurrentAction,\n\t\t\trecentActions,\n\t\t\tlastCompletedAction,\n\n\t\t\t// Summary\n\t\t\tsummary,\n\n\t\t\t// Voice\n\t\t\tvoice,\n\n\t\t\t// Tools\n\t\t\ttools,\n\n\t\t\t// Derived\n\t\t\tisVoiceActive,\n\t\t}),\n\t\t[\n\t\t\tthreadMessages,\n\t\t\tisRunning,\n\t\t\thasMessages,\n\t\t\tactions,\n\t\t\tcurrentAction,\n\t\t\trecentActions,\n\t\t\tlastCompletedAction,\n\t\t\tsummary,\n\t\t\tvoice,\n\t\t\ttools,\n\t\t\tisVoiceActive,\n\t\t]\n\t)\n}\n","/**\n * AgentUIProvider\n *\n * Manages non-thread UI state that persists across thread switches.\n * This includes open/close status, pill mode, position, and unread indicators.\n *\n * Thread-level state (messages, tool calls, etc.) is managed by @assistant-ui/react.\n * This provider only handles UI-specific state that is independent of the current thread.\n *\n * @example Basic usage\n * ```tsx\n * import { AgentUIProvider, useAgentUI } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return (\n * <AgentUIProvider>\n * <MyComponent />\n * </AgentUIProvider>\n * )\n * }\n *\n * function MyComponent() {\n * const { isOpen, setOpen, userMode, setUserMode } = useAgentUI()\n * // ...\n * }\n * ```\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react'\n\nimport type { FC, ReactNode } from 'react'\n\n/** UI mode for the pill widget */\nexport type PillMode = 'collapsed' | 'hovered' | 'composing' | 'active' | 'expanded'\n\n/** Position for draggable elements */\nexport interface Position {\n\tx: number\n\ty: number\n}\n\n/**\n * Agent UI state - non-thread state that persists across sessions\n */\nexport interface AgentUIState {\n\t/** Whether the agent UI is open (modal or expanded pill) */\n\tisOpen: boolean\n\n\t/** Current pill mode */\n\tuserMode: PillMode\n\n\t/** Drag position offset for the pill */\n\tposition: Position\n\n\t/** Whether there are unread messages */\n\thasUnread: boolean\n\n\t/** Whether voice mode is currently active */\n\tisVoiceActive: boolean\n\n\t/** Whether the pill is in full-screen mode */\n\tisFullScreen: boolean\n}\n\n/**\n * Agent UI context value with state and actions\n */\nexport interface AgentUIContextValue extends AgentUIState {\n\t/** Set the open state */\n\tsetOpen: (open: boolean) => void\n\n\t/** Toggle the open state */\n\ttoggleOpen: () => void\n\n\t/** Set the pill mode */\n\tsetUserMode: (mode: PillMode) => void\n\n\t/** Set the drag position */\n\tsetPosition: (position: Position) => void\n\n\t/** Reset position to default */\n\tresetPosition: () => void\n\n\t/** Mark messages as read */\n\tmarkRead: () => void\n\n\t/** Mark messages as unread */\n\tmarkUnread: () => void\n\n\t/** Set voice active state */\n\tsetVoiceActive: (active: boolean) => void\n\n\t/** Collapse the pill to its default state */\n\tcollapse: () => void\n\n\t/** Expand the pill to composing mode */\n\texpand: () => void\n\n\t/** Enter full-screen mode */\n\tenterFullScreen: () => void\n\n\t/** Exit full-screen mode */\n\texitFullScreen: () => void\n\n\t/** Toggle full-screen mode */\n\ttoggleFullScreen: () => void\n}\n\nconst AgentUIContext = createContext<AgentUIContextValue | null>(null)\n\nconst DEFAULT_POSITION: Position = { x: 0, y: 0 }\n\nexport interface AgentUIProviderProps {\n\tchildren: ReactNode\n\n\t/** Initial open state (default: false) */\n\tdefaultOpen?: boolean\n\n\t/** Initial pill mode (default: 'collapsed') */\n\tdefaultMode?: PillMode\n\n\t/** Callback when open state changes */\n\tonOpenChange?: (open: boolean) => void\n\n\t/** Callback when mode changes */\n\tonModeChange?: (mode: PillMode) => void\n}\n\n/**\n * Provider for non-thread UI state.\n *\n * This state persists across:\n * - Thread switches\n * - Modal open/close\n * - Component remounts\n */\nexport const AgentUIProvider: FC<AgentUIProviderProps> = ({\n\tchildren,\n\tdefaultOpen = false,\n\tdefaultMode = 'collapsed',\n\tonOpenChange,\n\tonModeChange,\n}) => {\n\t// Core UI state\n\tconst [isOpen, setIsOpenState] = useState(defaultOpen)\n\tconst [userMode, setUserModeState] = useState<PillMode>(defaultMode)\n\tconst [position, setPositionState] = useState<Position>(DEFAULT_POSITION)\n\tconst [hasUnread, setHasUnread] = useState(false)\n\tconst [isVoiceActive, setIsVoiceActiveState] = useState(false)\n\tconst [isFullScreen, setIsFullScreen] = useState(false)\n\n\t// Callback refs to avoid stale closures\n\tconst onOpenChangeRef = useRef(onOpenChange)\n\tconst onModeChangeRef = useRef(onModeChange)\n\tonOpenChangeRef.current = onOpenChange\n\tonModeChangeRef.current = onModeChange\n\n\t// Actions\n\tconst setOpen = useCallback((open: boolean) => {\n\t\tsetIsOpenState(open)\n\t\tonOpenChangeRef.current?.(open)\n\t}, [])\n\n\tconst toggleOpen = useCallback(() => {\n\t\tsetIsOpenState((prev) => {\n\t\t\tconst next = !prev\n\t\t\tonOpenChangeRef.current?.(next)\n\t\t\treturn next\n\t\t})\n\t}, [])\n\n\tconst setUserMode = useCallback((mode: PillMode) => {\n\t\tsetUserModeState(mode)\n\t\tonModeChangeRef.current?.(mode)\n\t}, [])\n\n\tconst setPosition = useCallback((pos: Position) => {\n\t\tsetPositionState(pos)\n\t}, [])\n\n\tconst resetPosition = useCallback(() => {\n\t\tsetPositionState(DEFAULT_POSITION)\n\t}, [])\n\n\tconst markRead = useCallback(() => {\n\t\tsetHasUnread(false)\n\t}, [])\n\n\tconst markUnread = useCallback(() => {\n\t\tsetHasUnread(true)\n\t}, [])\n\n\tconst setVoiceActive = useCallback((active: boolean) => {\n\t\tsetIsVoiceActiveState(active)\n\t}, [])\n\n\tconst collapse = useCallback(() => {\n\t\tsetUserModeState('collapsed')\n\t\tsetPositionState(DEFAULT_POSITION)\n\t\tsetIsFullScreen(false)\n\t\tonModeChangeRef.current?.('collapsed')\n\t}, [])\n\n\tconst expand = useCallback(() => {\n\t\tsetUserModeState('composing')\n\t\tonModeChangeRef.current?.('composing')\n\t}, [])\n\n\tconst enterFullScreen = useCallback(() => {\n\t\tsetIsFullScreen(true)\n\t}, [])\n\n\tconst exitFullScreen = useCallback(() => {\n\t\tsetIsFullScreen(false)\n\t}, [])\n\n\tconst toggleFullScreen = useCallback(() => {\n\t\tsetIsFullScreen((prev) => !prev)\n\t}, [])\n\n\t// Memoized context value\n\tconst value = useMemo<AgentUIContextValue>(\n\t\t() => ({\n\t\t\t// State\n\t\t\tisOpen,\n\t\t\tuserMode,\n\t\t\tposition,\n\t\t\thasUnread,\n\t\t\tisVoiceActive,\n\t\t\tisFullScreen,\n\n\t\t\t// Actions\n\t\t\tsetOpen,\n\t\t\ttoggleOpen,\n\t\t\tsetUserMode,\n\t\t\tsetPosition,\n\t\t\tresetPosition,\n\t\t\tmarkRead,\n\t\t\tmarkUnread,\n\t\t\tsetVoiceActive,\n\t\t\tcollapse,\n\t\t\texpand,\n\t\t\tenterFullScreen,\n\t\t\texitFullScreen,\n\t\t\ttoggleFullScreen,\n\t\t}),\n\t\t[\n\t\t\tisOpen,\n\t\t\tuserMode,\n\t\t\tposition,\n\t\t\thasUnread,\n\t\t\tisVoiceActive,\n\t\t\tisFullScreen,\n\t\t\tsetOpen,\n\t\t\ttoggleOpen,\n\t\t\tsetUserMode,\n\t\t\tsetPosition,\n\t\t\tresetPosition,\n\t\t\tmarkRead,\n\t\t\tmarkUnread,\n\t\t\tsetVoiceActive,\n\t\t\tcollapse,\n\t\t\texpand,\n\t\t\tenterFullScreen,\n\t\t\texitFullScreen,\n\t\t\ttoggleFullScreen,\n\t\t]\n\t)\n\n\treturn <AgentUIContext.Provider value={value}>{children}</AgentUIContext.Provider>\n}\n\n/**\n * Hook to access agent UI state and actions\n * @throws Error if used outside AgentUIProvider\n */\nexport function useAgentUI(): AgentUIContextValue {\n\tconst context = useContext(AgentUIContext)\n\tif (!context) {\n\t\tthrow new Error('useAgentUI must be used within an AgentUIProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access agent UI state (returns null if not in provider)\n */\nexport function useOptionalAgentUI(): AgentUIContextValue | null {\n\treturn useContext(AgentUIContext)\n}\n\n/**\n * Hook to get just the pill mode (for components that only need mode)\n */\nexport function usePillMode(): PillMode {\n\tconst { userMode } = useAgentUI()\n\treturn userMode\n}\n\n/**\n * Hook to check if agent has unread messages\n */\nexport function useHasUnread(): boolean {\n\tconst { hasUnread } = useAgentUI()\n\treturn hasUnread\n}\n","'use client'\n\nimport { useCallback, useEffect, useState } from 'react'\n\nimport { KEYBOARD_VISIBILITY_THRESHOLD_PX } from '../lib/constants'\n\ninterface KeyboardState {\n\t/** Whether the soft keyboard is currently visible */\n\tisKeyboardVisible: boolean\n\t/** Height of the keyboard in pixels (0 if not visible) */\n\tkeyboardHeight: number\n\t/** Visible viewport height (excluding keyboard) */\n\tvisibleHeight: number\n}\n\n/**\n * Hook to detect and respond to soft keyboard visibility on mobile devices.\n *\n * Uses the Visual Viewport API for reliable keyboard detection.\n * Falls back gracefully on unsupported browsers.\n *\n * Usage:\n * ```tsx\n * const { isKeyboardVisible, keyboardHeight } = useKeyboardAware()\n * // Adjust UI based on keyboard state\n * ```\n */\nexport function useKeyboardAware(): KeyboardState {\n\tconst [state, setState] = useState<KeyboardState>({\n\t\tisKeyboardVisible: false,\n\t\tkeyboardHeight: 0,\n\t\tvisibleHeight: typeof window !== 'undefined' ? window.innerHeight : 0,\n\t})\n\n\tconst updateKeyboardState = useCallback(() => {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst visualViewport = window.visualViewport\n\t\tif (!visualViewport) {\n\t\t\t// Fallback for browsers without Visual Viewport API\n\t\t\tsetState({\n\t\t\t\tisKeyboardVisible: false,\n\t\t\t\tkeyboardHeight: 0,\n\t\t\t\tvisibleHeight: window.innerHeight,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst windowHeight = window.innerHeight\n\t\tconst viewportHeight = visualViewport.height\n\n\t\t// Keyboard is likely visible if viewport is significantly smaller than window\n\t\tconst heightDiff = windowHeight - viewportHeight\n\t\tconst isKeyboardVisible = heightDiff > KEYBOARD_VISIBILITY_THRESHOLD_PX\n\n\t\tsetState({\n\t\t\tisKeyboardVisible,\n\t\t\tkeyboardHeight: isKeyboardVisible ? heightDiff : 0,\n\t\t\tvisibleHeight: viewportHeight,\n\t\t})\n\t}, [])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst visualViewport = window.visualViewport\n\n\t\t// Initial update\n\t\tupdateKeyboardState()\n\n\t\tif (visualViewport) {\n\t\t\t// Visual Viewport API - most reliable\n\t\t\tvisualViewport.addEventListener('resize', updateKeyboardState)\n\t\t\tvisualViewport.addEventListener('scroll', updateKeyboardState)\n\n\t\t\treturn () => {\n\t\t\t\tvisualViewport.removeEventListener('resize', updateKeyboardState)\n\t\t\t\tvisualViewport.removeEventListener('scroll', updateKeyboardState)\n\t\t\t}\n\t\t} else {\n\t\t\t// Fallback: listen for window resize\n\t\t\twindow.addEventListener('resize', updateKeyboardState)\n\n\t\t\treturn () => {\n\t\t\t\twindow.removeEventListener('resize', updateKeyboardState)\n\t\t\t}\n\t\t}\n\t}, [updateKeyboardState])\n\n\treturn state\n}\n\n/**\n * Returns a CSS transform value to offset an element above the keyboard.\n * Use this with fixed-position elements that should stay visible when keyboard appears.\n *\n * @param keyboardHeight - Height of keyboard from useKeyboardAware\n * @param additionalOffset - Extra pixels to add above keyboard (default: 8)\n */\nexport function getKeyboardOffset(keyboardHeight: number, additionalOffset = 8): string {\n\tif (keyboardHeight <= 0) return 'translateY(0)'\n\treturn `translateY(-${keyboardHeight + additionalOffset}px)`\n}\n\nexport default useKeyboardAware\n","'use client'\n\nimport { useEffect, useState } from 'react'\n\n/**\n * Hook to detect if the current device is a mobile/touch device.\n * Uses media queries for reliable detection that works with SSR.\n *\n * Detection strategy:\n * 1. (hover: none) - Device has no hover capability (touch-only)\n * 2. (pointer: coarse) - Device uses imprecise pointer (finger vs mouse)\n *\n * Returns:\n * - isMobile: true if device is likely a mobile/touch device\n * - isTouchDevice: true if device supports touch input\n * - isCoarsePointer: true if primary input is coarse (finger)\n */\nexport function useMobileDetect() {\n\tconst [isMobile, setIsMobile] = useState(false)\n\tconst [isTouchDevice, setIsTouchDevice] = useState(false)\n\tconst [isCoarsePointer, setIsCoarsePointer] = useState(false)\n\n\tuseEffect(() => {\n\t\t// Check for touch capability\n\t\tconst hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0\n\n\t\t// Check media queries\n\t\tconst hoverNone = window.matchMedia('(hover: none)')\n\t\tconst pointerCoarse = window.matchMedia('(pointer: coarse)')\n\n\t\tconst updateState = () => {\n\t\t\tsetIsTouchDevice(hasTouch)\n\t\t\tsetIsCoarsePointer(pointerCoarse.matches)\n\t\t\t// Consider mobile if no hover OR coarse pointer\n\t\t\tsetIsMobile(hoverNone.matches || pointerCoarse.matches)\n\t\t}\n\n\t\tupdateState()\n\n\t\t// Listen for changes (e.g., connecting mouse to tablet)\n\t\tconst handleHoverChange = () => updateState()\n\t\tconst handlePointerChange = () => updateState()\n\n\t\thoverNone.addEventListener('change', handleHoverChange)\n\t\tpointerCoarse.addEventListener('change', handlePointerChange)\n\n\t\treturn () => {\n\t\t\thoverNone.removeEventListener('change', handleHoverChange)\n\t\t\tpointerCoarse.removeEventListener('change', handlePointerChange)\n\t\t}\n\t}, [])\n\n\treturn { isMobile, isTouchDevice, isCoarsePointer }\n}\n\n/**\n * Static check for mobile - useful for SSR fallback\n * Returns true on server/initial render to be safe\n */\nexport function checkIsMobileSSR(): boolean {\n\tif (typeof window === 'undefined') return false\n\treturn (\n\t\twindow.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches\n\t)\n}\n\nexport default useMobileDetect\n","/**\n * usePendingToolCalls Hook\n *\n * Derives pending tool call state from assistant-ui's thread state.\n * This replaces the external pendingApprovalStore by using the single source of truth.\n *\n * Benefits:\n * - No external store synchronization needed\n * - No registration/unregistration logic\n * - No infinite loop issues from useSyncExternalStore\n * - Naturally reactive to thread state changes\n *\n * For non-reactive utilities (callbacks/effects), see lib/thread-utils.ts\n */\nimport { useThread, useThreadRuntime } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport type { ThreadAssistantMessage } from '@assistant-ui/react'\n// Import the type for internal use\nimport type { PendingToolCallInfo } from '../lib/thread-utils'\n\n// Re-export the shared type for backwards compatibility\nexport type { PendingToolCallInfo as PendingToolCall } from '../lib/thread-utils'\n\n/**\n * Hook to get all pending tool calls that require user approval.\n * Derives state from assistant-ui's thread messages.\n *\n * This is a reactive hook - it will re-render when thread state changes.\n * For non-reactive access in callbacks, use getPendingToolCalls() from lib/thread-utils.ts\n */\nexport function usePendingToolCalls(): PendingToolCallInfo[] {\n\tconst messages = useThread((t) => t.messages)\n\n\treturn useMemo(() => {\n\t\tconst result: PendingToolCallInfo[] = []\n\n\t\tfor (const msg of messages) {\n\t\t\t// Only assistant messages can have tool calls\n\t\t\tif (msg.role !== 'assistant') continue\n\n\t\t\t// Cast to assistant message to access status\n\t\t\tconst assistantMsg = msg as ThreadAssistantMessage\n\n\t\t\t// Only process messages waiting for tool results\n\t\t\t// Check for requires-action status (don't check reason - it may vary)\n\t\t\tif (assistantMsg.status?.type !== 'requires-action') continue\n\n\t\t\t// Find tool-call parts without results\n\t\t\tfor (const part of assistantMsg.content) {\n\t\t\t\tif (part.type !== 'tool-call') continue\n\t\t\t\tif (part.result !== undefined) continue\n\n\t\t\t\tresult.push({\n\t\t\t\t\tmessageId: msg.id,\n\t\t\t\t\ttoolCallId: part.toolCallId,\n\t\t\t\t\ttoolName: part.toolName,\n\t\t\t\t\targs: (part.args as Record<string, unknown>) ?? {},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}, [messages])\n}\n\n/**\n * Hook to check if there are any pending tool calls.\n * Optimized for conditional rendering - returns boolean instead of array.\n */\nexport function useHasPendingToolCalls(): boolean {\n\tconst messages = useThread((t) => t.messages)\n\n\treturn useMemo(() => {\n\t\tfor (const msg of messages) {\n\t\t\tif (msg.role !== 'assistant') continue\n\n\t\t\tconst assistantMsg = msg as ThreadAssistantMessage\n\n\t\t\t// Check for requires-action status (don't check reason - it may vary)\n\t\t\tif (assistantMsg.status?.type !== 'requires-action') continue\n\n\t\t\tfor (const part of assistantMsg.content) {\n\t\t\t\tif (part.type === 'tool-call' && part.result === undefined) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false\n\t}, [messages])\n}\n\n/**\n * Hook to get the thread runtime for calling addToolResult.\n * Re-exported for convenience.\n */\nexport { useThreadRuntime }\n","'use client'\n\nimport { useCallback, useRef } from 'react'\n\nimport { PINCH_GESTURE_CONFIG } from '../lib/constants'\n\nimport type { TouchEvent as ReactTouchEvent } from 'react'\n\ninterface PinchGestureOptions {\n\t/** Callback when pinch-out (expand) gesture detected */\n\tonPinchOut?: () => void\n\t/** Callback when pinch-in (collapse) gesture detected */\n\tonPinchIn?: () => void\n\t/** Whether gesture detection is enabled */\n\tenabled?: boolean\n\t/** Minimum scale change to trigger (default from PINCH_GESTURE_CONFIG) */\n\tthreshold?: number\n}\n\ninterface PinchState {\n\tinitialDistance: number | null\n\tlastDistance: number | null\n\tisActive: boolean\n}\n\n/** Minimal touch point interface for distance calculation */\ninterface TouchPoint {\n\tclientX: number\n\tclientY: number\n}\n\n/**\n * Calculate distance between two touch points\n */\nfunction getTouchDistance(touch1: TouchPoint, touch2: TouchPoint): number {\n\tconst dx = touch2.clientX - touch1.clientX\n\tconst dy = touch2.clientY - touch1.clientY\n\treturn Math.sqrt(dx * dx + dy * dy)\n}\n\n/**\n * Hook for detecting two-finger pinch gestures.\n *\n * Implements pinch-to-expand (out) and pinch-to-collapse (in) detection\n * using native Touch Events for maximum compatibility.\n *\n * @example\n * ```tsx\n * const { handlers } = usePinchGesture({\n * onPinchOut: () => enterFullScreen(),\n * onPinchIn: () => exitFullScreen(),\n * enabled: isMobile && isExpanded,\n * })\n *\n * return <div {...handlers}>Content</div>\n * ```\n */\nexport function usePinchGesture({\n\tonPinchOut,\n\tonPinchIn,\n\tenabled = true,\n\tthreshold = PINCH_GESTURE_CONFIG.threshold,\n}: PinchGestureOptions) {\n\tconst stateRef = useRef<PinchState>({\n\t\tinitialDistance: null,\n\t\tlastDistance: null,\n\t\tisActive: false,\n\t})\n\n\tconst handleTouchStart = useCallback(\n\t\t(e: ReactTouchEvent) => {\n\t\t\tif (!enabled) return\n\t\t\tif (e.touches.length === 2) {\n\t\t\t\tconst distance = getTouchDistance(e.touches[0], e.touches[1])\n\n\t\t\t\t// Only start tracking if fingers are far enough apart\n\t\t\t\tif (distance >= PINCH_GESTURE_CONFIG.minInitialDistance) {\n\t\t\t\t\tstateRef.current = {\n\t\t\t\t\t\tinitialDistance: distance,\n\t\t\t\t\t\tlastDistance: distance,\n\t\t\t\t\t\tisActive: true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[enabled]\n\t)\n\n\tconst handleTouchMove = useCallback(\n\t\t(e: ReactTouchEvent) => {\n\t\t\tif (!enabled || !stateRef.current.isActive) return\n\t\t\tif (e.touches.length !== 2) return\n\n\t\t\t// Track the latest distance during the gesture\n\t\t\tconst currentDistance = getTouchDistance(e.touches[0], e.touches[1])\n\t\t\tstateRef.current.lastDistance = currentDistance\n\t\t},\n\t\t[enabled]\n\t)\n\n\tconst handleTouchEnd = useCallback(\n\t\t(e: ReactTouchEvent) => {\n\t\t\tif (!enabled || !stateRef.current.isActive) return\n\n\t\t\tconst { initialDistance, lastDistance } = stateRef.current\n\n\t\t\t// When gesture ends, evaluate if it was a pinch\n\t\t\tif (e.touches.length < 2 && initialDistance !== null && lastDistance !== null) {\n\t\t\t\tconst scaleDelta = (lastDistance - initialDistance) / initialDistance\n\n\t\t\t\tif (scaleDelta > threshold) {\n\t\t\t\t\tonPinchOut?.()\n\t\t\t\t} else if (scaleDelta < -threshold) {\n\t\t\t\t\tonPinchIn?.()\n\t\t\t\t}\n\n\t\t\t\t// Reset state\n\t\t\t\tstateRef.current = {\n\t\t\t\t\tinitialDistance: null,\n\t\t\t\t\tlastDistance: null,\n\t\t\t\t\tisActive: false,\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[enabled, threshold, onPinchOut, onPinchIn]\n\t)\n\n\treturn {\n\t\thandlers: {\n\t\t\tonTouchStart: handleTouchStart,\n\t\t\tonTouchMove: handleTouchMove,\n\t\t\tonTouchEnd: handleTouchEnd,\n\t\t},\n\t}\n}\n\nexport default usePinchGesture\n","/**\n * ActivityIndicator Component\n *\n * Shows what the agent is currently doing based on thread state.\n * Displays in the composer area when the agent is running.\n *\n * Activity states:\n * - \"Thinking...\" - Agent is processing, no tools called yet\n * - \"Running {toolName}...\" - Single tool is executing\n * - \"Running {n} tools...\" - Multiple tools executing in parallel\n * - Shows streaming text preview when available\n */\n'use client'\n\nimport { useThread } from '@assistant-ui/react'\nimport {\n\tCamera,\n\tFileText,\n\tLoader2,\n\tMousePointer,\n\tNavigation,\n\tPenLine,\n\tSearch,\n\tTrash2,\n\tWrench,\n} from 'lucide-react'\nimport { useMemo } from 'react'\n\nimport { humanizeToolName } from '../../lib/format'\nimport { cn } from '../../lib/utils'\n\nimport type { LucideIcon } from 'lucide-react'\nimport type { FC } from 'react'\n\n// ============================================================================\n// Tool Icon Mapping\n// ============================================================================\n\n/**\n * Get an appropriate icon for a tool based on its name.\n * Uses pattern matching to categorize tools.\n */\nexport function getToolIcon(toolName: string): LucideIcon {\n\tconst name = toolName.toLowerCase()\n\n\t// Search/find operations\n\tif (\n\t\tname.includes('search') ||\n\t\tname.includes('find') ||\n\t\tname.includes('grep') ||\n\t\tname.includes('glob')\n\t) {\n\t\treturn Search\n\t}\n\n\t// Read/get operations\n\tif (\n\t\tname.includes('read') ||\n\t\tname.includes('get') ||\n\t\tname.includes('fetch') ||\n\t\tname.includes('list')\n\t) {\n\t\treturn FileText\n\t}\n\n\t// Write/create operations\n\tif (\n\t\tname.includes('write') ||\n\t\tname.includes('create') ||\n\t\tname.includes('add') ||\n\t\tname.includes('insert')\n\t) {\n\t\treturn PenLine\n\t}\n\n\t// Delete/remove operations\n\tif (name.includes('delete') || name.includes('remove') || name.includes('clear')) {\n\t\treturn Trash2\n\t}\n\n\t// Navigation operations\n\tif (name.includes('navigate') || name.includes('goto') || name.includes('open')) {\n\t\treturn Navigation\n\t}\n\n\t// UI interaction operations\n\tif (\n\t\tname.includes('click') ||\n\t\tname.includes('fill') ||\n\t\tname.includes('type') ||\n\t\tname.includes('hover')\n\t) {\n\t\treturn MousePointer\n\t}\n\n\t// Screenshot/snapshot operations\n\tif (name.includes('screenshot') || name.includes('snapshot') || name.includes('capture')) {\n\t\treturn Camera\n\t}\n\n\t// Default\n\treturn Wrench\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface ActivityState {\n\ttype: 'idle' | 'thinking' | 'tool' | 'parallel_tools' | 'streaming'\n\tlabel: string\n\ticon: LucideIcon\n\ttoolNames?: string[]\n\tstreamingText?: string\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook to derive current activity state from the thread.\n */\nexport function useActivityState(): ActivityState | null {\n\tconst messages = useThread((thread) => thread.messages)\n\tconst isRunning = useThread((thread) => thread.isRunning)\n\n\treturn useMemo(() => {\n\t\tif (!isRunning) return null\n\n\t\t// Find the last assistant message\n\t\tconst lastAssistantMessage = messages\n\t\t\t? [...messages].reverse().find((m) => m.role === 'assistant')\n\t\t\t: null\n\n\t\tif (!lastAssistantMessage) {\n\t\t\t// No assistant message yet - thinking\n\t\t\treturn {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tlabel: 'Thinking...',\n\t\t\t\ticon: Loader2,\n\t\t\t}\n\t\t}\n\n\t\t// Get running tool calls from the message\n\t\tconst runningToolNames: string[] = []\n\t\tlet lastText: string | undefined\n\n\t\tfor (const part of lastAssistantMessage.content) {\n\t\t\tif (part.type === 'tool-call') {\n\t\t\t\t// Check if this tool call is running (no status means running, or status.type === 'running')\n\t\t\t\tconst toolPart = part as { toolName: string; status?: { type: string } }\n\t\t\t\tif (!toolPart.status || toolPart.status.type === 'running') {\n\t\t\t\t\trunningToolNames.push(toolPart.toolName)\n\t\t\t\t}\n\t\t\t} else if (part.type === 'text') {\n\t\t\t\tconst textPart = part as { text: string }\n\t\t\t\tlastText = textPart.text\n\t\t\t}\n\t\t}\n\n\t\t// Determine activity state\n\t\tif (runningToolNames.length === 0) {\n\t\t\t// No running tools\n\t\t\tif (lastText && lastText.length > 0) {\n\t\t\t\t// Has text content - streaming response\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'streaming',\n\t\t\t\t\tlabel: 'Writing response...',\n\t\t\t\t\ticon: PenLine,\n\t\t\t\t\tstreamingText: lastText,\n\t\t\t\t}\n\t\t\t}\n\t\t\t// No text either - still thinking\n\t\t\treturn {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tlabel: 'Thinking...',\n\t\t\t\ticon: Loader2,\n\t\t\t}\n\t\t}\n\n\t\tif (runningToolNames.length === 1) {\n\t\t\t// Single tool running\n\t\t\tconst toolName = runningToolNames[0]\n\t\t\treturn {\n\t\t\t\ttype: 'tool',\n\t\t\t\tlabel: humanizeToolName(toolName, true),\n\t\t\t\ticon: getToolIcon(toolName),\n\t\t\t\ttoolNames: [toolName],\n\t\t\t}\n\t\t}\n\n\t\t// Multiple tools running in parallel\n\t\treturn {\n\t\t\ttype: 'parallel_tools',\n\t\t\tlabel: `Running ${runningToolNames.length} tools...`,\n\t\t\ticon: Loader2,\n\t\t\ttoolNames: runningToolNames,\n\t\t}\n\t}, [messages, isRunning])\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\ninterface ActivityIndicatorProps {\n\tclassName?: string\n}\n\n/**\n * Displays the current agent activity.\n * Shows in the composer area when the agent is running.\n */\nexport const ActivityIndicator: FC<ActivityIndicatorProps> = ({ className }) => {\n\tconst activity = useActivityState()\n\n\tif (!activity) return null\n\n\tconst Icon = activity.icon\n\tconst isSpinning = activity.type === 'thinking' || activity.type === 'parallel_tools'\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex items-center gap-2 px-3 py-2',\n\t\t\t\t'rounded-lg bg-blue-500/10 border border-blue-500/20',\n\t\t\t\t'text-sm text-blue-400',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t<Icon className={cn('h-4 w-4 flex-shrink-0', isSpinning && 'animate-spin')} />\n\t\t\t<span className=\"truncate\">{activity.label}</span>\n\n\t\t\t{/* Show parallel tool names on hover/expand */}\n\t\t\t{activity.type === 'parallel_tools' && activity.toolNames && (\n\t\t\t\t<div className=\"hidden sm:flex items-center gap-1 ml-1\">\n\t\t\t\t\t{activity.toolNames.slice(0, 3).map((name, i) => {\n\t\t\t\t\t\tconst ToolIcon = getToolIcon(name)\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span key={i} title={humanizeToolName(name, true)}>\n\t\t\t\t\t\t\t\t<ToolIcon className=\"h-3 w-3 text-blue-400/60\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t\t{activity.toolNames.length > 3 && (\n\t\t\t\t\t\t<span className=\"text-xs text-blue-400/60\">+{activity.toolNames.length - 3}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nexport default ActivityIndicator\n","/**\n * Approval Mode Toggle\n *\n * A compact toggle for switching between 'auto' and 'ask' modes\n * for destructive tool approval. Shows in the pill header.\n */\nimport { Shield, ShieldOff } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { useOptionalToolApproval } from '../../providers/ToolApprovalProvider'\n\nimport type { FC } from 'react'\n\nexport interface ApprovalModeToggleProps {\n\t/** Additional class name */\n\tclassName?: string\n}\n\n/**\n * Compact toggle button for approval mode.\n * Shows a shield icon that indicates current mode.\n */\nexport const ApprovalModeToggle: FC<ApprovalModeToggleProps> = ({ className }) => {\n\tconst toolApproval = useOptionalToolApproval()\n\n\t// Don't render if no approval context\n\tif (!toolApproval) return null\n\n\tconst { mode, toggleMode } = toolApproval\n\tconst isAskMode = mode === 'ask'\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonClick={toggleMode}\n\t\t\tclassName={cn(\n\t\t\t\t'flex items-center gap-1 rounded-md px-1.5 py-1',\n\t\t\t\t'text-[10px] font-medium uppercase tracking-wide',\n\t\t\t\t'transition-colors duration-150',\n\t\t\t\tisAskMode\n\t\t\t\t\t? 'bg-amber-500/20 text-amber-400 hover:bg-amber-500/30'\n\t\t\t\t\t: 'bg-zinc-700/50 text-white/40 hover:bg-zinc-700 hover:text-white/60',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\ttitle={\n\t\t\t\tisAskMode ? 'Ask before action (click to auto-approve)' : 'Auto-approve (click to ask)'\n\t\t\t}\n\t\t>\n\t\t\t{isAskMode ? (\n\t\t\t\t<>\n\t\t\t\t\t<Shield className=\"h-3 w-3\" />\n\t\t\t\t\t<span>Ask</span>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<ShieldOff className=\"h-3 w-3\" />\n\t\t\t\t\t<span>Auto</span>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</button>\n\t)\n}\n\n/**\n * Inline approval mode indicator for the pill header.\n * Shows current mode with ability to toggle.\n */\nexport const ApprovalModeIndicator: FC<ApprovalModeToggleProps> = ({ className }) => {\n\tconst toolApproval = useOptionalToolApproval()\n\n\t// Don't render if no approval context\n\tif (!toolApproval) return null\n\n\tconst { mode, toggleMode } = toolApproval\n\tconst isAskMode = mode === 'ask'\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonClick={toggleMode}\n\t\t\tclassName={cn(\n\t\t\t\t'flex items-center justify-center rounded-full p-1',\n\t\t\t\t'transition-colors duration-150',\n\t\t\t\tisAskMode\n\t\t\t\t\t? 'text-amber-500 hover:bg-amber-500/20'\n\t\t\t\t\t: 'text-white/30 hover:bg-white/10 hover:text-white/50',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\ttitle={\n\t\t\t\tisAskMode\n\t\t\t\t\t? 'Ask before destructive actions (click to auto-approve)'\n\t\t\t\t\t: 'Auto-approve all actions (click to ask first)'\n\t\t\t}\n\t\t>\n\t\t\t{isAskMode ? <Shield className=\"h-3.5 w-3.5\" /> : <ShieldOff className=\"h-3.5 w-3.5\" />}\n\t\t</button>\n\t)\n}\n\nexport default ApprovalModeToggle\n","'use client'\n\nimport { AlertCircle, CheckCircle2, Circle, Loader2 } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nimport type { FC } from 'react'\nimport type { Action } from '../../hooks/useActions'\n\ninterface CurrentActivityProps {\n\tcurrentAction: Action | null\n\trecentActions?: Action[]\n\tshowRecent?: boolean\n\tclassName?: string\n}\n\n/**\n * Displays the current action the agent is performing,\n * with optional recent completed steps shown below.\n */\nexport const CurrentActivity: FC<CurrentActivityProps> = ({\n\tcurrentAction,\n\trecentActions = [],\n\tshowRecent = true,\n\tclassName,\n}) => {\n\treturn (\n\t\t<div className={cn('space-y-2', className)}>\n\t\t\t{/* Current action - prominent display */}\n\t\t\t{currentAction ? (\n\t\t\t\t<div className=\"flex items-center gap-2.5\">\n\t\t\t\t\t<ActionStatusIcon status={currentAction.status} />\n\t\t\t\t\t<span className=\"text-sm font-medium text-white\">{currentAction.label}...</span>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t/* Thinking indicator - when running but no specific action yet */\n\t\t\t\t<div className=\"flex items-center gap-2.5\">\n\t\t\t\t\t<Loader2 className=\"h-4 w-4 text-blue-400 animate-spin\" />\n\t\t\t\t\t<span className=\"text-sm font-medium text-white/80\">Thinking...</span>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Recent completed actions - muted, smaller */}\n\t\t\t{showRecent && recentActions.length > 0 && (\n\t\t\t\t<div className=\"ml-1 border-l border-white/20 pl-3 space-y-1\">\n\t\t\t\t\t{recentActions.map((action) => (\n\t\t\t\t\t\t<div key={action.id} className=\"flex items-center gap-2 text-xs text-white/60\">\n\t\t\t\t\t\t\t<ActionStatusIcon status={action.status} size=\"sm\" />\n\t\t\t\t\t\t\t<span className={cn(action.status === 'error' && 'text-red-400')}>\n\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\ninterface ActionStatusIconProps {\n\tstatus: Action['status']\n\tsize?: 'sm' | 'md'\n\tclassName?: string\n}\n\n/**\n * Icon component for action status\n */\nexport const ActionStatusIcon: FC<ActionStatusIconProps> = ({ status, size = 'md', className }) => {\n\tconst sizeClass = size === 'sm' ? 'h-3 w-3' : 'h-4 w-4'\n\n\tswitch (status) {\n\t\tcase 'running':\n\t\t\treturn <Loader2 className={cn(sizeClass, 'text-blue-400 animate-spin', className)} />\n\t\tcase 'pending':\n\t\t\treturn <Circle className={cn(sizeClass, 'text-amber-400', className)} />\n\t\tcase 'success':\n\t\t\treturn <CheckCircle2 className={cn(sizeClass, 'text-green-400', className)} />\n\t\tcase 'error':\n\t\t\treturn <AlertCircle className={cn(sizeClass, 'text-red-400', className)} />\n\t\tdefault:\n\t\t\treturn <Circle className={cn(sizeClass, 'text-white/40', className)} />\n\t}\n}\n\n/**\n * Idle state indicator when no actions are running\n */\nexport const IdleIndicator: FC<{ className?: string }> = ({ className }) => {\n\treturn (\n\t\t<div className={cn('flex items-center gap-2 text-white/50', className)}>\n\t\t\t<div className=\"h-2 w-2 rounded-full bg-green-400/60\" />\n\t\t\t<span className=\"text-xs\">Ready</span>\n\t\t</div>\n\t)\n}\n","/**\n * MCP Tool Registry Component\n *\n * Registers all MCP tools with the assistant-ui runtime.\n * Uses the unified callTool function which auto-routes based on tool source.\n *\n * Supports destructive tool approval when ToolApprovalProvider is present:\n * - Tools with destructiveHint: true require user confirmation before execution\n * - Approval mode can be 'ask' (require confirmation) or 'auto' (execute immediately)\n * - Approval UI is handled by UnifiedToolFallback using the HITL pattern\n *\n * Tool execution captures metadata (timing, source info) and stores it in the\n * assistant-ui thread via ToolResponse artifacts. This enables:\n * - Performance monitoring (duration tracking)\n * - Source attribution (which MCP server handled the call)\n * - Error tracking (including abort status)\n *\n * Usage:\n * <MCPToolRegistry />\n *\n * This component should be placed inside both MCPToolsProvider and AssistantRuntimeProvider.\n */\nimport { useAssistantTool } from '@assistant-ui/react'\nimport { ToolResponse } from 'assistant-stream'\n\nimport { useMCPTools } from '../providers/MCPToolsProvider'\nimport { useOptionalToolApproval } from '../providers/ToolApprovalProvider'\n\nimport type { CallToolResult, ToolCallMetadata, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { ReadonlyJSONValue } from 'assistant-stream/utils'\nimport type { FC } from 'react'\n\n// ============================================================================\n// Tool Result Formatting\n// ============================================================================\n\n/**\n * Format tool result content for the assistant\n */\nexport function formatToolResult(result: CallToolResult): string {\n\tconst textContent = result.content\n\t\t.map((c: { type: string; text?: string }) => {\n\t\t\tif ('text' in c && typeof c.text === 'string') {\n\t\t\t\treturn c.text\n\t\t\t}\n\t\t\treturn JSON.stringify(c)\n\t\t})\n\t\t.join('\\n')\n\n\treturn textContent || 'Tool executed successfully'\n}\n\n// ============================================================================\n// Tool Bridge Components\n// ============================================================================\n\n/**\n * Bridge component that registers a single tool with assistant-ui.\n * Executes the tool immediately via MCP.\n * Captures execution metadata (timing, source) and stores in thread artifacts.\n */\nconst ToolBridge: FC<{\n\ttool: ToolWithSource\n\tcallTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n}> = ({ tool, callTool }) => {\n\tuseAssistantTool({\n\t\ttoolName: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tparameters: (tool.inputSchema ?? {}) as Record<string, unknown>,\n\t\texecute: async (args) => {\n\t\t\tconst startedAt = Date.now()\n\t\t\tlet isError = false\n\t\t\tlet wasAborted = false\n\n\t\t\ttry {\n\t\t\t\tconst result = await callTool(tool.name, args)\n\n\t\t\t\t// Check if the result indicates an error\n\t\t\t\tisError = result.isError === true\n\n\t\t\t\t// Check if the call was aborted (tool removed during execution)\n\t\t\t\twasAborted = result.content.some(\n\t\t\t\t\t(c) =>\n\t\t\t\t\t\tc.type === 'text' && typeof c.text === 'string' && c.text.includes('Tool call aborted')\n\t\t\t\t)\n\n\t\t\t\t// Build metadata artifact for thread persistence\n\t\t\t\tconst metadata = {\n\t\t\t\t\tstartedAt,\n\t\t\t\t\tduration: Date.now() - startedAt,\n\t\t\t\t\tsourceId: tool._sourceId,\n\t\t\t\t\tisError,\n\t\t\t\t\twasAborted,\n\t\t\t\t} satisfies ToolCallMetadata\n\n\t\t\t\t// Return ToolResponse with artifact for thread storage\n\t\t\t\treturn new ToolResponse({\n\t\t\t\t\tresult: formatToolResult(result),\n\t\t\t\t\tartifact: metadata as unknown as ReadonlyJSONValue,\n\t\t\t\t\tisError,\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`[ToolBridge] Tool '${tool.name}' execution failed:`, error)\n\n\t\t\t\t// Still capture metadata for failed calls\n\t\t\t\tconst metadata = {\n\t\t\t\t\tstartedAt,\n\t\t\t\t\tduration: Date.now() - startedAt,\n\t\t\t\t\tsourceId: tool._sourceId,\n\t\t\t\t\tisError: true,\n\t\t\t\t\twasAborted: false,\n\t\t\t\t} satisfies ToolCallMetadata\n\n\t\t\t\t// Return error as ToolResponse with metadata\n\t\t\t\treturn new ToolResponse({\n\t\t\t\t\tresult: `Error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\tartifact: metadata as unknown as ReadonlyJSONValue,\n\t\t\t\t\tisError: true,\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t})\n\n\treturn null\n}\n\n/**\n * Bridge component for destructive tools that require approval.\n *\n * IMPORTANT: No execute function is provided!\n * This makes assistant-ui wait for the fallback to call addResult().\n * The model pauses until the user approves/denies via the fallback UI.\n */\nconst DestructiveToolBridge: FC<{\n\ttool: ToolWithSource\n}> = ({ tool }) => {\n\t// Register tool WITHOUT execute - this is key for HITL!\n\t// The fallback component handles execution via addResult()\n\tuseAssistantTool({\n\t\ttoolName: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tparameters: (tool.inputSchema ?? {}) as Record<string, unknown>,\n\t\t// No execute function = model waits for addResult()\n\t})\n\n\treturn null\n}\n\n// ============================================================================\n// Main Registry Component\n// ============================================================================\n\n/**\n * Tool registry that registers all MCP tools with assistant-ui.\n * Routes tool calls automatically based on _sourceId.\n * Uses DestructiveToolBridge for tools that require approval.\n */\nexport const MCPToolRegistry: FC = () => {\n\tconst { tools, callTool } = useMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\n\treturn (\n\t\t<>\n\t\t\t{tools.map((tool) => {\n\t\t\t\t// Check if this tool requires approval\n\t\t\t\tconst needsApproval = toolApproval?.requiresApproval(tool) ?? false\n\n\t\t\t\tif (needsApproval) {\n\t\t\t\t\treturn <DestructiveToolBridge key={`${tool._sourceId}-${tool.name}`} tool={tool} />\n\t\t\t\t}\n\n\t\t\t\treturn <ToolBridge key={`${tool._sourceId}-${tool.name}`} tool={tool} callTool={callTool} />\n\t\t\t})}\n\t\t</>\n\t)\n}\n","/**\n * ToolApprovalCard\n *\n * Shared approval UI used by both text and voice modes.\n * Renders tool name, description, argument preview, countdown (optional),\n * and approve/deny buttons.\n */\n'use client'\n\nimport { AlertTriangle, Check, Loader2, X } from 'lucide-react'\nimport { motion } from 'motion/react'\n\nimport { formatArgs, humanizeToolName } from '../../lib/format'\nimport { cn } from '../../lib/utils'\n\nimport type { FC, ReactNode } from 'react'\n\nexport interface ToolApprovalCardProps {\n\ttoolName: string\n\tdescription?: string\n\targs?: Record<string, unknown>\n\ttimeoutRemaining?: number\n\tisExecuting?: boolean\n\tonApprove: () => void\n\tonDeny: () => void\n\tclassName?: string\n\theaderAddon?: ReactNode\n\tsubtitle?: ReactNode\n}\n\nconst countdownVariants = {\n\tpulse: {\n\t\tscale: [1, 1.1, 1],\n\t\ttransition: { duration: 1, repeat: Infinity },\n\t},\n}\n\nexport const ToolApprovalCard: FC<ToolApprovalCardProps> = ({\n\ttoolName,\n\tdescription,\n\targs,\n\ttimeoutRemaining,\n\tisExecuting = false,\n\tonApprove,\n\tonDeny,\n\tclassName,\n\theaderAddon,\n\tsubtitle,\n}) => {\n\tconst humanName = humanizeToolName(toolName)\n\tconst hasArgs = args && Object.keys(args).length > 0\n\tconst formattedArgs = hasArgs ? formatArgs(args) : null\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col gap-2 rounded-xl px-4 py-3',\n\t\t\t\t'border border-amber-500/30 bg-amber-500/10',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t{/* Header row: Warning icon, tool name, countdown */}\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<AlertTriangle className=\"h-4 w-4 flex-shrink-0 text-amber-500\" />\n\t\t\t\t<span className=\"min-w-0 flex-1 truncate text-sm text-white/90\">\n\t\t\t\t\t<span className=\"font-medium text-amber-400\">Approve</span> {humanName}?\n\t\t\t\t</span>\n\n\t\t\t\t{timeoutRemaining !== undefined && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium',\n\t\t\t\t\t\t\ttimeoutRemaining <= 10\n\t\t\t\t\t\t\t\t? 'bg-red-500/20 text-red-400'\n\t\t\t\t\t\t\t\t: 'bg-amber-500/20 text-amber-400'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tvariants={timeoutRemaining <= 10 ? countdownVariants : undefined}\n\t\t\t\t\t\tanimate={timeoutRemaining <= 10 ? 'pulse' : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t{timeoutRemaining}\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{subtitle}\n\n\t\t\t{/* Tool description */}\n\t\t\t{description && <p className=\"text-xs leading-relaxed text-white/60\">{description}</p>}\n\n\t\t\t{/* Arguments preview */}\n\t\t\t{formattedArgs && (\n\t\t\t\t<pre className=\"max-h-24 overflow-auto whitespace-pre-wrap rounded-lg bg-white/5 p-2 font-mono text-[11px] leading-relaxed text-white/60\">\n\t\t\t\t\t{formattedArgs}\n\t\t\t\t</pre>\n\t\t\t)}\n\n\t\t\t{headerAddon}\n\n\t\t\t{/* Action buttons */}\n\t\t\t{isExecuting ? (\n\t\t\t\t<div className=\"flex items-center justify-center gap-2 rounded-lg bg-blue-500/10 px-3 py-2 text-sm text-blue-400\">\n\t\t\t\t\t<Loader2 className=\"h-4 w-4 animate-spin\" />\n\t\t\t\t\t<span>\n\t\t\t\t\t\tExecuting <strong>{humanName}</strong>...\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onDeny}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex flex-1 items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium',\n\t\t\t\t\t\t\t'border border-zinc-600 text-white/70',\n\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\t'hover:border-red-500/50 hover:bg-red-500/20 hover:text-red-400',\n\t\t\t\t\t\t\t'active:scale-[0.98]'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\tDeny\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onApprove}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex flex-1 items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium',\n\t\t\t\t\t\t\t'border border-amber-500/50 bg-amber-500/20 text-amber-400',\n\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\t'hover:border-amber-500 hover:bg-amber-500/30',\n\t\t\t\t\t\t\t'active:scale-[0.98]'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Check className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\tApprove\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nexport default ToolApprovalCard\n","/**\n * ElicitationButtonBar Component\n *\n * Renders an approval card above the composer when a tool requires approval.\n * Shows the tool name, description, and input arguments so users know\n * exactly what they're approving.\n *\n * - Accept: Executes the tool and returns the result\n * - Deny: Stops the thread entirely (user doesn't want to continue)\n */\n'use client'\n\nimport { useThreadRuntime } from '@assistant-ui/react'\nimport { Loader2 } from 'lucide-react'\nimport { useState } from 'react'\n\nimport { usePendingToolCalls } from '../../hooks/usePendingToolCalls'\nimport { TOOL_DENIED_MESSAGE } from '../../lib/format'\nimport { resolveAllPendingToolCalls } from '../../lib/thread-utils'\nimport { cn } from '../../lib/utils'\nimport { useMCPTools } from '../../providers/MCPToolsProvider'\nimport { formatToolResult } from '../MCPToolRegistry'\nimport { ToolApprovalCard } from './ToolApprovalCard'\n\nimport type { FC } from 'react'\n\nexport interface ElicitationButtonBarProps {\n\t/** Additional class name */\n\tclassName?: string\n}\n\n/**\n * Approval card for tool execution that sits above the composer.\n * Shows tool name, description, and arguments when a tool requires approval.\n *\n * Returns null if there are no pending approvals.\n */\nexport const ElicitationButtonBar: FC<ElicitationButtonBarProps> = ({ className }) => {\n\tconst [isExecuting, setIsExecuting] = useState(false)\n\tconst pendingToolCalls = usePendingToolCalls()\n\tconst threadRuntime = useThreadRuntime()\n\tconst { callTool, tools } = useMCPTools()\n\n\t// Don't render if no pending approvals\n\tif (pendingToolCalls.length === 0) {\n\t\treturn null\n\t}\n\n\t// Get the first pending tool call\n\tconst firstTool = pendingToolCalls[0]\n\n\t// Get tool metadata\n\tconst toolDescription = tools.find((t) => t.name === firstTool.toolName)?.description\n\n\t// Get the message part runtime for this tool call\n\tconst getPartRuntime = () => {\n\t\tconst messageRuntime = threadRuntime?.getMessageById(firstTool.messageId)\n\t\tif (!messageRuntime) return null\n\n\t\t// Ensure the pending part still exists before creating a runtime; voice/text race conditions\n\t\t// can remove the part between renders and tool execution.\n\t\tconst hasPendingPart = messageRuntime\n\t\t\t.getState()\n\t\t\t.content.some(\n\t\t\t\t(part) =>\n\t\t\t\t\tpart.type === 'tool-call' &&\n\t\t\t\t\tpart.toolCallId === firstTool.toolCallId &&\n\t\t\t\t\tpart.result === undefined\n\t\t\t)\n\t\tif (!hasPendingPart) return null\n\n\t\ttry {\n\t\t\treturn messageRuntime.getMessagePartByToolCallId(firstTool.toolCallId)\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message === 'Entry not available in the store') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tconst handleAccept = async () => {\n\t\tsetIsExecuting(true)\n\t\ttry {\n\t\t\tconst toolResult = await callTool(firstTool.toolName, firstTool.args)\n\t\t\tconst partRuntime = getPartRuntime()\n\t\t\tpartRuntime?.addToolResult(formatToolResult(toolResult))\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\t\tconst partRuntime = getPartRuntime()\n\t\t\tpartRuntime?.addToolResult(`Error: ${errorMessage}`)\n\t\t} finally {\n\t\t\tsetIsExecuting(false)\n\t\t}\n\t}\n\n\tconst handleDeny = () => {\n\t\t// Resolve all pending tool calls with denial message to prevent stuck state\n\t\tresolveAllPendingToolCalls(threadRuntime, TOOL_DENIED_MESSAGE)\n\t\t// Stop the thread entirely - user doesn't want to continue\n\t\tthreadRuntime.cancelRun()\n\t}\n\n\t// Show loading state while executing\n\tif (isExecuting) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn('rounded-xl border border-blue-500/30 bg-blue-500/10 px-3 py-2.5', className)}\n\t\t\t>\n\t\t\t\t<div className=\"flex items-center justify-center gap-2\">\n\t\t\t\t\t<Loader2 className=\"h-4 w-4 animate-spin text-blue-400\" />\n\t\t\t\t\t<span className=\"text-sm text-white/80\">Executing...</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t)\n\t}\n\n\treturn (\n\t\t<ToolApprovalCard\n\t\t\ttoolName={firstTool.toolName}\n\t\t\tdescription={toolDescription}\n\t\t\targs={firstTool.args}\n\t\t\tisExecuting={isExecuting}\n\t\t\tonApprove={handleAccept}\n\t\t\tonDeny={handleDeny}\n\t\t\tclassName={cn('px-3 py-2.5', className)}\n\t\t/>\n\t)\n}\n\nexport default ElicitationButtonBar\n","'use client'\n\nimport {\n\tComposerPrimitive,\n\tThreadPrimitive,\n\tuseComposer,\n\tuseComposerRuntime,\n} from '@assistant-ui/react'\nimport { Mic, Send, Square } from 'lucide-react'\nimport { useCallback, useRef } from 'react'\n\nimport { useMobileDetect } from '../../hooks/useMobileDetect'\nimport { COMPOSER_MAX_CHARS } from '../../lib/constants'\nimport { cn } from '../../lib/utils'\n\nimport type { FC } from 'react'\n\ninterface PillComposerProps {\n\tplaceholder?: string\n\tshowVoiceButton?: boolean\n\tisVoiceActive?: boolean\n\tonVoiceToggle?: () => void\n\tshowCharCount?: boolean\n\tclassName?: string\n\t/** Whether in elicitation mode (tool approval pending) */\n\tisEliciting?: boolean\n\t/** Called when user submits text during elicitation (denial with reason) */\n\tonElicitationSubmit?: (reason: string) => void\n\t/** Whether in voice mode (sends text via voice session instead of chat) */\n\tisVoiceMode?: boolean\n\t/** Called when user submits text during voice mode */\n\tonVoiceSend?: (text: string) => void\n}\n\n/**\n * Character count indicator\n */\nconst CharacterCount: FC = () => {\n\tconst composer = useComposer((c) => c.text)\n\tconst charCount = composer?.length ?? 0\n\n\t// Only show when approaching limit or over\n\tif (charCount < COMPOSER_MAX_CHARS * 0.8) return null\n\n\tconst isOver = charCount > COMPOSER_MAX_CHARS\n\tconst remaining = COMPOSER_MAX_CHARS - charCount\n\n\treturn (\n\t\t<span className={cn('text-[10px] tabular-nums', isOver ? 'text-red-400' : 'text-white/40')}>\n\t\t\t{remaining}\n\t\t</span>\n\t)\n}\n\n/**\n * Compact composer for the pill UI.\n * Uses assistant-ui primitives for data binding.\n * Features auto-growing textarea and character count.\n */\nexport const PillComposer: FC<PillComposerProps> = ({\n\tplaceholder = 'Ask something...',\n\tshowVoiceButton = false,\n\tisVoiceActive = false,\n\tonVoiceToggle,\n\tshowCharCount = true,\n\tclassName,\n\tisEliciting = false,\n\tonElicitationSubmit,\n\tisVoiceMode = false,\n\tonVoiceSend,\n}) => {\n\t// Don't auto-focus on mobile to avoid triggering the keyboard immediately\n\tconst { isMobile } = useMobileDetect()\n\tconst inputRef = useRef<HTMLTextAreaElement>(null)\n\tconst composerRuntime = useComposerRuntime()\n\n\t// Dynamic placeholder based on elicitation state\n\tconst effectivePlaceholder = isEliciting ? 'Tell Char what to do differently' : placeholder\n\n\t// Blur input on submit to dismiss mobile keyboard\n\tconst handleSubmit = useCallback(() => {\n\t\tif (isMobile && inputRef.current) {\n\t\t\tinputRef.current.blur()\n\t\t}\n\t}, [isMobile])\n\n\t// Handle elicitation submission (denial with reason)\n\tconst handleElicitationSubmit = useCallback(() => {\n\t\tconst text = composerRuntime.getState().text.trim()\n\t\tif (text && onElicitationSubmit) {\n\t\t\tonElicitationSubmit(text)\n\t\t\tcomposerRuntime.setText('')\n\t\t\tif (isMobile && inputRef.current) {\n\t\t\t\tinputRef.current.blur()\n\t\t\t}\n\t\t}\n\t}, [composerRuntime, onElicitationSubmit, isMobile])\n\n\t// Handle voice mode submission (send text via voice session)\n\tconst handleVoiceSend = useCallback(() => {\n\t\tconst text = composerRuntime.getState().text.trim()\n\t\tif (text && onVoiceSend) {\n\t\t\tonVoiceSend(text)\n\t\t\tcomposerRuntime.setText('')\n\t\t\tif (isMobile && inputRef.current) {\n\t\t\t\tinputRef.current.blur()\n\t\t\t}\n\t\t}\n\t}, [composerRuntime, onVoiceSend, isMobile])\n\n\t// Handle Enter key during elicitation or voice mode - prevent normal form submission\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (e.key === 'Enter' && !e.shiftKey) {\n\t\t\t\tif (isVoiceMode) {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\thandleVoiceSend()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (isEliciting) {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\thandleElicitationSubmit()\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[isVoiceMode, handleVoiceSend, isEliciting, handleElicitationSubmit]\n\t)\n\n\treturn (\n\t\t<ComposerPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\t'flex items-end gap-1.5',\n\t\t\t\t'rounded-xl',\n\t\t\t\t'bg-white/8 border border-white/8',\n\t\t\t\t'px-2 py-1',\n\t\t\t\t'focus-within:border-white/15 focus-within:bg-white/10',\n\t\t\t\t'transition-colors duration-150',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tonSubmit={handleSubmit}\n\t\t>\n\t\t\t{/* Text input - auto-grows with content */}\n\t\t\t<ComposerPrimitive.Input\n\t\t\t\tref={inputRef}\n\t\t\t\tplaceholder={effectivePlaceholder}\n\t\t\t\tminRows={1}\n\t\t\t\tmaxRows={6}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'flex-1 min-w-0',\n\t\t\t\t\t'bg-transparent',\n\t\t\t\t\t'text-sm leading-[21px] text-white placeholder:text-white/40',\n\t\t\t\t\t'outline-none',\n\t\t\t\t\t'resize-none',\n\t\t\t\t\t'overflow-y-auto scroll-touch'\n\t\t\t\t)}\n\t\t\t\tstyle={{ touchAction: 'pan-y' }}\n\t\t\t\tautoFocus={!isMobile}\n\t\t\t\t// Stop pointer events from bubbling to drag handler when typing\n\t\t\t\tonPointerDownCapture={(e) => e.stopPropagation()}\n\t\t\t\t// Intercept Enter key during elicitation to call handleElicitationSubmit\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t/>\n\n\t\t\t{/* Character count */}\n\t\t\t{showCharCount && <CharacterCount />}\n\n\t\t\t{/* Voice button (optional) - hidden when already in voice mode */}\n\t\t\t{showVoiceButton && onVoiceToggle && !isVoiceMode && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onVoiceToggle}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t'p-2 sm:p-1.5 rounded-full',\n\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\tisVoiceActive\n\t\t\t\t\t\t\t? 'bg-white/20 text-white'\n\t\t\t\t\t\t\t: 'hover:bg-white/10 text-white/50 hover:text-white/80'\n\t\t\t\t\t)}\n\t\t\t\t\taria-label={isVoiceActive ? 'Stop voice input' : 'Start voice input'}\n\t\t\t\t>\n\t\t\t\t\t<Mic className=\"h-4.5 w-4.5 sm:h-4 sm:w-4\" />\n\t\t\t\t</button>\n\t\t\t)}\n\n\t\t\t{/* Send button - shown when not running */}\n\t\t\t<ThreadPrimitive.If running={false}>\n\t\t\t\t{isVoiceMode ? (\n\t\t\t\t\t/* Voice mode: custom button that sends text via voice session */\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleVoiceSend}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t\t'p-2 sm:p-1.5 rounded-full',\n\t\t\t\t\t\t\t'bg-white/90 text-slate-900',\n\t\t\t\t\t\t\t'hover:bg-white',\n\t\t\t\t\t\t\t'disabled:opacity-40 disabled:cursor-not-allowed',\n\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\taria-label=\"Send message in voice mode\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Send className=\"h-4.5 w-4.5 sm:h-4 sm:w-4\" />\n\t\t\t\t\t</button>\n\t\t\t\t) : isEliciting ? (\n\t\t\t\t\t/* During elicitation: custom button that sends denial with reason */\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleElicitationSubmit}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t\t'p-2 sm:p-1.5 rounded-full',\n\t\t\t\t\t\t\t'bg-white/90 text-slate-900',\n\t\t\t\t\t\t\t'hover:bg-white',\n\t\t\t\t\t\t\t'disabled:opacity-40 disabled:cursor-not-allowed',\n\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\taria-label=\"Send feedback\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Send className=\"h-4.5 w-4.5 sm:h-4 sm:w-4\" />\n\t\t\t\t\t</button>\n\t\t\t\t) : (\n\t\t\t\t\t/* Normal mode: use ComposerPrimitive.Send for standard message sending */\n\t\t\t\t\t<ComposerPrimitive.Send asChild>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t\t\t'p-2 sm:p-1.5 rounded-full',\n\t\t\t\t\t\t\t\t'bg-white/90 text-slate-900',\n\t\t\t\t\t\t\t\t'hover:bg-white',\n\t\t\t\t\t\t\t\t'disabled:opacity-40 disabled:cursor-not-allowed',\n\t\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\taria-label=\"Send message\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Send className=\"h-4.5 w-4.5 sm:h-4 sm:w-4\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</ComposerPrimitive.Send>\n\t\t\t\t)}\n\t\t\t</ThreadPrimitive.If>\n\n\t\t\t{/* Cancel button - shown when running */}\n\t\t\t<ThreadPrimitive.If running>\n\t\t\t\t<ComposerPrimitive.Cancel asChild>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t\t'p-2 sm:p-1.5 rounded-full',\n\t\t\t\t\t\t\t'bg-white/20 text-white',\n\t\t\t\t\t\t\t'hover:bg-white/30',\n\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\taria-label=\"Stop generating\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Square className=\"h-4 w-4 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t</button>\n\t\t\t\t</ComposerPrimitive.Cancel>\n\t\t\t</ThreadPrimitive.If>\n\t\t</ComposerPrimitive.Root>\n\t)\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\n\n/**\n * Hook to manage aria-hidden on background content when a modal is open.\n *\n * This hook sets aria-hidden=\"true\" on all direct children of <body> except\n * the element containing the dialog, making the background inaccessible to\n * screen readers while the modal is active.\n *\n * Per WCAG, this is important because some mobile screen readers don't\n * consistently respect aria-modal=\"true\", so we need to explicitly hide\n * the background content.\n *\n * @param isActive - Whether the modal is currently active\n * @param containerRef - Ref to the modal container element\n */\nexport function useAriaHidden(\n\tisActive: boolean,\n\tcontainerRef: React.RefObject<HTMLElement | null>\n): void {\n\t// Track elements we've modified so we can restore them\n\tconst modifiedElementsRef = useRef<Map<Element, string | null>>(new Map())\n\n\tuseEffect(() => {\n\t\tif (!isActive) {\n\t\t\t// Restore all modified elements when modal closes\n\t\t\tmodifiedElementsRef.current.forEach((originalValue, element) => {\n\t\t\t\tif (originalValue === null) {\n\t\t\t\t\telement.removeAttribute('aria-hidden')\n\t\t\t\t} else {\n\t\t\t\t\telement.setAttribute('aria-hidden', originalValue)\n\t\t\t\t}\n\t\t\t})\n\t\t\tmodifiedElementsRef.current.clear()\n\t\t\treturn\n\t\t}\n\n\t\t// Find the container element's root ancestor (direct child of body)\n\t\tconst container = containerRef.current\n\t\tif (!container) return\n\n\t\t// Walk up to find the direct child of body\n\t\tlet dialogRoot: Element | null = container\n\t\twhile (dialogRoot && dialogRoot.parentElement !== document.body) {\n\t\t\tdialogRoot = dialogRoot.parentElement\n\t\t}\n\n\t\tif (!dialogRoot) return\n\n\t\t// Get all direct children of body\n\t\tconst bodyChildren = Array.from(document.body.children)\n\n\t\t// Hide all siblings of the dialog root\n\t\tbodyChildren.forEach((child) => {\n\t\t\t// Skip the dialog's root ancestor\n\t\t\tif (child === dialogRoot) return\n\n\t\t\t// Skip script and style elements\n\t\t\tif (child.tagName === 'SCRIPT' || child.tagName === 'STYLE' || child.tagName === 'LINK') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Store the original aria-hidden value\n\t\t\tconst originalValue = child.getAttribute('aria-hidden')\n\t\t\tmodifiedElementsRef.current.set(child, originalValue)\n\n\t\t\t// Set aria-hidden to true\n\t\t\tchild.setAttribute('aria-hidden', 'true')\n\t\t})\n\n\t\t// Cleanup function to restore original values\n\t\treturn () => {\n\t\t\tmodifiedElementsRef.current.forEach((originalValue, element) => {\n\t\t\t\tif (originalValue === null) {\n\t\t\t\t\telement.removeAttribute('aria-hidden')\n\t\t\t\t} else {\n\t\t\t\t\telement.setAttribute('aria-hidden', originalValue)\n\t\t\t\t}\n\t\t\t})\n\t\t\tmodifiedElementsRef.current.clear()\n\t\t}\n\t}, [isActive, containerRef])\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef } from 'react'\n\n/** Selector for all focusable elements within a container */\nconst FOCUSABLE_SELECTOR = [\n\t'a[href]',\n\t'button:not([disabled])',\n\t'input:not([disabled])',\n\t'select:not([disabled])',\n\t'textarea:not([disabled])',\n\t'[tabindex]:not([tabindex=\"-1\"])',\n\t'[contenteditable=\"true\"]',\n].join(', ')\n\ninterface UseFocusTrapOptions {\n\t/** Whether the focus trap is active */\n\tisActive: boolean\n\t/** Callback when user attempts to escape (e.g., pressing Escape) */\n\tonEscape?: () => void\n\t/** Whether to auto-focus the first focusable element when activated */\n\tautoFocus?: boolean\n\t/** Whether to return focus to the trigger element when deactivated */\n\treturnFocus?: boolean\n\t/** Whether to skip returning focus to input elements (prevents mobile keyboard re-trigger) */\n\tskipInputFocusReturn?: boolean\n}\n\ninterface UseFocusTrapReturn {\n\t/** Ref to attach to the container element */\n\tcontainerRef: React.RefObject<HTMLDivElement | null>\n\t/** Store the trigger element before activating the trap */\n\tstoreTrigger: () => void\n}\n\n/**\n * Focus trap hook for modal dialogs.\n *\n * Implements WCAG 2.4.3 Focus Order requirements:\n * - Traps Tab/Shift+Tab within the container\n * - Returns focus to trigger element on close\n * - Supports Escape key to close\n *\n * @example\n * ```tsx\n * const { containerRef, storeTrigger } = useFocusTrap({\n * isActive: isDialogOpen,\n * onEscape: () => setIsDialogOpen(false),\n * })\n *\n * // Before opening dialog:\n * storeTrigger()\n * setIsDialogOpen(true)\n *\n * // In JSX:\n * <div ref={containerRef} role=\"dialog\">...</div>\n * ```\n */\nexport function useFocusTrap({\n\tisActive,\n\tonEscape,\n\tautoFocus = true,\n\treturnFocus = true,\n\tskipInputFocusReturn = false,\n}: UseFocusTrapOptions): UseFocusTrapReturn {\n\tconst containerRef = useRef<HTMLDivElement | null>(null)\n\tconst triggerRef = useRef<HTMLElement | null>(null)\n\tconst previouslyFocusedRef = useRef<HTMLElement | null>(null)\n\n\t/** Store the currently focused element as the trigger */\n\tconst storeTrigger = useCallback(() => {\n\t\ttriggerRef.current = document.activeElement as HTMLElement\n\t}, [])\n\n\t/** Get all focusable elements within the container */\n\tconst getFocusableElements = useCallback((): HTMLElement[] => {\n\t\tif (!containerRef.current) return []\n\t\treturn Array.from(containerRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n\t}, [])\n\n\t// Handle focus trap activation/deactivation\n\tuseEffect(() => {\n\t\tif (isActive) {\n\t\t\t// Store the currently focused element before trapping\n\t\t\tpreviouslyFocusedRef.current = document.activeElement as HTMLElement\n\n\t\t\t// Auto-focus the first focusable element\n\t\t\tif (autoFocus) {\n\t\t\t\t// Small delay to ensure container is mounted and visible\n\t\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\t\tconst focusableElements = getFocusableElements()\n\t\t\t\t\tif (focusableElements.length > 0) {\n\t\t\t\t\t\tfocusableElements[0].focus()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If no focusable elements, focus the container itself\n\t\t\t\t\t\tcontainerRef.current?.focus()\n\t\t\t\t\t}\n\t\t\t\t}, 50)\n\n\t\t\t\treturn () => clearTimeout(timeoutId)\n\t\t\t}\n\t\t} else {\n\t\t\t// Return focus to the trigger element\n\t\t\tif (returnFocus && triggerRef.current && triggerRef.current.isConnected) {\n\t\t\t\t// Skip returning focus to inputs/textareas if configured (prevents mobile keyboard re-trigger)\n\t\t\t\tconst isInputElement =\n\t\t\t\t\ttriggerRef.current.tagName === 'INPUT' || triggerRef.current.tagName === 'TEXTAREA'\n\n\t\t\t\tif (skipInputFocusReturn && isInputElement) {\n\t\t\t\t\t// Blur the input instead of focusing it\n\t\t\t\t\ttriggerRef.current.blur()\n\t\t\t\t} else {\n\t\t\t\t\ttriggerRef.current.focus()\n\t\t\t\t}\n\t\t\t} else if (returnFocus && previouslyFocusedRef.current?.isConnected) {\n\t\t\t\tconst isInputElement =\n\t\t\t\t\tpreviouslyFocusedRef.current.tagName === 'INPUT' ||\n\t\t\t\t\tpreviouslyFocusedRef.current.tagName === 'TEXTAREA'\n\n\t\t\t\tif (skipInputFocusReturn && isInputElement) {\n\t\t\t\t\tpreviouslyFocusedRef.current.blur()\n\t\t\t\t} else {\n\t\t\t\t\tpreviouslyFocusedRef.current.focus()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [isActive, autoFocus, returnFocus, skipInputFocusReturn, getFocusableElements])\n\n\t// Handle keyboard navigation\n\tuseEffect(() => {\n\t\tif (!isActive) return\n\n\t\tconst handleKeyDown = (event: KeyboardEvent) => {\n\t\t\t// Handle Escape key\n\t\t\tif (event.key === 'Escape' && onEscape) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEscape()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Handle Tab key for focus trapping\n\t\t\tif (event.key === 'Tab') {\n\t\t\t\tconst focusableElements = getFocusableElements()\n\t\t\t\tif (focusableElements.length === 0) return\n\n\t\t\t\tconst firstElement = focusableElements[0]\n\t\t\t\tconst lastElement = focusableElements[focusableElements.length - 1]\n\t\t\t\tconst activeElement = document.activeElement\n\n\t\t\t\t// Shift+Tab from first element -> go to last\n\t\t\t\tif (event.shiftKey && activeElement === firstElement) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tlastElement.focus()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Tab from last element -> go to first\n\t\t\t\tif (!event.shiftKey && activeElement === lastElement) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstElement.focus()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If focus is outside the container, bring it back\n\t\t\t\tif (!containerRef.current?.contains(activeElement)) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirstElement.focus()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => document.removeEventListener('keydown', handleKeyDown)\n\t}, [isActive, onEscape, getFocusableElements])\n\n\treturn {\n\t\tcontainerRef,\n\t\tstoreTrigger,\n\t}\n}\n","'use client'\n\nimport { AnimatePresence, motion, useReducedMotion } from 'motion/react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { useAriaHidden } from '../../hooks/useAriaHidden'\nimport { useFocusTrap } from '../../hooks/useFocusTrap'\nimport { useMobileDetect } from '../../hooks/useMobileDetect'\nimport {\n\tARIA_IDS,\n\tARIA_LABELS,\n\tclampSize,\n\tFULL_SCREEN_CONFIG,\n\tPILL_BORDER_RADIUS,\n\tPILL_CONTAINER_SIZES,\n\tUI_TIMING,\n} from '../../lib/constants'\nimport { cn } from '../../lib/utils'\n\nimport type { Variants } from 'motion/react'\nimport type { FC, ReactNode } from 'react'\nimport type { PillMode } from '../../core/providers/AgentUIProvider'\n\n// Re-export PillMode for consumers who import from this file\nexport type { PillMode } from '../../core/providers/AgentUIProvider'\n\ninterface PillContainerProps {\n\tmode: PillMode\n\tchildren: ReactNode\n\tonModeChange?: (mode: PillMode) => void\n\t/** Whether the pill is in full-screen expanded mode */\n\tisFullScreen?: boolean\n\tclassName?: string\n}\n\n// Spring configuration for size changes - snappy but smooth\nconst sizeSpring = {\n\ttype: 'spring' as const,\n\tstiffness: 400,\n\tdamping: 35,\n\tmass: 0.8,\n}\n\n// Smooth tween for full-screen transitions (spring is too aggressive for large viewport changes)\nconst fullScreenTween = {\n\ttype: 'tween' as const,\n\tduration: 0.35,\n\tease: [0.4, 0, 0.2, 1], // Material Design standard easing\n}\n\n// Reduced motion alternative - instant transitions\nconst reducedMotionTransition = {\n\tduration: 0,\n}\n\n// Container size variants - derived from centralized PILL_CONTAINER_SIZES config\n// See lib/constants.ts for the source of truth\n// Padding reduced for better mobile information density\nconst sizes = PILL_CONTAINER_SIZES\nconst containerVariants: Record<\n\tPillMode,\n\t{ width: string; height: string; padding: string; borderRadius: string }\n> = {\n\tcollapsed: {\n\t\twidth: clampSize(sizes.collapsed.width),\n\t\theight: clampSize(sizes.collapsed.height),\n\t\tpadding: '0px',\n\t\tborderRadius: PILL_BORDER_RADIUS.pill,\n\t},\n\thovered: {\n\t\twidth: clampSize(sizes.hovered.width),\n\t\theight: clampSize(sizes.hovered.height),\n\t\tpadding: '0px 10px',\n\t\tborderRadius: PILL_BORDER_RADIUS.pill,\n\t},\n\tcomposing: {\n\t\twidth: clampSize(sizes.composing.width),\n\t\theight: 'auto',\n\t\tpadding: '8px 10px',\n\t\tborderRadius: PILL_BORDER_RADIUS.rounded,\n\t},\n\tactive: {\n\t\twidth: clampSize(sizes.active.width),\n\t\theight: 'auto',\n\t\tpadding: '8px 10px',\n\t\tborderRadius: PILL_BORDER_RADIUS.rounded,\n\t},\n\texpanded: {\n\t\twidth: clampSize(sizes.expanded.width),\n\t\theight: 'auto',\n\t\tpadding: '10px 10px',\n\t\tborderRadius: PILL_BORDER_RADIUS.rounded,\n\t},\n}\n\n// Full-screen variant - uses the same animation system\nconst fullScreenVariant = {\n\twidth: `min(${FULL_SCREEN_CONFIG.widthPercent}vw, ${FULL_SCREEN_CONFIG.maxWidth})`,\n\theight: `${FULL_SCREEN_CONFIG.heightPercent}vh`,\n\tpadding: `${FULL_SCREEN_CONFIG.padding}px`,\n\tborderRadius: PILL_BORDER_RADIUS.rounded,\n}\n\n// Content animation variants - simple fade, no transform\nconst contentVariants: Variants = {\n\thidden: {\n\t\topacity: 0,\n\t},\n\tvisible: {\n\t\topacity: 1,\n\t\ttransition: {\n\t\t\tduration: 0.15,\n\t\t\tdelay: 0.1, // Wait for container to expand first\n\t\t},\n\t},\n\texit: {\n\t\topacity: 0,\n\t\ttransition: {\n\t\t\tduration: 0.1,\n\t\t},\n\t},\n}\n\n// Hint text animation - simple fade\nconst hintVariants: Variants = {\n\thidden: { opacity: 0 },\n\tvisible: {\n\t\topacity: 1,\n\t\ttransition: { delay: 0.05, duration: 0.15 },\n\t},\n\texit: {\n\t\topacity: 0,\n\t\ttransition: { duration: 0.08 },\n\t},\n}\n\n// Collapsed bar animation\nconst barVariants: Variants = {\n\tidle: {\n\t\topacity: 0.6,\n\t\tscaleX: 1,\n\t},\n\thover: {\n\t\topacity: 1,\n\t\tscaleX: 1.1,\n\t\ttransition: { duration: 0.2 },\n\t},\n}\n\n/**\n * Morphing container that changes size and shape based on state.\n * Uses spring animations for smooth, natural transitions.\n *\n * States:\n * - collapsed: Tiny 4px tall bar (ambient)\n * - hovered: Medium pill with prompt\n * - composing: User is typing\n * - active: Agent is working\n * - expanded: Full panel with summary/forms\n */\nexport const PillContainer: FC<PillContainerProps> = ({\n\tmode,\n\tchildren,\n\tonModeChange,\n\tisFullScreen = false,\n\tclassName,\n}) => {\n\tconst [isHovered, setIsHovered] = useState(false)\n\tconst hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n\tconst prefersReducedMotion = useReducedMotion()\n\n\t// Track previous full-screen state for smooth exit animations\n\tconst wasFullScreenRef = useRef(isFullScreen)\n\tconst isTransitioningFullScreen = isFullScreen !== wasFullScreenRef.current\n\t// Update ref after render\n\tuseEffect(() => {\n\t\twasFullScreenRef.current = isFullScreen\n\t}, [isFullScreen])\n\n\t// Detect mobile/touch devices\n\tconst { isMobile } = useMobileDetect()\n\n\t// Determine if dialog mode (for focus trap)\n\tconst isDialogActive = mode === 'composing' || mode === 'active' || mode === 'expanded'\n\n\t// Focus trap for accessibility - traps focus when in dialog mode\n\tconst { containerRef: focusTrapRef, storeTrigger } = useFocusTrap({\n\t\tisActive: isDialogActive,\n\t\tonEscape: () => {\n\t\t\t// Only collapse if not in active mode (agent is working)\n\t\t\tif (mode !== 'active') {\n\t\t\t\tonModeChange?.('collapsed')\n\t\t\t}\n\t\t},\n\t\tautoFocus: true,\n\t\treturnFocus: true,\n\t\t// On mobile, don't return focus to inputs (prevents keyboard re-triggering)\n\t\tskipInputFocusReturn: isMobile,\n\t})\n\n\t// Store trigger element before transitioning to dialog mode\n\tconst prevModeRef = useRef(mode)\n\tuseEffect(() => {\n\t\tconst wasCollapsedOrHovered =\n\t\t\tprevModeRef.current === 'collapsed' || prevModeRef.current === 'hovered'\n\t\tconst isNowDialog = mode === 'composing' || mode === 'active' || mode === 'expanded'\n\n\t\tif (wasCollapsedOrHovered && isNowDialog) {\n\t\t\tstoreTrigger()\n\t\t}\n\n\t\tprevModeRef.current = mode\n\t}, [mode, storeTrigger])\n\n\t// Hide background content from screen readers when in dialog mode\n\t// This is a fallback for mobile screen readers that don't respect aria-modal\n\tuseAriaHidden(isDialogActive, focusTrapRef)\n\n\t// Handle hover with debounce - only on non-touch devices\n\tconst handleMouseEnter = useCallback(() => {\n\t\t// Skip hover behavior on touch devices\n\t\tif (isMobile) return\n\n\t\tif (hoverTimeoutRef.current) {\n\t\t\tclearTimeout(hoverTimeoutRef.current)\n\t\t}\n\t\thoverTimeoutRef.current = setTimeout(() => {\n\t\t\tsetIsHovered(true)\n\t\t\tif (mode === 'collapsed') {\n\t\t\t\tonModeChange?.('hovered')\n\t\t\t}\n\t\t}, UI_TIMING.hoverDebounce)\n\t}, [mode, onModeChange, isMobile])\n\n\tconst handleMouseLeave = useCallback(() => {\n\t\t// Skip hover behavior on touch devices\n\t\tif (isMobile) return\n\n\t\tif (hoverTimeoutRef.current) {\n\t\t\tclearTimeout(hoverTimeoutRef.current)\n\t\t}\n\t\tsetIsHovered(false)\n\t\tif (mode === 'hovered') {\n\t\t\t// Small delay before collapsing to prevent flicker\n\t\t\thoverTimeoutRef.current = setTimeout(() => {\n\t\t\t\tonModeChange?.('collapsed')\n\t\t\t}, UI_TIMING.collapseDelay)\n\t\t}\n\t}, [mode, onModeChange, isMobile])\n\n\t// Handle click/tap to expand - on mobile, skip hover and go straight to composing\n\tconst handleClick = useCallback(() => {\n\t\tif (mode === 'collapsed' || mode === 'hovered') {\n\t\t\tonModeChange?.('composing')\n\t\t}\n\t}, [mode, onModeChange])\n\n\t// Handle focus for keyboard navigation - also helps on touch\n\tconst handleFocus = useCallback(() => {\n\t\tif (mode === 'collapsed' && !isMobile) {\n\t\t\tonModeChange?.('hovered')\n\t\t}\n\t}, [mode, onModeChange, isMobile])\n\n\tconst handleBlur = useCallback(() => {\n\t\tif (mode === 'hovered' && !isMobile) {\n\t\t\tonModeChange?.('collapsed')\n\t\t}\n\t}, [mode, onModeChange, isMobile])\n\n\t// Handle keyboard shortcuts (Cmd+Shift+K to toggle, Escape to close)\n\tuseEffect(() => {\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tconst isShortcut = (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === 'k'\n\t\t\tconst isEscape = e.key === 'Escape'\n\n\t\t\tif (isShortcut) {\n\t\t\t\te.preventDefault()\n\t\t\t\tif (mode === 'collapsed') {\n\t\t\t\t\tonModeChange?.('composing')\n\t\t\t\t} else if (mode === 'composing' || mode === 'hovered') {\n\t\t\t\t\tonModeChange?.('collapsed')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Escape to close (only when expanded, not when agent is running)\n\t\t\tif (isEscape && (mode === 'composing' || mode === 'expanded' || mode === 'hovered')) {\n\t\t\t\te.preventDefault()\n\t\t\t\tonModeChange?.('collapsed')\n\t\t\t}\n\t\t}\n\n\t\twindow.addEventListener('keydown', handleKeyDown)\n\t\treturn () => window.removeEventListener('keydown', handleKeyDown)\n\t}, [mode, onModeChange])\n\n\t// Clean up timeout on unmount\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tif (hoverTimeoutRef.current) {\n\t\t\t\tclearTimeout(hoverTimeoutRef.current)\n\t\t\t}\n\t\t}\n\t}, [])\n\n\tconst showContent = mode !== 'collapsed' && mode !== 'hovered'\n\t// Use full-screen variant when in full-screen mode, otherwise use mode-based variant\n\tconst currentVariant = isFullScreen ? fullScreenVariant : containerVariants[mode]\n\tconst isDialogMode = mode === 'composing' || mode === 'active' || mode === 'expanded'\n\n\t// Combine refs for motion.div (focus trap ref + internal needs)\n\tconst setContainerRef = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\t// Update the focus trap ref\n\t\t\tif (focusTrapRef) {\n\t\t\t\tfocusTrapRef.current = node\n\t\t\t}\n\t\t},\n\t\t[focusTrapRef]\n\t)\n\n\t// Determine glass styling class based on mode\n\tconst glassClassName = cn(\n\t\t'relative',\n\t\t// Full-screen: allow scrolling. Normal: clip overflow during animations\n\t\tisFullScreen ? 'overflow-y-auto scrollbar-thin scroll-touch' : 'overflow-hidden',\n\t\t// GPU acceleration hint (skip if reduced motion)\n\t\t!prefersReducedMotion && 'will-change-transform',\n\t\t// Focus states for keyboard navigation\n\t\t'focus:outline-none focus-visible:ring-2 focus-visible:ring-white/30 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent',\n\t\t// Base glass styling (overridden by mode-specific classes)\n\t\tmode === 'collapsed' && 'glass-pill-collapsed',\n\t\tmode === 'hovered' && 'glass-pill-hovered',\n\t\t(mode === 'composing' || mode === 'expanded') && 'glass-pill',\n\t\tmode === 'active' && 'glass-pill glass-active',\n\t\tclassName\n\t)\n\n\t// Use reduced motion transition when user prefers it\n\t// Use smooth tween for full-screen transitions (spring is too aggressive for large viewport changes)\n\tconst transition = prefersReducedMotion\n\t\t? reducedMotionTransition\n\t\t: isTransitioningFullScreen || isFullScreen\n\t\t\t? fullScreenTween\n\t\t\t: sizeSpring\n\n\treturn (\n\t\t<motion.div\n\t\t\tref={setContainerRef}\n\t\t\tclassName={glassClassName}\n\t\t\tinitial={false}\n\t\t\tanimate={{\n\t\t\t\twidth: currentVariant.width,\n\t\t\t\theight: currentVariant.height,\n\t\t\t\tpadding: currentVariant.padding,\n\t\t\t\tborderRadius: currentVariant.borderRadius,\n\t\t\t}}\n\t\t\ttransition={transition}\n\t\t\tonMouseEnter={handleMouseEnter}\n\t\t\tonMouseLeave={handleMouseLeave}\n\t\t\tonClick={handleClick}\n\t\t\tonFocus={handleFocus}\n\t\t\tonBlur={handleBlur}\n\t\t\t// Button mode: collapsed/hovered - acts as a button to open\n\t\t\trole={isDialogMode ? 'dialog' : 'button'}\n\t\t\ttabIndex={isDialogMode ? -1 : 0}\n\t\t\t// Dialog mode: composing/active/expanded - acts as a modal dialog\n\t\t\taria-modal={isDialogMode ? true : undefined}\n\t\t\taria-labelledby={isDialogMode ? ARIA_IDS.pillTitle : undefined}\n\t\t\taria-label={!isDialogMode ? ARIA_LABELS.openAssistant : undefined}\n\t\t>\n\t\t\t{/* Collapsed state - glass shimmer highlight */}\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t{mode === 'collapsed' && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tkey=\"collapsed-bar\"\n\t\t\t\t\t\tclassName=\"absolute inset-0\"\n\t\t\t\t\t\tvariants={barVariants}\n\t\t\t\t\t\tinitial=\"idle\"\n\t\t\t\t\t\tanimate={isHovered ? 'hover' : 'idle'}\n\t\t\t\t\t\texit={{ opacity: 0, transition: { duration: 0.1 } }}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent)',\n\t\t\t\t\t\t\tbackgroundSize: '200% 100%',\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Hovered state - hint text */}\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t{mode === 'hovered' && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tkey=\"hover-hint\"\n\t\t\t\t\t\tclassName=\"relative z-10 flex h-full w-full items-center justify-center\"\n\t\t\t\t\t\tvariants={hintVariants}\n\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\texit=\"exit\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"text-xs text-white/70\">\n\t\t\t\t\t\t\tClick or{' '}\n\t\t\t\t\t\t\t<kbd className=\"rounded bg-white/10 px-1.5 py-0.5 font-mono text-[10px]\">⌘⇧K</kbd>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Expanded content - z-10 ensures content sits above glass highlight overlays */}\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t{showContent && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tkey=\"content\"\n\t\t\t\t\t\tclassName=\"relative z-10 flex flex-col gap-1.5\"\n\t\t\t\t\t\tvariants={contentVariants}\n\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\texit=\"exit\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Visually hidden title for screen readers (referenced by aria-labelledby) */}\n\t\t\t\t\t\t<span id={ARIA_IDS.pillTitle} className=\"sr-only\">\n\t\t\t\t\t\t\tAI Assistant\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\t\t</motion.div>\n\t)\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '../lib/utils'\n\nimport type { VariantProps } from 'class-variance-authority'\n\nexport interface ButtonProps\n\textends React.ComponentProps<'button'>,\n\t\tVariantProps<typeof buttonVariants> {\n\tasChild?: boolean\n}\n\nconst buttonVariants = cva(\n\t\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: 'bg-primary text-primary-foreground hover:bg-primary/90',\n\t\t\t\tdestructive:\n\t\t\t\t\t'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n\t\t\t\toutline:\n\t\t\t\t\t'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n\t\t\t\tsecondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n\t\t\t\tghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n\t\t\t\tlink: 'text-primary underline-offset-4 hover:underline',\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault: 'h-9 px-4 py-2 has-[>svg]:px-3',\n\t\t\t\tsm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n\t\t\t\tlg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n\t\t\t\ticon: 'size-9',\n\t\t\t\t'icon-sm': 'size-8',\n\t\t\t\t'icon-lg': 'size-10',\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: 'default',\n\t\t\tsize: 'default',\n\t\t},\n\t}\n)\n\nfunction Button({\n\tclassName,\n\tvariant,\n\tsize,\n\tasChild = false,\n\t...props\n}: React.ComponentProps<'button'> &\n\tVariantProps<typeof buttonVariants> & {\n\t\tasChild?: boolean\n\t}) {\n\tconst Comp = asChild ? Slot : 'button'\n\n\treturn (\n\t\t<Comp\n\t\t\tdata-slot=\"button\"\n\t\t\tclassName={cn(buttonVariants({ variant, size, className }))}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nexport { Button, buttonVariants }\n","/**\n * UnifiedToolFallback Component\n *\n * A unified fallback component that handles ALL tool call states:\n * - Running: Shows activity indicator with tool name\n * - Pending approval: Shows approval dialog for destructive tools\n * - Completed: Shows success indicator with collapsible args/result\n * - Error: Shows error state\n *\n * This provides an alternative to separate ActionList/CurrentActivity components\n * by rendering tool states directly in the message thread.\n */\n'use client'\n\nimport { AlertCircle, AlertTriangle, Check, ChevronDownIcon, ChevronUpIcon, X } from 'lucide-react'\nimport { useCallback, useEffect, useState } from 'react'\n\nimport { formatArgs, humanizeToolName, TOOL_DENIED_MESSAGE } from '../lib/format'\nimport { cn } from '../lib/utils'\nimport { useMCPTools } from '../providers/MCPToolsProvider'\nimport { Button } from './button'\nimport { formatToolResult } from './MCPToolRegistry'\nimport { getToolIcon } from './pill/ActivityIndicator'\n\nimport type { ToolCallMessagePartComponent } from '@assistant-ui/react'\n\n// ============================================================================\n// Approval Result Types\n// ============================================================================\n\ninterface ApprovedResult {\n\tapproved: true\n\tresult: string\n}\n\nfunction isApprovedResult(result: unknown): result is ApprovedResult {\n\treturn (\n\t\ttypeof result === 'object' &&\n\t\tresult !== null &&\n\t\t'approved' in result &&\n\t\t(result as ApprovedResult).approved === true &&\n\t\t'result' in result\n\t)\n}\n\n/**\n * Check if result indicates a denied tool execution.\n * Handles both string format (legacy) and structured format.\n */\nfunction isDeniedResult(result: unknown): boolean {\n\t// Check for string denial message\n\tif (typeof result === 'string' && result === TOOL_DENIED_MESSAGE) {\n\t\treturn true\n\t}\n\t// Check for structured denial (future-proofing)\n\tif (\n\t\ttypeof result === 'object' &&\n\t\tresult !== null &&\n\t\t'approved' in result &&\n\t\t(result as { approved: boolean }).approved === false\n\t) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * Type guard for status with error property\n */\nfunction hasStatusError(status: { type: string }): status is { type: string; error: string } {\n\treturn 'error' in status && typeof (status as { error?: unknown }).error === 'string'\n}\n\n// ============================================================================\n// Sub-Components for Each State\n// ============================================================================\n\n/**\n * Running state - tool is currently executing\n */\nconst RunningToolDisplay: React.FC<{\n\ttoolName: string\n}> = ({ toolName }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"my-1 flex items-center gap-1.5 rounded-lg bg-white/5 px-2 py-1.5 text-sm text-white/70\">\n\t\t\t<ToolIcon className=\"h-3.5 w-3.5 animate-pulse text-white/50\" />\n\t\t\t<span>\n\t\t\t\t<strong className=\"text-white/90\">{humanizeToolName(toolName)}</strong>\n\t\t\t</span>\n\t\t</div>\n\t)\n}\n\n/**\n * Approval dialog for destructive tools (HITL pattern)\n * Used when a tool has no execute function and requires user approval.\n */\nconst ApprovalDialog: React.FC<{\n\ttoolName: string\n\ttoolDescription?: string\n\tinputArgs: Record<string, unknown>\n\tonApprove: () => void\n\tonDeny: () => void\n\tisExecuting: boolean\n}> = ({ toolName, toolDescription, inputArgs, onApprove, onDeny, isExecuting }) => {\n\tconst [isHovered, setIsHovered] = useState<'approve' | 'deny' | null>(null)\n\tconst ToolIcon = getToolIcon(toolName)\n\n\tif (isExecuting) {\n\t\treturn (\n\t\t\t<div className=\"my-1 flex items-center gap-1.5 rounded-lg bg-white/5 px-2 py-1.5 text-sm text-white/70\">\n\t\t\t\t<ToolIcon className=\"h-3.5 w-3.5 animate-pulse text-white/50\" />\n\t\t\t\t<span>\n\t\t\t\t\t<strong className=\"text-white/90\">{humanizeToolName(toolName)}</strong>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t)\n\t}\n\n\treturn (\n\t\t<div className={cn('my-1 overflow-hidden rounded-lg', 'bg-white/5')}>\n\t\t\t{/* Header - compact */}\n\t\t\t<div className=\"flex items-center gap-1.5 px-2 py-1.5 border-b border-white/5\">\n\t\t\t\t<div className=\"relative\">\n\t\t\t\t\t<ToolIcon className=\"h-3.5 w-3.5 text-white/70\" />\n\t\t\t\t\t<AlertTriangle className=\"absolute -bottom-0.5 -right-0.5 h-2 w-2 text-white/70\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"text-xs font-medium text-white/90\">{humanizeToolName(toolName)}</span>\n\t\t\t</div>\n\n\t\t\t{/* Content */}\n\t\t\t<div className=\"px-2 py-2\">\n\t\t\t\t{toolDescription && (\n\t\t\t\t\t<div className=\"mb-2 line-clamp-3 text-xs text-white/50\">{toolDescription}</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Arguments - compact */}\n\t\t\t\t{inputArgs && Object.keys(inputArgs).length > 0 && (\n\t\t\t\t\t<div className=\"mb-2 rounded bg-white/5 p-1.5\">\n\t\t\t\t\t\t<pre className=\"whitespace-pre-wrap text-[11px] text-white/60\">\n\t\t\t\t\t\t\t{formatArgs(inputArgs)}\n\t\t\t\t\t\t</pre>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Action buttons - compact */}\n\t\t\t\t<div className=\"flex justify-end gap-1.5\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onDeny}\n\t\t\t\t\t\tonMouseEnter={() => setIsHovered('deny')}\n\t\t\t\t\t\tonMouseLeave={() => setIsHovered(null)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex items-center gap-1 rounded px-2.5 py-1.5 text-xs font-medium sm:px-2 sm:py-1',\n\t\t\t\t\t\t\t'border border-white/10 text-white/60',\n\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\tisHovered === 'deny' ? 'bg-white/10 text-white/80' : 'hover:bg-white/5'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X className=\"h-3.5 w-3.5 sm:h-3 sm:w-3\" />\n\t\t\t\t\t\tDeny\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onApprove}\n\t\t\t\t\t\tonMouseEnter={() => setIsHovered('approve')}\n\t\t\t\t\t\tonMouseLeave={() => setIsHovered(null)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex items-center gap-1 rounded px-2.5 py-1.5 text-xs font-medium sm:px-2 sm:py-1',\n\t\t\t\t\t\t\t'bg-white/90 text-slate-900',\n\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\tisHovered === 'approve' ? 'bg-white' : 'hover:bg-white/95'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Check className=\"h-3.5 w-3.5 sm:h-3 sm:w-3\" />\n\t\t\t\t\t\tOK\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/**\n * Completed tool display - success state with collapsible details\n */\nconst CompletedToolDisplay: React.FC<{\n\ttoolName: string\n\targsText: string\n\tresult: unknown\n}> = ({ toolName, argsText, result }) => {\n\tconst [isExpanded, setIsExpanded] = useState(false)\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"my-1 overflow-hidden rounded-lg bg-white/5\">\n\t\t\t{/* Header - compact */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={() => setIsExpanded(!isExpanded)}\n\t\t\t\tclassName=\"flex w-full items-center gap-1.5 px-2 py-1.5 text-left transition-colors hover:bg-white/5\"\n\t\t\t>\n\t\t\t\t<div className=\"relative\">\n\t\t\t\t\t<ToolIcon className=\"h-3.5 w-3.5 text-white/50\" />\n\t\t\t\t\t<Check className=\"absolute -bottom-0.5 -right-0.5 h-2 w-2 text-white/50\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"flex-grow text-xs font-medium text-white/80\">\n\t\t\t\t\t{humanizeToolName(toolName)}\n\t\t\t\t</span>\n\t\t\t\t<Button variant=\"ghost\" size=\"sm\" className=\"h-5 w-5 p-0\" asChild>\n\t\t\t\t\t<span>\n\t\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t\t<ChevronUpIcon className=\"h-3 w-3 text-white/40\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChevronDownIcon className=\"h-3 w-3 text-white/40\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t</button>\n\n\t\t\t{/* Expandable content */}\n\t\t\t{isExpanded && (\n\t\t\t\t<div className=\"border-t border-white/5 px-2 py-1.5\">\n\t\t\t\t\t{/* Input args */}\n\t\t\t\t\t{argsText && (\n\t\t\t\t\t\t<div className=\"mb-1.5\">\n\t\t\t\t\t\t\t<div className=\"mb-0.5 text-[10px] font-medium uppercase tracking-wide text-white/40\">\n\t\t\t\t\t\t\t\tInput\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<pre className=\"max-h-24 overflow-auto whitespace-pre-wrap rounded bg-white/5 p-1.5 font-mono text-[11px] text-white/60\">\n\t\t\t\t\t\t\t\t{argsText}\n\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Output result */}\n\t\t\t\t\t{result !== undefined && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div className=\"mb-0.5 text-[10px] font-medium uppercase tracking-wide text-white/40\">\n\t\t\t\t\t\t\t\tOutput\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<pre className=\"max-h-32 overflow-auto whitespace-pre-wrap rounded bg-white/5 p-1.5 font-mono text-[11px] text-white/60\">\n\t\t\t\t\t\t\t\t{typeof result === 'string' ? result : JSON.stringify(result, null, 2)}\n\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/**\n * Error state display\n */\nconst ErrorToolDisplay: React.FC<{\n\ttoolName: string\n\terror?: string\n}> = ({ toolName, error }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"my-1 overflow-hidden rounded-lg bg-white/5\">\n\t\t\t<div className=\"flex items-center gap-1.5 px-2 py-1.5\">\n\t\t\t\t<div className=\"relative\">\n\t\t\t\t\t<ToolIcon className=\"h-3.5 w-3.5 text-white/50\" />\n\t\t\t\t\t<AlertCircle className=\"absolute -bottom-0.5 -right-0.5 h-2 w-2 text-white/50\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"text-xs font-medium text-white/70\">\n\t\t\t\t\t{humanizeToolName(toolName)} failed\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t{error && (\n\t\t\t\t<div className=\"border-t border-white/5 px-2 py-1.5\">\n\t\t\t\t\t<pre className=\"whitespace-pre-wrap font-mono text-[11px] text-white/50\">{error}</pre>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/**\n * Denied approval display\n */\nconst DeniedToolDisplay: React.FC<{\n\ttoolName: string\n}> = ({ toolName }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"my-1 flex items-center gap-1.5 rounded-lg bg-white/5 px-2 py-1.5 text-xs text-white/60\">\n\t\t\t<div className=\"relative\">\n\t\t\t\t<ToolIcon className=\"h-3.5 w-3.5 text-white/40\" />\n\t\t\t\t<X className=\"absolute -bottom-0.5 -right-0.5 h-2 w-2 text-white/40\" />\n\t\t\t</div>\n\t\t\t<span>\n\t\t\t\t<strong className=\"text-white/70\">{humanizeToolName(toolName)}</strong> denied\n\t\t\t</span>\n\t\t</div>\n\t)\n}\n\n// ============================================================================\n// Main Unified Fallback Component\n// ============================================================================\n\n/**\n * Unified fallback component that handles all tool call states.\n * This is the single source of truth for tool rendering in the thread.\n *\n * HITL Pattern: For tools without an execute function (destructive tools),\n * the model pauses and waits for addResult() to be called. This component\n * shows an approval dialog and handles the execution on user approval.\n */\nexport const UnifiedToolFallback: ToolCallMessagePartComponent = ({\n\ttoolCallId: _toolCallId,\n\ttoolName,\n\targsText,\n\targs,\n\tstatus,\n\tresult,\n\taddResult,\n}) => {\n\tconst { callTool, tools } = useMCPTools()\n\tconst [isExecuting, setIsExecuting] = useState(false)\n\tconst [showApprovalDialog, setShowApprovalDialog] = useState(false)\n\n\t// Parse args - use args prop if available, otherwise parse from argsText\n\tconst parsedArgs: Record<string, unknown> =\n\t\targs ??\n\t\t(() => {\n\t\t\ttry {\n\t\t\t\treturn argsText ? JSON.parse(argsText) : {}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn(`[UnifiedToolFallback] Failed to parse args for tool \"${toolName}\":`, e)\n\t\t\t\treturn {}\n\t\t\t}\n\t\t})()\n\n\t// Get tool description from registered tools\n\tconst toolDescription = tools.find((t) => t.name === toolName)?.description\n\n\t// Handle approval - execute the tool and add result\n\tconst handleApprove = useCallback(async () => {\n\t\tsetIsExecuting(true)\n\t\ttry {\n\t\t\tconst toolResult = await callTool(toolName, parsedArgs)\n\t\t\taddResult(formatToolResult(toolResult))\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\t\taddResult(`Error: ${errorMessage}`)\n\t\t} finally {\n\t\t\tsetIsExecuting(false)\n\t\t}\n\t}, [toolName, parsedArgs, callTool, addResult])\n\n\t// Handle denial - add denial result using shared constant\n\tconst handleDeny = useCallback(() => {\n\t\taddResult(TOOL_DENIED_MESSAGE)\n\t}, [addResult])\n\n\t// Determine the current state and render accordingly\n\tconst statusType = status.type\n\n\t// Check if this is a pending approval\n\tconst isPendingApproval = statusType === 'requires-action' && result === undefined\n\n\t// Delay showing approval dialog to prevent flash when state transitions quickly\n\t// This gives time for auto-approved tools to complete before showing the dialog\n\tuseEffect(() => {\n\t\tif (isPendingApproval) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tsetShowApprovalDialog(true)\n\t\t\t}, 100) // 100ms delay prevents flash\n\t\t\treturn () => clearTimeout(timer)\n\t\t} else {\n\t\t\tsetShowApprovalDialog(false)\n\t\t}\n\t}, [isPendingApproval])\n\n\t// Case 1: HITL - Tool requires action (no execute function, waiting for approval)\n\t// This is the key case for destructive tools!\n\t// We delay showing the dialog by 100ms to prevent flash when state transitions quickly\n\tif (isPendingApproval) {\n\t\t// During the delay, show the running state to prevent a blank flash\n\t\tif (!showApprovalDialog) {\n\t\t\treturn <RunningToolDisplay toolName={toolName} />\n\t\t}\n\t\treturn (\n\t\t\t<ApprovalDialog\n\t\t\t\ttoolName={toolName}\n\t\t\t\ttoolDescription={toolDescription}\n\t\t\t\tinputArgs={parsedArgs}\n\t\t\t\tonApprove={handleApprove}\n\t\t\t\tonDeny={handleDeny}\n\t\t\t\tisExecuting={isExecuting}\n\t\t\t/>\n\t\t)\n\t}\n\n\t// Case 2: Tool was denied (result contains denial message)\n\tif (isDeniedResult(result)) {\n\t\treturn <DeniedToolDisplay toolName={toolName} />\n\t}\n\n\t// Case 3: Tool is currently running (has execute function)\n\tif (statusType === 'running') {\n\t\treturn <RunningToolDisplay toolName={toolName} />\n\t}\n\n\t// Case 4: Tool completed with error\n\tif (statusType === 'incomplete' || hasStatusError(status)) {\n\t\tconst errorMessage = hasStatusError(status) ? status.error : 'Tool execution failed'\n\t\treturn <ErrorToolDisplay toolName={toolName} error={errorMessage} />\n\t}\n\n\t// Case 5: Tool completed successfully\n\t// Also handle transition state where result is set but status hasn't updated yet\n\tif (statusType === 'complete' || (result !== undefined && !isDeniedResult(result))) {\n\t\t// If it's an approved result object, show the actual result\n\t\tconst displayResult = isApprovedResult(result) ? result.result : result\n\n\t\treturn <CompletedToolDisplay toolName={toolName} argsText={argsText} result={displayResult} />\n\t}\n\n\t// Fallback - show running state to prevent flash during state transitions\n\treturn <RunningToolDisplay toolName={toolName} />\n}\n\nexport default UnifiedToolFallback\n","/**\n * PillMessageContent Component\n *\n * Renders assistant message content (tool calls) using assistant-ui primitives.\n * Uses UnifiedToolFallback to render ALL tool states directly in the thread:\n * - Running tools with activity indicator\n * - Pending approval dialogs for destructive tools\n * - Completed tools with collapsible args/result\n * - Error states\n *\n * This provides an alternative to separate ActionList/CurrentActivity components\n * by rendering tool state directly in the conversation flow.\n */\n'use client'\n\nimport { MessagePrimitive, ThreadPrimitive } from '@assistant-ui/react'\n\nimport { UnifiedToolFallback } from '../UnifiedToolFallback'\n\nimport type { FC } from 'react'\n\n/**\n * Renders the thread messages with tool UIs.\n * Uses UnifiedToolFallback to handle all tool call states.\n */\nexport const PillMessageContent: FC = () => {\n\treturn (\n\t\t<ThreadPrimitive.Messages\n\t\t\tcomponents={{\n\t\t\t\t// Skip user messages in pill - we only want tool UIs from assistant\n\t\t\t\tUserMessage: () => null,\n\t\t\t\tAssistantMessage: PillAssistantMessage,\n\t\t\t}}\n\t\t/>\n\t)\n}\n\n/**\n * Assistant message renderer for the pill.\n * Renders tool calls via UnifiedToolFallback.\n * Text content is skipped here (handled by SummaryBlock).\n */\nconst PillAssistantMessage: FC = () => {\n\treturn (\n\t\t<MessagePrimitive.Root>\n\t\t\t<MessagePrimitive.Parts\n\t\t\t\tcomponents={{\n\t\t\t\t\t// Text is handled by SummaryBlock, so we skip it here\n\t\t\t\t\tText: () => null,\n\t\t\t\t\t// UnifiedToolFallback handles ALL tool states:\n\t\t\t\t\t// - Running: activity indicator\n\t\t\t\t\t// - Pending approval: approval dialog\n\t\t\t\t\t// - Completed: success with collapsible details\n\t\t\t\t\t// - Error: error display\n\t\t\t\t\t// - Denied: denied indicator\n\t\t\t\t\ttools: { Fallback: UnifiedToolFallback },\n\t\t\t\t}}\n\t\t\t/>\n\t\t</MessagePrimitive.Root>\n\t)\n}\n","/**\n * PillToolsSection Component\n *\n * A collapsible, scrollable container for tool UIs in the pill.\n * Shows a header with action count that expands/collapses the tool list.\n * Contains PillMessageContent which renders tools via UnifiedToolFallback.\n *\n * Auto-expands when a tool requires approval (HITL pattern).\n */\n'use client'\n\nimport { AlertTriangle, ChevronDown } from 'lucide-react'\nimport { useEffect, useRef, useState } from 'react'\n\nimport { useActions } from '../../hooks/useActions'\nimport { cn } from '../../lib/utils'\nimport { PillMessageContent } from './PillMessageContent'\n\nimport type { FC } from 'react'\n\nexport interface PillToolsSectionProps {\n\t/** Start collapsed (default: true) */\n\tdefaultCollapsed?: boolean\n\t/** Additional class name */\n\tclassName?: string\n\t/** Full-screen mode - larger height, starts expanded */\n\tisFullScreen?: boolean\n\t/** Force collapse (e.g., during approval) to avoid duplicate UIs */\n\tforceCollapsed?: boolean\n}\n\n/**\n * Collapsible section containing all tool UIs.\n * Shows \"Actions (completed/total)\" header with expand/collapse toggle.\n * Tool cards render in a scrollable container.\n *\n * Auto-expands when approval is needed for a destructive tool.\n */\nexport const PillToolsSection: FC<PillToolsSectionProps> = ({\n\tdefaultCollapsed = false,\n\tclassName,\n\tisFullScreen = false,\n\tforceCollapsed = false,\n}) => {\n\t// Start expanded in full-screen mode\n\tconst initialCollapsed = isFullScreen ? false : defaultCollapsed\n\tconst [isCollapsed, setIsCollapsed] = useState(initialCollapsed)\n\tconst lastUserCollapsed = useRef(initialCollapsed)\n\tconst wasForceCollapsed = useRef(false)\n\tconst actions = useActions()\n\n\t// Count different statuses\n\tconst completedCount = actions.filter((a) => a.status === 'success').length\n\tconst runningCount = actions.filter((a) => a.status === 'running').length\n\tconst pendingCount = actions.filter((a) => a.status === 'pending').length\n\tconst totalCount = actions.length\n\n\t// Enter/exit forced collapse while remembering prior user state\n\tuseEffect(() => {\n\t\tif (forceCollapsed) {\n\t\t\twasForceCollapsed.current = true\n\t\t\tlastUserCollapsed.current = isCollapsed\n\t\t\tsetIsCollapsed(true)\n\t\t\treturn\n\t\t}\n\n\t\t// Restore previous state when leaving forced collapse\n\t\tif (wasForceCollapsed.current) {\n\t\t\tsetIsCollapsed(lastUserCollapsed.current)\n\t\t\twasForceCollapsed.current = false\n\t\t}\n\t}, [forceCollapsed, isCollapsed])\n\n\t// Auto-expand when approval is needed\n\tuseEffect(() => {\n\t\tif (forceCollapsed) return\n\t\tif (pendingCount > 0 && isCollapsed) {\n\t\t\tsetIsCollapsed(false)\n\t\t}\n\t}, [pendingCount, isCollapsed, forceCollapsed])\n\n\t// Don't render if no actions\n\tif (actions.length === 0) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<div className={cn('mt-1.5', className)}>\n\t\t\t{/* Header - compact, no background card */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={() => {\n\t\t\t\t\tif (forceCollapsed) return\n\t\t\t\t\tconst next = !isCollapsed\n\t\t\t\t\tlastUserCollapsed.current = next\n\t\t\t\t\tsetIsCollapsed(next)\n\t\t\t\t}}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'flex w-full items-center justify-between',\n\t\t\t\t\t'px-1 py-1',\n\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t'hover:bg-white/5 rounded'\n\t\t\t\t)}\n\t\t\t\taria-expanded={!isCollapsed}\n\t\t\t\taria-disabled={forceCollapsed}\n\t\t\t\tdisabled={forceCollapsed}\n\t\t\t>\n\t\t\t\t<div className=\"flex items-center gap-1.5\">\n\t\t\t\t\t<span className=\"text-xs font-medium text-white/70\">Tools</span>\n\t\t\t\t\t<span className=\"text-[11px] text-white/40\">\n\t\t\t\t\t\t{completedCount}/{totalCount}\n\t\t\t\t\t</span>\n\t\t\t\t\t{/* Pending approval indicator */}\n\t\t\t\t\t{pendingCount > 0 && (\n\t\t\t\t\t\t<span className=\"flex items-center gap-1 text-[11px] font-medium text-white/90\">\n\t\t\t\t\t\t\t<AlertTriangle className=\"h-3 w-3\" />\n\t\t\t\t\t\t\t{pendingCount}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* Running indicator */}\n\t\t\t\t\t{runningCount > 0 && (\n\t\t\t\t\t\t<span className=\"flex items-center gap-1 text-[11px] text-white/60\">\n\t\t\t\t\t\t\t<span className=\"h-1.5 w-1.5 animate-pulse rounded-full bg-white/60\" />\n\t\t\t\t\t\t\t{runningCount}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<ChevronDown\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'h-3.5 w-3.5 transition-transform duration-200 text-white/40',\n\t\t\t\t\t\t!isCollapsed && 'rotate-180'\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t</button>\n\n\t\t\t{/* Expandable content */}\n\t\t\t{!forceCollapsed && (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'grid transition-[grid-template-rows] duration-300 ease-out',\n\t\t\t\t\t\tisCollapsed ? 'grid-rows-[0fr]' : 'grid-rows-[1fr]'\n\t\t\t\t\t)}\n\t\t\t\t\taria-hidden={isCollapsed}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"overflow-hidden\">\n\t\t\t\t\t\t{/* Scrollable tool cards - larger height in full-screen mode */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'mt-1 overflow-y-auto scrollbar-thin scroll-touch',\n\t\t\t\t\t\t\t\tisFullScreen ? 'max-h-[30vh]' : 'max-h-40 sm:max-h-32'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tstyle={{ touchAction: 'pan-y' }}\n\t\t\t\t\t\t\tonPointerDownCapture={(e) => e.stopPropagation()}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PillMessageContent />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nexport default PillToolsSection\n","import { useEffect, useRef } from 'react'\n\nimport { cn } from '../lib/utils'\n\nimport type { HTMLAttributes } from 'react'\n\nexport type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {\n\tactive?: boolean\n\tprocessing?: boolean\n\tbarWidth?: number\n\tbarGap?: number\n\tbarRadius?: number\n\tbarColor?: string\n\tfadeEdges?: boolean\n\tfadeWidth?: number\n\theight?: string | number\n\tsensitivity?: number\n\tsmoothingTimeConstant?: number\n\tmode?: 'scrolling' | 'static'\n\t/** Manual audio level (0-1) instead of using microphone */\n\tmanualAudioLevel?: number\n}\n\nexport const LiveWaveform = ({\n\tactive = false,\n\tprocessing = false,\n\tbarWidth = 3,\n\tbarGap = 1,\n\tbarRadius = 1.5,\n\tbarColor,\n\tfadeEdges = true,\n\tfadeWidth = 24,\n\theight = 64,\n\tsensitivity = 1,\n\tmode = 'static',\n\tmanualAudioLevel,\n\tclassName,\n\t...props\n}: LiveWaveformProps) => {\n\tconst canvasRef = useRef<HTMLCanvasElement>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst historyRef = useRef<number[]>([])\n\tconst _animationRef = useRef<number>(0)\n\tconst lastUpdateRef = useRef<number>(0)\n\tconst processingAnimationRef = useRef<number | null>(null)\n\tconst lastActiveDataRef = useRef<number[]>([])\n\tconst transitionProgressRef = useRef(0)\n\tconst staticBarsRef = useRef<number[]>([])\n\tconst needsRedrawRef = useRef(true)\n\tconst gradientCacheRef = useRef<CanvasGradient | null>(null)\n\tconst lastWidthRef = useRef(0)\n\n\tconst heightStyle = typeof height === 'number' ? `${height}px` : height\n\tconst historySize = 60\n\tconst updateRate = 30\n\n\t// Handle canvas resizing\n\tuseEffect(() => {\n\t\tconst canvas = canvasRef.current\n\t\tconst container = containerRef.current\n\t\tif (!canvas || !container) return\n\n\t\tconst resizeObserver = new ResizeObserver(() => {\n\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\tconst dpr = window.devicePixelRatio || 1\n\n\t\t\tcanvas.width = rect.width * dpr\n\t\t\tcanvas.height = rect.height * dpr\n\t\t\tcanvas.style.width = `${rect.width}px`\n\t\t\tcanvas.style.height = `${rect.height}px`\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (ctx) {\n\t\t\t\tctx.scale(dpr, dpr)\n\t\t\t}\n\n\t\t\tgradientCacheRef.current = null\n\t\t\tlastWidthRef.current = rect.width\n\t\t\tneedsRedrawRef.current = true\n\t\t})\n\n\t\tresizeObserver.observe(container)\n\t\treturn () => resizeObserver.disconnect()\n\t}, [])\n\n\t// Processing animation effect\n\tuseEffect(() => {\n\t\tif (processing && !active) {\n\t\t\tlet time = 0\n\t\t\ttransitionProgressRef.current = 0\n\n\t\t\tconst animateProcessing = () => {\n\t\t\t\ttime += 0.03\n\t\t\t\ttransitionProgressRef.current = Math.min(1, transitionProgressRef.current + 0.02)\n\n\t\t\t\tconst processingData: number[] = []\n\t\t\t\tconst barCount = Math.floor(\n\t\t\t\t\t(containerRef.current?.getBoundingClientRect().width || 200) / (barWidth + barGap)\n\t\t\t\t)\n\n\t\t\t\tif (mode === 'static') {\n\t\t\t\t\tconst halfCount = Math.floor(barCount / 2)\n\n\t\t\t\t\tfor (let i = 0; i < barCount; i++) {\n\t\t\t\t\t\tconst normalizedPosition = (i - halfCount) / halfCount\n\t\t\t\t\t\tconst centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n\t\t\t\t\t\tconst wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n\t\t\t\t\t\tconst wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n\t\t\t\t\t\tconst wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n\t\t\t\t\t\tconst combinedWave = wave1 + wave2 + wave3\n\t\t\t\t\t\tconst processingValue = (0.2 + combinedWave) * centerWeight\n\n\t\t\t\t\t\tlet finalValue = processingValue\n\t\t\t\t\t\tif (lastActiveDataRef.current.length > 0 && transitionProgressRef.current < 1) {\n\t\t\t\t\t\t\tconst lastDataIndex = Math.min(i, lastActiveDataRef.current.length - 1)\n\t\t\t\t\t\t\tconst lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n\t\t\t\t\t\t\tfinalValue =\n\t\t\t\t\t\t\t\tlastValue * (1 - transitionProgressRef.current) +\n\t\t\t\t\t\t\t\tprocessingValue * transitionProgressRef.current\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tprocessingData.push(Math.max(0.05, Math.min(1, finalValue)))\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (let i = 0; i < barCount; i++) {\n\t\t\t\t\t\tconst normalizedPosition = (i - barCount / 2) / (barCount / 2)\n\t\t\t\t\t\tconst centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n\t\t\t\t\t\tconst wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n\t\t\t\t\t\tconst wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n\t\t\t\t\t\tconst wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n\t\t\t\t\t\tconst combinedWave = wave1 + wave2 + wave3\n\t\t\t\t\t\tconst processingValue = (0.2 + combinedWave) * centerWeight\n\n\t\t\t\t\t\tlet finalValue = processingValue\n\t\t\t\t\t\tif (lastActiveDataRef.current.length > 0 && transitionProgressRef.current < 1) {\n\t\t\t\t\t\t\tconst lastDataIndex = Math.floor((i / barCount) * lastActiveDataRef.current.length)\n\t\t\t\t\t\t\tconst lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n\t\t\t\t\t\t\tfinalValue =\n\t\t\t\t\t\t\t\tlastValue * (1 - transitionProgressRef.current) +\n\t\t\t\t\t\t\t\tprocessingValue * transitionProgressRef.current\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tprocessingData.push(Math.max(0.05, Math.min(1, finalValue)))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'static') {\n\t\t\t\t\tstaticBarsRef.current = processingData\n\t\t\t\t} else {\n\t\t\t\t\thistoryRef.current = processingData\n\t\t\t\t}\n\n\t\t\t\tneedsRedrawRef.current = true\n\t\t\t\tprocessingAnimationRef.current = requestAnimationFrame(animateProcessing)\n\t\t\t}\n\n\t\t\tanimateProcessing()\n\n\t\t\treturn () => {\n\t\t\t\tif (processingAnimationRef.current) {\n\t\t\t\t\tcancelAnimationFrame(processingAnimationRef.current)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!active && !processing) {\n\t\t\tconst hasData =\n\t\t\t\tmode === 'static' ? staticBarsRef.current.length > 0 : historyRef.current.length > 0\n\n\t\t\tif (hasData) {\n\t\t\t\tlet fadeProgress = 0\n\t\t\t\tconst fadeToIdle = () => {\n\t\t\t\t\tfadeProgress += 0.03\n\t\t\t\t\tif (fadeProgress < 1) {\n\t\t\t\t\t\tif (mode === 'static') {\n\t\t\t\t\t\t\tstaticBarsRef.current = staticBarsRef.current.map(\n\t\t\t\t\t\t\t\t(value) => value * (1 - fadeProgress)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thistoryRef.current = historyRef.current.map((value) => value * (1 - fadeProgress))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tneedsRedrawRef.current = true\n\t\t\t\t\t\trequestAnimationFrame(fadeToIdle)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (mode === 'static') {\n\t\t\t\t\t\t\tstaticBarsRef.current = []\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thistoryRef.current = []\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfadeToIdle()\n\t\t\t}\n\t\t}\n\t}, [processing, active, barWidth, barGap, mode])\n\n\t// Animation loop\n\tuseEffect(() => {\n\t\tconst canvas = canvasRef.current\n\t\tif (!canvas) return\n\n\t\tconst ctx = canvas.getContext('2d')\n\t\tif (!ctx) return\n\n\t\tlet rafId: number\n\n\t\tconst animate = (currentTime: number) => {\n\t\t\tconst rect = canvas.getBoundingClientRect()\n\n\t\t\t// Update audio data if active\n\t\t\tif (active && currentTime - lastUpdateRef.current > updateRate) {\n\t\t\t\tlastUpdateRef.current = currentTime\n\n\t\t\t\t// Use manual audio level if provided\n\t\t\t\tif (manualAudioLevel !== undefined) {\n\t\t\t\t\tconst level = Math.max(0.05, Math.min(1, manualAudioLevel * sensitivity))\n\n\t\t\t\t\tif (mode === 'static') {\n\t\t\t\t\t\tconst barCount = Math.floor(rect.width / (barWidth + barGap))\n\t\t\t\t\t\tconst halfCount = Math.floor(barCount / 2)\n\t\t\t\t\t\tconst newBars: number[] = []\n\n\t\t\t\t\t\t// Create symmetric bars based on manual level\n\t\t\t\t\t\tfor (let i = halfCount - 1; i >= 0; i--) {\n\t\t\t\t\t\t\tconst distanceFromCenter = Math.abs(i - halfCount / 2) / (halfCount / 2)\n\t\t\t\t\t\t\tconst value = level * (1 - distanceFromCenter * 0.3)\n\t\t\t\t\t\t\tnewBars.push(Math.max(0.05, value))\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (let i = 0; i < halfCount; i++) {\n\t\t\t\t\t\t\tconst distanceFromCenter = Math.abs(i - halfCount / 2) / (halfCount / 2)\n\t\t\t\t\t\t\tconst value = level * (1 - distanceFromCenter * 0.3)\n\t\t\t\t\t\t\tnewBars.push(Math.max(0.05, value))\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstaticBarsRef.current = newBars\n\t\t\t\t\t\tlastActiveDataRef.current = newBars\n\t\t\t\t\t} else {\n\t\t\t\t\t\thistoryRef.current.push(level)\n\t\t\t\t\t\tlastActiveDataRef.current = [...historyRef.current]\n\n\t\t\t\t\t\tif (historyRef.current.length > historySize) {\n\t\t\t\t\t\t\thistoryRef.current.shift()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tneedsRedrawRef.current = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Only redraw if needed\n\t\t\tif (!needsRedrawRef.current && !active) {\n\t\t\t\trafId = requestAnimationFrame(animate)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tneedsRedrawRef.current = active\n\t\t\tctx.clearRect(0, 0, rect.width, rect.height)\n\n\t\t\tconst computedBarColor =\n\t\t\t\tbarColor ||\n\t\t\t\t(() => {\n\t\t\t\t\tconst style = getComputedStyle(canvas)\n\t\t\t\t\tconst color = style.color\n\t\t\t\t\treturn color || '#000'\n\t\t\t\t})()\n\n\t\t\tconst step = barWidth + barGap\n\t\t\tconst barCount = Math.floor(rect.width / step)\n\t\t\tconst centerY = rect.height / 2\n\n\t\t\t// Draw bars based on mode\n\t\t\tif (mode === 'static') {\n\t\t\t\tconst dataToRender = processing\n\t\t\t\t\t? staticBarsRef.current\n\t\t\t\t\t: active\n\t\t\t\t\t\t? staticBarsRef.current\n\t\t\t\t\t\t: staticBarsRef.current.length > 0\n\t\t\t\t\t\t\t? staticBarsRef.current\n\t\t\t\t\t\t\t: []\n\n\t\t\t\tfor (let i = 0; i < barCount && i < dataToRender.length; i++) {\n\t\t\t\t\tconst value = dataToRender[i] || 0.1\n\t\t\t\t\tconst x = i * step\n\t\t\t\t\tconst barHeight = Math.max(4, value * rect.height * 0.8)\n\t\t\t\t\tconst y = centerY - barHeight / 2\n\n\t\t\t\t\tctx.fillStyle = computedBarColor\n\t\t\t\t\tctx.globalAlpha = 0.4 + value * 0.6\n\n\t\t\t\t\tif (barRadius > 0) {\n\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\tctx.roundRect(x, y, barWidth, barHeight, barRadius)\n\t\t\t\t\t\tctx.fill()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.fillRect(x, y, barWidth, barHeight)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Scrolling mode\n\t\t\t\tfor (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n\t\t\t\t\tconst dataIndex = historyRef.current.length - 1 - i\n\t\t\t\t\tconst value = historyRef.current[dataIndex] || 0.1\n\t\t\t\t\tconst x = rect.width - (i + 1) * step\n\t\t\t\t\tconst barHeight = Math.max(4, value * rect.height * 0.8)\n\t\t\t\t\tconst y = centerY - barHeight / 2\n\n\t\t\t\t\tctx.fillStyle = computedBarColor\n\t\t\t\t\tctx.globalAlpha = 0.4 + value * 0.6\n\n\t\t\t\t\tif (barRadius > 0) {\n\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\tctx.roundRect(x, y, barWidth, barHeight, barRadius)\n\t\t\t\t\t\tctx.fill()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.fillRect(x, y, barWidth, barHeight)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply edge fading\n\t\t\tif (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n\t\t\t\tif (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n\t\t\t\t\tconst gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n\t\t\t\t\tconst fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n\t\t\t\t\tgradient.addColorStop(0, 'rgba(255,255,255,1)')\n\t\t\t\t\tgradient.addColorStop(fadePercent, 'rgba(255,255,255,0)')\n\t\t\t\t\tgradient.addColorStop(1 - fadePercent, 'rgba(255,255,255,0)')\n\t\t\t\t\tgradient.addColorStop(1, 'rgba(255,255,255,1)')\n\n\t\t\t\t\tgradientCacheRef.current = gradient\n\t\t\t\t\tlastWidthRef.current = rect.width\n\t\t\t\t}\n\n\t\t\t\tctx.globalCompositeOperation = 'destination-out'\n\t\t\t\tctx.fillStyle = gradientCacheRef.current\n\t\t\t\tctx.fillRect(0, 0, rect.width, rect.height)\n\t\t\t\tctx.globalCompositeOperation = 'source-over'\n\t\t\t}\n\n\t\t\tctx.globalAlpha = 1\n\n\t\t\trafId = requestAnimationFrame(animate)\n\t\t}\n\n\t\trafId = requestAnimationFrame(animate)\n\n\t\treturn () => {\n\t\t\tif (rafId) {\n\t\t\t\tcancelAnimationFrame(rafId)\n\t\t\t}\n\t\t}\n\t}, [\n\t\tactive,\n\t\tprocessing,\n\t\tsensitivity,\n\t\tbarWidth,\n\t\tbarGap,\n\t\tbarRadius,\n\t\tbarColor,\n\t\tfadeEdges,\n\t\tfadeWidth,\n\t\tmode,\n\t\tmanualAudioLevel,\n\t\thistorySize,\n\t\tupdateRate,\n\t])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn('relative h-full w-full', className)}\n\t\t\tref={containerRef}\n\t\t\tstyle={{ height: heightStyle }}\n\t\t\taria-label={\n\t\t\t\tactive ? 'Live audio waveform' : processing ? 'Processing audio' : 'Audio waveform idle'\n\t\t\t}\n\t\t\trole=\"img\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{!active && !processing && (\n\t\t\t\t<div className=\"border-muted-foreground/20 absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted\" />\n\t\t\t)}\n\t\t\t<canvas className=\"block h-full w-full\" ref={canvasRef} />\n\t\t</div>\n\t)\n}\n","/**\n * PillVoiceApprovalBar Component\n *\n * Approval UI for voice mode. Shows when a destructive tool needs approval.\n * Audio is paused while waiting for the user to tap approve or deny.\n *\n * Features:\n * - Pauses audio playback when approval is pending\n * - Displays tool name and countdown timer\n * - Approve/Deny buttons\n * - Amber warning styling consistent with text mode approval\n * - Resumes audio after approval/denial\n */\n'use client'\n\nimport { Pause } from 'lucide-react'\nimport { AnimatePresence, motion } from 'motion/react'\nimport { useEffect, useState } from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { useOptionalMCPTools } from '../../providers/MCPToolsProvider'\nimport { useOptionalVoiceThread } from '../../providers/VoiceThreadBridge'\nimport { useOptionalVoiceToolApproval } from '../../providers/VoiceToolApprovalProvider'\nimport { ToolApprovalCard } from './ToolApprovalCard'\n\nimport type { FC } from 'react'\n\n// Animation variants\nconst approvalBarVariants = {\n\thidden: {\n\t\topacity: 0,\n\t\theight: 0,\n\t\ty: -8,\n\t},\n\tvisible: {\n\t\topacity: 1,\n\t\theight: 'auto',\n\t\ty: 0,\n\t\ttransition: {\n\t\t\ttype: 'spring' as const,\n\t\t\tstiffness: 400,\n\t\t\tdamping: 30,\n\t\t},\n\t},\n\texit: {\n\t\topacity: 0,\n\t\theight: 0,\n\t\ty: -8,\n\t\ttransition: {\n\t\t\tduration: 0.15,\n\t\t},\n\t},\n}\n\nexport interface PillVoiceApprovalBarProps {\n\t/** Additional class name */\n\tclassName?: string\n}\n\n/**\n * Voice mode approval bar component.\n *\n * Shows when a destructive tool is waiting for approval in voice mode.\n * Pauses audio while waiting for approval, resumes after user responds.\n */\nexport const PillVoiceApprovalBar: FC<PillVoiceApprovalBarProps> = ({ className }) => {\n\tconst voiceThread = useOptionalVoiceThread()\n\tconst voiceApproval = useOptionalVoiceToolApproval()\n\tconst mcpTools = useOptionalMCPTools()\n\tconst [isExecuting, setIsExecuting] = useState(false)\n\n\t// Pause audio when approval is pending, resume when resolved\n\tuseEffect(() => {\n\t\tif (voiceApproval?.pendingApproval && voiceThread) {\n\t\t\t// Pause audio when this component mounts (approval pending)\n\t\t\tvoiceThread.pauseAudio()\n\n\t\t\t// Resume audio when this component unmounts (approval resolved)\n\t\t\treturn () => {\n\t\t\t\tvoiceThread.resumeAudio()\n\t\t\t}\n\t\t}\n\t}, [voiceApproval?.pendingApproval, voiceThread])\n\n\t// Don't render if no pending approval\n\tif (!voiceApproval?.pendingApproval) {\n\t\treturn null\n\t}\n\n\tconst { pendingApproval, timeoutRemaining, approve, deny } = voiceApproval\n\tconst toolDescription = mcpTools?.tools.find(\n\t\t(t) => t.name === pendingApproval.toolName\n\t)?.description\n\tconst hasArgs = Object.keys(pendingApproval.args ?? {}).length > 0\n\tconst formattedArgs = hasArgs ? pendingApproval.args : undefined\n\n\t// Handle approve button click\n\tconst handleApprove = () => {\n\t\tsetIsExecuting(true)\n\t\tapprove()\n\t}\n\n\t// Handle deny button click\n\tconst handleDeny = () => {\n\t\tdeny()\n\t}\n\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t<motion.div\n\t\t\t\tclassName={cn('overflow-hidden', className)}\n\t\t\t\tvariants={approvalBarVariants}\n\t\t\t\tinitial=\"hidden\"\n\t\t\t\tanimate=\"visible\"\n\t\t\t\texit=\"exit\"\n\t\t\t>\n\t\t\t\t<ToolApprovalCard\n\t\t\t\t\ttoolName={pendingApproval.toolName}\n\t\t\t\t\tdescription={toolDescription}\n\t\t\t\t\targs={formattedArgs}\n\t\t\t\t\ttimeoutRemaining={timeoutRemaining}\n\t\t\t\t\tisExecuting={isExecuting}\n\t\t\t\t\tonApprove={handleApprove}\n\t\t\t\t\tonDeny={handleDeny}\n\t\t\t\t\theaderAddon={\n\t\t\t\t\t\t<div className=\"flex items-center gap-1.5 text-xs text-white/50\">\n\t\t\t\t\t\t\t<Pause className=\"h-3 w-3\" />\n\t\t\t\t\t\t\t<span>Audio paused. Tap to approve or deny.</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</motion.div>\n\t\t</AnimatePresence>\n\t)\n}\n\nexport default PillVoiceApprovalBar\n","'use client'\n\nimport { useThreadRuntime } from '@assistant-ui/react'\nimport { Mic, MicOff, PhoneOff } from 'lucide-react'\nimport { AnimatePresence, motion } from 'motion/react'\nimport { useCallback } from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { useOptionalVoiceThread } from '../../providers/VoiceThreadBridge'\nimport { useOptionalVoiceToolApproval } from '../../providers/VoiceToolApprovalProvider'\nimport { LiveWaveform } from '../live-waveform'\nimport { PillComposer } from './PillComposer'\nimport { PillVoiceApprovalBar } from './PillVoiceApprovalBar'\n\nimport type { FC } from 'react'\nimport type { ToolBorderStatus } from './ToolStatusBorder'\n\ninterface PillVoiceProps {\n\t/** Callback when voice mode ends */\n\tonEnd?: () => void\n\t/** Whether to show a compact version */\n\tcompact?: boolean\n\t/** Additional class name */\n\tclassName?: string\n}\n\n// Animation variants for the voice UI\nconst voiceVariants = {\n\thidden: {\n\t\topacity: 0,\n\t\tscale: 0.95,\n\t\ty: 4,\n\t},\n\tvisible: {\n\t\topacity: 1,\n\t\tscale: 1,\n\t\ty: 0,\n\t\ttransition: {\n\t\t\ttype: 'spring' as const,\n\t\t\tstiffness: 400,\n\t\t\tdamping: 30,\n\t\t},\n\t},\n\texit: {\n\t\topacity: 0,\n\t\tscale: 0.95,\n\t\ty: -4,\n\t\ttransition: {\n\t\t\tduration: 0.15,\n\t\t},\n\t},\n}\n\n// Button animation\nconst buttonVariants = {\n\tidle: { scale: 1 },\n\thover: { scale: 1.05 },\n\ttap: { scale: 0.95 },\n}\n\n// Transcript animation\nconst transcriptVariants = {\n\thidden: { opacity: 0, height: 0 },\n\tvisible: {\n\t\topacity: 1,\n\t\theight: 'auto',\n\t\ttransition: {\n\t\t\ttype: 'spring' as const,\n\t\t\tstiffness: 300,\n\t\t\tdamping: 25,\n\t\t},\n\t},\n\texit: {\n\t\topacity: 0,\n\t\theight: 0,\n\t\ttransition: {\n\t\t\tduration: 0.1,\n\t\t},\n\t},\n}\n\n/**\n * Convert voice mode tool call status to border status\n */\nexport function voiceToolCallToBorderStatus(toolCall?: {\n\tstatus: 'started' | 'completed'\n\terror?: string\n}): ToolBorderStatus {\n\tif (!toolCall) return 'idle'\n\tif (toolCall.status === 'started') return 'calling'\n\tif (toolCall.status === 'completed') {\n\t\treturn toolCall.error ? 'error' : 'success'\n\t}\n\treturn 'idle'\n}\n\n/**\n * Compact voice mode UI for the pill.\n * Shows waveforms, controls, and transcript preview.\n * Uses motion animations for smooth transitions.\n *\n * Uses VoiceThreadBridge for voice state (integrated with thread).\n */\nexport const PillVoice: FC<PillVoiceProps> = ({ onEnd, compact = false, className }) => {\n\tconst voiceThread = useOptionalVoiceThread()\n\tconst voiceToolApproval = useOptionalVoiceToolApproval()\n\tconst threadRuntime = useThreadRuntime()\n\n\tconst handleEnd = useCallback(() => {\n\t\t// Clear any pending voice approvals\n\t\tvoiceToolApproval?.clearPendingApproval()\n\n\t\t// Stop the voice session\n\t\tvoiceThread?.stop()\n\t\tonEnd?.()\n\t}, [voiceThread, voiceToolApproval, onEnd])\n\n\tconst handleToggleMute = useCallback(() => {\n\t\tvoiceThread?.toggleMute()\n\t}, [voiceThread])\n\n\t// Handle text submission in voice mode\n\tconst handleVoiceSend = useCallback(\n\t\t(text: string) => {\n\t\t\tconst trimmed = text.trim()\n\t\t\tif (!trimmed) return\n\n\t\t\t// Append to thread for single source of truth, matching transcript metadata\n\t\t\tif (voiceThread?.sessionId) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tconst metadata: any = {\n\t\t\t\t\tcustom: {\n\t\t\t\t\t\tsource: 'voice',\n\t\t\t\t\t\tvoiceSessionId: voiceThread.sessionId,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tthreadRuntime.append({\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: [{ type: 'text', text: trimmed }],\n\t\t\t\t\tmetadata,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tvoiceThread?.sendMessage(trimmed)\n\t\t},\n\t\t[voiceThread, threadRuntime]\n\t)\n\n\t// Don't render if no voice context or not active/connecting/error\n\tif (\n\t\t!voiceThread ||\n\t\t(!voiceThread.isActive && !voiceThread.isConnecting && !voiceThread.isError)\n\t) {\n\t\treturn null\n\t}\n\n\tconst { isActive, isConnecting, isMuted, isError, error, audioLevel, transcript, toolCall } =\n\t\tvoiceThread\n\n\t// Check if we're waiting for approval\n\tconst isWaitingForApproval = voiceToolApproval?.isWaitingForApproval ?? false\n\tconst micLevel = audioLevel?.micLevel ?? 0\n\tconst speakerLevel = audioLevel?.speakerLevel ?? 0\n\n\treturn (\n\t\t<motion.div\n\t\t\tclassName={cn('flex flex-col gap-3', className)}\n\t\t\tvariants={voiceVariants}\n\t\t\tinitial=\"hidden\"\n\t\t\tanimate=\"visible\"\n\t\t\texit=\"exit\"\n\t\t>\n\t\t\t{/* Waveforms row */}\n\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t{/* User mic indicator */}\n\t\t\t\t<div className=\"flex flex-1 items-center gap-2\">\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-11 w-11 shrink-0 items-center justify-center rounded-full sm:h-7 sm:w-7',\n\t\t\t\t\t\t\tisMuted ? 'bg-red-500/20 text-red-400' : 'bg-white/10 text-white/80'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tanimate={{ opacity: isMuted ? 0.6 : 1 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isMuted ? (\n\t\t\t\t\t\t\t<MicOff className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Mic className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</motion.div>\n\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn('h-5 flex-1', compact ? 'max-w-24 sm:max-w-16' : 'max-w-32 sm:max-w-24')}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LiveWaveform\n\t\t\t\t\t\t\tactive={isActive && !isMuted}\n\t\t\t\t\t\t\tprocessing={isConnecting}\n\t\t\t\t\t\t\tmanualAudioLevel={micLevel}\n\t\t\t\t\t\t\tbarWidth={2}\n\t\t\t\t\t\t\tbarGap={1}\n\t\t\t\t\t\t\tbarRadius={1}\n\t\t\t\t\t\t\tbarColor=\"rgba(255, 255, 255, 0.7)\"\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tmode=\"static\"\n\t\t\t\t\t\t\tsensitivity={2.0}\n\t\t\t\t\t\t\tfadeEdges={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Separator */}\n\t\t\t\t<div className=\"h-5 w-px bg-white/10\" />\n\n\t\t\t\t{/* Agent speaker indicator */}\n\t\t\t\t<div className=\"flex flex-1 items-center gap-2\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn('h-5 flex-1', compact ? 'max-w-24 sm:max-w-16' : 'max-w-32 sm:max-w-24')}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LiveWaveform\n\t\t\t\t\t\t\tactive={isActive}\n\t\t\t\t\t\t\tprocessing={isConnecting}\n\t\t\t\t\t\t\tmanualAudioLevel={speakerLevel}\n\t\t\t\t\t\t\tbarWidth={2}\n\t\t\t\t\t\t\tbarGap={1}\n\t\t\t\t\t\t\tbarRadius={1}\n\t\t\t\t\t\t\tbarColor=\"rgba(255, 255, 255, 0.4)\"\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tmode=\"static\"\n\t\t\t\t\t\t\tsensitivity={2.0}\n\t\t\t\t\t\t\tfadeEdges={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{/* Agent avatar */}\n\t\t\t\t\t<div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-white/10 sm:h-7 sm:w-7\">\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tclassName=\"h-2.5 w-2.5 rounded-full bg-green-400\"\n\t\t\t\t\t\t\tanimate={{\n\t\t\t\t\t\t\t\tscale: speakerLevel > 0.1 ? [1, 1.2, 1] : 1,\n\t\t\t\t\t\t\t\topacity: speakerLevel > 0.1 ? 1 : 0.5,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\ttransition={{ duration: 0.2 }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Separator */}\n\t\t\t\t<div className=\"h-5 w-px bg-white/10\" />\n\n\t\t\t\t{/* Controls */}\n\t\t\t\t<div className=\"flex shrink-0 items-center gap-2 sm:gap-1.5\">\n\t\t\t\t\t{/* Mute button */}\n\t\t\t\t\t<motion.button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleToggleMute}\n\t\t\t\t\t\tdisabled={!isActive}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-11 w-11 items-center justify-center rounded-full sm:h-7 sm:w-7',\n\t\t\t\t\t\t\t'transition-colors duration-150',\n\t\t\t\t\t\t\tisMuted\n\t\t\t\t\t\t\t\t? 'bg-red-500/20 text-red-400 hover:bg-red-500/30'\n\t\t\t\t\t\t\t\t: 'bg-white/10 text-white/70 hover:bg-white/20 hover:text-white'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tvariants={buttonVariants}\n\t\t\t\t\t\tinitial=\"idle\"\n\t\t\t\t\t\twhileHover=\"hover\"\n\t\t\t\t\t\twhileTap=\"tap\"\n\t\t\t\t\t\taria-label={isMuted ? 'Unmute microphone' : 'Mute microphone'}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isMuted ? (\n\t\t\t\t\t\t\t<MicOff className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Mic className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</motion.button>\n\n\t\t\t\t\t{/* End button */}\n\t\t\t\t\t<motion.button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleEnd}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-11 w-11 items-center justify-center rounded-full sm:h-7 sm:w-7',\n\t\t\t\t\t\t\t'bg-red-500/20 text-red-400',\n\t\t\t\t\t\t\t'hover:bg-red-500/30 hover:text-red-300',\n\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tvariants={buttonVariants}\n\t\t\t\t\t\tinitial=\"idle\"\n\t\t\t\t\t\twhileHover=\"hover\"\n\t\t\t\t\t\twhileTap=\"tap\"\n\t\t\t\t\t\taria-label=\"End voice session\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<PhoneOff className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t</motion.button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{/* Voice Tool Approval Bar - shows when a destructive tool needs approval */}\n\t\t\t<AnimatePresence>{isWaitingForApproval && <PillVoiceApprovalBar />}</AnimatePresence>\n\n\t\t\t{/* Tool call indicator - only show when NOT waiting for approval */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{toolCall && !isWaitingForApproval && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex max-w-full items-center gap-2 rounded-full px-3 py-1.5',\n\t\t\t\t\t\t\t'text-xs',\n\t\t\t\t\t\t\ttoolCall.status === 'started' && 'bg-blue-500/10 text-blue-400',\n\t\t\t\t\t\t\ttoolCall.status === 'completed' &&\n\t\t\t\t\t\t\t\t!toolCall.error &&\n\t\t\t\t\t\t\t\t'bg-green-500/10 text-green-400',\n\t\t\t\t\t\t\ttoolCall.status === 'completed' && toolCall.error && 'bg-red-500/10 text-red-400'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tinitial={{ opacity: 0, y: -4 }}\n\t\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\n\t\t\t\t\t\texit={{ opacity: 0, y: -4 }}\n\t\t\t\t\t\ttransition={{ type: 'spring', stiffness: 400, damping: 30 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'h-1.5 w-1.5 shrink-0 rounded-full',\n\t\t\t\t\t\t\t\ttoolCall.status === 'started' && 'bg-blue-500',\n\t\t\t\t\t\t\t\ttoolCall.status === 'completed' && !toolCall.error && 'bg-green-500',\n\t\t\t\t\t\t\t\ttoolCall.status === 'completed' && toolCall.error && 'bg-red-500'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tanimate={toolCall.status === 'started' ? { opacity: [1, 0.5, 1] } : {}}\n\t\t\t\t\t\t\ttransition={{ duration: 0.8, repeat: Infinity }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"min-w-0 truncate\">{toolCall.toolName}</span>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Transcript preview */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{transcript && transcript.text && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName=\"overflow-hidden\"\n\t\t\t\t\t\tvariants={transcriptVariants}\n\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\texit=\"exit\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'rounded-lg px-3 py-2 text-xs',\n\t\t\t\t\t\t\t\ttranscript.type === 'user'\n\t\t\t\t\t\t\t\t\t? 'bg-white/10 text-white/80'\n\t\t\t\t\t\t\t\t\t: 'bg-white/5 text-white/60'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"mr-1.5 shrink-0 text-white/40\">\n\t\t\t\t\t\t\t\t{transcript.type === 'user' ? 'You:' : 'Agent:'}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className={cn('line-clamp-3', !transcript.isDone && 'animate-pulse')}>\n\t\t\t\t\t\t\t\t{transcript.text}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Connecting state */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{isConnecting && !isActive && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName=\"flex items-center justify-center gap-2 py-2 text-xs text-white/50\"\n\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName=\"h-1.5 w-1.5 rounded-full bg-amber-500\"\n\t\t\t\t\t\t\tanimate={{ opacity: [1, 0.5, 1] }}\n\t\t\t\t\t\t\ttransition={{ duration: 0.8, repeat: Infinity }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span>Connecting...</span>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Error state */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{isError && error && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName=\"flex items-center gap-2 rounded-lg bg-red-500/10 px-3 py-2 text-xs text-red-400\"\n\t\t\t\t\t\tinitial={{ opacity: 0, y: -4 }}\n\t\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\n\t\t\t\t\t\texit={{ opacity: 0, y: -4 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"h-1.5 w-1.5 shrink-0 rounded-full bg-red-500\" />\n\t\t\t\t\t\t<span className=\"line-clamp-2\">{error}</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleEnd}\n\t\t\t\t\t\t\tclassName=\"ml-auto shrink-0 text-red-300 hover:text-red-200\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDismiss\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Voice mode text input - allows typing while in voice session */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{isActive && !isWaitingForApproval && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName=\"mt-3 border-t border-white/10 pt-3\"\n\t\t\t\t\t\tinitial={{ opacity: 0, y: 8 }}\n\t\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\n\t\t\t\t\t\texit={{ opacity: 0, y: 8 }}\n\t\t\t\t\t\ttransition={{ delay: 0.1 }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<PillComposer\n\t\t\t\t\t\t\tplaceholder=\"Type a message...\"\n\t\t\t\t\t\t\tisVoiceMode={true}\n\t\t\t\t\t\t\tonVoiceSend={handleVoiceSend}\n\t\t\t\t\t\t\tshowVoiceButton={false}\n\t\t\t\t\t\t\tshowCharCount={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\t\t</motion.div>\n\t)\n}\n\n/**\n * Hook to get voice border status for the pill container\n */\nexport function useVoiceBorderStatus(): ToolBorderStatus {\n\tconst voiceThread = useOptionalVoiceThread()\n\n\tif (!voiceThread) return 'idle'\n\n\treturn voiceToolCallToBorderStatus(voiceThread.toolCall)\n}\n\nexport default PillVoice\n","/**\n * PromptBadge\n *\n * Intercom-style floating prompt bubbles that appear above the collapsed pill.\n * Shows up to MAX_PROMPT_BUBBLES in a triangular layout with staggered animations.\n *\n * Accessibility:\n * - Focus-visible rings for keyboard navigation\n * - Screen reader live region announces suggestions\n * - Touch-friendly dismiss targets on mobile\n */\nimport { X } from 'lucide-react'\nimport { AnimatePresence, motion } from 'motion/react'\nimport { useCallback, useState } from 'react'\n\nimport { useMobileDetect } from '../../hooks/useMobileDetect'\nimport { MAX_PROMPT_BUBBLES } from '../../lib/constants'\nimport { cn } from '../../lib/utils'\n\nimport type { Prompt } from '@mcp-b/cloud-mirror-types'\nimport type { Variants } from 'motion/react'\nimport type { FC, MouseEvent } from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PromptBadgeProps {\n\t/** Available prompts to display */\n\tprompts: Prompt[]\n\t/** Callback when a prompt is selected */\n\tonSelect: (prompt: Prompt) => void\n\t/** Additional class name */\n\tclassName?: string\n}\n\n// ============================================================================\n// Animation Configuration\n// ============================================================================\n\n/** Stagger timing for bubble animations (seconds) */\nconst STAGGER_DELAY = 0.08\nconst STAGGER_DELAY_INITIAL = 0.05\nconst STAGGER_DELAY_EXIT = 0.03\n\n/** Container animation variants for staggered children */\nconst containerVariants: Variants = {\n\thidden: { opacity: 0 },\n\tvisible: {\n\t\topacity: 1,\n\t\ttransition: {\n\t\t\tstaggerChildren: STAGGER_DELAY,\n\t\t\tdelayChildren: STAGGER_DELAY_INITIAL,\n\t\t},\n\t},\n\texit: {\n\t\topacity: 0,\n\t\ttransition: {\n\t\t\tstaggerChildren: STAGGER_DELAY_EXIT,\n\t\t\tstaggerDirection: -1,\n\t\t},\n\t},\n}\n\n/** Individual bubble animation variants */\nconst bubbleVariants: Variants = {\n\thidden: { opacity: 0, y: 10, scale: 0.9 },\n\tvisible: {\n\t\topacity: 1,\n\t\ty: 0,\n\t\tscale: 1,\n\t\ttransition: { type: 'spring', stiffness: 400, damping: 25 },\n\t},\n\texit: { opacity: 0, y: 5, scale: 0.95, transition: { duration: 0.1 } },\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\n/** Bubble button styles */\nconst bubbleStyles = cn(\n\t'flex items-center px-3 py-1.5',\n\t'bg-white dark:bg-zinc-800',\n\t'rounded-full',\n\t'shadow-lg shadow-black/10 dark:shadow-black/30',\n\t'border border-zinc-200/80 dark:border-zinc-700/80',\n\t'text-sm text-zinc-700 dark:text-zinc-200',\n\t'hover:bg-zinc-50 dark:hover:bg-zinc-700',\n\t'transition-colors duration-100',\n\t'whitespace-nowrap',\n\t// Focus state for keyboard navigation\n\t'focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1'\n)\n\n/** Dismiss badge base styles (shared between mobile and desktop) */\nconst dismissBadgeBaseStyles = cn(\n\t'absolute -top-1.5 -right-1.5',\n\t'flex items-center justify-center',\n\t'rounded-full',\n\t'bg-zinc-100 dark:bg-zinc-700',\n\t'border border-zinc-200 dark:border-zinc-600',\n\t'text-zinc-400 dark:text-zinc-400',\n\t'hover:bg-zinc-200 dark:hover:bg-zinc-600',\n\t'hover:text-zinc-600 dark:hover:text-zinc-200',\n\t'shadow-sm',\n\t'transition-all duration-150',\n\t// Focus state for keyboard navigation\n\t'focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500'\n)\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Floating prompt bubbles displayed above the pill.\n * Positioning is handled by the parent wrapper - this component just renders the bubbles.\n */\nexport const PromptBadge: FC<PromptBadgeProps> = ({ prompts, onSelect, className }) => {\n\tconst [isDismissed, setIsDismissed] = useState(false)\n\tconst { isMobile } = useMobileDetect()\n\n\tconst handleSelect = useCallback(\n\t\t(prompt: Prompt) => {\n\t\t\tonSelect(prompt)\n\t\t},\n\t\t[onSelect]\n\t)\n\n\tconst handleDismiss = useCallback((e: MouseEvent) => {\n\t\te.stopPropagation()\n\t\tsetIsDismissed(true)\n\t}, [])\n\n\t// Early return if no prompts or dismissed\n\tif (prompts.length === 0 || isDismissed) {\n\t\treturn null\n\t}\n\n\t// Take up to MAX_PROMPT_BUBBLES prompts\n\tconst visiblePrompts = prompts.slice(0, MAX_PROMPT_BUBBLES)\n\n\t// Dynamic dismiss badge styles based on device type\n\tconst dismissBadgeStyles = cn(\n\t\tdismissBadgeBaseStyles,\n\t\t// Size: 24px on mobile (WCAG AA), 16px on desktop\n\t\tisMobile ? 'w-6 h-6' : 'w-4 h-4',\n\t\t// Visibility: always visible on mobile, hover-only on desktop\n\t\tisMobile\n\t\t\t? 'opacity-100 scale-100'\n\t\t\t: 'opacity-0 group-hover:opacity-100 scale-75 group-hover:scale-100'\n\t)\n\n\treturn (\n\t\t<div className={className}>\n\t\t\t{/* Screen reader announcement */}\n\t\t\t<div role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n\t\t\t\t{visiblePrompts.length} suggestion{visiblePrompts.length !== 1 ? 's' : ''} available\n\t\t\t</div>\n\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t<motion.div\n\t\t\t\t\tkey=\"bubbles\"\n\t\t\t\t\tvariants={containerVariants}\n\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\texit=\"exit\"\n\t\t\t\t\tclassName=\"flex items-end gap-2\"\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\taria-label=\"Suggested prompts\"\n\t\t\t\t>\n\t\t\t\t\t{visiblePrompts.map((prompt, index) => {\n\t\t\t\t\t\t// Triangular offset: middle bubble (index 1) is raised when showing 3 bubbles\n\t\t\t\t\t\tconst isMiddleBubble = visiblePrompts.length === 3 && index === 1\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div key={prompt.name} className={cn('group relative', isMiddleBubble && 'mb-3')}>\n\t\t\t\t\t\t\t\t<motion.button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariants={bubbleVariants}\n\t\t\t\t\t\t\t\t\tonClick={() => handleSelect(prompt)}\n\t\t\t\t\t\t\t\t\tclassName={bubbleStyles}\n\t\t\t\t\t\t\t\t\ttitle={prompt.description || prompt.name}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span>{prompt.name}</span>\n\t\t\t\t\t\t\t\t</motion.button>\n\n\t\t\t\t\t\t\t\t{/* Dismiss badge - always visible on mobile, hover on desktop */}\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={handleDismiss}\n\t\t\t\t\t\t\t\t\tclassName={dismissBadgeStyles}\n\t\t\t\t\t\t\t\t\taria-label=\"Dismiss suggestions\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X size={isMobile ? 12 : 10} />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t</motion.div>\n\t\t\t</AnimatePresence>\n\t\t</div>\n\t)\n}\n\nexport default PromptBadge\n","/**\n * PromptSuggestions\n *\n * Inline prompt suggestions shown inside the expanded pill.\n * Compact horizontal scrollable list of prompt chips.\n */\nimport { AnimatePresence, motion } from 'motion/react'\nimport { useCallback, useRef } from 'react'\n\nimport { cn } from '../../lib/utils'\n\nimport type { Prompt } from '@mcp-b/cloud-mirror-types'\nimport type { FC } from 'react'\n\nexport interface PromptSuggestionsProps {\n\t/** Available prompts to display */\n\tprompts: Prompt[]\n\t/** Callback when a prompt is selected */\n\tonSelect: (prompt: Prompt) => void\n\t/** Additional class name */\n\tclassName?: string\n}\n\n/**\n * Inline prompt suggestions for the expanded pill.\n * Horizontally scrollable list of compact prompt chips.\n */\nexport const PromptSuggestions: FC<PromptSuggestionsProps> = ({ prompts, onSelect, className }) => {\n\tconst scrollRef = useRef<HTMLDivElement>(null)\n\n\tconst handleClick = useCallback(\n\t\t(prompt: Prompt) => {\n\t\t\tonSelect(prompt)\n\t\t},\n\t\t[onSelect]\n\t)\n\n\tif (prompts.length === 0) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<motion.div\n\t\t\tinitial={{ opacity: 0, height: 0 }}\n\t\t\tanimate={{ opacity: 1, height: 'auto' }}\n\t\t\texit={{ opacity: 0, height: 0 }}\n\t\t\tclassName={cn('overflow-hidden', className)}\n\t\t>\n\t\t\t<div\n\t\t\t\tref={scrollRef}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'flex gap-2 overflow-x-auto scrollbar-hide',\n\t\t\t\t\t'pb-1 -mb-1' // Padding for focus ring visibility\n\t\t\t\t)}\n\t\t\t\t// Allow horizontal scrolling within draggable parent\n\t\t\t\tstyle={{ touchAction: 'pan-x' }}\n\t\t\t\tonPointerDownCapture={(e) => e.stopPropagation()}\n\t\t\t>\n\t\t\t\t<AnimatePresence mode=\"popLayout\">\n\t\t\t\t\t{prompts.map((prompt, index) => (\n\t\t\t\t\t\t<motion.button\n\t\t\t\t\t\t\tkey={prompt.name}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.9 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.9 }}\n\t\t\t\t\t\t\ttransition={{\n\t\t\t\t\t\t\t\ttype: 'spring',\n\t\t\t\t\t\t\t\tstiffness: 400,\n\t\t\t\t\t\t\t\tdamping: 25,\n\t\t\t\t\t\t\t\tdelay: index * 0.03,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonClick={() => handleClick(prompt)}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'flex-shrink-0',\n\t\t\t\t\t\t\t\t'px-2.5 py-1 rounded-full',\n\t\t\t\t\t\t\t\t'bg-white/10 hover:bg-white/20',\n\t\t\t\t\t\t\t\t'text-white/80 hover:text-white',\n\t\t\t\t\t\t\t\t'text-xs font-medium',\n\t\t\t\t\t\t\t\t'border border-white/10 hover:border-white/20',\n\t\t\t\t\t\t\t\t'transition-all duration-150',\n\t\t\t\t\t\t\t\t'cursor-pointer',\n\t\t\t\t\t\t\t\t'whitespace-nowrap'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\ttitle={prompt.description || prompt.name}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{prompt.name}\n\t\t\t\t\t\t</motion.button>\n\t\t\t\t\t))}\n\t\t\t\t</AnimatePresence>\n\t\t\t</div>\n\t\t</motion.div>\n\t)\n}\n\nexport default PromptSuggestions\n","/**\n * StreamingResponse Component\n *\n * Shows the streaming text response from the agent as it's being generated.\n * This provides real-time visibility into what the agent is writing,\n * rather than waiting for the complete response.\n *\n * Features:\n * - Shows text as it streams in\n * - Typing cursor animation\n * - Compact, scrollable container\n * - Fades in/out smoothly\n */\n'use client'\n\nimport { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport { cn } from '../../lib/utils'\nimport { PillMarkdown } from './PillMarkdown'\n\nimport type { FC } from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface TextPart {\n\ttype: 'text'\n\ttext: string\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook to get the current streaming text from the thread.\n * Returns null if not currently streaming or no text content.\n */\nexport function useStreamingText(): string | null {\n\tconst messages = useThread((thread) => thread.messages)\n\tconst isRunning = useThread((thread) => thread.isRunning)\n\n\treturn useMemo(() => {\n\t\tif (!isRunning) return null\n\n\t\t// Find the last assistant message\n\t\tconst lastAssistantMessage = messages\n\t\t\t? [...messages].reverse().find((m) => m.role === 'assistant')\n\t\t\t: null\n\n\t\tif (!lastAssistantMessage) return null\n\n\t\t// Get text parts\n\t\tconst textParts = lastAssistantMessage.content.filter(\n\t\t\t(part): part is TextPart => part.type === 'text'\n\t\t)\n\t\tconst lastText = textParts.at(-1)?.text\n\n\t\t// Only return if there's actual text content\n\t\tif (!lastText || lastText.trim().length === 0) return null\n\n\t\treturn lastText\n\t}, [messages, isRunning])\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\ninterface StreamingResponseProps {\n\t/** Maximum height before scrolling (ignored when isFullScreen) */\n\tmaxHeight?: string\n\t/** Additional class name */\n\tclassName?: string\n\t/** Full-screen mode - larger text, no height constraints (parent handles scrolling) */\n\tisFullScreen?: boolean\n}\n\n/**\n * Displays the streaming response text as it's being generated.\n * Shows a typing cursor and scrolls to keep latest content visible.\n */\nexport const StreamingResponse: FC<StreamingResponseProps> = ({\n\tmaxHeight = '8rem',\n\tclassName,\n\tisFullScreen = false,\n}) => {\n\tconst streamingText = useStreamingText()\n\n\tif (!streamingText) return null\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'rounded-lg bg-white/5 border border-white/10 p-3',\n\t\t\t\t'overflow-y-auto scrollbar-thin scroll-touch',\n\t\t\t\t// Bottom margin for spacing from tool section\n\t\t\t\t'mb-1.5',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tstyle={isFullScreen ? undefined : { maxHeight }}\n\t\t>\n\t\t\t<div className=\"relative\">\n\t\t\t\t<PillMarkdown content={streamingText} className=\"text-white/90\" compact={!isFullScreen} />\n\t\t\t\t{/* Typing cursor */}\n\t\t\t\t<span className=\"inline-block w-0.5 h-4 bg-blue-400 ml-0.5 animate-pulse align-middle\" />\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default StreamingResponse\n","'use client'\n\nimport { AnimatePresence, motion } from 'motion/react'\nimport { useEffect, useRef, useState } from 'react'\n\nimport { cn } from '../../lib/utils'\n\nimport type { FC, ReactNode } from 'react'\n\n// Minimalist: only idle, calling, and error states\n// Success is the default - no special treatment needed\nexport type ToolBorderStatus = 'idle' | 'calling' | 'success' | 'error'\n\ninterface ToolStatusBorderProps {\n\tstatus: ToolBorderStatus\n\tchildren: ReactNode\n\tclassName?: string\n\tborderRadius?: string\n}\n\n// Animation variants for the border glow\nconst borderVariants = {\n\tidle: {\n\t\topacity: 0,\n\t\tscale: 1,\n\t},\n\tcalling: {\n\t\topacity: 1,\n\t\tscale: 1,\n\t\ttransition: {\n\t\t\topacity: { duration: 0.15 },\n\t\t},\n\t},\n\terror: {\n\t\topacity: 1,\n\t\tscale: 1,\n\t\ttransition: {\n\t\t\topacity: { duration: 0.1 },\n\t\t},\n\t},\n}\n\n// Subtle shake animation for errors only\nconst shakeAnimation = {\n\tx: [0, -2, 2, -2, 2, 0],\n\ttransition: {\n\t\tduration: 0.3,\n\t\tease: [0.25, 0.1, 0.25, 1] as const,\n\t},\n}\n\n/**\n * Minimal animated border for tool execution status.\n *\n * - idle/success: clean, no border (success is the default state)\n * - calling: subtle animated gradient\n * - error: brief red flash with shake\n */\nexport const ToolStatusBorder: FC<ToolStatusBorderProps> = ({\n\tstatus,\n\tchildren,\n\tclassName,\n\tborderRadius = '20px',\n}) => {\n\t// Treat success as idle - no special visual treatment\n\tconst effectiveStatus = status === 'success' ? 'idle' : status\n\n\treturn (\n\t\t<motion.div\n\t\t\tclassName={cn('relative', className)}\n\t\t\tanimate={effectiveStatus === 'error' ? shakeAnimation : undefined}\n\t\t>\n\t\t\t{/* Animated border layer - only for calling and error */}\n\t\t\t<AnimatePresence>\n\t\t\t\t{effectiveStatus !== 'idle' && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'absolute -inset-[1px] pointer-events-none',\n\t\t\t\t\t\t\teffectiveStatus === 'calling' && 'tool-border-calling',\n\t\t\t\t\t\t\teffectiveStatus === 'error' && 'tool-border-error'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ borderRadius }}\n\t\t\t\t\t\tvariants={borderVariants}\n\t\t\t\t\t\tinitial=\"idle\"\n\t\t\t\t\t\tanimate={effectiveStatus}\n\t\t\t\t\t\texit={{ opacity: 0, transition: { duration: 0.15 } }}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t{/* Inner content container - no ring for cleaner look */}\n\t\t\t<div className=\"relative\" style={{ borderRadius }}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</motion.div>\n\t)\n}\n\n/**\n * Hook to manage tool border status based on actions.\n * Minimalist approach: success returns to idle immediately.\n */\nexport function useToolBorderStatus(\n\thasRunningAction: boolean,\n\tlastActionStatus?: 'success' | 'error' | null\n): ToolBorderStatus {\n\tconst [status, setStatus] = useState<ToolBorderStatus>('idle')\n\tconst timeoutRef = useRef<NodeJS.Timeout | null>(null)\n\n\tuseEffect(() => {\n\t\tif (timeoutRef.current) {\n\t\t\tclearTimeout(timeoutRef.current)\n\t\t\ttimeoutRef.current = null\n\t\t}\n\n\t\tif (hasRunningAction) {\n\t\t\tsetStatus('calling')\n\t\t} else if (lastActionStatus === 'error') {\n\t\t\tsetStatus('error')\n\t\t\t// Brief error flash, then back to idle\n\t\t\ttimeoutRef.current = setTimeout(() => {\n\t\t\t\tsetStatus('idle')\n\t\t\t}, 400)\n\t\t} else {\n\t\t\t// Success or no action = idle (clean state)\n\t\t\tsetStatus('idle')\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (timeoutRef.current) {\n\t\t\t\tclearTimeout(timeoutRef.current)\n\t\t\t}\n\t\t}\n\t}, [hasRunningAction, lastActionStatus])\n\n\treturn status\n}\n","'use client'\n\nimport { ThreadPrimitive, useComposerRuntime, useThreadRuntime } from '@assistant-ui/react'\nimport { Expand, GripHorizontal, Minimize, X } from 'lucide-react'\nimport { AnimatePresence, motion, useDragControls } from 'motion/react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { useAgent } from '../../core/hooks/useAgent'\nimport { useOptionalAgentUI } from '../../core/providers/AgentUIProvider'\nimport { useKeyboardAware } from '../../hooks/useKeyboardAware'\nimport { useMobileDetect } from '../../hooks/useMobileDetect'\nimport { useHasPendingToolCalls, usePendingToolCalls } from '../../hooks/usePendingToolCalls'\nimport { usePinchGesture } from '../../hooks/usePinchGesture'\nimport {\n\tARIA_LABELS,\n\tAUTO_COLLAPSE_TIMEOUT_MS,\n\tdebugLog,\n\tDRAG_OPACITY,\n\tGESTURE_CONFIG,\n\tKEYBOARD_GAP_PX,\n\tPILL_BORDER_RADIUS,\n} from '../../lib/constants'\nimport { formatToolDenialWithReason } from '../../lib/format'\nimport { resolvePendingToolCall } from '../../lib/thread-utils'\nimport { cn } from '../../lib/utils'\nimport { ActivityIndicator } from './ActivityIndicator'\nimport { ApprovalModeIndicator } from './ApprovalModeToggle'\nimport { IdleIndicator } from './CurrentActivity'\nimport { ElicitationButtonBar } from './ElicitationButtonBar'\nimport { PillComposer } from './PillComposer'\nimport { PillContainer } from './PillContainer'\nimport { PillToolsSection } from './PillToolsSection'\nimport { PillVoice, useVoiceBorderStatus } from './PillVoice'\nimport { PromptBadge } from './PromptBadge'\nimport { PromptSuggestions } from './PromptSuggestions'\nimport { StreamingResponse } from './StreamingResponse'\nimport { SummaryBlock, WelcomeMessage } from './SummaryBlock'\nimport { ToolStatusBorder, useToolBorderStatus } from './ToolStatusBorder'\n\nimport type { Prompt } from '@mcp-b/cloud-mirror-types'\nimport type { FC } from 'react'\nimport type { PillMode } from './PillContainer'\n\n/** Position of the pill on screen */\nexport type PillPosition = 'bottom-center' | 'bottom-right'\n\nexport interface AgentPillProps {\n\t/** Position of the pill on screen */\n\tposition?: PillPosition\n\t/** Show voice button in composer */\n\tshowVoiceButton?: boolean\n\t/** Voice mode active state (external control) */\n\tisVoiceActive?: boolean\n\t/** Voice toggle callback */\n\tonVoiceToggle?: () => void\n\t/** Auto-collapse after inactivity (default: true) */\n\tautoCollapse?: boolean\n\t/** Additional class name */\n\tclassName?: string\n}\n\n/**\n * Action-first agent pill UI.\n *\n * A compact, morphing interface that shows:\n * - Current activity when agent is working\n * - Action list (collapsible)\n * - Summary when complete\n * - Input composer\n *\n * Uses assistant-ui primitives for data binding.\n * UI state (mode, position, hasUnread) comes from AgentUIProvider.\n * Thread state (messages, actions) comes from assistant-ui.\n */\nexport const AgentPill: FC<AgentPillProps> = ({\n\tposition = 'bottom-center',\n\tshowVoiceButton = false,\n\tisVoiceActive = false,\n\tonVoiceToggle,\n\tautoCollapse = true,\n\tclassName,\n}) => {\n\t// Get agent state (unified facade over thread, actions, voice, tools)\n\tconst agent = useAgent()\n\n\t// Destructure agent state for convenience\n\tconst {\n\t\tmessages,\n\t\tisRunning,\n\t\thasMessages,\n\t\tcurrentAction,\n\t\tlastCompletedAction,\n\t\tsummary,\n\t\tvoice,\n\t\ttools,\n\t\tisVoiceActive: agentVoiceActive,\n\t} = agent\n\n\t// Check if there are pending approvals (HITL tools) - derived from thread state\n\tconst hasPendingApprovalRaw = useHasPendingToolCalls()\n\tconst pendingToolCalls = usePendingToolCalls()\n\tconst threadRuntime = useThreadRuntime()\n\n\t// Delay showing/hiding approval UI to prevent flash when state transitions quickly\n\t// This gives time for state to settle before UI changes\n\tconst [hasPendingApproval, setHasPendingApproval] = useState(false)\n\tuseEffect(() => {\n\t\tif (hasPendingApprovalRaw) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tsetHasPendingApproval(true)\n\t\t\t}, 100) // 100ms delay prevents flash when showing\n\t\t\treturn () => clearTimeout(timer)\n\t\t} else {\n\t\t\t// Also delay hiding to prevent flash when approval completes\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tsetHasPendingApproval(false)\n\t\t\t}, 50) // 50ms delay prevents flash when hiding\n\t\t\treturn () => clearTimeout(timer)\n\t\t}\n\t}, [hasPendingApprovalRaw])\n\n\t// Get UI state from AgentUIProvider (falls back to local state if not wrapped)\n\tconst agentUI = useOptionalAgentUI()\n\n\t// UI state - prefer provider state, fallback to default\n\tconst userMode = agentUI?.userMode ?? 'collapsed'\n\tconst setUserMode = agentUI?.setUserMode ?? (() => {})\n\tconst hasUnread = agentUI?.hasUnread ?? false\n\tconst markRead = agentUI?.markRead ?? (() => {})\n\tconst markUnread = agentUI?.markUnread ?? (() => {})\n\tconst dragPosition = agentUI?.position ?? { x: 0, y: 0 }\n\tconst setDragPosition = agentUI?.setPosition ?? (() => {})\n\tconst resetPosition = agentUI?.resetPosition ?? (() => {})\n\n\t// Full-screen mode state\n\tconst isFullScreen = agentUI?.isFullScreen ?? false\n\tconst enterFullScreen = agentUI?.enterFullScreen ?? (() => {})\n\tconst exitFullScreen = agentUI?.exitFullScreen ?? (() => {})\n\n\tconst dragControls = useDragControls()\n\tconst constraintsRef = useRef<HTMLDivElement>(null)\n\tconst autoCollapseTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n\tconst lastMessageCountRef = useRef(0)\n\n\t// Keyboard-aware positioning for mobile\n\tconst { isKeyboardVisible, keyboardHeight } = useKeyboardAware()\n\n\t// Mobile detection for gesture handling\n\tconst { isMobile } = useMobileDetect()\n\n\t// Get prompts from tools (if available)\n\tconst prompts = tools?.prompts ?? []\n\tconst getPrompt = tools?.getPrompt\n\n\t// Get composer runtime for programmatic message sending\n\tconst composerRuntime = useComposerRuntime()\n\n\t/**\n\t * Handle drag end - processes both drag-to-reposition and swipe-to-dismiss gestures.\n\t *\n\t * Behavior:\n\t * - Desktop: Drag to reposition only (no swipe gestures)\n\t * - Mobile: Drag to reposition + aggressive swipe-up to dismiss\n\t */\n\tconst handleDragEnd = useCallback(\n\t\t(_: unknown, info: { offset: { x: number; y: number }; velocity: { y: number } }) => {\n\t\t\tconst { offset, velocity } = info\n\t\t\tconst dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2)\n\n\t\t\t// Check if pill is in an expanded state (not collapsed or hovered)\n\t\t\tconst isExpanded =\n\t\t\t\tuserMode === 'composing' || userMode === 'active' || userMode === 'expanded'\n\n\t\t\t// === MOBILE: Check for swipe-to-dismiss (aggressive upward swipe) ===\n\t\t\tif (isMobile && isExpanded) {\n\t\t\t\tconst swipeDistance = -offset.y // Positive = upward swipe\n\t\t\t\tconst swipeVelocity = -velocity.y // Positive = upward velocity\n\n\t\t\t\tconst { swipe } = GESTURE_CONFIG\n\t\t\t\tconst isAggressiveSwipe =\n\t\t\t\t\t// Either: distance AND velocity both exceed thresholds\n\t\t\t\t\t(swipeDistance > swipe.minDistance && swipeVelocity > swipe.minVelocity) ||\n\t\t\t\t\t// Or: extremely fast swipe (regardless of distance)\n\t\t\t\t\tswipeVelocity > swipe.velocityOnlyThreshold\n\n\t\t\t\tif (isAggressiveSwipe) {\n\t\t\t\t\tsetUserMode('collapsed')\n\t\t\t\t\tresetPosition()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// === DRAG: Only update position if drag exceeded activation threshold ===\n\t\t\tif (dragDistance >= GESTURE_CONFIG.dragActivationDistance) {\n\t\t\t\tsetDragPosition({\n\t\t\t\t\tx: dragPosition.x + offset.x,\n\t\t\t\t\ty: dragPosition.y + offset.y,\n\t\t\t\t})\n\t\t\t}\n\t\t\t// If drag distance is below threshold, ignore it (allows clean taps)\n\t\t},\n\t\t[\n\t\t\tdragPosition.x,\n\t\t\tdragPosition.y,\n\t\t\tsetDragPosition,\n\t\t\tisMobile,\n\t\t\tuserMode,\n\t\t\tsetUserMode,\n\t\t\tresetPosition,\n\t\t]\n\t)\n\n\t// Track unread messages when collapsed\n\tuseEffect(() => {\n\t\tconst currentCount = messages?.length ?? 0\n\t\tif (userMode === 'collapsed' && currentCount > lastMessageCountRef.current) {\n\t\t\tmarkUnread()\n\t\t}\n\t\tlastMessageCountRef.current = currentCount\n\t}, [messages?.length, userMode, markUnread])\n\n\t// Clear unread when expanded\n\tuseEffect(() => {\n\t\tif (userMode !== 'collapsed') {\n\t\t\tmarkRead()\n\t\t}\n\t}, [userMode, markRead])\n\n\t// Voice border status for animations\n\tconst voiceBorderStatus = useVoiceBorderStatus()\n\n\t// Voice mode is active when connected, connecting, or showing an error\n\tconst isVoiceModeActive = agentVoiceActive || isVoiceActive\n\n\t// Get border status - use voice status when in voice mode\n\tconst textBorderStatus = useToolBorderStatus(\n\t\t!!currentAction,\n\t\tlastCompletedAction?.status === 'success'\n\t\t\t? 'success'\n\t\t\t: lastCompletedAction?.status === 'error'\n\t\t\t\t? 'error'\n\t\t\t\t: null\n\t)\n\tconst borderStatus = isVoiceModeActive ? voiceBorderStatus : textBorderStatus\n\n\t// Determine actual mode based on state\n\tconst mode = useMemo((): PillMode => {\n\t\t// Voice mode is active - always show as active\n\t\tif (isVoiceModeActive) return 'active'\n\n\t\t// User explicitly collapsed\n\t\tif (userMode === 'collapsed') return 'collapsed'\n\t\tif (userMode === 'hovered') return 'hovered'\n\n\t\t// Agent is running or pending approval - show active mode\n\t\tif (isRunning || hasPendingApproval) return 'active'\n\n\t\t// Has messages (completed)\n\t\tif (hasMessages) return 'expanded'\n\n\t\t// User is composing\n\t\tif (userMode === 'composing') return 'composing'\n\n\t\treturn 'collapsed'\n\t}, [userMode, isRunning, hasMessages, isVoiceModeActive, hasPendingApproval])\n\n\t// Handle mode changes\n\tconst handleModeChange = useCallback(\n\t\t(newMode: PillMode) => {\n\t\t\tsetUserMode(newMode)\n\t\t},\n\t\t[setUserMode]\n\t)\n\n\t// Handle collapse - close back to collapsed state\n\tconst handleCollapse = useCallback(() => {\n\t\tsetUserMode('collapsed')\n\t}, [setUserMode])\n\n\t// Reset position when pill collapses (position only applies to expanded state)\n\tuseEffect(() => {\n\t\tif (mode === 'collapsed' || mode === 'hovered') {\n\t\t\tresetPosition()\n\t\t}\n\t}, [mode, resetPosition])\n\n\t// Auto-collapse after inactivity (only when expanded/composing and not running)\n\tuseEffect(() => {\n\t\tif (!autoCollapse) return\n\n\t\t// Clear existing timeout\n\t\tif (autoCollapseTimeoutRef.current) {\n\t\t\tclearTimeout(autoCollapseTimeoutRef.current)\n\t\t\tautoCollapseTimeoutRef.current = null\n\t\t}\n\n\t\t// Only auto-collapse when in composing or expanded mode (not active/running)\n\t\tif (mode === 'composing' || (mode === 'expanded' && !isRunning)) {\n\t\t\tautoCollapseTimeoutRef.current = setTimeout(() => {\n\t\t\t\tsetUserMode('collapsed')\n\t\t\t}, AUTO_COLLAPSE_TIMEOUT_MS)\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (autoCollapseTimeoutRef.current) {\n\t\t\t\tclearTimeout(autoCollapseTimeoutRef.current)\n\t\t\t}\n\t\t}\n\t}, [mode, isRunning, autoCollapse, setUserMode])\n\n\t// Handle voice toggle\n\tconst handleVoiceToggle = useCallback(() => {\n\t\tif (voice) {\n\t\t\tif (voice.isActive || voice.isConnecting) {\n\t\t\t\tvoice.stop()\n\t\t\t} else {\n\t\t\t\tvoid voice.start()\n\t\t\t}\n\t\t}\n\t\tonVoiceToggle?.()\n\t}, [voice, onVoiceToggle])\n\n\t// Handle prompt selection - expand pill and send prompt content\n\tconst handlePromptSelect = useCallback(\n\t\tasync (prompt: Prompt) => {\n\t\t\t// Expand the pill to composing mode\n\t\t\tsetUserMode('composing')\n\n\t\t\tif (!getPrompt) return\n\n\t\t\ttry {\n\t\t\t\t// Get the expanded prompt content\n\t\t\t\tconst result = await getPrompt(prompt.name)\n\n\t\t\t\t// Find the first user message in the prompt result\n\t\t\t\tconst userMessage = result.messages?.find(\n\t\t\t\t\t(m: { role: string; content: unknown }) => m.role === 'user'\n\t\t\t\t)\n\t\t\t\tif (userMessage) {\n\t\t\t\t\t// Extract text content from the message\n\t\t\t\t\tlet textContent = ''\n\t\t\t\t\tif (typeof userMessage.content === 'string') {\n\t\t\t\t\t\ttextContent = userMessage.content\n\t\t\t\t\t} else if (userMessage.content.type === 'text') {\n\t\t\t\t\t\ttextContent = userMessage.content.text\n\t\t\t\t\t}\n\n\t\t\t\t\tif (textContent) {\n\t\t\t\t\t\t// Set the composer text and send\n\t\t\t\t\t\tcomposerRuntime.setText(textContent)\n\t\t\t\t\t\tcomposerRuntime.send()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tdebugLog('AgentPill', 'Failed to get prompt', err)\n\t\t\t}\n\t\t},\n\t\t[getPrompt, composerRuntime, setUserMode]\n\t)\n\n\t// Handle elicitation denial with reason (user tells Char what to do differently)\n\tconst handleElicitationDeny = useCallback(\n\t\t(reason: string) => {\n\t\t\tif (pendingToolCalls.length > 0) {\n\t\t\t\tconst firstTool = pendingToolCalls[0]\n\t\t\t\tconst message = formatToolDenialWithReason(reason)\n\t\t\t\tresolvePendingToolCall(threadRuntime, firstTool.messageId, firstTool.toolCallId, message)\n\t\t\t}\n\t\t},\n\t\t[pendingToolCalls, threadRuntime]\n\t)\n\n\t// Get border radius for current mode\n\tconst borderRadius =\n\t\tmode === 'collapsed' || mode === 'hovered'\n\t\t\t? PILL_BORDER_RADIUS.pill\n\t\t\t: PILL_BORDER_RADIUS.rounded\n\n\t// Check if pill is expanded (can be collapsed and can be dragged)\n\tconst isExpanded = mode === 'composing' || mode === 'active' || mode === 'expanded'\n\n\t// Pinch gesture for mobile expand/collapse to full-screen\n\tconst { handlers: pinchHandlers } = usePinchGesture({\n\t\tonPinchOut: () => {\n\t\t\tif (isExpanded && !isFullScreen && !isVoiceModeActive) {\n\t\t\t\tenterFullScreen()\n\t\t\t}\n\t\t},\n\t\tonPinchIn: () => {\n\t\t\tif (isFullScreen) {\n\t\t\t\texitFullScreen()\n\t\t\t}\n\t\t},\n\t\tenabled: isMobile && (isExpanded || isFullScreen),\n\t})\n\n\t// Deferred composer mount - delays rendering PillComposer until container animation settles\n\t// This fixes a bug where react-textarea-autosize measures wrong height during width animation\n\tconst [isComposerReady, setComposerReady] = useState(false)\n\tuseEffect(() => {\n\t\tif (isExpanded) {\n\t\t\tconst timer = setTimeout(() => setComposerReady(true), 200) // Wait for spring to settle\n\t\t\treturn () => {\n\t\t\t\tclearTimeout(timer)\n\t\t\t\tsetComposerReady(false)\n\t\t\t}\n\t\t} else {\n\t\t\tsetComposerReady(false)\n\t\t}\n\t}, [isExpanded])\n\n\t// Handle Escape key to exit full-screen\n\tuseEffect(() => {\n\t\tif (!isFullScreen) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\te.preventDefault()\n\t\t\t\texitFullScreen()\n\t\t\t}\n\t\t}\n\n\t\twindow.addEventListener('keydown', handleKeyDown)\n\t\treturn () => window.removeEventListener('keydown', handleKeyDown)\n\t}, [isFullScreen, exitFullScreen])\n\n\treturn (\n\t\t<>\n\t\t\t{/* Drag constraints - full viewport */}\n\t\t\t<div ref={constraintsRef} className=\"fixed inset-0 pointer-events-none\" />\n\n\t\t\t<ThreadPrimitive.Root\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'fixed z-50 bottom-safe pb-safe pointer-events-auto',\n\t\t\t\t\tposition === 'bottom-center' && 'left-1/2 -translate-x-1/2',\n\t\t\t\t\tposition === 'bottom-right' && 'right-4',\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<motion.div\n\t\t\t\t\t// Allow dragging when expanded (including full-screen mode)\n\t\t\t\t\tdrag={isExpanded}\n\t\t\t\t\tdragControls={dragControls}\n\t\t\t\t\tdragConstraints={constraintsRef}\n\t\t\t\t\tdragElastic={0.15}\n\t\t\t\t\tdragMomentum={false}\n\t\t\t\t\t// High transparency while dragging lets user see underlying content (useful for reference)\n\t\t\t\t\twhileDrag={{ scale: 1.02, opacity: DRAG_OPACITY.dragging }}\n\t\t\t\t\tonDragEnd={handleDragEnd}\n\t\t\t\t\t// Keyboard positioning: snap to fixed center position above keyboard\n\t\t\t\t\t// This ensures consistent, predictable placement every time keyboard appears\n\t\t\t\t\t// When keyboard hides: restore the user's previous drag position\n\t\t\t\t\tinitial={false}\n\t\t\t\t\tanimate={{\n\t\t\t\t\t\tx: isExpanded ? (isKeyboardVisible ? 0 : dragPosition.x) : 0,\n\t\t\t\t\t\ty: isExpanded\n\t\t\t\t\t\t\t? isKeyboardVisible\n\t\t\t\t\t\t\t\t? -keyboardHeight - KEYBOARD_GAP_PX\n\t\t\t\t\t\t\t\t: dragPosition.y\n\t\t\t\t\t\t\t: 0,\n\t\t\t\t\t}}\n\t\t\t\t\ttransition={{ type: 'spring', stiffness: 400, damping: 30 }}\n\t\t\t\t\tclassName={cn('relative', isExpanded && 'cursor-grab active:cursor-grabbing')}\n\t\t\t\t\t// Prevent touch events from affecting underlying page scroll (only when expanded)\n\t\t\t\t\tstyle={{ touchAction: isExpanded || isFullScreen ? 'none' : 'auto' }}\n\t\t\t\t\t// Pinch gesture handlers for mobile\n\t\t\t\t\t{...pinchHandlers}\n\t\t\t\t>\n\t\t\t\t\t{/* Prompt badge - floating above collapsed pill when prompts exist */}\n\t\t\t\t\t{/* Positioned relative to motion.div so it centers over the actual pill content */}\n\t\t\t\t\t{mode === 'collapsed' && prompts.length > 0 && (\n\t\t\t\t\t\t<div className=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-3 z-20\">\n\t\t\t\t\t\t\t<PromptBadge prompts={prompts} onSelect={handlePromptSelect} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Unread indicator dot - shown when collapsed with unread messages */}\n\t\t\t\t\t{mode === 'collapsed' && hasUnread && (\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tinitial={{ scale: 0 }}\n\t\t\t\t\t\t\tanimate={{ scale: 1 }}\n\t\t\t\t\t\t\tclassName=\"absolute -top-1 -right-1 w-2 h-2 bg-blue-500 rounded-full z-10\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<ToolStatusBorder status={borderStatus} borderRadius={borderRadius}>\n\t\t\t\t\t\t<PillContainer mode={mode} onModeChange={handleModeChange} isFullScreen={isFullScreen}>\n\t\t\t\t\t\t\t{/* Header with drag handle and close button - shown when expanded or in voice mode */}\n\t\t\t\t\t\t\t{(isVoiceModeActive || isExpanded) && (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between mb-1 -mt-1\">\n\t\t\t\t\t\t\t\t\t{/* Drag handle - visual affordance for repositioning */}\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center text-white/30 p-1 -m-1 cursor-grab active:cursor-grabbing\"\n\t\t\t\t\t\t\t\t\t\tonPointerDown={(e) => dragControls.start(e)}\n\t\t\t\t\t\t\t\t\t\taria-label={ARIA_LABELS.dragHandle}\n\t\t\t\t\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<GripHorizontal className=\"h-4 w-4 sm:h-3 sm:w-3\" />\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Right side controls */}\n\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2 sm:gap-1\">\n\t\t\t\t\t\t\t\t\t\t{/* Expand/Minimize button - desktop only, not in voice mode */}\n\t\t\t\t\t\t\t\t\t\t{!isMobile && !isVoiceModeActive && (\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={isFullScreen ? exitFullScreen : enterFullScreen}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'min-w-7 min-h-7',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'flex items-center justify-center',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'p-1 rounded-full',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'hover:bg-white/10 active:bg-white/20',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'text-white/40 hover:text-white/70',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\t\t\t\tisFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? ARIA_LABELS.collapseFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ARIA_LABELS.expandFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{isFullScreen ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Minimize className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Expand className=\"h-3.5 w-3.5\" />\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t\t{/* Approval mode toggle */}\n\t\t\t\t\t\t\t\t\t\t<ApprovalModeIndicator />\n\n\t\t\t\t\t\t\t\t\t\t{/* Close button - larger touch target on mobile (min 44px for AAA) */}\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={\n\t\t\t\t\t\t\t\t\t\t\t\tisVoiceModeActive\n\t\t\t\t\t\t\t\t\t\t\t\t\t? handleVoiceToggle\n\t\t\t\t\t\t\t\t\t\t\t\t\t: isFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? exitFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: handleCollapse\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t// Touch target: 44px on mobile (AAA), 28px on desktop\n\t\t\t\t\t\t\t\t\t\t\t\t'min-w-11 min-h-11 sm:min-w-7 sm:min-h-7',\n\t\t\t\t\t\t\t\t\t\t\t\t'flex items-center justify-center',\n\t\t\t\t\t\t\t\t\t\t\t\t'p-2 sm:p-1 rounded-full',\n\t\t\t\t\t\t\t\t\t\t\t\t'hover:bg-white/10 active:bg-white/20',\n\t\t\t\t\t\t\t\t\t\t\t\t'text-white/40 hover:text-white/70',\n\t\t\t\t\t\t\t\t\t\t\t\t'transition-colors duration-150'\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\t\t\tisVoiceModeActive\n\t\t\t\t\t\t\t\t\t\t\t\t\t? ARIA_LABELS.endVoiceSession\n\t\t\t\t\t\t\t\t\t\t\t\t\t: isFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? ARIA_LABELS.collapseFullScreen\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ARIA_LABELS.closeAssistant\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<X className=\"h-5 w-5 sm:h-3.5 sm:w-3.5\" />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* Voice mode UI - when voice is active (not in full-screen) */}\n\t\t\t\t\t\t\t{!isFullScreen && (\n\t\t\t\t\t\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t\t\t\t\t\t{isVoiceModeActive && <PillVoice key=\"voice-mode\" onEnd={handleVoiceToggle} />}\n\t\t\t\t\t\t\t\t</AnimatePresence>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* Main content - simple flex column, scrolling handled by PillContainer */}\n\t\t\t\t\t\t\t{!isVoiceModeActive && (\n\t\t\t\t\t\t\t\t<div className=\"flex flex-col\">\n\t\t\t\t\t\t\t\t\t{/* Welcome message - composing without messages */}\n\t\t\t\t\t\t\t\t\t{mode === 'composing' && !hasMessages && <WelcomeMessage />}\n\n\t\t\t\t\t\t\t\t\t{/* Summary - when completed */}\n\t\t\t\t\t\t\t\t\t{mode === 'expanded' && !isRunning && summary && (\n\t\t\t\t\t\t\t\t\t\t<SummaryBlock\n\t\t\t\t\t\t\t\t\t\t\tsummary={summary}\n\t\t\t\t\t\t\t\t\t\t\tisSuccess={!lastCompletedAction?.error}\n\t\t\t\t\t\t\t\t\t\t\tisFullScreen={isFullScreen}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Streaming response - shows text as it's being generated */}\n\t\t\t\t\t\t\t\t\t<AnimatePresence>\n\t\t\t\t\t\t\t\t\t\t{(mode === 'active' || mode === 'expanded') && isRunning && (\n\t\t\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t\t\tkey=\"streaming\"\n\t\t\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\ttransition={{ duration: 0.1 }}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<StreamingResponse isFullScreen={isFullScreen} />\n\t\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</AnimatePresence>\n\n\t\t\t\t\t\t\t\t\t{/* Idle indicator - when expanded but no activity */}\n\t\t\t\t\t\t\t\t\t{mode === 'expanded' && !isRunning && !summary && <IdleIndicator />}\n\n\t\t\t\t\t\t\t\t\t{/* Tool UIs in collapsible, scrollable section */}\n\t\t\t\t\t\t\t\t\t<AnimatePresence>\n\t\t\t\t\t\t\t\t\t\t{(mode === 'active' || mode === 'expanded') && (\n\t\t\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t\t\tkey=\"tools\"\n\t\t\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\ttransition={{ duration: 0.1 }}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<PillToolsSection\n\t\t\t\t\t\t\t\t\t\t\t\t\tdefaultCollapsed={mode === 'active' && !isFullScreen}\n\t\t\t\t\t\t\t\t\t\t\t\t\tisFullScreen={isFullScreen}\n\t\t\t\t\t\t\t\t\t\t\t\t\tforceCollapsed={hasPendingApproval}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</AnimatePresence>\n\n\t\t\t\t\t\t\t\t\t{/* Elicitation buttons - above composer when approval is needed */}\n\t\t\t\t\t\t\t\t\t<AnimatePresence>\n\t\t\t\t\t\t\t\t\t\t{(mode === 'active' || mode === 'expanded') && hasPendingApproval && (\n\t\t\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t\t\tkey=\"elicitation\"\n\t\t\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\ttransition={{ duration: 0.1 }}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<ElicitationButtonBar />\n\t\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</AnimatePresence>\n\n\t\t\t\t\t\t\t\t\t{/* Prompt suggestions - inline chips when expanded and not running (hidden in full-screen) */}\n\t\t\t\t\t\t\t\t\t{!isFullScreen &&\n\t\t\t\t\t\t\t\t\t\t(mode === 'composing' || mode === 'expanded') &&\n\t\t\t\t\t\t\t\t\t\t!isRunning &&\n\t\t\t\t\t\t\t\t\t\t!hasPendingApproval &&\n\t\t\t\t\t\t\t\t\t\tprompts.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t<PromptSuggestions prompts={prompts} onSelect={handlePromptSelect} />\n\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Activity indicator - shows what agent is doing when running */}\n\t\t\t\t\t\t\t\t\t<AnimatePresence>\n\t\t\t\t\t\t\t\t\t\t{(mode === 'active' || mode === 'expanded') &&\n\t\t\t\t\t\t\t\t\t\t\tisRunning &&\n\t\t\t\t\t\t\t\t\t\t\t!hasPendingApproval && (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey=\"activity\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\ttransition={{ duration: 0.1 }}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ActivityIndicator />\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</AnimatePresence>\n\n\t\t\t\t\t\t\t\t\t{/* Composer - always visible when expanded (no longer hidden during approval) */}\n\t\t\t\t\t\t\t\t\t<AnimatePresence>\n\t\t\t\t\t\t\t\t\t\t{isComposerReady &&\n\t\t\t\t\t\t\t\t\t\t\t(mode === 'composing' || mode === 'active' || mode === 'expanded') && (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\ttransition={{ duration: 0.15 }}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"mt-1.5\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<PillComposer\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tshowVoiceButton={showVoiceButton || !!voice?.isSupported}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisVoiceActive={isVoiceActive}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonVoiceToggle={handleVoiceToggle}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisEliciting={hasPendingApproval}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonElicitationSubmit={handleElicitationDeny}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</AnimatePresence>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</PillContainer>\n\t\t\t\t\t</ToolStatusBorder>\n\t\t\t\t</motion.div>\n\t\t\t</ThreadPrimitive.Root>\n\t\t</>\n\t)\n}\n\nexport default AgentPill\n","'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { FC, ReactNode } from 'react'\n\nexport interface ShadowRootProps {\n\t/** Children to render inside the shadow DOM */\n\tchildren: ReactNode\n\t/** CSS styles to inject into the shadow root */\n\tstyles: string\n\t/** Optional class name for the shadow host element */\n\tclassName?: string\n\t/** Mode for the shadow DOM (default: 'open') */\n\tmode?: 'open' | 'closed'\n}\n\n/**\n * ShadowRoot - Renders children inside an isolated shadow DOM\n *\n * This component creates a shadow DOM boundary that:\n * - Isolates styles from the main page (no style leakage in/out)\n * - Injects provided CSS directly into the shadow root\n * - Uses React portals to render children into the shadow DOM\n * - Properly handles fixed-positioned children (like floating widgets)\n *\n * The shadow host uses position:fixed with inset:0 and pointer-events:none\n * to create a full-viewport container that doesn't interfere with the page.\n * Fixed-positioned children inside will position relative to the viewport.\n *\n * Why shadow DOM?\n * - Prevents host page CSS from affecting the agent widget\n * - Prevents agent CSS from affecting the host page\n * - Perfect for embeddable widgets on third-party sites\n *\n * @example\n * ```tsx\n * import { WEBMCP_SHADOW_STYLES } from './generated/inline-styles'\n *\n * <ShadowRoot styles={WEBMCP_SHADOW_STYLES}>\n * <AgentPill />\n * </ShadowRoot>\n * ```\n */\nexport const ShadowRoot: FC<ShadowRootProps> = ({ children, styles, className, mode = 'open' }) => {\n\tconst hostRef = useRef<HTMLDivElement>(null)\n\tconst [portalContainer, setPortalContainer] = useState<Element | null>(null)\n\n\tuseEffect(() => {\n\t\tconst host = hostRef.current\n\t\tif (!host) return\n\n\t\t// Check if shadow root already exists (strict mode / hot reload)\n\t\tlet shadow = host.shadowRoot\n\t\tif (!shadow) {\n\t\t\tshadow = host.attachShadow({ mode })\n\t\t}\n\n\t\t// Host styles ensure the shadow DOM container doesn't interfere with page layout\n\t\t// - position:fixed + inset:0 creates a viewport-sized container\n\t\t// - pointer-events:none allows clicks to pass through to the page\n\t\t// - z-index ensures it's above other content\n\t\t// Children with pointer-events:auto will still receive events\n\t\tconst hostStyles = `\n\t\t\t:host {\n\t\t\t\tposition: fixed !important;\n\t\t\t\tinset: 0 !important;\n\t\t\t\tpointer-events: none !important;\n\t\t\t\tz-index: 2147483647 !important;\n\t\t\t}\n\t\t\t[data-webmcp-container] {\n\t\t\t\tdisplay: contents !important;\n\t\t\t}\n\t\t`\n\n\t\t// Create or update the style element\n\t\tlet styleElement = shadow.querySelector('style[data-webmcp-styles]')\n\t\tif (!styleElement) {\n\t\t\tstyleElement = document.createElement('style')\n\t\t\tstyleElement.setAttribute('data-webmcp-styles', '')\n\t\t\tshadow.insertBefore(styleElement, shadow.firstChild)\n\t\t}\n\t\t// Prepend host styles to ensure proper layout\n\t\tstyleElement.textContent = hostStyles + styles\n\n\t\t// Create container for React content if it doesn't exist\n\t\tlet container = shadow.querySelector('[data-webmcp-container]')\n\t\tif (!container) {\n\t\t\tcontainer = document.createElement('div')\n\t\t\tcontainer.setAttribute('data-webmcp-container', '')\n\t\t\tshadow.appendChild(container)\n\t\t}\n\n\t\tsetPortalContainer(container)\n\t}, [mode, styles])\n\n\treturn (\n\t\t<div ref={hostRef} className={className}>\n\t\t\t{portalContainer && createPortal(children, portalContainer)}\n\t\t</div>\n\t)\n}\n\nexport default ShadowRoot\n","/**\n * AgentProvider\n *\n * Unified provider that wraps all agent infrastructure:\n * - AgentUIProvider (non-thread UI state: open/close, position)\n * - MCPToolsProvider (tool registry and execution)\n * - AssistantRuntimeProvider (chat runtime - single source of truth for thread)\n * - VoiceThreadBridge (voice mode integrated with thread)\n *\n * This is the single entry point for setting up agent capabilities.\n * Widgets (Pill, Modal) and custom UIs should be wrapped by this provider.\n *\n * Architecture:\n * ```\n * AgentUIProvider (UI state - persists across threads)\n * └── MCPToolsProvider (tools - shared across threads)\n * └── AssistantRuntimeProvider (thread state - single source of truth)\n * └── VoiceThreadBridge (voice → thread integration)\n * └── MCPToolRegistry\n * └── children\n * ```\n *\n * @example Basic usage\n * ```tsx\n * import { AgentProvider, AgentPill } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return (\n * <AgentProvider apiBase=\"https://your-worker.workers.dev\">\n * <AgentPill />\n * </AgentProvider>\n * )\n * }\n * ```\n *\n * @example Headless usage (custom UI)\n * ```tsx\n * import { AgentProvider, useAgent } from '@mcp-b/embedded-agent'\n *\n * function CustomUI() {\n * const agent = useAgent()\n * return <div>{agent.messages.map(m => ...)}</div>\n * }\n *\n * function App() {\n * return (\n * <AgentProvider apiBase=\"https://...\">\n * <CustomUI />\n * </AgentProvider>\n * )\n * }\n * ```\n */\n\nimport { AssistantRuntimeProvider } from '@assistant-ui/react'\nimport { AssistantChatTransport, useChatRuntime } from '@assistant-ui/react-ai-sdk'\nimport { lastAssistantMessageIsCompleteWithToolCalls } from 'ai'\nimport { useMemo } from 'react'\n\nimport { MCPToolRegistry } from '../../components/MCPToolRegistry'\nimport { WEBMCP_PRODUCTION_API_BASE } from '../../lib/constants'\nimport { MCPToolsProvider } from '../../providers/MCPToolsProvider'\nimport { ToolApprovalProvider } from '../../providers/ToolApprovalProvider'\nimport { VoiceThreadBridge } from '../../providers/VoiceThreadBridge'\nimport { AgentUIProvider } from './AgentUIProvider'\n\nimport type { ToolApprovalMode, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { FC, ReactNode } from 'react'\nimport type { PillMode } from './AgentUIProvider'\n\nexport interface AgentProviderProps {\n\tchildren: ReactNode\n\n\t/** API base URL for chat and token endpoints (defaults to production WebMCP API) */\n\tapiBase?: string\n\n\t/** Voice mode token endpoint (defaults to {apiBase}/api/realtime/session) */\n\ttokenEndpoint?: string\n\n\t/** Auto-connect to local MCP source (default: true) */\n\tautoConnectLocal?: boolean\n\n\t/** Initial open state for UI (default: false) */\n\tdefaultOpen?: boolean\n\n\t/** Initial pill mode (default: 'collapsed') */\n\tdefaultMode?: PillMode\n\n\t/** Initial tool approval mode: 'ask' requires confirmation, 'auto' executes immediately (default: 'ask') */\n\tdefaultApprovalMode?: ToolApprovalMode\n\n\t/** Callback when MCP tools change */\n\tonToolsChange?: (tools: ToolWithSource[]) => void\n\n\t/** Callback when voice mode errors */\n\tonVoiceError?: (error: string) => void\n\n\t/** Callback when voice mode connects */\n\tonVoiceConnect?: () => void\n\n\t/** Callback when voice mode disconnects */\n\tonVoiceDisconnect?: (duration: number) => void\n\n\t/** Callback when UI open state changes */\n\tonOpenChange?: (open: boolean) => void\n\n\t/** Callback when pill mode changes */\n\tonModeChange?: (mode: PillMode) => void\n\n\t/** Callback when tool approval mode changes */\n\tonApprovalModeChange?: (mode: ToolApprovalMode) => void\n}\n\n/**\n * Internal component that sets up the chat runtime and voice bridge.\n * Must be inside MCPToolsProvider so VoiceThreadBridge can access tools.\n */\ninterface AgentRuntimeProps {\n\tchildren: ReactNode\n\tapiBase?: string\n\ttokenEndpoint?: string\n\tonVoiceError?: (error: string) => void\n\tonVoiceConnect?: () => void\n\tonVoiceDisconnect?: (duration: number) => void\n}\n\nconst AgentRuntime: FC<AgentRuntimeProps> = ({\n\tchildren,\n\tapiBase,\n\ttokenEndpoint,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\t// Resolve API base (defaults to production)\n\tconst resolvedApiBase = apiBase ?? WEBMCP_PRODUCTION_API_BASE\n\n\t// Create transport with API endpoint\n\tconst transport = useMemo(() => {\n\t\tconst chatApi = `${resolvedApiBase}/api/chat`\n\t\treturn new AssistantChatTransport({ api: chatApi })\n\t}, [resolvedApiBase])\n\n\tconst runtime = useChatRuntime({\n\t\ttransport,\n\t\tsendAutomaticallyWhen: (messages) => {\n\t\t\treturn lastAssistantMessageIsCompleteWithToolCalls(messages)\n\t\t},\n\t})\n\n\t// Compute token endpoint from apiBase if not explicitly provided\n\tconst resolvedTokenEndpoint = tokenEndpoint || `${resolvedApiBase}/api/realtime/session`\n\n\treturn (\n\t\t<AssistantRuntimeProvider runtime={runtime}>\n\t\t\t<VoiceThreadBridge\n\t\t\t\ttokenEndpoint={resolvedTokenEndpoint}\n\t\t\t\tonError={onVoiceError}\n\t\t\t\tonConnect={onVoiceConnect}\n\t\t\t\tonDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t<MCPToolRegistry />\n\t\t\t\t{children}\n\t\t\t</VoiceThreadBridge>\n\t\t</AssistantRuntimeProvider>\n\t)\n}\n\n/**\n * Unified provider for all agent capabilities.\n *\n * Provides:\n * - UI state (open/close, position) via AgentUIProvider\n * - MCP tool registry and execution via MCPToolsProvider\n * - Tool approval settings via ToolApprovalProvider\n * - Chat runtime (via @assistant-ui/react) - single source of truth for thread\n * - Voice mode integrated with thread (via VoiceThreadBridge)\n *\n * Use the `useAgent` hook to access agent state and capabilities.\n * Use the `useAgentUI` hook to access UI state (open/close, mode, position).\n * Use the `useToolApproval` hook to access tool approval settings.\n */\nexport const AgentProvider: FC<AgentProviderProps> = ({\n\tchildren,\n\tapiBase,\n\ttokenEndpoint,\n\tautoConnectLocal = true,\n\tdefaultOpen = false,\n\tdefaultMode = 'collapsed',\n\tdefaultApprovalMode,\n\tonToolsChange,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n\tonOpenChange,\n\tonModeChange,\n\tonApprovalModeChange,\n}) => {\n\treturn (\n\t\t<AgentUIProvider\n\t\t\tdefaultOpen={defaultOpen}\n\t\t\tdefaultMode={defaultMode}\n\t\t\tonOpenChange={onOpenChange}\n\t\t\tonModeChange={onModeChange}\n\t\t>\n\t\t\t<ToolApprovalProvider defaultMode={defaultApprovalMode} onModeChange={onApprovalModeChange}>\n\t\t\t\t<MCPToolsProvider autoConnectLocal={autoConnectLocal} onToolsChange={onToolsChange}>\n\t\t\t\t\t<AgentRuntime\n\t\t\t\t\t\tapiBase={apiBase}\n\t\t\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\t\t\tonVoiceError={onVoiceError}\n\t\t\t\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\t\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</AgentRuntime>\n\t\t\t\t</MCPToolsProvider>\n\t\t\t</ToolApprovalProvider>\n\t\t</AgentUIProvider>\n\t)\n}\n","/**\n * Auto-generated file - DO NOT EDIT\n * Generated by scripts/generate-inline-styles.js\n *\n * Contains the compiled CSS for the web component standalone build.\n */\n\n/**\n * Full CSS styles for global injection.\n * Use this when NOT using shadow DOM isolation.\n * @deprecated Prefer using WEBMCP_SHADOW_STYLES with the ShadowRoot component for style isolation.\n */\nexport const WEBMCP_STYLES = \"/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */\\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-600:oklch(55.8% .288 302.321);--color-slate-900:oklch(20.8% .042 265.755);--color-zinc-50:oklch(98.5% 0 0);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-xs:.125rem;--ease-out:cubic-bezier(0,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:host,:root{--radius:.75rem;--background:oklch(100% 0 0);--foreground:oklch(14.1% .005 285.823);--card:oklch(100% 0 0);--card-foreground:oklch(14.1% .005 285.823);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.1% .005 285.823);--primary:oklch(21% .006 285.885);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.7% .001 286.375);--secondary-foreground:oklch(21% .006 285.885);--muted:oklch(96.7% .001 286.375);--muted-foreground:oklch(55.2% .016 285.938);--accent:oklch(96.7% .001 286.375);--accent-foreground:oklch(21% .006 285.885);--destructive:oklch(57.7% .245 27.325);--destructive-foreground:oklch(98.5% 0 0);--border:oklch(92% .004 286.32);--input:oklch(92% .004 286.32);--ring:oklch(70.5% .015 286.067)}:host(.dark),.dark{--background:oklch(14.1% .005 285.823);--foreground:oklch(98.5% 0 0);--card:oklch(21% .006 285.885);--card-foreground:oklch(98.5% 0 0);--popover:oklch(21% .006 285.885);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92% .004 286.32);--primary-foreground:oklch(21% .006 285.885);--secondary:oklch(27.4% .006 286.033);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(27.4% .006 286.033);--muted-foreground:oklch(70.5% .015 286.067);--accent:oklch(27.4% .006 286.033);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--destructive-foreground:oklch(98.5% 0 0);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.2% .016 285.938)}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklch,var(--ring),transparent 50%)}}body{background-color:var(--background);color:var(--foreground)}}@layer components{.app-shell{z-index:0;background-color:var(--background);background-image:radial-gradient(80% 60% at -10% -10%,oklch(82% .15 270/.15),#0000),radial-gradient(60% 50% at 110% 10%,oklch(85% .1 220/.12),#0000),radial-gradient(50% 45% at 50% 120%,oklch(95% .02 250/.08),#0000);position:relative}.dark .app-shell{background-image:radial-gradient(80% 60% at -10% -10%,oklch(55% .14 270/.25),#0000),radial-gradient(60% 50% at 110% 15%,oklch(60% .12 220/.22),#0000),radial-gradient(50% 45% at 50% 120%,oklch(35% .04 250/.16),#0000)}.app-shell:before,.app-shell:after{content:\\\"\\\";pointer-events:none;filter:blur(32px);opacity:.6;z-index:-1;border-radius:9999px;position:absolute;inset:auto}.app-shell:before{background:radial-gradient(60% 60% at 40% 40%,oklch(80% .12 270/.3),#0000);width:260px;height:260px;top:-60px;left:-80px}.app-shell:after{background:radial-gradient(60% 60% at 60% 60%,oklch(84% .1 220/.25),#0000);width:300px;height:300px;bottom:-80px;right:-60px}.toolbar-surface{border-top:1px solid var(--border);background:linear-gradient(to right,var(--background),var(--background),var(--background))}@supports (color:color-mix(in lab, red, red)){.toolbar-surface{background:linear-gradient(to right,var(--background),color-mix(in oklch,var(--background),transparent 5%),var(--background))}}.toolbar-surface{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.toolbar-surface{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.toolbar-surface{background:color-mix(in oklch,var(--background),transparent 20%)}}}.toolbar-surface-top{border-bottom:1px solid var(--border);background:linear-gradient(to right,var(--background),var(--background),var(--background))}@supports (color:color-mix(in lab, red, red)){.toolbar-surface-top{background:linear-gradient(to right,var(--background),color-mix(in oklch,var(--background),transparent 5%),var(--background))}}.toolbar-surface-top{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.toolbar-surface-top{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.toolbar-surface-top{background:color-mix(in oklch,var(--background),transparent 20%)}}}.toolbar-inner{justify-content:space-between;align-items:center;padding:.5rem .75rem;display:flex}.toolbar-card{background:var(--card);justify-content:space-between;align-items:center;gap:.5rem;display:flex}@supports (color:color-mix(in lab, red, red)){.toolbar-card{background:color-mix(in oklch,var(--card),transparent 60%)}}.toolbar-card{border:1px solid var(--border);border-radius:.75rem;padding:.5rem .75rem}.toolbar-group{align-items:center;gap:.25rem;display:flex}.btn-toolbar-primary{background:linear-gradient(to right,var(--primary),var(--primary));border-radius:.75rem;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;display:flex}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary{background:linear-gradient(to right,color-mix(in oklch,var(--primary),transparent 95%),color-mix(in oklch,var(--primary),transparent 90%))}}.btn-toolbar-primary{border:1px solid var(--primary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary{border:1px solid color-mix(in oklch,var(--primary),transparent 80%)}}.btn-toolbar-primary{transition:all .2s}.btn-toolbar-primary:hover{background:linear-gradient(to right,var(--primary),var(--primary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary:hover{background:linear-gradient(to right,color-mix(in oklch,var(--primary),transparent 90%),color-mix(in oklch,var(--primary),transparent 80%))}}.btn-toolbar-icon-primary{background:linear-gradient(to bottom right,var(--primary),var(--primary));border-radius:9999px;width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--primary),transparent 90%),color-mix(in oklch,var(--primary),transparent 80%))}}.btn-toolbar-icon-primary{border:1px solid var(--primary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary{border:1px solid color-mix(in oklch,var(--primary),transparent 70%)}}.btn-toolbar-icon-primary{transition:all .2s;box-shadow:0 1px 2px #0000000d}.btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,var(--primary),var(--primary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--primary),transparent 80%),color-mix(in oklch,var(--primary),transparent 70%))}}.btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,var(--secondary),var(--secondary));border-radius:9999px;width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--secondary),transparent 90%),color-mix(in oklch,var(--secondary),transparent 80%))}}.btn-toolbar-icon-secondary{border:1px solid var(--secondary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary{border:1px solid color-mix(in oklch,var(--secondary),transparent 70%)}}.btn-toolbar-icon-secondary{transition:all .2s;box-shadow:0 1px 2px #0000000d}.btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,var(--secondary),var(--secondary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--secondary),transparent 80%),color-mix(in oklch,var(--secondary),transparent 70%))}}.badge-compact{height:1.25rem;padding:0 .5rem;font-size:10px}.badge-mini{height:1rem;padding:0 .375rem;font-size:10px}@keyframes shimmer-bg{0%{background-position:-1000px 0}to{background-position:1000px 0}}.shimmer{background:linear-gradient(90deg,#0000,#ffffff1a,#0000) 0 0/1000px 100%;animation:3s linear infinite shimmer-bg}.animate-shimmer{animation:2s linear infinite shimmer}@keyframes pulse-glow{0%,to{box-shadow:0 0 20px rgba(var(--primary),.1)}50%{box-shadow:0 0 30px rgba(var(--primary),.2)}}.pulse-glow{animation:2s ease-in-out infinite pulse-glow}@keyframes gradient-x{0%,to{background-position:0%}50%{background-position:100%}}.animate-gradient-x{animation:8s ease-in-out infinite gradient-x}.gradient-text{background:linear-gradient(to right,var(--foreground),var(--foreground))}@supports (color:color-mix(in lab, red, red)){.gradient-text{background:linear-gradient(to right,var(--foreground),color-mix(in oklch,var(--foreground),transparent 30%))}}.gradient-text{-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text}.glass{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.glass{background:color-mix(in oklch,var(--background),transparent 50%)}}.glass{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--border)}@supports (color:color-mix(in lab, red, red)){.glass{border:1px solid color-mix(in oklch,var(--border),transparent 50%)}}.tool-card{transition:all .3s ease-out}.tool-card:hover{transform:scale(1.02);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}.scrollbar-thin{scrollbar-width:thin}.scrollbar-thin::-webkit-scrollbar{width:6px;height:6px}.scrollbar-thin::-webkit-scrollbar-track{background:0 0}.scrollbar-thin::-webkit-scrollbar-thumb{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.scrollbar-thin::-webkit-scrollbar-thumb{background-color:color-mix(in oklch,var(--primary),transparent 80%)}}.scrollbar-thin::-webkit-scrollbar-thumb{border-radius:3px}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:color-mix(in oklch,var(--primary),transparent 70%)}}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.-inset-\\\\[1px\\\\]{inset:-1px}.inset-0{inset:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\\\\.5{top:calc(var(--spacing)*-1.5)}.top-1\\\\.5{top:calc(var(--spacing)*1.5)}.top-1\\\\/2{top:50%}.top-4{top:calc(var(--spacing)*4)}.top-\\\\[50\\\\%\\\\]{top:50%}.-right-0\\\\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\\\\.5{right:calc(var(--spacing)*-1.5)}.right-0{right:calc(var(--spacing)*0)}.right-1\\\\.5{right:calc(var(--spacing)*1.5)}.right-4{right:calc(var(--spacing)*4)}.-bottom-0\\\\.5{bottom:calc(var(--spacing)*-.5)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing)*0)}.left-1\\\\/2,.left-\\\\[50\\\\%\\\\]{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-full{grid-column:1/-1}.col-start-1{grid-column-start:1}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-m-1{margin:calc(var(--spacing)*-1)}.m-0{margin:calc(var(--spacing)*0)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.-mt-1{margin-top:calc(var(--spacing)*-1)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1\\\\.5{margin-right:calc(var(--spacing)*1.5)}.-mb-1{margin-bottom:calc(var(--spacing)*-1)}.mb-0\\\\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.ml-0\\\\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-2\\\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-14{width:calc(var(--spacing)*14);height:calc(var(--spacing)*14)}.size-\\\\[34px\\\\]{width:34px;height:34px}.size-full{width:100%;height:100%}.h-1\\\\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\\\\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\\\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\\\\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-auto{height:auto}.h-full{height:100%}.max-h-24{max-height:calc(var(--spacing)*24)}.max-h-32{max-height:calc(var(--spacing)*32)}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-\\\\[30vh\\\\]{max-height:30vh}.max-h-\\\\[80dvh\\\\]{max-height:80dvh}.max-h-\\\\[80vh\\\\]{max-height:80vh}.min-h-7{min-height:calc(var(--spacing)*7)}.min-h-11{min-height:calc(var(--spacing)*11)}.min-h-screen{min-height:100vh}.w-0\\\\.5{width:calc(var(--spacing)*.5)}.w-1\\\\.5{width:calc(var(--spacing)*1.5)}.w-2{width:calc(var(--spacing)*2)}.w-2\\\\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\\\\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\\\\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-11{width:calc(var(--spacing)*11)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-24{max-width:calc(var(--spacing)*24)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\\\\[100px\\\\]{max-width:100px}.max-w-\\\\[calc\\\\(100\\\\%-2rem\\\\)\\\\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-7{min-width:calc(var(--spacing)*7)}.min-w-11{min-width:calc(var(--spacing)*11)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.border-separate{border-collapse:separate}.border-spacing-0{--tw-border-spacing-x:calc(var(--spacing)*0);--tw-border-spacing-y:calc(var(--spacing)*0);border-spacing:var(--tw-border-spacing-x)var(--tw-border-spacing-y)}.origin-\\\\(--radix-tooltip-content-transform-origin\\\\){transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\\\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\\\\[-50\\\\%\\\\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\\\\[-50\\\\%\\\\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\\\\[calc\\\\(-50\\\\%_-_2px\\\\)\\\\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-75{--tw-scale-x:75%;--tw-scale-y:75%;--tw-scale-z:75%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.rotate-45{rotate:45deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.scroll-m-20{scroll-margin:calc(var(--spacing)*20)}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-rows-\\\\[0fr\\\\]{grid-template-rows:0fr}.grid-rows-\\\\[1fr\\\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\\\\[2px\\\\]{border-radius:2px}.rounded-\\\\[14px\\\\]{border-radius:14px}.rounded-\\\\[inherit\\\\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-xs{border-radius:var(--radius-xs)}.\\\\!rounded-t-none{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.rounded-b-lg{border-bottom-right-radius:var(--radius);border-bottom-left-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-amber-500\\\\/30{border-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.border-amber-500\\\\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-amber-500\\\\/50{border-color:#f99c0080}@supports (color:color-mix(in lab, red, red)){.border-amber-500\\\\/50{border-color:color-mix(in oklab,var(--color-amber-500)50%,transparent)}}.border-blue-500\\\\/20{border-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.border-blue-500\\\\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\\\\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\\\\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-border{border-color:var(--border)}.border-foreground\\\\/20{border-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.border-foreground\\\\/20{border-color:color-mix(in oklab,var(--foreground)20%,transparent)}}.border-input{border-color:var(--input)}.border-muted-foreground\\\\/20{border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\\\\/20{border-color:color-mix(in oklab,var(--muted-foreground)20%,transparent)}}.border-transparent{border-color:#0000}.border-white\\\\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/5{border-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.border-white\\\\/8{border-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/8{border-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.border-white\\\\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\\\\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-zinc-200{border-color:var(--color-zinc-200)}.border-zinc-200\\\\/80{border-color:#e4e4e7cc}@supports (color:color-mix(in lab, red, red)){.border-zinc-200\\\\/80{border-color:color-mix(in oklab,var(--color-zinc-200)80%,transparent)}}.border-zinc-600{border-color:var(--color-zinc-600)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\\\\/10{background-color:#f99c001a}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\\\\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\\\\/20{background-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\\\\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-background{background-color:var(--background)}.bg-black{background-color:var(--color-black)}.bg-black\\\\/30{background-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.bg-black\\\\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\\\\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\\\\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\\\\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\\\\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-border{background-color:var(--border)}.bg-destructive{background-color:var(--destructive)}.bg-foreground{background-color:var(--foreground)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-400\\\\/60{background-color:#05df7299}@supports (color:color-mix(in lab, red, red)){.bg-green-400\\\\/60{background-color:color-mix(in oklab,var(--color-green-400)60%,transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\\\\/10{background-color:#00c7581a}@supports (color:color-mix(in lab, red, red)){.bg-green-500\\\\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-muted{background-color:var(--muted)}.bg-muted-foreground\\\\/15{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\\\/15{background-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.bg-muted\\\\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\\\\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.bg-primary{background-color:var(--primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\\\\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\\\\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\\\\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.bg-red-500\\\\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\\\\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/5{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.bg-white\\\\/8{background-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/8{background-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.bg-white\\\\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-white\\\\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/20{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.bg-white\\\\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/60{background-color:color-mix(in oklab,var(--color-white)60%,transparent)}}.bg-white\\\\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-zinc-100{background-color:var(--color-zinc-100)}.bg-zinc-700\\\\/50{background-color:#3f3f4680}@supports (color:color-mix(in lab, red, red)){.bg-zinc-700\\\\/50{background-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-indigo-500{--tw-gradient-from:var(--color-indigo-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-600{--tw-gradient-to:var(--color-purple-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.fill-foreground{fill:var(--foreground)}.stroke-\\\\[1\\\\.5px\\\\]{stroke-width:1.5px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-px{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\\\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-0\\\\.5{padding-top:calc(var(--spacing)*.5)}.pt-1\\\\.5{padding-top:calc(var(--spacing)*1.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\\\[10px\\\\]{font-size:10px}.text-\\\\[11px\\\\]{font-size:11px}.text-\\\\[13px\\\\]{font-size:13px}.text-\\\\[15px\\\\]{font-size:15px}.text-\\\\[17px\\\\]{font-size:17px}.text-\\\\[19px\\\\]{font-size:19px}.text-\\\\[21px\\\\]{font-size:21px}.text-\\\\[25px\\\\]{font-size:25px}.leading-\\\\[21px\\\\]{--tw-leading:21px;line-height:21px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-background{color:var(--background)}.text-blue-400{color:var(--color-blue-400)}.text-blue-400\\\\/60{color:#54a2ff99}@supports (color:color-mix(in lab, red, red)){.text-blue-400\\\\/60{color:color-mix(in oklab,var(--color-blue-400)60%,transparent)}}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground{color:var(--foreground)}.text-green-400{color:var(--color-green-400)}.text-green-600{color:var(--color-green-600)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.text-white\\\\/30{color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/30{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.text-white\\\\/40{color:#fff6}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-white\\\\/50{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/50{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.text-white\\\\/60{color:#fff9}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\\\\/70{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/70{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.text-white\\\\/80{color:#fffc}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\\\\/90{color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-700{color:var(--color-zinc-700)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-black\\\\/10{--tw-shadow-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.shadow-black\\\\/10{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-black)10%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\\\[color\\\\,box-shadow\\\\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\\\[grid-template-rows\\\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.will-change-transform{will-change:transform}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\\\\:scale-100:is(:where(.group):hover *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\\\\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\\\\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.placeholder\\\\:text-white\\\\/40::placeholder{color:#fff6}@supports (color:color-mix(in lab, red, red)){.placeholder\\\\:text-white\\\\/40::placeholder{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.first\\\\:mt-0:first-child{margin-top:calc(var(--spacing)*0)}.first\\\\:rounded-tl-lg:first-child{border-top-left-radius:var(--radius)}.first\\\\:border-t:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.last\\\\:mb-0:last-child{margin-bottom:calc(var(--spacing)*0)}.last\\\\:rounded-tr-lg:last-child{border-top-right-radius:var(--radius)}.last\\\\:border-r:last-child{border-right-style:var(--tw-border-style);border-right-width:1px}.empty\\\\:hidden:empty{display:none}.focus-within\\\\:border-white\\\\/15:focus-within{border-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.focus-within\\\\:border-white\\\\/15:focus-within{border-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.focus-within\\\\:bg-white\\\\/10:focus-within{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.focus-within\\\\:bg-white\\\\/10:focus-within{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}@media (hover:hover){.hover\\\\:border-amber-500:hover{border-color:var(--color-amber-500)}.hover\\\\:border-red-500\\\\/50:hover{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.hover\\\\:border-red-500\\\\/50:hover{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.hover\\\\:border-white\\\\/20:hover{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:border-white\\\\/20:hover{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\\\\:\\\\!bg-white:hover{background-color:var(--color-white)!important}.hover\\\\:bg-accent:hover,.hover\\\\:bg-accent\\\\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-accent\\\\/50:hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.hover\\\\:bg-amber-500\\\\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-amber-500\\\\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.hover\\\\:bg-amber-500\\\\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-amber-500\\\\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\\\\:bg-destructive\\\\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/10:hover{background-color:color-mix(in oklab,var(--destructive)10%,transparent)}}.hover\\\\:bg-destructive\\\\/80:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}}.hover\\\\:bg-destructive\\\\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}}.hover\\\\:bg-muted-foreground\\\\/15:hover{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-muted-foreground\\\\/15:hover{background-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.hover\\\\:bg-primary\\\\/80:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-primary\\\\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}}.hover\\\\:bg-primary\\\\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-primary\\\\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}}.hover\\\\:bg-red-500\\\\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-red-500\\\\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\\\\:bg-red-500\\\\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-red-500\\\\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\\\\:bg-secondary\\\\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-secondary\\\\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}}.hover\\\\:bg-white:hover{background-color:var(--color-white)}.hover\\\\:bg-white\\\\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\\\\:bg-white\\\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\\\:bg-white\\\\/15:hover{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/15:hover{background-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.hover\\\\:bg-white\\\\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\\\\:bg-white\\\\/30:hover{background-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/30:hover{background-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.hover\\\\:bg-white\\\\/95:hover{background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/95:hover{background-color:color-mix(in oklab,var(--color-white)95%,transparent)}}.hover\\\\:bg-zinc-50:hover{background-color:var(--color-zinc-50)}.hover\\\\:bg-zinc-200:hover{background-color:var(--color-zinc-200)}.hover\\\\:bg-zinc-700:hover{background-color:var(--color-zinc-700)}.hover\\\\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\\\\:text-destructive:hover{color:var(--destructive)}.hover\\\\:text-foreground:hover{color:var(--foreground)}.hover\\\\:text-primary\\\\/80:hover{color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-primary\\\\/80:hover{color:color-mix(in oklab,var(--primary)80%,transparent)}}.hover\\\\:text-red-200:hover{color:var(--color-red-200)}.hover\\\\:text-red-300:hover{color:var(--color-red-300)}.hover\\\\:text-red-400:hover{color:var(--color-red-400)}.hover\\\\:text-white:hover{color:var(--color-white)}.hover\\\\:text-white\\\\/50:hover{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/50:hover{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.hover\\\\:text-white\\\\/60:hover{color:#fff9}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/60:hover{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.hover\\\\:text-white\\\\/70:hover{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/70:hover{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.hover\\\\:text-white\\\\/80:hover{color:#fffc}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\\\\:text-zinc-600:hover{color:var(--color-zinc-600)}.hover\\\\:underline:hover{text-decoration-line:underline}.hover\\\\:opacity-75:hover{opacity:.75}.hover\\\\:opacity-100:hover{opacity:1}}.focus\\\\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\\\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\\\\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\\\\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\\\\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus\\\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\\\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\\\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-\\\\[3px\\\\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-blue-500:focus-visible{--tw-ring-color:var(--color-blue-500)}.focus-visible\\\\:ring-destructive\\\\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-destructive\\\\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.focus-visible\\\\:ring-ring:focus-visible,.focus-visible\\\\:ring-ring\\\\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-ring\\\\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.focus-visible\\\\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\\\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\\\\:ring-offset-transparent:focus-visible{--tw-ring-offset-color:transparent}.focus-visible\\\\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\\\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\\\\:scale-\\\\[0\\\\.98\\\\]:active{scale:.98}.active\\\\:cursor-grabbing:active{cursor:grabbing}.active\\\\:bg-white\\\\/15:active{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.active\\\\:bg-white\\\\/15:active{background-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.active\\\\:bg-white\\\\/20:active{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.active\\\\:bg-white\\\\/20:active{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.disabled\\\\:pointer-events-none:disabled{pointer-events:none}.disabled\\\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\\\:opacity-40:disabled{opacity:.4}.disabled\\\\:opacity-50:disabled{opacity:.5}.has-\\\\[\\\\>svg\\\\]\\\\:px-2\\\\.5:has(>svg){padding-inline:calc(var(--spacing)*2.5)}.has-\\\\[\\\\>svg\\\\]\\\\:px-3:has(>svg){padding-inline:calc(var(--spacing)*3)}.has-\\\\[\\\\>svg\\\\]\\\\:px-4:has(>svg){padding-inline:calc(var(--spacing)*4)}.aria-invalid\\\\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\\\\:ring-destructive\\\\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\\\\:ring-destructive\\\\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.data-\\\\[orientation\\\\=horizontal\\\\]\\\\:h-px[data-orientation=horizontal]{height:1px}.data-\\\\[orientation\\\\=horizontal\\\\]\\\\:w-full[data-orientation=horizontal]{width:100%}.data-\\\\[orientation\\\\=vertical\\\\]\\\\:h-full[data-orientation=vertical]{height:100%}.data-\\\\[orientation\\\\=vertical\\\\]\\\\:w-px[data-orientation=vertical]{width:1px}.data-\\\\[state\\\\=open\\\\]\\\\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\\\\[state\\\\=open\\\\]\\\\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}@media (min-width:40rem){.sm\\\\:flex{display:flex}.sm\\\\:h-3{height:calc(var(--spacing)*3)}.sm\\\\:h-3\\\\.5{height:calc(var(--spacing)*3.5)}.sm\\\\:h-4{height:calc(var(--spacing)*4)}.sm\\\\:h-7{height:calc(var(--spacing)*7)}.sm\\\\:max-h-24{max-height:calc(var(--spacing)*24)}.sm\\\\:max-h-32{max-height:calc(var(--spacing)*32)}.sm\\\\:max-h-48{max-height:calc(var(--spacing)*48)}.sm\\\\:min-h-7{min-height:calc(var(--spacing)*7)}.sm\\\\:w-3{width:calc(var(--spacing)*3)}.sm\\\\:w-3\\\\.5{width:calc(var(--spacing)*3.5)}.sm\\\\:w-4{width:calc(var(--spacing)*4)}.sm\\\\:w-7{width:calc(var(--spacing)*7)}.sm\\\\:max-w-3xl{max-width:var(--container-3xl)}.sm\\\\:max-w-16{max-width:calc(var(--spacing)*16)}.sm\\\\:max-w-24{max-width:calc(var(--spacing)*24)}.sm\\\\:max-w-lg{max-width:var(--container-lg)}.sm\\\\:max-w-md{max-width:var(--container-md)}.sm\\\\:min-w-7{min-width:calc(var(--spacing)*7)}.sm\\\\:flex-row{flex-direction:row}.sm\\\\:justify-end{justify-content:flex-end}.sm\\\\:gap-1{gap:calc(var(--spacing)*1)}.sm\\\\:gap-1\\\\.5{gap:calc(var(--spacing)*1.5)}.sm\\\\:p-1{padding:calc(var(--spacing)*1)}.sm\\\\:p-1\\\\.5{padding:calc(var(--spacing)*1.5)}.sm\\\\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\\\\:py-1{padding-block:calc(var(--spacing)*1)}.sm\\\\:text-left{text-align:left}.sm\\\\:opacity-0{opacity:0}@media (hover:hover){.sm\\\\:group-hover\\\\:opacity-100:is(:where(.group):hover *){opacity:1}}}.dark\\\\:border-input:is(.dark *){border-color:var(--input)}.dark\\\\:border-muted-foreground\\\\/15:is(.dark *){border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:border-muted-foreground\\\\/15:is(.dark *){border-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.dark\\\\:border-zinc-600:is(.dark *){border-color:var(--color-zinc-600)}.dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:#3f3f46cc}@supports (color:color-mix(in lab, red, red)){.dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:color-mix(in oklab,var(--color-zinc-700)80%,transparent)}}.dark\\\\:bg-destructive\\\\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-destructive\\\\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive)60%,transparent)}}.dark\\\\:bg-input\\\\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-input\\\\/30:is(.dark *){background-color:color-mix(in oklab,var(--input)30%,transparent)}}.dark\\\\:bg-muted-foreground\\\\/20:is(.dark *){background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-muted-foreground\\\\/20:is(.dark *){background-color:color-mix(in oklab,var(--muted-foreground)20%,transparent)}}.dark\\\\:bg-zinc-700:is(.dark *){background-color:var(--color-zinc-700)}.dark\\\\:bg-zinc-800:is(.dark *){background-color:var(--color-zinc-800)}.dark\\\\:stroke-\\\\[2\\\\.5px\\\\]:is(.dark *){stroke-width:2.5px}.dark\\\\:text-green-400:is(.dark *){color:var(--color-green-400)}.dark\\\\:text-zinc-200:is(.dark *){color:var(--color-zinc-200)}.dark\\\\:text-zinc-400:is(.dark *){color:var(--color-zinc-400)}.dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-black)30%,transparent)var(--tw-shadow-alpha),transparent)}}@media (hover:hover){.dark\\\\:hover\\\\:bg-accent\\\\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-accent\\\\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.dark\\\\:hover\\\\:bg-input\\\\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-input\\\\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input)50%,transparent)}}.dark\\\\:hover\\\\:bg-muted-foreground\\\\/30:is(.dark *):hover{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-muted-foreground\\\\/30:is(.dark *):hover{background-color:color-mix(in oklab,var(--muted-foreground)30%,transparent)}}.dark\\\\:hover\\\\:bg-zinc-600:is(.dark *):hover{background-color:var(--color-zinc-600)}.dark\\\\:hover\\\\:bg-zinc-700:is(.dark *):hover{background-color:var(--color-zinc-700)}.dark\\\\:hover\\\\:text-zinc-200:is(.dark *):hover{color:var(--color-zinc-200)}}.dark\\\\:focus-visible\\\\:ring-destructive\\\\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:focus-visible\\\\:ring-destructive\\\\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\\\\:aria-invalid\\\\:ring-destructive\\\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:aria-invalid\\\\:ring-destructive\\\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.\\\\[\\\\&_svg\\\\]\\\\:pointer-events-none svg{pointer-events:none}.\\\\[\\\\&_svg\\\\]\\\\:shrink-0 svg{flex-shrink:0}.\\\\[\\\\&_svg\\\\]\\\\:text-background svg{color:var(--background)}.\\\\[\\\\&_svg\\\\]\\\\:text-black svg{color:var(--color-black)}@media (hover:hover){.hover\\\\:\\\\[\\\\&_svg\\\\]\\\\:text-destructive:hover svg{color:var(--destructive)}}.\\\\[\\\\&_svg\\\\:not\\\\(\\\\[class\\\\*\\\\=\\\\'size-\\\\'\\\\]\\\\)\\\\]\\\\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\\\[\\\\&\\\\:last-child\\\\>td\\\\:first-child\\\\]\\\\:rounded-bl-lg:last-child>td:first-child{border-bottom-left-radius:var(--radius)}.\\\\[\\\\&\\\\:last-child\\\\>td\\\\:last-child\\\\]\\\\:rounded-br-lg:last-child>td:last-child{border-bottom-right-radius:var(--radius)}.only\\\\:\\\\[\\\\&\\\\>\\\\#attachment-tile\\\\]\\\\:size-24:only-child>#attachment-tile{width:calc(var(--spacing)*24);height:calc(var(--spacing)*24)}.\\\\[\\\\&\\\\>a\\\\]\\\\:text-xs>a{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\\\\[\\\\&\\\\>a\\\\]\\\\:no-underline>a{text-decoration-line:none}.\\\\[\\\\&\\\\>button\\\\]\\\\:rounded-full>button{border-radius:3.40282e38px}.\\\\[\\\\&\\\\>button\\\\]\\\\:bg-foreground\\\\/60>button{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.\\\\[\\\\&\\\\>button\\\\]\\\\:bg-foreground\\\\/60>button{background-color:color-mix(in oklab,var(--foreground)60%,transparent)}}.\\\\[\\\\&\\\\>button\\\\]\\\\:p-1>button{padding:calc(var(--spacing)*1)}.\\\\[\\\\&\\\\>button\\\\]\\\\:opacity-100>button{opacity:1}.\\\\[\\\\&\\\\>button\\\\]\\\\:\\\\!ring-0>button{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}@media (hover:hover){.\\\\[\\\\&\\\\>button\\\\]\\\\:hover\\\\:\\\\[\\\\&_svg\\\\]\\\\:text-destructive>button:hover svg{color:var(--destructive)}}.\\\\[\\\\&\\\\>li\\\\]\\\\:mt-0\\\\.5>li{margin-top:calc(var(--spacing)*.5)}.\\\\[\\\\&\\\\>li\\\\]\\\\:mt-1>li{margin-top:calc(var(--spacing)*1)}.\\\\[\\\\&\\\\>span\\\\]\\\\:text-xs>span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\\\\[\\\\&\\\\[align\\\\=center\\\\]\\\\]\\\\:text-center[align=center]{text-align:center}.\\\\[\\\\&\\\\[align\\\\=right\\\\]\\\\]\\\\:text-right[align=right]{text-align:right}}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(200%)}}@keyframes subtle-pulse{0%,to{opacity:1}50%{opacity:.85}}@keyframes smooth-slide-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes gradient-shift{0%,to{transform:translate(0%)translateY(0%)}25%{transform:translate(100%)translateY(100%)}50%{transform:translate(100%)translateY(0%)}75%{transform:translate(0%)translateY(100%)}}@keyframes float{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(-30px)translate(20px)}66%{transform:translateY(20px)translate(-20px)}}@keyframes float-delayed{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(30px)translate(-30px)}66%{transform:translateY(-20px)translate(20px)}}.tool-card-transition{transition:all .4s cubic-bezier(.34,1.56,.64,1)}.tool-card-smooth{transition:all .35s cubic-bezier(.4,0,.2,1)}.animate-fadeInUp{opacity:0;animation:.5s ease-out forwards fadeInUp}.animate-gradient-shift{background-size:200% 200%;animation:20s ease-in-out infinite gradient-shift}.animate-float-slow{animation:20s ease-in-out infinite float}.animate-float-delayed{animation:25s ease-in-out 5s infinite float-delayed}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@keyframes tool-border-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@supports (background:paint(something)){@property --tool-border-angle{syntax: \\\"<angle>\\\"; initial-value: 0deg; inherits: false;}}.tool-border-calling{position:relative;overflow:hidden}.tool-border-calling:before{content:\\\"\\\";background:conic-gradient(#0000 0deg 60deg,#3b82f680 90deg,#60a5fab3 120deg,#93c5fd80 150deg,#0000 180deg 360deg);animation:1.5s linear infinite tool-border-rotate;position:absolute;inset:-50%}.tool-border-success{background:#22c55e66;box-shadow:0 0 12px #22c55e4d,inset 0 0 8px #22c55e1a}.tool-border-error{background:#ef444466;box-shadow:0 0 12px #ef44444d,inset 0 0 8px #ef44441a}@keyframes pulse-success{0%,to{box-shadow:0 0 #22c55e66}50%{box-shadow:0 0 0 8px #22c55e00}}@keyframes shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.animate-pulse-success{animation:.6s ease-out pulse-success}.animate-shake{animation:.3s ease-out shake}@keyframes aui-pulse{50%{opacity:.5}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;animation:2s cubic-bezier(.4,0,.6,1) infinite aui-pulse}.glass-pill{-webkit-backdrop-filter:blur(20px)saturate(150%);background:#0f172ad9;border:1px solid #ffffff0f;box-shadow:0 4px 16px #0003,inset 0 .5px #ffffff14}.glass-pill:before{content:\\\"\\\";border-radius:inherit;pointer-events:none;z-index:1;background:linear-gradient(#ffffff0a 0%,#0000 40%);position:absolute;inset:0}.glass-pill:after{display:none}.glass-pill-collapsed{-webkit-backdrop-filter:blur(20px)saturate(150%);background:#0f172ad9;border:1px solid #ffffff0f;box-shadow:0 2px 8px #0003,inset 0 .5px #ffffff14}.glass-pill-collapsed:before,.glass-pill-collapsed:after{display:none}.glass-pill-hovered{-webkit-backdrop-filter:blur(16px)saturate(140%);background:#0f172acc;border:1px solid #ffffff0f;box-shadow:0 2px 12px #0000002e}.glass-pill-hovered:before,.glass-pill-hovered:after{display:none}@keyframes glass-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.glass-shimmer{background:linear-gradient(90deg,#ffffff14 0%,#ffffff26 50%,#ffffff14 100%) 0 0/200% 100%;animation:4s ease-in-out infinite glass-shimmer}.scrollbar-thin{scrollbar-width:thin;scrollbar-color:#fff3 transparent}.scrollbar-thin::-webkit-scrollbar{width:4px;height:4px}.scrollbar-thin::-webkit-scrollbar-thumb{background-color:#fff3;border-radius:9999px}.scrollbar-thin::-webkit-scrollbar-track{background-color:#0000}.scroll-touch{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}@media (hover:none){.scrollbar-thin{scrollbar-width:none}.scrollbar-thin::-webkit-scrollbar{display:none}}.scroll-fade-y{-webkit-mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000);mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000)}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px)}.mb-safe{margin-bottom:env(safe-area-inset-bottom,0px)}.bottom-safe{bottom:max(1rem,env(safe-area-inset-bottom,0px))}@supports (padding-bottom:env(safe-area-inset-bottom)){.pill-safe-bottom{padding-bottom:calc(env(safe-area-inset-bottom,0px) + .5rem)}}@property --tw-border-spacing-x{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-translate-x{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-scale-x{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-scale-y{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-scale-z{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:\\\"*\\\";inherits:false}@property --tw-rotate-y{syntax:\\\"*\\\";inherits:false}@property --tw-rotate-z{syntax:\\\"*\\\";inherits:false}@property --tw-skew-x{syntax:\\\"*\\\";inherits:false}@property --tw-skew-y{syntax:\\\"*\\\";inherits:false}@property --tw-space-y-reverse{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\\\"*\\\";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:\\\"*\\\";inherits:false}@property --tw-gradient-from{syntax:\\\"<color>\\\";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:\\\"<color>\\\";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:\\\"<color>\\\";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:\\\"*\\\";inherits:false}@property --tw-gradient-via-stops{syntax:\\\"*\\\";inherits:false}@property --tw-gradient-from-position{syntax:\\\"<length-percentage>\\\";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:\\\"<length-percentage>\\\";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:\\\"<length-percentage>\\\";inherits:false;initial-value:100%}@property --tw-leading{syntax:\\\"*\\\";inherits:false}@property --tw-font-weight{syntax:\\\"*\\\";inherits:false}@property --tw-tracking{syntax:\\\"*\\\";inherits:false}@property --tw-ordinal{syntax:\\\"*\\\";inherits:false}@property --tw-slashed-zero{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-figure{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-spacing{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-fraction{syntax:\\\"*\\\";inherits:false}@property --tw-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\\\"*\\\";inherits:false}@property --tw-shadow-alpha{syntax:\\\"<percentage>\\\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\\\"*\\\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\\\"<percentage>\\\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\\\"*\\\";inherits:false}@property --tw-ring-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\\\"*\\\";inherits:false}@property --tw-inset-ring-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\\\"*\\\";inherits:false}@property --tw-ring-offset-width{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\\\"*\\\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:\\\"*\\\";inherits:false;initial-value:solid}@property --tw-blur{syntax:\\\"*\\\";inherits:false}@property --tw-brightness{syntax:\\\"*\\\";inherits:false}@property --tw-contrast{syntax:\\\"*\\\";inherits:false}@property --tw-grayscale{syntax:\\\"*\\\";inherits:false}@property --tw-hue-rotate{syntax:\\\"*\\\";inherits:false}@property --tw-invert{syntax:\\\"*\\\";inherits:false}@property --tw-opacity{syntax:\\\"*\\\";inherits:false}@property --tw-saturate{syntax:\\\"*\\\";inherits:false}@property --tw-sepia{syntax:\\\"*\\\";inherits:false}@property --tw-drop-shadow{syntax:\\\"*\\\";inherits:false}@property --tw-drop-shadow-color{syntax:\\\"*\\\";inherits:false}@property --tw-drop-shadow-alpha{syntax:\\\"<percentage>\\\";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:\\\"*\\\";inherits:false}@property --tw-duration{syntax:\\\"*\\\";inherits:false}@property --tw-ease{syntax:\\\"*\\\";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}\";\n\n/**\n * CSS styles optimized for shadow DOM injection.\n * Use this with the ShadowRoot component for complete style isolation.\n *\n * Differences from WEBMCP_STYLES:\n * - No body styles (shadow DOM doesn't have a body element)\n * - No @property declarations (not supported in shadow DOM)\n * - Uses :host selector for theming (in addition to :root)\n */\nexport const WEBMCP_SHADOW_STYLES = \"/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */\\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-600:oklch(55.8% .288 302.321);--color-slate-900:oklch(20.8% .042 265.755);--color-zinc-50:oklch(98.5% 0 0);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-xs:.125rem;--ease-out:cubic-bezier(0,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:host,:root{--radius:.75rem;--background:oklch(100% 0 0);--foreground:oklch(14.1% .005 285.823);--card:oklch(100% 0 0);--card-foreground:oklch(14.1% .005 285.823);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.1% .005 285.823);--primary:oklch(21% .006 285.885);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.7% .001 286.375);--secondary-foreground:oklch(21% .006 285.885);--muted:oklch(96.7% .001 286.375);--muted-foreground:oklch(55.2% .016 285.938);--accent:oklch(96.7% .001 286.375);--accent-foreground:oklch(21% .006 285.885);--destructive:oklch(57.7% .245 27.325);--destructive-foreground:oklch(98.5% 0 0);--border:oklch(92% .004 286.32);--input:oklch(92% .004 286.32);--ring:oklch(70.5% .015 286.067)}:host(.dark),.dark{--background:oklch(14.1% .005 285.823);--foreground:oklch(98.5% 0 0);--card:oklch(21% .006 285.885);--card-foreground:oklch(98.5% 0 0);--popover:oklch(21% .006 285.885);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92% .004 286.32);--primary-foreground:oklch(21% .006 285.885);--secondary:oklch(27.4% .006 286.033);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(27.4% .006 286.033);--muted-foreground:oklch(70.5% .015 286.067);--accent:oklch(27.4% .006 286.033);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--destructive-foreground:oklch(98.5% 0 0);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.2% .016 285.938)}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklch,var(--ring),transparent 50%)}}}@layer components{.app-shell{z-index:0;background-color:var(--background);background-image:radial-gradient(80% 60% at -10% -10%,oklch(82% .15 270/.15),#0000),radial-gradient(60% 50% at 110% 10%,oklch(85% .1 220/.12),#0000),radial-gradient(50% 45% at 50% 120%,oklch(95% .02 250/.08),#0000);position:relative}.dark .app-shell{background-image:radial-gradient(80% 60% at -10% -10%,oklch(55% .14 270/.25),#0000),radial-gradient(60% 50% at 110% 15%,oklch(60% .12 220/.22),#0000),radial-gradient(50% 45% at 50% 120%,oklch(35% .04 250/.16),#0000)}.app-shell:before,.app-shell:after{content:\\\"\\\";pointer-events:none;filter:blur(32px);opacity:.6;z-index:-1;border-radius:9999px;position:absolute;inset:auto}.app-shell:before{background:radial-gradient(60% 60% at 40% 40%,oklch(80% .12 270/.3),#0000);width:260px;height:260px;top:-60px;left:-80px}.app-shell:after{background:radial-gradient(60% 60% at 60% 60%,oklch(84% .1 220/.25),#0000);width:300px;height:300px;bottom:-80px;right:-60px}.toolbar-surface{border-top:1px solid var(--border);background:linear-gradient(to right,var(--background),var(--background),var(--background))}@supports (color:color-mix(in lab, red, red)){.toolbar-surface{background:linear-gradient(to right,var(--background),color-mix(in oklch,var(--background),transparent 5%),var(--background))}}.toolbar-surface{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.toolbar-surface{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.toolbar-surface{background:color-mix(in oklch,var(--background),transparent 20%)}}}.toolbar-surface-top{border-bottom:1px solid var(--border);background:linear-gradient(to right,var(--background),var(--background),var(--background))}@supports (color:color-mix(in lab, red, red)){.toolbar-surface-top{background:linear-gradient(to right,var(--background),color-mix(in oklch,var(--background),transparent 5%),var(--background))}}.toolbar-surface-top{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.toolbar-surface-top{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.toolbar-surface-top{background:color-mix(in oklch,var(--background),transparent 20%)}}}.toolbar-inner{justify-content:space-between;align-items:center;padding:.5rem .75rem;display:flex}.toolbar-card{background:var(--card);justify-content:space-between;align-items:center;gap:.5rem;display:flex}@supports (color:color-mix(in lab, red, red)){.toolbar-card{background:color-mix(in oklch,var(--card),transparent 60%)}}.toolbar-card{border:1px solid var(--border);border-radius:.75rem;padding:.5rem .75rem}.toolbar-group{align-items:center;gap:.25rem;display:flex}.btn-toolbar-primary{background:linear-gradient(to right,var(--primary),var(--primary));border-radius:.75rem;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;display:flex}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary{background:linear-gradient(to right,color-mix(in oklch,var(--primary),transparent 95%),color-mix(in oklch,var(--primary),transparent 90%))}}.btn-toolbar-primary{border:1px solid var(--primary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary{border:1px solid color-mix(in oklch,var(--primary),transparent 80%)}}.btn-toolbar-primary{transition:all .2s}.btn-toolbar-primary:hover{background:linear-gradient(to right,var(--primary),var(--primary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-primary:hover{background:linear-gradient(to right,color-mix(in oklch,var(--primary),transparent 90%),color-mix(in oklch,var(--primary),transparent 80%))}}.btn-toolbar-icon-primary{background:linear-gradient(to bottom right,var(--primary),var(--primary));border-radius:9999px;width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--primary),transparent 90%),color-mix(in oklch,var(--primary),transparent 80%))}}.btn-toolbar-icon-primary{border:1px solid var(--primary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary{border:1px solid color-mix(in oklch,var(--primary),transparent 70%)}}.btn-toolbar-icon-primary{transition:all .2s;box-shadow:0 1px 2px #0000000d}.btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,var(--primary),var(--primary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--primary),transparent 80%),color-mix(in oklch,var(--primary),transparent 70%))}}.btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,var(--secondary),var(--secondary));border-radius:9999px;width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--secondary),transparent 90%),color-mix(in oklch,var(--secondary),transparent 80%))}}.btn-toolbar-icon-secondary{border:1px solid var(--secondary)}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary{border:1px solid color-mix(in oklch,var(--secondary),transparent 70%)}}.btn-toolbar-icon-secondary{transition:all .2s;box-shadow:0 1px 2px #0000000d}.btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,var(--secondary),var(--secondary))}@supports (color:color-mix(in lab, red, red)){.btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--secondary),transparent 80%),color-mix(in oklch,var(--secondary),transparent 70%))}}.badge-compact{height:1.25rem;padding:0 .5rem;font-size:10px}.badge-mini{height:1rem;padding:0 .375rem;font-size:10px}@keyframes shimmer-bg{0%{background-position:-1000px 0}to{background-position:1000px 0}}.shimmer{background:linear-gradient(90deg,#0000,#ffffff1a,#0000) 0 0/1000px 100%;animation:3s linear infinite shimmer-bg}.animate-shimmer{animation:2s linear infinite shimmer}@keyframes pulse-glow{0%,to{box-shadow:0 0 20px rgba(var(--primary),.1)}50%{box-shadow:0 0 30px rgba(var(--primary),.2)}}.pulse-glow{animation:2s ease-in-out infinite pulse-glow}@keyframes gradient-x{0%,to{background-position:0%}50%{background-position:100%}}.animate-gradient-x{animation:8s ease-in-out infinite gradient-x}.gradient-text{background:linear-gradient(to right,var(--foreground),var(--foreground))}@supports (color:color-mix(in lab, red, red)){.gradient-text{background:linear-gradient(to right,var(--foreground),color-mix(in oklch,var(--foreground),transparent 30%))}}.gradient-text{-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text}.glass{background:var(--background)}@supports (color:color-mix(in lab, red, red)){.glass{background:color-mix(in oklch,var(--background),transparent 50%)}}.glass{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--border)}@supports (color:color-mix(in lab, red, red)){.glass{border:1px solid color-mix(in oklch,var(--border),transparent 50%)}}.tool-card{transition:all .3s ease-out}.tool-card:hover{transform:scale(1.02);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}.scrollbar-thin{scrollbar-width:thin}.scrollbar-thin::-webkit-scrollbar{width:6px;height:6px}.scrollbar-thin::-webkit-scrollbar-track{background:0 0}.scrollbar-thin::-webkit-scrollbar-thumb{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.scrollbar-thin::-webkit-scrollbar-thumb{background-color:color-mix(in oklch,var(--primary),transparent 80%)}}.scrollbar-thin::-webkit-scrollbar-thumb{border-radius:3px}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:color-mix(in oklch,var(--primary),transparent 70%)}}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.-inset-\\\\[1px\\\\]{inset:-1px}.inset-0{inset:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\\\\.5{top:calc(var(--spacing)*-1.5)}.top-1\\\\.5{top:calc(var(--spacing)*1.5)}.top-1\\\\/2{top:50%}.top-4{top:calc(var(--spacing)*4)}.top-\\\\[50\\\\%\\\\]{top:50%}.-right-0\\\\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\\\\.5{right:calc(var(--spacing)*-1.5)}.right-0{right:calc(var(--spacing)*0)}.right-1\\\\.5{right:calc(var(--spacing)*1.5)}.right-4{right:calc(var(--spacing)*4)}.-bottom-0\\\\.5{bottom:calc(var(--spacing)*-.5)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing)*0)}.left-1\\\\/2,.left-\\\\[50\\\\%\\\\]{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-full{grid-column:1/-1}.col-start-1{grid-column-start:1}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-m-1{margin:calc(var(--spacing)*-1)}.m-0{margin:calc(var(--spacing)*0)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.-mt-1{margin-top:calc(var(--spacing)*-1)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1\\\\.5{margin-right:calc(var(--spacing)*1.5)}.-mb-1{margin-bottom:calc(var(--spacing)*-1)}.mb-0\\\\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.ml-0\\\\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-2\\\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-14{width:calc(var(--spacing)*14);height:calc(var(--spacing)*14)}.size-\\\\[34px\\\\]{width:34px;height:34px}.size-full{width:100%;height:100%}.h-1\\\\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\\\\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\\\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\\\\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-auto{height:auto}.h-full{height:100%}.max-h-24{max-height:calc(var(--spacing)*24)}.max-h-32{max-height:calc(var(--spacing)*32)}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-\\\\[30vh\\\\]{max-height:30vh}.max-h-\\\\[80dvh\\\\]{max-height:80dvh}.max-h-\\\\[80vh\\\\]{max-height:80vh}.min-h-7{min-height:calc(var(--spacing)*7)}.min-h-11{min-height:calc(var(--spacing)*11)}.min-h-screen{min-height:100vh}.w-0\\\\.5{width:calc(var(--spacing)*.5)}.w-1\\\\.5{width:calc(var(--spacing)*1.5)}.w-2{width:calc(var(--spacing)*2)}.w-2\\\\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\\\\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\\\\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-11{width:calc(var(--spacing)*11)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-24{max-width:calc(var(--spacing)*24)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\\\\[100px\\\\]{max-width:100px}.max-w-\\\\[calc\\\\(100\\\\%-2rem\\\\)\\\\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-7{min-width:calc(var(--spacing)*7)}.min-w-11{min-width:calc(var(--spacing)*11)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.border-separate{border-collapse:separate}.border-spacing-0{--tw-border-spacing-x:calc(var(--spacing)*0);--tw-border-spacing-y:calc(var(--spacing)*0);border-spacing:var(--tw-border-spacing-x)var(--tw-border-spacing-y)}.origin-\\\\(--radix-tooltip-content-transform-origin\\\\){transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\\\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\\\\[-50\\\\%\\\\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\\\\[-50\\\\%\\\\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\\\\[calc\\\\(-50\\\\%_-_2px\\\\)\\\\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-75{--tw-scale-x:75%;--tw-scale-y:75%;--tw-scale-z:75%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.rotate-45{rotate:45deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.scroll-m-20{scroll-margin:calc(var(--spacing)*20)}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-rows-\\\\[0fr\\\\]{grid-template-rows:0fr}.grid-rows-\\\\[1fr\\\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\\\\[2px\\\\]{border-radius:2px}.rounded-\\\\[14px\\\\]{border-radius:14px}.rounded-\\\\[inherit\\\\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-xs{border-radius:var(--radius-xs)}.\\\\!rounded-t-none{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.rounded-b-lg{border-bottom-right-radius:var(--radius);border-bottom-left-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-amber-500\\\\/30{border-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.border-amber-500\\\\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-amber-500\\\\/50{border-color:#f99c0080}@supports (color:color-mix(in lab, red, red)){.border-amber-500\\\\/50{border-color:color-mix(in oklab,var(--color-amber-500)50%,transparent)}}.border-blue-500\\\\/20{border-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.border-blue-500\\\\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\\\\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\\\\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-border{border-color:var(--border)}.border-foreground\\\\/20{border-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.border-foreground\\\\/20{border-color:color-mix(in oklab,var(--foreground)20%,transparent)}}.border-input{border-color:var(--input)}.border-muted-foreground\\\\/20{border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\\\\/20{border-color:color-mix(in oklab,var(--muted-foreground)20%,transparent)}}.border-transparent{border-color:#0000}.border-white\\\\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/5{border-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.border-white\\\\/8{border-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/8{border-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.border-white\\\\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\\\\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.border-white\\\\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-zinc-200{border-color:var(--color-zinc-200)}.border-zinc-200\\\\/80{border-color:#e4e4e7cc}@supports (color:color-mix(in lab, red, red)){.border-zinc-200\\\\/80{border-color:color-mix(in oklab,var(--color-zinc-200)80%,transparent)}}.border-zinc-600{border-color:var(--color-zinc-600)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\\\\/10{background-color:#f99c001a}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\\\\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\\\\/20{background-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\\\\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-background{background-color:var(--background)}.bg-black{background-color:var(--color-black)}.bg-black\\\\/30{background-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.bg-black\\\\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\\\\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\\\\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\\\\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\\\\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-border{background-color:var(--border)}.bg-destructive{background-color:var(--destructive)}.bg-foreground{background-color:var(--foreground)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-400\\\\/60{background-color:#05df7299}@supports (color:color-mix(in lab, red, red)){.bg-green-400\\\\/60{background-color:color-mix(in oklab,var(--color-green-400)60%,transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\\\\/10{background-color:#00c7581a}@supports (color:color-mix(in lab, red, red)){.bg-green-500\\\\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-muted{background-color:var(--muted)}.bg-muted-foreground\\\\/15{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\\\/15{background-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.bg-muted\\\\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\\\\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.bg-primary{background-color:var(--primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\\\\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\\\\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\\\\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.bg-red-500\\\\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\\\\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/5{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.bg-white\\\\/8{background-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/8{background-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.bg-white\\\\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-white\\\\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/20{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.bg-white\\\\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/60{background-color:color-mix(in oklab,var(--color-white)60%,transparent)}}.bg-white\\\\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){.bg-white\\\\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-zinc-100{background-color:var(--color-zinc-100)}.bg-zinc-700\\\\/50{background-color:#3f3f4680}@supports (color:color-mix(in lab, red, red)){.bg-zinc-700\\\\/50{background-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-indigo-500{--tw-gradient-from:var(--color-indigo-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-600{--tw-gradient-to:var(--color-purple-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.fill-foreground{fill:var(--foreground)}.stroke-\\\\[1\\\\.5px\\\\]{stroke-width:1.5px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-px{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\\\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-0\\\\.5{padding-top:calc(var(--spacing)*.5)}.pt-1\\\\.5{padding-top:calc(var(--spacing)*1.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\\\[10px\\\\]{font-size:10px}.text-\\\\[11px\\\\]{font-size:11px}.text-\\\\[13px\\\\]{font-size:13px}.text-\\\\[15px\\\\]{font-size:15px}.text-\\\\[17px\\\\]{font-size:17px}.text-\\\\[19px\\\\]{font-size:19px}.text-\\\\[21px\\\\]{font-size:21px}.text-\\\\[25px\\\\]{font-size:25px}.leading-\\\\[21px\\\\]{--tw-leading:21px;line-height:21px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-background{color:var(--background)}.text-blue-400{color:var(--color-blue-400)}.text-blue-400\\\\/60{color:#54a2ff99}@supports (color:color-mix(in lab, red, red)){.text-blue-400\\\\/60{color:color-mix(in oklab,var(--color-blue-400)60%,transparent)}}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground{color:var(--foreground)}.text-green-400{color:var(--color-green-400)}.text-green-600{color:var(--color-green-600)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.text-white\\\\/30{color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/30{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.text-white\\\\/40{color:#fff6}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-white\\\\/50{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/50{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.text-white\\\\/60{color:#fff9}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\\\\/70{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/70{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.text-white\\\\/80{color:#fffc}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\\\\/90{color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){.text-white\\\\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-700{color:var(--color-zinc-700)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-black\\\\/10{--tw-shadow-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.shadow-black\\\\/10{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-black)10%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\\\[color\\\\,box-shadow\\\\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\\\[grid-template-rows\\\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.will-change-transform{will-change:transform}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\\\\:scale-100:is(:where(.group):hover *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\\\\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\\\\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.placeholder\\\\:text-white\\\\/40::placeholder{color:#fff6}@supports (color:color-mix(in lab, red, red)){.placeholder\\\\:text-white\\\\/40::placeholder{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.first\\\\:mt-0:first-child{margin-top:calc(var(--spacing)*0)}.first\\\\:rounded-tl-lg:first-child{border-top-left-radius:var(--radius)}.first\\\\:border-t:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.last\\\\:mb-0:last-child{margin-bottom:calc(var(--spacing)*0)}.last\\\\:rounded-tr-lg:last-child{border-top-right-radius:var(--radius)}.last\\\\:border-r:last-child{border-right-style:var(--tw-border-style);border-right-width:1px}.empty\\\\:hidden:empty{display:none}.focus-within\\\\:border-white\\\\/15:focus-within{border-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.focus-within\\\\:border-white\\\\/15:focus-within{border-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.focus-within\\\\:bg-white\\\\/10:focus-within{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.focus-within\\\\:bg-white\\\\/10:focus-within{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}@media (hover:hover){.hover\\\\:border-amber-500:hover{border-color:var(--color-amber-500)}.hover\\\\:border-red-500\\\\/50:hover{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.hover\\\\:border-red-500\\\\/50:hover{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.hover\\\\:border-white\\\\/20:hover{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:border-white\\\\/20:hover{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\\\\:\\\\!bg-white:hover{background-color:var(--color-white)!important}.hover\\\\:bg-accent:hover,.hover\\\\:bg-accent\\\\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-accent\\\\/50:hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.hover\\\\:bg-amber-500\\\\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-amber-500\\\\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.hover\\\\:bg-amber-500\\\\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-amber-500\\\\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\\\\:bg-destructive\\\\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/10:hover{background-color:color-mix(in oklab,var(--destructive)10%,transparent)}}.hover\\\\:bg-destructive\\\\/80:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}}.hover\\\\:bg-destructive\\\\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-destructive\\\\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}}.hover\\\\:bg-muted-foreground\\\\/15:hover{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-muted-foreground\\\\/15:hover{background-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.hover\\\\:bg-primary\\\\/80:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-primary\\\\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}}.hover\\\\:bg-primary\\\\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-primary\\\\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}}.hover\\\\:bg-red-500\\\\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-red-500\\\\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\\\\:bg-red-500\\\\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-red-500\\\\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\\\\:bg-secondary\\\\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-secondary\\\\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}}.hover\\\\:bg-white:hover{background-color:var(--color-white)}.hover\\\\:bg-white\\\\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\\\\:bg-white\\\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\\\:bg-white\\\\/15:hover{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/15:hover{background-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.hover\\\\:bg-white\\\\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\\\\:bg-white\\\\/30:hover{background-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/30:hover{background-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.hover\\\\:bg-white\\\\/95:hover{background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.hover\\\\:bg-white\\\\/95:hover{background-color:color-mix(in oklab,var(--color-white)95%,transparent)}}.hover\\\\:bg-zinc-50:hover{background-color:var(--color-zinc-50)}.hover\\\\:bg-zinc-200:hover{background-color:var(--color-zinc-200)}.hover\\\\:bg-zinc-700:hover{background-color:var(--color-zinc-700)}.hover\\\\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\\\\:text-destructive:hover{color:var(--destructive)}.hover\\\\:text-foreground:hover{color:var(--foreground)}.hover\\\\:text-primary\\\\/80:hover{color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-primary\\\\/80:hover{color:color-mix(in oklab,var(--primary)80%,transparent)}}.hover\\\\:text-red-200:hover{color:var(--color-red-200)}.hover\\\\:text-red-300:hover{color:var(--color-red-300)}.hover\\\\:text-red-400:hover{color:var(--color-red-400)}.hover\\\\:text-white:hover{color:var(--color-white)}.hover\\\\:text-white\\\\/50:hover{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/50:hover{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.hover\\\\:text-white\\\\/60:hover{color:#fff9}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/60:hover{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.hover\\\\:text-white\\\\/70:hover{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/70:hover{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.hover\\\\:text-white\\\\/80:hover{color:#fffc}@supports (color:color-mix(in lab, red, red)){.hover\\\\:text-white\\\\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\\\\:text-zinc-600:hover{color:var(--color-zinc-600)}.hover\\\\:underline:hover{text-decoration-line:underline}.hover\\\\:opacity-75:hover{opacity:.75}.hover\\\\:opacity-100:hover{opacity:1}}.focus\\\\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\\\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\\\\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\\\\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\\\\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus\\\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\\\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\\\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-\\\\[3px\\\\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\\\:ring-blue-500:focus-visible{--tw-ring-color:var(--color-blue-500)}.focus-visible\\\\:ring-destructive\\\\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-destructive\\\\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.focus-visible\\\\:ring-ring:focus-visible,.focus-visible\\\\:ring-ring\\\\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-ring\\\\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.focus-visible\\\\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\\\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\\\\:ring-offset-transparent:focus-visible{--tw-ring-offset-color:transparent}.focus-visible\\\\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\\\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\\\\:scale-\\\\[0\\\\.98\\\\]:active{scale:.98}.active\\\\:cursor-grabbing:active{cursor:grabbing}.active\\\\:bg-white\\\\/15:active{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.active\\\\:bg-white\\\\/15:active{background-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.active\\\\:bg-white\\\\/20:active{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.active\\\\:bg-white\\\\/20:active{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.disabled\\\\:pointer-events-none:disabled{pointer-events:none}.disabled\\\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\\\:opacity-40:disabled{opacity:.4}.disabled\\\\:opacity-50:disabled{opacity:.5}.has-\\\\[\\\\>svg\\\\]\\\\:px-2\\\\.5:has(>svg){padding-inline:calc(var(--spacing)*2.5)}.has-\\\\[\\\\>svg\\\\]\\\\:px-3:has(>svg){padding-inline:calc(var(--spacing)*3)}.has-\\\\[\\\\>svg\\\\]\\\\:px-4:has(>svg){padding-inline:calc(var(--spacing)*4)}.aria-invalid\\\\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\\\\:ring-destructive\\\\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\\\\:ring-destructive\\\\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.data-\\\\[orientation\\\\=horizontal\\\\]\\\\:h-px[data-orientation=horizontal]{height:1px}.data-\\\\[orientation\\\\=horizontal\\\\]\\\\:w-full[data-orientation=horizontal]{width:100%}.data-\\\\[orientation\\\\=vertical\\\\]\\\\:h-full[data-orientation=vertical]{height:100%}.data-\\\\[orientation\\\\=vertical\\\\]\\\\:w-px[data-orientation=vertical]{width:1px}.data-\\\\[state\\\\=open\\\\]\\\\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\\\\[state\\\\=open\\\\]\\\\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}@media (min-width:40rem){.sm\\\\:flex{display:flex}.sm\\\\:h-3{height:calc(var(--spacing)*3)}.sm\\\\:h-3\\\\.5{height:calc(var(--spacing)*3.5)}.sm\\\\:h-4{height:calc(var(--spacing)*4)}.sm\\\\:h-7{height:calc(var(--spacing)*7)}.sm\\\\:max-h-24{max-height:calc(var(--spacing)*24)}.sm\\\\:max-h-32{max-height:calc(var(--spacing)*32)}.sm\\\\:max-h-48{max-height:calc(var(--spacing)*48)}.sm\\\\:min-h-7{min-height:calc(var(--spacing)*7)}.sm\\\\:w-3{width:calc(var(--spacing)*3)}.sm\\\\:w-3\\\\.5{width:calc(var(--spacing)*3.5)}.sm\\\\:w-4{width:calc(var(--spacing)*4)}.sm\\\\:w-7{width:calc(var(--spacing)*7)}.sm\\\\:max-w-3xl{max-width:var(--container-3xl)}.sm\\\\:max-w-16{max-width:calc(var(--spacing)*16)}.sm\\\\:max-w-24{max-width:calc(var(--spacing)*24)}.sm\\\\:max-w-lg{max-width:var(--container-lg)}.sm\\\\:max-w-md{max-width:var(--container-md)}.sm\\\\:min-w-7{min-width:calc(var(--spacing)*7)}.sm\\\\:flex-row{flex-direction:row}.sm\\\\:justify-end{justify-content:flex-end}.sm\\\\:gap-1{gap:calc(var(--spacing)*1)}.sm\\\\:gap-1\\\\.5{gap:calc(var(--spacing)*1.5)}.sm\\\\:p-1{padding:calc(var(--spacing)*1)}.sm\\\\:p-1\\\\.5{padding:calc(var(--spacing)*1.5)}.sm\\\\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\\\\:py-1{padding-block:calc(var(--spacing)*1)}.sm\\\\:text-left{text-align:left}.sm\\\\:opacity-0{opacity:0}@media (hover:hover){.sm\\\\:group-hover\\\\:opacity-100:is(:where(.group):hover *){opacity:1}}}.dark\\\\:border-input:is(.dark *){border-color:var(--input)}.dark\\\\:border-muted-foreground\\\\/15:is(.dark *){border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:border-muted-foreground\\\\/15:is(.dark *){border-color:color-mix(in oklab,var(--muted-foreground)15%,transparent)}}.dark\\\\:border-zinc-600:is(.dark *){border-color:var(--color-zinc-600)}.dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:#3f3f46cc}@supports (color:color-mix(in lab, red, red)){.dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:color-mix(in oklab,var(--color-zinc-700)80%,transparent)}}.dark\\\\:bg-destructive\\\\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-destructive\\\\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive)60%,transparent)}}.dark\\\\:bg-input\\\\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-input\\\\/30:is(.dark *){background-color:color-mix(in oklab,var(--input)30%,transparent)}}.dark\\\\:bg-muted-foreground\\\\/20:is(.dark *){background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:bg-muted-foreground\\\\/20:is(.dark *){background-color:color-mix(in oklab,var(--muted-foreground)20%,transparent)}}.dark\\\\:bg-zinc-700:is(.dark *){background-color:var(--color-zinc-700)}.dark\\\\:bg-zinc-800:is(.dark *){background-color:var(--color-zinc-800)}.dark\\\\:stroke-\\\\[2\\\\.5px\\\\]:is(.dark *){stroke-width:2.5px}.dark\\\\:text-green-400:is(.dark *){color:var(--color-green-400)}.dark\\\\:text-zinc-200:is(.dark *){color:var(--color-zinc-200)}.dark\\\\:text-zinc-400:is(.dark *){color:var(--color-zinc-400)}.dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-black)30%,transparent)var(--tw-shadow-alpha),transparent)}}@media (hover:hover){.dark\\\\:hover\\\\:bg-accent\\\\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-accent\\\\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.dark\\\\:hover\\\\:bg-input\\\\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-input\\\\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input)50%,transparent)}}.dark\\\\:hover\\\\:bg-muted-foreground\\\\/30:is(.dark *):hover{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:hover\\\\:bg-muted-foreground\\\\/30:is(.dark *):hover{background-color:color-mix(in oklab,var(--muted-foreground)30%,transparent)}}.dark\\\\:hover\\\\:bg-zinc-600:is(.dark *):hover{background-color:var(--color-zinc-600)}.dark\\\\:hover\\\\:bg-zinc-700:is(.dark *):hover{background-color:var(--color-zinc-700)}.dark\\\\:hover\\\\:text-zinc-200:is(.dark *):hover{color:var(--color-zinc-200)}}.dark\\\\:focus-visible\\\\:ring-destructive\\\\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:focus-visible\\\\:ring-destructive\\\\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\\\\:aria-invalid\\\\:ring-destructive\\\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\\\:aria-invalid\\\\:ring-destructive\\\\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.\\\\[\\\\&_svg\\\\]\\\\:pointer-events-none svg{pointer-events:none}.\\\\[\\\\&_svg\\\\]\\\\:shrink-0 svg{flex-shrink:0}.\\\\[\\\\&_svg\\\\]\\\\:text-background svg{color:var(--background)}.\\\\[\\\\&_svg\\\\]\\\\:text-black svg{color:var(--color-black)}@media (hover:hover){.hover\\\\:\\\\[\\\\&_svg\\\\]\\\\:text-destructive:hover svg{color:var(--destructive)}}.\\\\[\\\\&_svg\\\\:not\\\\(\\\\[class\\\\*\\\\=\\\\'size-\\\\'\\\\]\\\\)\\\\]\\\\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\\\[\\\\&\\\\:last-child\\\\>td\\\\:first-child\\\\]\\\\:rounded-bl-lg:last-child>td:first-child{border-bottom-left-radius:var(--radius)}.\\\\[\\\\&\\\\:last-child\\\\>td\\\\:last-child\\\\]\\\\:rounded-br-lg:last-child>td:last-child{border-bottom-right-radius:var(--radius)}.only\\\\:\\\\[\\\\&\\\\>\\\\#attachment-tile\\\\]\\\\:size-24:only-child>#attachment-tile{width:calc(var(--spacing)*24);height:calc(var(--spacing)*24)}.\\\\[\\\\&\\\\>a\\\\]\\\\:text-xs>a{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\\\\[\\\\&\\\\>a\\\\]\\\\:no-underline>a{text-decoration-line:none}.\\\\[\\\\&\\\\>button\\\\]\\\\:rounded-full>button{border-radius:3.40282e38px}.\\\\[\\\\&\\\\>button\\\\]\\\\:bg-foreground\\\\/60>button{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.\\\\[\\\\&\\\\>button\\\\]\\\\:bg-foreground\\\\/60>button{background-color:color-mix(in oklab,var(--foreground)60%,transparent)}}.\\\\[\\\\&\\\\>button\\\\]\\\\:p-1>button{padding:calc(var(--spacing)*1)}.\\\\[\\\\&\\\\>button\\\\]\\\\:opacity-100>button{opacity:1}.\\\\[\\\\&\\\\>button\\\\]\\\\:\\\\!ring-0>button{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}@media (hover:hover){.\\\\[\\\\&\\\\>button\\\\]\\\\:hover\\\\:\\\\[\\\\&_svg\\\\]\\\\:text-destructive>button:hover svg{color:var(--destructive)}}.\\\\[\\\\&\\\\>li\\\\]\\\\:mt-0\\\\.5>li{margin-top:calc(var(--spacing)*.5)}.\\\\[\\\\&\\\\>li\\\\]\\\\:mt-1>li{margin-top:calc(var(--spacing)*1)}.\\\\[\\\\&\\\\>span\\\\]\\\\:text-xs>span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\\\\[\\\\&\\\\[align\\\\=center\\\\]\\\\]\\\\:text-center[align=center]{text-align:center}.\\\\[\\\\&\\\\[align\\\\=right\\\\]\\\\]\\\\:text-right[align=right]{text-align:right}}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(200%)}}@keyframes subtle-pulse{0%,to{opacity:1}50%{opacity:.85}}@keyframes smooth-slide-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes gradient-shift{0%,to{transform:translate(0%)translateY(0%)}25%{transform:translate(100%)translateY(100%)}50%{transform:translate(100%)translateY(0%)}75%{transform:translate(0%)translateY(100%)}}@keyframes float{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(-30px)translate(20px)}66%{transform:translateY(20px)translate(-20px)}}@keyframes float-delayed{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(30px)translate(-30px)}66%{transform:translateY(-20px)translate(20px)}}.tool-card-transition{transition:all .4s cubic-bezier(.34,1.56,.64,1)}.tool-card-smooth{transition:all .35s cubic-bezier(.4,0,.2,1)}.animate-fadeInUp{opacity:0;animation:.5s ease-out forwards fadeInUp}.animate-gradient-shift{background-size:200% 200%;animation:20s ease-in-out infinite gradient-shift}.animate-float-slow{animation:20s ease-in-out infinite float}.animate-float-delayed{animation:25s ease-in-out 5s infinite float-delayed}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@keyframes tool-border-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@supports (background:paint(something)){}.tool-border-calling{position:relative;overflow:hidden}.tool-border-calling:before{content:\\\"\\\";background:conic-gradient(#0000 0deg 60deg,#3b82f680 90deg,#60a5fab3 120deg,#93c5fd80 150deg,#0000 180deg 360deg);animation:1.5s linear infinite tool-border-rotate;position:absolute;inset:-50%}.tool-border-success{background:#22c55e66;box-shadow:0 0 12px #22c55e4d,inset 0 0 8px #22c55e1a}.tool-border-error{background:#ef444466;box-shadow:0 0 12px #ef44444d,inset 0 0 8px #ef44441a}@keyframes pulse-success{0%,to{box-shadow:0 0 #22c55e66}50%{box-shadow:0 0 0 8px #22c55e00}}@keyframes shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.animate-pulse-success{animation:.6s ease-out pulse-success}.animate-shake{animation:.3s ease-out shake}@keyframes aui-pulse{50%{opacity:.5}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;animation:2s cubic-bezier(.4,0,.6,1) infinite aui-pulse}.glass-pill{-webkit-backdrop-filter:blur(20px)saturate(150%);background:#0f172ad9;border:1px solid #ffffff0f;box-shadow:0 4px 16px #0003,inset 0 .5px #ffffff14}.glass-pill:before{content:\\\"\\\";border-radius:inherit;pointer-events:none;z-index:1;background:linear-gradient(#ffffff0a 0%,#0000 40%);position:absolute;inset:0}.glass-pill:after{display:none}.glass-pill-collapsed{-webkit-backdrop-filter:blur(20px)saturate(150%);background:#0f172ad9;border:1px solid #ffffff0f;box-shadow:0 2px 8px #0003,inset 0 .5px #ffffff14}.glass-pill-collapsed:before,.glass-pill-collapsed:after{display:none}.glass-pill-hovered{-webkit-backdrop-filter:blur(16px)saturate(140%);background:#0f172acc;border:1px solid #ffffff0f;box-shadow:0 2px 12px #0000002e}.glass-pill-hovered:before,.glass-pill-hovered:after{display:none}@keyframes glass-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.glass-shimmer{background:linear-gradient(90deg,#ffffff14 0%,#ffffff26 50%,#ffffff14 100%) 0 0/200% 100%;animation:4s ease-in-out infinite glass-shimmer}.scrollbar-thin{scrollbar-width:thin;scrollbar-color:#fff3 transparent}.scrollbar-thin::-webkit-scrollbar{width:4px;height:4px}.scrollbar-thin::-webkit-scrollbar-thumb{background-color:#fff3;border-radius:9999px}.scrollbar-thin::-webkit-scrollbar-track{background-color:#0000}.scroll-touch{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}@media (hover:none){.scrollbar-thin{scrollbar-width:none}.scrollbar-thin::-webkit-scrollbar{display:none}}.scroll-fade-y{-webkit-mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000);mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000)}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px)}.mb-safe{margin-bottom:env(safe-area-inset-bottom,0px)}.bottom-safe{bottom:max(1rem,env(safe-area-inset-bottom,0px))}@supports (padding-bottom:env(safe-area-inset-bottom)){.pill-safe-bottom{padding-bottom:calc(env(safe-area-inset-bottom,0px) + .5rem)}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}\";\n\n/**\n * Inject the WebMCP styles into the document head.\n * This is called automatically when registering the web component without shadow DOM.\n *\n * @deprecated For new implementations, use the ShadowRoot component with WEBMCP_SHADOW_STYLES\n * instead of global style injection for better isolation.\n */\nexport function injectStyles(): void {\n\tif (typeof document === 'undefined') return\n\n\tconst styleId = 'webmcp-agent-styles'\n\tif (document.getElementById(styleId)) return\n\n\tconst style = document.createElement('style')\n\tstyle.id = styleId\n\tstyle.textContent = WEBMCP_STYLES\n\tdocument.head.appendChild(style)\n}\n\n/**\n * Get the shadow DOM compatible styles.\n * Use this when manually creating a shadow root.\n *\n * @example\n * const shadow = element.attachShadow({ mode: 'open' })\n * const style = document.createElement('style')\n * style.textContent = getShadowStyles()\n * shadow.appendChild(style)\n */\nexport function getShadowStyles(): string {\n\treturn WEBMCP_SHADOW_STYLES\n}\n","/**\n * WebMCP Agent\n *\n * An Intercom-like AI chat widget with MCP tool support and voice mode.\n * Drop it into your app and you're done - no configuration needed.\n *\n * Uses shadow DOM for complete style isolation from the host page:\n * - Host page styles cannot affect the agent widget\n * - Agent styles cannot leak to the host page\n * - Perfect for embedding on third-party sites\n *\n * @example Web Component (simplest)\n * ```html\n * <script src=\"https://cdn.webmcp.ai/agent.js\"></script>\n * <webmcp-agent app-id=\"your-app-id\"></webmcp-agent>\n * ```\n *\n * @example React Component\n * ```tsx\n * import { EmbeddedAgent } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return <EmbeddedAgent appId=\"your-app-id\" />\n * }\n * ```\n *\n * @example Development mode (use your own API keys)\n * ```tsx\n * <EmbeddedAgent\n * appId=\"your-app-id\"\n * devMode={{\n * anthropicApiKey: \"sk-ant-...\",\n * openaiApiKey: \"sk-...\" // Optional, for voice mode\n * }}\n * />\n * ```\n *\n * @example Disable shadow DOM isolation (not recommended)\n * ```tsx\n * <EmbeddedAgent appId=\"your-app-id\" disableShadowDOM />\n * ```\n */\n\nimport r2wc from '@r2wc/react-to-web-component'\n\nimport { AgentPill } from './components/pill'\nimport { ShadowRoot } from './components/ShadowRoot'\nimport { AgentProvider } from './core/providers/AgentProvider'\nimport { injectStyles, WEBMCP_SHADOW_STYLES } from './generated/inline-styles'\nimport { WEBMCP_PRODUCTION_API_BASE } from './lib/constants'\n\nimport type { FC } from 'react'\n\n/**\n * Get the default API base URL.\n * Always uses production unless explicitly overridden with useLocalApi.\n */\nconst getDefaultApiBase = (useLocalApi?: boolean): string => {\n\tif (useLocalApi && typeof window !== 'undefined') {\n\t\treturn window.location.origin\n\t}\n\treturn WEBMCP_PRODUCTION_API_BASE\n}\n\n/**\n * Development mode configuration\n *\n * In dev mode, you provide your own API keys for testing.\n * Requests still go through WebMCP infrastructure (Cloudflare Workers),\n * but use your keys so there's no cost to us during development.\n */\nexport interface DevModeConfig {\n\t/** Your Anthropic API key for chat (required for dev mode) */\n\tanthropicApiKey: string\n\t/** Your OpenAI API key for voice mode (optional) */\n\topenaiApiKey?: string\n\t/** Use window.location.origin instead of production API (for internal development) */\n\tuseLocalApi?: boolean\n}\n\n/**\n * Props for the EmbeddedAgent component\n */\nexport interface EmbeddedAgentProps {\n\t/** Your WebMCP app ID - get one at webmcp.ai */\n\tappId: string\n\n\t/**\n\t * Development mode - use your own API keys for testing.\n\t * In production, leave this undefined to use your WebMCP plan.\n\t */\n\tdevMode?: DevModeConfig\n\n\t/**\n\t * Disable shadow DOM style isolation.\n\t * NOT RECOMMENDED - only use this if you need to customize internal styles\n\t * and understand the risks of style conflicts with the host page.\n\t *\n\t * When enabled:\n\t * - Styles are injected globally into document.head\n\t * - Host page styles may affect the agent widget\n\t * - Agent styles may leak to the host page\n\t *\n\t * @default false\n\t */\n\tdisableShadowDOM?: boolean\n}\n\n/**\n * EmbeddedAgent - Drop-in AI chat widget\n *\n * A fully self-contained chat widget with:\n * - MCP tool support (connect to any MCP server)\n * - Voice mode (talk to your AI assistant)\n * - Action-first UI (shows what the AI is doing, not just typing)\n * - Shadow DOM isolation (styles don't leak in or out)\n *\n * Just add your app ID and you're done. Everything else is handled.\n */\nexport const EmbeddedAgent: FC<EmbeddedAgentProps> = ({\n\tappId,\n\tdevMode,\n\tdisableShadowDOM = false,\n}) => {\n\t// API base: always production unless useLocalApi is explicitly set\n\tconst apiBase = getDefaultApiBase(devMode?.useLocalApi)\n\n\t// Log initialization\n\tif (typeof window !== 'undefined') {\n\t\tconsole.debug('[WebMCP] Initialized', {\n\t\t\tappId,\n\t\t\tmode: devMode ? 'development' : 'production',\n\t\t\tapiBase,\n\t\t\tshadowDOM: !disableShadowDOM,\n\t\t})\n\t}\n\n\t// Inject global styles only when shadow DOM is disabled (legacy mode)\n\t// With shadow DOM enabled, styles are injected into the shadow root instead\n\tif (disableShadowDOM) {\n\t\tinjectStyles()\n\t}\n\n\t// Voice is enabled if we have an OpenAI key in dev mode, or in production (uses plan)\n\tconst voiceEnabled = !devMode || !!devMode.openaiApiKey\n\n\t// Agent content - same regardless of shadow DOM usage\n\tconst agentContent = (\n\t\t<AgentProvider\n\t\t\tapiBase={apiBase}\n\t\t\ttokenEndpoint={voiceEnabled ? `${apiBase}/api/realtime/session` : undefined}\n\t\t\tautoConnectLocal={true}\n\t\t>\n\t\t\t<AgentPill position=\"bottom-center\" showVoiceButton={voiceEnabled} />\n\t\t</AgentProvider>\n\t)\n\n\t// Use shadow DOM for style isolation (default)\n\tif (!disableShadowDOM) {\n\t\treturn <ShadowRoot styles={WEBMCP_SHADOW_STYLES}>{agentContent}</ShadowRoot>\n\t}\n\n\t// Legacy mode: styles already injected above\n\treturn agentContent\n}\n\n/**\n * Web Component wrapper\n *\n * Converts EmbeddedAgent to a <webmcp-agent> custom element.\n * Attributes map to props in kebab-case (app-id -> appId).\n */\nconst WebMCPAgentElement = r2wc(EmbeddedAgent as unknown as Parameters<typeof r2wc>[0], {\n\tprops: {\n\t\tappId: 'string',\n\t\t// Note: devMode is JSON-stringified when passed as attribute\n\t\t// <webmcp-agent dev-mode='{\"anthropicApiKey\": \"sk-...\"}'>\n\t\tdevMode: 'json',\n\t\t// Disable shadow DOM isolation (not recommended)\n\t\t// <webmcp-agent disable-shadow-dom=\"true\">\n\t\tdisableShadowDOM: 'boolean',\n\t},\n})\n\n/**\n * Register the <webmcp-agent> custom element\n *\n * Called automatically when importing this module.\n *\n * With shadow DOM (default):\n * - Styles are injected into the shadow root, not the document\n * - Complete isolation from host page styles\n *\n * With disableShadowDOM:\n * - Styles are injected into document.head on first render\n * - May conflict with host page styles\n */\nexport function registerWebMCPAgent(tagName = 'webmcp-agent'): void {\n\tif (typeof window === 'undefined') return\n\n\t// Note: Styles are NOT injected here anymore.\n\t// With shadow DOM (default), styles are injected into the shadow root by ShadowRoot component.\n\t// With disableShadowDOM, styles are injected on first render by EmbeddedAgent component.\n\n\tif (!customElements.get(tagName)) {\n\t\tcustomElements.define(tagName, WebMCPAgentElement)\n\t}\n}\n\n// Auto-register on import\nregisterWebMCPAgent()\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAaA,iBAAiB;CAE7BC,wBAAwB;CAGxBC,OAAO;EAENC,aAAa;EAEbC,aAAa;EAEbC,uBAAuB;EACxB;CACA;;;;;;;;;;;AAYD,MAAaE,uBAAuB;CACnCC,WAAW;EAAEC,OAAO;GAAEC,KAAK;GAAIC,IAAI;GAAIC,KAAK;GAAI;EAAEC,QAAQ;GAAEH,KAAK;GAAIC,IAAI;GAAGC,KAAK;GAAG;EAAG;CACvFE,SAAS;EAAEL,OAAO;GAAEC,KAAK;GAAKC,IAAI;GAAIC,KAAK;GAAK;EAAEC,QAAQ;GAAEH,KAAK;GAAIC,IAAI;GAAGC,KAAK;GAAG;EAAG;CACvFG,WAAW,EAAEN,OAAO;EAAEC,KAAK;EAAKC,IAAI;EAAIC,KAAK;EAAI,EAAG;CACpDI,QAAQ,EAAEP,OAAO;EAAEC,KAAK;EAAKC,IAAI;EAAIC,KAAK;EAAI,EAAG;CACjDK,UAAU,EAAER,OAAO;EAAEC,KAAK;EAAKC,IAAI;EAAIC,KAAK;EAAI,EAAE;CAClD;;AAGD,SAAgBM,UAAUC,QAA0D;AACnF,QAAO,SAASA,OAAOT,IAAG,MAAOS,OAAOR,GAAE,MAAOQ,OAAOP,IAAG;;;AAI5D,MAAaQ,2BAA2B;;AAGxC,MAAaC,qBAAqB;;AAGlC,MAAaC,qBAAqB;CAEjCC,MAAM;CAENC,SAAS;CAETC,OAAO;CAEPC,OAAO;CACP;;AAkCD,MAAaa,qBAAqB;;AAGlC,MAAaC,YAAY;CAExBC,eAAe;CAEfC,eAAe;CAEfC,cAAc;CACd;;AAGD,MAAaC,mCAAmC;;AAGhD,MAAaC,kBAAkB;;;;;AAM/B,MAAaC,eAAe;CAE3BC,UAAU;CAEVC,QAAQ;CACR;;;;;AAUD,MAAaC,qBAAqB;CAEjCC,UAAU;CAEVC,cAAc;CAEdC,eAAe;CAEfC,SAAS;CACT;;;;AAKD,MAAaC,uBAAuB;CAEnCC,WAAW;CAEXC,oBAAoB;CACpB;;AAOD,MAAaC,WAAW;CAEvBC,WAAW;CAEXC,iBAAiB;CAEjBC,YAAY;CACZ;;AAGD,MAAaC,cAAc;CAC1BC,eAAe;CACfC,gBAAgB;CAChBC,iBAAiB;CACjBC,YAAY;CACZC,aAAa;CACbC,YAAY;CACZC,kBAAkB;CAClBC,oBAAoB;CACpB;;AAOD,MAAaC,6BAA6B;;AAgB1C,MAAaI,2BAA2B;;AAOxC,MAAaC,uBAAuB;;AAGpC,MAAaC,yBAAyB;;AAGtC,MAAaC,yBAAyB;;AAGtC,MAAaC,2BAA2B;;AAGxC,MAAaC,kCAAkC;;AAG/C,MAAaC,4BAA4B;;AAGzC,MAAaC,gCAAgC;;AAG7C,MAAaC,sCAAsC;;AAanD,MAAaG,4BAA4B;;AAGzC,MAAaC,uCAAuC;;;;;AAepD,MAAaI,6BAA6B;CAEzCC,SAAS;CAETC,cAAc;CACd;;;;;;AA4BD,MAAaI,wBACZ,OAAOC,WAAW,eACjBA,OAA0CC,qBAAqB;;;;;;;;;AAUjE,SAAgBC,SAASC,WAAmBC,SAAiBC,MAAsB;AAMlF,KAHC,OAAOL,WAAW,eACjBA,OAA0CC,qBAAqB,KAGhE,KAAII,SAASE,OACZC,SAAQC,IAAI,IAAIN,UAAS,IAAKC,WAAWC,KAAK;KAE9CG,SAAQC,IAAI,IAAIN,UAAS,IAAKC,UAAU;;;;;;;;;AC3T3C,SAAgBS,GAAG,GAAGC,QAA8B;AACnD,QAAOH,QAAQD,KAAKI,OAAO,CAAC;;;;;;;;;;;;;ACkB7B,MAAagB,eAAsCb,MAAKc,OAAA;CAAA,MAAAC,IAAAhB,EAAA,GAAA;CAAC,MAAA,EAAAS,SAAAC,WAAAC,YAAAI;CAA+B,IAAAE;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAP,EAAA,OAAAL,SAAA;AAElFM,QAAAO,SAAA;GAAC,MAAA,EAAAd,WAAAe,KAAA,GAAAC,UAAAF;AAA0C,UAC9C,oBAAA;IACY,WAAApB,GACV,sEACAO,UAAA,cAAA,WACAc,IACD;IAAC,GACGC;KACH;;AAECR,QAAAS,SAAA;GAAC,MAAA,EAAAjB,WAAAkB,OAAA,GAAAC,YAAAF;AAA0C,UAC9C,oBAAA;IACY,WAAAvB,GACV,qFACAO,UAAA,YAAA,aACAc,MACD;IAAC,GACGC;KACH;;AAECP,QAAAW,UAAA;GAAC,MAAA,EAAApB,WAAAqB,OAAA,GAAAC,YAAAF;AAA0C,UAC9C,oBAAA;IACY,WAAA1B,GACV,qFACAO,UAAA,YAAA,eACAc,MACD;IAAC,GACGC;KACH;;AAEAN,QAAAa,UAAA;GAAC,MAAA,EAAAvB,WAAAwB,OAAA,GAAAC,YAAAF;AAA0C,UAC7C,oBAAA;IACY,WAAA7B,GACV,iDACAO,UAAA,iBAAA,gBACAc,MACD;IAAC,GACGC;KACH;;AAEAL,QAAAe,UAAA;GAAC,MAAA,EAAA1B,WAAA2B,OAAA,GAAAC,YAAAF;AAA+D,UAClE,oBAAA;IACY,WAAAhC,GACV,wFACAO,UAAA,YAAA,WACAc,MACD;IAAC,GACGC;KACH;;AAECJ,QAAAiB,UAAA;GAAC,MAAA,EAAA7B,WAAA8B,OAAA,GAAAC,YAAAF;AAA0C,UAC9C,oBAAA;IACY,WAAAnC,GACV,0CACAO,UAAA,iBAAA,gBACAc,MACD;IAAC,GACGC;KACH;;AAECH,QAAAmB,UAAA;GAAC,MAAA,EAAAhC,WAAAiC,OAAA,GAAAC,YAAAF;AAA0C,UAC9C,oBAAA;IACY,WAAAtC,GACV,6CACAO,UAAA,iBAAA,gBACAc,MACD;IAAC,GACGC;KACH;;AACFV,IAAA,KAAAL;AAAAK,IAAA,KAAAC;AAAAD,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;AAAAL,IAAA,KAAAM;AAAAN,IAAA,KAAAO;QAAA;AAAAN,OAAAD,EAAA;AAAAE,OAAAF,EAAA;AAAAG,OAAAH,EAAA;AAAAI,OAAAJ,EAAA;AAAAK,OAAAL,EAAA;AAAAM,OAAAN,EAAA;AAAAO,OAAAP,EAAA;;CAAA,IAAAc;CAAA,IAAAN;CAAA,IAAAG;AAAA,KAAAX,EAAA,OAAAL,SAAA;AAIWa,QAAAS,UAAA;GAAC,MAAA,EAAAvB,WAAAmC,OAAA,GAAAC,YAAAb;AAA0C,UACtD,oBAAA;IACY,WAAA7B,GACV,0EACAO,UAAA,YAAA,WACAc,MACD;IAAC,GACGC;KACH;;AAEGC,QAAAS,UAAA;GAAC,MAAA,EAAA1B,WAAAqC,OAAA,GAAAC,YAAAZ;AAGN,OADiB,CAACX,OAAGyB,SAAW,YAAY,CAChC,QAEV,oBAAA;IACY,WAAA9C,GACV,gEACAO,UAAA,gBAAA,WACAc,MACD;IAAC,GACGC;KACH;AAEH,UAEA,oBAAA;IACY,WAAAtB,GAAG,+BAA+BO,UAAA,gBAAA,WAAqCc,MAAG;IAAC,GAClFC;KACH;;AAGCI,SAAAS,UAAA;GAAC,MAAA,EAAA7B,WAAAyC,OAAA,GAAAC,YAAAb;AAA0C,UAC/C,oBAAA;IACY,WAAAnC,GACV,8DACAO,UAAA,gBAAA,WACAc,MACD;IAAC,GACGC;KACH;;AACFV,IAAA,KAAAL;AAAAK,IAAA,KAAAc;AAAAd,IAAA,MAAAQ;AAAAR,IAAA,MAAAW;QAAA;AAAAG,QAAAd,EAAA;AAAAQ,OAAAR,EAAA;AAAAW,OAAAX,EAAA;;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,QAAAC,MAAAD,EAAA,QAAAc,OAAAd,EAAA,QAAAE,MAAAF,EAAA,QAAAG,MAAAH,EAAA,QAAAI,MAAAJ,EAAA,QAAAK,MAAAL,EAAA,QAAAM,MAAAN,EAAA,QAAAO,MAAAP,EAAA,QAAAQ,MAAAR,EAAA,QAAAW,IAAA;AAnH6BM,QAAA;GAAAoB,IAC1BpC;GASHqC,IACGpC;GASHqC,IACGpC;GASHqC,GACEpC;GASFqC,GACEpC;GASFqC,IACGpC;GASHqC,IACGpC;GASHqC,IACGC;GAEHC,YACWtC;GASXuC,MACKpC;GAqBLqC,KACIlC;GASJmC,IACGC;GAEHC,QACOC;GAEPC,IACGC;GAGJ;AAAAtD,IAAA,MAAAC;AAAAD,IAAA,MAAAc;AAAAd,IAAA,MAAAE;AAAAF,IAAA,MAAAG;AAAAH,IAAA,MAAAI;AAAAJ,IAAA,MAAAK;AAAAL,IAAA,MAAAM;AAAAN,IAAA,MAAAO;AAAAP,IAAA,MAAAQ;AAAAR,IAAA,MAAAW;AAAAX,IAAA,MAAAiB;OAAAA,OAAAjB,EAAA;CA7HD,MAAAuD,aAA+BtC;CAgIa,MAAAG,MAAAzB,WAAA;CAAkC,IAAA4B;AAAA,KAAAvB,EAAA,QAAAN,aAAAM,EAAA,QAAAoB,KAAA;AAA7DG,QAAAnC,GAAG,wBAAwBgC,KAAoC1B,UAAU;AAAAM,IAAA,MAAAN;AAAAM,IAAA,MAAAoB;AAAApB,IAAA,MAAAuB;OAAAA,OAAAvB,EAAA;CAAA,IAAA0B;AAAA,KAAA1B,EAAA,QAAAwD,OAAAC,IAAA,4BAAA,EAAA;AAC1D/B,QAAA,CAACvC,UAAU;AAAAa,IAAA,MAAA0B;OAAAA,OAAA1B,EAAA;CAAA,IAAA0D;AAAA,KAAA1D,EAAA,QAAAuD,cAAAvD,EAAA,QAAAP,SAAA;AAAzCiE,QAAA,oBAAC;GAA6B,eAAAhC;GAAyB6B;aACrD9D;IACc;AAAAO,IAAA,MAAAuD;AAAAvD,IAAA,MAAAP;AAAAO,IAAA,MAAA0D;OAAAA,OAAA1D,EAAA;CAAA,IAAA2D;AAAA,KAAA3D,EAAA,QAAAuB,OAAAvB,EAAA,QAAA0D,KAAA;AAHjBC,QAAA,oBAAA;GAAgB,WAAApC;aACfmC;IAGK;AAAA1D,IAAA,MAAAuB;AAAAvB,IAAA,MAAA0D;AAAA1D,IAAA,MAAA2D;OAAAA,OAAA3D,EAAA;AAAA,QAJN2D;EAMA;AAEF7D,aAAa8D,cAAc;AAzI6B,SAAAf,SAAA9C,IAAA;CAwEjD,MAAA,EAAAL,WAAAmE,OAAA,GAAAC,YAAA/D;AAA0C,QAC9C,oBAAA;EAAe,WAAAX,GAAG,aAAaqB,MAAG;EAAC,GAAMC;GAAS;;AAzEG,SAAAwC,UAAAnD,IAAA;CAqHjD,MAAA,EAAAL,WAAAqE,QAAA,GAAAC,aAAAjE;AAA0C,QAC9C,oBAAA;EAAe,WAAAX,GAAG,kCAAkCqB,OAAG;EAAC,GAAMC;GAAS;;AAtHlB,SAAA0C,SAAArD,IAAA;CAwH7C,MAAA,EAAAL,WAAAuE,QAAA,GAAAC,aAAAnE;AAA0C,QAClD,oBAAA;EAAmB,WAAAX,GAAG,+BAA+BqB,OAAG;EAAC,GAAMC;GAAS;;AAzHnB,SAAA4C,SAAAvD,IAAA;CA2HjD,MAAA,EAAAL,WAAAyE,QAAA,GAAAC,aAAArE;AAA0C,QAC9C,oBAAA;EAAe,WAAAX,GAAG,oBAAoBqB,OAAG;EAAC,GAAMC;GAAS;;;;;;;;;;ACvH5D,MAAaqF,gBAAsCC,OAAA;CAAA,MAAAC,IAAA3B,EAAA,GAAA;CAAC,MAAA,EAAAe,SAAAC,WAAAC,SAAAC,SAAAE,WAAAC,cAAAO,OAAAF;CAMnD,MAAAL,eAAAO,OAAAC,SAAA,QAAAD;CAEA,MAAA,CAAAE,QAAAC,aAA4BvB,SAAS,MAAM;CAAA,IAAAwB;AAAA,KAAAL,EAAA,OAAAZ,SAAA;AAEZiB,OAAA,YAAA;AAC9B,OAAA;AACC,UAAMC,UAASC,UAAUC,UAAWpB,QAAQ;AAC5CgB,cAAU,KAAK;AACfK,qBAAiBL,UAAU,MAAM,EAAEtB,UAAS4B,aAAc;WAAA;;AAI3DV,IAAA,KAAAZ;AAAAY,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CARD,MAAAW,aAAmBN;CAQN,IAAAO;AAAA,KAAAZ,EAAA,OAAAP,WAAA;AAGImB,OAAA7B,GAAG,iCAAiC,cAAcU,UAAU;AAAAO,IAAA,KAAAP;AAAAO,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAW,YAAA;AAIjEE,QAAAC,MAAA;AACRA,KAACC,iBAAkB;AACdJ,eAAY;;AACjBX,IAAA,KAAAW;AAAAX,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,OAAAiB,OAAAC,IAAA,4BAAA,EAAA;AACUF,OAAAjC,GACV,mCACA,wBAEA,sDACA,wCACA,qCACA,8BACA;AAAAiB,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CACW,MAAAmB,KAAAhB,SAAA,YAAA;CAAoC,IAAAiB;AAAA,KAAApB,EAAA,OAAAG,QAAA;AAE/CiB,OAAAjB,SACA,oBAAC,SAAgB,WAAA,4CAGjB,GADA,oBAAC,QAAe,WAAA,8BAChB;AAAAH,IAAA,KAAAG;AAAAH,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,OAAAa,MAAAb,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,IAAA;AArBFC,OAAA,oBAAA;GACM,MAAA;GACI,SAAAR;GAIE,WAAAG;GASC,cAAAG;aAEXC;IAKO;AAAApB,IAAA,KAAAa;AAAAb,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,QAAAV,WAAAU,EAAA,QAAAX,WAAA;AAGRiC,QAACjC,aAAAC,YACD,qBAAA;GAAe,WAAA;;IACbD,aAAa,oBAAC,gBAAuB,WAAA,8BAA6B;IAClEC,WAAW,oBAAC,eAAsB,WAAA,8BAA6B;IAChE,oBAAA;KAAgB,WAAA;eACdD,YAAA,SAAA;MAEH;;IACA;AAAAW,IAAA,MAAAV;AAAAU,IAAA,MAAAX;AAAAW,IAAA,MAAAsB;OAAAA,MAAAtB,EAAA;CAMC,MAAAuB,MAAA,CAAC7B,gBAAD;CAAuC,IAAA8B;AAAA,KAAAxB,EAAA,QAAAuB,KAAA;AAF7BC,QAAAzC,GACV,+CACAwC,IACA;AAAAvB,IAAA,MAAAuB;AAAAvB,IAAA,MAAAwB;OAAAA,OAAAxB,EAAA;CAEkE,MAAAyB,MAAA,CAAC/B;CAAY,IAAAgC;AAAA,KAAA1B,EAAA,QAAAZ,WAAAY,EAAA,QAAAyB,KAAA;AAAhFC,QAAA,oBAAC;GAAsBtC,SAAAA;GAAmB,WAAA;GAAyB,SAAAqC;IAAiB;AAAAzB,IAAA,MAAAZ;AAAAY,IAAA,MAAAyB;AAAAzB,IAAA,MAAA0B;OAAAA,OAAA1B,EAAA;CAAA,IAAA2B;AAAA,KAAA3B,EAAA,QAAAwB,OAAAxB,EAAA,QAAA0B,KAAA;AANrFC,QAAA,oBAAA;GACY,WAAAH;aAKXE;IACK;AAAA1B,IAAA,MAAAwB;AAAAxB,IAAA,MAAA0B;AAAA1B,IAAA,MAAA2B;OAAAA,OAAA3B,EAAA;CAAA,IAAA4B;AAAA,KAAA5B,EAAA,QAAAT,SAAA;AAGLqC,QAAArC,WAAWA,QAAOsC,SAAU,KAC5B,oBAAA;GAAe,WAAA;aACbtC,QAAOuC,IAAKC,SAiBZ;IAEF;AAAA/B,IAAA,MAAAT;AAAAS,IAAA,MAAA4B;OAAAA,OAAA5B,EAAA;CAAA,IAAAgC;AAAA,KAAAhC,EAAA,QAAA2B,OAAA3B,EAAA,QAAA4B,OAAA5B,EAAA,QAAAY,MAAAZ,EAAA,QAAAqB,MAAArB,EAAA,QAAAsB,IAAA;AArEFU,QAAA,qBAAA;GAAgB,WAAApB;;IAEfS;IAyBCC;IAWDK;IAUCC;;IAsBI;AAAA5B,IAAA,MAAA2B;AAAA3B,IAAA,MAAA4B;AAAA5B,IAAA,MAAAY;AAAAZ,IAAA,MAAAqB;AAAArB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAgC;OAAAA,OAAAhC,EAAA;AAAA,QAtENgC;;;;;;AAmFF,SAAOI,mBAAA;CAAA,MAAApC,IAAA3B,EAAA,EAAA;CAEN,MAAAgE,WAAiB/D,UAAUgE,UAA4B;CAAA,IAAAvC;AAAA,KAAAC,EAAA,OAAAqC,UAAA;AAAAE,OAAA;AAGtD,OAAI,CAACF,YAAYA,SAAQR,WAAY,GAAC;AAAE9B,SAAO;AAAP,UAAAwC;;GAExC,MAAAC,uBAA6B,CAAA,GAAIH,SAAS,CAAAI,SAAU,CAAAC,KAAMC,SAA8B;AAExF,OAAI,CAACH,sBAAoB;AAAEzC,SAAO;AAAP,UAAAwC;;GAI3B,MAAAS,WADkBR,qBAAoBK,QAAQC,OAAQC,SAAwC,CACpEE,GAAI,GAAG;AAEjC,OAAI,CAACD,UAAQ;AAAEjD,SAAO;AAAP,UAAAwC;;AAEfxC,QAAOiD,SAAQb;;AAAKnC,IAAA,KAAAqC;AAAArC,IAAA,KAAAD;OAAAA,MAAAC,EAAA;AAAA,QAbdD;;;;;AAJD,SAAAgD,SAAA3E,KAAA;AAAA,QAYuEA,IAAC8D,SAAU;;AAZlF,SAAAS,SAAAO,GAAA;AAAA,QAO4DA,EAACC,SAAU;;AAPvE,SAAAb,UAAAc,QAAA;AAAA,QAEiCA,OAAMf;;AAsB9C,MAAagB,kBAA6CtD,OAAA;CAAA,MAAAC,IAAA3B,EAAA,EAAA;CAAC,MAAA,EAAAoB,cAAAM;CAAa,IAAAE;AAAA,KAAAD,EAAA,OAAAP,WAAA;AAEtDQ,OAAAlB,GAAG,oBAAoBU,UAAU;AAAAO,IAAA,KAAAP;AAAAO,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAA,IAAAK;CAAA,IAAAO;AAAA,KAAAZ,EAAA,OAAAiB,OAAAC,IAAA,4BAAA,EAAA;AAChDb,OAAA,oBAAA;GAAc,WAAA;aAAwC;IAAW;AACjEO,OAAA,oBAAA;GAAa,WAAA;aAAwB;IAA6B;AAAAZ,IAAA,KAAAK;AAAAL,IAAA,KAAAY;QAAA;AAAAP,OAAAL,EAAA;AAAAY,OAAAZ,EAAA;;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAC,IAAA;AAFnEY,OAAA,qBAAA;GAAgB,WAAAZ;cACfI,IACAO;IACK;AAAAZ,IAAA,KAAAC;AAAAD,IAAA,KAAAa;OAAAA,MAAAb,EAAA;AAAA,QAHNa;;AAlIiD,SAAAkB,SAAA+B,QAAAC,GAAA;AAAA,QAwE7C,oBAAA;EAEU,UAAAC,QAAA;AACRlD,OAACC,iBAAkB;AACnB+C,UAAMlE,SAAU;;EAEN,WAAAb,GACV,6CACA,kCACA+E,OAAMjE,YAAa,YAAnB,8CAAA,8CAGD;YAECiE,OAAMnE;IAbFoE,EAcG;;;;;;;;;;;;;;;;;;;;;;ACtGf,SAAgBE,iBAAiBC,MAAcC,cAAc,OAAe;CAE3E,MAAMC,QAAQF,KACZG,QAAQ,mBAAmB,QAAQ,CACnCA,QAAQ,MAAM,IAAI,CAClBC,aAAa,CACbC,MAAM,IAAI;AAEZ,KAAIH,MAAMI,WAAW,EAAG,QAAON;AAE/B,KAAIC,aAAa;EAEhB,MAAMM,OAAOL,MAAM;EACnB,MAAMM,kBAAkBD,KAAKE,SAAS,IAAI,GAAGF,KAAKG,MAAM,GAAG,GAAG,GAAG,QAAQH,OAAO;AAChFL,QAAM,KAAKM,gBAAgBG,OAAO,EAAE,CAACC,aAAa,GAAGJ,gBAAgBE,MAAM,EAAE;OAG7ER,OAAM,KAAKA,MAAM,GAAGS,OAAO,EAAE,CAACC,aAAa,GAAGV,MAAM,GAAGQ,MAAM,EAAE;AAGhE,QAAOR,MAAMW,KAAK,IAAI;;;;;;;;;AAUvB,SAAgBC,WAAWC,MAAuC;CACjE,MAAME,UAAUC,OAAOD,QAAQF,KAAK;AACpC,KAAIE,QAAQX,WAAW,EAAG,QAAO;AAEjC,QAAOW,QACLE,KAAK,CAACC,KAAKC,WAAW;AAOtB,SAAO,GAAGD,IAAG,IALZ,OAAOC,UAAU,WACdA,MAAMf,SAAS,KACd,IAAIe,MAAMX,MAAM,GAAG,GAAG,CAAA,QACtB,IAAIW,MAAK,KACVE,KAAKC,UAAUH,MAAM;GAExB,CACDR,KAAK,KAAK;;;;;;AAOb,MAAaY,sBAAsB;;;;;;;;AASnC,SAAgBC,2BAA2BC,QAAwB;AAClE,QAAO,gBAAgBA;;;;;;;;AC/BxB,SAASsB,mBAAmBF,UAAiD;AAC5E,KAAI,CAACA,YAAY,OAAOA,aAAa,SAAU,QAAO;CACtD,MAAMG,IAAIH;AACV,QACC,OAAOG,EAAEV,cAAc,YACvB,OAAOU,EAAET,aAAa,YACtB,OAAOS,EAAER,aAAa;;;;;;;;;;;AAaxB,SAAOU,aAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAEN,MAAAC,WAAiB3B,UAAU4B,SAA4B;CAAA,IAAAC;AAAAC,MAAA;AAGtD,MAAI,CAACH,YAAYA,SAAQI,WAAY,GAAC;GAAA,IAAAC;AAAA,OAAAP,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAC9BF,SAAA,EAAE;AAAAP,MAAA,KAAAO;SAAAA,MAAAP,EAAA;AAATI,QAAOG;AAAP,SAAAF;;EACA,IAAAK;AAAA,MAAAV,EAAA,OAAAE,UAAA;AAEDQ,aAA0B,EAAE;AAE5B,QAAK,MAAAC,WAAiBT,UAAQ;AAC7B,QAAIS,QAAOC,SAAU,YAAa;AAElC,SAAK,MAAAC,QAAcF,QAAOG,SAAQ;AACjC,SAAID,KAAIrB,SAAU,YAAa;KAE/B,MAAAuB,WAAiBF;KACjB,MAAAG,aAAmBD,SAAQ9B,WAAYgC;KACvC,MAAAC,WACCH,SAAQpB,YAAa,QACpBoB,SAAQ9B,UACR,OAAO8B,SAAQ9B,WAAY,YAC3B,WAAY8B,SAAQ9B;KAGtB,MAAAkC,iBAAuBJ,SAAQhC,QAAaS,SAAK;KAE7CT,IAAAA;AACJ,SAAImC,SACHnC,UAASA;cACCiC,WACVjC,UAASA;cACCoC,eACVpC,UAASA;SAETA,UAASA;KAIV,MAAAqC,WAAiBxB,mBAAmBmB,SAAQrB,SAA0C,GAA7BqB,SAAQrB,WAAhDuB;AAEjBP,aAAOW,KAAM;MAAAzC,IACRmC,SAAQtB;MAAWX,UACbiC,SAAQjC;MAASD,OACpBJ,iBAAiBsC,SAAQjC,UAAWC,WAAW,UAAU;MAAAA;MAAAC,MAE1D+B,SAAQ/B;MAAKC,QACX8B,SAAQ9B;MAAOC,OAChBgC,WAAWI,OAAQP,SAAQ9B,OAAkCC,MAAoB,GAAjF+B;MAAiF9B,WAE7EiC,UAAQjC;MAAWC,UACpBgC,UAAQhC;MAAUC,UAClB+B,UAAQ/B;MAAUC,YAChB8B,UAAQ9B;MACpB,CAAC;;;AAEHU,KAAA,KAAAE;AAAAF,KAAA,KAAAU;QAAAA,WAAAV,EAAA;AAEDI,OAAOM;;AAAO,QAvDRN;;;;;AAJD,SAAAD,SAAAoB,QAAA;AAAA,QAEiCA,OAAMrB;;AAgE9C,SAAOsB,mBAAA;CAAA,MAAAxB,IAAAC,EAAA,EAAA;CACN,MAAAS,UAAgBX,YAAY;CAAA,IAAAK;AAAA,KAAAJ,EAAA,OAAAU,SAAA;AACrBN,OAAAM,QAAOe,KAAMC,SAAsC,IAAnD;AAAmD1B,IAAA,KAAAU;AAAAV,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAAnDI;;;;;AAFD,SAAAsB,SAAA7B,GAAA;AAAA,QAEqBA,EAACd,WAAY;;AAMzC,SAAO4C,iBAAAvB,IAAA;CAAA,MAAAJ,IAAAC,EAAA,EAAA;CAA0B,MAAA2B,QAAAxB,OAAAa,SAAA,IAAAb;CAChC,MAAAM,UAAgBX,YAAY;CAAA,IAAAQ;AAAA,KAAAP,EAAA,OAAAU,WAAAV,EAAA,OAAA4B,OAAA;AACrBrB,OAAAG,QAAOmB,OAAQC,SAAsD,CAAAC,MAAO,CAACH,MAAM;AAAA5B,IAAA,KAAAU;AAAAV,IAAA,KAAA4B;AAAA5B,IAAA,KAAAO;OAAAA,MAAAP,EAAA;AAAA,QAAnFO;;;;;AAFD,SAAAuB,SAAAjC,GAAA;AAAA,QAEuBA,EAACd,WAAY,aAAac,EAACd,WAAY;;AAMrE,SAAOiD,yBAAA;CAAA,MAAAhC,IAAAC,EAAA,EAAA;CACN,MAAAS,UAAgBX,YAAY;CAAA,IAAAK;AAAA,KAAAJ,EAAA,OAAAU,SAAA;AAErBN,OADWM,QAAOmB,OAAQK,SAAsD,CACvEC,GAAI,GAAW,IAAxB;AAAwBnC,IAAA,KAAAU;AAAAV,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAAxBI;;AAHD,SAAA8B,SAAArC,GAAA;AAAA,QAEkCA,EAACd,WAAY,aAAac,EAACd,WAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChHhF,SAAgB2D,mBACfC,QACAC,gBAA+B,QACnB;AACZ,KAAID,OAAOE,SAAS,MACnB,QAAO,IAAIT,mBAAmB;EAC7BU,cAAcH,OAAOG,gBAAgBC,OAAOC,SAASC;EACrDC,WAAWP,OAAOO,aAAa;EAC/B,CAAC;CAIH,MAAMC,YAAY,IAAIC,IAAIT,OAAOU,IAAI;CACrC,MAAMC,UAAkC;EACvCE,QAAQ;EACR,GAAIb,OAAOc,iBAAiB,EAAE;EAC9B;AAED,KAAId,OAAOe,UACVJ,SAAQK,gBAAgB,UAAUhB,OAAOe;CAG1C,MAAME,mBAAmB,EACxBC,aAAa,EAAEP,SAAQ,EACvB;AAED,KAAIV,kBAAkB,MACrB,QAAO,IAAIP,mBAAmBc,WAAWS,iBAAiB;AAG3D,QAAO,IAAItB,8BAA8Ba,WAAWS,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;AC1BtE,MAAaoC,eAAe;AAqE5B,MAAM+B,kBAAkBlD,cAA2C,KAAK;AAYxE,SAAgBwD,iBAAiB,EAChCJ,UACAC,mBAAmB,MACnBC,eACAC,mBACyB;CAEzB,MAAME,aAAapD,uBAAiC,IAAI+B,KAAK,CAAC;CAG9D,MAAMsB,mBAAmBrD,uBAAsC,IAAI+B,KAAK,CAAC;CAGzE,MAAMuB,mBAAmBtD,OAAO,EAAE;CAGlC,MAAM,GAAGuD,eAAetD,SAAS,EAAE,CAAC;CAGpC,MAAM,CAACuD,WAAWC,gBAAgBxD,SAA2B,EAAE,CAAC;CAGhE,MAAM,CAACyD,aAAaC,kBAAkB1D,SAAmB,EAAE,CAAC;;;;;CAM5D,MAAM2D,qBAAqBhE,aAAaiE,iBAAmC;EAC1E,MAAMC,mBAAmB,IAAIC,IAAIF,aAAaG,KAAKC,MAAMA,EAAEzB,KAAK,CAAC;AAEjEa,mBAAiBa,QAAQC,SAASC,MAAMC,WAAW;AAClD,OAAI,CAACP,iBAAiBQ,IAAIF,KAAK5C,SAAS,EAAE;AACzC+C,YAAQC,KACP,mDAAmDJ,KAAK5C,SAAQ,aAAc6C,OAAM,GACpF;AACDD,SAAK1C,gBAAgB+C,sBAAM,IAAIC,MAAM,SAASN,KAAK5C,SAAQ,0BAA2B,CAAC;AACvF6B,qBAAiBa,QAAQS,OAAON,OAAO;;IAEvC;IACA,EAAE,CAAC;;;;CAKN,MAAMO,eAAehF,kBAAkB;EACtC,MAAMiF,WAA6B,EAAE;AAErCzB,aAAWc,QAAQC,SAASW,WAAW;AACtCA,UAAOjD,MAAMsC,SAASY,SAAS;AAC9BF,aAASG,KAAK;KACb,GAAGD;KACHE,WAAWH,OAAO7C;KAClB,CAAC;KACD;IACD;AAGF2B,qBAAmBiB,SAAS;AAE5BpB,eAAaoB,SAAS;IACpB,CAACjB,mBAAmB,CAAC;;;;CAKxB,MAAMsB,iBAAiBtF,kBAAkB;EACxC,MAAMuF,aAAuB,EAAE;AAE/B/B,aAAWc,QAAQC,SAASW,aAAW;AACtCA,YAAOxD,QAAQ6C,SAASiB,WAAW;AAClCD,eAAWH,KAAKI,OAAO;KACtB;IACD;AAEFzB,iBAAewB,WAAW;IACxB,EAAE,CAAC;;;;CAKN,MAAME,kBAAkBzF,aAAakF,aAAmC;AACvE,SAAO;GACN7C,IAAI6C,SAAO7C;GACXC,QAAQ4C,SAAO5C;GACfoD,OAAOR,SAAOQ;GACdC,OAAOT,SAAOS;GACd1D,OAAOiD,SAAOjD;GACdT,WAAW0D,SAAO1D;GAClBC,mBAAmByD,SAAOzD;GAC1BC,SAASwD,SAAOxD;GAChB;IACC,EAAE,CAAC;;;;CAKN,MAAMU,YAAYpC,YACjB,OAAOqC,IAAYC,WAA2C;AAE7D,MAAIkB,WAAWc,QAAQI,IAAIrC,GAAG,CAC7B,OAAMG,aAAaH,GAAG;EAIvB,MAAMuD,cAA2B;GAChCvD;GACAC;GACAoD,OAAO;GACPC,OAAO;GACP1D,OAAO,EAAE;GACTT,WAAW,EAAE;GACbC,mBAAmB,EAAE;GACrBC,SAAS,EAAE;GACXJ,QAAQ;GACRC,WAAW;GACX;AAEDiC,aAAWc,QAAQuB,IAAIxD,IAAIuD,YAAY;AACvCjC,cAAY,EAAE,CAAC;AAEf,MAAI;GAEH,MAAMrC,SAAS,IAAI1B,OAAO;IACzBgD,MAAM,cAAcP;IACpByD,SAAS;IACT,CAAC;GAEF,MAAMvE,YAAYhB,mBAAmB+B,OAAO;AAG5C,SAAMhB,OAAOyE,QAAQxE,UAAU;AAG/BqE,eAAYtE,SAASA;AACrBsE,eAAYrE,YAAYA;GAGxB,MAAM,EAAEU,UAAU,MAAMX,OAAO0E,WAAW;AAC1CJ,eAAY3D,QAAQA;AAGpB,OAAI;IACH,MAAM,EAAEP,YAAY,MAAMJ,OAAO2E,aAAa;AAC9CL,gBAAYlE,UAAUA;YACdwE,OAAK;AACbvB,YAAQC,KAAK,qBAAqBvC,GAAE,qCAAsC6D,MAAI;AAC9EN,gBAAYlE,UAAU,EAAE;;AAGzBkE,eAAYF,QAAQ;AAGpBpE,UAAO6E,uBAAuBrG,mCAAmC,YAAY;AAC5E,QAAI;AAEH8F,iBAAY3D,SADI,MAAMX,OAAO0E,WAAW,EACZ/D;AAC5B+C,mBAAc;AACdrB,iBAAY,EAAE,CAAC;aACPuC,OAAK;AACbvB,aAAQgB,MAAM,qBAAqBtD,GAAE,4BAA6B6D,MAAI;;KAEtE;AAGF5E,UAAO6E,uBAAuBtG,qCAAqC,YAAY;AAC9E,QAAI;AAEH+F,iBAAYlE,WADI,MAAMJ,OAAO2E,aAAa,EACZvE;AAC9B4D,qBAAgB;AAChB3B,iBAAY,EAAE,CAAC;aACPuC,OAAK;AACbvB,aAAQgB,MAAM,qBAAqBtD,GAAE,8BAA+B6D,MAAI;;KAExE;AAEFlB,iBAAc;AACdM,mBAAgB;AAChB3B,eAAY,EAAE,CAAC;WACPuC,KAAK;GACb,MAAMP,QAAQO,eAAepB,QAAQoB,MAAM,IAAIpB,MAAMuB,OAAOH,IAAI,CAAC;AACjEvB,WAAQgB,MAAM,qBAAqBtD,GAAE,uBAAwBsD,MAAM;AAEnEC,eAAYF,QAAQ;AACpBE,eAAYD,QAAQA;AACpBhC,eAAY,EAAE,CAAC;;IAGjB,CAACqB,cAAcM,eAChB,CAAC;;;;CAKD,MAAM9C,eAAexC,YACpB,OAAOqC,SAA8B;EACpC,MAAM6C,WAAS1B,WAAWc,QAAQgC,IAAIjE,KAAG;AACzC,MAAI,CAAC6C,SAAQ;AAGb,MAAIA,SAAO5D,OACV,KAAI;AACH,SAAM4D,SAAO5D,OAAOiF,OAAO;WACnBL,OAAK;AACbvB,WAAQgB,MAAM,qBAAqBtD,KAAE,0BAA2B6D,MAAI;;AAItE,MAAIhB,SAAO3D,UACV,KAAI;AACH,SAAM2D,SAAO3D,UAAUgF,OAAO;WACtBL,OAAK;AACbvB,WAAQgB,MAAM,qBAAqBtD,KAAE,6BAA8B6D,MAAI;;AAIzE1C,aAAWc,QAAQS,OAAO1C,KAAG;AAC7B2C,gBAAc;AACdM,kBAAgB;AAChB3B,cAAY,EAAE,CAAC;IAEhB,CAACqB,cAAcM,eAChB,CAAC;;;;CAKD,MAAM7C,YAAYzC,aAChBqC,SAAsC;EACtC,MAAM6C,WAAS1B,WAAWc,QAAQgC,IAAIjE,KAAG;AACzC,SAAO6C,WAASO,gBAAgBP,SAAO,GAAGsB;IAE3C,CAACf,gBACF,CAAC;;;;CAKD,MAAM/C,cAAc1C,aAAaqC,SAAwB;AAExD,SADemB,WAAWc,QAAQgC,IAAIjE,KAAG,EAC1BqD,UAAU;IACvB,EAAE,CAAC;;;;;CAMN,MAAM3C,mBAAmB/C,YACxB,OACC6B,UACAe,MACAC,SAC6B;EAC7B,MAAMqC,WAAS1B,WAAWc,QAAQgC,IAAIzE,SAAS;AAC/C,MAAI,CAACqD,UAAQ5D,OACZ,OAAM,IAAIwD,MAAM,WAAWjD,SAAQ,iBAAkB;EAItD,MAAM4C,WAAS,GAAG5C,SAAQ,GAAIe,KAAI,GAAI,EAAEc,iBAAiBY;EACzD,MAAMxC,kBAAkB,IAAIC,iBAAiB;AAG7C0B,mBAAiBa,QAAQuB,IAAIpB,UAAQ;GACpC7C,UAAUgB;GACVf;GACAC;GACA,CAAC;AAEF,MAAI;GAEH,MAAM2E,eAAe,IAAIlE,SAAgBmE,GAAGC,WAAW;IACtD,MAAMC,SAAS9E,gBAAgB8E;AAG/B,QAAIA,OAAOC,SAAS;AACnBF,YAAOC,OAAOE,0BAAU,IAAIhC,MAAM,SAASlC,KAAI,oBAAqB,CAAC;AACrE;;AAIDgE,WAAOG,iBACN,eACM;AACLJ,YAAOC,OAAOE,0BAAU,IAAIhC,MAAM,SAASlC,KAAI,oBAAqB,CAAC;OAEtE,EAAEoE,MAAM,MACT,CAAC;KACA;AAQF,UALe,MAAMzE,QAAQ2E,KAAK,CACjChC,SAAO5D,OAAOqB,SAAS;IAAEC;IAAMuE,WAAWtE;IAAM,CAAC,EACjD4D,aACA,CAAC;WAGMd,SAAO;AAEf,OAAI7D,gBAAgB8E,OAAOC,QAE1B,QAAO;IACNO,SAAS,CACR;KACCC,MAAM;KACNE,MAAM,sBAAsB5B,mBAAiBb,QAAQa,QAAM6B,UAAUnB,OAAOV,QAAM;KAClF,CACD;IACD8B,SAAS;IACT;AAEF,SAAM9B;YACG;AAETlC,oBAAiBa,QAAQS,OAAON,SAAO;;IAGzC,EACD,CAAC;;;;CAKD,MAAM9B,WAAW3C,YAChB,OAAO4C,QAAcC,WAA2D;EAE/E,MAAMsC,SAAOvB,UAAU8D,MAAMrD,QAAMA,IAAEzB,SAASA,OAAK;AACnD,MAAI,CAACuC,OACJ,OAAM,IAAIL,MAAM,SAASlC,OAAI,aAAc;AAG5C,SAAOG,iBAAiBoC,OAAKE,WAAWzC,QAAMC,OAAK;IAEpD,CAACe,WAAWb,iBACb,CAAC;;;;CAKD,MAAMC,YAAYhD,YACjB,OAAO4C,QAAcC,WAA4D;AAEhF,OAAK,MAAMqC,YAAU1B,WAAWc,QAAQqD,QAAQ,CAE/C,KADkBzC,SAAOxD,QAAQmG,MAAMC,MAAMA,EAAElF,SAASA,OAAK,IAC5CsC,SAAO5D,OACvB,QAAQ,MAAM4D,SAAO5D,OAAO0B,UAAU;GAAEJ,MAAAA;GAAMuE,WAAWtE;GAAM,CAAC;AAGlE,QAAM,IAAIiC,MAAM,WAAWlC,OAAI,aAAc;IAE9C,EACD,CAAC;;;;;;;;;;CAWD,MAAMV,UAAU/B,cAAc;EAC7B,MAAM4H,gCAAgB,IAAI5F,KAAwB;AAClDqB,aAAWc,QAAQC,SAASW,aAAW;AACtC6C,iBAAclC,IAAIX,SAAO7C,IAAIoD,gBAAgBP,SAAO,CAAC;IACpD;AACF,SAAO6C;IACL;EAACnE;EAAWE;EAAa2B;EAAgB,CAAC;AAG7CvF,iBAAgB;AACf,MAAIkD,kBAAkB;GACrB,MAAM4E,QAAQC,iBAAiB;AAC9B,IAAK7F,UAAUlB,cAAc,EAAEmG,MAAM,OAAO,CAAC;MAC3C/G,yBAAyB;AAC5B,gBAAa4H,aAAaF,MAAM;;IAE/B,CAAC5E,kBAAkBhB,UAAU,CAAC;AAGjClC,iBAAgB;AACfmD,kBAAgBO,UAAU;IACxB,CAACA,WAAWP,cAAc,CAAC;AAG9BnD,iBAAgB;AACfoD,oBAAkBQ,YAAY;IAC5B,CAACA,aAAaR,gBAAgB,CAAC;AAGlCpD,iBAAgB;EACf,MAAMgC,YAAUsB;EAChB,MAAM2E,gBAAgB1E;AACtB,eAAa;AAGZ0E,iBAAc7D,QAAQC,SAASC,WAAS;AACvCA,WAAK1C,gBAAgB+C,sBAAM,IAAIC,MAAM,qBAAqB,CAAC;KAC1D;AACFqD,iBAAc7D,QAAQ8D,OAAO;AAG7BlG,aAAQoC,QAAQC,SAASW,aAAW;AACnC,QAAIA,SAAO5D,OACV,CAAK4D,SAAO5D,OAAOiF,OAAO,CAAC8B,MAAM1D,QAAQgB,MAAM;AAEhD,QAAIT,SAAO3D,UACV,CAAK2D,SAAO3D,UAAUgF,OAAO,CAAC8B,MAAM1D,QAAQgB,MAAM;KAElD;AACFzD,aAAQoC,QAAQ8D,OAAO;;IAEtB,EAAE,CAAC;CAEN,MAAME,QAAQnI,eACN;EACN8B,OAAO2B;EACPlC,SAASoC;EACT5B;EACAE;EACAI;EACAC;EACAC;EACAC;EACAI;EACAC;EACA,GACD;EACCY;EACAE;EACA5B;EACAE;EACAI;EACAC;EACAC;EACAC;EACAI;EACAC;EAEF,CAAC;AAED,QAAO,oBAAC,gBAAgB;EAAgBsF;EAAQnF;GAAoC;;;;;AAMrF,SAAOoF,cAAA;CACN,MAAAC,UAAgBvI,WAAWgD,gBAAgB;AAC3C,KAAI,CAACuF,QACJ,OAAM,IAAI1D,MAAM,sDAAsD;AACtE,QACM0D;;;;;AAMR,SAAOC,sBAAA;AAAA,QACCxI,WAAWgD,gBAAgB;;;;;;;;;;;;;;ACziBnC,SAAgBiG,oBAAoBC,eAAqD;CACxF,MAAMC,WAAWD,cAAcE,UAAU,CAACD;CAC1C,MAAME,SAAgC,EAAE;AAExC,MAAK,MAAMC,OAAOH,UAAU;AAE3B,MAAIG,IAAIC,SAAS,YAAa;EAG9B,MAAMC,eAAeF;AAGrB,MAAIE,aAAaC,QAAQC,SAAS,kBAAmB;AAGrD,OAAK,MAAMC,QAAQH,aAAaI,SAAS;AACxC,OAAID,KAAKD,SAAS,YAAa;AAC/B,OAAIC,KAAKN,WAAWQ,OAAW;AAE/BR,UAAOS,KAAK;IACXlB,WAAWU,IAAIS;IACflB,YAAYc,KAAKd;IACjBC,UAAUa,KAAKb;IACfC,MAAOY,KAAKZ,QAAoC,EAAC;IACjD,CAAC;;;AAIJ,QAAOM;;;;;;;;;AAUR,SAAgBW,0BACfd,eACAJ,UACwB;AACxB,QAAOG,oBAAoBC,cAAc,CAACe,QAAQC,OAAOA,GAAGpB,aAAaA,SAAS;;;;;;;;;;;AAYnF,SAAgBqB,uBACfjB,eACAN,WACAC,YACAQ,QACU;CACV,MAAMe,iBAAiBlB,cAAcmB,eAAezB,UAAU;AAC9D,KAAI,CAACwB,eACJ,QAAO;AAQR,KAAI,CALiBA,eAAehB,UAAU,CACVQ,QAAQY,MAC1Cb,SACAA,KAAKD,SAAS,eAAeC,KAAKd,eAAeA,cAAcc,KAAKN,WAAWQ,OAChF,CAEA,QAAO;AAGR,KAAI;AAEHY,EADoBL,eAAeM,2BAA2B7B,WAAW,CAC7D8B,cAActB,OAAO;AACjC,SAAO;UACCuB,OAAO;AAGf,MAAIA,iBAAiBC,SAASD,MAAME,YAAY,mCAC/C,QAAO;AAER,QAAMF;;;;;;;;;;;AAYR,SAAgBG,iCACf7B,eACAJ,UACAO,QACS;CACT,MAAM2B,eAAehB,0BAA0Bd,eAAeJ,SAAS;CACvE,IAAImC,WAAW;AAEf,MAAK,MAAMC,QAAQF,aAClB,KAAIb,uBAAuBjB,eAAegC,KAAKtC,WAAWsC,KAAKrC,YAAYQ,OAAO,CACjF4B;AAIF,QAAOA;;;;;;;;;AAUR,SAAgBE,2BAA2BjC,eAA8BG,QAAwB;CAChG,MAAM2B,eAAe/B,oBAAoBC,cAAc;CACvD,IAAI+B,WAAW;AAEf,MAAK,MAAMC,QAAQF,aAClB,KAAIb,uBAAuBjB,eAAegC,KAAKtC,WAAWsC,KAAKrC,YAAYQ,OAAO,CACjF4B;AAIF,QAAOA;;;;;;;;;;;;;;;;;;;;;;AC3IR,MAAMa,cAAc;AACpB,MAAMC,eAAiC;AAgBvC,MAAMQ,sBAAsBnB,cAA+C,KAAK;;;;;;;;;;AAqBhF,SAASyB,mBAAmBR,MAAqB;CAChD,MAAMS,cAAcT,KAAKS;AAGzB,KAAI,CAACA,YACJ,QAAO;AAIR,KAAIA,YAAYC,iBAAiB,KAChC,QAAO;AAIR,KAAI,OAAOD,YAAYE,oBAAoB,UAC1C,QAAOF,YAAYE;AAIpB,QAAO;;AAGR,SAAgBC,qBAAqB,EACpCR,UACAC,aACAC,qBAAqB,OACrBC,gBAC6B;CAE7B,MAAM,CAACV,MAAMgB,gBAAgBzB,eAAiC;AAC7D,MAAIiB,YAAa,QAAOA;AACxB,MAAIC,mBAAoB,QAAOZ;AAE/B,MAAI;GACH,MAAMoB,SAASC,aAAaC,QAAQvB,YAAY;AAChD,OAAIqB,WAAW,UAAUA,WAAW,MACnC,QAAOA;UAED;AAGR,SAAOpB;GACN;AAGFR,iBAAgB;AACf,MAAIoB,mBAAoB;AAExB,MAAI;AACHS,gBAAaE,QAAQxB,aAAaI,KAAK;UAChC;IAGN,CAACA,MAAMS,mBAAmB,CAAC;CAG9B,MAAMV,UAAUZ,aACdkC,YAA8B;AAC9BL,eAAaK,QAAQ;AACrBX,iBAAeW,QAAQ;IAExB,CAACX,aACF,CAAC;CAGD,MAAMT,aAAad,kBAAkB;AACpCY,UAAQC,SAAS,SAAS,QAAQ,OAAO;IACvC,CAACA,MAAMD,QAAQ,CAAC;CAGnB,MAAMK,gBAAgBjB,aAAagB,SAAwB;AAC1D,SAAOQ,mBAAmBR,KAAK;IAC7B,EAAE,CAAC;CAGN,MAAMD,mBAAmBf,aACvBgB,WAAwB;AACxB,MAAIH,SAAS,OAAQ,QAAO;AAC5B,SAAOI,cAAcD,OAAK;IAE3B,CAACH,MAAMI,cACR,CAAC;CAED,MAAMkB,QAAQhC,eACN;EACNU;EACAD;EACAE;EACAC;EACAE;EACA,GACD;EAACJ;EAAMD;EAASE;EAAYC;EAAkBE;EAC/C,CAAC;AAED,QAAO,oBAAC,oBAAoB;EAAgBkB;EAAQf;GAAwC;;;;;AAiB7F,SAAOmB,0BAAA;AAAA,QACCtC,WAAWiB,oBAAoB;;;;;;;;;ACtKvC,IAAauB,gBAAb,MAA2B;CAC1B,AAAQC,eAAoC;CAC5C,AAAQE,WAAgC;CACxC,AAAQE,SAA4C;CACpD,AAAQE,YAA4C;CACpD,AAAQG,cAA6B;;;;;CAMrC,MAAMC,WAAWC,QAAoC;EAEpD,MAAMG,cAAcH,OAAOI,gBAAgB;AAC3CjB,WAAS,iBAAiB,4BAA4B;GACrDkB,UAAUL,OAAOM;GACjBH,aAAaA,YAAYI;GACzBC,WAAWL,YAAYM,KAAKC,OAAO;IAClCJ,IAAII,EAAEJ;IACNK,OAAOD,EAAEC;IACTC,SAASF,EAAEE;IACXC,OAAOH,EAAEG;IACTC,YAAYJ,EAAEI;IACd,EAAC;GACF,CAAC;AAEF,OAAKzB,eAAe,IAAIC,cAAc;AACtCH,WAAS,iBAAiB,wCAAwC,KAAKE,aAAa0B,QAAQ;AAG5F,MAAI;AACH,SAAM,KAAK1B,aAAa2B,QAAQ;AAChC7B,YAAS,iBAAiB,8BAA8B,KAAKE,aAAa0B,QAAQ;WAC1EE,KAAK;AACbC,WAAQC,KAAK,kDAAkDF,IAAI;;AAGpE,OAAK1B,WAAW,KAAKF,aAAa+B,gBAAgB;AAClD,OAAK7B,SAAS8B,UAAU;AACxB,OAAK9B,SAAS+B,wBAAwB;AAEtC,OAAK7B,SAAS,KAAKJ,aAAakC,wBAAwBvB,OAAO;AAC/D,OAAKP,OAAO+B,QAAQ,KAAKjC,SAAS;EAElC,MAAMkC,eAAe,KAAKlC,SAASmC;AACnC,OAAK/B,YAAY,IAAIC,WAAW,IAAIC,YAAY4B,aAAa,CAAC;AAE9DtC,WAAS,iBAAiB,kBAAkB;GAC3CwC,YAAY,KAAKtC,aAAasC;GAC9BD,mBAAmBD;GACnBG,cAAc,KAAKvC,aAAa0B;GAChC,CAAC;;CAGHc,gBAAwB;AACvB,MAAI,CAAC,KAAKtC,YAAY,CAAC,KAAKI,UAAW,QAAO;AAE9C,OAAKJ,SAASuC,qBAAqB,KAAKnC,UAAU;EAGlD,IAAIoC,MAAM;AACV,OAAK,IAAIC,IAAI,GAAGA,IAAI,KAAKrC,UAAUY,QAAQyB,IAC1CD,QAAO,KAAKpC,UAAUqC;EAEvB,MAAMC,UAAUF,MAAM,KAAKpC,UAAUY;AAGrC,SAAO2B,KAAKC,IAAI,GAAGF,UAAU,IAAI;;CAGlCG,iBAAiBC,OAAO,IAAc;AACrC,MAAI,CAAC,KAAK9C,YAAY,CAAC,KAAKI,UAAW,QAAO,IAAI2C,MAAMD,KAAK,CAACE,KAAK,EAAE;AAErE,OAAKhD,SAASuC,qBAAqB,KAAKnC,UAAU;EAElD,MAAM6C,SAAmB,EAAE;EAC3B,MAAMC,gBAAgBP,KAAKQ,MAAM,KAAK/C,UAAUY,SAAS8B,KAAK;AAE9D,OAAK,IAAIL,IAAI,GAAGA,IAAIK,MAAML,KAAK;GAC9B,IAAID,MAAM;AACV,QAAK,IAAIY,IAAI,GAAGA,IAAIF,eAAeE,IAClCZ,QAAO,KAAKpC,UAAUqC,IAAIS,gBAAgBE;AAG3CH,UAAOI,KAAKV,KAAKC,IAAI,GAAGJ,MAAMU,gBAAgB,IAAI,CAAC;;AAGpD,SAAOD;;CAGRK,cAAcC,UAAgE;EAC7E,MAAMG,gBAAgB;AAGrBH,YAFc,KAAKjB,eAAe,EACd,KAAKO,kBAAkB,CACf;AAC5B,QAAKtC,cAAcoD,sBAAsBD,QAAQ;;AAElDA,WAAS;;CAGVE,eAAqB;AACpB,MAAI,KAAKrD,gBAAgB,MAAM;AAC9BsD,wBAAqB,KAAKtD,YAAY;AACtC,QAAKA,cAAc;;;CAIrBuD,UAAgB;AACf,OAAKF,cAAc;AAEnB,MAAI,KAAK1D,QAAQ;AAChB,QAAKA,OAAO6D,YAAY;AACxB,QAAK7D,SAAS;;AAGf,MAAI,KAAKF,UAAU;AAClB,QAAKA,SAAS+D,YAAY;AAC1B,QAAK/D,WAAW;;AAGjB,MAAI,KAAKF,cAAc;AACtB,GAAK,KAAKA,aAAakE,OAAO;AAC9B,QAAKlE,eAAe;;AAGrB,OAAKM,YAAY;;;;;;ACjInB,IAAa+D,eAAb,MAAmD;CAClD,AAAQC,4BAAY,IAAIC,KAAiC;CAEzDE,GAAGC,OAAeC,UAA+B;AAChD,MAAI,CAAC,KAAKL,UAAUM,IAAIF,MAAM,CAC7B,MAAKJ,UAAUO,IAAIH,uBAAO,IAAIF,KAAK,CAAC;EAErC,MAAMF,YAAY,KAAKA,UAAUQ,IAAIJ,MAAM;AAC3C,MAAIJ,UACHA,WAAUS,IAAIJ,SAAS;;CAIzBK,IAAIN,OAAeC,UAA+B;AACjD,OAAKL,UAAUQ,IAAIJ,MAAM,EAAEO,OAAON,SAAS;;CAG5CO,KAAKR,OAAeS,MAAqB;AACxC,OAAKb,UAAUQ,IAAIJ,MAAM,EAAEU,SAAST,aAAa;AAChD,OAAI;AACHA,aAASQ,KAAK;YACNE,OAAO;AACfC,YAAQD,MAAM,+BAA+BX,MAAK,IAAKW,MAAM;;IAE7D;;CAGHE,mBAAmBb,OAAsB;AACxC,MAAIA,MACH,MAAKJ,UAAUW,OAAOP,MAAM;MAE5B,MAAKJ,UAAUkB,OAAO;;CAIxBC,cAAcf,OAAuB;AACpC,SAAO,KAAKJ,UAAUQ,IAAIJ,MAAM,EAAEgB,QAAQ;;;;;;;;;AClB5C,SAASY,wBAAwBC,MAI/B;AACD,QACCA,KAAKN,SAAS,mBACdM,KAAKL,WAAW,eAChB,OAAOK,KAAKJ,SAAS,YACrB,OAAOI,KAAKH,YAAY;;AAI1B,IAAaI,iBAAb,MAA4B;CAC3B,AAAQC,uBAAuB;CAC/B,AAAQC,uCAAuB,IAAIC,KAAa;CAChD,AAAQC,uBAA6D;CACrE,AAAQG,uBAAuB;CAE/BC,YACC,AAAQC,aACR,AAAQC,cACP;EAFOD;EACAC;;CAGT,MAAMC,cAAcC,MAAcC,aAA4C;EAC7E,IAAIG;AAEJ,MAAI;AACHA,SAAMC,KAAKC,MAAMN,KAAK;WACdO,OAAO;AACfC,WAAQD,MAAM,qCAAqCA,MAAM;AACzD;;AAKD,UAAQH,IAAIvB,MAAZ;GACC,KAAK;AACJ,SAAK4B,sBAAsBL,IAAI;AAC/B;GAED,KAAK;AACJ,UAAM,KAAKM,mBAAmBN,KAAKH,YAAY;AAC/C;GAED,KAAK;AACJ,SAAKU,6BAA6B;AAClC;GAED,KAAK;GACL,KAAK;AACJ,SAAKC,mBAAmBR,IAAI;AAC5B;GAGD,KAAK;GACL,KAAK;AACJ,SAAKS,kBAAkBT,IAAI;AAC3B;GAGD,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;AACJ,SAAKU,uBAAuBV,IAAI;AAChC;GAED,KAAK;AACJ,SAAKW,qBAAqBX,IAAI;AAC9B;GAED,KAAK;AACJ,SAAKY,YAAYZ,IAAI;AACrB;GAED,KAAK;GACL,KAAK;AACJ,SAAKa,oBAAoBb,IAAI;AAC7B;GAED,KAAK;GACL,KAAK,+BAEJ;;;CAIH,AAAQK,sBAAsBS,MAA6B;AAC1D,OAAK7B,uBAAuB;AAC5B,OAAKM,uBAAuB;;CAG7B,MAAce,mBACbN,KACAH,aACgB;EAEhB,MAAMkB,cAAc,KAAKC,sBAAsBhB,IAAIiB,SAAS;AAM5D,MAAI,CAHqBF,YAAYI,KAAKrC,wBAAwB,EAG3C;AACtB,QAAKG,uBAAuB;AAC5B,QAAKM,uBAAuB;;AAI7B,MAAIwB,YAAYK,SAAS,GAAG;GAE3B,MAAMC,gBAAgCN,YACpCO,OAAOxC,wBAAwB,CAC/ByC,KAAKxC,UAAU;IACfJ,MAAMI,KAAKJ;IACXC,SAASG,KAAKH;IACdC,WAAWE,KAAKF,aAAa;IAC7B,EAAE;AAEJ,QAAK,MAAM2C,gBAAgBH,cAC1B,KAAI,CAAC,KAAKnC,qBAAqBuC,IAAID,aAAa5C,QAAQ,EAAE;AACzD,SAAKM,qBAAqBwC,IAAIF,aAAa5C,QAAQ;AACnD,UAAM,KAAK+C,oBAAoBH,cAAc3B,YAAY;SAEzDO,SAAQwB,KACP,sDAAsDJ,aAAa7C,KAAI,IAAK6C,aAAa5C,QAAO,GAChG;AAKH,OAAIyC,cAAcD,SAAS,KAAK,KAAKlC,qBAAqB2C,SAAS,EAClE,MAAKC,wBAAwBjC,YAAY;;;;;;CAQ5C,AAAQmB,sBAAsBC,UAAyC;AACtE,MAAI,CAACA,YAAY,OAAOA,aAAa,SACpC,QAAO,EAAE;EAGV,MAAMc,IAAId;AACV,MAAI,CAACgB,MAAMC,QAAQH,EAAEI,OAAO,CAC3B,QAAO,EAAE;AAIV,SAAOJ,EAAEI,OAAOb,QACdvC,SACAA,SAAS,QACT,OAAOA,SAAS,YAChB,OAAQA,KAA4BN,SAAS,SAC9C;;CAGF,AAAQ8B,8BAAoC;CAK5C,AAAQC,mBAAmBR,KAA4B;EACtD,MAAMoC,YACLpC,IAAIvB,SAAS,sCAAsC,mBAAmB;AACvE,OAAKiB,aAAa2C,KAAKD,WAAWpC,IAAI;;CAGvC,AAAQS,kBAAkBT,KAA4B;EACrD,MAAMoC,YAAYpC,IAAIvB,SAAS,gCAAgC,kBAAkB;AACjF2B,UAAQkC,IAAI,8BAA8BF,aAAa;GACtD3D,MAAMuB,IAAIvB;GACV8D,UAAU,CAAC,CAAEvC,IAA4BwC;GACzC,CAAC;AACF,OAAK9C,aAAa2C,KAAKD,WAAWpC,IAAI;;CAGvC,AAAQU,uBAAuBV,KAA4B;EAS1D,MAAMoC,YAPmC;GACxC,0CAA0C;GAC1C,yCAAyC;GACzC,8BAA8B;GAC9B,6BAA6B;GAC7B,CAE0BpC,IAAIvB;AAC/B,MAAI2D,UACH,MAAK1C,aAAa2C,KAAKD,WAAWpC,IAAI;;CAIxC,AAAQW,qBAAqBX,KAA4B;AACxD,OAAKN,aAAa2C,KAAK,wBAAwB,EAAEK,MAAM1C,IAAI2C,YAAY,CAAC;;CAGzE,AAAQ9B,oBAAoBC,MAA6B;CAIzD,AAAQF,YAAYZ,KAA4B;AAC/CI,UAAQD,MAAM,uBAAuBH,IAAI;AACzC,OAAKN,aAAa2C,KAAK,SAASrC,IAAI;AACpC,OAAKf,uBAAuB;AAC5B,OAAKM,uBAAuB;AAG5B,MAAI,KAAKH,sBAAsB;AAC9BwD,gBAAa,KAAKxD,qBAAqB;AACvC,QAAKA,uBAAuB;;;CAI9B,MAAcuC,oBACbH,cACA3B,aACgB;EAChB,MAAM,EAAElB,MAAMC,YAAY4C;AAE1B,MAAI;AAEH,QAAK9B,aAAa2C,KAAK,qBAAqB,EAAE1D,MAAM,CAAC;GAGrD,MAAMkE,SAAS,MAAM,KAAKpD,YAAYqD,gBAAgBtB,aAAa;AAGnE,OAAI3B,YAAYkD,eAAe,QAAQ;AACtC3C,YAAQD,MACP,gDAAgDxB,KAAI,mBAAoBkB,YAAYkD,aACpF;AACD,SAAKrD,aAAa2C,KAAK,uBAAuB;KAC7C1D;KACAwB,OAAO;KACP,CAAC;AACF;;GAID,MAAMc,WAAW;IAChBxC,MAAM;IACNM,MAAM;KACLN,MAAM;KACGG;KACTuD,QAAQlC,KAAK+C,UACZH,OAAOI,UACJJ,OAAOjD,OACP;MACAO,OAAO0C,OAAO1C;MACd8C,SAAS;MAEb,CAAA;KACD;IACA;AAEDpD,eAAYqD,KAAKjD,KAAK+C,UAAU/B,SAAS,CAAC;AAG1C,QAAKvB,aAAa2C,KAAK,uBAAuB;IAC7C1D;IACAwB,OAAO0C,OAAOI,UAAUE,SAAYN,OAAO1C;IAC3C,CAAC;WACMA,OAAO;AACfC,WAAQD,MAAM,8CAA8CxB,KAAI,IAAKwB,MAAM;AAC3E,QAAKiD,cAAcxE,SAASyE,OAAOlD,MAAM,EAAEN,YAAY;YAC9C;AACT,QAAKX,qBAAqBoE,OAAO1E,QAAQ;AAGzC,OAAI,KAAKM,qBAAqB2C,SAAS,GAAG;AAEzC,SAAK5C,uBAAuB;AAC5B,SAAKM,uBAAuB;AAC5B,SAAKuC,wBAAwBjC,YAAY;;;;CAK5C,AAAQuD,cAAcxE,SAAiBuB,OAAeN,aAAmC;AAExF,MAAIA,YAAYkD,eAAe,QAAQ;AACtC3C,WAAQD,MACP,2DAA2DN,YAAYkD,aACvE;AACD;;EAGD,MAAMQ,gBAAgB;GACrB9E,MAAM;GACNM,MAAM;IACLN,MAAM;IACGG;IACTuD,QAAQlC,KAAK+C,UAAU;KAAE7C;KAAO8C,SAAS;KAAO,CAAA;IACjD;GACA;AAEDpD,cAAYqD,KAAKjD,KAAK+C,UAAUO,cAAc,CAAC;;CAGhD,AAAQzB,wBAAwBjC,aAAmC;AAElE,MAAI,KAAKT,sBAAsB;AAC9BwD,gBAAa,KAAKxD,qBAAqB;AACvC,QAAKA,uBAAuB;;AAI7B,OAAKA,uBAAuBE,iBAAiB;AAC5C,OACC,CAAC,KAAKL,wBACN,CAAC,KAAKM,wBACNM,YAAYkD,eAAe,UAC3B,KAAK7D,qBAAqB2C,SAAS,GAClC;AACD,SAAKtC,uBAAuB;AAC5B,SAAKN,uBAAuB;AAC5BY,gBAAYqD,KAAKjD,KAAK+C,UAAU,EAAEvE,MAAM,mBAAmB,CAAC,CAAC;;AAE9D,QAAKW,uBAAuB;KAC1BjB,0BAA0B;;CAG9BqF,QAAc;AACb,OAAKvE,uBAAuB;AAC5B,OAAKM,uBAAuB;AAC5B,OAAKL,qBAAqBuE,OAAO;AAGjC,MAAI,KAAKrE,sBAAsB;AAC9BwD,gBAAa,KAAKxD,qBAAqB;AACvC,QAAKA,uBAAuB;;;;;;;ACrV/B,IAAakF,cAAb,MAAyB;CACxB,AAAQC,QAA0B,EAAE;CACpC,AAAQC,WAAgC;CACxC,AAAQC,wBAAwB;CAEhCC,SAASH,OAA+B;AACvC,OAAKA,QAAQA;;CAGdI,YAAYH,UAA8B;AACzC,OAAKA,WAAWA;;CAGjBI,eAAqB;AACpBC,UAAQC,IAAI,sEAAsE;;CAGnF,AAAQC,iBAAiBR,OAAiC;AACzD,SAAOA,MACLS,KAAKC,MAAMA,EAAElB,KAAK,CAClBmB,MAAM,CACNC,KAAK,IAAI;;CAGZC,kBAA2B;AAE1B,SADyB,KAAKL,iBAAiB,KAAKR,MAAM,KAC9B,KAAKE;;CAGlCa,gBAAsB;AACrB,OAAKb,wBAAwB,KAAKM,iBAAiB,KAAKR,MAAM;;CAG/DgB,uBAAqC;EAEpC,MAAMC,eAA6B,CAClC;GACCC,MAAM;GACN1B,MAAM;GACNC,aACC;GACD0B,YAAY;IACXD,MAAM;IACNE,YAAY,EAAE;IACdC,UAAU,EAAA;IACX;GACA,CACD;EAGD,MAAMC,kBAAkB,KAAKtB,MAAMS,KAAKc,UAAU;GACjDL,MAAM;GACN1B,MAAM+B,KAAK/B;GACXC,aAAa8B,KAAK9B,eAAe,WAAW8B,KAAK/B,KAAI;GACrD2B,YAAY,KAAKM,mBAAmBF,KAAK7B,YAAW;GACpD,EAAE;AAEH,SAAO,CAAC,GAAGuB,cAAc,GAAGK,gBAAgB;;CAG7C,AAAQG,mBAAmBC,QAIzB;AACD,MAAI,CAACA,OACJ,QAAO;GAAER,MAAM;GAAUE,YAAY,EAAE;GAAEC,UAAU,EAAA;GAAI;EAGxD,MAAMM,SAIF;GAAET,MAAM;GAAU,GAAGQ;GAAQ;AAEjC,MAAIC,OAAOT,SAAS,UAAU;AAC7BS,UAAOP,aAAcO,OAAOP,cAA0C,EAAE;AAGxEO,UAAOP,aAAa,KAAKQ,sBAAsBD,OAAOP,WAAW;AAGjE,OAAI,CAACO,OAAON,YAAYM,OAAOP,WAC9BO,QAAON,WAAWQ,OAAOC,QAAQH,OAAOP,WAAW,CACjDW,QAAQ,GAAGC,UAAU;AACrB,QAAIA,QAAQ,OAAOA,SAAS,UAAU;KACrC,MAAMC,IAAID;AACV,YAAO,CAACC,EAAEC,YAAY,CAACD,EAAEE,YAAYF,EAAEf,SAAS;;AAEjD,WAAO;KACN,CACDT,KAAK,CAAC2B,SAASA,IAAI;;AAIvB,SAAOT;;;;;;CAOR,AAAQC,sBAAsBR,YAA8D;EAC3F,MAAMiB,YAAqC,EAAE;AAE7C,OAAK,MAAM,CAACD,KAAKE,UAAUT,OAAOC,QAAQV,WAAW,EAAE;AACtD,OAAI,CAACkB,SAAS,OAAOA,UAAU,UAAU;AACxCD,cAAUD,OAAOE;AACjB;;GAGD,MAAMN,OAAOM;GACb,MAAMC,WAAWP,KAAKd;AAEtB,OAAIqB,aAAa,QAEhB,KAAI,CAACP,KAAKQ,OAAO;AAChBlC,YAAQmC,KACP,iCAAiCL,IAAG,iDACpC;AACDC,cAAUD,OAAO;KAChB,GAAGJ;KACHQ,OAAO,EAAEtB,MAAM,UAAS;KACxB;cACS,OAAOc,KAAKQ,UAAU,UAAU;IAE1C,MAAMA,QAAQR,KAAKQ;AACnB,QAAIA,MAAMtB,SAAS,YAAYsB,MAAMpB,WACpCiB,WAAUD,OAAO;KAChB,GAAGJ;KACHQ,OAAO;MACN,GAAGA;MACHpB,YAAY,KAAKQ,sBAAsBY,MAAMpB,WAAqC;MACnF;KACA;QAEDiB,WAAUD,OAAOJ;SAGlBK,WAAUD,OAAOJ;YAERO,aAAa,YAAYP,KAAKZ,WAExCiB,WAAUD,OAAO;IAChB,GAAGJ;IACHZ,YAAY,KAAKQ,sBAAsBI,KAAKZ,WAAqC;IACjF;OAEDiB,WAAUD,OAAOJ;;AAInB,SAAOK;;CAGR,MAAMK,gBAAgBC,cAA0D;EAC/E,MAAM,EAAEnD,MAAMoD,WAAWC,eAAeF;AAGxC,MAAInD,SAAS,uBACZ,QAAO,KAAKsD,kBAAkB;AAI/B,MAAI,CAAC,KAAK7C,UAAU;AACnBK,WAAQyC,MAAM,6CAA6C;AAC3D,UAAO;IAAEC,SAAS;IAAOD,OAAO;IAAgC;;EAIjE,IAAIlD;AACJ,MAAI;GACH,MAAMoD,WAAWJ,aAAa1D,WAAW0D,WAAW,GAAG;AACvDhD,UAAOqD,KAAKC,MAAMF,SAAS;WACnBF,OAAO;AACfzC,WAAQyC,MAAM,4CAA4CA,MAAM;AAChEzC,WAAQyC,MAAM,iCAAiCF,YAAYO,MAAM,GAAG,IAAI,CAAC;AACzE,UAAO;IAAEJ,SAAS;IAAOD,OAAO;IAA4B;;AAQ7D,MAAI;AAEH,UAAO;IAAEC,SAAS;IAAMK,MADT,MAAM,KAAKpD,SAAST,MAAMK,KAAK;IACR;WAC9BkD,OAAO;AACfzC,WAAQyC,MAAM,0CAA0CvD,KAAI,IAAKuD,MAAM;AACvE,UAAO;IAAEC,SAAS;IAAOD,OAAOO,OAAOP,MAAK;IAAG;;;CAIjD,AAAQD,mBAAwC;EAC/C,MAAMS,WAAW,KAAKvD,MAAMS,KAAKc,UAAU;GAC1C/B,MAAM+B,KAAK/B;GACXC,aAAa8B,KAAK9B,eAAe;GACjC0B,YAAYI,KAAK7B,eAAe,EAAC;GACjC,EAAE;AAEH,SAAO;GACNsD,SAAS;GACTK,MAAM;IACLrD,OAAOuD;IACPC,OAAOD,SAASE;IAChBC,SACCH,SAASE,SAAS,IACf,SAASF,SAASE,OAAM,oBACxB;IACL;GACA;;CAGFE,oBAAkF;AACjF,MAAI,CAAC,KAAK9C,iBAAiB,CAC1B,QAAO;EAGR,MAAMkD,YAAY,KAAK7D,sBAAsB8D,MAAM,IAAI,CAACjC,OAAOkC,QAAQ;EACvE,MAAMC,YAAY,KAAKlE,MAAMS,KAAKC,MAAMA,EAAElB,KAAK;EAE/C,MAAM2E,UAAU,IAAIC,IAAIL,UAAU;EAClC,MAAMM,UAAU,IAAID,IAAIF,UAAU;AAKlC,SAAO;GACNN,OAJaM,UAAUnC,QAAQvC,SAAS,CAAC2E,QAAQG,IAAI9E,KAAK,CAAC;GAK3DqE,SAJeE,UAAUhC,QAAQvC,SAAS,CAAC6E,QAAQC,IAAI9E,KAAK,CAAC;GAK7DsE,OAAO,KAAK9D,MAAMyD;GAClB;;;;;;ACrOH,SAASuB,gBAAgBC,UAEvB;AACD,KAAI,CAACA,YAAY,OAAOA,aAAa,SACpC,QAAO;AAGR,QAAO,OADSA,SAAoCH,eAC9BC,UAAU;;AAGjC,IAAaI,gBAAb,MAA2B;CAC1B,AAAQC;CAERC,YAAYD,eAAuB;AAClC,OAAKA,gBAAgBA;;CAGtB,MAAME,cAAcC,SAAyB,EAAE,EAA4B;EAC1E,MAAME,QAAQF,OAAOE,SAAShB;EAC9B,MAAMiB,QAAQH,OAAOG,SAAShB;EAC9B,MAAMiB,SAASJ,OAAOI,UAAUnB;EAGhC,MAAMoB,eAAe,MAAM,KAAKC,kBAAkBJ,OAAOC,MAAM;EAG/D,MAAMI,KAAK,IAAIC,mBAAmB;EAGlC,MAAMC,eAAe,KAAKC,oBAAoB;EAE9C,IAAIC,eAAmC;AACvCJ,KAAGM,WAAWC,MAAM;AACnBH,kBAAeG,EAAEC,QAAQ;AACzBN,gBAAaO,YAAYL;AACzB3B,YAAS,UAAU,+DAA+D;IACjFiC,UAAUN,aAAaO;IACvBC,QAAQR,aAAaS,WAAW,CAACC;IACjC,CAAC;;EAIH,MAAMC,cAAc,MAAM,KAAKC,cAAc;AAC7CvC,WAAS,UAAU,oCAAoC;GACtDiC,UAAUK,YAAYJ;GACtBC,QAAQG,YAAYF,WAAW,CAACI,KAAKC,OAAO;IAC3CC,MAAMD,EAAEC;IACRC,SAASF,EAAEE;IACXC,OAAOH,EAAEG;IACTC,YAAYJ,EAAEI;IACd,EAAC;GACF,CAAC;AAEFP,cAAYF,WAAW,CAACU,SAASC,UAAU;AAC1CxB,MAAGyB,SAASD,OAAOT,YAAY;IAC9B;EAGF,MAAMW,cAAc1B,GAAG2B,kBAAkB,aAAa;EAGtD,MAAMC,QAAQ,MAAM5B,GAAG6B,aAAa;AACpC,QAAM7B,GAAG8B,oBAAoBF,MAAM;AAGnC,MAAI,CAACA,MAAMG,IACV,OAAM,IAAIC,MAAM,6BAA6B;EAE9C,MAAMC,SAAS,MAAM,KAAKC,gBAAgBrC,QAAQF,OAAOiC,MAAMG,KAAKjC,aAAa;AACjF,QAAME,GAAGmC,qBAAqBF,OAAO;EAGrC,MAAMG,gBAAgB;AACrBrB,eAAYF,WAAW,CAACU,SAASC,UAAU;AAC1CA,UAAMa,MAAM;KACX;AACFnC,gBAAaoC,QAAQ;AACrBZ,eAAYa,OAAO;AACnBvC,MAAGuC,OAAO;;AAGX,SAAO;GACNvC;GACA0B;GACAxB;GACAa;GACAX;GACAgC;GACA;;CAGF,MAAcrC,kBAAkBJ,OAAeC,OAAgC;EAC9E,MAAMT,WAAW,MAAMqD,MAAM,KAAKlD,eAAe;GAChDmD,QAAQ;GACRC,SAAS,EACR,gBAAgB,oBAChB;GACDC,MAAMC,KAAKC,UAAU;IAAElD;IAAOC;IAAO,CAAA;GACrC,CAAC;AAEF,MAAI,CAACT,SAAS2D,IAAI;GACjB,MAAMC,YAAY,MAAM5D,SAAS6D,MAAM;AACvCC,WAAQC,MAAM,kCAAkCH,UAAU;AAC1D,SAAM,IAAIf,MAAM,kCAAkC7C,SAASgE,aAAa;;EAGzE,MAAMC,OAAgB,MAAMjE,SAASkE,MAAM;AAE3C,MAAI,CAACnE,gBAAgBkE,KAAK,CACzB,OAAM,IAAIpB,MAAM,gCAAgC;AAGjD,SAAOoB,KAAKpE,cAAcC;;CAG3B,AAAQkB,qBAAuC;EAC9C,MAAMD,eAAeqD,SAASC,cAAc,QAAQ;AACpDtD,eAAauD,WAAW;AACxBvD,eAAawD,MAAMC,UAAU;AAC7BJ,WAASZ,KAAKiB,YAAY1D,aAAa;AACvC,SAAOA;;CAGR,MAAcc,eAAqC;AAClD,MAAI;AACH,UAAO,MAAM6C,UAAUC,aAAa9C,aAAa,EAChD+C,OAAO;IACNC,kBAAkB;IAClBC,kBAAkB;IAClBC,iBAAiB;IAClB,EACA,CAAC;WACMhB,OAAO;AACf,SAAM,IAAIlB,MAAM,gCAAgCkB,QAAQ;;;CAI1D,MAAchB,gBACbiC,SACAxE,OACAoC,KACAjC,cACqC;EACrC,MAAMX,WAAW,MAAMqD,MAAM,GAAG2B,QAAO,SAAUxE,SAAS;GACzD8C,QAAQ;GACRE,MAAMZ;GACNW,SAAS;IACR2B,eAAe,UAAUvE;IACzB,gBAAgB;IACjB;GACA,CAAC;AAEF,MAAI,CAACX,SAAS2D,GACb,OAAM,IAAId,MAAM,0CAA0C7C,SAASgE,aAAa;AAIjF,SAAO;GACNoB,MAAM;GACNxC,KAHiB,MAAM5C,SAAS6D,MAAM;GAItC;;;;;;;AChKH,MAAMuC,2BAA2BC,OAAOC,OAAO,IAAIC,MAAMjB,qBAAqB,CAACkB,KAAK,EAAE,CAAC;AACvF,MAAMC,iCAA2C,CAAC,GAAGL,yBAAyB;;;;;;;AAQ9E,IAAaM,wBAAb,MAAmC;CAClC,AAAQC,UAAkC;CAC1C,AAAQC;CACR,AAAQC;CACR,AAAQC;CACR,AAAQC;CACR,AAAQC,QAAQ;CAChB,AAAQC,YAAmE;CAC3E,AAAQC,gBAAsC;CAC9C,AAAQC,iBAAuC;CAC/C,AAAQC,wBAA+D;CACvE,AAAQG,mBAAkC;CAC1C,AAAQC,yBAA8C;CAEtDC,YAAYC,eAAuB;AAClC,OAAKd,gBAAgB,IAAIf,cAAc6B,cAAc;AACrD,OAAKb,cAAc,IAAIjB,aAAa;AACpC,OAAKmB,eAAe,IAAIrB,cAAc;AACtC,OAAKoB,iBAAiB,IAAInB,eAAe,KAAKkB,aAAa,KAAKE,aAAa;;;;;CAM9EY,SAASC,OAA+B;AACvC,OAAKf,YAAYc,SAASC,MAAM;AAChC,MAAI,KAAKC,iBAAiB,CACzB,MAAKC,oBAAoB;;;;;CAO3BC,gBAAgBC,UAA8B;AAC7C,OAAKnB,YAAYoB,YAAYD,SAAS;;;;;CAMvCE,eAAeC,UAA4B;AAC1C,OAAKX,yBAAyBW;;;;;CAM/B,MAAMC,aAAaC,SAAyB,EAAE,EAA4B;AACzE,MAAI;AAEH,OAAI,KAAK1B,QACR,MAAK4B,aAAa;AAGnB,QAAKvB,QAAQ;AACb,QAAKO,mBAAmBiB,KAAKC,KAAK;AAClC,QAAKC,iBAAiB,aAAa;AAGnC,QAAK/B,UAAU,MAAM,KAAKC,cAAc+B,cAAcN,OAAO;AAG7D,QAAKO,iBAAiB,KAAKjC,QAAQkC,YAAY;AAG/C,QAAKC,8BAA8B,KAAKnC,QAAQoC,GAAG;AAEnD,OAAI,KAAKpC,QAAQqC,YAChB,OAAM,KAAKC,wBAAwB,KAAKtC,QAAQqC,YAAY;AAG7D,OAAI,KAAKrC,QAAQuC,aAChB,CAAK,KAAKC,yBAAyB,KAAKxC,QAAQuC,aAAa;GAI9D,MAAME,kBAAkB,KAAKzC,QAAQoC,GAAGM;GACxC,MAAM1C,UAAU,KAAKA;AACrB,QAAKA,QAAQoC,GAAGM,WAAWC,MAAM;AAChC,QAAIF,gBAAiBA,iBAAgBG,KAAK5C,QAAQoC,IAAIO,EAAE;AACxD,QAAI,KAAK3C,QACR,MAAKA,QAAQuC,eAAeI,EAAEE,QAAQ;IAGvC,MAAMN,eAAeI,EAAEE,QAAQ;AAC/B,QAAI,CAACN,cAAc;AAClBO,aAAQC,KAAK,gEAAgE;AAC7E;;AAGD,IAAK,KAAKP,yBAAyBD,aAAa;;AAGjD,UAAO,KAAKvC;WACJgD,OAAO;AACf,QAAKC,mBAAmBD,MAAM;AAC9B,SAAMA;;;;;;CAORpB,cAAoB;EAEnB,IAAIsB,kBAAkB;AACtB,MAAI,KAAKtC,iBACRsC,mBAAkBC,KAAKC,OAAOvB,KAAKC,KAAK,GAAG,KAAKlB,oBAAoB,IAAK;AAG1E,MAAI,KAAKH,uBAAuB;AAC/B4C,iBAAc,KAAK5C,sBAAsB;AACzC,QAAKA,wBAAwB;;AAG9B,MAAI,KAAKF,eAAe;AACvB,QAAKA,cAAc+C,SAAS;AAC5B,QAAK/C,gBAAgB;;AAGtB,MAAI,KAAKC,gBAAgB;AACxB,QAAKA,eAAe8C,SAAS;AAC7B,QAAK9C,iBAAiB;;AAEvB,MAAI,KAAKR,SAAS;AACjB,QAAKA,QAAQuD,SAAS;AACtB,QAAKvD,UAAU;;AAEhB,OAAKG,eAAeqD,OAAO;AAC3B,OAAKtD,YAAYuD,cAAc;AAG/B,OAAKpD,QAAQ;AACb,OAAK0B,iBAAiB,gBAAgB,EAAEmB,iBAAiB,CAAC;AAG1D,OAAKtC,mBAAmB;;;;;CAMzB8C,gBAAgBC,MAAoB;AACnC,MAAI,CAAC,KAAKzC,iBAAiB,CAC1B,OAAM,IAAI0C,MAAM,oBAAoB;EAGrC,MAAMC,UAAU;GACfC,MAAM;GACNC,MAAM;IACLD,MAAM;IACNE,MAAM;IACNC,SAAS,CAAC;KAAEH,MAAM;KAAcH;KAAM,CAAA;IACvC;GACA;AAED,MAAI,CAAC,KAAK3D,QACT,OAAM,IAAI4D,MAAM,wBAAwB;AAEzC,OAAK5D,QAAQkC,YAAYgC,KAAKC,KAAKC,UAAUP,QAAQ,CAAC;AACtD,OAAK7D,QAAQkC,YAAYgC,KAAKC,KAAKC,UAAU,EAAEN,MAAM,mBAAmB,CAAC,CAAC;;;;;CAM3E5C,kBAA2B;AAC1B,SAAO,KAAKlB,YAAY,QAAQ,KAAKA,QAAQkC,YAAYmC,eAAe;;;;;CAMzEC,iBAAqC;AACpC,SAAO,KAAKtE,SAASqC,eAAe;;;;;CAMrCmC,kBAAsC;AACrC,SAAO,KAAKxE,SAASuC,gBAAgB;;;;;CAMtCkC,WAAWpE,OAAsB;AAChC,MAAI,KAAKL,SAAS0E,aACjB,MAAK1E,QAAQ0E,aAAarE,QAAQA;AAEnC,OAAKA,QAAQA;AACb,OAAK0B,iBAAiB,KAAKzB,WAAW,EAAEqE,SAAS,KAAKtE,OAAO,CAAC;;;;;;CAO/DuE,aAAmB;AAClB,MAAI,KAAK5E,SAAS0E,aACjB,MAAK1E,QAAQ0E,aAAaG,OAAO;;;;;CAOnCC,cAAoB;AACnB,MAAI,KAAK9E,SAAS0E,aACjB,MAAK1E,QAAQ0E,aAAaK,MAAM,CAACC,OAAOhC,UAAU;AAEjDF,WAAQC,KAAK,mDAAmDC,MAAM;IACrE;;;;;CAOJiC,GAAGC,OAAe1D,UAA+B;AAChD,OAAKpB,aAAa6E,GAAGC,OAAO1D,SAAS;;CAGtC2D,IAAID,OAAe1D,UAA+B;AACjD,OAAKpB,aAAa+E,IAAID,OAAO1D,SAAS;;CAGvC4D,mBAIE;AACD,SAAO;GACNC,OAAO,KAAK/E;GACZgF,UAAU,KAAKhF,cAAc;GAC7BqE,SAAS,KAAKtE;GACd;;;;;CAMF,AAAQ4B,iBAAiBC,aAAmC;AAE3DA,cAAYsD,iBAAiB,cAAc;AAC1C,QAAKC,iBAAiBvD,YAAY;AAClC,QAAK7B,QAAQ;AACb,QAAK0B,iBAAiB,YAAY;IACjC;AAGFG,cAAYsD,iBAAiB,YAAYN,UAAgC;AACxE,IAAM,YAAY;AACjB,QAAI;AACH,WAAM,KAAK/E,eAAewF,cAAcT,MAAMU,MAAM1D,YAAY;aACxDc,OAAO;AACfF,aAAQE,MAAM,2BAA2BA,MAAM;;OAE7C;IACH;AAGFd,cAAYsD,iBAAiB,UAAUxC,UAAU;AAChDF,WAAQE,MAAM,sBAAsBA,MAAM;AAC1C,QAAK5C,aAAayF,KAAK,SAAS;IAAE/B,MAAM;IAAqBd;IAAO,CAAC;IACpE;AAGFd,cAAYsD,iBAAiB,eAAe;AAC3C,QAAKrF,eAAeqD,OAAO;AAC3B,QAAKpD,aAAayF,KAAK,kBAAkB,EAAE,CAAC;IAC3C;;CAGH,AAAQ1D,8BAA8BC,IAA6B;AAElEA,KAAGoD,iBAAiB,+BAA+B;AAClD,OAAIpD,GAAG2D,oBAAoB,YAAY3D,GAAG2D,oBAAoB,gBAAgB;AAC7EjD,YAAQE,MAAM,yCAAyC;AACvD,SAAK7C,eAAeqD,OAAO;AAC3B,SAAKpD,aAAayF,KAAK,SAAS;KAC/B/B,MAAM;KACND,SAAS,cAAczB,GAAG2D;KAC1B,CAAC;;IAEF;AAGF3D,KAAGoD,iBAAiB,kCAAkC;AACrD,OAAIpD,GAAG4D,uBAAuB,YAAY5D,GAAG4D,uBAAuB,eACnElD,SAAQE,MAAM,wCAAwC;IAEtD;AAGFZ,KAAGoD,iBAAiB,8BAA8B,GAAG;;CAGtD,AAAQC,iBAAiBvD,aAAmC;AAE3D,OAAKhC,YAAYuD,cAAc;EAG/B,MAAMxC,QAAQ,KAAKf,YAAY+F,sBAAsB;AAErD,OAAK/F,YAAYgG,eAAe;EAmBhC,MAAMa,gBAAgB;GACrBjD,MAAM;GACN9D,SAnBoC;IACpCoG,YAAY,CAAC,QAAQ,QAAQ;IAC7BC,cAAc,KAAKC,wBAAwB;IAC3CC,OAAO;IACAtF;IACPuF,aAAa;IACbC,gBAAgB;KACf3C,MAAM;KACN4C,WAAW;KACXC,mBAAmB;KACnBC,qBAAqB;KACrB;IACDC,2BAA2B,EAC1BC,OAAO,aACR;IACA;GAKA;AAED5E,cAAYgC,KAAKC,KAAKC,UAAU2C,cAAc,CAAC;;CAGhD,AAAQ5F,qBAA2B;AAClC,MAAI,CAAC,KAAKnB,SAAS;AAClB8C,WAAQC,KAAK,iEAAiE;AAC9E;;AAGD,MAAI,KAAK/C,QAAQkC,YAAYmC,eAAe,QAAQ;AACnDvB,WAAQC,KACP,+DAA+D,KAAK/C,QAAQkC,YAAYmC,aACxF;AACD;;EAID,MAAM2C,iBAAiB,KAAK9G,YAAY+G,mBAAmB;AAC3D,MAAI,CAACD,eACJ;EAID,MAAM/F,QAAQ,KAAKf,YAAY+F,sBAAsB;AAErDnD,UAAQoE,IACP,0DACA,GAAGF,eAAeG,MAAK,gBACvBH,eAAeI,MAAMC,SAAS,IAC3B,IAAIL,eAAeI,MAAMC,OAAM,UAAWL,eAAeI,MAAME,MAAM,GAAG,EAAE,CAACC,KAAK,KAAK,GAAGP,eAAeI,MAAMC,SAAS,IAAI,QAAQ,GAAE,KACpI,IACHL,eAAeQ,QAAQH,SAAS,IAAI,IAAIL,eAAeQ,QAAQH,OAAM,YAAa,GAClF;AAGD,OAAKnH,YAAYgG,eAAe;EAEhC,MAAMa,gBAAgB;GACrBjD,MAAM;GACN9D,SAAS;IACDiB;IACPuF,aAAa;IACd;GACA;AAED,OAAKxG,QAAQkC,YAAYgC,KAAKC,KAAKC,UAAU2C,cAAc,CAAC;;CAG7D,AAAQT,yBAAiC;AACxC,SAAO;;;;;CAMR,AAAQrD,mBAAmBD,OAAsB;AAChDF,UAAQE,MAAM,kBAAkBA,MAAM;AACtC,OAAKjB,iBAAiB,SAAS;GAC9B+B,MAAM;GACNd,OAAOyE,OAAOzE,MAAK;GACnB,CAAC;AACF,OAAKpB,aAAa;;CAGnB,MAAcU,wBAAwBoF,QAAoC;AACzE,MAAI,KAAKnH,cACR,MAAKA,cAAc+C,SAAS;AAG7B,OAAK/C,gBAAgB,IAAIzB,eAAe;AACxC,MAAI;GAEH,MAAM6I,eAAe,IAAIpD,YAAYmD,OAAOE,gBAAgB,CAACC,KAAKC,MAAMA,EAAEC,OAAO,CAAC,CAAC;AACnF,SAAM,KAAKxH,cAAcyH,WAAWL,aAAa;AACjD,QAAKM,yBAAyB;WACtBjF,OAAO;AACfF,WAAQE,MAAM,qEAAqEA,MAAM;AACzF,OAAI,KAAKzC,eAAe;AACvB,SAAKA,cAAc+C,SAAS;AAC5B,SAAK/C,gBAAgB;;;;CAKxB,MAAciC,yBAAyBkF,QAAoC;AAC1E,MAAI,KAAKlH,eACR,MAAKA,eAAe8C,SAAS;AAG9B,OAAK9C,iBAAiB,IAAI1B,eAAe;AACzC,MAAI;GAEH,MAAM6I,eAAe,IAAIpD,YAAYmD,OAAOE,gBAAgB,CAACC,KAAKC,MAAMA,EAAEC,OAAO,CAAC,CAAC;AACnF,SAAM,KAAKvH,eAAewH,WAAWL,aAAa;AAClD,QAAKM,yBAAyB;WACtBjF,OAAO;AACfF,WAAQE,MAAM,sEAAsEA,MAAM;AAC1F,OAAI,KAAKxC,gBAAgB;AACxB,SAAKA,eAAe8C,SAAS;AAC7B,SAAK9C,iBAAiB;;;;CAKzB,AAAQyH,0BAAgC;AACvC,MAAI,CAAC,KAAK1H,iBAAiB,CAAC,KAAKC,gBAAgB;AAChD3B,YAAS,yBAAyB,sDAAsD;AACxF;;AAGD,MAAI,KAAK4B,sBACR4C,eAAc,KAAK5C,sBAAsB;EAG1C,IAAIyH,aAAa;AACjB,OAAKzH,wBAAwBE,kBAAkB;GAC9C,MAAMwH,WAAW,KAAK5H,eAAe6H,eAAe,IAAI;GACxD,MAAMC,eACL,KAAK9H,eAAe+H,iBAAiB3J,qBAAqB,IAAImB,0BAA0B;GACzF,MAAMyI,eAAe,KAAK/H,gBAAgB4H,eAAe,IAAI;GAC7D,MAAMI,mBACL,KAAKhI,gBAAgB8H,iBAAiB3J,qBAAqB,IAAImB,0BAA0B;AAG1FoI;AACA,OAAIA,aAAa,OAAO,EACvBrJ,UAAS,yBAAyB,gBAAgB;IACjD4J,KAAKN,SAASO,QAAQ,EAAE;IACxBC,SAASJ,aAAaG,QAAQ,EAAC;IAC/B,CAAC;AAGH,QAAKtI,aAAayF,KAAK,eAAe;IACrCsC;IACAE;IACAE;IACAC;IACA,CAAC;KACA5J,gCAAgC;;CAGpC,AAAQmD,iBACPsD,OACAuD,QAAiC,EAAE,EAC5B;AACP,OAAKtI,YAAY+E;EACjB,MAAMyD,UAAU;GACfzD;GACAC,UAAUD,UAAU;GACpBV,SAAS,KAAKtE;GACd,GAAGuI;GACH;AAED,OAAKxI,aAAayF,KAAK,iBAAiBiD,QAAQ;AAEhD,UAAQzD,OAAR;GACC,KAAK;AACJ,SAAKjF,aAAayF,KAAK,sBAAsBiD,QAAQ;AACrD;GACD,KAAK;AACJ,SAAK1I,aAAayF,KAAK,qBAAqBiD,QAAQ;AACpD;GACD,KAAK;AACJ,SAAK1I,aAAayF,KAAK,kBAAkBiD,QAAQ;AACjD;GACD,KAAK;AACJ,SAAK1I,aAAayF,KAAK,SAASiD,QAAQ;AACxC;GACD,QACC;;;;;;;;;;AClVJ,SAAgByF,wBAAwB1C,MAA8C;AACrF,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;CAC9C,MAAM2C,IAAI3C;AACV,QACC,OAAO2C,EAAEd,UAAU,YACnB;EAAC;EAAc;EAAa;EAAgB;EAAQ,CAACe,SAASD,EAAEd,MAAM,IACtE,OAAOc,EAAEvB,aAAa,aACtB,OAAOuB,EAAErB,YAAY;;;;;AAOvB,SAAgBuB,0BAA0B7C,MAAgD;AACzF,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;AAE9C,QAAO,OADGA,KACMe,SAAS;;;;;AAM1B,SAAgB+B,+BACf9C,MACuC;AACvC,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;CAC9C,MAAM2C,IAAI3C;AACV,QAAO2C,EAAEV,UAAUc,UAAa,OAAOJ,EAAEV,UAAU;;;;;AAMpD,SAAgBe,2BAA2BhD,MAAiD;AAC3F,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;AAE9C,QAAO,OADGA,KACM5B,SAAS;;;;;AAM1B,SAAgB6E,6BAA6BjD,MAAmD;AAC/F,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;AAE9C,QAAO,OADGA,KACM5B,SAAS;;;;;AAM1B,SAAgB8E,iBAAiBlD,MAAuC;AACvE,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;CAE9C,MAAM2C,IAAI3C;AAGV,QADiB,OAAO2C,EAAE1C,UAAU,YAAa,OAAO0C,EAAE1C,UAAU,YAAY0C,EAAE1C,UAAU,QACzE,OAAO0C,EAAEL,YAAY,YAAY,OAAOK,EAAExE,SAAS;;;;;;AAOvE,SAAgBiF,oBAAoBpD,MAA8B;AAEjE,KAAIA,KAAKC,SAAS,OAAOD,KAAKC,UAAU,UAAU;EACjD,MAAMoD,cAAcrD,KAAKC;AACzB,SAAOoD,YAAYf,WAAWe,YAAYhB,QAAQ;;AAInD,KAAI,OAAOrC,KAAKC,UAAU,SACzB,QAAOD,KAAKC;AAIb,KAAI,OAAOD,KAAKsC,YAAY,SAC3B,QAAOtC,KAAKsC;AAGb,QAAO;;;;;AAMR,SAAgBgB,iBAAiBtD,MAAuC;AACvE,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;CAC9C,MAAM2C,IAAI3C;AACV,QACC,OAAO2C,EAAEjC,aAAa,YACtB6C,MAAMC,QAAQb,EAAEhC,aAAa,IAC7B,OAAOgC,EAAE/B,iBAAiB,YAC1B2C,MAAMC,QAAQb,EAAE9B,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;ACxMnC,SAAOyF,aAAAC,SAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CACN,MAAA,EAAAxB,eAAAC,OAAAC,cAAAC,WAAAC,cAAAE,SAAAE,kBAAAE,0BASIY;CAGJ,MAAA,CAAAG,UAAAC,eAAgC9C,SAAS,MAAM;CAC/C,MAAA,CAAA+C,cAAAC,mBAAwChD,SAAS,MAAM;CACvD,MAAA,CAAAiD,SAAAC,cAA8BlD,SAAS,MAAM;CAC7C,MAAA,CAAAmD,SAAAC,cAA8BpD,SAAS,MAAM;CAC7C,MAAA,CAAAqD,iBAAAC,sBAA8CtD,SAAS,eAAe;CACtE,MAAA,CAAAuD,YAAAC,iBAAoCxD,UAAsC;CAC1E,MAAA,CAAAyD,YAAAC,iBAAoC1D,UAAsC;CAC1E,MAAA,CAAA2D,UAAAC,eAAgC5D,UAAoC;CACpE,MAAA,CAAA2B,OAAAkC,YAA0B7D,UAA8B;CAGxD,MAAA8D,aAAmB/D,OAAqC,KAAK;CAG7D,MAAAgE,eAAqBhE,OAAOwB,UAAU;CACtC,MAAAyC,kBAAwBjE,OAAOyB,aAAa;CAC5C,MAAAyC,aAAmBlE,OAAO2B,QAAQ;CAClC,MAAAwC,sBAA4BnE,OAAO6B,iBAAiB;CACpD,MAAAuC,2BAAiCpE,OAAO+B,sBAAsB;CAAA,IAAAsC;CAAA,IAAAC;AAAA,KAAA1B,EAAA,OAAAb,yBAAAa,EAAA,OAAApB,aAAAoB,EAAA,OAAAnB,gBAAAmB,EAAA,OAAAjB,WAAAiB,EAAA,OAAAf,kBAAA;AAEpDwC,aAAA;AACTL,gBAAYO,UAAW/C;AACvByC,mBAAeM,UAAW9C;AAC1ByC,cAAUK,UAAW5C;AACrBwC,uBAAmBI,UAAW1C;AAC9BuC,4BAAwBG,UAAWxC;;AACjCuC,OAAA;GAAC9C;GAAWC;GAAcE;GAASE;GAAkBE;GAAsB;AAAAa,IAAA,KAAAb;AAAAa,IAAA,KAAApB;AAAAoB,IAAA,KAAAnB;AAAAmB,IAAA,KAAAjB;AAAAiB,IAAA,KAAAf;AAAAe,IAAA,KAAAyB;AAAAzB,IAAA,KAAA0B;QAAA;AAAAD,OAAAzB,EAAA;AAAA0B,OAAA1B,EAAA;;AAN9E9C,WAAUuE,IAMPC,GAA4E;CAAA,IAAAE;AAAA,KAAA5B,EAAA,OAAAvB,eAAA;AAGhDmD,aAAA;AAC9B,OAAI,CAACT,WAAUQ,QACdR,YAAUQ,UAAW,IAAI3D,sBAAsBS,cAA7B;AAClB,UACM0C,WAAUQ;;AACjB3B,IAAA,KAAAvB;AAAAuB,IAAA,KAAA4B;OAAAA,MAAA5B,EAAA;CALD,MAAA6B,aAAmBD;CAKA,IAAAE;CAAA,IAAAC;AAAA,KAAA/B,EAAA,OAAA6B,cAAA7B,EAAA,QAAAtB,OAAA;AAGToD,aAAA;AACT,OAAIpD,MAEHsD,CADgBH,YAAY,CACrBI,SAAUvD,MAAM;;AAEtBqD,OAAA,CAACrD,OAAOmD,WAAW;AAAA7B,IAAA,KAAA6B;AAAA7B,IAAA,MAAAtB;AAAAsB,IAAA,MAAA8B;AAAA9B,IAAA,MAAA+B;QAAA;AAAAD,OAAA9B,EAAA;AAAA+B,OAAA/B,EAAA;;AALtB9C,WAAU4E,IAKPC,GAAoB;CAAA,IAAAG;CAAA,IAAAC;AAAA,KAAAnC,EAAA,QAAA6B,cAAA7B,EAAA,QAAArB,cAAA;AAGbuD,aAAA;AACT,OAAIvD,aAEHqD,CADgBH,YAAY,CACrBQ,gBAAiB1D,aAAa;;AAEpCwD,OAAA,CAACxD,cAAckD,WAAW;AAAA7B,IAAA,MAAA6B;AAAA7B,IAAA,MAAArB;AAAAqB,IAAA,MAAAkC;AAAAlC,IAAA,MAAAmC;QAAA;AAAAD,OAAAlC,EAAA;AAAAmC,OAAAnC,EAAA;;AAL7B9C,WAAUgF,IAKPC,GAA2B;CAAA,IAAAG;CAAA,IAAAC;AAAA,KAAAvC,EAAA,QAAA6B,YAAA;AAGpBS,aAAA;GACT,MAAAE,YAAgBX,YAAY;GAG5B,MAAAY,sBAA2BC,SAAA;AAC1B,QAAI,CAAC9E,wBAAwB8E,KAAK,EAAA;AACjCC,aAAOC,KAAM,oDAAoDF,KAAK;AAAA;;AAIvE/B,uBAAmB+B,KAAIG,MAAO;AAC9B1C,gBAAYuC,KAAIxC,SAAU;AAC1BK,eAAWmC,KAAIpC,QAAS;AACxBD,oBAAgBqC,KAAIG,UAAW,aAAa;AAC5CpC,eAAWiC,KAAIG,UAAW,QAAQ;AAElC,QAAIH,KAAIG,UAAW,YAClBzB,cAAYO,WAAY;aACde,KAAIG,UAAW,eACzBxB,iBAAeM,UAAWe,KAAI5D,mBAAJ,EAA0B;;GAKtD,MAAAgE,oBAAyBC,WAAA;AACxB,QAAIrF,iBAAiBgF,OAAK,CACzB7B,eAAc6B,OAAK;;GAKrB,MAAAM,wBAA6BC,WAAA;AAC5B,QAAI,CAAClF,0BAA0B2E,OAAK,EAAA;AACnCC,aAAOC,KAAM,sDAAsDF,OAAK;AAAA;;AAGzE3B,kBAAc;KAAAmC,MAAQ;KAAMhE,MAAQwD,OAAIxD;KAAKiE,QAAU;KAAM,CAAC;AAC9D5B,wBAAmBI,UAAWe,OAAIxD,KAAM;;GAIzC,MAAAkE,6BAAkCC,WAAA;AACjC,QAAI,CAAC5F,+BAA+BiF,OAAK,CAAA;IAGzC,MAAAxD,OAAawD,OAAIY,SAAUZ,OAAI5B,cAAlB;AACbC,mBAAcwC,UAAW;KAAAL,MAClB;KAAWhE,MACXqE,MAAIL,SAAW,cAAcK,KAAIrE,OAAQA,OAAzCA;KAAoDiE,QAClD;KACR,EAAE;;GAIJ,MAAAK,iCAAsCC,WAAA;AACrC,QAAI,CAAChG,+BAA+BiF,OAAK,CAAA;IAGzC,MAAAgB,SAAahB,OAAI5B,cAAJ;AACbC,kBAAc;KAAAmC,MAAQ;KAAWhE,MAAEA;KAAIiE,QAAU;KAAM,CAAC;AACxD3B,6BAAwBG,UAAWzC,OAAK;;GAIzC,MAAAyE,yBAA8BC,WAAA;AAC7B,QAAI,CAAC9F,2BAA2B4E,OAAK,EAAA;AACpCC,aAAOC,KAAM,wDAAwDF,OAAK;AAAA;;AAG3EzB,gBAAY;KAAA4C,QAAU;KAASC,UAAYpB,OAAIqB;KAAO,CAAC;;GAIxD,MAAAC,2BAAgCC,WAAA;AAC/B,QAAI,CAACpG,6BAA6B6E,OAAK,EAAA;AACtCC,aAAOC,KAAM,0DAA0DF,OAAK;AAAA;;AAG7EzB,gBAAY;KAAA4C,QAAU;KAAWC,UAAYpB,OAAIqB;KAAK/E,OAAS0D,OAAI1D;KAAQ,CAAC;AAG5EkF,qBACC;AACCjD,iBAAYkD,OAAU;OAEvBzB,OAAI1D,QAAJzB,sCAAAD,8BACA;;GAIF,MAAA8G,eAAoBC,WAAA;AACnB,QAAI,CAAC1G,iBAAiB+E,OAAK,EAAA;AAC1BxB,cAAS,gBAAgB;AACzBT,gBAAW,KAAK;AAChBa,gBAAUK,UAAW,gBAAgB;AAAA;;IAItC,MAAA2C,WAAiB9G,oBAAoBkF,OAAK;AAC1CxB,aAASoD,SAAS;AAClB7D,eAAW,KAAK;AAChBa,eAAUK,UAAW2C,SAAS;;AAI/BtC,aAAOuC,GAAI,iBAAiB9B,mBAAmB;AAC/CT,aAAOuC,GAAI,eAAezB,iBAAiB;AAC3Cd,aAAOuC,GAAI,wBAAwBvB,qBAAqB;AACxDhB,aAAOuC,GAAI,wBAAwBnB,0BAA0B;AAC7DpB,aAAOuC,GAAI,6BAA6Bf,8BAA8B;AACtExB,aAAOuC,GAAI,qBAAqBZ,sBAAsB;AACtD3B,aAAOuC,GAAI,uBAAuBP,wBAAwB;AAC1DhC,aAAOuC,GAAI,SAASH,YAAY;AAAA,gBAGzB;AACNpC,cAAOwC,IAAK,iBAAiB/B,mBAAmB;AAChDT,cAAOwC,IAAK,eAAe1B,iBAAiB;AAC5Cd,cAAOwC,IAAK,wBAAwBxB,qBAAqB;AACzDhB,cAAOwC,IAAK,wBAAwBpB,0BAA0B;AAC9DpB,cAAOwC,IAAK,6BAA6BhB,8BAA8B;AACvExB,cAAOwC,IAAK,qBAAqBb,sBAAsB;AACvD3B,cAAOwC,IAAK,uBAAuBR,wBAAwB;AAC3DhC,cAAOwC,IAAK,SAASJ,YAAY;;;AAEhC7B,OAAA,CAACV,WAAW;AAAA7B,IAAA,MAAA6B;AAAA7B,IAAA,MAAAsC;AAAAtC,IAAA,MAAAuC;QAAA;AAAAD,OAAAtC,EAAA;AAAAuC,OAAAvC,EAAA;;AA7Hf9C,WAAUoF,IA6HPC,GAAa;CAAA,IAAAkC;AAAA,KAAAzE,EAAA,QAAA6B,YAAA;AAIf4C,OAAA,OAAAnF,WAAA;AACC,OAAA;AACCe,oBAAgB,KAAK;AACrBI,eAAW,MAAM;AACjBS,aAASiD,OAAU;AAGnB,UADgBtC,YAAY,CACfxC,aAAcC,OAAO;YAAAqF,OAAA;IAC1BC,MAAAA,MAAAA;AACRvE,oBAAgB,MAAM;AACtBI,eAAW,KAAK;IAChB,MAAAoE,aAAiBD,eAAeE,QAAQF,IAAGG,UAA1B;AACjB7D,aAASoD,WAAS;AAClBhD,eAAUK,UAAW2C,WAAS;;;AAE/BtE,IAAA,MAAA6B;AAAA7B,IAAA,MAAAyE;OAAAA,MAAAzE,EAAA;CAhBF,MAAAX,eAAqBoF;CAkBpB,IAAAE;AAAA,KAAA3E,EAAA,QAAA6B,YAAA;AAG+B8C,cAAA;AAE/B3C,GADgBH,YAAY,CACrBrC,aAAc;AACrBqB,iBAAcsD,OAAU;AACxBpD,iBAAcoD,OAAU;AACxBlD,eAAYkD,OAAU;;AACtBnE,IAAA,MAAA6B;AAAA7B,IAAA,MAAA2E;OAAAA,OAAA3E,EAAA;CAND,MAAAR,cAAoBmF;CAMJ,IAAAM;AAAA,KAAAjF,EAAA,QAAA6B,cAAA7B,EAAA,QAAAM,SAAA;AAIf2E,SAAAvF,UAAA;GACC,MAAAwF,YAAgBrD,YAAY;GAC5B,MAAAsD,WAAiBzF,UAAUyE,SAAVzE,QAAA,CAA+BY;AAChD0B,aAAOvC,WAAY0F,SAAS;AAC5B5E,cAAW4E,SAAS;;AACpBnF,IAAA,MAAA6B;AAAA7B,IAAA,MAAAM;AAAAN,IAAA,MAAAiF;OAAAA,OAAAjF,EAAA;CANF,MAAAP,aAAmBwF;CAQlB,IAAAG;AAAA,KAAApF,EAAA,QAAA6B,YAAA;AAIAuD,SAAAC,WAAA;GACC,MAAAC,YAAgBzD,YAAY;AAC5B,OAAIG,UAAOuD,iBAAkB,CAC5BvD,WAAOwD,gBAAiBtG,OAAK;;AAE9Bc,IAAA,MAAA6B;AAAA7B,IAAA,MAAAoF;OAAAA,OAAApF,EAAA;CANF,MAAAL,cAAoByF;CAQnB,IAAAK;AAAA,KAAAzF,EAAA,QAAA6B,YAAA;AAG8B4D,cAAA;AAE9BzD,GADgBH,YAAY,CACrBjC,YAAa;;AACpBI,IAAA,MAAA6B;AAAA7B,IAAA,MAAAyF;OAAAA,OAAAzF,EAAA;CAHD,MAAAJ,aAAmB6F;CAGH,IAAAE;AAAA,KAAA3F,EAAA,QAAA6B,YAAA;AAGgB8D,cAAA;AAE/B3D,GADgBH,YAAY,CACrBhC,aAAc;;AACrBG,IAAA,MAAA6B;AAAA7B,IAAA,MAAA2F;OAAAA,OAAA3F,EAAA;CAHD,MAAAH,cAAoB8F;CAGJ,IAAAE;AAAA,KAAA7F,EAAA,QAAAY,cAAAZ,EAAA,QAAAU,mBAAAV,EAAA,QAAAhB,SAAAgB,EAAA,QAAAE,YAAAF,EAAA,QAAAI,gBAAAJ,EAAA,QAAAQ,WAAAR,EAAA,QAAAM,WAAAN,EAAA,QAAAJ,cAAAI,EAAA,QAAAH,eAAAG,EAAA,QAAAL,eAAAK,EAAA,QAAAX,gBAAAW,EAAA,QAAAR,eAAAQ,EAAA,QAAAP,cAAAO,EAAA,QAAAgB,YAAAhB,EAAA,QAAAc,YAAA;AAIR+E,QAAA;GAAA3F;GAAAE;GAAAE;GAAAE;GAAAE;GAAAE;GAAAE;GAAAE;GAAAhC;GAAAK;GAAAG;GAAAC;GAAAE;GAAAC;GAAAC;GAgBN;AAAAG,IAAA,MAAAY;AAAAZ,IAAA,MAAAU;AAAAV,IAAA,MAAAhB;AAAAgB,IAAA,MAAAE;AAAAF,IAAA,MAAAI;AAAAJ,IAAA,MAAAQ;AAAAR,IAAA,MAAAM;AAAAN,IAAA,MAAAJ;AAAAI,IAAA,MAAAH;AAAAG,IAAA,MAAAL;AAAAK,IAAA,MAAAX;AAAAW,IAAA,MAAAR;AAAAQ,IAAA,MAAAP;AAAAO,IAAA,MAAAgB;AAAAhB,IAAA,MAAAc;AAAAd,IAAA,MAAA6F;OAAAA,OAAA7F,EAAA;AAAA,QAhBM6F;;;;;AClUT,MAAMW,mBAAmBV,cAA4C,KAAK;;;;AAyB1E,SAASwB,wBAAiC;AACzC,QAAO,CAAC,EACP,OAAOC,WAAW,eAClBA,OAAOC,qBACPC,UAAUC,cAAcC;;AAI1B,SAAOC,kBAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAA2B,MAAA,EAAArB,UAAAC,eAAAC,OAAAC,cAAAC,WAAAC,cAAAE,SAAAE,kBAAAE,0BAAAQ;CAUT,IAAAG;AAAA,KAAAF,EAAA,OAAAT,yBAAAS,EAAA,OAAAhB,aAAAgB,EAAA,OAAAf,gBAAAe,EAAA,OAAAb,WAAAa,EAAA,OAAAX,oBAAAW,EAAA,OAAAnB,iBAAAmB,EAAA,OAAAjB,gBAAAiB,EAAA,OAAAlB,OAAA;AACOoB,OAAA;GAAArB;GAAAC;GAAAC;GAAAC;GAAAC;GAAAE;GAAAE;GAAAE;GAS9B;AAAAS,IAAA,KAAAT;AAAAS,IAAA,KAAAhB;AAAAgB,IAAA,KAAAf;AAAAe,IAAA,KAAAb;AAAAa,IAAA,KAAAX;AAAAW,IAAA,KAAAnB;AAAAmB,IAAA,KAAAjB;AAAAiB,IAAA,KAAAlB;AAAAkB,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CATD,MAAAG,YAAkBhC,aAAa+B,GAS7B;CAAA,IAAAE;AAAA,KAAAJ,EAAA,OAAAK,OAAAC,IAAA,4BAAA,EAAA;AAEgCF,OAAAZ,uBAAuB;AAAAQ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAzD,MAAAvB,cAAkC2B;CAA4B,IAAAG;AAAA,KAAAP,EAAA,QAAAG,WAAA;AAGtDI,OAAA;GAAA,GACHJ;GAAS1B;GAEZ;AAAAuB,IAAA,MAAAG;AAAAH,IAAA,MAAAO;OAAAA,MAAAP,EAAA;CAJF,MAAAQ,QACQD;CAKP,IAAAE;AAAA,KAAAT,EAAA,QAAApB,YAAAoB,EAAA,QAAAQ,OAAA;AAEMC,OAAA,oBAAA,iBAAA;GAAkCD;GAAQ5B;IAAqC;AAAAoB,IAAA,MAAApB;AAAAoB,IAAA,MAAAQ;AAAAR,IAAA,MAAAS;OAAAA,MAAAT,EAAA;AAAA,QAA/ES;;;;;AAiBR,SAAOI,8BAAA;AAAA,QACC5C,WAAWS,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/BpC,MAAM8D,2BAA2B1B,cAAoD,KAAK;;;;;;AAmB1F,MAAaiC,6BAAiE,EAC7EL,UACAC,UAAUrB,2BACVsB,WACAC,WACAC,aACK;CAEL,MAAM,CAACd,iBAAiBgB,sBAAsB5B,SAAsC,KAAK;CAGzF,MAAM,CAACe,kBAAkBc,uBAAuB7B,SAAS,EAAE;CAG3D,MAAM8B,aAAa/B,OAA6C,KAAK;CACrE,MAAMiC,eAAejC,OAA6C,KAAK;CACvE,MAAMoC,iBAAiBpC,OAA8C,KAAK;CAG1E,MAAMsC,eAAetC,OAAOyB,UAAU;CACtC,MAAMc,eAAevC,OAAO0B,UAAU;CACtC,MAAMc,YAAYxC,OAAO2B,OAAO;AAChCW,cAAaG,UAAUhB;AACvBc,cAAaE,UAAUf;AACvBc,WAAUC,UAAUd;;;;CAKpB,MAAMe,cAAc9C,kBAAkB;AACrC,MAAIqC,aAAaQ,SAAS;AACzBE,gBAAaV,aAAaQ,QAAQ;AAClCR,gBAAaQ,UAAU;;AAExB,MAAIL,eAAeK,SAAS;AAC3BG,iBAAcR,eAAeK,QAAQ;AACrCL,kBAAeK,UAAU;;IAExB,EAAE,CAAC;;;;CAKN,MAAMI,kBAAkBjD,aACtBoC,UAAmBc,SAAyCd,WAAW,YAAY,WAAW;EAC9F,MAAMxB,WAAWK,iBAAiBL;AAGlC,MAAIuB,WAAWU,SAAS;AACvBV,cAAWU,QAAQT,SAAS;AAC5BD,cAAWU,UAAU;;AAItBC,eAAa;AACbb,qBAAmB,KAAK;AACxBC,sBAAoB,EAAE;AAGtB,MAAItB,SACH,KAAIsC,WAAW,UACdR,cAAaG,UAAUjC,SAAS;WACtBsC,WAAW,UACrBP,cAAaE,UAAUjC,SAAS;MAEhCgC,WAAUC,UAAUjC,SAAS;IAIhC,CAACK,iBAAiBL,UAAUkC,YAC7B,CAAC;;;;CAKD,MAAM5B,UAAUlB,kBAAkB;AACjC,MAAIiB,gBACHgC,iBAAgB,MAAM,UAAU;IAE/B,CAAChC,iBAAiBgC,gBAAgB,CAAC;;;;CAKtC,MAAM9B,OAAOnB,kBAAkB;AAC9B,MAAIiB,gBACHgC,iBAAgB,OAAO,OAAO;IAE7B,CAAChC,iBAAiBgC,gBAAgB,CAAC;;;;CAKtC,MAAMzB,uBAAuBxB,kBAAkB;AAC9C,MAAImC,WAAWU,SAAS;AACvBV,cAAWU,QAAQ,MAAM;AACzBV,cAAWU,UAAU;;AAEtBC,eAAa;AACbb,qBAAmB,KAAK;AACxBC,sBAAoB,EAAE;IACpB,CAACY,YAAY,CAAC;;;;;CAMjB,MAAMxB,kBAAkBtB,aACtBW,QAAgBC,YAAkBC,SAAoD;AACtF,SAAO,IAAIU,SAAS4B,YAAY;AAE/B,OAAIhB,WAAWU,QACdV,YAAWU,QAAQ,MAAM;AAE1BC,gBAAa;AAGbX,cAAWU,UAAUM;AAGrBlB,sBAAmB;IAClBtB;IACAC,UAAAA;IACAC;IACAE,WAAWqC,KAAKC,KAAI;IACpB,CAAC;AAIFnB,uBADuBqB,KAAKC,KAAK5B,UAAU,IAAK,CACb;AAGnCY,kBAAeK,UAAUJ,kBAAkB;AAC1CP,yBAAqBuB,SAAS;AAC7B,SAAIA,QAAQ,EACX,QAAO;AAER,YAAOA,OAAO;MACb;MACAnD,qCAAqC;AAGxC+B,gBAAaQ,UAAUN,iBAAiB;AAEvC,QAAIJ,WAAWU,SAAS;AACvBV,gBAAWU,QAAQ,MAAM;AACzBV,gBAAWU,UAAU;;AAEtBC,iBAAa;AACbb,uBAAmB,KAAK;AACxBC,wBAAoB,EAAE;AACtBQ,iBAAaG,UAAUjC,WAAS;MAC9BgB,QAAQ;IACV;IAEH,CAACA,SAASkB,YACX,CAAC;AAGD5C,iBAAgB;AACf,eAAa;AACZ4C,gBAAa;AACb,OAAIX,WAAWU,SAAS;AACvBV,eAAWU,QAAQ,MAAM;AACzBV,eAAWU,UAAU;;;IAGrB,CAACC,YAAY,CAAC;CAEjB,MAAMY,QAAQvD,eACN;EACNc;EACAC;EACAC;EACAC;EACAC,sBAAsBJ,oBAAoB;EAC1CK;EACAE;EACA,GACD;EAACP;EAAiBC;EAASC;EAAMC;EAAkBE;EAAiBE;EACrE,CAAC;AAED,QACC,oBAAC,yBAAyB;EAAgBkC;EAAQ/B;GAA6C;;;;;;AAoBjG,SAAOmC,+BAAA;AAAA,QACC7D,WAAWwB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;ACjL5C,MAAMwG,qBAAqBhE,cAA8C,KAAK;;;;AAK9E,SAASiE,oBAA4B;AACpC,QAAO,SAASC,KAAKC,KAAK,CAAA,GAAIC,KAAKC,QAAQ,CAACC,SAAS,GAAG,CAACC,MAAM,GAAG,EAAE;;;;;AAMrE,SAASC,wBAAwBC,MAAsC;AACtE,QAAO;EACNC,MAAMD,KAAKC;EACXC,aAAaF,KAAKE,eAAe;EACjCC,aAAcH,KAAKG,eAAe;GAAEhB,MAAM;GAAUiB,YAAY,EAAC;GAAG;EAIpE;;;;;;AAmBF,MAAMQ,yBAQA,EAAEN,UAAUjC,WAAWwC,cAAcE,gBAAgBP,WAAWC,cAAcE,cAAc;CACjG,MAAMK,gBAAgB1F,kBAAkB;CACxC,MAAM2F,YAAY3E,6BAA6B;CAG/C,MAAM4E,wBAAwBtF,OAAe,GAAG;CAChD,MAAMuF,6BAA6BvF,OAAe,GAAG;CACrD,MAAMwF,eAAexF,OAAO,MAAM;CAGlC,MAAMyF,eAAezF,OAAO4E,UAAU;CACtC,MAAMc,kBAAkB1F,OAAO6E,aAAa;CAC5C,MAAMc,aAAa3F,OAAO+E,QAAQ;AAClCU,cAAaG,UAAUhB;AACvBc,iBAAgBE,UAAUf;AAC1Bc,YAAWC,UAAUb;;;;;AAMrBjF,iBAAgB;AACfqF,iBAAeS,WAAW9D,SAA4B;AACrD,OAAI,CAACW,WAAW;AACfoD,YAAQC,KAAK,mEAAmE;AAChF;;AAKDV,iBAAcW,OAAO;IACpBC,MAAM;IACNC,SAAS,CACR;KACC1C,MAAM;KACNjC,YAAYQ,KAAKR;KACjBC,UAAUO,KAAKP;KACfC,MAAMM,KAAKN;KACX0E,UAAUC,KAAKC,UAAUtE,KAAKN,KAAK;KACnCE,QAAQI,KAAKJ;KACbC,SAASG,KAAKH;KACdC,UAAUE,KAAKF;KACf,CACD;IACDyE,UAAU,EACTC,QAAQ;KACPtE,QAAQ;KACRC,gBAAgBQ;KAChBP,WAAW2B,KAAKC,KAAI;KACrB,EACD;IAEA,CAAQ;;AAGV,eAAa;AACZqB,kBAAeS,UAAU;;IAExB;EAACR;EAAe3C;EAAW0C;EAAe,CAAC;;;;CAK9C,MAAMoB,iBAAiB3G,aACrBoD,SAAiB;AACjB,MAAI,CAACP,aAAa,CAACO,KAAKwD,MAAM,CAAE;EAIhC,MAAMH,WAAgB,EACrBC,QAAQ;GACPtE,QAAQ;GACRC,gBAAgBQ;GAChBP,WAAW2B,KAAKC,KAAI;GACrB,EACA;AAEDsB,gBAAcW,OAAO;GACpBC,MAAM;GACNC,SAAS,CAAC;IAAE1C,MAAM;IAAQP;IAAM,CAAC;GACjCqD;GACA,CAAC;IAEH,CAACjB,eAAe3C,UACjB,CAAC;;;;CAKD,MAAMgE,sBAAsB7G,aAC1BoD,WAAiB;AACjB,MAAI,CAACP,aAAa,CAACO,OAAKwD,MAAM,CAAE;EAIhC,MAAMH,aAAgB,EACrBC,QAAQ;GACPtE,QAAQ;GACRC,gBAAgBQ;GAChBP,WAAW2B,KAAKC,KAAI;GACrB,EACA;AAEDsB,gBAAcW,OAAO;GACpBC,MAAM;GACNC,SAAS,CAAC;IAAE1C,MAAM;IAAQP,MAAAA;IAAM,CAAC;GACjCqD,UAAAA;GACA,CAAC;IAEH,CAACjB,eAAe3C,UACjB,CAAC;AAGD3C,iBAAgB;AACf,MAAI,CAACuF,UAAW;EAEhB,MAAMjD,WAAWiD,UAAUjD,YAAYiD,UAAUhD;AAGjD,MAAI,CAACmD,aAAaI,WAAWxD,YAAY,CAACK,UAEzCwC,cADqBrB,mBAAmB,CACd;AAI3B,MAAI,CAAC4B,aAAaI,WAAWP,UAAUjD,SACtCqD,cAAaG,WAAW;AAIzB,MAAIJ,aAAaI,WAAW,CAACxD,UAAU;AAItC,OAAImD,2BAA2BK,SAAS;AACvCa,wBAAoBlB,2BAA2BK,QAAQ;AACvDL,+BAA2BK,UAAU;;AAEtCN,yBAAsBM,UAAU;AAGhCvF,8BAA2B+E,eAAelF,2BAA2ByG,aAAa;AAGlF1B,gBAAa,KAAK;AAGlBS,mBAAgBE,UAAU,EAAE;;AAG7BJ,eAAaI,UAAUxD;IACrB;EACFiD,WAAWjD;EACXiD,WAAWhD;EACXI;EACAwC;EACAwB;EACArB;EACA,CAAC;AAGFtF,iBAAgB;AACf,MAAI,CAACuF,WAAW/B,cAAc,CAACb,UAAW;EAE1C,MAAM,EAAEc,MAAMP,MAAAA,QAAMQ,WAAW6B,UAAU/B;AAEzC,MAAIC,SAAS,UAAUC,UAAUR,WAASsC,sBAAsBM,SAAS;AAExE,OAAIL,2BAA2BK,SAAS;AACvCa,wBAAoBlB,2BAA2BK,QAAQ;AACvDL,+BAA2BK,UAAU;;AAItCW,kBAAevD,OAAK;AACpBsC,yBAAsBM,UAAU5C;aACtBO,SAAS,eAAeC,UAAUR,WAASuC,2BAA2BK,QAIhFL,4BAA2BK,UAAU5C;IAEpC;EAACqC,WAAW/B;EAAYb;EAAW8D;EAAgBE;EAAoB,CAAC;AAG3E3G,iBAAgB;AACf,MAAIuF,WAAW1D,WAAW0D,WAAW7C,MACpCmD,YAAWC,UAAUP,UAAU7C,MAAM;IAEpC,CAAC6C,WAAW1D,SAAS0D,WAAW7C,MAAM,CAAC;AAE1C,QAAO,gCAAGkC,WAAY;;;;;;AAOvB,MAAMkC,4BAUDE,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAtC,UAAAC,eAAAkC,YAAApE,WAAAwC,cAAAE,gBAAAP,WAAAC,cAAAE,YAAA+B;CAWL,MAAAG,WAAiBzG,qBAAqB;CACtC,MAAA0G,eAAqBzG,yBAAyB;CAC9C,MAAA0G,oBAA0BvG,8BAA8B;CACxD,MAAAwE,gBAAsB1F,kBAAkB;CACxC,MAAA0H,iBAAuB3H,UAAU4H,SAAkB;CAAA,IAAAC;AAAA,KAAAP,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAKlDF,uBAAA,IAAIG,KAAK;AAAAV,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CADV,MAAAW,0BAAgC1H,OAC/BsH,GACA;CAAA,IAAAK;AAAA,KAAAZ,EAAA,OAAAE,YAAAF,EAAA,OAAA3B,iBAAA2B,EAAA,OAAAG,gBAAAH,EAAA,OAAAI,mBAAA;AAKAQ,OAAA,OAAAtD,MAAA7C,SAAA;AACC,OAAI,CAACyF,UAAQW,SACZ,OAAM,IAAIC,MAAM,0BAA0B;GAI3C,MAAAzD,OAAa6C,SAAQa,MAAMC,MAAMC,QAAOC,IAAC5D,SAAUA,KAAK;AAGxD,OAFsBD,QAAQ8C,cAAYiB,iBAAmB/D,KAAK,IAE9D+C,mBAAkC;IAErC,MAAAiB,SAAe,SAASvE,KAAIC,KAAM,CAAA,GAAIC,KAAIC,QAAS,CAAAC,SAAU,GAAG,CAAAC,MAAO,GAAG,EAAE;IAG5E,MAAAmE,WAAiB,MAAMlB,kBAAiBmB,gBAAiBF,QAAQ/D,MAAM7C,KAAK;IAG5E,MAAA+G,gBAAsBF,WAAWnI,2BAA0BsI,UAArCrI;AAKtB,QAJoBG,iCAAiC8E,eAAef,MAAMkE,cAAc,KAIpE,GAAC;KACpB,MAAAG,QAAchB,wBAAuB9B,QAAQ+C,IAAKtE,KAAW,IAA/C,EAA+C;AAC7DqE,WAAKE,KAAM;MAAAlH,QAAU6G;MAAarG,WAAa2B,KAAIC,KAAK;MAAG,CAAC;AAC5D4D,6BAAuB9B,QAAQiD,IAAKxE,MAAMqE,MAAM;;AAGjD,QAAI,CAACL,SAAQ,QAELlI;;GAKT,MAAAuB,SAAe,MAAMuF,SAAQW,SAAUvD,MAAM7C,KAAK;AAMjD,WAHmBE,OAAMuE,SAAc8B,KACvCgB,SAEA,GACiB/F,QAAUmD,KAAIC,UAAW1E,OAAO;;AAClDqF,IAAA,KAAAE;AAAAF,IAAA,KAAA3B;AAAA2B,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CA5CF,MAAAiC,eAAmCrB;CA8ClC,IAAAsB;AAAA,KAAAlC,EAAA,OAAA3B,eAAA;AAGS6D,aAAA;AACT,OAAIvB,wBAAuB9B,QAAQsD,SAAU,EAAC;GAE9C,MAAApF,MAAYD,KAAIC,KAAM;AACtB,QAAK,MAAA,CAAAvC,UAAA4H,YAA2B,CAAA,GAAIzB,wBAAuB9B,QAAQwD,SAAU,CAAC,EAAA;IAC7E,MAAAC,aAAmBX,QAAKY,QAAQC,SAAA;KAAC,MAAA,EAAArH,cAAAqH;AAAa,YAAKzF,MAAM5B,aAzD3B;MAyDgE;AAC9F,QAAImH,WAAUG,WAAY,GAAC;AAC1B9B,6BAAuB9B,QAAQ6D,OAAQlI,SAAS;AAChD;;IAGD,MAAAmI,eAAqBtJ,0BAA0BgF,eAAe7D,SAAS;IAGvE,IAAAoI,aAAiB;AACjB,SAAK,MAAAC,QAAcF,cAAY;AAC9B,SAAIC,cAAcN,WAAUG,OAAS;KACrC,MAAA,EAAA9H,QAAAmI,aAAmBR,WAAWM;AAC9B,SAAIpJ,uBAAuB6E,eAAewE,KAAIE,WAAYF,KAAItI,YAAaI,SAAO,CACjFiI;;AAIF,QAAIA,cAAcN,WAAUG,OAC3B9B,yBAAuB9B,QAAQ6D,OAAQlI,SAAS;QAEhDmG,yBAAuB9B,QAAQiD,IAAKtH,UAAU8H,WAAUnF,MAAOyF,WAAW,CAAC;;;AAG7E5C,IAAA,KAAA3B;AAAA2B,IAAA,KAAAkC;OAAAA,MAAAlC,EAAA;CAAA,IAAAwC;AAAA,KAAAxC,EAAA,OAAAK,kBAAAL,EAAA,OAAA3B,eAAA;AAAEmE,OAAA,CAACnC,gBAAgBhC,cAAc;AAAA2B,IAAA,KAAAK;AAAAL,IAAA,KAAA3B;AAAA2B,IAAA,MAAAwC;OAAAA,MAAAxC,EAAA;AA7BlCjH,WAAUmJ,IA6BPM,GAAgC;CAAA,IAAAQ;AAAA,KAAAhD,EAAA,QAAArC,YAAAqC,EAAA,QAAAtE,WAAA;AAYhCsH,OAAA,oBAAC;GAAsCtH;GAAYiC;IAAsC;AAAAqC,IAAA,MAAArC;AAAAqC,IAAA,MAAAtE;AAAAsE,IAAA,MAAAgD;OAAAA,MAAAhD,EAAA;CAAA,IAAAiD;AAAA,KAAAjD,EAAA,QAAA5B,kBAAA4B,EAAA,QAAAnC,aAAAmC,EAAA,QAAAlC,gBAAAkC,EAAA,QAAAhC,WAAAgC,EAAA,QAAAtE,aAAAsE,EAAA,QAAA9B,gBAAA8B,EAAA,QAAAgD,IAAA;AAR1FC,OAAA,oBAAC;GACWvH;GACGwC;GACEE;GACLP;GACGC;GACLE;aAETgF;IACuB;AAAAhD,IAAA,MAAA5B;AAAA4B,IAAA,MAAAnC;AAAAmC,IAAA,MAAAlC;AAAAkC,IAAA,MAAAhC;AAAAgC,IAAA,MAAAtE;AAAAsE,IAAA,MAAA9B;AAAA8B,IAAA,MAAAgD;AAAAhD,IAAA,MAAAiD;OAAAA,MAAAjD,EAAA;CAAA,IAAAkD;AAAA,KAAAlD,EAAA,QAAAiD,MAAAjD,EAAA,QAAApC,iBAAAoC,EAAA,QAAAiC,gBAAAjC,EAAA,QAAAF,YAAA;AAVzBoD,OAAA,oBAAC;GAAiCtF;GAAsBkC,OAAAA;GAA0BmC;aACjFgB;IAUmB;AAAAjD,IAAA,MAAAiD;AAAAjD,IAAA,MAAApC;AAAAoC,IAAA,MAAAiC;AAAAjC,IAAA,MAAAF;AAAAE,IAAA,MAAAkD;OAAAA,MAAAlD,EAAA;AAAA,QAXpBkD;;;;;;;;;;;;;;;;;AA8BF,MAAaC,qBAAiD,EAC7DxF,UACAC,eACAC,WACAC,cACAE,cACK;CACL,MAAMkC,WAAWzG,qBAAqB;CAGtC,MAAM,CAACiC,WAAWwC,gBAAgBhF,SAAwB,KAAK;CAG/D,MAAMkF,iBAAiBnF,OAAmC,KAAK;AAQ/D,QACC,oBAAC,uCACA,oBAAC;EACe2E;EACf,YATgB5E,cAAgC;AAClD,OAAI,CAACkH,UAAUa,MAAO,QAAO,EAAE;AAC/B,UAAOb,SAASa,MAAMqC,IAAIhG,wBAAwB;KAChD,CAAC8C,UAAUa,MAAM,CAAC;EAOPrF;EACGwC;EACEE;EACLP;EACGC;EACLE;EAERL;GACwB,GACC;;;;;AAO9B,MAAM0F,8BAAoFtD,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAtC,UAAAjC,cAAAqE;CAI1F,MAAAzB,YAAkB3E,6BAA6B;CAAA,IAAA4G;AAAA+C,MAAA;AAI9C,MAAI,CAAChF,WAAS;AAAEiC,QAAO;AAAP,SAAA+C;;EAAW,IAAA1C;AAAA,MAAAZ,EAAA,OAAA1B,UAAAlC,YAAA;AAUdwE,UAAAtC,UAASlC,aAAT;IAAAC,UAECiC,UAASlC,WAAWC;IAASC,cACzBgC,UAASlC,WAAWE;IAEzB,GALAiH;AAKAvD,KAAA,KAAA1B,UAAAlC;AAAA4D,KAAA,KAAAY;QAAAA,QAAAZ,EAAA;EAAA,IAAAkC;AAAA,MAAAlC,EAAA,OAAA1B,UAAA/B,YAAA;AACA2F,QAAA5D,UAAS/B,aAAT;IAAAC,MAEH8B,UAAS/B,WAAWC;IAAKP,MACzBqC,UAAS/B,WAAWN;IAAKQ,QACvB6B,UAAS/B,WAAWE;IAEnB,GANA8G;AAMAvD,KAAA,KAAA1B,UAAA/B;AAAAyD,KAAA,KAAAkC;QAAAA,MAAAlC,EAAA;EAAA,IAAAwC;AAAA,MAAAxC,EAAA,OAAA1B,UAAA5B,UAAA;AACF8F,QAAAlE,UAAS5B,WAAT;IAAAC,QAEC2B,UAAS5B,SAASC;IAAOnC,UACvB8D,UAAS5B,SAASlC;IAASiB,OAC9B6C,UAAS5B,SAASjB;IAEhB,GANF8H;AAMEvD,KAAA,KAAA1B,UAAA5B;AAAAsD,KAAA,KAAAwC;QAAAA,MAAAxC,EAAA;EAAA,IAAAgD;AAAA,MAAAhD,EAAA,OAAAtE,aAAAsE,EAAA,OAAAY,QAAAZ,EAAA,OAAAkC,MAAAlC,EAAA,OAAAwC,MAAAxC,EAAA,QAAA1B,UAAA7C,SAAAuE,EAAA,QAAA1B,UAAAjD,YAAA2E,EAAA,QAAA1B,UAAAhD,gBAAA0E,EAAA,QAAA1B,UAAA1D,WAAAoF,EAAA,QAAA1B,UAAA/C,WAAAyE,EAAA,QAAA1B,UAAA9C,eAAAwE,EAAA,QAAA1B,UAAApC,cAAA8D,EAAA,QAAA1B,UAAAnC,eAAA6D,EAAA,QAAA1B,UAAAtC,eAAAgE,EAAA,QAAA1B,UAAAkF,gBAAAxD,EAAA,QAAA1B,UAAAmF,eAAAzD,EAAA,QAAA1B,UAAAxC,YAAA;AA3BNkH,QAAA;IAAA3H,UACIiD,UAASjD;IAASC,cACdgD,UAAShD;IAAaV,SAC3B0D,UAAS1D;IAAQW,SACjB+C,UAAS/C;IAAQC,aACb8C,UAAS9C;IAAYC,OAC3B6C,UAAS7C;IAAMC;IAAAU,YAEVwE;IAKArE,YACA2F;IAMAxF,UACF8F;IAME7G,OACL2C,UAASkF;IAAa3H,MACvByC,UAASmF;IAAY3H,YACfwC,UAASxC;IAAWE,aACnBsC,UAAStC;IAAYE,YACtBoC,UAASpC;IAAWC,aACnBmC,UAASnC;IACtB;AAAA6D,KAAA,KAAAtE;AAAAsE,KAAA,KAAAY;AAAAZ,KAAA,KAAAkC;AAAAlC,KAAA,KAAAwC;AAAAxC,KAAA,MAAA1B,UAAA7C;AAAAuE,KAAA,MAAA1B,UAAAjD;AAAA2E,KAAA,MAAA1B,UAAAhD;AAAA0E,KAAA,MAAA1B,UAAA1D;AAAAoF,KAAA,MAAA1B,UAAA/C;AAAAyE,KAAA,MAAA1B,UAAA9C;AAAAwE,KAAA,MAAA1B,UAAApC;AAAA8D,KAAA,MAAA1B,UAAAnC;AAAA6D,KAAA,MAAA1B,UAAAtC;AAAAgE,KAAA,MAAA1B,UAAAkF;AAAAxD,KAAA,MAAA1B,UAAAmF;AAAAzD,KAAA,MAAA1B,UAAAxC;AAAAkE,KAAA,MAAAgD;QAAAA,MAAAhD,EAAA;AAlCDO,OAAOyC;;CAHR,MAAAU,eAAqBnD;AAwCrB,KAAI,CAACmD,cAAY;EAAA,IAAA9C;AAAA,MAAAZ,EAAA,QAAArC,UAAA;AACTiD,UAAA,gCAAGjD,WAAY;AAAAqC,KAAA,MAAArC;AAAAqC,KAAA,MAAAY;QAAAA,QAAAZ,EAAA;AAAA,SAAfY;;CACP,IAAAA;AAAA,KAAAZ,EAAA,QAAArC,YAAAqC,EAAA,QAAA0D,cAAA;AAEM9C,OAAA,oBAAA,mBAAA;GAAoC8C,OAAAA;GAAe/F;IAAuC;AAAAqC,IAAA,MAAArC;AAAAqC,IAAA,MAAA0D;AAAA1D,IAAA,MAAAY;OAAAA,MAAAZ,EAAA;AAAA,QAA1FY;;;;;AAkBR,SAAOiD,yBAAA;AAAA,QACC/K,WAAW8D,mBAAmB;;AAxPjC,SAAA0D,SAAAY,GAAA;AAAA,QAeoCA,EAAC6C;;AAfrC,SAAA/B,SAAAgC,KAAA;AAAA,QAkEAA,IAACxH,SAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpShB,SAAOsL,WAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAEN,MAAAC,iBAAuBhE,UAAUiE,SAA4B;CAC7D,MAAAd,YAAkBnD,UAAUkE,SAA6B;CAGzD,MAAAb,UAAgBlD,YAAY;CAC5B,MAAAmD,gBAAsBlD,kBAAkB;CACxC,MAAAmD,gBAAsBjD,iBAAiB,EAAE;CACzC,MAAAkD,sBAA4BnD,wBAAwB;CAGpD,MAAAoD,UAAgBvD,kBAAkB;CAGlC,MAAAiE,cAAoB3D,wBAAwB;CAG5C,MAAA4D,aAAmB7D,qBAAqB;CAGxC,MAAAqD,gBAAsB,CAAC,EACtBO,aAAWpD,YACXoD,aAAWnD,gBACXmD,aAAWlD;CAIZ,MAAAmC,eAAqBY,gBAAcK,UAAd,KAA+B;CAAC,IAAAC;AAAAC,MAAA;AAIpD,MAAI,CAACJ,aAAW;AAAEG,QAAO;AAAP,SAAAC;;EAAW,IAAAC;AAAA,MAAAV,EAAA,OAAAK,YAAA7C,cAAAwC,EAAA,OAAAK,YAAA/C,SAAA0C,EAAA,OAAAK,YAAApD,YAAA+C,EAAA,OAAAK,YAAAnD,gBAAA8C,EAAA,OAAAK,YAAAlD,WAAA6C,EAAA,OAAAK,YAAAjD,WAAA4C,EAAA,OAAAK,YAAAhD,eAAA2C,EAAA,OAAAK,YAAAjC,eAAA4B,EAAA,OAAAK,YAAA9C,aAAAyC,EAAA,OAAAK,YAAAtC,SAAAiC,EAAA,QAAAK,YAAApC,QAAA+B,EAAA,QAAAK,YAAAnC,cAAA8B,EAAA,QAAAK,YAAA1C,YAAA;AAEtB+C,UAAA;IAAAzD,UACIoD,YAAWpD;IAASC,cAChBmD,YAAWnD;IAAaC,SAC7BkD,YAAWlD;IAAQC,SACnBiD,YAAWjD;IAAQC,aACfgD,YAAWhD;IAAYC,OAC7B+C,YAAW/C;IAAMC,WACb8C,YAAW9C;IAAUC,YACpB6C,YAAW7C;IAAWG,YACtB0C,YAAW1C;IAAWI,OAC3BsC,YAAWtC;IAAME,MAClBoC,YAAWpC;IAAKC,YACVmC,YAAWnC;IAAWE,aACrBiC,YAAWjC;IACxB;AAAA4B,KAAA,KAAAK,YAAA7C;AAAAwC,KAAA,KAAAK,YAAA/C;AAAA0C,KAAA,KAAAK,YAAApD;AAAA+C,KAAA,KAAAK,YAAAnD;AAAA8C,KAAA,KAAAK,YAAAlD;AAAA6C,KAAA,KAAAK,YAAAjD;AAAA4C,KAAA,KAAAK,YAAAhD;AAAA2C,KAAA,KAAAK,YAAAjC;AAAA4B,KAAA,KAAAK,YAAA9C;AAAAyC,KAAA,KAAAK,YAAAtC;AAAAiC,KAAA,MAAAK,YAAApC;AAAA+B,KAAA,MAAAK,YAAAnC;AAAA8B,KAAA,MAAAK,YAAA1C;AAAAqC,KAAA,MAAAU;QAAAA,QAAAV,EAAA;AAdDQ,OAAOE;;CAHR,MAAAd,QAAiCY;CAkBhB,IAAAE;AAAAC,MAAA;AAIhB,MAAI,CAACL,YAAU;AAAEI,QAAO;AAAP,SAAAC;;EAAW,IAAAC;AAAA,MAAAZ,EAAA,QAAAM,WAAA3B,SAAA;AAKlBiC,UAAAN,WAAU3B,WAAV,EAAwB;AAAAqB,KAAA,MAAAM,WAAA3B;AAAAqB,KAAA,MAAAY;QAAAA,QAAAZ,EAAA;EAAA,IAAAa;AAAA,MAAAb,EAAA,QAAAM,WAAAQ,YAAAd,EAAA,QAAAM,WAAA1B,aAAAoB,EAAA,QAAAM,WAAAT,SAAAG,EAAA,QAAAY,MAAA;AAH3BC,UAAA;IAAAvC,MACAgC,WAAUT;IAAMtB,MAChB+B,WAAUQ;IAASnC,SAChBiC;IAAwBhC,WACtB0B,WAAU1B;IACrB;AAAAoB,KAAA,MAAAM,WAAAQ;AAAAd,KAAA,MAAAM,WAAA1B;AAAAoB,KAAA,MAAAM,WAAAT;AAAAG,KAAA,MAAAY;AAAAZ,KAAA,MAAAa;QAAAA,QAAAb,EAAA;AALDU,OAAOG;;CAHR,MAAAhB,QAAiCa;CASjB,IAAAE;AAAA,KAAAZ,EAAA,QAAAE,gBAAA;AAMHU,OAAAV,kBAAA,EAAoB;AAAAF,IAAA,MAAAE;AAAAF,IAAA,MAAAY;OAAAA,MAAAZ,EAAA;CAArB,MAAAa,KAACD;CAAgD,IAAAG;AAAA,KAAAf,EAAA,QAAAT,WAAAS,EAAA,QAAAR,iBAAAQ,EAAA,QAAAV,eAAAU,EAAA,QAAAX,aAAAW,EAAA,QAAAF,iBAAAE,EAAA,QAAAN,uBAAAM,EAAA,QAAAP,iBAAAO,EAAA,QAAAL,WAAAK,EAAA,QAAAa,MAAAb,EAAA,QAAAH,SAAAG,EAAA,QAAAJ,OAAA;AAFrDmB,OAAA;GAAA3B,UAEIyB;GAAiDxB;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAqB3D;AAAAE,IAAA,MAAAT;AAAAS,IAAA,MAAAR;AAAAQ,IAAA,MAAAV;AAAAU,IAAA,MAAAX;AAAAW,IAAA,MAAAF;AAAAE,IAAA,MAAAN;AAAAM,IAAA,MAAAP;AAAAO,IAAA,MAAAL;AAAAK,IAAA,MAAAa;AAAAb,IAAA,MAAAH;AAAAG,IAAA,MAAAJ;AAAAI,IAAA,MAAAe;OAAAA,MAAAf,EAAA;AAAA,QAvBMe;;AAjEF,SAAAX,SAAAY,UAAA;AAAA,QAGkCC,SAAM5B;;AAHxC,SAAAc,SAAAc,QAAA;AAAA,QAEuCA,OAAM7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvCpD,MAAMkE,iBAAiBpC,cAA0C,KAAK;AAEtE,MAAMqC,mBAA6B;CAAE3B,GAAG;CAAGC,GAAG;CAAG;;;;;;;;;AA0BjD,MAAaiC,mBAA6C,EACzDL,UACAC,cAAc,OACdC,cAAc,aACdC,cACAC,mBACK;CAEL,MAAM,CAAC9B,QAAQgC,kBAAkBxC,SAASmC,YAAY;CACtD,MAAM,CAAC1B,UAAUgC,oBAAoBzC,SAAmBoC,YAAY;CACpE,MAAM,CAAC1B,UAAUgC,oBAAoB1C,SAAmBgC,iBAAiB;CACzE,MAAM,CAACrB,WAAWgC,gBAAgB3C,SAAS,MAAM;CACjD,MAAM,CAACY,eAAegC,yBAAyB5C,SAAS,MAAM;CAC9D,MAAM,CAACa,cAAcgC,mBAAmB7C,SAAS,MAAM;CAGvD,MAAM8C,kBAAkB/C,OAAOsC,aAAa;CAC5C,MAAMU,kBAAkBhD,OAAOuC,aAAa;AAC5CQ,iBAAgBE,UAAUX;AAC1BU,iBAAgBC,UAAUV;CAG1B,MAAMvB,UAAUnB,aAAaoB,SAAkB;AAC9CwB,iBAAexB,KAAK;AACpB8B,kBAAgBE,UAAUhC,KAAK;IAC7B,EAAE,CAAC;CAEN,MAAMC,aAAarB,kBAAkB;AACpC4C,kBAAgBS,SAAS;GACxB,MAAMC,OAAO,CAACD;AACdH,mBAAgBE,UAAUE,KAAK;AAC/B,UAAOA;IACN;IACA,EAAE,CAAC;CAEN,MAAMhC,cAActB,aAAauB,SAAmB;AACnDsB,mBAAiBtB,KAAK;AACtB4B,kBAAgBC,UAAU7B,KAAK;IAC7B,EAAE,CAAC;CAEN,MAAMC,cAAcxB,aAAauD,QAAkB;AAClDT,mBAAiBS,IAAI;IACnB,EAAE,CAAC;CAEN,MAAM9B,gBAAgBzB,kBAAkB;AACvC8C,mBAAiBV,iBAAiB;IAChC,EAAE,CAAC;CAEN,MAAMV,WAAW1B,kBAAkB;AAClC+C,eAAa,MAAM;IACjB,EAAE,CAAC;CAEN,MAAMpB,aAAa3B,kBAAkB;AACpC+C,eAAa,KAAK;IAChB,EAAE,CAAC;CAEN,MAAMnB,iBAAiB5B,aAAa6B,WAAoB;AACvDmB,wBAAsBnB,OAAO;IAC3B,EAAE,CAAC;CAEN,MAAMC,WAAW9B,kBAAkB;AAClC6C,mBAAiB,YAAY;AAC7BC,mBAAiBV,iBAAiB;AAClCa,kBAAgB,MAAM;AACtBE,kBAAgBC,UAAU,YAAY;IACpC,EAAE,CAAC;CAEN,MAAMrB,SAAS/B,kBAAkB;AAChC6C,mBAAiB,YAAY;AAC7BM,kBAAgBC,UAAU,YAAY;IACpC,EAAE,CAAC;CAEN,MAAMpB,kBAAkBhC,kBAAkB;AACzCiD,kBAAgB,KAAK;IACnB,EAAE,CAAC;CAEN,MAAMhB,iBAAiBjC,kBAAkB;AACxCiD,kBAAgB,MAAM;IACpB,EAAE,CAAC;CAEN,MAAMf,mBAAmBlC,kBAAkB;AAC1CiD,mBAAiBI,WAAS,CAACA,OAAK;IAC9B,EAAE,CAAC;CAGN,MAAMG,QAAQtD,eACN;EAENU;EACAC;EACAC;EACAC;EACAC;EACAC;EAGAE;EACAE;EACAC;EACAE;EACAC;EACAC;EACAC;EACAC;EACAE;EACAC;EACAC;EACAC;EACAC;EACA,GACD;EACCtB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAE;EACAE;EACAC;EACAE;EACAC;EACAC;EACAC;EACAC;EACAE;EACAC;EACAC;EACAC;EACAC;EAEF,CAAC;AAED,QAAO,oBAAC,eAAe;EAAgBsB;EAAQlB;GAAmC;;;;;AAkBnF,SAAOsB,qBAAA;AAAA,QACC3D,WAAWkC,eAAe;;;;;;;;;;;;;;;;;ACrQlC,SAAOsC,mBAAA;CAAA,MAAAC,IAAAV,EAAA,EAAA;CAAA,IAAAW;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAC4CF,OAAA;GAAAL,mBAC9B;GAAKC,gBACR;GAACC,eACF,OAAOM,WAAW,cAAcA,OAAMC,cAAtC;GACf;AAAAL,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAJD,MAAA,CAAAM,OAAAC,YAA0Bd,SAAwBQ,GAIhD;CAAA,IAAAO;AAAA,KAAAR,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAEsCK,aAAA;AACvC,OAAI,OAAOJ,WAAW,YAAW;GAEjC,MAAAK,iBAAuBL,OAAMK;AAC7B,OAAI,CAACA,gBAAc;AAElBF,aAAS;KAAAX,mBACW;KAAKC,gBACR;KAACC,eACFM,OAAMC;KACrB,CAAC;AAAA;;GAIH,MAAAK,eAAqBN,OAAMC;GAC3B,MAAAM,iBAAuBF,eAAcG;GAGrC,MAAAC,aAAmBH,eAAeC;GAClC,MAAAf,oBAA0BiB,aAAanB;AAEvCa,YAAS;IAAAX;IAAAC,gBAEQD,oBAAAiB,aAAA;IAAkCf,eACnCa;IACf,CAAC;;AACFX,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CA1BD,MAAAc,sBAA4BN;CA0BtB,IAAAO;CAAA,IAAAC;AAAA,KAAAhB,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAEIY,aAAA;AACT,OAAI,OAAOX,WAAW,YAAW;GAEjC,MAAAa,mBAAuBb,OAAMK;AAG7BK,wBAAqB;AAErB,OAAIL,kBAAc;AAEjBA,qBAAcS,iBAAkB,UAAUJ,oBAAoB;AAC9DL,qBAAcS,iBAAkB,UAAUJ,oBAAoB;AAAA,iBAEvD;AACNL,sBAAcU,oBAAqB,UAAUL,oBAAoB;AACjEL,sBAAcU,oBAAqB,UAAUL,oBAAoB;;UACjE;AAGDV,WAAMc,iBAAkB,UAAUJ,oBAAoB;AAAA,iBAE/C;AACNV,YAAMe,oBAAqB,UAAUL,oBAAoB;;;;AAGzDE,OAAA,CAACF,oBAAoB;AAAAd,IAAA,KAAAe;AAAAf,IAAA,KAAAgB;QAAA;AAAAD,OAAAf,EAAA;AAAAgB,OAAAhB,EAAA;;AAzBxBR,WAAUuB,IAyBPC,GAAsB;AAAA,QAElBV;;;;;;;;;;;;;;;;;;ACxER,SAAOoB,kBAAA;CAAA,MAAAC,IAAAJ,EAAA,EAAA;CACN,MAAA,CAAAK,UAAAC,eAAgCJ,SAAS,MAAM;CAC/C,MAAA,CAAAK,eAAAC,oBAA0CN,SAAS,MAAM;CACzD,MAAA,CAAAO,iBAAAC,sBAA8CR,SAAS,MAAM;CAAA,IAAAS;CAAA,IAAAC;AAAA,KAAAR,EAAA,OAAAS,OAAAC,IAAA,4BAAA,EAAA;AAEnDH,aAAA;GAET,MAAAI,WAAiB,kBAAkBC,UAAUC,UAASC,iBAAkB;GAGxE,MAAAC,YAAkBH,OAAMI,WAAY,gBAAgB;GACpD,MAAAC,gBAAsBL,OAAMI,WAAY,oBAAoB;GAE5D,MAAAE,oBAAoB;AACnBd,qBAAiBO,SAAS;AAC1BL,uBAAmBW,cAAaE,QAAS;AAEzCjB,gBAAYa,UAASI,WAAYF,cAAaE,QAAS;;AAGxDD,gBAAa;GAGb,MAAAE,0BAAgCF,aAAa;GAC7C,MAAAG,4BAAkCH,aAAa;AAE/CH,aAASO,iBAAkB,UAAUF,kBAAkB;AACvDH,iBAAaK,iBAAkB,UAAUD,oBAAoB;AAAA,gBAEtD;AACNN,cAASQ,oBAAqB,UAAUH,kBAAkB;AAC1DH,kBAAaM,oBAAqB,UAAUF,oBAAoB;;;AAE/Db,OAAA,EAAE;AAAAR,IAAA,KAAAO;AAAAP,IAAA,KAAAQ;QAAA;AAAAD,OAAAP,EAAA;AAAAQ,OAAAR,EAAA;;AA5BLH,WAAUU,IA4BPC,GAAG;CAAA,IAAAgB;AAAA,KAAAxB,EAAA,OAAAK,mBAAAL,EAAA,OAAAC,YAAAD,EAAA,OAAAG,eAAA;AAECqB,OAAA;GAAAvB;GAAAE;GAAAE;GAA4C;AAAAL,IAAA,KAAAK;AAAAL,IAAA,KAAAC;AAAAD,IAAA,KAAAG;AAAAH,IAAA,KAAAwB;OAAAA,MAAAxB,EAAA;AAAA,QAA5CwB;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBR,SAAOQ,sBAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CACN,MAAAC,WAAiBT,UAAUU,QAAkB;CAAA,IAAAC;AAAA,KAAAJ,EAAA,OAAAE,UAAA;AAG5CE,WAAsC,EAAE;AAExC,OAAK,MAAAC,OAAaH,UAAQ;AAEzB,OAAIG,IAAGC,SAAU,YAAa;GAG9B,MAAAC,eAAqBF;AAIrB,OAAIE,aAAYC,QAAaC,SAAK,kBAAmB;AAGrD,QAAK,MAAAC,QAAcH,aAAYI,SAAQ;AACtC,QAAID,KAAID,SAAU,YAAa;AAC/B,QAAIC,KAAIN,WAAYQ,OAAW;AAE/BR,WAAMS,KAAM;KAAAC,WACAT,IAAGU;KAAGC,YACLN,KAAIM;KAAWC,UACjBP,KAAIO;KAASC,MAChBR,KAAIQ,QAAL,EAA2C;KACjD,CAAC;;;AAEHlB,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,UAAAJ,EAAA;AAAA,QAEDI;;;;;;AA/BK,SAAAD,QAAAiB,GAAA;AAAA,QAC4BA,EAAClB;;AAsCpC,SAAOmB,yBAAA;CACN,MAAAnB,WAAiBT,UAAU6B,SAAkB;CAAA,IAAAC;AAAAC,MAAA;AAG5C,OAAK,MAAAnB,OAAaH,UAAQ;AACzB,OAAIG,IAAGC,SAAU,YAAa;GAE9B,MAAAC,eAAqBF;AAGrB,OAAIE,aAAYC,QAAaC,SAAK,kBAAmB;AAErD,QAAK,MAAAC,QAAcH,aAAYI,QAC9B,KAAID,KAAID,SAAU,eAAeC,KAAIN,WAAYQ,QAAS;AACzDW,SAAO;AAAP,UAAAC;;;AAKHD,OAAO;;AAAK,QAhBNA;;;;;;AAHD,SAAAD,SAAAF,GAAA;AAAA,QAC4BA,EAAClB;;;;;;;;ACrCpC,SAAS0C,iBAAiBC,QAAoBC,QAA4B;CACzE,MAAMC,KAAKD,OAAOJ,UAAUG,OAAOH;CACnC,MAAMM,KAAKF,OAAOH,UAAUE,OAAOF;AACnC,QAAOM,KAAKC,KAAKH,KAAKA,KAAKC,KAAKA,GAAG;;;;;;;;;;;;;;;;;;;AAoBpC,SAAOG,gBAAAC,IAAA;CAAA,MAAAC,IAAA3B,EAAA,GAAA;CAAyB,MAAA,EAAAO,YAAAC,WAAAC,SAAAmB,IAAAlB,WAAAmB,OAAAH;CAG/B,MAAAjB,UAAAmB,OAAAE,SAAA,OAAAF;CACA,MAAAlB,YAAAmB,OAAAC,SAAY3B,qBAAoBO,YAAhCmB;CAA0C,IAAAE;AAAA,KAAAJ,EAAA,OAAAK,OAAAC,IAAA,4BAAA,EAAA;AAENF,OAAA;GAAAnB,iBAClB;GAAIC,cACP;GAAIC,UACR;GACV;AAAAa,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAJD,MAAAO,WAAiBhC,OAAmB6B,GAIlC;CAAA,IAAAI;AAAA,KAAAR,EAAA,OAAAlB,SAAA;AAGD0B,QAAAC,MAAA;AACC,OAAI,CAAC3B,QAAO;AACZ,OAAI2B,EAACC,QAAQC,WAAY,GAAC;IACzB,MAAAC,WAAiBrB,iBAAiBkB,EAACC,QAAQ,IAAKD,EAACC,QAAQ,GAAI;AAG7D,QAAIE,YAAYpC,qBAAoBqC,mBACnCN,UAAQO,UAAW;KAAA7B,iBACD2B;KAAQ1B,cACX0B;KAAQzB,UACZ;KAHK;;;AAOlBa,IAAA,KAAAlB;AAAAkB,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CAfF,MAAAe,mBAAyBP;CAiBxB,IAAAQ;AAAA,KAAAhB,EAAA,OAAAlB,SAAA;AAGAkC,QAAAC,QAAA;AACC,OAAI,CAACnC,WAAD,CAAayB,SAAQO,QAAQ3B,SAAS;AAC1C,OAAIsB,IAACC,QAAQC,WAAY,EAAC;GAG1B,MAAAO,kBAAwB3B,iBAAiBkB,IAACC,QAAQ,IAAKD,IAACC,QAAQ,GAAI;AACpEH,YAAQO,QAAQ5B,eAAgBgC;;AAChClB,IAAA,KAAAlB;AAAAkB,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CARF,MAAAmB,kBAAwBH;CAUvB,IAAAI;AAAA,KAAApB,EAAA,OAAAlB,WAAAkB,EAAA,OAAAnB,aAAAmB,EAAA,OAAApB,cAAAoB,EAAA,OAAAjB,WAAA;AAGAqC,QAAAC,QAAA;AACC,OAAI,CAACvC,WAAD,CAAayB,SAAQO,QAAQ3B,SAAS;GAE1C,MAAA,EAAAF,iBAAAC,iBAA0CqB,SAAQO;AAGlD,OAAIL,IAACC,QAAQC,SAAU,KAAK1B,oBAAoB,QAAQC,iBAAiB,MAAI;IAC5E,MAAAoC,cAAoBpC,eAAeD,mBAAmBA;AAEtD,QAAIqC,aAAavC,UAChBH,eAAc;aACJ0C,aAAa,CAACvC,UACxBF,cAAa;AAId0B,aAAQO,UAAW;KAAA7B,iBACD;KAAIC,cACP;KAAIC,UACR;KAHK;;;AAMjBa,IAAA,KAAAlB;AAAAkB,IAAA,KAAAnB;AAAAmB,IAAA,KAAApB;AAAAoB,IAAA,KAAAjB;AAAAiB,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAvBF,MAAAuB,iBAAuBH;CAyBtB,IAAAI;AAAA,KAAAxB,EAAA,QAAAuB,kBAAAvB,EAAA,QAAAmB,mBAAAnB,EAAA,QAAAe,kBAAA;AAEMS,OAAA,EAAAC,UACI;GAAAC,cACKX;GAAgBY,aACjBR;GAAeS,YAChBL;GACb,EACA;AAAAvB,IAAA,MAAAuB;AAAAvB,IAAA,MAAAmB;AAAAnB,IAAA,MAAAe;AAAAf,IAAA,MAAAwB;OAAAA,MAAAxB,EAAA;AAAA,QANMwB;;;;;;;;;;;;;;;;;;;;;ACrFR,SAAgBsB,YAAYC,UAA8B;CACzD,MAAMC,OAAOD,SAASE,aAAa;AAGnC,KACCD,KAAKE,SAAS,SAAS,IACvBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,CAErB,QAAOZ;AAIR,KACCU,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,MAAM,IACpBF,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,OAAO,CAErB,QAAOjB;AAIR,KACCe,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,SAAS,IACvBF,KAAKE,SAAS,MAAM,IACpBF,KAAKE,SAAS,SAAS,CAEvB,QAAOb;AAIR,KAAIW,KAAKE,SAAS,SAAS,IAAIF,KAAKE,SAAS,SAAS,IAAIF,KAAKE,SAAS,QAAQ,CAC/E,QAAOX;AAIR,KAAIS,KAAKE,SAAS,WAAW,IAAIF,KAAKE,SAAS,OAAO,IAAIF,KAAKE,SAAS,OAAO,CAC9E,QAAOd;AAIR,KACCY,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,QAAQ,CAEtB,QAAOf;AAIR,KAAIa,KAAKE,SAAS,aAAa,IAAIF,KAAKE,SAAS,WAAW,IAAIF,KAAKE,SAAS,UAAU,CACvF,QAAOlB;AAIR,QAAOQ;;;;;AAsBR,SAAOiB,mBAAA;CAAA,MAAAC,IAAA5B,EAAA,GAAA;CACN,MAAA6B,WAAiB5B,UAAU6B,QAA4B;CACvD,MAAAC,YAAkB9B,UAAU+B,SAA6B;CAAA,IAAAC;AAAA,KAAAL,EAAA,OAAAG,aAAAH,EAAA,OAAAC,UAAA;AAAAK,OAAA;AAGxD,OAAI,CAACH,WAAS;AAAEE,SAAO;AAAP,UAAAC;;GAGhB,MAAAC,uBAA6BN,WAC1B,CAAA,GAAIA,SAAS,CAAAO,SAAU,CAAAC,KAAMC,SACzB,GAFsB;AAI7B,OAAI,CAACH,sBAAoB;IAAA,IAAAI;AAAA,QAAAX,EAAA,OAAAY,OAAAC,IAAA,4BAAA,EAAA;AAEjBF,YAAA;MAAAjB,MACA;MAAUC,OACT;MAAaC,MACdpB;MACN;AAAAwB,OAAA,KAAAW;UAAAA,QAAAX,EAAA;AAJDK,SAAOM;AAAP,UAAAL;;GAQD,MAAAQ,mBAAmC,EAAE;GACjCC,IAAAA;AAEJ,QAAK,MAAAC,QAAcT,qBAAoBU,QACtC,KAAID,KAAItB,SAAU,aAAW;IAE5B,MAAAwB,WAAiBF;AACjB,QAAI,CAACE,SAAQC,UAAWD,SAAQC,OAAOzB,SAAU,UAChDoB,kBAAgBM,KAAMF,SAAQ7B,SAAU;cAE/B2B,KAAItB,SAAU,OAExBqB,YADiBC,KACEM;AAKrB,OAAIR,iBAAgBS,WAAY,GAAC;AAEhC,QAAIR,YAAYA,SAAQQ,SAAU,GAAC;AAElClB,UAAO;MAAAX,MACA;MAAWC,OACV;MAAqBC,MACtBjB;MAAOmB,eACEiB;MACf;AALD,WAAAT;;IAMA,IAAAK;AAAA,QAAAX,EAAA,OAAAY,OAAAC,IAAA,4BAAA,EAAA;AAEMF,YAAA;MAAAjB,MACA;MAAUC,OACT;MAAaC,MACdpB;MACN;AAAAwB,OAAA,KAAAW;UAAAA,QAAAX,EAAA;AAJDK,SAAOM;AAAP,UAAAL;;AAOD,OAAIQ,iBAAgBS,WAAY,GAAC;IAEhC,MAAAlC,WAAiByB,iBAAgB;IAAG,IAAAH;AAAA,QAAAX,EAAA,OAAAX,UAAA;AAKxBsB,YAAA,CAACtB,SAAS;AAAAW,OAAA,KAAAX;AAAAW,OAAA,KAAAW;UAAAA,QAAAX,EAAA;AAJtBK,SAAO;KAAAX,MACA;KAAMC,OACLX,iBAAiBK,UAAU,KAAK;KAAAO,MACjCR,YAAYC,SAAS;KAAAQ,WAChBc;KACX;AALD,UAAAL;;GAWO,MAAAK,KAAA,WAAWG,iBAAgBS,OAAO;GAAW,IAAAC;AAAA,OAAAxB,EAAA,OAAAc,oBAAAd,EAAA,OAAAW,IAAA;AAF9Ca,SAAA;KAAA9B,MACA;KAAgBC,OACfgB;KAA6Cf,MAC9CpB;KAAOqB,WACFiB;KACX;AAAAd,MAAA,KAAAc;AAAAd,MAAA,KAAAW;AAAAX,MAAA,KAAAwB;SAAAA,MAAAxB,EAAA;AALDK,QAAOmB;;AAKNxB,IAAA,KAAAG;AAAAH,IAAA,KAAAC;AAAAD,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAvEKK;;AAJD,SAAAK,SAAAe,GAAA;AAAA,QASkCA,EAACC,SAAU;;AAT7C,SAAAtB,SAAAuB,UAAA;AAAA,QAEkCC,SAAMzB;;AAFxC,SAAAD,QAAA0B,QAAA;AAAA,QACiCA,OAAM3B;;;;;;AA0F9C,MAAa8B,qBAAgD1B,OAAA;CAAA,MAAAL,IAAA5B,EAAA,GAAA;CAAC,MAAA,EAAA0D,cAAAzB;CAC7D,MAAA2B,WAAiBjC,kBAAkB;AAEnC,KAAI,CAACiC,SAAQ,QAAS;CAEtB,MAAAC,OAAaD,SAAQpC;CACrB,MAAAsC,aAAmBF,SAAQtC,SAAU,cAAcsC,SAAQtC,SAAU;CAAgB,IAAAiB;AAAA,KAAAX,EAAA,OAAA8B,WAAA;AAIxEnB,OAAA1B,GACV,qCACA,uDACA,yBACA6C,UACA;AAAA9B,IAAA,KAAA8B;AAAA9B,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAE4C,MAAAwB,KAAAU,cAAA;CAA4B,IAAAC;AAAA,KAAAnC,EAAA,OAAAwB,IAAA;AAAxDW,OAAAlD,GAAG,yBAAyBuC,GAA6B;AAAAxB,IAAA,KAAAwB;AAAAxB,IAAA,KAAAmC;OAAAA,MAAAnC,EAAA;CAAA,IAAAoC;AAAA,KAAApC,EAAA,OAAAiC,QAAAjC,EAAA,OAAAmC,IAAA;AAA1EC,OAAA,oBAAC,QAAgB,WAAAD,KAA6D;AAAAnC,IAAA,KAAAiC;AAAAjC,IAAA,KAAAmC;AAAAnC,IAAA,KAAAoC;OAAAA,MAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,OAAAgC,SAAArC,OAAA;AAC9E0C,OAAA,oBAAA;GAAgB,WAAA;aAAYL,SAAQrC;IAAc;AAAAK,IAAA,KAAAgC,SAAArC;AAAAK,IAAA,KAAAqC;OAAAA,MAAArC,EAAA;CAAA,IAAAsC;AAAA,KAAAtC,EAAA,OAAAgC,SAAAnC,aAAAG,EAAA,QAAAgC,SAAAtC,MAAA;AAGjD4C,OAAAN,SAAQtC,SAAU,oBAAoBsC,SAAQnC,aAC9C,qBAAA;GAAe,WAAA;cACbmC,SAAQnC,UAAU0C,MAAO,GAAG,EAAE,CAAAC,IAAKC,SAOnC,EACAT,SAAQnC,UAAU0B,SAAU,KAC5B,qBAAA;IAAgB,WAAA;eAA2B,KAAES,SAAQnC,UAAU0B,SAAU;KAC1E;IAED;AAAAvB,IAAA,KAAAgC,SAAAnC;AAAAG,IAAA,MAAAgC,SAAAtC;AAAAM,IAAA,MAAAsC;OAAAA,MAAAtC,EAAA;CAAA,IAAA0C;AAAA,KAAA1C,EAAA,QAAAW,MAAAX,EAAA,QAAAoC,MAAApC,EAAA,QAAAqC,MAAArC,EAAA,QAAAsC,IAAA;AA1BFI,OAAA,qBAAA;GACY,WAAA/B;;IAOXyB;IACAC;IAGCC;;IAeI;AAAAtC,IAAA,MAAAW;AAAAX,IAAA,MAAAoC;AAAApC,IAAA,MAAAqC;AAAArC,IAAA,MAAAsC;AAAAtC,IAAA,MAAA0C;OAAAA,MAAA1C,EAAA;AAAA,QA3BN0C;;AAT2D,SAAAD,SAAAnD,MAAAqD,GAAA;CAwBvD,MAAAC,WAAiBxD,YAAYE,KAAK;AAAA,QAEjC,oBAAA;EAAqB,OAAAN,iBAAiBM,MAAM,KAAI;YAC/C,oBAAC,YAAmB,WAAA,6BACrB;IAFWqD,EAEJ;;;;;;;;;;;;;;;AC/Kd,MAAasB,yBAAqDZ,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,cAAAE;CAClE,MAAAG,eAAqBR,yBAAyB;AAG9C,KAAI,CAACQ,aAAY,QAAS;CAE1B,MAAA,EAAAC,MAAAC,eAA6BF;CAC7B,MAAAG,YAAkBF,SAAS;CASxB,MAAAG,KAAAD,YAAA,yCAAA;CAEwD,IAAAE;AAAA,KAAAP,EAAA,OAAAH,aAAAG,EAAA,OAAAM,IAAA;AAL9CC,OAAAd,GACV,qDACA,kCACAa,IAGAT,UACA;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAM;AAAAN,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAEA,MAAAQ,KAAAH,YAAA,2DAAA;CAEkD,IAAAI;AAAA,KAAAT,EAAA,OAAAK,WAAA;AAGlDI,OAAAJ,YAAY,oBAAC,UAAiB,WAAA,gBAAwD,GAArC,oBAAC,aAAoB,WAAA,gBAAgB;AAAAL,IAAA,KAAAK;AAAAL,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,OAAAO,MAAAP,EAAA,OAAAQ,MAAAR,EAAA,OAAAS,MAAAT,EAAA,OAAAI,YAAA;AAjBxFM,OAAA,oBAAA;GACM,MAAA;GACIN,SAAAA;GACE,WAAAG;GASV,OAAAC;aAKAC;IACO;AAAAT,IAAA,KAAAO;AAAAP,IAAA,KAAAQ;AAAAR,IAAA,KAAAS;AAAAT,IAAA,KAAAI;AAAAJ,IAAA,KAAAU;OAAAA,MAAAV,EAAA;AAAA,QAlBTU;;;;;;;;ACWF,MAAaoC,iBAA4CnB,OAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAC,MAAA,EAAAY,cAAAE;CAAa,IAAAE;AAAA,KAAAD,EAAA,OAAAH,WAAA;AAErDI,OAAAX,GAAG,yCAAyCO,UAAU;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAA,IAAAE;CAAA,IAAAC;AAAA,KAAAH,EAAA,OAAAmB,OAAAC,IAAA,4BAAA,EAAA;AACrElB,OAAA,oBAAA,SAAe,WAAA,yCAAyC;AACxDC,OAAA,oBAAA;GAAgB,WAAA;aAAU;IAAY;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;QAAA;AAAAD,OAAAF,EAAA;AAAAG,OAAAH,EAAA;;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAC,IAAA;AAFvCI,OAAA,qBAAA;GAAgB,WAAAJ;cACfC,IACAC;IACK;AAAAH,IAAA,KAAAC;AAAAD,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAHNK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnDF,SAAgB2B,iBAAiBC,QAAgC;AAUhE,QAToBA,OAAOE,QACzBC,KAAKC,QAAuC;AAC5C,MAAI,UAAUA,OAAK,OAAOA,IAAEE,SAAS,SACpC,QAAOF,IAAEE;AAEV,SAAOC,KAAKC,UAAUJ,IAAE;GACvB,CACDK,KAAK,KAAK,IAEU;;;;;;;AAYvB,MAAMC,cAGDO,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAR,MAAAC,aAAAK;CAGS,MAAAG,KAAAT,KAAIU,eAAJ;CAAsB,IAAAC;AAAA,KAAAJ,EAAA,OAAAP,KAAAY,aAAA;AACtBD,OAAAX,KAAIY,eAAJ,EAAsB;AAAAL,IAAA,KAAAP,KAAAY;AAAAL,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAvB,MAAAM,KAACF;CAAkD,IAAAG;AAAA,KAAAP,EAAA,OAAAN,YAAAM,EAAA,OAAAP,KAAAe,aAAAR,EAAA,OAAAP,KAAAE,MAAA;AACtDY,OAAA,OAAAX,SAAA;GACR,MAAAa,YAAkBC,KAAIC,KAAM;GAC5B,IAAAC;GACA,IAAAC;AAEA,OAAA;IACC,MAAA/B,SAAe,MAAMY,SAASD,KAAIE,MAAOC,KAAK;AAG9CgB,cAAU9B,OAAM8B,YAAa;AAG7BC,iBAAa/B,OAAME,QAAQ8B,KAC1BC,QAEA;IAGD,MAAAC,aAAiB;KAAAP;KAAAQ,UAENP,KAAIC,KAAM,GAAGF;KAASS,UACtBzB,KAAIe;KAAUI;KAAAC;KAGxB;AAA2B,WAGrB,IAAIxC,aAAa;KAAAS,QACfD,iBAAiBC,OAAO;KAAAqC,UACtBC;KAAwCR;KAElD,CAAC;YAAAS,MAAA;IACMC,MAAAA,QAAAA;AACRC,YAAOD,MAAO,sBAAsB7B,KAAIE,KAAK,sBAAuB2B,MAAM;IAG1E,MAAAF,WAAiB;KAAAX;KAAAQ,UAENP,KAAIC,KAAM,GAAGF;KAASS,UACtBzB,KAAIe;KAAUI,SACf;KAAIC,YACD;KACZ;AAA2B,WAGrB,IAAIxC,aAAa;KAAAS,QACf,UAAUwC,iBAAiBE,QAAQF,MAAKG,UAAWC,OAAOJ,MAAM;KAAEH,UAChEC;KAAwCR,SACzC;KACT,CAAC;;;AAEHZ,IAAA,KAAAN;AAAAM,IAAA,KAAAP,KAAAe;AAAAR,IAAA,KAAAP,KAAAE;AAAAK,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,OAAAE,MAAAF,EAAA,OAAAM,MAAAN,EAAA,OAAAO,MAAAP,EAAA,OAAAP,KAAAE,MAAA;AAvDe0B,OAAA;GAAAM,UACNlC,KAAIE;GAAKQ,aACND;GAAsB0B,YACvBtB;GAAmDuB,SACtDtB;GAoDT;AAAAP,IAAA,KAAAE;AAAAF,IAAA,KAAAM;AAAAN,IAAA,KAAAO;AAAAP,IAAA,KAAAP,KAAAE;AAAAK,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;AAxDD5B,kBAAiBiD,GAwDf;AAAA,QAEK;;;;;;;;;AAUR,MAAMS,yBAED/B,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAR,SAAAM;CAKS,MAAAG,KAAAT,KAAIU,eAAJ;CAAsB,IAAAC;AAAA,KAAAJ,EAAA,OAAAP,KAAAY,aAAA;AACtBD,OAAAX,KAAIY,eAAJ,EAAsB;AAAAL,IAAA,KAAAP,KAAAY;AAAAL,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAvB,MAAAM,KAACF;CAAkD,IAAAG;AAAA,KAAAP,EAAA,OAAAE,MAAAF,EAAA,OAAAM,MAAAN,EAAA,OAAAP,KAAAE,MAAA;AAH/CY,OAAA;GAAAoB,UACNlC,KAAIE;GAAKQ,aACND;GAAsB0B,YACvBtB;GAEZ;AAAAN,IAAA,KAAAE;AAAAF,IAAA,KAAAM;AAAAN,IAAA,KAAAP,KAAAE;AAAAK,IAAA,KAAAO;OAAAA,MAAAP,EAAA;AALD5B,kBAAiBmC,GAKf;AAAA,QAEK;;;;;;;AAYR,MAAawB,wBAAsB;CAAA,MAAA/B,IAAAC,EAAA,EAAA;CAClC,MAAA,EAAA+B,OAAAtC,aAA4BpB,aAAa;CACzC,MAAA2D,eAAqB1D,yBAAyB;CAAA,IAAAwB;AAAA,KAAAC,EAAA,OAAAN,YAAAM,EAAA,OAAAiC,gBAAAjC,EAAA,OAAAgC,OAAA;EAAA,IAAA9B;AAAA,MAAAF,EAAA,OAAAN,YAAAM,EAAA,OAAAiC,cAAA;AAIjC/B,WAAAT,SAAA;AAIV,QAFsBwC,cAAYE,iBAAmB1C,KAAc,IAA7C,MAEL,QACT,oBAAC,yBAAmEA,QAAxC,GAAGA,KAAIe,UAAU,GAAIf,KAAIE,OAAuB;AACnF,WAEM,oBAAC;KAAwDF;KAAgBC;OAAxD,GAAGD,KAAIe,UAAU,GAAIf,KAAIE,OAA2C;;AAC5FK,KAAA,KAAAN;AAAAM,KAAA,KAAAiC;AAAAjC,KAAA,KAAAE;QAAAA,QAAAF,EAAA;AATAD,OAAAiC,MAAK/C,IAAKiB,KAST;AAAAF,IAAA,KAAAN;AAAAM,IAAA,KAAAiC;AAAAjC,IAAA,KAAAgC;AAAAhC,IAAA,KAAAD;OAAAA,MAAAC,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAVHG,OAAA,0CACEH,KAUC;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAXHE;;AAlGG,SAAAa,QAAA7B,KAAA;AAAA,QAmBCA,IAACC,SAAU,UAAU,OAAOD,IAACE,SAAU,YAAYF,IAACE,KAAKgD,SAAU,oBAAoB;;;;;;;;;;;;ACrD7F,MAAMyB,oBAAoB,EACzBC,OAAO;CACNC,OAAO;EAAC;EAAG;EAAK;EAAE;CAClBC,YAAY;EAAEC,UAAU;EAAGC,QAAQC;EAAS;CAC7C,EACA;AAED,MAAaC,oBAA8CC,OAAA;CAAA,MAAAC,IAAAhC,EAAA,GAAA;CAAC,MAAA,EAAAY,UAAAC,aAAAC,MAAAE,kBAAAC,aAAAgB,IAAAf,WAAAC,QAAAC,WAAAC,aAAAC,aAAAS;CAK3D,MAAAd,cAAAgB,OAAAC,SAAA,QAAAD;CAAmB,IAAAE;AAAA,KAAAH,EAAA,OAAApB,UAAA;AAODuB,OAAA5B,iBAAiBK,SAAS;AAAAoB,IAAA,KAAApB;AAAAoB,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAA5C,MAAAI,YAAkBD;CAA0B,IAAAE;AAAA,KAAAL,EAAA,OAAAlB,MAAA;AAC5BuB,OAAAvB,QAAQwB,OAAMC,KAAMzB,KAAK,CAAA0B,SAAU;AAACR,IAAA,KAAAlB;AAAAkB,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAApD,MAAAS,UAAgBJ;CAAoC,IAAAK;AAAA,KAAAV,EAAA,OAAAlB,QAAAkB,EAAA,OAAAS,SAAA;AAC9BC,OAAAD,UAAUnC,WAAWQ,KAAY,GAAjC;AAAiCkB,IAAA,KAAAlB;AAAAkB,IAAA,KAAAS;AAAAT,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAvD,MAAAW,gBAAsBD;CAAiC,IAAAE;AAAA,KAAAZ,EAAA,OAAAZ,WAAA;AAI1CwB,OAAApC,GACV,4CACA,8CACAY,UACA;AAAAY,IAAA,KAAAZ;AAAAY,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAc,OAAAC,IAAA,4BAAA,EAAA;AAIAF,OAAA,oBAAC,iBAAwB,WAAA,yCAAyC;AAAAb,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,QAAAc,OAAAC,IAAA,4BAAA,EAAA;AAEjEC,OAAA,oBAAA;GAAgB,WAAA;aAA6B;IAAc;AAAAhB,IAAA,MAAAgB;OAAAA,MAAAhB,EAAA;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,QAAAI,WAAA;AAD5Da,OAAA,qBAAA;GAAgB,WAAA;;IACfD;IAA2D;IAAEZ;IAAU;;IACjE;AAAAJ,IAAA,MAAAI;AAAAJ,IAAA,MAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,QAAAhB,kBAAA;AAENkC,OAAAlC,qBAAqBkB,UACrB,oBAAA,OAAA;GACY,WAAA1B,GACV,6EACAQ,oBAAoB,KAApB,+BAAA,iCAGD;GACU,UAAAA,oBAAoB,KAApBO,oBAAAW;GACD,SAAAlB,oBAAoB,KAApB,UAAAkB;aAERlB;IAEF;AAAAgB,IAAA,MAAAhB;AAAAgB,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAiB,MAAAjB,EAAA,QAAAkB,IAAA;AAnBFC,QAAA,qBAAA;GAAe,WAAA;;IACdN;IACAI;IAICC;;IAcI;AAAAlB,IAAA,MAAAiB;AAAAjB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,OAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAnB,aAAA;AAKLuC,QAAAvC,eAAe,oBAAA;GAAa,WAAA;aAAyCA;IAAgB;AAAAmB,IAAA,MAAAnB;AAAAmB,IAAA,MAAAoB;OAAAA,OAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,QAAAW,eAAA;AAGrFU,QAAAV,iBACA,oBAAA;GAAe,WAAA;aACbA;IAEF;AAAAX,IAAA,MAAAW;AAAAX,IAAA,MAAAqB;OAAAA,OAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,QAAAI,aAAAJ,EAAA,QAAAf,eAAAe,EAAA,QAAAd,aAAAc,EAAA,QAAAb,QAAA;AAKAmC,QAAArC,cACA,qBAAA;GAAe,WAAA;cACd,oBAAC,WAAkB,WAAA,yBACnB,uBAAA;IAAM;IACK,oBAAA,sBAASmB,YAAmB;;OAExC;IAgCA,GA9BA,qBAAA;GAAe,WAAA;cACd,qBAAA;IACM,MAAA;IACIjB,SAAAA;IACE,WAAAX,GACV,4FACA,wCACA,kCACA,kEACA,sBACD;eAEA,oBAAC,KAAY,WAAA,gBAAgB;KAG9B,uBAAA;IACM,MAAA;IACIU,SAAAA;IACE,WAAAV,GACV,4FACA,6DACA,kCACA,gDACA,sBACD;eAEA,oBAAC,SAAgB,WAAA,gBAAgB;KAGnC;IACA;AAAAwB,IAAA,MAAAI;AAAAJ,IAAA,MAAAf;AAAAe,IAAA,MAAAd;AAAAc,IAAA,MAAAb;AAAAa,IAAA,MAAAsB;OAAAA,OAAAtB,EAAA;CAAA,IAAAuB;AAAA,KAAAvB,EAAA,QAAAX,eAAAW,EAAA,QAAAV,YAAAU,EAAA,QAAAmB,OAAAnB,EAAA,QAAAoB,OAAApB,EAAA,QAAAqB,OAAArB,EAAA,QAAAsB,OAAAtB,EAAA,QAAAY,IAAA;AAnFFW,QAAA,qBAAA;GACY,WAAAX;;IAOXO;IAsBC7B;IAGA8B;IAGAC;IAMAhC;IAGAiC;;IAuCI;AAAAtB,IAAA,MAAAX;AAAAW,IAAA,MAAAV;AAAAU,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;AAAArB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAY;AAAAZ,IAAA,MAAAuB;OAAAA,OAAAvB,EAAA;AAAA,QApFNuB;;;;;;;;;;;;;;;;;;;;;ACjBF,MAAac,wBAAuD,EAAED,gBAAgB;CACrF,MAAM,CAACE,aAAaC,kBAAkBb,SAAS,MAAM;CACrD,MAAMc,mBAAmBb,qBAAqB;CAC9C,MAAMc,gBAAgBjB,kBAAkB;CACxC,MAAM,EAAEkB,UAAUC,UAAUZ,aAAa;AAGzC,KAAIS,iBAAiBI,WAAW,EAC/B,QAAO;CAIR,MAAMC,YAAYL,iBAAiB;CAGnC,MAAMM,kBAAkBH,MAAMI,MAAMC,MAAMA,EAAEC,SAASJ,UAAUK,SAAS,EAAEC;CAG1E,MAAMC,uBAAuB;EAC5B,MAAMC,iBAAiBZ,eAAea,eAAeT,UAAUU,UAAU;AACzE,MAAI,CAACF,eAAgB,QAAO;AAY5B,MAAI,CARmBA,eACrBI,UAAU,CACVC,QAAQC,MACPC,SACAA,KAAKC,SAAS,eACdD,KAAKE,eAAejB,UAAUiB,cAC9BF,KAAKG,WAAWC,OACjB,CACmB,QAAO;AAE5B,MAAI;AACH,UAAOX,eAAeY,2BAA2BpB,UAAUiB,WAAW;WAC9DI,OAAO;AACf,OAAIA,iBAAiBC,SAASD,MAAME,YAAY,mCAC/C,QAAO;AAER,SAAMF;;;CAIR,MAAMG,eAAe,YAAY;AAChC9B,iBAAe,KAAK;AACpB,MAAI;GACH,MAAM+B,aAAa,MAAM5B,SAASG,UAAUK,UAAUL,UAAU0B,KAAK;AAErEC,GADoBpB,gBAAgB,EACvBqB,cAAczC,iBAAiBsC,WAAW,CAAC;WAChDJ,SAAO;GACf,MAAMQ,eAAeR,mBAAiBC,QAAQD,QAAME,UAAUO,OAAOT,QAAM;AAE3EM,GADoBpB,gBAAgB,EACvBqB,cAAc,UAAUC,eAAe;YAC3C;AACTnC,kBAAe,MAAM;;;CAIvB,MAAMqC,mBAAmB;AAExB/C,6BAA2BY,eAAeb,oBAAoB;AAE9Da,gBAAcoC,WAAW;;AAI1B,KAAIvC,YACH,QACC,oBAAC;EACA,WAAWR,GAAG,mEAAmEM,UAAU;YAE3F,qBAAC;GAAI,WAAU;cACd,oBAAC,WAAQ,WAAU,uCAAoC,EACvD,oBAAC;IAAK,WAAU;cAAwB;KAAkB;IACtD;GACA;AAIR,QACC,oBAAC;EACA,UAAUS,UAAUK;EACpB,aAAaJ;EACb,MAAMD,UAAU0B;EACHjC;EACb,WAAW+B;EACX,QAAQO;EACR,WAAW9C,GAAG,eAAeM,UAAU;GACtC;;;;;;;;ACzFJ,MAAMsE,uBAAqB;CAAA,MAAAC,IAAA5B,EAAA,EAAA;CAE1B,MAAA+B,YADiB5B,YAAY2B,QAAc,EACjBE,UAAR;AAGlB,KAAID,YAAYpB,qBAAqB,GAAG,QAAS;CAEjD,MAAAsB,SAAeF,YAAYpB;CAC3B,MAAAuB,YAAkBvB,qBAAqBoB;CAGU,MAAAI,KAAAF,SAAA,iBAAA;CAAyC,IAAAG;AAAA,KAAAR,EAAA,OAAAO,IAAA;AAAxEC,OAAAxB,GAAG,4BAA4BuB,GAA0C;AAAAP,IAAA,KAAAO;AAAAP,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAM,aAAAN,EAAA,OAAAQ,IAAA;AAA1FC,OAAA,oBAAA;GAAiB,WAAAD;aACfF;IACK;AAAAN,IAAA,KAAAM;AAAAN,IAAA,KAAAQ;AAAAR,IAAA,KAAAS;OAAAA,MAAAT,EAAA;AAAA,QAFPS;;;;;;;AAWF,MAAaC,gBAAsCH,OAAA;CAAA,MAAAP,IAAA5B,EAAA,GAAA;CAAC,MAAA,EAAAe,aAAAqB,IAAApB,iBAAAqB,IAAApB,eAAAsB,IAAArB,eAAAC,eAAAqB,IAAApB,WAAAC,aAAAoB,IAAAnB,qBAAAE,aAAAkB,IAAAjB,gBAAAU;CACnD,MAAApB,cAAAqB,OAAAO,SAAA,qBAAAP;CACA,MAAApB,kBAAAqB,OAAAM,SAAA,QAAAN;CACA,MAAApB,gBAAAsB,OAAAI,SAAA,QAAAJ;CAEA,MAAApB,gBAAAqB,OAAAG,SAAA,OAAAH;CAEA,MAAAnB,cAAAoB,OAAAE,SAAA,QAAAF;CAEA,MAAAjB,cAAAkB,OAAAC,SAAA,QAAAD;CAIA,MAAA,EAAAE,aAAqBlC,iBAAiB;CACtC,MAAAmC,WAAiBpC,OAA4B,KAAK;CAClD,MAAAqC,kBAAwB1C,oBAAoB;CAG5C,MAAA2C,uBAA6B1B,cAAA,qCAAAN;CAA8D,IAAAiC;AAAA,KAAApB,EAAA,OAAAgB,UAAA;AAG1DI,aAAA;AAChC,OAAIJ,YAAYC,SAAQI,QACvBJ,UAAQI,QAAQC,MAAO;;AAExBtB,IAAA,KAAAgB;AAAAhB,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAJD,MAAAuB,eAAqBH;CAIP,IAAAI;AAAA,KAAAxB,EAAA,OAAAkB,mBAAAlB,EAAA,OAAAgB,YAAAhB,EAAA,OAAAN,qBAAA;AAG8B8B,aAAA;GAC3C,MAAA1B,OAAaoB,gBAAeO,UAAW,CAAA3B,KAAK4B,MAAO;AACnD,OAAI5B,QAAAJ,qBAA2B;AAC9BA,wBAAoBI,KAAK;AACzBoB,oBAAeS,QAAS,GAAG;AAC3B,QAAIX,YAAYC,SAAQI,QACvBJ,UAAQI,QAAQC,MAAO;;;AAGzBtB,IAAA,KAAAkB;AAAAlB,IAAA,KAAAgB;AAAAhB,IAAA,KAAAN;AAAAM,IAAA,KAAAwB;OAAAA,MAAAxB,EAAA;CATD,MAAA4B,0BAAgCJ;CASoB,IAAAK;AAAA,KAAA7B,EAAA,OAAAkB,mBAAAlB,EAAA,OAAAgB,YAAAhB,EAAA,OAAAH,aAAA;AAGhBgC,aAAA;GACnC,MAAAC,SAAaZ,gBAAeO,UAAW,CAAA3B,KAAK4B,MAAO;AACnD,OAAII,UAAAjC,aAAmB;AACtBA,gBAAYC,OAAK;AACjBoB,oBAAeS,QAAS,GAAG;AAC3B,QAAIX,YAAYC,SAAQI,QACvBJ,UAAQI,QAAQC,MAAO;;;AAGzBtB,IAAA,KAAAkB;AAAAlB,IAAA,KAAAgB;AAAAhB,IAAA,KAAAH;AAAAG,IAAA,KAAA6B;OAAAA,MAAA7B,EAAA;CATD,MAAA+B,kBAAwBF;CASoB,IAAAG;AAAA,KAAAhC,EAAA,QAAA4B,2BAAA5B,EAAA,QAAA+B,mBAAA/B,EAAA,QAAAP,eAAAO,EAAA,QAAAJ,aAAA;AAI3CoC,SAAAC,MAAA;AACC,OAAIA,EAACC,QAAS,WAAV,CAAsBD,EAACE,UAAS;AACnC,QAAIvC,aAAW;AACdqC,OAACG,gBAAiB;AAClBL,sBAAiB;AAAA;;AAGlB,QAAItC,aAAW;AACdwC,OAACG,gBAAiB;AAClBR,8BAAyB;;;;AAG3B5B,IAAA,MAAA4B;AAAA5B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAP;AAAAO,IAAA,MAAAJ;AAAAI,IAAA,MAAAgC;OAAAA,OAAAhC,EAAA;CAbF,MAAAqC,gBAAsBL;CAerB,IAAAM;AAAA,KAAAtC,EAAA,QAAAR,WAAA;AAIY8C,QAAAtD,GACV,0BACA,cACA,oCACA,aACA,yDACA,kCACAQ,UACA;AAAAQ,IAAA,MAAAR;AAAAQ,IAAA,MAAAsC;OAAAA,OAAAtC,EAAA;CAAA,IAAAuC;CAAA,IAAAC;AAAA,KAAAxC,EAAA,QAAAyC,OAAAC,IAAA,4BAAA,EAAA;AASWH,QAAAvD,GACV,kBACA,kBACA,+DACA,gBACA,eACA,+BACA;AACMwD,QAAA,EAAAG,aAAe,SAAS;AAAA3C,IAAA,MAAAuC;AAAAvC,IAAA,MAAAwC;QAAA;AAAAD,QAAAvC,EAAA;AAAAwC,QAAAxC,EAAA;;CACpB,MAAA4C,MAAA,CAAC5B;CAAQ,IAAA6B;AAAA,KAAA7C,EAAA,QAAAmB,wBAAAnB,EAAA,QAAAqC,iBAAArC,EAAA,QAAA4C,KAAA;AAdrBC,QAAA,oBAAA,kBAAA;GACM5B,KAAAA;GACQE,aAAAA;GACJ,SAAA;GACA,SAAA;GACE,WAAAoB;GAQJ,OAAAC;GACI,WAAAI;GAEW,sBAAAE;GAEXT,WAAAA;IACV;AAAArC,IAAA,MAAAmB;AAAAnB,IAAA,MAAAqC;AAAArC,IAAA,MAAA4C;AAAA5C,IAAA,MAAA6C;OAAAA,OAAA7C,EAAA;CAAA,IAAA+C;AAAA,KAAA/C,EAAA,QAAAT,eAAA;AAGDwD,QAAAxD,iBAAiB,oBAAC,mBAAiB;AAAAS,IAAA,MAAAT;AAAAS,IAAA,MAAA+C;OAAAA,OAAA/C,EAAA;CAAA,IAAAgD;AAAA,KAAAhD,EAAA,QAAAX,iBAAAW,EAAA,QAAAJ,eAAAI,EAAA,QAAAV,iBAAAU,EAAA,QAAAZ,iBAAA;AAGnC4D,QAAA5D,mBAAAE,iBAAA,CAAqCM,eACrC,oBAAA;GACM,MAAA;GACIN,SAAAA;GACE,WAAAN,GACV,iBACA,6BACA,kCACAK,gBAAA,2BAAA,sDAGD;GACY,cAAAA,gBAAA,qBAAA;aAEZ,oBAAC,OAAc,WAAA,8BAChB;IACA;AAAAW,IAAA,MAAAX;AAAAW,IAAA,MAAAJ;AAAAI,IAAA,MAAAV;AAAAU,IAAA,MAAAZ;AAAAY,IAAA,MAAAgD;OAAAA,OAAAhD,EAAA;CAAA,IAAAiD;AAAA,KAAAjD,EAAA,QAAA4B,2BAAA5B,EAAA,QAAA+B,mBAAA/B,EAAA,QAAAP,eAAAO,EAAA,QAAAJ,aAAA;AAGDqD,QAAA,oBAAA,gBAAA;GAA6B,SAAA;aAC3BrD,cAEA,oBAAA;IACM,MAAA;IACImC,SAAAA;IACE,WAAA/C,GACV,iBACA,6BACA,8BACA,kBACA,mDACA,iCACD;IACW,cAAA;cAEX,oBAAC,QAAe,WAAA,8BACjB;KAoCA,GAnCGS,cAEH,oBAAA;IACM,MAAA;IACImC,SAAAA;IACE,WAAA5C,GACV,iBACA,6BACA,8BACA,kBACA,mDACA,iCACD;IACW,cAAA;cAEX,oBAAC,QAAe,WAAA,8BACjB;KAmBA,GAhBA,oBAAA,kBAAA;IAAwB,SAAA;cACvB,oBAAA;KACM,MAAA;KACM,WAAAA,GACV,iBACA,6BACA,8BACA,kBACA,mDACA,iCACD;KACW,cAAA;eAEX,oBAAC,QAAe,WAAA,8BACjB;MACD;KACD;IACoB;AAAAgB,IAAA,MAAA4B;AAAA5B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAP;AAAAO,IAAA,MAAAJ;AAAAI,IAAA,MAAAiD;OAAAA,OAAAjD,EAAA;CAAA,IAAAkD;AAAA,KAAAlD,EAAA,QAAAyC,OAAAC,IAAA,4BAAA,EAAA;AAOPQ,QAAAlE,GACV,iBACA,6BACA,0BACA,qBACA,iCACA;AAAAgB,IAAA,MAAAkD;OAAAA,OAAAlD,EAAA;CAAA,IAAAmD;AAAA,KAAAnD,EAAA,QAAAyC,OAAAC,IAAA,4BAAA,EAAA;AAVJS,QAAA,oBAAA,gBAAA;GAAoB,SAAA;aACnB,oBAAA,kBAAA;IAA0B,SAAA;cACzB,oBAAA;KACM,MAAA;KACM,WAAAD;KAOA,cAAA;eAEX,oBAAC,UAAiB,WAAA,8BACnB;MACD;KACD;IAAqB;AAAAlD,IAAA,MAAAmD;OAAAA,OAAAnD,EAAA;CAAA,IAAAoD;AAAA,KAAApD,EAAA,QAAAuB,gBAAAvB,EAAA,QAAAsC,OAAAtC,EAAA,QAAA6C,OAAA7C,EAAA,QAAA+C,OAAA/C,EAAA,QAAAgD,OAAAhD,EAAA,QAAAiD,KAAA;AAlItBG,QAAA,qBAAA,kBAAA;GACY,WAAAd;GASDf,UAAAA;;IAGVsB;IAsBCE;IAGAC;IAmBDC;IAyDAE;;IAiBwB;AAAAnD,IAAA,MAAAuB;AAAAvB,IAAA,MAAAsC;AAAAtC,IAAA,MAAA6C;AAAA7C,IAAA,MAAA+C;AAAA/C,IAAA,MAAAgD;AAAAhD,IAAA,MAAAiD;AAAAjD,IAAA,MAAAoD;OAAAA,OAAApD,EAAA;AAAA,QAnIzBoD;;AA5FyB,SAAAlD,QAAA/B,KAAA;AAAA,QACUA,IAAC2B;;AAqBa,SAAAgD,SAAAO,KAAA;AAAA,QAmGlBpB,IAACqB,iBAAkB;;;;;;;;;;;;;;;;;;;AC5IpD,SAAOK,cAAAC,UAAAC,cAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAK0DF,uBAAA,IAAIG,KAAK;AAAAJ,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAzE,MAAAK,sBAA4BT,OAAoCK,GAAU;CAAA,IAAAK;CAAA,IAAAC;AAAA,KAAAP,EAAA,OAAAD,gBAAAC,EAAA,OAAAF,UAAA;AAEhEQ,aAAA;AACT,OAAI,CAACR,UAAQ;AAEZO,wBAAmBG,QAAQC,QAASC,QAMlC;AACFL,wBAAmBG,QAAQG,OAAQ;AAAA;;GAKpC,MAAAC,YAAkBb,aAAYS;AAC9B,OAAI,CAACI,UAAS;GAGd,IAAAC,aAAiCD;AACjC,UAAOC,cAAcA,WAAUC,kBAAmBC,SAAQC,KACzDH,cAAaA,WAAUC;AAGxB,OAAI,CAACD,WAAU;AAMfI,GAHqBC,MAAKC,KAAMJ,SAAQC,KAAKI,SAAU,CAG3CX,SAASY,UAAA;AAEpB,QAAIA,UAAUR,WAAU;AAGxB,QAAIQ,MAAKC,YAAa,YAAYD,MAAKC,YAAa,WAAWD,MAAKC,YAAa,OAAM;IAKvF,MAAAC,kBAAsBF,MAAKG,aAAc,cAAc;AACvDnB,wBAAmBG,QAAQiB,IAAKJ,OAAOK,gBAAc;AAGrDL,UAAKM,aAAc,eAAe,OAAO;KACxC;AAAA,gBAGK;AACNtB,wBAAmBG,QAAQC,QAASmB,SAMlC;AACFvB,wBAAmBG,QAAQG,OAAQ;;;AAElCJ,OAAA,CAACT,UAAUC,aAAa;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAF;AAAAE,IAAA,KAAAM;AAAAN,IAAA,KAAAO;QAAA;AAAAD,OAAAN,EAAA;AAAAO,OAAAP,EAAA;;AA1D3BL,WAAUW,IA0DPC,GAAyB;;AAjEtB,SAAAqB,SAAAC,iBAAAC,WAAA;AAyDH,KAAIJ,oBAAkB,KACrBK,WAAOC,gBAAiB,cAAc;KAEtCD,WAAOJ,aAAc,eAAeD,gBAAc;;AA5DhD,SAAAhB,QAAAgB,eAAAK,SAAA;AAWH,KAAIL,kBAAkB,KACrBK,SAAOC,gBAAiB,cAAc;KAEtCD,SAAOJ,aAAc,eAAeD,cAAc;;;;;;AC3BvD,MAAMY,qBAAqB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAACC,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;AA6CZ,SAAOa,aAAAC,IAAA;CAAA,MAAAC,IAAApB,EAAA,GAAA;CAAsB,MAAA,EAAAO,UAAAC,UAAAC,WAAAY,IAAAX,aAAAY,IAAAX,sBAAAY,OAAAJ;CAG5B,MAAAV,YAAAY,OAAAG,SAAA,OAAAH;CACA,MAAAX,cAAAY,OAAAE,SAAA,OAAAF;CACA,MAAAX,uBAAAY,OAAAC,SAAA,QAAAD;CAEA,MAAAV,eAAqBV,OAA8B,KAAK;CACxD,MAAAsB,aAAmBtB,OAA2B,KAAK;CACnD,MAAAuB,uBAA6BvB,OAA2B,KAAK;CAAA,IAAAwB;AAAA,KAAAP,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAG5BF,aAAA;AAChCF,cAAUK,UAAWC,SAAQC;;AAC7BZ,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAFD,MAAAH,eAAqBU;CAEf,IAAAO;AAAA,KAAAd,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAGmCK,aAAA;AACxC,OAAI,CAACrB,aAAYiB,QAAQ,QAAS,EAAE;AAAA,UAC7BK,MAAKC,KAAMvB,aAAYiB,QAAQO,iBAA+BjC,mBAAmB,CAAC;;AACzFgB,IAAA,KAAAc;OAAAA,MAAAd,EAAA;CAHD,MAAAkB,uBAA6BJ;CAGvB,IAAAK;CAAA,IAAAC;AAAA,KAAApB,EAAA,OAAAX,aAAAW,EAAA,OAAAb,YAAAa,EAAA,OAAAV,eAAAU,EAAA,OAAAT,sBAAA;AAGI4B,aAAA;AACT,OAAIhC,UAAQ;AAEXmB,yBAAoBI,UAAWC,SAAQC;AAGvC,QAAIvB,WAAS;KAEZ,MAAAgC,YAAkBC,iBAAW;MAC5B,MAAAC,oBAA0BL,sBAAsB;AAChD,UAAIK,kBAAiBC,SAAU,EAC9BD,mBAAiB,GAAGE,OAAQ;UAG5BhC,cAAYiB,SAAee,OAAE;QAE5B,GAAG;AAAA,kBAEOC,aAAaL,UAAU;;cAIjC/B,eAAee,WAAUK,WAAYL,WAAUK,QAAQiB,aAAY;IAEtE,MAAAC,iBACCvB,WAAUK,QAAQmB,YAAa,WAAWxB,WAAUK,QAAQmB,YAAa;AAE1E,QAAItC,wBAAAqC,eAEHvB,YAAUK,QAAQoB,MAAO;QAEzBzB,YAAUK,QAAQe,OAAQ;cAEjBnC,eAAegB,qBAAoBI,SAAqBiB,aAAA;IAClE,MAAAI,mBACCzB,qBAAoBI,QAAQmB,YAAa,WACzCvB,qBAAoBI,QAAQmB,YAAa;AAE1C,QAAItC,wBAAAwC,iBACHzB,sBAAoBI,QAAQoB,MAAO;QAEnCxB,sBAAoBI,QAAQe,OAAQ;;;AAIrCL,OAAA;GAACjC;GAAUE;GAAWC;GAAaC;GAAsB2B;GAAqB;AAAAlB,IAAA,KAAAX;AAAAW,IAAA,KAAAb;AAAAa,IAAA,KAAAV;AAAAU,IAAA,KAAAT;AAAAS,IAAA,KAAAmB;AAAAnB,IAAA,KAAAoB;QAAA;AAAAD,OAAAnB,EAAA;AAAAoB,OAAApB,EAAA;;AA7CjFlB,WAAUqC,IA6CPC,GAA+E;CAAA,IAAAY;CAAA,IAAAC;AAAA,KAAAjC,EAAA,OAAAb,YAAAa,EAAA,OAAAZ,UAAA;AAGxE4C,aAAA;AACT,OAAI,CAAC7C,SAAQ;GAEb,MAAA+C,iBAAsBC,UAAA;AAErB,QAAIA,MAAKC,QAAS,YAAdhD,UAAkC;AACrC+C,WAAKE,gBAAiB;AACtBjD,eAAU;AAAA;;AAKX,QAAI+C,MAAKC,QAAS,OAAK;KACtB,MAAAE,sBAA0BpB,sBAAsB;AAChD,SAAIK,oBAAiBC,WAAY,EAAC;KAElC,MAAAe,eAAqBhB,oBAAiB;KACtC,MAAAiB,cAAoBjB,oBAAkBA,oBAAiBC,SAAU;KACjE,MAAAZ,gBAAsBD,SAAQC;AAG9B,SAAIuB,MAAKM,YAAa7B,kBAAkB2B,cAAY;AACnDJ,YAAKE,gBAAiB;AACtBG,kBAAWf,OAAQ;AAAA;;AAKpB,SAAI,CAACU,MAAKM,YAAa7B,kBAAkB4B,aAAW;AACnDL,YAAKE,gBAAiB;AACtBE,mBAAYd,OAAQ;AAAA;;AAKrB,SAAI,CAAChC,aAAYiB,SAAkBgC,SAAC9B,cAAc,EAAA;AACjDuB,YAAKE,gBAAiB;AACtBE,mBAAYd,OAAQ;;;;AAKvBd,YAAQgC,iBAAkB,WAAWT,cAAc;AAAA,gBACtCvB,SAAQiC,oBAAqB,WAAWV,cAAc;;AACjED,OAAA;GAAC9C;GAAUC;GAAU8B;GAAqB;AAAAlB,IAAA,KAAAb;AAAAa,IAAA,KAAAZ;AAAAY,IAAA,MAAAgC;AAAAhC,IAAA,MAAAiC;QAAA;AAAAD,OAAAhC,EAAA;AAAAiC,OAAAjC,EAAA;;AA5C7ClB,WAAUkD,IA4CPC,GAA2C;CAAA,IAAAY;AAAA,KAAA7C,EAAA,QAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAEvCoC,QAAA;GAAApD;GAAAI;GAGN;AAAAG,IAAA,MAAA6C;OAAAA,OAAA7C,EAAA;AAAA,QAHM6C;;;;;AC3IR,MAAM6B,aAAa;CAClBC,MAAM;CACNE,WAAW;CACXC,SAAS;CACTC,MAAM;CACN;AAGD,MAAMC,kBAAkB;CACvBL,MAAM;CACNM,UAAU;CACVC,MAAM;EAAC;EAAK;EAAG;EAAK;EAAE;CACtB;AAGD,MAAMC,0BAA0B,EAC/BF,UAAU,GACV;AAKD,MAAMG,QAAQvB;AACd,MAAMwB,sBAGF;CACHM,WAAW;EACVJ,OAAO7B,UAAU0B,MAAMO,UAAUJ,MAAM;EACvCC,QAAQ9B,UAAU0B,MAAMO,UAAUH,OAAO;EACzCC,SAAS;EACTC,cAAc9B,mBAAmBgC;EACjC;CACDC,SAAS;EACRN,OAAO7B,UAAU0B,MAAMS,QAAQN,MAAM;EACrCC,QAAQ9B,UAAU0B,MAAMS,QAAQL,OAAO;EACvCC,SAAS;EACTC,cAAc9B,mBAAmBgC;EACjC;CACDE,WAAW;EACVP,OAAO7B,UAAU0B,MAAMU,UAAUP,MAAM;EACvCC,QAAQ;EACRC,SAAS;EACTC,cAAc9B,mBAAmBmC;EACjC;CACDC,QAAQ;EACPT,OAAO7B,UAAU0B,MAAMY,OAAOT,MAAM;EACpCC,QAAQ;EACRC,SAAS;EACTC,cAAc9B,mBAAmBmC;EACjC;CACDE,UAAU;EACTV,OAAO7B,UAAU0B,MAAMa,SAASV,MAAM;EACtCC,QAAQ;EACRC,SAAS;EACTC,cAAc9B,mBAAmBmC;EAClC;CACA;AAGD,MAAMG,oBAAoB;CACzBX,OAAO,OAAO5B,mBAAmBwC,aAAY,MAAOxC,mBAAmByC,SAAQ;CAC/EZ,QAAQ,GAAG7B,mBAAmB0C,cAAa;CAC3CZ,SAAS,GAAG9B,mBAAmB8B,QAAO;CACtCC,cAAc9B,mBAAmBmC;CACjC;AAGD,MAAMO,kBAA4B;CACjCC,QAAQ,EACPC,SAAS,GACT;CACDC,SAAS;EACRD,SAAS;EACTE,YAAY;GACXzB,UAAU;GACV0B,OAAO;GACR;EACA;CACDC,MAAM;EACLJ,SAAS;EACTE,YAAY,EACXzB,UAAU,IACX;EACD;CACA;AAGD,MAAM4B,eAAyB;CAC9BN,QAAQ,EAAEC,SAAS,GAAG;CACtBC,SAAS;EACRD,SAAS;EACTE,YAAY;GAAEC,OAAO;GAAM1B,UAAU;GAAK;EAC1C;CACD2B,MAAM;EACLJ,SAAS;EACTE,YAAY,EAAEzB,UAAU,KAAK;EAC9B;CACA;AAGD,MAAM6B,cAAwB;CAC7BC,MAAM;EACLP,SAAS;EACTQ,QAAQ;EACR;CACDC,OAAO;EACNT,SAAS;EACTQ,QAAQ;EACRN,YAAY,EAAEzB,UAAU,IAAI;EAC7B;CACA;;;;;;;;;;;;AAaD,MAAaiC,iBAAyC,EACrD7C,MACAC,UACAC,cACAC,eAAe,OACfC,gBACK;CACL,MAAM,CAAC0C,WAAWC,gBAAgBhE,SAAS,MAAM;CACjD,MAAMiE,kBAAkBlE,OAA8B,KAAK;CAC3D,MAAMqE,uBAAuBxE,kBAAkB;CAG/C,MAAMyE,mBAAmBtE,OAAOqB,aAAa;CAC7C,MAAMkD,4BAA4BlD,iBAAiBiD,iBAAiBE;AAEpEzE,iBAAgB;AACfuE,mBAAiBE,UAAUnD;IACzB,CAACA,aAAa,CAAC;CAGlB,MAAM,EAAEoD,aAAarE,iBAAiB;CAGtC,MAAMsE,iBAAiBxD,SAAS,eAAeA,SAAS,YAAYA,SAAS;CAG7E,MAAM,EAAEyD,cAAcC,cAAcC,iBAAiB1E,aAAa;EACjE2E,UAAUJ;EACVK,gBAAgB;AAEf,OAAI7D,SAAS,SACZE,gBAAe,YAAY;;EAG7B4D,WAAW;EACXC,aAAa;EAEbC,sBAAsBT;EACtB,CAAC;CAGF,MAAMU,cAAcnF,OAAOkB,KAAK;AAChCnB,iBAAgB;AAKf,OAHCoF,YAAYX,YAAY,eAAeW,YAAYX,YAAY,eAC5CtD,SAAS,eAAeA,SAAS,YAAYA,SAAS,YAGzE2D,eAAc;AAGfM,cAAYX,UAAUtD;IACpB,CAACA,MAAM2D,aAAa,CAAC;AAIxB3E,eAAcwE,gBAAgBE,aAAa;CAG3C,MAAMU,mBAAmBxF,kBAAkB;AAE1C,MAAI2E,SAAU;AAEd,MAAIP,gBAAgBM,QACnBe,cAAarB,gBAAgBM,QAAQ;AAEtCN,kBAAgBM,UAAUgB,iBAAiB;AAC1CvB,gBAAa,KAAK;AAClB,OAAI/C,SAAS,YACZE,gBAAe,UAAU;KAExBT,UAAU8E,cAAc;IACzB;EAACvE;EAAME;EAAcqD;EAAS,CAAC;CAElC,MAAMiB,mBAAmB5F,kBAAkB;AAE1C,MAAI2E,SAAU;AAEd,MAAIP,gBAAgBM,QACnBe,cAAarB,gBAAgBM,QAAQ;AAEtCP,eAAa,MAAM;AACnB,MAAI/C,SAAS,UAEZgD,iBAAgBM,UAAUgB,iBAAiB;AAC1CpE,kBAAe,YAAY;KACzBT,UAAUgF,cAAc;IAE1B;EAACzE;EAAME;EAAcqD;EAAS,CAAC;CAGlC,MAAMmB,cAAc9F,kBAAkB;AACrC,MAAIoB,SAAS,eAAeA,SAAS,UACpCE,gBAAe,YAAY;IAE1B,CAACF,MAAME,aAAa,CAAC;CAGxB,MAAMyE,cAAc/F,kBAAkB;AACrC,MAAIoB,SAAS,eAAe,CAACuD,SAC5BrD,gBAAe,UAAU;IAExB;EAACF;EAAME;EAAcqD;EAAS,CAAC;CAElC,MAAMqB,aAAahG,kBAAkB;AACpC,MAAIoB,SAAS,aAAa,CAACuD,SAC1BrD,gBAAe,YAAY;IAE1B;EAACF;EAAME;EAAcqD;EAAS,CAAC;AAGlC1E,iBAAgB;EACf,MAAMgG,iBAAiBC,MAAqB;GAC3C,MAAME,cAAcF,EAAEG,WAAWH,EAAEI,YAAYJ,EAAEK,YAAYL,EAAEM,IAAIC,aAAa,KAAK;GACrF,MAAMC,WAAWR,EAAEM,QAAQ;AAE3B,OAAIJ,YAAY;AACfF,MAAES,gBAAgB;AAClB,QAAIvF,SAAS,YACZE,gBAAe,YAAY;aACjBF,SAAS,eAAeA,SAAS,UAC3CE,gBAAe,YAAY;;AAK7B,OAAIoF,aAAatF,SAAS,eAAeA,SAAS,cAAcA,SAAS,YAAY;AACpF8E,MAAES,gBAAgB;AAClBrF,mBAAe,YAAY;;;AAI7BsF,SAAOC,iBAAiB,WAAWZ,cAAc;AACjD,eAAaW,OAAOE,oBAAoB,WAAWb,cAAc;IAC/D,CAAC7E,MAAME,aAAa,CAAC;AAGxBrB,iBAAgB;AACf,eAAa;AACZ,OAAImE,gBAAgBM,QACnBe,cAAarB,gBAAgBM,QAAQ;;IAGrC,EAAE,CAAC;CAEN,MAAMqC,cAAc3F,SAAS,eAAeA,SAAS;CAErD,MAAM4F,iBAAiBzF,eAAe0B,oBAAoBb,oBAAkBhB;CAC5E,MAAM6F,eAAe7F,SAAS,eAAeA,SAAS,YAAYA,SAAS;CAG3E,MAAM8F,kBAAkBlH,aACtBmH,SAAgC;AAEhC,MAAIrC,aACHA,cAAaJ,UAAUyC;IAGzB,CAACrC,aACF,CAAC;CAGD,MAAMuC,iBAAiBvG,GACtB,YAEAS,eAAe,gDAAgD,mBAE/D,CAACgD,wBAAwB,yBAEzB,yIAEAnD,SAAS,eAAe,wBACxBA,SAAS,aAAa,uBACrBA,SAAS,eAAeA,SAAS,eAAe,cACjDA,SAAS,YAAY,2BACrBI,UACA;CAID,MAAMiC,aAAac,uBAChBrC,0BACAuC,6BAA6BlD,eAC5BQ,kBACAN;AAEJ,QACC,qBAAC,OAAO;EACP,KAAKyF;EACL,WAAWG;EACX,SAAS;EACT,SAAS;GACR/E,OAAO0E,eAAe1E;GACtBC,QAAQyE,eAAezE;GACvBC,SAASwE,eAAexE;GACxBC,cAAcuE,eAAevE;GAC7B;EACWgB;EACZ,cAAc+B;EACd,cAAcI;EACd,SAASE;EACT,SAASC;EACT,QAAQC;EAER,MAAMiB,eAAe,WAAW;EAChC,UAAUA,eAAe,KAAK;EAE9B,cAAYA,eAAe,OAAOK;EAClC,mBAAiBL,eAAe1G,SAASgH,YAAYD;EACrD,cAAY,CAACL,eAAezG,YAAYgH,gBAAgBF;;GAGxD,oBAAC;IAAgB,MAAK;cACpBlG,SAAS,eACT,oBAAC,OAAO;KAEP,WAAU;KACV,UAAUyC;KACV,SAAQ;KACR,SAASK,YAAY,UAAU;KAC/B,MAAM;MAAEX,SAAS;MAAGE,YAAY,EAAEzB,UAAU,IAAI;MAAG;KACnD,OAAO;MACNyF,YAAY;MACZC,gBAAgB;MAChB;OATG,gBAWL;KACe;GAGjB,oBAAC;IAAgB,MAAK;cACpBtG,SAAS,aACT,oBAAC,OAAO;KAEP,WAAU;KACV,UAAUwC;KACV,SAAQ;KACR,SAAQ;KACR,MAAK;eAEL,qBAAC;MAAK,WAAU;;OAAuB;OAC7B;OACT,oBAAC;QAAI,WAAU;kBAA0D;SAAQ;;OAC5E;OAVF,aAYL;KACe;GAGjB,oBAAC;IAAgB,MAAK;cACpBmD,eACA,qBAAC,OAAO;KAEP,WAAU;KACV,UAAU1D;KACV,SAAQ;KACR,SAAQ;KACR,MAAK;gBAGL,oBAAC;MAAK,IAAI9C,SAASgH;MAAW,WAAU;gBAAS;OAE3C,EACLlG;OAXG,UAaL;KACe;;GACL;;;;;AC7Zf,MAAM6G,mBAAiBN,IACtB,+bACA;CACCQ,UAAU;EACTC,SAAS;GACRC,SAAS;GACTC,aACC;GACDC,SACC;GACDC,WAAW;GACXC,OAAO;GACPC,MAAM;GACN;EACDC,MAAM;GACLN,SAAS;GACTO,IAAI;GACJC,IAAI;GACJC,MAAM;GACN,WAAW;GACX,WAAW;GACZ;EACA;CACDC,iBAAiB;EAChBX,SAAS;EACTO,MAAM;EACP;CAEF,CAAC;AAED,SAAAK,OAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAV;CAAA,IAAAW;CAAA,IAAAlB;AAAA,KAAAc,EAAA,OAAAD,IAAA;AAAgB,GAAA,CAAAG,WAAAhB,SAAAO,MAAAT,SAAAoB,OAAAD,SAAAJ;AASdC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAP;AAAAO,IAAA,KAAAI;AAAAJ,IAAA,KAAAd;QAAA;AAAAgB,cAAAF,EAAA;AAAAG,UAAAH,EAAA;AAAAP,SAAAO,EAAA;AAAAI,OAAAJ,EAAA;AAAAd,YAAAc,EAAA;;CACD,MAAAM,QANAF,OAAAC,SAAA,QAAAD,MAMa5B,OAAA;CAAyB,IAAA+B;AAAA,KAAAP,EAAA,OAAAE,aAAAF,EAAA,OAAAP,QAAAO,EAAA,OAAAd,SAAA;AAKzBqB,OAAA5B,GAAGI,iBAAe;GAAAG;GAAAO;GAAAS;GAA4B,CAAC,CAAC;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAP;AAAAO,IAAA,KAAAd;AAAAc,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAAA,IAAAQ;AAAA,KAAAR,EAAA,QAAAM,QAAAN,EAAA,QAAAG,SAAAH,EAAA,QAAAO,IAAA;AAF5DC,OAAA,oBAAC;GACU,aAAA;GACC,WAAAD;GAAgD,GACvDJ;IACH;AAAAH,IAAA,MAAAM;AAAAN,IAAA,MAAAG;AAAAH,IAAA,MAAAO;AAAAP,IAAA,MAAAQ;OAAAA,MAAAR,EAAA;AAAA,QAJFQ;;;;;;;;;;;;;;;;;ACtBF,SAASwB,iBAAiBD,QAA2C;AACpE,QACC,OAAOA,WAAW,YAClBA,WAAW,QACX,cAAcA,UACbA,OAA0BD,aAAa,QACxC,YAAYC;;;;;;AAQd,SAASE,eAAeF,QAA0B;AAEjD,KAAI,OAAOA,WAAW,YAAYA,WAAWT,oBAC5C,QAAO;AAGR,KACC,OAAOS,WAAW,YAClBA,WAAW,QACX,cAAcA,UACbA,OAAiCD,aAAa,MAE/C,QAAO;AAER,QAAO;;;;;AAMR,SAASI,eAAeC,QAAqE;AAC5F,QAAO,WAAWA,UAAU,OAAQA,OAA+BE,UAAU;;;;;AAU9E,MAAMC,sBAEDI,OAAA;CAAA,MAAAC,IAAAjC,EAAA,GAAA;CAAC,MAAA,EAAA+B,aAAAC;CAAY,IAAAE;AAAA,KAAAD,EAAA,OAAAF,UAAA;AACAG,OAAAjB,YAAYc,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAtC,MAAAE,WAAiBD;CAAqB,IAAAE;AAAA,KAAAH,EAAA,OAAAE,UAAA;AAIpCC,OAAA,oBAAC,YAAmB,WAAA,4CAA4C;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAF,UAAA;AAE5BM,OAAA1B,iBAAiBoB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAI,IAAA;AAD9DC,OAAA,oBAAA,oBACC,oBAAA;GAAkB,WAAA;aAAiBD;IACpC,GAAO;AAAAJ,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAG,MAAAH,EAAA,OAAAK,IAAA;AAJRC,OAAA,qBAAA;GAAe,WAAA;cACdH,IACAE;IAGK;AAAAL,IAAA,KAAAG;AAAAH,IAAA,KAAAK;AAAAL,IAAA,MAAAM;OAAAA,MAAAN,EAAA;AAAA,QALNM;;;;;;AAaF,MAAMC,kBAODR,OAAA;CAAA,MAAAC,IAAAjC,EAAA,GAAA;CAAC,MAAA,EAAA+B,UAAAU,iBAAAC,WAAAE,WAAAC,QAAAC,gBAAAd;CACL,MAAA,CAAAe,WAAAC,gBAAkCvC,SAAoC,KAAK;CAAA,IAAAyB;AAAA,KAAAD,EAAA,OAAAF,UAAA;AAC1DG,OAAAjB,YAAYc,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAtC,MAAAE,WAAiBD;AAEjB,KAAIY,aAAW;EAAA,IAAAV;AAAA,MAAAH,EAAA,OAAAE,UAAA;AAGZC,UAAA,oBAAC,YAAmB,WAAA,4CAA4C;AAAAH,KAAA,KAAAE;AAAAF,KAAA,KAAAG;QAAAA,QAAAH,EAAA;EAAA,IAAAI;AAAA,MAAAJ,EAAA,OAAAF,UAAA;AAE5BM,UAAA1B,iBAAiBoB,SAAS;AAAAE,KAAA,KAAAF;AAAAE,KAAA,KAAAI;QAAAA,QAAAJ,EAAA;EAAA,IAAAK;AAAA,MAAAL,EAAA,OAAAI,MAAA;AAD9DC,UAAA,oBAAA,oBACC,oBAAA;IAAkB,WAAA;cAAiBD;KACpC,GAAO;AAAAJ,KAAA,KAAAI;AAAAJ,KAAA,KAAAK;QAAAA,QAAAL,EAAA;EAAA,IAAAM;AAAA,MAAAN,EAAA,OAAAG,QAAAH,EAAA,OAAAK,MAAA;AAJRC,UAAA,qBAAA;IAAe,WAAA;eACdH,MACAE;KAGK;AAAAL,KAAA,KAAAG;AAAAH,KAAA,KAAAK;AAAAL,KAAA,MAAAM;QAAAA,QAAAN,EAAA;AAAA,SALNM;;CAOD,IAAAH;AAAA,KAAAH,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAGgBd,OAAAvB,GAAG,mCAAmC,aAAa;AAAAoB,IAAA,MAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,QAAAE,UAAA;AAIhEE,OAAA,oBAAC,YAAmB,WAAA,8BAA8B;AAAAJ,IAAA,MAAAE;AAAAF,IAAA,MAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAClDZ,OAAA,oBAAC,iBAAwB,WAAA,0DAA0D;AAAAL,IAAA,MAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,QAAAI,IAAA;AAFpFE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAL,IAAA,MAAAI;AAAAJ,IAAA,MAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,QAAAF,UAAA;AAC+CoB,OAAAxC,iBAAiBoB,SAAS;AAAAE,IAAA,MAAAF;AAAAE,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAkB,IAAA;AAA/EC,OAAA,oBAAA;GAAgB,WAAA;aAAqCD;IAAkC;AAAAlB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAM,MAAAN,EAAA,QAAAmB,IAAA;AALxFC,OAAA,qBAAA;GAAe,WAAA;cACdd,IAIAa;IACK;AAAAnB,IAAA,MAAAM;AAAAN,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,QAAAQ,iBAAA;AAIJa,OAAAb,mBACA,oBAAA;GAAe,WAAA;aAA2CA;IAC1D;AAAAR,IAAA,MAAAQ;AAAAR,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,QAAAS,WAAA;AAGAa,QAAAb,aAAac,OAAMC,KAAMf,UAAU,CAAAgB,SAAU,KAC7C,oBAAA;GAAe,WAAA;aACd,oBAAA;IAAe,WAAA;cACbhD,WAAWgC,UAAS;KAEvB;IACA;AAAAT,IAAA,MAAAS;AAAAT,IAAA,MAAAsB;OAAAA,OAAAtB,EAAA;CAAA,IAAA0B;CAAA,IAAAC;AAAA,KAAA3B,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAOeS,cAAMX,aAAa,OAAO;AAC1BY,cAAMZ,aAAa,KAAK;AAAAf,IAAA,MAAA0B;AAAA1B,IAAA,MAAA2B;QAAA;AAAAD,QAAA1B,EAAA;AAAA2B,QAAA3B,EAAA;;CAKrC,MAAA4B,MAAAd,cAAc,SAAd,8BAAA;CAAuE,IAAAe;AAAA,KAAA7B,EAAA,QAAA4B,KAAA;AAJ7DC,QAAAjD,GACV,qFACA,wCACA,kCACAgD,IACA;AAAA5B,IAAA,MAAA4B;AAAA5B,IAAA,MAAA6B;OAAAA,OAAA7B,EAAA;CAAA,IAAA8B;AAAA,KAAA9B,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAEDa,QAAA,oBAAC,KAAY,WAAA,8BAA8B;AAAA9B,IAAA,MAAA8B;OAAAA,OAAA9B,EAAA;CAAA,IAAA+B;AAAA,KAAA/B,EAAA,QAAAY,UAAAZ,EAAA,QAAA6B,KAAA;AAZ5CE,QAAA,qBAAA;GACM,MAAA;GACInB,SAAAA;GACK,cAAAc;GACA,cAAAC;GACH,WAAAE;cAOXC,KAA2C;IAEnC;AAAA9B,IAAA,MAAAY;AAAAZ,IAAA,MAAA6B;AAAA7B,IAAA,MAAA+B;OAAAA,OAAA/B,EAAA;CAAA,IAAAgC;CAAA,IAAAC;AAAA,KAAAjC,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAIMe,cAAMjB,aAAa,UAAU;AAC7BkB,cAAMlB,aAAa,KAAK;AAAAf,IAAA,MAAAgC;AAAAhC,IAAA,MAAAiC;QAAA;AAAAD,QAAAhC,EAAA;AAAAiC,QAAAjC,EAAA;;CAKrC,MAAAkC,MAAApB,cAAc,YAAd,aAAA;CAA0D,IAAAqB;AAAA,KAAAnC,EAAA,QAAAkC,KAAA;AAJhDC,QAAAvD,GACV,qFACA,8BACA,kCACAsD,IACA;AAAAlC,IAAA,MAAAkC;AAAAlC,IAAA,MAAAmC;OAAAA,OAAAnC,EAAA;CAAA,IAAAoC;AAAA,KAAApC,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAEDmB,QAAA,oBAAC,SAAgB,WAAA,8BAA8B;AAAApC,IAAA,MAAAoC;OAAAA,OAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,QAAAW,aAAAX,EAAA,QAAAmC,KAAA;AAZhDE,QAAA,qBAAA;GACM,MAAA;GACI1B,SAAAA;GACK,cAAAqB;GACA,cAAAC;GACH,WAAAE;cAOXC,KAA+C;IAEvC;AAAApC,IAAA,MAAAW;AAAAX,IAAA,MAAAmC;AAAAnC,IAAA,MAAAqC;OAAAA,OAAArC,EAAA;CAAA,IAAAsC;AAAA,KAAAtC,EAAA,QAAA+B,OAAA/B,EAAA,QAAAqC,KAAA;AA9BVC,QAAA,qBAAA;GAAe,WAAA;cACdP,KAeAM;IAeK;AAAArC,IAAA,MAAA+B;AAAA/B,IAAA,MAAAqC;AAAArC,IAAA,MAAAsC;OAAAA,OAAAtC,EAAA;CAAA,IAAAuC;AAAA,KAAAvC,EAAA,QAAAsB,OAAAtB,EAAA,QAAAsC,OAAAtC,EAAA,QAAAqB,IAAA;AA9CPkB,QAAA,qBAAA;GAAe,WAAA;;IACblB;IAKAC;IASDgB;;IAgCK;AAAAtC,IAAA,MAAAsB;AAAAtB,IAAA,MAAAsC;AAAAtC,IAAA,MAAAqB;AAAArB,IAAA,MAAAuC;OAAAA,OAAAvC,EAAA;CAAA,IAAAwC;AAAA,KAAAxC,EAAA,QAAAuC,OAAAvC,EAAA,QAAAoB,IAAA;AA1DPoB,QAAA,qBAAA;GAAgB,WAAArC;cAEfiB,IASAmB;IAgDK;AAAAvC,IAAA,MAAAuC;AAAAvC,IAAA,MAAAoB;AAAApB,IAAA,MAAAwC;OAAAA,OAAAxC,EAAA;AAAA,QA3DNwC;;;;;AAkEF,MAAMC,wBAID1C,OAAA;CAAA,MAAAC,IAAAjC,EAAA,GAAA;CAAC,MAAA,EAAA+B,UAAA4C,UAAAtD,WAAAW;CACL,MAAA,CAAA4C,YAAAC,iBAAoCpE,SAAS,MAAM;CAAA,IAAAyB;AAAA,KAAAD,EAAA,OAAAF,UAAA;AAClCG,OAAAjB,YAAYc,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAtC,MAAAE,WAAiBD;CAAqB,IAAAE;AAAA,KAAAH,EAAA,OAAA2C,YAAA;AAO1BxC,aAAMyC,cAAc,CAACD,WAAW;AAAA3C,IAAA,KAAA2C;AAAA3C,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAE,UAAA;AAIxCE,OAAA,oBAAC,YAAmB,WAAA,8BAA8B;AAAAJ,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAClDZ,OAAA,oBAAC,SAAgB,WAAA,0DAA0D;AAAAL,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAI,IAAA;AAF5EE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAL,IAAA,KAAAI;AAAAJ,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,OAAAF,UAAA;AAEJoB,OAAAxC,iBAAiBoB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAkB,IAAA;AAD5BC,OAAA,oBAAA;GAAgB,WAAA;aACdD;IACK;AAAAlB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAA2C,YAAA;AACPvB,OAAA,oBAAC;GAAe,SAAA;GAAa,MAAA;GAAe,WAAA;GAAc,SAAA;aACzD,oBAAA,oBACEuB,aACA,oBAAC,iBAAwB,WAAA,0BAGzB,GADA,oBAAC,mBAA0B,WAAA,0BAC5B,GAEF;IAAS;AAAA3C,IAAA,MAAA2C;AAAA3C,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,QAAAG,MAAAH,EAAA,QAAAM,MAAAN,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,IAAA;AApBVC,OAAA,qBAAA;GACM,MAAA;GACI,SAAAlB;GACC,WAAA;;IAEVG;IAIAa;IAGAC;;IASQ;AAAApB,IAAA,MAAAG;AAAAH,IAAA,MAAAM;AAAAN,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,QAAA0C,YAAA1C,EAAA,QAAA2C,cAAA3C,EAAA,QAAAZ,QAAA;AAGRkC,QAAAqB,cACA,qBAAA;GAAe,WAAA;cAEbD,YACA,qBAAA;IAAe,WAAA;eACd,oBAAA;KAAe,WAAA;eAAuE;MAGtF,sBAAA;KAAe,WAAA;eACbA;MAEH;KACD,EAGCtD,WAAWyD,UACX,qBAAA,oBACC,oBAAA;IAAe,WAAA;cAAuE;KAGtF,sBAAA;IAAe,WAAA;cACb,OAAOzD,WAAW,WAAlBA,SAAsC0D,KAAIC,UAAW3D,QAAQ,MAAM,EAAC;KAEvE,IACD;IAED;AAAAY,IAAA,MAAA0C;AAAA1C,IAAA,MAAA2C;AAAA3C,IAAA,MAAAZ;AAAAY,IAAA,MAAAsB;OAAAA,OAAAtB,EAAA;CAAA,IAAA0B;AAAA,KAAA1B,EAAA,QAAAsB,OAAAtB,EAAA,QAAAqB,IAAA;AApDFK,QAAA,qBAAA;GAAe,WAAA;cAEdL,IAwBCC;IA2BI;AAAAtB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAqB;AAAArB,IAAA,MAAA0B;OAAAA,OAAA1B,EAAA;AAAA,QArDN0B;;;;;AA4DF,MAAMsB,oBAGDjD,OAAA;CAAA,MAAAC,IAAAjC,EAAA,GAAA;CAAC,MAAA,EAAA+B,UAAAJ,UAAAK;CAAmB,IAAAE;AAAA,KAAAD,EAAA,OAAAF,UAAA;AACPG,OAAAjB,YAAYc,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAtC,MAAAE,WAAiBD;CAAqB,IAAAE;AAAA,KAAAH,EAAA,OAAAE,UAAA;AAMlCC,OAAA,oBAAC,YAAmB,WAAA,8BAA8B;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAClDb,OAAA,oBAAC,eAAsB,WAAA,0DAA0D;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,IAAA;AAFlFE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAJ,IAAA,KAAAG;AAAAH,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAF,UAAA;AAEJQ,OAAA5B,iBAAiBoB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,OAAAM,IAAA;AAD5BY,OAAA,qBAAA;GAAgB,WAAA;cACdZ,IAA2B;IACtB;AAAAN,IAAA,KAAAM;AAAAN,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAK,MAAAL,EAAA,QAAAkB,IAAA;AAPRC,OAAA,qBAAA;GAAe,WAAA;cACdd,IAIAa;IAGK;AAAAlB,IAAA,MAAAK;AAAAL,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAN,OAAA;AACL0B,OAAA1B,SACA,oBAAA;GAAe,WAAA;aACd,oBAAA;IAAe,WAAA;cAA2DA;KAC3E;IACA;AAAAM,IAAA,MAAAN;AAAAM,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,IAAA;AAdFC,OAAA,qBAAA;GAAe,WAAA;cACdF,IASCC;IAKI;AAAApB,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;AAAA,QAfNqB;;;;;AAsBF,MAAM4B,qBAEDlD,OAAA;CAAA,MAAAC,IAAAjC,EAAA,GAAA;CAAC,MAAA,EAAA+B,aAAAC;CAAY,IAAAE;AAAA,KAAAD,EAAA,OAAAF,UAAA;AACAG,OAAAjB,YAAYc,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;OAAAA,MAAAD,EAAA;CAAtC,MAAAE,WAAiBD;CAAqB,IAAAE;AAAA,KAAAH,EAAA,OAAAE,UAAA;AAKnCC,OAAA,oBAAC,YAAmB,WAAA,8BAA8B;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAClDb,OAAA,oBAAC,KAAY,WAAA,0DAA0D;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,IAAA;AAFxEE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAJ,IAAA,KAAAG;AAAAH,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAF,UAAA;AAE8BQ,OAAA5B,iBAAiBoB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,OAAAM,IAAA;AAD9DY,OAAA,qBAAA,qBACC,oBAAA;GAAkB,WAAA;aAAiBZ;IAAoC,eACjE;AAAAN,IAAA,KAAAM;AAAAN,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAK,MAAAL,EAAA,QAAAkB,IAAA;AAPRC,OAAA,qBAAA;GAAe,WAAA;cACdd,IAIAa;IAGK;AAAAlB,IAAA,MAAAK;AAAAL,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;AAAA,QARNmB;;;;;;;;;;AAwBF,MAAa+B,uBAAqD,EACjEC,YAAYC,aACZtD,UACA4C,UACAW,MACA7D,QACAJ,QACAkE,gBACK;CACL,MAAM,EAAEC,UAAUC,UAAU3E,aAAa;CACzC,MAAM,CAACgC,aAAa4C,kBAAkBjF,SAAS,MAAM;CACrD,MAAM,CAACkF,oBAAoBC,yBAAyBnF,SAAS,MAAM;CAGnE,MAAMoF,aACLP,eACO;AACN,MAAI;AACH,UAAOX,WAAWI,KAAKe,MAAMnB,SAAS,GAAG,EAAE;WACnCoB,GAAG;AACXC,WAAQC,KAAK,wDAAwDlE,SAAQ,KAAMgE,EAAE;AACrF,UAAO,EAAE;;KAEP;CAGL,MAAMtD,kBAAkBgD,MAAMS,MAAMC,MAAMA,EAAEC,SAASrE,SAAS,EAAEsE;CAGhE,MAAMC,gBAAgB/F,YAAY,YAAY;AAC7CmF,iBAAe,KAAK;AACpB,MAAI;AAEHH,aAAUvE,iBADS,MAAMwE,SAASzD,UAAU8D,WAAW,CACjB,CAAC;WAC/BlE,OAAO;AAEf4D,aAAU,UADW5D,iBAAiB8E,QAAQ9E,MAAM+E,UAAUC,OAAOhF,MAAM,GACxC;YAC1B;AACT+D,kBAAe,MAAM;;IAEpB;EAAC3D;EAAU8D;EAAYL;EAAUD;EAAU,CAAC;CAG/C,MAAMqB,aAAarG,kBAAkB;AACpCgF,YAAU3E,oBAAoB;IAC5B,CAAC2E,UAAU,CAAC;CAGf,MAAMsB,aAAapF,OAAOC;CAG1B,MAAMoF,oBAAoBD,eAAe,qBAAqBxF,WAAWyD;AAIzEtE,iBAAgB;AACf,MAAIsG,mBAAmB;GACtB,MAAMC,QAAQC,iBAAiB;AAC9BpB,0BAAsB,KAAK;MACzB,IAAI;AACP,gBAAaqB,aAAaF,MAAM;QAEhCnB,uBAAsB,MAAM;IAE3B,CAACkB,kBAAkB,CAAC;AAKvB,KAAIA,mBAAmB;AAEtB,MAAI,CAACnB,mBACJ,QAAO,oBAAC,sBAA6B5D,WAAY;AAElD,SACC,oBAAC;GACUA;GACOU;GACjB,WAAWoD;GACX,WAAWS;GACX,QAAQM;GACK9D;IACZ;;AAKJ,KAAIvB,eAAeF,OAAO,CACzB,QAAO,oBAAC,qBAA4BU,WAAY;AAIjD,KAAI8E,eAAe,UAClB,QAAO,oBAAC,sBAA6B9E,WAAY;AAIlD,KAAI8E,eAAe,gBAAgBrF,eAAeC,OAAO,CAExD,QAAO,oBAAC;EAA2BM;EAAU,OADxBP,eAAeC,OAAO,GAAGA,OAAOE,QAAQ;GACO;AAKrE,KAAIkF,eAAe,cAAexF,WAAWyD,UAAa,CAACvD,eAAeF,OAAQ,CAIjF,QAAO,oBAAC;EAA+BU;EAAoB4C;EAAU,QAF/CrD,iBAAiBD,OAAO,GAAGA,OAAOA,SAASA;GAE6B;AAI/F,QAAO,oBAAC,sBAA6BU,WAAY;;;;;;;;;;;;;;;;;;;;;;ACnZlD,MAAa0F,2BAAyB;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAEpCF,OAAA,oBAAA,gBAAA,YACa,YAAA;GAAAG,aAEEC;GAAUC,kBACLC;GACnB,GACC;AAAAP,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QANFC;;;;;;;AAeF,MAAMM,6BAA2B;CAAA,MAAAP,IAAAN,EAAA,EAAA;CAAA,IAAAO;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAE/BF,OAAA,oBAAA,iBAAA,kBACC,oBAAA,iBAAA,SACa,YAAA;GAAAO,MAELC;GAAUC,OAOT,EAAAC,UAAYd,qBAAoB;GACxC,GAEF,GAAwB;AAAAG,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QAdxBC;;AAnBoC,SAAAI,UAAA;AAAA,QAKf;;AAYU,SAAAI,WAAA;AAAA,QAMhB;;;;;;;;;;;;;;;;;;;;;ACVjB,MAAamB,oBAA8CC,OAAA;CAAA,MAAAC,IAAAjB,EAAA,GAAA;CAAC,MAAA,EAAAW,kBAAAO,IAAAN,WAAAC,cAAAM,IAAAL,gBAAAM,OAAAJ;CAC3D,MAAAL,mBAAAO,OAAAG,SAAA,QAAAH;CAEA,MAAAL,eAAAM,OAAAE,SAAA,QAAAF;CACA,MAAAL,iBAAAM,OAAAC,SAAA,QAAAD;CAGA,MAAAE,mBAAyBT,eAAA,QAAAF;CACzB,MAAA,CAAAY,aAAAC,kBAAsCnB,SAASiB,iBAAiB;CAChE,MAAAG,oBAA0BrB,OAAOkB,iBAAiB;CAClD,MAAAI,oBAA0BtB,OAAO,MAAM;CACvC,MAAAuB,UAAgBrB,YAAY;CAAA,IAAAsB;AAAA,KAAAX,EAAA,OAAAU,SAAA;AAGLC,OAAAD,QAAOE,OAAQC,QAA8B;AAAAb,IAAA,KAAAU;AAAAV,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAApE,MAAAc,iBAAuBH,GAA6CI;CAAO,IAAAC;AAAA,KAAAhB,EAAA,OAAAU,SAAA;AACtDM,OAAAN,QAAOE,OAAQK,SAA8B;AAAAjB,IAAA,KAAAU;AAAAV,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CAAlE,MAAAkB,eAAqBF,GAA6CD;CAAO,IAAAI;AAAA,KAAAnB,EAAA,OAAAU,SAAA;AACpDS,OAAAT,QAAOE,OAAQQ,SAA8B;AAAApB,IAAA,KAAAU;AAAAV,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CAAlE,MAAAqB,eAAqBF,GAA6CJ;CAClE,MAAAO,aAAmBZ,QAAOK;CAAO,IAAAQ;CAAA,IAAAC;AAAA,KAAAxB,EAAA,OAAAH,kBAAAG,EAAA,OAAAM,aAAA;AAGvBiB,aAAA;AACT,OAAI1B,gBAAc;AACjBY,sBAAiBgB,UAAW;AAC5BjB,sBAAiBiB,UAAWnB;AAC5BC,mBAAe,KAAK;AAAA;;AAKrB,OAAIE,kBAAiBgB,SAAQ;AAC5BlB,mBAAeC,kBAAiBiB,QAAS;AACzChB,sBAAiBgB,UAAW;;;AAE3BD,OAAA,CAAC3B,gBAAgBS,YAAY;AAAAN,IAAA,KAAAH;AAAAG,IAAA,KAAAM;AAAAN,IAAA,KAAAuB;AAAAvB,IAAA,KAAAwB;QAAA;AAAAD,OAAAvB,EAAA;AAAAwB,OAAAxB,EAAA;;AAbhCd,WAAUqC,IAaPC,GAA8B;CAAA,IAAAE;CAAA,IAAAC;AAAA,KAAA3B,EAAA,QAAAH,kBAAAG,EAAA,QAAAM,eAAAN,EAAA,QAAAqB,cAAA;AAGvBM,aAAA;AACT,OAAI9B,eAAc;AAClB,OAAIwB,eAAe,KAAff,YACHC,gBAAe,MAAM;;AAEpBmB,QAAA;GAACL;GAAcf;GAAaT;GAAe;AAAAG,IAAA,MAAAH;AAAAG,IAAA,MAAAM;AAAAN,IAAA,MAAAqB;AAAArB,IAAA,MAAA0B;AAAA1B,IAAA,MAAA2B;QAAA;AAAAD,QAAA1B,EAAA;AAAA2B,OAAA3B,EAAA;;AAL9Cd,WAAUyC,IAKPD,IAA4C;AAG/C,KAAIhB,QAAOK,WAAY,EAAC,QAChB;CACP,IAAAa;AAAA,KAAA5B,EAAA,QAAAL,WAAA;AAGgBiC,QAAAtC,GAAG,UAAUK,UAAU;AAAAK,IAAA,MAAAL;AAAAK,IAAA,MAAA4B;OAAAA,OAAA5B,EAAA;CAAA,IAAA6B;AAAA,KAAA7B,EAAA,QAAAH,kBAAAG,EAAA,QAAAM,aAAA;AAI5BuB,cAAA;AACR,OAAIhC,eAAc;GAClB,MAAAiC,OAAa,CAACxB;AACdE,qBAAiBiB,UAAWK;AAC5BvB,kBAAeuB,KAAK;;AACpB9B,IAAA,MAAAH;AAAAG,IAAA,MAAAM;AAAAN,IAAA,MAAA6B;OAAAA,OAAA7B,EAAA;CAAA,IAAA+B;AAAA,KAAA/B,EAAA,QAAAgC,OAAAC,IAAA,4BAAA,EAAA;AACUF,QAAAzC,GACV,4CACA,aACA,kCACA,2BACA;AAAAU,IAAA,MAAA+B;OAAAA,OAAA/B,EAAA;CACc,MAAAkC,MAAA,CAAC5B;CAAW,IAAA6B;AAAA,KAAAnC,EAAA,QAAAgC,OAAAC,IAAA,4BAAA,EAAA;AAK1BE,QAAA,oBAAA;GAAgB,WAAA;aAAoC;IAAY;AAAAnC,IAAA,MAAAmC;OAAAA,OAAAnC,EAAA;CAAA,IAAAoC;AAAA,KAAApC,EAAA,QAAAc,kBAAAd,EAAA,QAAAsB,YAAA;AAChEc,QAAA,qBAAA;GAAgB,WAAA;;IACdtB;IAAe;IAAEQ;;IACZ;AAAAtB,IAAA,MAAAc;AAAAd,IAAA,MAAAsB;AAAAtB,IAAA,MAAAoC;OAAAA,OAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,QAAAqB,cAAA;AAENgB,QAAAhB,eAAe,KACf,qBAAA;GAAgB,WAAA;cACf,oBAAC,iBAAwB,WAAA,YACxBA,EAAAA;IAEF;AAAArB,IAAA,MAAAqB;AAAArB,IAAA,MAAAqC;OAAAA,OAAArC,EAAA;CAAA,IAAAsC;AAAA,KAAAtC,EAAA,QAAAkB,cAAA;AAEAoB,QAAApB,eAAe,KACf,qBAAA;GAAgB,WAAA;cACf,oBAAA,UAAgB,WAAA,uDACfA,EAAAA;IAEF;AAAAlB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAsC;OAAAA,OAAAtC,EAAA;CAAA,IAAAuC;AAAA,KAAAvC,EAAA,QAAAoC,OAAApC,EAAA,QAAAqC,OAAArC,EAAA,QAAAsC,KAAA;AAlBFC,QAAA,qBAAA;GAAe,WAAA;;IACdJ;IACAC;IAICC;IAOAC;;IAMI;AAAAtC,IAAA,MAAAoC;AAAApC,IAAA,MAAAqC;AAAArC,IAAA,MAAAsC;AAAAtC,IAAA,MAAAuC;OAAAA,OAAAvC,EAAA;CAIJ,MAAAwC,MAAA,CAAClC,eAAD;CAA4B,IAAAmC;AAAA,KAAAzC,EAAA,QAAAwC,KAAA;AAFlBC,QAAAnD,GACV,+DACAkD,IACA;AAAAxC,IAAA,MAAAwC;AAAAxC,IAAA,MAAAyC;OAAAA,OAAAzC,EAAA;CAAA,IAAA0C;AAAA,KAAA1C,EAAA,QAAAyC,KAAA;AAJFC,QAAA,oBAAC,eACW,WAAAD,MAIV;AAAAzC,IAAA,MAAAyC;AAAAzC,IAAA,MAAA0C;OAAAA,OAAA1C,EAAA;CAAA,IAAA2C;AAAA,KAAA3C,EAAA,QAAAH,kBAAAG,EAAA,QAAA6B,OAAA7B,EAAA,QAAAkC,OAAAlC,EAAA,QAAAuC,OAAAvC,EAAA,QAAA0C,KAAA;AA3CHC,QAAA,qBAAA;GACM,MAAA;GACI,SAAAd;GAME,WAAAE;GAMI,iBAAAG;GACArC,iBAAAA;GACLA,UAAAA;cAEV0C,KAoBAG;IAMQ;AAAA1C,IAAA,MAAAH;AAAAG,IAAA,MAAA6B;AAAA7B,IAAA,MAAAkC;AAAAlC,IAAA,MAAAuC;AAAAvC,IAAA,MAAA0C;AAAA1C,IAAA,MAAA2C;OAAAA,OAAA3C,EAAA;CAAA,IAAA4C;AAAA,KAAA5C,EAAA,QAAAH,kBAAAG,EAAA,QAAAM,eAAAN,EAAA,QAAAJ,cAAA;AAGRgD,QAAA,CAAC/C,kBACD,oBAAA;GACY,WAAAP,GACV,8DACAgB,cAAA,oBAAA,kBACD;GACaA,eAAAA;aAEb,oBAAA;IAAe,WAAA;cAEd,oBAAA;KACY,WAAAhB,GACV,oDACAM,eAAA,iBAAA,uBACD;KACO,OAAA,EAAAiD,aAAe,SAAQ;KACR,sBAAAC;eAEtB,oBAAC,uBACF;MACD;KACD;IACA;AAAA9C,IAAA,MAAAH;AAAAG,IAAA,MAAAM;AAAAN,IAAA,MAAAJ;AAAAI,IAAA,MAAA4C;OAAAA,OAAA5C,EAAA;CAAA,IAAA+C;AAAA,KAAA/C,EAAA,QAAA4B,OAAA5B,EAAA,QAAA2C,OAAA3C,EAAA,QAAA4C,KAAA;AAvEFG,QAAA,qBAAA;GAAgB,WAAAnB;cAEfe,KA+CCC;IAuBI;AAAA5C,IAAA,MAAA4B;AAAA5B,IAAA,MAAA2C;AAAA3C,IAAA,MAAA4C;AAAA5C,IAAA,MAAA+C;OAAAA,OAAA/C,EAAA;AAAA,QAxEN+C;;AAjDyD,SAAAlC,QAAAmC,GAAA;AAAA,QAcbA,EAACC,WAAY;;AAdA,SAAAhC,SAAAiC,KAAA;AAAA,QAefF,IAACC,WAAY;;AAfE,SAAA7B,SAAA+B,KAAA;AAAA,QAgBfH,IAACC,WAAY;;AAhBE,SAAAH,SAAAM,GAAA;AAAA,QAkHvBA,EAACC,iBAAkB;;;;;ACjIvD,MAAaoB,gBAAeC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAX;CAAA,IAAAY;CAAA,IAAAL;CAAA,IAAAM;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAb,EAAA,OAAAD,IAAA;AAAC,GAAA,CAAAd,QAAAmB,IAAAlB,YAAAoB,IAAAnB,UAAAoB,IAAAnB,QAAAoB,IAAAnB,WAAAoB,IAAAnB,UAAAC,WAAAmB,IAAAlB,WAAAmB,IAAAlB,QAAAmB,IAAAlB,aAAAmB,IAAAjB,MAAAS,KAAAR,kBAAAK,cAAAC,SAAAJ;AAeTC,IAAA,KAAAD;AAAAC,IAAA,KAAAV;AAAAU,IAAA,KAAAE;AAAAF,IAAA,KAAAH;AAAAG,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;AAAAL,IAAA,KAAAM;AAAAN,IAAA,KAAAO;AAAAP,IAAA,KAAAQ;AAAAR,IAAA,MAAAS;AAAAT,IAAA,MAAAU;AAAAV,IAAA,MAAAW;AAAAX,IAAA,MAAAY;AAAAZ,IAAA,MAAAa;QAAA;AAAAvB,aAAAU,EAAA;AAAAE,cAAAF,EAAA;AAAAH,qBAAAG,EAAA;AAAAG,UAAAH,EAAA;AAAAI,OAAAJ,EAAA;AAAAK,QAAAL,EAAA;AAAAM,OAAAN,EAAA;AAAAO,OAAAP,EAAA;AAAAQ,OAAAR,EAAA;AAAAS,OAAAT,EAAA;AAAAU,OAAAV,EAAA;AAAAW,OAAAX,EAAA;AAAAY,OAAAZ,EAAA;AAAAa,OAAAb,EAAA;;CAdnB,MAAAf,SAAAmB,OAAAU,SAAA,QAAAV;CACA,MAAAlB,aAAAoB,OAAAQ,SAAA,QAAAR;CACA,MAAAnB,WAAAoB,OAAAO,SAAA,IAAAP;CACA,MAAAnB,SAAAoB,OAAAM,SAAA,IAAAN;CACA,MAAAnB,YAAAoB,OAAAK,SAAA,MAAAL;CAEA,MAAAlB,YAAAmB,OAAAI,SAAA,OAAAJ;CACA,MAAAlB,YAAAmB,OAAAG,SAAA,KAAAH;CACA,MAAAlB,SAAAmB,OAAAE,SAAA,KAAAF;CACA,MAAAlB,cAAAmB,OAAAC,SAAA,IAAAD;CACA,MAAAjB,OAAAS,QAAAS,SAAA,WAAAT;CAKA,MAAAU,YAAkBnC,OAA0B,KAAK;CACjD,MAAAoC,eAAqBpC,OAAuB,KAAK;CAAA,IAAAqC;AAAA,KAAAjB,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AACbF,QAAA,EAAE;AAAAjB,IAAA,MAAAiB;OAAAA,OAAAjB,EAAA;CAAtC,MAAAoB,aAAmBxC,OAAiBqC,IAAG;AACjBrC,QAAe,EAAE;CACvC,MAAAyC,gBAAsBzC,OAAe,EAAE;CACvC,MAAA0C,yBAA+B1C,OAAsB,KAAK;CAAA,IAAA2C;AAAA,KAAAvB,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AACfI,QAAA,EAAE;AAAAvB,IAAA,MAAAuB;OAAAA,OAAAvB,EAAA;CAA7C,MAAAwB,oBAA0B5C,OAAiB2C,IAAG;CAC9C,MAAAE,wBAA8B7C,OAAO,EAAE;CAAA,IAAA8C;AAAA,KAAA1B,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AACAO,QAAA,EAAE;AAAA1B,IAAA,MAAA0B;OAAAA,OAAA1B,EAAA;CAAzC,MAAA2B,gBAAsB/C,OAAiB8C,IAAG;CAC1C,MAAAE,iBAAuBhD,OAAO,KAAK;CACnC,MAAAiD,mBAAyBjD,OAA8B,KAAK;CAC5D,MAAAkD,eAAqBlD,OAAO,EAAE;CAE9B,MAAAmD,cAAoB,OAAOtC,WAAW,WAAlB,GAAgCA,OAAM,MAAtCA;CAAmD,IAAAuC;CAAA,IAAAC;AAAA,KAAAjC,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAK7Da,cAAA;GACT,MAAAE,SAAenB,UAASoB;GACxB,MAAAC,YAAkBpB,aAAYmB;AAC9B,OAAI,CAACD,UAAD,CAAYE,UAAS;GAEzB,MAAAC,iBAAuB,IAAIC,qBAAe;IACzC,MAAAC,OAAaH,UAASI,uBAAwB;IAC9C,MAAAC,MAAYC,OAAMC,oBAAN;AAEZT,WAAMU,QAASL,KAAIK,QAASH;AAC5BP,WAAMzC,SAAU8C,KAAI9C,SAAUgD;AAC9BP,WAAMW,MAAMD,QAAS,GAAGL,KAAIK,MAAM;AAClCV,WAAMW,MAAMpD,SAAU,GAAG8C,KAAI9C,OAAO;IAEpC,MAAAqD,MAAYZ,OAAMa,WAAY,KAAK;AACnC,QAAID,IACHA,KAAGE,MAAOP,KAAKA,IAAI;AAGpBZ,qBAAgBM,UAAW;AAC3BL,iBAAYK,UAAWI,KAAIK;AAC3BhB,mBAAcO,UAAW;KACxB;AAEFE,kBAAcY,QAASb,UAAU;AAAA,gBACpBC,eAAca,YAAa;;AACtCjB,QAAA,EAAE;AAAAjC,IAAA,MAAAgC;AAAAhC,IAAA,MAAAiC;QAAA;AAAAD,QAAAhC,EAAA;AAAAiC,QAAAjC,EAAA;;AA1BLrB,WAAUqD,KA0BPC,IAAG;CAAA,IAAAkB;CAAA,IAAAC;AAAA,KAAApD,EAAA,QAAAf,UAAAe,EAAA,QAAAZ,UAAAY,EAAA,QAAAb,YAAAa,EAAA,QAAAJ,QAAAI,EAAA,QAAAd,YAAA;AAGIiE,cAAA;AACT,OAAIjE,cAAA,CAAeD,QAAM;IACxB,IAAAoE,OAAW;AACX5B,0BAAqBU,UAAW;IAEhC,MAAAmB,0BAA0B;AACzBD,YAAAA,OAAQ;AACR5B,2BAAqBU,UAAWoB,KAAIC,IAAK,GAAG/B,sBAAqBU,UAAW,IAA/C;KAE7B,MAAAsB,iBAAiC,EAAE;KACnC,MAAAC,WAAiBH,KAAII,OACnB3C,aAAYmB,SAA+BK,uBAAQ,CAAAI,SAAnD,QAA+DzD,WAAWC,QAC3E;AAED,SAAIQ,SAAS,UAAQ;MACpB,MAAAgE,YAAkBL,KAAII,MAAOD,WAAW,EAAE;AAE1C,WAAA,IAAAG,IAAa,GAAGA,IAAIH,UAAUG,KAAG;OAChC,MAAAC,sBAA4BD,IAAID,aAAaA;OAC7C,MAAAG,eAAqB,IAAIR,KAAIS,IAAKF,mBAAmB,GAAG;OAExD,MAAAG,QAAcV,KAAIW,IAAKb,OAAO,MAAMS,qBAAqB,EAAE,GAAG;OAC9D,MAAAK,QAAcZ,KAAIW,IAAKb,OAAO,KAAMS,qBAAqB,EAAE,GAAG;OAC9D,MAAAM,QAAcb,KAAIc,IAAKhB,OAAO,IAAIS,mBAAmB,GAAG;OAExD,MAAAS,mBAAyB,MADJN,QAAQE,QAAQC,UACUL;OAE/C,IAAAS,aAAiBD;AACjB,WAAI/C,kBAAiBW,QAAQsC,SAAU,KAAKhD,sBAAqBU,UAAW,GAAC;QAC5E,MAAAuC,gBAAsBnB,KAAIC,IAAKK,GAAGrC,kBAAiBW,QAAQsC,SAAU,EAAE;AAEvED,sBADkBhD,kBAAiBW,QAASuC,kBAA1B,MAEJ,IAAIjD,sBAAqBU,WACtCoC,kBAAkB9C,sBAAqBU;;AAGzCsB,sBAAcmB,KAAMrB,KAAIsB,IAAK,KAAMtB,KAAIC,IAAK,GAAGgB,WAAW,CAAC,CAAC;;WAG7D,MAAA,IAAAM,MAAa,GAAGjB,MAAIH,UAAUG,OAAG;MAChC,MAAAkB,wBAA4BlB,MAAIH,WAAW,MAAMA,WAAW;MAC5D,MAAAsB,iBAAqB,IAAIzB,KAAIS,IAAKF,qBAAmB,GAAG;MAExD,MAAAmB,UAAc1B,KAAIW,IAAKb,OAAO,MAAMQ,MAAI,IAAK,GAAG;MAChD,MAAAqB,UAAc3B,KAAIW,IAAKb,OAAO,KAAMQ,MAAI,GAAI,GAAG;MAC/C,MAAAsB,UAAc5B,KAAIc,IAAKhB,OAAO,IAAIQ,MAAI,IAAK,GAAG;MAE9C,MAAAwB,qBAAyB,MADJpB,UAAQE,UAAQC,YACUL;MAE/C,IAAAuB,eAAiBf;AACjB,UAAI/C,kBAAiBW,QAAQsC,SAAU,KAAKhD,sBAAqBU,UAAW,GAAC;OAC5E,MAAAoD,kBAAsBhC,KAAII,MAAQE,MAAIH,WAAYlC,kBAAiBW,QAAQsC,OAAQ;AAEnFD,uBADkBhD,kBAAiBW,QAASuC,oBAA1B,MAEJ,IAAIjD,sBAAqBU,WACtCoC,oBAAkB9C,sBAAqBU;;AAGzCsB,qBAAcmB,KAAMrB,KAAIsB,IAAK,KAAMtB,KAAIC,IAAK,GAAGgB,aAAW,CAAC,CAAC;;AAI9D,SAAI5E,SAAS,SACZ+B,eAAaQ,UAAWsB;SAExBrC,YAAUe,UAAWsB;AAGtB7B,oBAAcO,UAAW;AACzBb,4BAAsBa,UAAWsD,sBAAsBnC,kBAAzB;;AAG/BA,uBAAmB;AAAA,iBAEZ;AACN,SAAIhC,uBAAsBa,QACzBuD,sBAAqBpE,uBAAsBa,QAAS;;;AAKvD,OAAI,CAAClD,UAAD,CAAYC,YAIf;QAFCU,SAAS,WAAW+B,cAAaQ,QAAQsC,SAAU,IAAIrD,WAAUe,QAAQsC,SAAU,GAEzE;KACV,IAAAmB,eAAmB;KACnB,MAAAC,mBAAmB;AAClBD,qBAAAA,eAAgB;AAChB,UAAIA,eAAe,GAAC;AACnB,WAAIhG,SAAS,SACZ+B,eAAaQ,UAAWR,cAAaQ,QAAQ2D,KAC5CC,UAAWA,SAAS,IAAIH,cADJ;WAIrBxE,YAAUe,UAAWf,WAAUe,QAAQ2D,KAAKE,YAAWD,WAAS,IAAIH,cAAlD;AAEnBhE,sBAAcO,UAAW;AACzBsD,6BAAsBI,WAAW;iBAE7BjG,SAAS,SACZ+B,eAAaQ,UAAW,EAAH;UAErBf,YAAUe,UAAW,EAAH;;AAIrB0D,iBAAY;;;;AAGZzC,QAAA;GAAClE;GAAYD;GAAQE;GAAUC;GAAQQ;GAAK;AAAAI,IAAA,MAAAf;AAAAe,IAAA,MAAAZ;AAAAY,IAAA,MAAAb;AAAAa,IAAA,MAAAJ;AAAAI,IAAA,MAAAd;AAAAc,IAAA,MAAAmD;AAAAnD,IAAA,MAAAoD;QAAA;AAAAD,QAAAnD,EAAA;AAAAoD,QAAApD,EAAA;;AA9G/CrB,WAAUwE,KA8GPC,IAA6C;CAAA,IAAA6C;CAAA,IAAAC;AAAA,KAAAlG,EAAA,QAAAf,UAAAe,EAAA,QAAAV,YAAAU,EAAA,QAAAZ,UAAAY,EAAA,QAAAX,aAAAW,EAAA,QAAAb,YAAAa,EAAA,QAAAT,aAAAS,EAAA,QAAAR,aAAAQ,EAAA,QAAAH,oBAAAG,EAAA,QAAAJ,QAAAI,EAAA,QAAAd,cAAAc,EAAA,QAAAN,aAAA;AAGtCuG,cAAA;GACT,MAAAE,WAAepF,UAASoB;AACxB,OAAI,CAACD,SAAM;GAEX,MAAAkE,QAAYlE,SAAMa,WAAY,KAAK;AACnC,OAAI,CAACD,MAAG;GAEJuD,IAAAA;GAEJ,MAAAC,WAAgBC,gBAAA;IACf,MAAAC,SAAatE,SAAMM,uBAAwB;AAG3C,QAAIvD,UAAUsH,cAAclF,cAAac,UA9JxB,IA8J6C;AAC7Dd,mBAAac,UAAWoE;AAGxB,SAAI1G,qBAAqBiB,QAAS;MACjC,MAAA2F,QAAclD,KAAIsB,IAAK,KAAMtB,KAAIC,IAAK,GAAG3D,mBAAmBH,YAAY,CAAC;AAEzE,UAAIE,SAAS,UAAQ;OACpB,MAAA8G,aAAiBnD,KAAII,MAAOpB,OAAIK,SAAUzD,WAAWC,QAAQ;OAC7D,MAAAuH,cAAkBpD,KAAII,MAAOD,aAAW,EAAE;OAC1C,MAAAkD,UAA0B,EAAE;AAG5B,YAAA,IAAAC,MAAajD,cAAY,GAAGC,OAAK,GAAGA,OAAG;QAEtC,MAAAkD,UAAcN,SAAS,IADIlD,KAAIS,IAAKH,MAAID,cAAY,EAAE,IAAIA,cAAY,KACtB;AAChDgD,gBAAOhC,KAAMrB,KAAIsB,IAAK,KAAMkB,QAAM,CAAC;;AAGpC,YAAA,IAAAiB,MAAa,GAAGnD,MAAID,aAAWC,OAAG;QAEjC,MAAAqD,UAAcT,SAAS,IADIlD,KAAIS,IAAKH,MAAID,cAAY,EAAE,IAAIA,cAAY,KACtB;AAChDgD,gBAAOhC,KAAMrB,KAAIsB,IAAK,KAAMkB,QAAM,CAAC;;AAGpCpE,qBAAaQ,UAAWyE;AACxBpF,yBAAiBW,UAAWyE;aAAH;AAEzBxF,kBAAUe,QAAQyC,KAAM6B,MAAM;AAC9BjF,yBAAiBW,UAAW,CAAA,GAAIf,WAAUe,QAAjB;AAEzB,WAAIf,WAAUe,QAAQsC,SA9LP,GA+LdrD,YAAUe,QAAQgF,OAAQ;;AAG5BvF,qBAAcO,UAAW;;;AAK3B,QAAI,CAACP,eAAcO,WAAf,CAA4BlD,QAAM;AACrCoH,aAAQZ,sBAAsBa,QAAQ;AAAjC;;AAIN1E,mBAAcO,UAAWlD;AACzB6D,UAAGsE,UAAW,GAAG,GAAG7E,OAAIK,OAAQL,OAAI9C,OAAQ;IAE5C,MAAA4H,mBACC/H,mBACC;AAEyB,YADXgI,iBAAiBpF,SAAO,CACnBqF,SACZ;QACJ;IAEL,MAAAC,OAAarI,WAAWC;IACxB,MAAAqI,aAAiBlE,KAAII,MAAOpB,OAAIK,QAAS4E,KAAK;IAC9C,MAAAE,UAAgBnF,OAAI9C,SAAU;AAG9B,QAAIG,SAAS,UAAQ;KACpB,MAAA+H,eAAqBzI,aAClByC,cAAaQ,UACblD,SACC0C,cAAaQ,UACbR,cAAaQ,QAAQsC,SAAU,IAC9B9C,cAAaQ,UADd,EAEG;AAEP,UAAA,IAAAyF,MAAa,GAAG/D,MAAIH,cAAYG,MAAI8D,aAAYlD,QAASZ,OAAG;MAC3D,MAAAgE,UAAcF,aAAa9D,QAAb;MACd,MAAAiE,IAAUjE,MAAI2D;MACd,MAAAO,YAAkBxE,KAAIsB,IAAK,GAAGkB,UAAQxD,OAAI9C,SAAU,GAAI;MACxD,MAAAuI,IAAUN,UAAUK,YAAY;AAEhCjF,YAAGmF,YAAaZ;AAChBvE,YAAGoF,cAAe,KAAMnC,UAAQ;AAEhC,UAAI1G,YAAY,GAAC;AAChByD,aAAGqF,WAAY;AACfrF,aAAGsF,UAAWN,GAAGE,GAAG7I,UAAU4I,WAAW1I,UAAU;AACnDyD,aAAGuF,MAAO;YAEVvF,OAAGwF,SAAUR,GAAGE,GAAG7I,UAAU4I,UAAU;;UAKzC,MAAA,IAAAQ,MAAa,GAAG1E,MAAIH,cAAYG,MAAIzC,WAAUe,QAAQsC,QAASZ,OAAG;KACjE,MAAA2E,YAAkBpH,WAAUe,QAAQsC,SAAU,IAAIZ;KAClD,MAAA4E,UAAcrH,WAAUe,QAASqG,cAAnB;KACd,MAAAE,MAAUnG,OAAIK,SAAUiB,MAAI,KAAK2D;KACjC,MAAAmB,cAAkBpF,KAAIsB,IAAK,GAAGkB,UAAQxD,OAAI9C,SAAU,GAAI;KACxD,MAAAmJ,MAAUlB,UAAUK,cAAY;AAEhCjF,WAAGmF,YAAaZ;AAChBvE,WAAGoF,cAAe,KAAMnC,UAAQ;AAEhC,SAAI1G,YAAY,GAAC;AAChByD,YAAGqF,WAAY;AACfrF,YAAGsF,UAAWN,KAAGE,KAAG7I,UAAU4I,aAAW1I,UAAU;AACnDyD,YAAGuF,MAAO;WAEVvF,OAAGwF,SAAUR,KAAGE,KAAG7I,UAAU4I,YAAU;;AAM1C,QAAIxI,aAAaC,YAAY,KAAK+C,OAAIK,QAAS,GAAC;AAC/C,SAAI,CAACf,iBAAgBM,WAAYL,aAAYK,YAAaI,OAAIK,OAAM;MACnE,MAAAiG,WAAiB/F,MAAGgG,qBAAsB,GAAG,GAAGvG,OAAIK,OAAQ,EAAE;MAC9D,MAAAmG,cAAoBxF,KAAIC,IAAK,IAAKhE,YAAY+C,OAAIK,MAAO;AAEzDiG,eAAQG,aAAc,GAAG,sBAAsB;AAC/CH,eAAQG,aAAcD,aAAa,sBAAsB;AACzDF,eAAQG,aAAc,IAAID,aAAa,sBAAsB;AAC7DF,eAAQG,aAAc,GAAG,sBAAsB;AAE/CnH,uBAAgBM,UAAW0G;AAC3B/G,mBAAYK,UAAWI,OAAIK;;AAG5BE,WAAGmG,2BAA4B;AAC/BnG,WAAGmF,YAAapG,iBAAgBM;AAChCW,WAAGwF,SAAU,GAAG,GAAG/F,OAAIK,OAAQL,OAAI9C,OAAQ;AAC3CqD,WAAGmG,2BAA4B;;AAGhCnG,UAAGoF,cAAe;AAElB7B,YAAQZ,sBAAsBa,QAAQ;;AAGvCD,WAAQZ,sBAAsBa,QAAQ;AAAjC,gBAEE;AACN,QAAID,MACHX,sBAAqBW,MAAM;;;AAG3BH,QAAA;GACFjH;GACAC;GACAQ;GACAP;GACAC;GACAC;GACAC;GACAC;GACAC;GACAI;GACAC;GAxTmB;GACD;GA0TlB;AAAAG,IAAA,MAAAf;AAAAe,IAAA,MAAAV;AAAAU,IAAA,MAAAZ;AAAAY,IAAA,MAAAX;AAAAW,IAAA,MAAAb;AAAAa,IAAA,MAAAT;AAAAS,IAAA,MAAAR;AAAAQ,IAAA,MAAAH;AAAAG,IAAA,MAAAJ;AAAAI,IAAA,MAAAd;AAAAc,IAAA,MAAAN;AAAAM,IAAA,MAAAiG;AAAAjG,IAAA,MAAAkG;QAAA;AAAAD,QAAAjG,EAAA;AAAAkG,QAAAlG,EAAA;;AAzKDrB,WAAUsH,KA2JPC,IAcD;CAAA,IAAAgD;AAAA,KAAAlJ,EAAA,QAAAE,WAAA;AAIWgJ,QAAArK,GAAG,0BAA0BqB,UAAU;AAAAF,IAAA,MAAAE;AAAAF,IAAA,MAAAkJ;OAAAA,OAAAlJ,EAAA;CAAA,IAAAmJ;AAAA,KAAAnJ,EAAA,QAAA+B,aAAA;AAE3CoH,QAAA,EAAA1J,QAAUsC,aAAa;AAAA/B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAmJ;OAAAA,OAAAnJ,EAAA;CAE7B,MAAAoJ,MAAAnK,SAAA,wBAAiCC,aAAA,qBAAA;CAAuD,IAAAmK;AAAA,KAAArJ,EAAA,QAAAf,UAAAe,EAAA,QAAAd,YAAA;AAKxFmK,QAAA,CAACpK,UAAD,CAAYC,cACZ,oBAAA,SAAe,WAAA,yGACf;AAAAc,IAAA,MAAAf;AAAAe,IAAA,MAAAd;AAAAc,IAAA,MAAAqJ;OAAAA,OAAArJ,EAAA;CAAA,IAAAsJ;AAAA,KAAAtJ,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AACDmI,QAAA,oBAAA;GAAkB,WAAA;GAA2BvI,KAAAA;IAAa;AAAAf,IAAA,MAAAsJ;OAAAA,OAAAtJ,EAAA;CAAA,IAAAuJ;AAAA,KAAAvJ,EAAA,QAAAG,SAAAH,EAAA,QAAAkJ,OAAAlJ,EAAA,QAAAmJ,OAAAnJ,EAAA,QAAAoJ,OAAApJ,EAAA,QAAAqJ,KAAA;AAb3DE,QAAA,qBAAA;GACY,WAAAL;GACNlI,KAAAA;GACE,OAAAmI;GAEN,cAAAC;GAEI,MAAA;GAAK,GACNjJ;cAEHkJ,KAGDC;IACK;AAAAtJ,IAAA,MAAAG;AAAAH,IAAA,MAAAkJ;AAAAlJ,IAAA,MAAAmJ;AAAAnJ,IAAA,MAAAoJ;AAAApJ,IAAA,MAAAqJ;AAAArJ,IAAA,MAAAuJ;OAAAA,OAAAvJ,EAAA;AAAA,QAdNuJ;;;;;;;;;;;;;;;;;;ACvVF,MAAMc,sBAAsB;CAC3BC,QAAQ;EACPC,SAAS;EACTC,QAAQ;EACRC,GAAG;EACH;CACDC,SAAS;EACRH,SAAS;EACTC,QAAQ;EACRC,GAAG;EACHE,YAAY;GACXC,MAAM;GACNE,WAAW;GACXC,SAAS;GACV;EACA;CACDC,MAAM;EACLT,SAAS;EACTC,QAAQ;EACRC,GAAG;EACHE,YAAY,EACXM,UAAU,KACX;EACD;CACA;;;;;;;AAaD,MAAaG,wBAAsDC,OAAA;CAAA,MAAAC,IAAA7B,EAAA,GAAA;CAAC,MAAA,EAAA0B,cAAAE;CACnE,MAAAE,cAAoBtB,wBAAwB;CAC5C,MAAAuB,gBAAsBtB,8BAA8B;CACpD,MAAAuB,WAAiBzB,qBAAqB;CACtC,MAAA,CAAA0B,aAAAC,kBAAsC7B,SAAS,MAAM;CAAA,IAAA8B;AAAA,KAAAN,EAAA,OAAAE,eAAAK,mBAAAP,EAAA,OAAAC,aAAA;AAG3CK,aAAA;AACT,OAAIJ,eAAaK,mBAAbN,aAA6C;AAEhDA,gBAAWO,YAAa;AAAA,iBAGjB;AACNP,iBAAWQ,aAAc;;;;AAG3BT,IAAA,KAAAE,eAAAK;AAAAP,IAAA,KAAAC;AAAAD,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAG,MAAAU,KAAAR,eAAaK;CAAiB,IAAAI;AAAA,KAAAX,EAAA,OAAAU,MAAAV,EAAA,OAAAC,aAAA;AAA/BU,OAAA,CAACD,IAAgCT,YAAY;AAAAD,IAAA,KAAAU;AAAAV,IAAA,KAAAC;AAAAD,IAAA,KAAAW;OAAAA,MAAAX,EAAA;AAVhDzB,WAAU+B,IAUPK,GAA8C;AAGjD,KAAI,CAACT,eAAaK,gBAAiB,QAC3B;CAGR,MAAA,EAAAA,iBAAAK,kBAAAC,SAAAC,SAA6DZ;CAAa,IAAAa;AAAA,KAAAf,EAAA,OAAAG,UAAAa,SAAAhB,EAAA,OAAAO,gBAAAU,UAAA;AAClDF,OAAAZ,UAAQa,MAAYE,MAC3CC,MAAOA,EAACC,SAAUb,gBAAeU,SACpB,EAAAI;AAAArB,IAAA,KAAAG,UAAAa;AAAAhB,IAAA,KAAAO,gBAAAU;AAAAjB,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAFd,MAAAsB,kBAAwBP;CAIxB,MAAAa,gBADgBJ,OAAMC,KAAMlB,gBAAemB,QAAf,EAA0B,CAAC,CAAAC,SAAU,IACjCpB,gBAAemB,OAAzBG;CAA0C,IAAAC;AAAA,KAAA9B,EAAA,OAAAa,SAAA;AAG1CiB,aAAA;AACrBzB,kBAAe,KAAK;AACpBQ,YAAS;;AACTb,IAAA,KAAAa;AAAAb,IAAA,MAAA8B;OAAAA,MAAA9B,EAAA;CAHD,MAAA+B,gBAAsBD;CAGrB,IAAAE;AAAA,KAAAhC,EAAA,QAAAc,MAAA;AAGkBkB,aAAA;AAClBlB,SAAM;;AACNd,IAAA,MAAAc;AAAAd,IAAA,MAAAgC;OAAAA,MAAAhC,EAAA;CAFD,MAAAiC,aAAmBD;CAElB,IAAAE;AAAA,KAAAlC,EAAA,QAAAH,WAAA;AAKaqC,OAAAzD,GAAG,mBAAmBoB,UAAU;AAAAG,IAAA,MAAAH;AAAAG,IAAA,MAAAkC;OAAAA,MAAAlC,EAAA;CAAA,IAAAmC;AAAA,KAAAnC,EAAA,QAAAoC,OAAAC,IAAA,4BAAA,EAAA;AAezCF,OAAA,qBAAA;GAAe,WAAA;cACd,oBAAC,SAAgB,WAAA,YACjB,sBAAA,oBAAM,0CACP;IAAM;AAAAnC,IAAA,MAAAmC;OAAAA,MAAAnC,EAAA;CAAA,IAAAsC;AAAA,KAAAtC,EAAA,QAAA4B,iBAAA5B,EAAA,QAAA+B,iBAAA/B,EAAA,QAAAiC,cAAAjC,EAAA,QAAAI,eAAAJ,EAAA,QAAAO,gBAAAU,YAAAjB,EAAA,QAAAY,oBAAAZ,EAAA,QAAAsB,iBAAA;AAZRgB,OAAA,oBAAC;GACU,UAAA/B,gBAAeU;GACZK,aAAAA;GACPM,MAAAA;GACYhB;GACLR;GACF2B,WAAAA;GACHE,QAAAA;GAEP,aAAAE;IAKA;AAAAnC,IAAA,MAAA4B;AAAA5B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAiC;AAAAjC,IAAA,MAAAI;AAAAJ,IAAA,MAAAO,gBAAAU;AAAAjB,IAAA,MAAAY;AAAAZ,IAAA,MAAAsB;AAAAtB,IAAA,MAAAsC;OAAAA,MAAAtC,EAAA;CAAA,IAAAuC;AAAA,KAAAvC,EAAA,QAAAkC,MAAAlC,EAAA,QAAAsC,IAAA;AAtBJC,QAAA,oBAAC,6BACA,oBAAA,OAAA;GACY,WAAAL;GACDnD,UAAAA;GACF,SAAA;GACA,SAAA;GACH,MAAA;aAELuD;IAgBF,GAAkB;AAAAtC,IAAA,MAAAkC;AAAAlC,IAAA,MAAAsC;AAAAtC,IAAA,MAAAuC;OAAAA,OAAAvC,EAAA;AAAA,QAxBlBuC;;;;;ACjFF,MAAMsB,gBAAgB;CACrBC,QAAQ;EACPC,SAAS;EACTC,OAAO;EACPC,GAAG;EACH;CACDC,SAAS;EACRH,SAAS;EACTC,OAAO;EACPC,GAAG;EACHE,YAAY;GACXC,MAAM;GACNE,WAAW;GACXC,SAAS;GACV;EACA;CACDC,MAAM;EACLT,SAAS;EACTC,OAAO;EACPC,GAAG;EACHE,YAAY,EACXM,UAAU,KACX;EACD;CACA;AAGD,MAAMC,iBAAiB;CACtBC,MAAM,EAAEX,OAAO,GAAG;CAClBY,OAAO,EAAEZ,OAAO,MAAM;CACtBa,KAAK,EAAEb,OAAO,KAAK;CACnB;AAGD,MAAMc,qBAAqB;CAC1BhB,QAAQ;EAAEC,SAAS;EAAGgB,QAAQ;EAAG;CACjCb,SAAS;EACRH,SAAS;EACTgB,QAAQ;EACRZ,YAAY;GACXC,MAAM;GACNE,WAAW;GACXC,SAAS;GACV;EACA;CACDC,MAAM;EACLT,SAAS;EACTgB,QAAQ;EACRZ,YAAY,EACXM,UAAU,IACX;EACD;CACA;;;;AAKD,SAAgBO,4BAA4BC,UAGvB;AACpB,KAAI,CAACA,SAAU,QAAO;AACtB,KAAIA,SAASC,WAAW,UAAW,QAAO;AAC1C,KAAID,SAASC,WAAW,YACvB,QAAOD,SAASE,QAAQ,UAAU;AAEnC,QAAO;;;;;;;;;AAUR,MAAaC,aAAgCC,OAAA;CAAA,MAAAC,IAAA7C,EAAA,IAAA;CAAC,MAAA,EAAAiB,OAAAC,SAAA4B,IAAA3B,cAAAyB;CAAS,MAAA1B,UAAA4B,OAAAC,SAAA,QAAAD;CACtD,MAAAE,cAAoBvC,wBAAwB;CAC5C,MAAAwC,oBAA0BvC,8BAA8B;CACxD,MAAAwC,gBAAsBjD,kBAAkB;CAAA,IAAAkD;AAAA,KAAAN,EAAA,OAAA5B,SAAA4B,EAAA,OAAAG,eAAAH,EAAA,OAAAI,mBAAA;AAEVE,aAAA;AAE7BF,sBAAiBG,sBAAwB;AAGzCJ,gBAAWK,MAAQ;AACnBpC,YAAS;;AACT4B,IAAA,KAAA5B;AAAA4B,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAPD,MAAAS,YAAkBH;CAOyB,IAAAI;AAAA,KAAAV,EAAA,OAAAG,aAAA;AAENO,aAAA;AACpCP,gBAAWQ,YAAc;;AACzBX,IAAA,KAAAG;AAAAH,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAFD,MAAAY,mBAAyBF;CAER,IAAAG;AAAA,KAAAb,EAAA,OAAAK,iBAAAL,EAAA,OAAAG,aAAA;AAIhBU,QAAAC,SAAA;GACC,MAAAC,UAAgBD,KAAIE,MAAO;AAC3B,OAAI,CAACD,QAAO;AAGZ,OAAIZ,aAAWc,WAAW;IAEzB,MAAAC,WAAsB,EAAAC,QACb;KAAAC,QACC;KAAOC,gBACClB,YAAWc;KAAUK,WAC1BC,KAAIC,KAAK;KACrB,EACA;AAEDnB,kBAAaoB,OAAQ;KAAAC,MACd;KAAMC,SACH,CAAC;MAAA7C,MAAQ;MAAMgC,MAAQC;MAAS,CAAC;KAAAG;KAE1C,CAAC;;AAGHf,gBAAWyB,YAAcb,QAAQ;;AACjCf,IAAA,KAAAK;AAAAL,IAAA,KAAAG;AAAAH,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAxBF,MAAA6B,kBAAwBhB;AA6BxB,KACC,CAACV,eACA,CAACA,YAAW2B,YAAZ,CAA0B3B,YAAW4B,gBAArC,CAAuD5B,YAAW6B,QAAS,QAErE;CAGR,MAAA,EAAAF,UAAAC,cAAAE,SAAAD,SAAAnC,OAAAqC,YAAAC,YAAAxC,aACCQ;CAGD,MAAAiC,uBAA6BhC,mBAAiBgC,wBAAjB;CAC7B,MAAAC,WAAiBH,YAAUG,YAAV;CACjB,MAAAC,eAAqBJ,YAAUI,gBAAV;CAA6B,IAAAC;AAAA,KAAAvC,EAAA,OAAA1B,WAAA;AAIrCiE,OAAA5E,GAAG,uBAAuBW,UAAU;AAAA0B,IAAA,KAAA1B;AAAA0B,IAAA,MAAAuC;OAAAA,MAAAvC,EAAA;CAa3C,MAAAwC,KAAAP,UAAA,+BAAA;CAAoE,IAAAQ;AAAA,KAAAzC,EAAA,QAAAwC,IAAA;AAF1DC,OAAA9E,GACV,kFACA6E,GACA;AAAAxC,IAAA,MAAAwC;AAAAxC,IAAA,MAAAyC;OAAAA,MAAAzC,EAAA;CACmB,MAAA0C,KAAAT,UAAA,KAAA;CAAiB,IAAAU;AAAA,KAAA3C,EAAA,QAAA0C,IAAA;AAA5BC,OAAA,EAAAlE,SAAWiE,IAAmB;AAAA1C,IAAA,MAAA0C;AAAA1C,IAAA,MAAA2C;OAAAA,MAAA3C,EAAA;CAAA,IAAA4C;AAAA,KAAA5C,EAAA,QAAAiC,SAAA;AAEtCW,QAAAX,UACA,oBAAC,UAAiB,WAAA,8BAGlB,GADA,oBAAC,OAAc,WAAA,8BACf;AAAAjC,IAAA,MAAAiC;AAAAjC,IAAA,MAAA4C;OAAAA,OAAA5C,EAAA;CAAA,IAAA6C;AAAA,KAAA7C,EAAA,QAAA4C,OAAA5C,EAAA,QAAAyC,MAAAzC,EAAA,QAAA2C,IAAA;AAXFE,QAAA,oBAAA,OAAA;GACY,WAAAJ;GAIF,SAAAE;aAERC;IAKW;AAAA5C,IAAA,MAAA4C;AAAA5C,IAAA,MAAAyC;AAAAzC,IAAA,MAAA2C;AAAA3C,IAAA,MAAA6C;OAAAA,OAAA7C,EAAA;CAGgB,MAAA8C,MAAAzE,UAAA,yBAAA;CAAyD,IAAA0E;AAAA,KAAA/C,EAAA,QAAA8C,KAAA;AAA1EC,QAAApF,GAAG,cAAcmF,IAA0D;AAAA9C,IAAA,MAAA8C;AAAA9C,IAAA,MAAA+C;OAAAA,OAAA/C,EAAA;CAG7E,MAAAgD,MAAAlB,YAAA,CAAaG;CAAO,IAAAgB;AAAA,KAAAjD,EAAA,QAAA+B,gBAAA/B,EAAA,QAAAqC,YAAArC,EAAA,QAAAgD,KAAA;AAD7BC,QAAA,oBAAC;GACQ,QAAAD;GACIjB,YAAAA;GACMM,kBAAAA;GACR,UAAA;GACF,QAAA;GACG,WAAA;GACF,UAAA;GACD,QAAA;GACH,MAAA;GACQ,aAAA;GACF,WAAA;IACV;AAAArC,IAAA,MAAA+B;AAAA/B,IAAA,MAAAqC;AAAArC,IAAA,MAAAgD;AAAAhD,IAAA,MAAAiD;OAAAA,OAAAjD,EAAA;CAAA,IAAAkD;AAAA,KAAAlD,EAAA,QAAA+C,OAAA/C,EAAA,QAAAiD,KAAA;AAfHC,QAAA,oBAAA;GACY,WAAAH;aAEXE;IAaK;AAAAjD,IAAA,MAAA+C;AAAA/C,IAAA,MAAAiD;AAAAjD,IAAA,MAAAkD;OAAAA,OAAAlD,EAAA;CAAA,IAAAmD;AAAA,KAAAnD,EAAA,QAAA6C,OAAA7C,EAAA,QAAAkD,KAAA;AA/BPC,QAAA,qBAAA;GAAe,WAAA;cACdN,KAcAK;IAiBK;AAAAlD,IAAA,MAAA6C;AAAA7C,IAAA,MAAAkD;AAAAlD,IAAA,MAAAmD;OAAAA,OAAAnD,EAAA;CAAA,IAAAoD;AAAA,KAAApD,EAAA,QAAAqD,OAAAC,IAAA,4BAAA,EAAA;AAGNF,QAAA,oBAAA,SAAe,WAAA,yBAAyB;AAAApD,IAAA,MAAAoD;OAAAA,OAAApD,EAAA;CAKV,MAAAuD,MAAAlF,UAAA,yBAAA;CAAyD,IAAAmF;AAAA,KAAAxD,EAAA,QAAAuD,KAAA;AAA1EC,QAAA7F,GAAG,cAAc4F,IAA0D;AAAAvD,IAAA,MAAAuD;AAAAvD,IAAA,MAAAwD;OAAAA,OAAAxD,EAAA;CAAA,IAAAyD;AAAA,KAAAzD,EAAA,QAAA8B,YAAA9B,EAAA,QAAA+B,gBAAA/B,EAAA,QAAAsC,cAAA;AAEtFmB,QAAA,oBAAC;GACQ3B,QAAAA;GACIC,YAAAA;GACMO,kBAAAA;GACR,UAAA;GACF,QAAA;GACG,WAAA;GACF,UAAA;GACD,QAAA;GACH,MAAA;GACQ,aAAA;GACF,WAAA;IACV;AAAAtC,IAAA,MAAA8B;AAAA9B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAsC;AAAAtC,IAAA,MAAAyD;OAAAA,OAAAzD,EAAA;CAAA,IAAA0D;AAAA,KAAA1D,EAAA,QAAAwD,OAAAxD,EAAA,QAAAyD,KAAA;AAfHC,QAAA,oBAAA;GACY,WAAAF;aAEXC;IAaK;AAAAzD,IAAA,MAAAwD;AAAAxD,IAAA,MAAAyD;AAAAzD,IAAA,MAAA0D;OAAAA,OAAA1D,EAAA;CAAA,IAAA2D;AAAA,KAAA3D,EAAA,QAAAsC,cAAA;AAOIqB,QAAArB,eAAe,KAAf;GAAsB;GAAG;GAAK;GAAM,GAApC;AAAoCtC,IAAA,MAAAsC;AAAAtC,IAAA,MAAA2D;OAAAA,OAAA3D,EAAA;CAClC,MAAA4D,MAAAtB,eAAe,KAAf,IAAA;CAA4B,IAAAuB;AAAA,KAAA7D,EAAA,QAAA2D,OAAA3D,EAAA,QAAA4D,KAAA;AAF7BC,QAAA;GAAAnF,OACDiF;GAAoClF,SAClCmF;GACT;AAAA5D,IAAA,MAAA2D;AAAA3D,IAAA,MAAA4D;AAAA5D,IAAA,MAAA6D;OAAAA,OAAA7D,EAAA;CAAA,IAAA8D;AAAA,KAAA9D,EAAA,QAAAqD,OAAAC,IAAA,4BAAA,EAAA;AACWQ,QAAA,EAAA3E,UAAY,IAAK;AAAAa,IAAA,MAAA8D;OAAAA,OAAA9D,EAAA;CAAA,IAAA+D;AAAA,KAAA/D,EAAA,QAAA6D,KAAA;AAP/BE,QAAA,oBAAA;GAAe,WAAA;aACd,oBAAA,OAAA;IACW,WAAA;IACD,SAAAF;IAIG,YAAAC;KAEd;IAAM;AAAA9D,IAAA,MAAA6D;AAAA7D,IAAA,MAAA+D;OAAAA,OAAA/D,EAAA;CAAA,IAAAgE;AAAA,KAAAhE,EAAA,QAAA0D,OAAA1D,EAAA,QAAA+D,KAAA;AA7BPC,QAAA,qBAAA;GAAe,WAAA;cACdN,KAmBAK;IAUK;AAAA/D,IAAA,MAAA0D;AAAA1D,IAAA,MAAA+D;AAAA/D,IAAA,MAAAgE;OAAAA,OAAAhE,EAAA;CAAA,IAAAiE;AAAA,KAAAjE,EAAA,QAAAqD,OAAAC,IAAA,4BAAA,EAAA;AAGNW,QAAA,oBAAA,SAAe,WAAA,yBAAyB;AAAAjE,IAAA,MAAAiE;OAAAA,OAAAjE,EAAA;CAQ5B,MAAAkE,MAAA,CAACpC;CAIV,MAAAqC,MAAAlC,UAAA,mDAAA;CAEiE,IAAAmC;AAAA,KAAApE,EAAA,QAAAmE,KAAA;AALvDC,QAAAzG,GACV,yEACA,kCACAwG,IAGA;AAAAnE,IAAA,MAAAmE;AAAAnE,IAAA,MAAAoE;OAAAA,OAAApE,EAAA;CAKW,MAAAqE,MAAApC,UAAA,sBAAA;CAAiD,IAAAqC;AAAA,KAAAtE,EAAA,QAAAiC,SAAA;AAE5DqC,QAAArC,UACA,oBAAC,UAAiB,WAAA,8BAGlB,GADA,oBAAC,OAAc,WAAA,8BACf;AAAAjC,IAAA,MAAAiC;AAAAjC,IAAA,MAAAsE;OAAAA,OAAAtE,EAAA;CAAA,IAAAuE;AAAA,KAAAvE,EAAA,QAAAY,oBAAAZ,EAAA,QAAAkE,OAAAlE,EAAA,QAAAoE,OAAApE,EAAA,QAAAqE,OAAArE,EAAA,QAAAsE,KAAA;AArBFC,QAAA,oBAAA,OAAA;GACM,MAAA;GACI3D,SAAAA;GACC,UAAAsD;GACC,WAAAE;GAODhF,UAAAA;GACF,SAAA;GACG,YAAA;GACF,UAAA;GACG,cAAAiF;aAEXC;IAKc;AAAAtE,IAAA,MAAAY;AAAAZ,IAAA,MAAAkE;AAAAlE,IAAA,MAAAoE;AAAApE,IAAA,MAAAqE;AAAArE,IAAA,MAAAsE;AAAAtE,IAAA,MAAAuE;OAAAA,OAAAvE,EAAA;CAAA,IAAAwE;AAAA,KAAAxE,EAAA,QAAAqD,OAAAC,IAAA,4BAAA,EAAA;AAMJkB,QAAA7G,GACV,yEACA,8BACA,0CACA,iCACA;AAAAqC,IAAA,MAAAwE;OAAAA,OAAAxE,EAAA;CAAA,IAAAyE;AAAA,KAAAzE,EAAA,QAAAqD,OAAAC,IAAA,4BAAA,EAAA;AAODmB,QAAA,oBAAC,YAAmB,WAAA,8BAA8B;AAAAzE,IAAA,MAAAyE;OAAAA,OAAAzE,EAAA;CAAA,IAAA0E;AAAA,KAAA1E,EAAA,QAAAS,WAAA;AAfnDiE,QAAA,oBAAA,OAAA;GACM,MAAA;GACIjE,SAAAA;GACE,WAAA+D;GAMDpF,UAAAA;GACF,SAAA;GACG,YAAA;GACF,UAAA;GACE,cAAA;aAEXqF;IACe;AAAAzE,IAAA,MAAAS;AAAAT,IAAA,MAAA0E;OAAAA,OAAA1E,EAAA;CAAA,IAAA2E;AAAA,KAAA3E,EAAA,QAAAuE,OAAAvE,EAAA,QAAA0E,KAAA;AA3CjBC,QAAA,qBAAA;GAAe,WAAA;cAEdJ,KAyBAG;IAiBK;AAAA1E,IAAA,MAAAuE;AAAAvE,IAAA,MAAA0E;AAAA1E,IAAA,MAAA2E;OAAAA,OAAA3E,EAAA;CAAA,IAAA4E;AAAA,KAAA5E,EAAA,QAAAmD,OAAAnD,EAAA,QAAAgE,OAAAhE,EAAA,QAAA2E,KAAA;AAxHPC,QAAA,qBAAA;GAAe,WAAA;;IAEdzB;IAmCAC;IAGAY;IAiCAC;IAGAU;;IA6CK;AAAA3E,IAAA,MAAAmD;AAAAnD,IAAA,MAAAgE;AAAAhE,IAAA,MAAA2E;AAAA3E,IAAA,MAAA4E;OAAAA,OAAA5E,EAAA;CAAA,IAAA6E;AAAA,KAAA7E,EAAA,QAAAoC,sBAAA;AAGYyC,QAAAzC,wBAAwB,oBAAC,yBAAuB;AAAApC,IAAA,MAAAoC;AAAApC,IAAA,MAAA6E;OAAAA,OAAA7E,EAAA;CAAA,IAAA8E;AAAA,KAAA9E,EAAA,QAAA6E,KAAA;AAAlEC,QAAA,oBAAC,6BAAiBD,MAAmE;AAAA7E,IAAA,MAAA6E;AAAA7E,IAAA,MAAA8E;OAAAA,OAAA9E,EAAA;CAAA,IAAA+E;AAAA,KAAA/E,EAAA,QAAAoC,wBAAApC,EAAA,QAAAL,UAAA;AAInFoF,QAAApF,YAAA,CAAayC,wBACb,qBAAA,OAAA;GACY,WAAAzE,GACV,+DACA,WACAgC,SAAQC,WAAY,aAApB,gCACAD,SAAQC,WAAY,eAApB,CACED,SAAQE,SADV,kCAGAF,SAAQC,WAAY,eAAeD,SAAQE,SAA3C,6BACD;GACS,SAAA;IAAApB,SAAW;IAACE,GAAK;IAAG;GACpB,SAAA;IAAAF,SAAW;IAACE,GAAK;IAAE;GACtB,MAAA;IAAAF,SAAW;IAACE,GAAK;IAAG;GACd,YAAA;IAAAG,MAAQ;IAAQE,WAAa;IAAGC,SAAW;IAAG;cAE1D,oBAAA,OAAA;IACY,WAAAtB,GACV,qCACAgC,SAAQC,WAAY,aAApB,eACAD,SAAQC,WAAY,eAApB,CAAoCD,SAAQE,SAA5C,gBACAF,SAAQC,WAAY,eAAeD,SAAQE,SAA3C,aACD;IACS,SAAAF,SAAQC,WAAY,YAApB,EAAAnB,SAA2C;KAAC;KAAG;KAAK;KAAC,EAAQ,GAA7D,EAA4D;IACzD,YAAA;KAAAU,UAAY;KAAG6F,QAAUC;KAAS;KAE/C,sBAAA;IAAgB,WAAA;cAAoBtF,SAAQuF;KAC7C;IACA;AAAAlF,IAAA,MAAAoC;AAAApC,IAAA,MAAAL;AAAAK,IAAA,MAAA+E;OAAAA,OAAA/E,EAAA;CAAA,IAAAmF;AAAA,KAAAnF,EAAA,QAAA+E,KAAA;AA7BFI,QAAA,oBAAC,6BACCJ,MA6BgB;AAAA/E,IAAA,MAAA+E;AAAA/E,IAAA,MAAAmF;OAAAA,OAAAnF,EAAA;CAAA,IAAAoF;AAAA,KAAApF,EAAA,QAAAmC,YAAA;AAIhBiD,QAAAjD,cAAcA,WAAUrB,QACxB,oBAAA,OAAA;GACW,WAAA;GACAtB,UAAAA;GACF,SAAA;GACA,SAAA;GACH,MAAA;aAEL,qBAAA;IACY,WAAA7B,GACV,gCACAwE,WAAUrD,SAAU,SAApB,8BAAA,2BAGD;eAEA,oBAAA;KAAgB,WAAA;eACdqD,WAAUrD,SAAU,SAApB,SAAA;MAEF,sBAAA;KAAiB,WAAAnB,GAAG,gBAAgB,CAACwE,WAAUkD,UAAX,gBAAqC;eACvElD,WAAUrB;MAEb;KACD;IACA;AAAAd,IAAA,MAAAmC;AAAAnC,IAAA,MAAAoF;OAAAA,OAAApF,EAAA;CAAA,IAAAsF;AAAA,KAAAtF,EAAA,QAAAoF,KAAA;AAzBFE,QAAA,oBAAC,6BACCF,MAyBgB;AAAApF,IAAA,MAAAoF;AAAApF,IAAA,MAAAsF;OAAAA,OAAAtF,EAAA;CAAA,IAAAuF;AAAA,KAAAvF,EAAA,QAAA8B,YAAA9B,EAAA,QAAA+B,cAAA;AAIhBwD,QAAAxD,gBAAA,CAAiBD,YACjB,qBAAA,OAAA;GACW,WAAA;GACD,SAAA,EAAArD,SAAW,GAAE;GACb,SAAA,EAAAA,SAAW,GAAE;GAChB,MAAA,EAAAA,SAAW,GAAE;cAEnB,oBAAA,OAAA;IACW,WAAA;IACD,SAAA,EAAAA,SAAW;KAAC;KAAG;KAAK;KAAC,EAAE;IACpB,YAAA;KAAAU,UAAY;KAAG6F,QAAUC;KAAS;KAE/C,sBAAA,oBAAM,kBACP;IACA;AAAAjF,IAAA,MAAA8B;AAAA9B,IAAA,MAAA+B;AAAA/B,IAAA,MAAAuF;OAAAA,OAAAvF,EAAA;CAAA,IAAAwF;AAAA,KAAAxF,EAAA,QAAAuF,KAAA;AAfFC,QAAA,oBAAC,6BACCD,MAegB;AAAAvF,IAAA,MAAAuF;AAAAvF,IAAA,MAAAwF;OAAAA,OAAAxF,EAAA;CAAA,IAAAyF;AAAA,KAAAzF,EAAA,QAAAH,SAAAG,EAAA,QAAAS,aAAAT,EAAA,QAAAgC,SAAA;AAIhByD,QAAAzD,WAAAnC,SACA,qBAAA,OAAA;GACW,WAAA;GACD,SAAA;IAAApB,SAAW;IAACE,GAAK;IAAG;GACpB,SAAA;IAAAF,SAAW;IAACE,GAAK;IAAE;GACtB,MAAA;IAAAF,SAAW;IAACE,GAAK;IAAG;;IAE1B,oBAAA,UAAgB,WAAA,iDAChB;wBAAA;KAAgB,WAAA;eAAgBkB;MAChC;wBAAA;KACM,MAAA;KACIY,SAAAA;KACC,WAAA;eACV;MAGF;;IACA;AAAAT,IAAA,MAAAH;AAAAG,IAAA,MAAAS;AAAAT,IAAA,MAAAgC;AAAAhC,IAAA,MAAAyF;OAAAA,OAAAzF,EAAA;CAAA,IAAA0F;AAAA,KAAA1F,EAAA,QAAAyF,KAAA;AAlBFC,QAAA,oBAAC,6BACCD,MAkBgB;AAAAzF,IAAA,MAAAyF;AAAAzF,IAAA,MAAA0F;OAAAA,OAAA1F,EAAA;CAAA,IAAA2F;AAAA,KAAA3F,EAAA,SAAA6B,mBAAA7B,EAAA,SAAA8B,YAAA9B,EAAA,SAAAoC,sBAAA;AAIhBuD,QAAA7D,YAAA,CAAaM,wBACb,oBAAA,OAAA;GACW,WAAA;GACD,SAAA;IAAA3D,SAAW;IAACE,GAAK;IAAE;GACnB,SAAA;IAAAF,SAAW;IAACE,GAAK;IAAE;GACtB,MAAA;IAAAF,SAAW;IAACE,GAAK;IAAE;GACb,YAAA,EAAAiH,OAAS,IAAI;aAEzB,oBAAC;IACY,aAAA;IACC,aAAA;IACA/D,aAAAA;IACI,iBAAA;IACF,eAAA;KAEjB;IACA;AAAA7B,IAAA,OAAA6B;AAAA7B,IAAA,OAAA8B;AAAA9B,IAAA,OAAAoC;AAAApC,IAAA,OAAA2F;OAAAA,OAAA3F,EAAA;CAAA,IAAA6F;AAAA,KAAA7F,EAAA,SAAA2F,KAAA;AAjBFE,QAAA,oBAAC,6BACCF,MAiBgB;AAAA3F,IAAA,OAAA2F;AAAA3F,IAAA,OAAA6F;OAAAA,OAAA7F,EAAA;CAAA,IAAA8F;AAAA,KAAA9F,EAAA,SAAA4E,OAAA5E,EAAA,SAAA8E,OAAA9E,EAAA,SAAAmF,OAAAnF,EAAA,SAAAsF,OAAAtF,EAAA,SAAAwF,OAAAxF,EAAA,SAAAuC,MAAAvC,EAAA,SAAA0F,OAAA1F,EAAA,SAAA6F,KAAA;AAhQnBC,QAAA,qBAAA,OAAA;GACY,WAAAvD;GACDhE,UAAAA;GACF,SAAA;GACA,SAAA;GACH,MAAA;;IAGLqG;IA4HAE;IAGAK;IAiCAG;IA6BAE;IAmBAE;IAsBAG;;IAmBY;AAAA7F,IAAA,OAAA4E;AAAA5E,IAAA,OAAA8E;AAAA9E,IAAA,OAAAmF;AAAAnF,IAAA,OAAAsF;AAAAtF,IAAA,OAAAwF;AAAAxF,IAAA,OAAAuC;AAAAvC,IAAA,OAAA0F;AAAA1F,IAAA,OAAA6F;AAAA7F,IAAA,OAAA8F;OAAAA,OAAA9F,EAAA;AAAA,QAjQb8F;;;;;AAwQF,SAAOC,uBAAA;CAAA,MAAA/F,IAAA7C,EAAA,EAAA;CACN,MAAAgD,cAAoBvC,wBAAwB;AAE5C,KAAI,CAACuC,YAAW,QAAS;CAAM,IAAAJ;AAAA,KAAAC,EAAA,OAAAG,YAAAR,UAAA;AAExBI,OAAAL,4BAA4BS,YAAWR,SAAU;AAAAK,IAAA,KAAAG,YAAAR;AAAAK,IAAA,KAAAD;OAAAA,MAAAC,EAAA;AAAA,QAAjDD;;;;;;;;;;;;;;;;;ACtYR,MAAMqH,oBAA8B;CACnCC,QAAQ,EAAEC,SAAS,GAAG;CACtBC,SAAS;EACRD,SAAS;EACTE,YAAY;GACXC,iBAVmB;GAWnBC,eAV2B;GAW5B;EACA;CACDC,MAAM;EACLL,SAAS;EACTE,YAAY;GACXC,iBAfwB;GAgBxBG,kBAAkB;GACnB;EACD;CACA;;AAGD,MAAMC,iBAA2B;CAChCR,QAAQ;EAAEC,SAAS;EAAGQ,GAAG;EAAIC,OAAO;EAAK;CACzCR,SAAS;EACRD,SAAS;EACTQ,GAAG;EACHC,OAAO;EACPP,YAAY;GAAEQ,MAAM;GAAUC,WAAW;GAAKC,SAAS;GAAG;EAC1D;CACDP,MAAM;EAAEL,SAAS;EAAGQ,GAAG;EAAGC,OAAO;EAAMP,YAAY,EAAEW,UAAU,IAAI;EAAE;CACrE;;AAOD,MAAMC,eAAe7B,GACpB,iCACA,6BACA,gBACA,kDACA,qDACA,4CACA,2CACA,kCACA,qBAEA,kGACA;;AAGD,MAAM8B,yBAAyB9B,GAC9B,gCACA,oCACA,gBACA,gCACA,+CACA,oCACA,4CACA,gDACA,aACA,+BAEA,sEACA;;;;;AAUD,MAAa+B,eAAoCC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAA5B,SAAAC,UAAAE,cAAAuB;CACjD,MAAA,CAAAG,aAAAC,kBAAsCvC,SAAS,MAAM;CACrD,MAAA,EAAAwC,aAAqBvC,iBAAiB;CAAA,IAAAwC;AAAA,KAAAL,EAAA,OAAA1B,UAAA;AAGrC+B,QAAA9B,WAAA;AACCD,YAASC,OAAO;;AAChByB,IAAA,KAAA1B;AAAA0B,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAHF,MAAAM,eAAqBD;CAKpB,IAAAE;AAAA,KAAAP,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAEiCF,QAAAG,MAAA;AACjCA,KAACC,iBAAkB;AACnBR,kBAAe,KAAK;;AACpBH,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAHD,MAAAY,gBAAsBL;AAMtB,KAAIlC,QAAOwC,WAAY,KAAnBX,YAAmC,QAC/B;CACP,IAAAY;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAA3B,EAAA,OAAAxB,aAAAwB,EAAA,OAAAM,gBAAAN,EAAA,OAAAI,YAAAJ,EAAA,OAAA3B,SAAA;EAGD,MAAAuD,iBAAuBvD,QAAOwD,MAAO,GAAG/D,mBAAmB;EAM1D,MAAAgE,QAAA1B,WAAA,YAAA;EAEA,MAAA2B,QAAA3B,WAAA,0BAAA;EAEqE,IAAA4B;AAAA,MAAAhC,EAAA,QAAA8B,SAAA9B,EAAA,QAAA+B,OAAA;AAP3CC,WAAAjE,GAC1B8B,wBAEAiC,OAEAC,MAGA;AAAA/B,KAAA,MAAA8B;AAAA9B,KAAA,MAAA+B;AAAA/B,KAAA,MAAAgC;QAAAA,SAAAhC,EAAA;EARD,MAAAiC,qBAA2BD;AAWVxD,QAAAA;AAEf4C,QAAA,qBAAA;GAAU,MAAA;GAAmB,aAAA;GAAmB,WAAA;;IAC9CQ,eAAcf;IAAQ;IAAYe,eAAcf,WAAY,IAA1B,MAAA;IAAuC;;IACrE;AAELE,OAAAtD;AAAqByD,QAAA;AACpBJ,OAAApD,OAAMwE;AACFb,OAAA;AACMzC,OAAAA;AACF2C,OAAA;AACAC,OAAA;AACHC,OAAA;AACKC,OAAA;AACLC,OAAA;AACMX,QAAA;AAEVC,QAAAW,eAAcO,KAAKC,UAAAC,UAAA;AAE8C,UAGhE,qBAAA;IAAkC,WAAAtE,GAAG,kBAHf6D,eAAcf,WAAY,KAAKwB,UAAU,KAGR,OAAwB;eAC9E,oBAAA,OAAA;KACM,MAAA;KACKhD,UAAAA;KACD,eAAMiB,aAAa/B,SAAM;KACvBqB,WAAAA;KACJ,OAAArB,SAAMiE,eAAgBjE,SAAMgE;eAEnC,oBAAA,oBAAOhE,SAAMgE,OACd;MAGA,sBAAA;KACM,MAAA;KACI3B,SAAAA;KACEqB,WAAAA;KACA,cAAA;eAEX,oBAAC,KAAQ,MAAA7B,WAAA,KAAA,KACV;MACD;MApBU7B,SAAMgE,KAoBV;IAEN;AAAAvC,IAAA,KAAAxB;AAAAwB,IAAA,KAAAM;AAAAN,IAAA,KAAAI;AAAAJ,IAAA,KAAA3B;AAAA2B,IAAA,KAAAc;AAAAd,IAAA,KAAAe;AAAAf,IAAA,KAAAgB;AAAAhB,IAAA,MAAAiB;AAAAjB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;AAAArB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAuB;AAAAvB,IAAA,MAAAwB;AAAAxB,IAAA,MAAAyB;AAAAzB,IAAA,MAAA0B;AAAA1B,IAAA,MAAA2B;QAAA;AAAAb,OAAAd,EAAA;AAAAe,OAAAf,EAAA;AAAAgB,QAAAhB,EAAA;AAAAiB,QAAAjB,EAAA;AAAAkB,QAAAlB,EAAA;AAAAmB,QAAAnB,EAAA;AAAAoB,QAAApB,EAAA;AAAAqB,OAAArB,EAAA;AAAAsB,OAAAtB,EAAA;AAAAuB,OAAAvB,EAAA;AAAAwB,OAAAxB,EAAA;AAAAyB,OAAAzB,EAAA;AAAA0B,OAAA1B,EAAA;AAAA2B,OAAA3B,EAAA;;CAAA,IAAA8B;AAAA,KAAA9B,EAAA,QAAAc,MAAAd,EAAA,QAAAgB,OAAAhB,EAAA,QAAAiB,OAAAjB,EAAA,QAAAqB,MAAArB,EAAA,QAAAsB,MAAAtB,EAAA,QAAAuB,MAAAvB,EAAA,QAAAwB,MAAAxB,EAAA,QAAAyB,MAAAzB,EAAA,QAAA0B,MAAA1B,EAAA,QAAA2B,IAAA;AArCHG,QAAA,oBAAC;GAEUlD,UAAAA;GACF,SAAA2C;GACA,SAAAC;GACH,MAAAC;GACK,WAAAC;GACL,MAAAC;GACM,cAAAX;aAEVC;KATGI,GAqCQ;AAAArB,IAAA,MAAAc;AAAAd,IAAA,MAAAgB;AAAAhB,IAAA,MAAAiB;AAAAjB,IAAA,MAAAqB;AAAArB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAuB;AAAAvB,IAAA,MAAAwB;AAAAxB,IAAA,MAAAyB;AAAAzB,IAAA,MAAA0B;AAAA1B,IAAA,MAAA2B;AAAA3B,IAAA,MAAA8B;OAAAA,OAAA9B,EAAA;CAAA,IAAA+B;AAAA,KAAA/B,EAAA,QAAAe,MAAAf,EAAA,QAAAkB,OAAAlB,EAAA,QAAA8B,KAAA;AAvCdC,QAAA,oBAAC;GAAqB,MAAAb;aACrBY;IAuCiB;AAAA9B,IAAA,MAAAe;AAAAf,IAAA,MAAAkB;AAAAlB,IAAA,MAAA8B;AAAA9B,IAAA,MAAA+B;OAAAA,OAAA/B,EAAA;CAAA,IAAAgC;AAAA,KAAAhC,EAAA,QAAAmB,OAAAnB,EAAA,QAAAoB,OAAApB,EAAA,QAAA+B,KAAA;AA9CnBC,QAAA,qBAAA;GAAgBxD,WAAAA;cAEf4C,KAIAW;IAyCK;AAAA/B,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAA+B;AAAA/B,IAAA,MAAAgC;OAAAA,OAAAhC,EAAA;AAAA,QA/CNgC;;;;;;;;;;;;;;;AChIF,MAAaqB,qBAAgDC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAP,SAAAC,UAAAE,cAAAE;CAC7D,MAAAG,YAAkBb,OAAuB,KAAK;CAAA,IAAAc;AAAA,KAAAH,EAAA,OAAAL,UAAA;AAG7CQ,QAAAP,WAAA;AACCD,YAASC,OAAO;;AAChBI,IAAA,KAAAL;AAAAK,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAHF,MAAAI,cAAoBD;AAOpB,KAAIT,QAAOW,WAAY,EAAC,QAChB;CACP,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAR,EAAA,OAAAS,OAAAC,IAAA,4BAAA,EAAA;AAIUJ,OAAA;GAAAK,SAAW;GAACC,QAAU;GAAG;AACzBL,OAAA;GAAAI,SAAW;GAACC,QAAU;GAAQ;AACjCJ,OAAA;GAAAG,SAAW;GAACC,QAAU;GAAG;AAAAZ,IAAA,KAAAM;AAAAN,IAAA,KAAAO;AAAAP,IAAA,KAAAQ;QAAA;AAAAF,OAAAN,EAAA;AAAAO,OAAAP,EAAA;AAAAQ,OAAAR,EAAA;;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAH,WAAA;AACpBgB,OAAAvB,GAAG,mBAAmBO,UAAU;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;CAAA,IAAAC;AAAA,KAAAf,EAAA,OAAAS,OAAAC,IAAA,4BAAA,EAAA;AAI/BI,OAAAxB,GACV,6CACA,aACA;AAEMyB,OAAA,EAAAC,aAAe,SAAS;AAAAhB,IAAA,KAAAc;AAAAd,IAAA,KAAAe;QAAA;AAAAD,OAAAd,EAAA;AAAAe,OAAAf,EAAA;;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,OAAAI,eAAAJ,EAAA,QAAAN,SAAA;EAAA,IAAAwB;AAAA,MAAAlB,EAAA,QAAAI,aAAA;AAIjBc,WAAAC,UAAAC,UACZ,oBAAA,OAAA;IAEM,MAAA;IACI,SAAA;KAAAT,SAAW;KAACW,OAAS;KAAI;IACzB,SAAA;KAAAX,SAAW;KAACW,OAAS;KAAE;IAC1B,MAAA;KAAAX,SAAW;KAACW,OAAS;KAAI;IACnB,YAAA;KAAAC,MACL;KAAQC,WACH;KAAGC,SACL;KAAEC,OACJN,QAAQ;KAChB;IACS,eAAMhB,YAAYR,SAAM;IACtB,WAAAN,GACV,iBACA,4BACA,iCACA,kCACA,uBACA,gDACA,+BACA,kBACA,oBACD;IACO,OAAAM,SAAM+B,eAAgB/B,SAAMyB;cAElCzB,SAAMyB;MAzBFzB,SAAMyB,KA2BZ;AAAArB,KAAA,MAAAI;AAAAJ,KAAA,MAAAkB;QAAAA,QAAAlB,EAAA;AA7BAiB,OAAAvB,QAAOkC,IAAKV,KA6BX;AAAAlB,IAAA,KAAAI;AAAAJ,IAAA,MAAAN;AAAAM,IAAA,MAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,QAAAiB,IAAA;AAxCJC,OAAA,oBAAA;GACMhB,KAAAA;GACM,WAAAY;GAKJ,OAAAC;GACe,sBAAAc;aAEtB,oBAAC;IAAqB,MAAA;cACpBZ;KA+BH;IAAM;AAAAjB,IAAA,MAAAiB;AAAAjB,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAA8B;AAAA,KAAA9B,EAAA,QAAAa,MAAAb,EAAA,QAAAkB,IAAA;AAhDPY,QAAA,oBAAA,OAAA;GACU,SAAAxB;GACA,SAAAC;GACH,MAAAC;GACK,WAAAK;aAEXK;IA2CY;AAAAlB,IAAA,MAAAa;AAAAb,IAAA,MAAAkB;AAAAlB,IAAA,MAAA8B;OAAAA,OAAA9B,EAAA;AAAA,QAjDb8B;;AAf2D,SAAAD,QAAAE,GAAA;AAAA,QA6B5BA,EAACC,iBAAkB;;;;;;;;;;;;;;;;;;;;;;AChBpD,SAAOW,mBAAA;CAAA,MAAAC,IAAAV,EAAA,EAAA;CACN,MAAAW,WAAiBV,UAAUW,QAA4B;CACvD,MAAAC,YAAkBZ,UAAUa,OAA6B;CAAA,IAAAC;AAAA,KAAAL,EAAA,OAAAG,aAAAH,EAAA,OAAAC,UAAA;AAAAK,OAAA;AAGxD,OAAI,CAACH,WAAS;AAAEE,SAAO;AAAP,UAAAC;;GAGhB,MAAAC,uBAA6BN,WAC1B,CAAA,GAAIA,SAAS,CAAAO,SAAU,CAAAC,KAAMC,OACzB,GAFsB;AAI7B,OAAI,CAACH,sBAAoB;AAAEF,SAAO;AAAP,UAAAC;;GAM3B,MAAAS,WAHkBR,qBAAoBK,QAAQC,OAC7CC,OACA,CACyBE,GAAI,GAAS,EAAAlB;AAGvC,OAAI,CAACiB,YAAYA,SAAQE,MAAO,CAAAC,WAAY,GAAC;AAAEb,SAAO;AAAP,UAAAC;;AAE/CD,QAAOU;;AAAQf,IAAA,KAAAG;AAAAH,IAAA,KAAAC;AAAAD,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAnBTK;;AAJD,SAAAS,OAAAK,MAAA;AAAA,QAgBwBA,KAAItB,SAAU;;AAhBtC,SAAAa,OAAAU,GAAA;AAAA,QASkCA,EAACC,SAAU;;AAT7C,SAAAjB,OAAAkB,UAAA;AAAA,QAEkCC,SAAMpB;;AAFxC,SAAAD,QAAAqB,QAAA;AAAA,QACiCA,OAAMtB;;;;;;AA2C9C,MAAa2B,qBAAgDvB,OAAA;CAAA,MAAAL,IAAAV,EAAA,GAAA;CAAC,MAAA,EAAAmC,WAAAI,IAAAH,WAAAC,cAAAG,OAAAzB;CAC7D,MAAAoB,YAAAI,OAAAE,SAAA,SAAAF;CAEA,MAAAF,eAAAG,OAAAC,SAAA,QAAAD;CAEA,MAAAE,gBAAsBjC,kBAAkB;AAExC,KAAI,CAACiC,cAAa,QAAS;CAAI,IAAAC;AAAA,KAAAjC,EAAA,OAAA0B,WAAA;AAIlBO,OAAAxC,GACV,oDACA,+CAEA,UACAiC,UACA;AAAA1B,IAAA,KAAA0B;AAAA1B,IAAA,KAAAiC;OAAAA,MAAAjC,EAAA;CAAA,IAAAkC;AAAA,KAAAlC,EAAA,OAAA2B,gBAAA3B,EAAA,OAAAyB,WAAA;AACMS,OAAAP,eAAAI,SAAA,EAAAN,WAAwC;AAAAzB,IAAA,KAAA2B;AAAA3B,IAAA,KAAAyB;AAAAzB,IAAA,KAAAkC;OAAAA,MAAAlC,EAAA;CAG2B,MAAAmC,KAAA,CAACR;CAAY,IAAAS;AAAA,KAAApC,EAAA,OAAAgC,iBAAAhC,EAAA,OAAAmC,IAAA;AAAtFC,OAAA,oBAAC;GAAsBJ,SAAAA;GAAyB,WAAA;GAAyB,SAAAG;IAAiB;AAAAnC,IAAA,KAAAgC;AAAAhC,IAAA,KAAAmC;AAAAnC,IAAA,KAAAoC;OAAAA,MAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,OAAAsC,OAAAC,IAAA,4BAAA,EAAA;AAE1FF,OAAA,oBAAA,UAAgB,WAAA,yEAAyE;AAAArC,IAAA,KAAAqC;OAAAA,MAAArC,EAAA;CAAA,IAAAwC;AAAA,KAAAxC,EAAA,OAAAoC,IAAA;AAH1FI,OAAA,qBAAA;GAAe,WAAA;cACdJ,IAEAC;IACK;AAAArC,IAAA,KAAAoC;AAAApC,IAAA,MAAAwC;OAAAA,MAAAxC,EAAA;CAAA,IAAAyC;AAAA,KAAAzC,EAAA,QAAAiC,MAAAjC,EAAA,QAAAkC,MAAAlC,EAAA,QAAAwC,IAAA;AAdPC,OAAA,oBAAA;GACY,WAAAR;GAOJ,OAAAC;aAEPM;IAKK;AAAAxC,IAAA,MAAAiC;AAAAjC,IAAA,MAAAkC;AAAAlC,IAAA,MAAAwC;AAAAxC,IAAA,MAAAyC;OAAAA,MAAAzC,EAAA;AAAA,QAfNyC;;;;;ACzEF,MAAMiB,iBAAiB;CACtBC,MAAM;EACLC,SAAS;EACTC,OAAO;EACP;CACDC,SAAS;EACRF,SAAS;EACTC,OAAO;EACPE,YAAY,EACXH,SAAS,EAAEI,UAAU,KAAK,EAC3B;EACA;CACDC,OAAO;EACNL,SAAS;EACTC,OAAO;EACPE,YAAY,EACXH,SAAS,EAAEI,UAAU,IAAI,EAC1B;EACD;CACA;AAGD,MAAME,iBAAiB;CACtBC,GAAG;EAAC;EAAG;EAAI;EAAG;EAAI;EAAG;EAAE;CACvBJ,YAAY;EACXC,UAAU;EACVI,MAAM;GAAC;GAAM;GAAK;GAAM;GAAE;EAC3B;CACA;;;;;;;;AASD,MAAaE,oBAA8CC,OAAA;CAAA,MAAAC,IAAA7B,EAAA,GAAA;CAAC,MAAA,EAAAW,QAAAC,UAAAC,WAAAC,cAAAgB,OAAAF;CAI3D,MAAAd,eAAAgB,OAAAC,SAAA,SAAAD;CAGA,MAAAE,kBAAwBrB,WAAW,YAAX,SAAAA;CAAsC,IAAAsB;AAAA,KAAAJ,EAAA,OAAAhB,WAAA;AAIjDoB,OAAA3B,GAAG,YAAYO,UAAU;AAAAgB,IAAA,KAAAhB;AAAAgB,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAC3B,MAAAK,KAAAF,oBAAoB,UAApBT,iBAAAQ;CAAwD,IAAAI;AAAA,KAAAN,EAAA,OAAAf,gBAAAe,EAAA,OAAAG,iBAAA;AAI/DG,OAAAH,oBAAoB,UACpB,oBAAA,OAAA;GACY,WAAA1B,GACV,6CACA0B,oBAAoB,aAApB,uBACAA,oBAAoB,WAApB,oBACD;GACO,OAAA,EAAAlB,cAAe;GACZC,UAAAA;GACF,SAAA;GACCiB,SAAAA;GACH,MAAA;IAAAf,SAAW;IAACG,YAAc,EAAAC,UAAY,KAAK;IAAE;IAEpD;AAAAQ,IAAA,KAAAf;AAAAe,IAAA,KAAAG;AAAAH,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAO;AAAA,KAAAP,EAAA,OAAAM,IAAA;AAdFC,OAAA,oBAAC,6BACCD,KAcgB;AAAAN,IAAA,KAAAM;AAAAN,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAAA,IAAAQ;AAAA,KAAAR,EAAA,OAAAf,cAAA;AAGeuB,OAAA,EAAAvB,cAAgB;AAAAe,IAAA,KAAAf;AAAAe,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAjB,YAAAiB,EAAA,QAAAQ,IAAA;AAAjDC,OAAA,oBAAA;GAAe,WAAA;GAAkB,OAAAD;GAC/BzB;IACI;AAAAiB,IAAA,KAAAjB;AAAAiB,IAAA,MAAAQ;AAAAR,IAAA,MAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,QAAAI,MAAAJ,EAAA,QAAAK,MAAAL,EAAA,QAAAO,MAAAP,EAAA,QAAAS,IAAA;AAzBPC,OAAA,qBAAA,OAAA;GACY,WAAAN;GACF,SAAAC;cAGTE,IAkBAE;IAGY;AAAAT,IAAA,MAAAI;AAAAJ,IAAA,MAAAK;AAAAL,IAAA,MAAAO;AAAAP,IAAA,MAAAS;AAAAT,IAAA,MAAAU;OAAAA,MAAAV,EAAA;AAAA,QA1BbU;;;;;;AAkCF,SAAOC,oBAAAC,kBAAAC,kBAAA;CAAA,MAAAb,IAAA7B,EAAA,EAAA;CAIN,MAAA,CAAAW,QAAAgC,aAA4BtC,SAA2B,OAAO;CAC9D,MAAAuC,aAAmBxC,OAA8B,KAAK;CAAA,IAAAwB;CAAA,IAAAE;AAAA,KAAAD,EAAA,OAAAY,oBAAAZ,EAAA,OAAAa,kBAAA;AAE5Cd,aAAA;AACT,OAAIgB,WAAUC,SAAQ;AACrBC,iBAAaF,WAAUC,QAAS;AAChCD,eAAUC,UAAW;;AAGtB,OAAIJ,iBACHE,WAAU,UAAU;YACVD,qBAAqB,SAAO;AACtCC,cAAU,QAAQ;AAElBC,eAAUC,UAAWE,iBAAW;AAC/BJ,eAAU,OAAO;OACf,IAFe;SAKlBA,WAAU,OAAO;AACjB,gBAEM;AACN,QAAIC,WAAUC,QACbC,cAAaF,WAAUC,QAAS;;;AAGhCf,OAAA,CAACW,kBAAkBC,iBAAiB;AAAAb,IAAA,KAAAY;AAAAZ,IAAA,KAAAa;AAAAb,IAAA,KAAAD;AAAAC,IAAA,KAAAC;QAAA;AAAAF,OAAAC,EAAA;AAAAC,OAAAD,EAAA;;AAxBvC1B,WAAUyB,IAwBPE,GAAqC;AAAA,QAEjCnB;;;;;;;;;;;;;;;;;;AC7DR,MAAagG,aAAiC,EAC7CN,WAAW,iBACXC,kBAAkB,OAClBC,gBAAgB,OAChBC,eACAC,eAAe,MACfC,gBACK;CAKL,MAAM,EACLG,UACAC,WACAC,aACAC,eACAC,qBACAC,SACAC,OACAC,OACAb,eAAec,qBAZFtD,UAAU;CAgBxB,MAAMuD,wBAAwBnD,wBAAwB;CACtD,MAAMoD,mBAAmBnD,qBAAqB;CAC9C,MAAMoD,gBAAgBtE,kBAAkB;CAIxC,MAAM,CAACuE,oBAAoBC,yBAAyB5D,SAAS,MAAM;AACnEH,iBAAgB;AACf,MAAI2D,uBAAuB;GAC1B,MAAMK,QAAQC,iBAAiB;AAC9BF,0BAAsB,KAAK;MACzB,IAAI;AACP,gBAAaG,aAAaF,MAAM;SAC1B;GAEN,MAAMA,UAAQC,iBAAiB;AAC9BF,0BAAsB,MAAM;MAC1B,GAAG;AACN,gBAAaG,aAAaF,QAAM;;IAE/B,CAACL,sBAAsB,CAAC;CAG3B,MAAMQ,UAAU9D,oBAAoB;CAGpC,MAAM+D,WAAWD,SAASC,YAAY;CACtC,MAAMC,cAAcF,SAASE,sBAAsB;CACnD,MAAMC,YAAYH,SAASG,aAAa;CACxC,MAAMC,WAAWJ,SAASI,mBAAmB;CAC7C,MAAMC,aAAaL,SAASK,qBAAqB;CACjD,MAAMC,eAAeN,SAASzB,YAAY;EAAEgC,GAAG;EAAGC,GAAG;EAAG;CACxD,MAAMC,kBAAkBT,SAASU,sBAAsB;CACvD,MAAMC,gBAAgBX,SAASW,wBAAwB;CAGvD,MAAMC,eAAeZ,SAASY,gBAAgB;CAC9C,MAAMC,kBAAkBb,SAASa,0BAA0B;CAC3D,MAAMC,iBAAiBd,SAASc,yBAAyB;CAEzD,MAAMC,eAAepF,iBAAiB;CACtC,MAAMqF,iBAAiBjF,OAAuB,KAAK;CACnD,MAAMmF,yBAAyBnF,OAA8B,KAAK;CAClE,MAAMsF,sBAAsBtF,OAAO,EAAE;CAGrC,MAAM,EAAEuF,mBAAmBC,mBAAmBpF,kBAAkB;CAGhE,MAAM,EAAEqF,aAAapF,iBAAiB;CAGtC,MAAMqF,UAAUnC,OAAOmC,WAAW,EAAE;CACpC,MAAMC,YAAYpC,OAAOoC;CAGzB,MAAMC,kBAAkBxG,oBAAoB;;;;;;;;CAS5C,MAAMyG,gBAAgBhG,aACpBiG,GAAYC,SAAwE;EACpF,MAAM,EAAEC,QAAQC,aAAaF;EAC7B,MAAMG,eAAeC,KAAKC,KAAKJ,OAAOxB,KAAK,IAAIwB,OAAOvB,KAAK,EAAE;AAO7D,MAAIgB,aAHHvB,aAAa,eAAeA,aAAa,YAAYA,aAAa,aAGvC;GAC3B,MAAMoC,gBAAgB,CAACN,OAAOvB;GAC9B,MAAM8B,gBAAgB,CAACN,SAASxB;GAEhC,MAAM,EAAE+B,UAAU3F;AAOlB,OAJEyF,gBAAgBE,MAAME,eAAeH,gBAAgBC,MAAMG,eAE5DJ,gBAAgBC,MAAMI,uBAEA;AACtBzC,gBAAY,YAAY;AACxBS,mBAAe;AACf;;;AAKF,MAAIsB,gBAAgBrF,eAAegG,uBAClCnC,iBAAgB;GACfF,GAAGD,aAAaC,IAAIwB,OAAOxB;GAC3BC,GAAGF,aAAaE,IAAIuB,OAAOvB;GAC3B,CAAC;IAIJ;EACCF,aAAaC;EACbD,aAAaE;EACbC;EACAe;EACAvB;EACAC;EACAS;EAEF,CAAC;AAGD9E,iBAAgB;EACf,MAAMgH,eAAe9D,UAAU+D,UAAU;AACzC,MAAI7C,aAAa,eAAe4C,eAAexB,oBAAoB0B,QAClE1C,aAAY;AAEbgB,sBAAoB0B,UAAUF;IAC5B;EAAC9D,UAAU+D;EAAQ7C;EAAUI;EAAW,CAAC;AAG5CxE,iBAAgB;AACf,MAAIoE,aAAa,YAChBG,WAAU;IAET,CAACH,UAAUG,SAAS,CAAC;CAGxB,MAAM4C,oBAAoBtF,sBAAsB;CAGhD,MAAMuF,oBAAoB1D,oBAAoBd;CAG9C,MAAMyE,mBAAmBjF,oBACxB,CAAC,CAACiB,eACFC,qBAAqBgE,WAAW,YAC7B,YACAhE,qBAAqBgE,WAAW,UAC/B,UACA,KACJ;CACD,MAAMC,eAAeH,oBAAoBD,oBAAoBE;CAG7D,MAAMG,OAAOvH,cAAwB;AAEpC,MAAImH,kBAAmB,QAAO;AAG9B,MAAIhD,aAAa,YAAa,QAAO;AACrC,MAAIA,aAAa,UAAW,QAAO;AAGnC,MAAIjB,aAAaW,mBAAoB,QAAO;AAG5C,MAAIV,YAAa,QAAO;AAGxB,MAAIgB,aAAa,YAAa,QAAO;AAErC,SAAO;IACL;EAACA;EAAUjB;EAAWC;EAAagE;EAAmBtD;EAAmB,CAAC;CAG7E,MAAM2D,mBAAmB1H,aACvB2H,YAAsB;AACtBrD,cAAYqD,QAAQ;IAErB,CAACrD,YACF,CAAC;CAGD,MAAMsD,iBAAiB5H,kBAAkB;AACxCsE,cAAY,YAAY;IACtB,CAACA,YAAY,CAAC;AAGjBrE,iBAAgB;AACf,MAAIwH,SAAS,eAAeA,SAAS,UACpC1C,gBAAe;IAEd,CAAC0C,MAAM1C,cAAc,CAAC;AAGzB9E,iBAAgB;AACf,MAAI,CAAC8C,aAAc;AAGnB,MAAIuC,uBAAuB6B,SAAS;AACnChD,gBAAamB,uBAAuB6B,QAAQ;AAC5C7B,0BAAuB6B,UAAU;;AAIlC,MAAIM,SAAS,eAAgBA,SAAS,cAAc,CAACrE,UACpDkC,wBAAuB6B,UAAUjD,iBAAiB;AACjDI,eAAY,YAAY;KACtBzD,yBAAyB;AAG7B,eAAa;AACZ,OAAIyE,uBAAuB6B,QAC1BhD,cAAamB,uBAAuB6B,QAAQ;;IAG5C;EAACM;EAAMrE;EAAWL;EAAcuB;EAAY,CAAC;CAGhD,MAAMuD,oBAAoB7H,kBAAkB;AAC3C,MAAIyD,MACH,KAAIA,MAAMqE,YAAYrE,MAAMsE,aAC3BtE,OAAMuE,MAAM;MAEZ,CAAKvE,MAAMwE,OAAO;AAGpBnF,mBAAiB;IACf,CAACW,OAAOX,cAAc,CAAC;CAG1B,MAAMoF,qBAAqBlI,YAC1B,OAAOmI,WAAmB;AAEzB7D,cAAY,YAAY;AAExB,MAAI,CAACwB,UAAW;AAEhB,MAAI;GAKH,MAAMwC,eAHS,MAAMxC,UAAUqC,OAAOE,KAAK,EAGhBlF,UAAUoF,MACnCC,MAA0CA,EAAEC,SAAS,OACtD;AACD,OAAIH,aAAa;IAEhB,IAAIK,cAAc;AAClB,QAAI,OAAOL,YAAYI,YAAY,SAClCC,eAAcL,YAAYI;aAChBJ,YAAYI,QAAQE,SAAS,OACvCD,eAAcL,YAAYI,QAAQG;AAGnC,QAAIF,aAAa;AAEhB5C,qBAAgB+C,QAAQH,YAAY;AACpC5C,qBAAgBgD,MAAM;;;WAGhBC,KAAK;AACblI,YAAS,aAAa,wBAAwBkI,IAAI;;IAGpD;EAAClD;EAAWC;EAAiBzB;EAC9B,CAAC;CAGD,MAAM2E,wBAAwBjJ,aAC5BkJ,WAAmB;AACnB,MAAIrF,iBAAiBqD,SAAS,GAAG;GAChC,MAAMiC,YAAYtF,iBAAiB;GACnC,MAAMuF,UAAUjI,2BAA2B+H,OAAO;AAClD9H,0BAAuB0C,eAAeqF,UAAUE,WAAWF,UAAUG,YAAYF,QAAQ;;IAG3F,CAACvF,kBAAkBC,cACpB,CAAC;CAGD,MAAMyF,eACL9B,SAAS,eAAeA,SAAS,YAC9BvG,mBAAmBsI,OACnBtI,mBAAmBuI;CAGvB,MAAMjD,eAAaiB,SAAS,eAAeA,SAAS,YAAYA,SAAS;CAGzE,MAAM,EAAEiC,UAAUC,kBAAkBhJ,gBAAgB;EACnDiJ,kBAAkB;AACjB,OAAIpD,gBAAc,CAACxB,gBAAgB,CAACqC,kBACnCpC,kBAAiB;;EAGnB4E,iBAAiB;AAChB,OAAI7E,aACHE,iBAAgB;;EAGlB4E,SAASlE,aAAaY,gBAAcxB;EACpC,CAAC;CAIF,MAAM,CAAC+E,iBAAiBC,oBAAoB5J,SAAS,MAAM;AAC3DH,iBAAgB;AACf,MAAIuG,cAAY;GACf,MAAMvC,UAAQC,iBAAiB8F,iBAAiB,KAAK,EAAE,IAAI;AAC3D,gBAAa;AACZ7F,iBAAaF,QAAM;AACnB+F,qBAAiB,MAAM;;QAGxBA,kBAAiB,MAAM;IAEtB,CAACxD,aAAW,CAAC;AAGhBvG,iBAAgB;AACf,MAAI,CAAC+E,aAAc;EAEnB,MAAMiF,iBAAiBC,MAAqB;AAC3C,OAAIA,EAAEE,QAAQ,UAAU;AACvBF,MAAEG,gBAAgB;AAClBnF,oBAAgB;;;AAIlBoF,SAAOC,iBAAiB,WAAWN,cAAc;AACjD,eAAaK,OAAOE,oBAAoB,WAAWP,cAAc;IAC/D,CAACjF,cAAcE,eAAe,CAAC;AAElC,QACC,4CAEC,oBAAC;EAAI,KAAKE;EAAgB,WAAU;GAAmC,EAEvE,oBAAC,gBAAgB;EAChB,WAAW/D,GACV,sDACAsB,aAAa,mBAAmB,6BAChCA,aAAa,kBAAkB,WAC/BK,UACA;YAED,qBAAC,OAAO;GAEP,MAAMwD;GACQrB;GACd,iBAAiBC;GACjB,aAAa;GACb,cAAc;GAEd,WAAW;IAAEqF,OAAO;IAAMC,SAAS3J,aAAa4J;IAAU;GAC1D,WAAW3E;GAIX,SAAS;GACT,SAAS;IACRrB,GAAG6B,eAAcd,oBAAoB,IAAIhB,aAAaC,IAAK;IAC3DC,GAAG4B,eACAd,oBACC,CAACC,iBAAiB1E,kBAClByD,aAAaE,IACd;IACH;GACD,YAAY;IAAEgE,MAAM;IAAUgC,WAAW;IAAKC,SAAS;IAAI;GAC3D,WAAWxJ,GAAG,YAAYmF,gBAAc,qCAAqC;GAE7E,OAAO,EAAEsE,aAAatE,gBAAcxB,eAAe,SAAS,QAAQ;GAEpE,GAAI2E;;IAIHlC,SAAS,eAAe5B,QAAQqB,SAAS,KACzC,oBAAC;KAAI,WAAU;eACd,oBAAC;MAAqBrB;MAAS,UAAUqC;OAAmB;MAE7D;IAGAT,SAAS,eAAelD,aACxB,oBAAC,OAAO;KACP,SAAS,EAAEkG,OAAO,GAAG;KACrB,SAAS,EAAEA,OAAO,GAAG;KACrB,WAAU;MAEX;IAED,oBAAC;KAAiB,QAAQjD;KAA4B+B;eACrD,qBAAC;MAAoB9B;MAAM,cAAcC;MAAgC1C;;QAEtEqC,qBAAqBb,iBACtB,qBAAC;QAAI,WAAU;mBAEd,oBAAC;SACA,WAAU;SACV,gBAAgB0D,QAAM/E,aAAa8C,MAAMiC,IAAE;SAC3C,cAAYtJ,YAAYmK;SACxB,MAAK;SACL,UAAU;mBAEV,oBAAC,kBAAe,WAAU,0BAAuB;UAC7C,EAGL,qBAAC;SAAI,WAAU;;UAEb,CAACnF,YAAY,CAACyB,qBACd,oBAAC;WACA,MAAK;WACL,SAASrC,eAAeE,iBAAiBD;WACzC,WAAW5D,GACV,mBACA,oCACA,oBACA,wCACA,qCACA,iCACA;WACD,cACC2D,eACGpE,YAAYoK,qBACZpK,YAAYqK;qBAGfjG,eACA,oBAAC,YAAS,WAAU,gBAAgB,GAEpC,oBAAC,UAAO,WAAU,gBAClB;YAEF;UAGD,oBAAC,0BAAqB;UAGtB,oBAAC;WACA,MAAK;WACL,SACCqC,oBACGQ,oBACA7C,eACCE,iBACA0C;WAEL,WAAWvG,GAEV,2CACA,oCACA,2BACA,wCACA,qCACA,iCACA;WACD,cACCgG,oBACGzG,YAAYsK,kBACZlG,eACCpE,YAAYoK,qBACZpK,YAAYuK;qBAGjB,oBAAC,KAAE,WAAU,8BAA2B;YACjC;;UACJ;SAEN;OAGA,CAACnG,gBACD,oBAAC;QAAgB,MAAK;kBACpBqC,qBAAqB,oBAAC,aAA2B,OAAOQ,qBAApB,aAAyC;SAE/E;OAGA,CAACR,qBACD,qBAAC;QAAI,WAAU;;SAEbI,SAAS,eAAe,CAACpE,eAAe,oBAAC,mBAAiB;SAG1DoE,SAAS,cAAc,CAACrE,aAAaI,WACrC,oBAAC;UACSA;UACT,WAAW,CAACD,qBAAqB6H;UACnBpG;WAEf;SAGD,oBAAC,8BACEyC,SAAS,YAAYA,SAAS,eAAerE,aAC9C,oBAAC,OAAO;UAEP,SAAS,EAAEsH,SAAS,GAAG;UACvB,SAAS,EAAEA,SAAS,GAAG;UACvB,MAAM,EAAEA,SAAS,GAAG;UACpB,YAAY,EAAEW,UAAU,IAAK;oBAE7B,oBAAC,qBAAgCrG,eAAa;YAN1C,YAQL,GACe;SAGhByC,SAAS,cAAc,CAACrE,aAAa,CAACI,WAAW,oBAAC,kBAAgB;SAGnE,oBAAC,8BACEiE,SAAS,YAAYA,SAAS,eAC/B,oBAAC,OAAO;UAEP,SAAS,EAAEiD,SAAS,GAAG;UACvB,SAAS,EAAEA,SAAS,GAAG;UACvB,MAAM,EAAEA,SAAS,GAAG;UACpB,YAAY,EAAEW,UAAU,IAAK;oBAE7B,oBAAC;WACA,kBAAkB5D,SAAS,YAAY,CAACzC;WAC1BA;WACd,gBAAgBjB;YAAmB;YAThC,QAYL,GACe;SAGjB,oBAAC,8BACE0D,SAAS,YAAYA,SAAS,eAAe1D,sBAC9C,oBAAC,OAAO;UAEP,SAAS,EAAE2G,SAAS,GAAG;UACvB,SAAS,EAAEA,SAAS,GAAG;UACvB,MAAM,EAAEA,SAAS,GAAG;UACpB,YAAY,EAAEW,UAAU,IAAK;oBAE7B,oBAAC,yBAAoB;YANjB,cAQL,GACe;SAGhB,CAACrG,iBACAyC,SAAS,eAAeA,SAAS,eAClC,CAACrE,aACD,CAACW,sBACD8B,QAAQqB,SAAS,KAChB,oBAAC;UAA2BrB;UAAS,UAAUqC;WAC/C;SAGF,oBAAC,8BACET,SAAS,YAAYA,SAAS,eAC/BrE,aACA,CAACW,sBACA,oBAAC,OAAO;UAEP,SAAS,EAAE2G,SAAS,GAAG;UACvB,SAAS,EAAEA,SAAS,GAAG;UACvB,MAAM,EAAEA,SAAS,GAAG;UACpB,YAAY,EAAEW,UAAU,IAAK;oBAE7B,oBAAC,sBAAiB;YANd,WAQL,GACc;SAGjB,oBAAC,6BACCtB,oBACCtC,SAAS,eAAeA,SAAS,YAAYA,SAAS,eACtD,oBAAC,OAAO;UACP,SAAS,EAAEiD,SAAS,GAAG;UACvB,SAAS,EAAEA,SAAS,GAAG;UACvB,MAAM,EAAEA,SAAS,GAAG;UACpB,YAAY,EAAEW,UAAU,KAAM;UAC9B,WAAU;oBAEV,oBAAC;WACA,iBAAiBzI,mBAAmB,CAAC,CAACa,OAAO6H;WAC9BzI;WACf,eAAegF;WACf,aAAa9D;WACb,qBAAqBkF;YAAsB;WAG7C,GACc;;SAElB;;OACa;MACE;;IACP;GACS,IACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxoBL,MAAamD,cAAkCC,OAAA;CAAA,MAAAC,IAAAd,EAAA,GAAA;CAAC,MAAA,EAAAQ,UAAAC,QAAAC,WAAAC,MAAAI,OAAAF;CAA+B,MAAAF,OAAAI,OAAAC,SAAA,SAAAD;CAC9E,MAAAE,UAAgBf,OAAuB,KAAK;CAC5C,MAAA,CAAAgB,iBAAAC,sBAA8ChB,SAAyB,KAAK;CAAA,IAAAiB;CAAA,IAAAC;AAAA,KAAAP,EAAA,OAAAH,QAAAG,EAAA,OAAAL,QAAA;AAElEW,aAAA;GACT,MAAAE,OAAaL,QAAOM;AACpB,OAAI,CAACD,KAAI;GAGT,IAAAE,SAAaF,KAAIG;AACjB,OAAI,CAACD,OACJA,UAASF,KAAII,aAAc,EAAAf,MAAQ,CAAC;GAqBrC,IAAAgB,eAAmBH,OAAMI,cAAe,4BAA4B;AACpE,OAAI,CAACD,cAAY;AAChBA,mBAAeE,SAAQC,cAAe,QAAQ;AAC9CH,iBAAYI,aAAc,sBAAsB,GAAG;AACnDP,WAAMQ,aAAcL,cAAcH,OAAMS,WAAY;;AAGrDN,gBAAYO,cApBO,wOAoBqBzB;GAGxC,IAAA0B,YAAgBX,OAAMI,cAAe,0BAA0B;AAC/D,OAAI,CAACO,WAAS;AACbA,gBAAYN,SAAQC,cAAe,MAAM;AACzCK,cAASJ,aAAc,yBAAyB,GAAG;AACnDP,WAAMY,YAAaD,UAAU;;AAG9BhB,sBAAmBgB,UAAU;;AAC3Bd,OAAA,CAACV,MAAMF,OAAO;AAAAK,IAAA,KAAAH;AAAAG,IAAA,KAAAL;AAAAK,IAAA,KAAAM;AAAAN,IAAA,KAAAO;QAAA;AAAAD,OAAAN,EAAA;AAAAO,OAAAP,EAAA;;AA9CjBb,WAAUmB,IA8CPC,GAAe;CAAA,IAAAgB;AAAA,KAAAvB,EAAA,OAAAN,YAAAM,EAAA,OAAAI,iBAAA;AAIfmB,OAAAnB,mBAAmBd,aAAaI,UAAUU,gBAAgB;AAAAJ,IAAA,KAAAN;AAAAM,IAAA,KAAAI;AAAAJ,IAAA,KAAAuB;OAAAA,MAAAvB,EAAA;CAAA,IAAAwB;AAAA,KAAAxB,EAAA,OAAAJ,aAAAI,EAAA,OAAAuB,IAAA;AAD5DC,OAAA,oBAAA;GAAUrB,KAAAA;GAAoBP;aAC5B2B;IACI;AAAAvB,IAAA,KAAAJ;AAAAI,IAAA,KAAAuB;AAAAvB,IAAA,KAAAwB;OAAAA,MAAAxB,EAAA;AAAA,QAFNwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC4BF,MAAMsC,gBAAsCC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAvB,UAAAC,SAAAC,eAAAO,cAAAE,gBAAAC,sBAAAS;CAS5C,MAAAG,kBAAwBvB,WAAAZ;CAIvB,MAAAoC,UAAgB,GAAGD,gBAAe;CAAW,IAAAE;AAAA,KAAAJ,EAAA,OAAAG,SAAA;AACtCC,OAAA,IAAI1C,uBAAuB,EAAA2C,KAAOF,SAAS,CAAC;AAAAH,IAAA,KAAAG;AAAAH,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAFpD,MAAAM,YAECF;CACoB,IAAAG;AAAA,KAAAP,EAAA,OAAAM,WAAA;AAEUC,OAAA;GAAAD;GAAAE,uBAEPC;GAGvB;AAAAT,IAAA,KAAAM;AAAAN,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CALD,MAAAU,UAAgB/C,eAAe4C,GAK7B;CAGF,MAAAI,wBAA8B/B,iBAAA,GAAoBsB,gBAAe;CAAuB,IAAAU;AAAA,KAAAZ,EAAA,OAAAa,OAAAC,IAAA,4BAAA,EAAA;AAUrFF,OAAA,oBAAC,oBAAkB;AAAAZ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAe;AAAA,KAAAf,EAAA,OAAAtB,YAAAsB,EAAA,OAAAX,kBAAAW,EAAA,OAAAV,qBAAAU,EAAA,OAAAb,gBAAAa,EAAA,OAAAW,uBAAA;AANpBI,OAAA,qBAAC;GACeJ,eAAAA;GACNxB,SAAAA;GACEE,WAAAA;GACGC,cAAAA;cAEdsB,IACClC;IACkB;AAAAsB,IAAA,KAAAtB;AAAAsB,IAAA,KAAAX;AAAAW,IAAA,KAAAV;AAAAU,IAAA,KAAAb;AAAAa,IAAA,KAAAW;AAAAX,IAAA,MAAAe;OAAAA,MAAAf,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,QAAAU,WAAAV,EAAA,QAAAe,IAAA;AATrBC,OAAA,oBAAC;GAAkCN;aAClCK;IAS0B;AAAAf,IAAA,MAAAU;AAAAV,IAAA,MAAAe;AAAAf,IAAA,MAAAgB;OAAAA,MAAAhB,EAAA;AAAA,QAV3BgB;;;;;;;;;;;;;;;;AA4BF,MAAaC,iBAAwClB,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAvB,UAAAC,SAAAC,eAAAC,kBAAAuB,IAAAtB,aAAAyB,IAAAxB,aAAA6B,IAAA5B,qBAAAC,eAAAE,cAAAE,gBAAAC,mBAAAE,cAAAE,cAAAE,yBAAAG;CAIrD,MAAAlB,mBAAAuB,OAAAc,SAAA,OAAAd;CACA,MAAAtB,cAAAyB,OAAAW,SAAA,QAAAX;CACA,MAAAxB,cAAA6B,OAAAM,SAAA,cAAAN;CAAyB,IAAAG;AAAA,KAAAf,EAAA,OAAArB,WAAAqB,EAAA,OAAAtB,YAAAsB,EAAA,OAAAX,kBAAAW,EAAA,OAAAV,qBAAAU,EAAA,OAAAb,gBAAAa,EAAA,OAAApB,eAAA;AAmBrBmC,OAAA,oBAAC;GACSpC;GACMC;GACDO;GACEE;GACGC;GAElBZ;IACa;AAAAsB,IAAA,KAAArB;AAAAqB,IAAA,KAAAtB;AAAAsB,IAAA,KAAAX;AAAAW,IAAA,KAAAV;AAAAU,IAAA,KAAAb;AAAAa,IAAA,KAAApB;AAAAoB,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,OAAAnB,oBAAAmB,EAAA,OAAAf,iBAAAe,EAAA,OAAAe,IAAA;AAThBC,OAAA,oBAAC;GAAmCnC;GAAiCI;aACpE8B;IASkB;AAAAf,IAAA,KAAAnB;AAAAmB,IAAA,KAAAf;AAAAe,IAAA,KAAAe;AAAAf,IAAA,MAAAgB;OAAAA,MAAAhB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAhB,uBAAAgB,EAAA,QAAAJ,wBAAAI,EAAA,QAAAgB,IAAA;AAXpBG,OAAA,oBAAC;GAAkCnC,aAAAA;GAAmCY,cAAAA;aACrEoB;IAWsB;AAAAhB,IAAA,MAAAhB;AAAAgB,IAAA,MAAAJ;AAAAI,IAAA,MAAAgB;AAAAhB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAjB,eAAAiB,EAAA,QAAAlB,eAAAkB,EAAA,QAAAN,gBAAAM,EAAA,QAAAR,gBAAAQ,EAAA,QAAAmB,IAAA;AAlBxBC,OAAA,oBAAC;GACatC;GACAC;GACCS;GACAE;aAEdyB;IAaiB;AAAAnB,IAAA,MAAAjB;AAAAiB,IAAA,MAAAlB;AAAAkB,IAAA,MAAAN;AAAAM,IAAA,MAAAR;AAAAQ,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;AAAA,QAnBlBoB;;AAzE0C,SAAAX,MAAAY,UAAA;AAAA,QAoBlCzD,4CAA4CyD,SAAS;;;;;;;;;;;;;;;;ACtI/D,MAAaC,gBAAgB;;;;;;;;;;AAW7B,MAAaC,uBAAuB;;;;;;;;AASpC,SAAgBC,eAAqB;AACpC,KAAI,OAAOC,aAAa,YAAa;CAErC,MAAMC,UAAU;AAChB,KAAID,SAASE,eAAeD,QAAQ,CAAE;CAEtC,MAAME,QAAQH,SAASI,cAAc,QAAQ;AAC7CD,OAAME,KAAKJ;AACXE,OAAMG,cAAcT;AACpBG,UAASO,KAAKC,YAAYL,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACgBjC,MAAMe,qBAAqBC,gBAAkC;AAC5D,KAAIA,eAAe,OAAOC,WAAW,YACpC,QAAOA,OAAOC,SAASC;AAExB,QAAON;;;;;;;;;;;;;AA0DR,MAAac,iBAAwCC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAN,OAAAC,SAAAC,kBAAAK,OAAAH;CAGrD,MAAAF,mBAAAK,OAAAC,SAAA,QAAAD;CAAwB,IAAAE;AAAA,KAAAJ,EAAA,OAAAL,SAAAK,EAAA,OAAAJ,WAAAI,EAAA,OAAAH,kBAAA;AAGxBO,YAAgBlB,kBAAkBU,SAAOT,YAAc;AAGvD,MAAI,OAAOC,WAAW,YACrBiB,SAAOC,MAAO,wBAAwB;GAAAX;GAAAY,MAE/BX,UAAA,gBAAA;GAAsCQ;GAAAI,WAEjC,CAACX;GACZ,CAAC;AACFG,IAAA,KAAAL;AAAAK,IAAA,KAAAJ;AAAAI,IAAA,KAAAH;AAAAG,IAAA,KAAAI;OAAAA,WAAAJ,EAAA;AAID,KAAIH,iBACHf,eAAc;CAIf,MAAA2B,eAAqB,CAACb,WAAD,CAAa,CAACA,QAAOH;CAMzB,MAAAiB,KAAAD,eAAA,GAAkBL,QAAO,yBAAzBD;CAA4D,IAAAQ;AAAA,KAAAX,EAAA,OAAAS,cAAA;AAG3EE,OAAA,oBAAC;GAAmB,UAAA;GAAiCF,iBAAAA;IAAgB;AAAAT,IAAA,KAAAS;AAAAT,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAI,WAAAJ,EAAA,OAAAU,MAAAV,EAAA,OAAAW,IAAA;AALtEC,OAAA,oBAAC;GACSR;GACM,eAAAM;GACG,kBAAA;aAElBC;IACe;AAAAX,IAAA,KAAAI;AAAAJ,IAAA,KAAAU;AAAAV,IAAA,KAAAW;AAAAX,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAPjB,MAAAa,eACCD;AAUD,KAAI,CAACf,kBAAgB;EAAA,IAAAiB;AAAA,MAAAd,EAAA,QAAAa,cAAA;AACbC,QAAA,oBAAC;IAAmB/B,QAAAA;cAAuB8B;KAA0B;AAAAb,KAAA,MAAAa;AAAAb,KAAA,MAAAc;QAAAA,MAAAd,EAAA;AAAA,SAArEc;;AACP,QAGMD;;;;;;;;AASR,MAAME,qBAAqBrC,KAAKoB,eAAwD,EACvFmB,OAAO;CACNtB,OAAO;CAGPC,SAAS;CAGTC,kBAAkB;CACnB,EACA,CAAC;;;;;;;;;;;;;;AAeF,SAAgBqB,oBAAoBC,UAAU,gBAAsB;AACnE,KAAI,OAAO/B,WAAW,YAAa;AAMnC,KAAI,CAACgC,eAAeC,IAAIF,QAAQ,CAC/BC,gBAAeE,OAAOH,SAASJ,mBAAmB;;AAKpDG,qBAAqB"}
|
|
1
|
+
{"version":3,"file":"web-component.js","names":["clsx","twMerge","ClassValue","cn","inputs","c","_c","React","TooltipPrimitive","cn","TooltipProvider","t0","$","props","t1","delayDuration","undefined","t2","Tooltip","TooltipTrigger","TooltipContent","children","className","sideOffset","t3","Symbol","for","t4","c","_c","React","DialogPrimitive","XIcon","cn","Dialog","t0","$","props","t1","DialogTrigger","DialogPortal","DialogClose","DialogOverlay","className","t2","DialogContent","children","showCloseButton","undefined","Symbol","for","t3","t4","t5","DialogHeader","DialogFooter","DialogTitle","DialogDescription","c","_c","React","AvatarPrimitive","cn","Avatar","t0","$","className","props","t1","t2","AvatarImage","AvatarFallback","React","Slot","cva","VariantProps","cn","buttonVariants","variants","variant","default","destructive","outline","secondary","ghost","link","size","sm","lg","icon","defaultVariants","Button","t0","$","_c","className","props","t1","t2","t3","asChild","undefined","Comp","t4","t5","c","_c","forwardRef","ComponentPropsWithRef","Slottable","Tooltip","TooltipContent","TooltipTrigger","Button","cn","TooltipIconButtonProps","tooltip","side","TooltipIconButton","HTMLButtonElement","t0","ref","$","children","className","rest","t1","undefined","t2","t3","t4","t5","t6","t7","displayName","c","_c","useEffect","useState","FC","PropsWithChildren","XIcon","PlusIcon","FileText","AttachmentPrimitive","ComposerPrimitive","MessagePrimitive","useAssistantState","useAssistantApi","useShallow","Tooltip","TooltipContent","TooltipTrigger","Dialog","DialogTitle","DialogContent","DialogTrigger","Avatar","AvatarImage","AvatarFallback","TooltipIconButton","cn","useFileSrc","file","$","src","setSrc","undefined","t0","t1","objectUrl","URL","createObjectURL","revokeObjectURL","useAttachmentSrc","src_0","_temp2","AttachmentPreviewProps","AttachmentPreview","isLoaded","setIsLoaded","t2","Symbol","for","t3","AttachmentPreviewDialog","children","t4","AttachmentThumb","isImage","_temp3","AttachmentUI","api","isComposer","attachment","source","_temp4","typeLabel","_temp5","t5","t6","t7","t8","t9","t10","AttachmentRemove","UserMessageAttachments","Attachment","ComposerAttachments","ComposerAddAttachment","_temp","type","content","filter","image","attachment_0","_exhaustiveCheck","Error","c","_c","CodeHeaderProps","MarkdownTextPrimitive","unstable_memoizeMarkdownComponents","memoizeMarkdownComponents","useIsMarkdownCodeBlock","remarkGfm","FC","memo","useState","CheckIcon","CopyIcon","TooltipIconButton","cn","MarkdownTextImpl","$","t0","Symbol","for","defaultComponents","MarkdownText","CodeHeader","language","code","isCopied","copyToClipboard","useCopyToClipboard","t1","onCopy","t2","t3","t4","t5","t6","undefined","copiedDuration","setIsCopied","value","navigator","clipboard","writeText","then","setTimeout","h1","className","props","h2","h3","h4","h5","h6","p","a","blockquote","ul","ol","hr","table","th","td","tr","sup","pre","Code","isCodeBlock","useLayoutEffect","Slot","React2","Collapsible","CollapsibleTrigger","CollapsibleContent","c","_c","CollapsiblePrimitive","Collapsible","t0","$","props","t1","CollapsibleTrigger","CollapsibleContent","c","_c","BrainIcon","ChevronDownIcon","memo","useCallback","useRef","useState","FC","PropsWithChildren","useScrollLock","useAssistantState","ReasoningMessagePartComponent","ReasoningGroupComponent","MarkdownText","Collapsible","CollapsibleContent","CollapsibleTrigger","cn","ANIMATION_DURATION","ReasoningRoot","className","t0","$","children","collapsibleRef","isOpen","setIsOpen","lockScroll","t1","open","handleOpenChange","t2","t3","Symbol","for","t4","React","CSSProperties","displayName","GradientFade","ReasoningTrigger","active","t5","t6","t7","ReasoningContent","ariaBusy","ReasoningText","ReasoningImpl","ReasoningGroupImpl","startIndex","endIndex","message","status","type","lastIndex","parts","length","lastType","isReasoningStreaming","Reasoning","ReasoningGroup","useEffect","useState","useDelayedState","value","delay","$","_c","delayedValue","setDelayedValue","t0","t1","timer","setTimeout","clearTimeout","GESTURE_CONFIG","dragActivationDistance","swipe","minDistance","minVelocity","velocityOnlyThreshold","const","PILL_CONTAINER_SIZES","collapsed","width","min","vw","max","height","hovered","composing","active","expanded","clampSize","config","AUTO_COLLAPSE_TIMEOUT_MS","COMPOSER_MAX_CHARS","PILL_BORDER_RADIUS","pill","rounded","inner","small","PILL_SPACING","xs","sm","md","lg","xl","PILL_MAX_HEIGHTS","tools","mobile","desktop","summary","composer","MAX_PROMPT_BUBBLES","UI_TIMING","hoverDebounce","collapseDelay","copyFeedback","KEYBOARD_VISIBILITY_THRESHOLD_PX","KEYBOARD_GAP_PX","DRAG_OPACITY","dragging","normal","FULL_SCREEN_CONFIG","maxWidth","widthPercent","heightPercent","padding","PINCH_GESTURE_CONFIG","threshold","minInitialDistance","ARIA_IDS","pillTitle","pillDescription","liveRegion","ARIA_LABELS","openAssistant","closeAssistant","endVoiceSession","dragHandle","sendMessage","voiceInput","expandFullScreen","collapseFullScreen","WEBMCP_PRODUCTION_API_BASE","MCP_MAX_RECONNECT_ATTEMPTS","MCP_BASE_RECONNECT_DELAY_MS","MCP_MAX_RECONNECT_DELAY_MS","MCP_TAB_CONNECT_DELAY_MS","AUDIO_FREQUENCY_BINS","REALTIME_DEFAULT_MODEL","REALTIME_DEFAULT_VOICE","REALTIME_DEFAULT_API_URL","AUDIO_VISUALIZATION_INTERVAL_MS","RESPONSE_REQUEST_DELAY_MS","TOOL_CALL_DISPLAY_DURATION_MS","TOOL_CALL_ERROR_DISPLAY_DURATION_MS","VOICE_ACTIONS_RETENTION_MS","VOICE_SUMMARY_RETENTION_MS","VOICE_APPROVAL_TIMEOUT_MS","VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS","VOICE_APPROVAL_KEYWORDS","approve","deny","VOICE_TOOL_RESULT_MESSAGES","handled","sessionEnded","WAVEFORM_HISTORY_SIZE","WAVEFORM_UPDATE_RATE_MS","WEBSOCKET_OPEN","DEBUG_LOGGING_ENABLED","window","__WEBMCP_DEBUG__","debugLog","component","message","data","isDebugEnabled","undefined","console","log","TabClientTransport","SSEClientTransport","StreamableHTTPClientTransport","MCPSourceConfig","Transport","TransportType","createMCPTransport","config","transportType","type","targetOrigin","window","location","origin","channelId","serverUrl","URL","url","headers","Record","Accept","customHeaders","authToken","Authorization","transportOptions","requestInit","shouldFallbackToSSE","error","Error","message","includes","calculateReconnectDelay","attempt","baseDelay","maxDelay","Math","min","pow","SOURCE_ID_RE","parseSourceScopedToolName","name","sourceId","toolName","separatorIndex","indexOf","slice","test","stripSourceScopedToolName","Client","PromptListChangedNotificationSchema","ToolListChangedNotificationSchema","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","MCP_TAB_CONNECT_DELAY_MS","createMCPTransport","stripSourceScopedToolName","CallToolResult","GetPromptResult","MCPSource","MCPSourceConfig","Prompt","Resource","ResourceTemplate","ToolWithSource","Transport","ReactNode","SOURCE_LOCAL","SOURCE_REMOTE","SourceState","Omit","client","transport","resources","resourceTemplates","prompts","InflightToolCall","toolName","sourceId","abortController","AbortController","MCPToolsContextValue","tools","sources","Map","addSource","id","config","Promise","removeSource","getSource","isConnected","callTool","name","args","Record","callToolOnSource","getPrompt","refreshTools","MCPToolsContext","MCPToolsProviderProps","children","autoConnectLocal","onToolsChange","onPromptsChange","MCPToolsProvider","sourcesRef","inflightCallsRef","callIdCounterRef","forceUpdate","toolsList","setToolsList","promptsList","setPromptsList","abortOrphanedCalls","currentTools","currentToolNames","Set","map","t","current","forEach","call","callId","has","console","warn","abort","Error","delete","rebuildTools","allTools","source","tool","push","_sourceId","rebuildPrompts","allPrompts","prompt","getPublicSource","state","error","sourceState","set","version","connect","listTools","listPrompts","err","setNotificationHandler","updated","String","get","close","undefined","abortPromise","_","reject","signal","aborted","reason","addEventListener","once","result","race","arguments","content","type","const","text","message","isError","find","stripped","values","hasPrompt","some","p","debug","length","publicSources","timer","setTimeout","clearTimeout","inflightCalls","clear","catch","value","useMCPTools","context","useOptionalMCPTools","Tool","isToolDestructive","annotations","readOnlyHint","destructiveHint","createContext","useCallback","useContext","useEffect","useMemo","useState","Tool","ToolApprovalMode","ToolApprovalSettings","ReactNode","isToolDestructive","STORAGE_KEY","DEFAULT_MODE","ToolApprovalContextValue","setMode","mode","toggleMode","requiresApproval","tool","isDestructive","ToolApprovalContext","ToolApprovalProviderProps","children","defaultMode","disablePersistence","onModeChange","ToolApprovalProvider","setModeState","stored","localStorage","getItem","setItem","newMode","annotations","value","useToolApproval","context","Error","useOptionalToolApproval","createContext","useCallback","useContext","useMemo","FC","ReactNode","ToolWithSource","ToolExclusionFilter","toolName","tool","ToolExclusionContextValue","shouldExclude","filterTools","tools","ToolExclusionContext","ToolExclusionProviderProps","children","exclude","excludeNames","excludePrefixes","ToolExclusionProvider","t0","$","_c","t1","name","includes","some","prefix","startsWith","t2","filter","tool_0","t3","value","t4","useToolExclusion","context","Error","useOptionalToolExclusion","useAssistantTool","ToolResponse","memo","useMemo","useMCPTools","useOptionalToolApproval","useOptionalToolExclusion","CallToolResult","ToolCallMetadata","ToolWithSource","ReadonlyJSONValue","FC","formatToolResult","result","textContent","content","map","c","type","text","JSON","stringify","join","ToolBridge","tool","callTool","name","args","Record","Promise","t0","$","_c","t1","description","t2","inputSchema","t3","t4","_sourceId","startedAt","Date","now","isError","wasAborted","some","_temp","metadata_0","duration","sourceId","artifact","metadata","t5","error","console","Error","message","String","toolName","parameters","execute","DestructiveToolBridge","MCPToolRegistry","tools","toolApproval","toolExclusion","bb0","debug","_temp2","filtered","filterTools","excluded","filter","t_0","includes","t","length","_temp3","_temp4","visibleTools","needsApproval","requiresApproval","t_1","t_2","createContext","useContext","CallToolResult","ToolWithSource","FC","ReactNode","ToolExecutionContextValue","executeTool","toolName","args","Record","Promise","getToolMetadata","description","annotations","ToolExecutionContext","ToolExecutionProviderProps","value","children","ToolExecutionProvider","t0","$","_c","t1","useToolExecution","context","Error","useOptionalToolExecution","stripSourceScopedToolName","humanizeToolName","name","progressive","normalizedName","words","replace","toLowerCase","split","length","verb","progressiveVerb","endsWith","slice","charAt","toUpperCase","join","formatArgs","args","Record","entries","Object","map","key","value","displayValue","JSON","stringify","TOOL_DENIED_MESSAGE","formatToolDenialWithReason","reason","c","_c","useThread","Camera","FileText","Loader2","MousePointer","Navigation","PenLine","Search","Trash2","Wrench","useMemo","humanizeToolName","stripSourceScopedToolName","cn","LucideIcon","FC","getToolIcon","toolName","name","toLowerCase","includes","ActivityState","type","label","icon","toolNames","streamingText","useActivityState","$","messages","_temp","isRunning","_temp2","t0","bb0","lastAssistantMessage","reverse","find","_temp3","t1","Symbol","for","runningToolNames","lastText","part","content","toolPart","status","push","textPart","text","length","t2","m","role","thread_0","thread","ActivityIndicatorProps","className","ActivityIndicator","activity","Icon","isSpinning","t3","t4","t5","t6","slice","map","_temp4","t7","i","ToolIcon","c","_c","AlertCircle","AlertTriangle","Check","ChevronDownIcon","ChevronUpIcon","X","useCallback","useMemo","useState","ToolResponse","useDelayedState","useMCPTools","formatToolResult","useOptionalToolApproval","useOptionalToolExecution","cn","formatArgs","humanizeToolName","TOOL_DENIED_MESSAGE","isToolDestructive","stripSourceScopedToolName","getToolIcon","ToolCallMessagePartComponent","ApprovedResult","approved","result","isApprovedResult","isDeniedResult","hasStatusError","status","type","error","RunningToolDisplay","React","FC","toolName","t0","$","t1","ToolIcon","t2","t3","t4","t5","ApprovalDialog","toolDescription","inputArgs","Record","onApprove","onDeny","isExecuting","isHovered","setIsHovered","Symbol","for","t6","t7","t8","t9","t10","Object","keys","length","t11","t12","t13","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","t24","t25","CompletedToolDisplay","argsText","isExpanded","setIsExpanded","undefined","JSON","stringify","ErrorToolDisplay","DeniedToolDisplay","UnifiedToolFallback","toolCallId","_toolCallId","args","addResult","callTool","tools","toolApproval","toolExecution","setIsExecuting","parsedArgs","parse","e","console","warn","strippedToolName","toolMetadata","getToolMetadata","localTool","find","t","name","description","toolAnnotations","annotations","requiresApproval","mode","executeTool","handleApprove","toolResult","resultText","isError","errorMessage","Error","message","String","handleDeny","statusType","isPendingApproval","showApprovalDialog","displayResult","useCallback","useOptionalMCPTools","GetPromptResult","Prompt","UsePromptsResult","prompts","hasPrompts","getPrompt","name","args","Record","Promise","usePrompts","$","_c","mcpTools","t0","length","t1","Error","t2","createContext","useContext","ThreadToolSelection","ToolSourceInfo","FC","ReactNode","ToolSelectionContextValue","sources","selection","setSelection","Promise","currentSourceId","ToolSelectionContext","ToolSelectionProviderProps","value","children","ToolSelectionProvider","t0","$","_c","t1","useToolSelection","context","Error","useOptionalToolSelection","ThreadAssistantMessage","ThreadRuntime","PendingToolCallInfo","messageId","toolCallId","toolName","args","Record","getPendingToolCalls","threadRuntime","messages","getState","result","msg","role","assistantMsg","status","type","part","content","undefined","push","id","getPendingToolCallsByName","filter","tc","resolvePendingToolCall","messageRuntime","getMessageById","messageState","hasPendingPart","some","partRuntime","getMessagePartByToolCallId","addToolResult","error","Error","message","resolveAllPendingToolCallsByName","pendingCalls","resolved","call","resolveAllPendingToolCalls","debugLog","AudioAnalyzer","audioContext","AudioContext","analyser","AnalyserNode","source","MediaStreamAudioSourceNode","dataArray","Uint8Array","ArrayBuffer","animationId","initialize","stream","MediaStream","Promise","audioTracks","getAudioTracks","streamId","id","length","trackInfo","map","t","label","enabled","muted","readyState","state","resume","err","console","warn","createAnalyser","fftSize","smoothingTimeConstant","createMediaStreamSource","connect","bufferLength","frequencyBinCount","sampleRate","contextState","getAudioLevel","getByteFrequencyData","sum","i","average","Math","min","getFrequencyData","bins","Array","fill","result","samplesPerBin","floor","j","push","startAnalysis","callback","level","frequencies","analyze","requestAnimationFrame","stopAnalysis","cancelAnimationFrame","destroy","disconnect","close","EventCallback","IEventEmitter","EventEmitter","listeners","Map","Set","on","event","callback","has","set","get","add","off","delete","emit","data","forEach","error","console","removeAllListeners","clear","listenerCount","size","RESPONSE_REQUEST_DELAY_MS","EventEmitter","ToolManager","FunctionCall","RealtimeMessage","ResponseOutputItem","type","status","name","call_id","arguments","isCompletedFunctionCall","item","MessageHandler","isProcessingResponse","pendingFunctionCalls","Set","responseRequestTimer","ReturnType","setTimeout","hasRequestedResponse","constructor","toolManager","eventEmitter","handleMessage","data","dataChannel","RTCDataChannel","Promise","msg","JSON","parse","error","console","log","handleResponseCreated","handleResponseDone","handleFunctionCallArguments","handleSpeechEvents","handleAudioEvents","handleTranscriptEvents","handleUserTranscript","handleError","handleSessionEvents","_msg","outputItems","extractResponseOutput","response","hasFunctionCalls","some","length","functionCalls","filter","map","functionCall","has","add","executeFunctionCall","warn","size","requestResponseIfNeeded","r","Record","Array","isArray","output","eventType","emit","hasAudio","delta","eventMap","transcript","text","session","tools","toolCount","toolNames","slice","t","hasOutputTranscription","output_audio_transcription","hasInputTranscription","input_audio_transcription","clearTimeout","result","executeToolCall","readyState","stringify","success","send","undefined","sendToolError","String","delete","errorResponse","reset","clear","jsonrepair","FunctionCall","OpenAITool","ToolExecutionResult","RegisteredTool","name","description","inputSchema","Record","ToolExecutor","args","Promise","ToolManager","tools","executor","lastSentToolSignature","setTools","console","log","length","getToolSignature","slice","setExecutor","resetSession","map","t","sort","join","hasToolsChanged","currentSignature","changed","currentSignatureLength","lastSentSignatureLength","currentFirst50","lastSentFirst50","markToolsSent","formatToolsForOpenAI","builtInTools","type","parameters","properties","required","registeredTools","tool","const","validateToolSchema","schema","result","validateNestedSchemas","Object","entries","filter","prop","p","optional","nullable","key","validated","value","propType","items","warn","executeToolCall","functionCall","arguments","argsString","executeListTools","error","success","repaired","JSON","parse","data","String","toolList","count","message","getChangesSummary","added","removed","total","prevTools","split","Boolean","currTools","prevSet","Set","currSet","has","debugLog","REALTIME_DEFAULT_API_URL","REALTIME_DEFAULT_MODEL","REALTIME_DEFAULT_VOICE","RealtimeConfig","RealtimeSession","EphemeralTokenResponse","client_secret","value","hasClientSecret","response","secret","WebRTCManager","tokenEndpoint","constructor","createSession","config","Promise","model","voice","apiUrl","ephemeralKey","getEphemeralToken","pc","RTCPeerConnection","audioElement","createAudioElement","remoteStream","MediaStream","ontrack","e","streams","srcObject","streamId","id","tracks","getTracks","length","localStream","getUserMedia","map","t","kind","enabled","muted","readyState","forEach","track","addTrack","dataChannel","createDataChannel","offer","createOffer","setLocalDescription","sdp","Error","answer","connectToOpenAI","setRemoteDescription","cleanup","stop","remove","close","fetch","method","headers","body","JSON","stringify","ok","errorText","text","console","error","statusText","data","json","HTMLAudioElement","document","createElement","autoplay","style","display","appendChild","navigator","mediaDevices","audio","echoCancellation","noiseSuppression","autoGainControl","baseUrl","RTCSessionDescriptionInit","Authorization","answerSdp","type","const","AUDIO_FREQUENCY_BINS","AUDIO_VISUALIZATION_INTERVAL_MS","debugLog","AudioAnalyzer","EventEmitter","MessageHandler","ToolManager","WebRTCManager","RegisteredTool","ToolExecutor","EventCallback","RealtimeConfig","RealtimeSession","SessionConfig","EMPTY_FREQUENCY_TEMPLATE","Object","freeze","Array","fill","createZeroFrequencyArray","OpenAIRealtimeService","session","webrtcManager","toolManager","messageHandler","eventEmitter","muted","lastState","localAnalyzer","remoteAnalyzer","visualizationInterval","ReturnType","setInterval","sessionStartTime","onToolsChangedCallback","constructor","tokenEndpoint","setTools","tools","console","log","length","slice","map","t","name","join","isSessionActive","updateSessionTools","setToolExecutor","executor","setExecutor","onToolsChanged","callback","startSession","config","Promise","stopSession","Date","now","emitSessionState","createSession","setupDataChannel","dataChannel","setupPeerConnectionMonitoring","pc","localStream","initializeLocalAnalyzer","remoteStream","initializeRemoteAnalyzer","originalOntrack","ontrack","e","call","streams","warn","error","handleSessionError","durationSeconds","Math","floor","clearInterval","destroy","cleanup","reset","resetSession","sendUserMessage","text","Error","message","type","item","role","content","send","JSON","stringify","readyState","getLocalStream","MediaStream","getRemoteStream","toggleMute","audioElement","isMuted","pauseAudio","pause","resumeAudio","play","catch","on","event","off","getSessionStatus","state","isActive","RTCDataChannel","addEventListener","configureSession","MessageEvent","handleMessage","data","emit","RTCPeerConnection","connectionState","iceConnectionState","formatToolsForOpenAI","markToolsSent","sessionConfig","modalities","instructions","getSessionInstructions","voice","tool_choice","turn_detection","threshold","prefix_padding_ms","silence_duration_ms","input_audio_transcription","model","output_audio_transcription","sessionUpdate","changesSummary","getChangesSummary","total","added","removed","String","stream","clonedStream","getAudioTracks","clone","initialize","startAudioVisualization","logCounter","micLevel","getAudioLevel","micFrequency","getFrequencyData","speakerLevel","speakerFrequency","mic","toFixed","speaker","extra","Record","payload","RealtimeConfig","model","voice","apiUrl","tokenEndpoint","RealtimeSession","pc","RTCPeerConnection","dataChannel","RTCDataChannel","audioElement","HTMLAudioElement","localStream","MediaStream","remoteStream","cleanup","OpenAITool","type","name","description","parameters","properties","Record","required","SessionConfig","modalities","instructions","tools","tool_choice","turn_detection","threshold","prefix_padding_ms","silence_duration_ms","input_audio_transcription","output_audio_transcription","FunctionCall","arguments","call_id","status","ConversationItem","role","content","output","RealtimeMessage","key","ToolExecutionResult","success","data","error","EventCallback","IEventEmitter","on","event","callback","off","emit","AudioLevelData","micLevel","micFrequency","speakerLevel","speakerFrequency","TranscriptData","text","isDone","ToolCallData","toolName","VoiceModeState","isActive","isConnecting","isMuted","isError","connectionState","audioLevel","transcript","toolCall","SessionStateEventData","state","durationSeconds","UserTranscriptEventData","AssistantTranscriptEventData","delta","ToolCallStartedEventData","ToolCallCompletedEventData","NestedErrorObject","code","message","param","event_id","ErrorEventData","isSessionStateEventData","d","includes","isUserTranscriptEventData","isAssistantTranscriptEventData","undefined","isToolCallStartedEventData","isToolCallCompletedEventData","isErrorEventData","hasError","extractErrorMessage","nestedError","isAudioLevelData","Array","isArray","useCallback","useEffect","useMemo","useRef","useState","TOOL_CALL_DISPLAY_DURATION_MS","TOOL_CALL_ERROR_DISPLAY_DURATION_MS","extractErrorMessage","isAssistantTranscriptEventData","isAudioLevelData","isErrorEventData","isSessionStateEventData","isToolCallCompletedEventData","isToolCallStartedEventData","isUserTranscriptEventData","OpenAIRealtimeService","AudioLevelData","RealtimeConfig","RegisteredTool","ToolCallData","ToolExecutor","TranscriptData","VoiceModeState","UseVoiceModeOptions","tokenEndpoint","tools","toolExecutor","onConnect","onDisconnect","durationSeconds","onError","error","onUserTranscript","text","onAssistantTranscript","UseVoiceModeReturn","startSession","config","Promise","stopSession","toggleMute","muted","sendMessage","pauseAudio","resumeAudio","useVoiceMode","options","$","_c","isActive","setIsActive","isConnecting","setIsConnecting","isMuted","setIsMuted","isError","setIsError","connectionState","setConnectionState","audioLevel","setAudioLevel","transcript","setTranscript","toolCall","setToolCall","setError","serviceRef","onConnectRef","onDisconnectRef","onErrorRef","onUserTranscriptRef","onAssistantTranscriptRef","t0","t1","current","t2","getService","t3","t4","service","setTools","t5","t6","service_0","setToolExecutor","t7","t8","service_1","handleSessionState","data","console","warn","state","handleAudioLevel","data_0","handleUserTranscript","data_1","type","isDone","handleAssistantTranscript","data_2","delta","prev","handleAssistantTranscriptDone","data_3","text_0","handleToolCallStarted","data_4","status","toolName","name","handleToolCallCompleted","data_5","setTimeout","undefined","handleError","data_6","errorMsg","on","off","t9","service_2","t10","err","errorMsg_0","Error","message","service_3","t11","service_4","newMuted","t12","text_1","service_5","isSessionActive","sendUserMessage","t13","service_6","t14","service_7","t15","createContext","useContext","useMemo","useVoiceMode","ReactNode","UseVoiceModeReturn","RegisteredTool","ToolExecutor","VoiceModeContextValue","isSupported","VoiceModeContext","VoiceModeProviderProps","children","tokenEndpoint","tools","toolExecutor","onConnect","onDisconnect","durationSeconds","onError","error","onUserTranscript","text","onAssistantTranscript","checkVoiceModeSupport","window","RTCPeerConnection","navigator","mediaDevices","getUserMedia","VoiceModeProvider","t0","$","_c","t1","voiceMode","t2","Symbol","for","t3","value","t4","useVoiceModeContext","context","Error","useOptionalVoiceModeContext","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS","VOICE_APPROVAL_TIMEOUT_MS","FC","ReactNode","VoicePendingApproval","callId","toolName","args","Record","timestamp","VoiceToolApprovalContextValue","pendingApproval","approve","deny","timeoutRemaining","isWaitingForApproval","requestApproval","Promise","clearPendingApproval","VoiceToolApprovalContext","VoiceToolApprovalProviderProps","children","timeout","onTimeout","onApprove","onDeny","VoiceToolApprovalProvider","setPendingApproval","setTimeoutRemaining","resolveRef","approved","timeoutIdRef","ReturnType","setTimeout","countdownIdRef","setInterval","onTimeoutRef","onApproveRef","onDenyRef","current","clearTimers","clearTimeout","clearInterval","resolveApproval","reason","resolve","Date","now","timeoutSeconds","Math","ceil","prev","value","useVoiceToolApproval","context","Error","useOptionalVoiceToolApproval","useThread","useThreadRuntime","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","VOICE_TOOL_RESULT_MESSAGES","TOOL_DENIED_MESSAGE","getPendingToolCallsByName","resolveAllPendingToolCalls","resolveAllPendingToolCallsByName","resolvePendingToolCall","useOptionalMCPTools","useOptionalToolApproval","useOptionalVoiceModeContext","VoiceModeProvider","useOptionalVoiceToolApproval","VoiceToolApprovalProvider","ToolCallMetadata","ToolWithSource","FC","MutableRefObject","ReactNode","RegisteredTool","ToolExecutor","VoiceToolCallData","toolCallId","toolName","args","Record","result","isError","artifact","AddToolCallToThread","data","VoiceMessageMetadata","source","voiceSessionId","timestamp","VoiceThreadContextValue","isActive","isConnecting","isMuted","isSupported","error","sessionId","start","Promise","stop","toggleMute","muted","sendMessage","text","pauseAudio","resumeAudio","audioLevel","micLevel","speakerLevel","transcript","type","isDone","toolCall","status","VoiceThreadContext","generateSessionId","Date","now","Math","random","toString","slice","convertToRegisteredTool","tool","name","description","inputSchema","properties","VoiceThreadBridgeProps","children","tokenEndpoint","onConnect","onDisconnect","durationSeconds","onError","VoiceThreadIntegrator","setSessionId","id","addToolCallRef","threadRuntime","voiceMode","lastUserTranscriptRef","lastAssistantTranscriptRef","wasActiveRef","onConnectRef","onDisconnectRef","onErrorRef","current","console","warn","append","role","content","argsText","JSON","stringify","metadata","custom","addUserMessage","trim","addAssistantMessage","newSessionId","sessionEnded","ApprovalAwareVoiceBridge","voiceTools","t0","$","_c","mcpTools","toolApproval","voiceToolApproval","threadMessages","_temp","t1","Symbol","for","Map","pendingVoiceResolutions","t2","callTool","Error","tools","find","t_0","t","needsApproval","requiresApproval","callId","approved","requestApproval","resultMessage","handled","resolvedNow","queue","get","push","set","textContent","_temp2","toolExecutor","t3","size","queue_0","entries","freshQueue","filter","t4","length","delete","pendingCalls","queueIndex","call","result_0","messageId","t5","t6","t7","VoiceThreadBridge","map","VoiceThreadContextProvider","bb0","undefined","startSession","stopSession","contextValue","useVoiceThread","context","useOptionalVoiceThread","useIsVoiceActive","messages","c","ComposerAddAttachment","ComposerAttachments","UserMessageAttachments","MarkdownText","Reasoning","ReasoningGroup","TooltipIconButton","Button","cn","ActionBarPrimitive","AssistantIf","BranchPickerPrimitive","ComposerPrimitive","ErrorPrimitive","MessagePrimitive","ThreadPrimitive","ArrowDownIcon","ArrowUpIcon","CheckIcon","ChevronLeftIcon","ChevronRightIcon","CopyIcon","DownloadIcon","History","Mic","PencilIcon","Plus","RefreshCwIcon","Shield","ShieldOff","SquareIcon","X","useCallback","useMemo","FC","UnifiedToolFallback","usePrompts","useOptionalToolSelection","useOptionalToolApproval","useOptionalVoiceThread","ThreadToolSelection","ToolSourceInfo","ThreadProps","onThreadsClick","onNewThread","onClose","glassmorphicButtonClass","Thread","thread","isEmpty","UserMessage","EditComposer","AssistantMessage","ThreadScrollToBottom","$","_c","t0","Symbol","for","ThreadWelcome","ThreadSuggestions","prompts","hasPrompts","slice","map","_temp","t1","Composer","voiceThread","isVoiceActive","isActive","isVoiceConnecting","isConnecting","t2","t3","t4","t5","t6","t7","t8","t9","getSourceLabel","source","title","trim","fallback","url","origin","URL","hostname","getSourceKey","sourceId","getSelectionKey","selection","buildSelection","current","selectedSources","selectedSet","Set","key","nextSelector","tabId","next","has","filter","item","ComposerToolSources","toolSelection","sources","selectedKeys","currentSourceId","nextSelection","setSelection","handleToggle","length","source_0","isSelected","label","isLocal","iconUrl","toolCount","ComposerApprovalButton","toolApproval","mode","toggleMode","isAskMode","ComposerVoiceButton","isSupported","start","stop","handleClick","ComposerAction","_temp2","_temp3","MessageError","Text","tools","Fallback","AssistantActionBar","_temp4","_temp5","UserActionBar","BranchPicker","Root","Props","className","rest","prompt","index","name","animationDelay","description","isRunning","thread_0","message","isCopied","message_0","c","_c","AssistantIf","ThreadListItemPrimitive","ThreadListPrimitive","Archive","Plus","cn","useMemo","FC","AgentThreadListProps","className","onSelectThread","AgentThreadList","ThreadListItem","Item","displayName","threads","isLoading","ThreadListNew","$","t0","Symbol","for","ThreadListSkeleton","Array","from","length","_temp","ThreadListItemBase","t1","t2","t3","t4","t5","ThreadListItemArchive","_","idx","useThread","useMemo","humanizeToolName","ToolCallMetadata","Action","id","label","toolName","status","args","result","error","startedAt","duration","sourceId","wasAborted","ToolCallPart","type","toolCallId","artifact","isError","isToolCallMetadata","a","Record","useActions","$","_c","messages","_temp","t0","bb0","length","t1","Symbol","for","actions","message","role","part","content","toolPart","isComplete","undefined","hasError","requiresAction","metadata","push","String","thread","c","_c","useThread","useMemo","TextPart","type","text","useLatestSummary","$","messages","_temp","t0","bb0","length","lastAssistantMessage","reverse","find","_temp2","textParts","content","filter","_temp3","at","m","role","thread","createContext","useContext","useMemo","FC","ReactNode","ThreadControlContextValue","reset","Promise","startNew","ThreadControlContext","ThreadControlProviderProps","children","ThreadControlProvider","t0","$","_c","t1","t2","value","t3","useThreadControl","context","Error","useOptionalThreadControl","useThread","useMemo","useActions","useLatestSummary","useOptionalMCPTools","useOptionalVoiceThread","useOptionalThreadControl","CallToolResult","Prompt","ToolWithSource","GetPromptResult","Action","AgentVoice","isActive","isConnecting","isError","isMuted","isSupported","error","sessionId","audioLevel","micLevel","speakerLevel","transcript","type","text","isDone","start","Promise","stop","toggleMute","muted","sendMessage","AgentThread","reset","startNew","AgentTools","list","call","name","args","Record","prompts","getPrompt","AgentMessage","id","role","content","status","metadata","AgentState","messages","isRunning","hasMessages","actions","currentAction","recentActions","lastCompletedAction","summary","voice","tools","thread","isVoiceActive","useAgent","$","_c","threadMessages","_temp","_temp2","t0","find","_temp3","t1","filter","_temp4","slice","t2","completed","_temp5","at","voiceThread","mcpContext","length","t3","bb0","t4","bb1","t5","t6","callTool","threadControl","bb2","thread_1","t7","t8","a_1","a","a_0","thread_0","useAssistantApi","useAssistantState","useCallback","useMemo","AgentThreadStatus","AgentThreadListItem","id","title","status","remoteId","externalId","AgentThreadsState","isLoading","currentThreadId","threadIds","archivedThreadIds","itemsById","Readonly","Record","switchToThread","threadId","switchToNewThread","rename","archive","useAgentThreads","$","_c","api","_temp","_temp2","_temp3","_temp4","threadItems","_temp5","t0","entries","map","_temp6","Object","fromEntries","t1","threads","t2","t3","threadId_0","item","t4","threadId_1","t5","normalized","const","threads_3","threads_2","threads_1","threads_0","mainThreadId","WEBMCP_STYLES","WEBMCP_SHADOW_STYLES","injectStyles","document","styleId","getElementById","style","createElement","id","textContent","head","appendChild","getShadowStyles","WEBMCP_STYLES","injected","injectStyles","document","getElementById","style","createElement","id","textContent","head","appendChild","React","Button","cn","AuthError","ErrorScreenProps","error","dashboardBaseUrl","docsBaseUrl","onRetry","onContact","showDebug","className","ErrorScreen","t0","$","_c","t1","t2","t3","undefined","isDebugExpanded","setIsDebugExpanded","useState","dashboardUrl","dashboardLink","docsUrl","docsLink","startsWith","t4","t5","title","t6","message","t7","t8","context","Object","keys","length","currentDomain","missingField","expectedIssuer","actualIssuer","t9","callToAction","steps","map","_temp","t10","examples","_temp2","t11","debugInfo","e","currentTarget","open","t12","t13","t14","recoverable","t15","t16","t17","t18","t19","t20","t21","code","example","index_0","index","step","React","ErrorScreen","AuthError","AuthErrorBoundaryProps","children","ReactNode","dashboardBaseUrl","docsBaseUrl","fallback","ComponentType","error","reset","onError","Error","errorInfo","ErrorInfo","showDebug","AuthErrorBoundaryState","hasError","AuthErrorBoundary","Component","constructor","props","state","getDerivedStateFromError","Partial","authError","isAuthError","code","title","message","recoverable","debugInfo","componentDidCatch","console","handlerError","handleReset","setState","handleContact","window","open","render","FallbackComponent","name","AssistantChatTransport","useChatRuntime","lastAssistantMessageIsCompleteWithToolCalls","useMemo","AssistantRuntime","UseStatelessRuntimeResult","runtime","UseStatelessRuntimeOptions","apiBase","system","anthropicApiKey","useStatelessRuntime","t0","$","_c","t1","undefined","options","t2","chatApi","t3","headers","api","transport","t4","sendAutomaticallyWhen","_temp","t5","messages","createContext","useCallback","useContext","useMemo","useRef","useState","FC","ReactNode","PillMode","Position","x","y","AgentUIState","isOpen","userMode","position","hasUnread","isVoiceActive","isFullScreen","AgentUIContextValue","setOpen","open","toggleOpen","setUserMode","mode","setPosition","resetPosition","markRead","markUnread","setVoiceActive","active","collapse","expand","enterFullScreen","exitFullScreen","toggleFullScreen","AgentUIContext","DEFAULT_POSITION","AgentUIProviderProps","children","defaultOpen","defaultMode","onOpenChange","onModeChange","AgentUIProvider","controlledOpen","isControlled","undefined","internalOpen","setInternalOpen","setUserModeState","setPositionState","setHasUnread","setIsVoiceActiveState","setIsFullScreen","onOpenChangeRef","onModeChangeRef","current","next","pos","prev","value","useAgentUI","context","Error","useOptionalAgentUI","usePillMode","useHasUnread","cn","Skeleton","t0","$","_c","className","props","t1","t2","InitContextResult","AuthError","AuthErrorCode","mapErrorCode","backendCode","includes","convertInitErrorToAuthError","result","success","Error","code","errorCode","title","errorTitle","message","callToAction","dashboardLink","docsLink","context","recoverable","debugInfo","AuthErrorException","constructor","authError","name","captureStackTrace","throwInitError","useRef","stableStringifyImpl","CallToolResult","HubToSiteMessage","SyncedToolSchema","ToolSourcesUpdateMessage","stableStringify","value","generateShortTabId","window","random","Math","floor","toString","padStart","EMBEDDED_AGENT_TAB_ID","getEmbeddedAgentTabId","areSyncedToolSchemasEquivalent","a","b","length","byName","Map","schema","set","name","next","prev","get","description","inputSchema","annotations","sources","safeParseHubToSiteMessage","data","parsed","JSON","parse","msg","Partial","type","callId","toolName","args","Record","safeParseToolSourcesMessage","Array","isArray","SOURCE_ID_RE","parseNamespacedTool","sourceId","idx","indexOf","slice","test","formatToolResult","result","textContent","content","find","c","text","stringify","sliceMessagesUntil","id","messages","T","parentId","index","findIndex","m","shallowEqualRecords","aKeys","Object","keys","bKeys","key","prototype","hasOwnProperty","call","useShallowStableObject","ref","current","useCallback","useEffect","useState","ToolConnectionMetadata","getEmbeddedAgentTabId","UseToolSourceMetadataOptions","enabled","UseToolSourceMetadataResult","metadata","useToolSourceMetadata","options","tabId","getMetadata","window","undefined","iconUrl","link","document","querySelector","HTMLLinkElement","href","getAttribute","URL","location","toString","url","origin","title","trim","setMetadata","updateMetadata","addEventListener","titleObserver","MutationObserver","titleElement","observe","childList","headObserver","head","subtree","attributes","attributeFilter","removeEventListener","disconnect","useEffect","useMemo","useRef","SyncedToolSchema","ToolConnectionMetadata","ToolWithSource","ThreadManagerState","useAgent","stableStringify","UseToolSourceRegistrationOptions","manager","ReturnType","tools","metadata","useToolSourceRegistration","options","toolsRef","current","localToolSchemasKey","tabId","schemas","map","t","name","description","inputSchema","annotations","sort","a","b","localeCompare","console","debug","readyState","hasMetadata","toolCount","length","toolNames","slice","WebSocket","OPEN","registerTools","warn","localTools","toolSchemas","call","error","JWTPayload","sub","key","decodeJWT","token","parts","split","length","payload","base64","replace","jsonPayload","decodeURIComponent","atob","map","c","charCodeAt","toString","slice","join","JSON","parse","extractUserIdFromToken","ExternalStoreThreadListAdapter","useAgent","useCallback","useEffect","useMemo","useRef","useState","CallToolResult","CreateThreadParams","CreateThreadResult","InitContextResult","SiteToHubMessage","ThreadManagerState","ThreadSummary","ThreadUpdateParams","ThreadWithDeleted","ToolSourceInfo","ToolWithSource","throwInitError","useToolSourceMetadata","useToolSourceRegistration","getEmbeddedAgentTabId","safeParseHubToSiteMessage","safeParseToolSourcesMessage","stableStringify","extractUserIdFromToken","UseCloudflareThreadAdapterOptions","host","authToken","mcpTools","executeMCPTool","toolName","args","Record","Promise","persistSelection","selectionStorageKey","UseCloudflareThreadAdapterResult","currentThreadId","setCurrentThreadId","threadId","threadListAdapter","isInitialized","isConnected","isReady","endUserId","organizationId","manager","ReturnType","toolSources","authError","AuthError","sortThreadsByRecency","lastMessageAt","createdAt","list","T","sort","a","b","aTime","bTime","isRegularThread","thread","status","isArchivedThread","areThreadListsEquivalent","length","byId","Map","set","id","next","prev","get","title","remoteId","externalId","messageCount","totalTokens","useCloudflareThreadAdapter","options","userId","fallbackUserIdRef","Math","random","toString","slice","effectiveUserId","current","setIsInitialized","initialSyncComplete","setInitialSyncComplete","setEndUserId","setOrganizationId","setAuthError","threads","setThreads","undefined","persistedThreadId","setPersistedThreadId","initPromiseRef","didApplyPersistedSelectionRef","effectiveSelectionStorageKey","agent","name","query","auth_token","onStateUpdate","state","source","tabId","setToolSources","handleMessage","event","MessageEvent","message","data","sources","addEventListener","removeEventListener","metadata","enabled","readyState","WebSocket","OPEN","tools","msg","type","result","response","callId","send","JSON","stringify","error","content","text","Error","isError","localStorage","getItem","ensureInitialized","origin","window","location","call","initResult","success","catch","console","filteredNonDeleted","filter","t","activeThreads","archivedThreads","preferred","some","fallback","exists","isLoading","createThread","params","onSwitchToNewThread","onSwitchToThread","onRename","newTitle","onArchive","nextActive","onUnarchive","onDelete","setItem","unstable_createMessageConverter","useExternalMessageConverter","ReasoningMessagePart","ToolCallMessagePart","TextMessagePart","SourceMessagePart","getToolName","isToolUIPart","UIMessage","MessagePart","NonNullable","JSONValue","key","JSONObject","stripClosingDelimiters","json","replace","getRawInput","part","rawInput","length","convertParts","message","metadata","Metadata","Array","parts","filter","p","type","map","text","toolName","toolCallId","args","argsText","result","isError","state","input","output","error","errorText","JSON","stringify","toolStatus","toolStatuses","interrupt","payload","status","const","reason","sourceType","id","sourceId","url","title","console","warn","Boolean","CloudflareMessageConverter","createdAt","Date","role","fileParts","Extract","attachments","idx","toString","mediaType","startsWith","name","filename","content","image","data","mimeType","contentType","msgWithMeta","annotations","unstable_annotations","unstable_data","isArray","undefined","custom","default","useCallback","useEffect","useMemo","useRef","useState","INTERNAL","useExternalStoreRuntime","useRuntimeAdapters","AppendMessage","AssistantRuntime","ThreadMessage","ToolExecutionStatus","CallToolResult","ThreadMetadata","ThreadManagerState","ThreadToolSelection","ToolApprovalMode","ToolSourceInfo","ToolWithSource","useAgentChat","AITool","useAgent","getToolName","isToolUIPart","UIMessage","CloudflareMessageConverter","isToolDestructive","formatToolResult","getEmbeddedAgentTabId","sliceMessagesUntil","useShallowStableObject","DISCONNECTED_THREAD_ID","ThreadAgentState","threadMetadata","toolSelection","FrontendTool","TInput","TOutput","FrontendTools","Record","UseThreadRuntimeOptions","threadId","host","authToken","manager","ReturnType","mcpTools","executeMCPTool","toolName","args","Promise","approvalMode","cancelPendingToolCallsOnSend","toolSources","adapters","NonNullable","Parameters","UseThreadRuntimeResult","runtime","reset","toolExecution","executeTool","getToolMetadata","description","annotations","sources","selection","setSelection","currentSourceId","useThreadRuntime","options","customAdapters","contextAdapters","toolStatuses","setToolStatuses","setToolSelectionState","tabId","match","find","source","sourceId","threadAgent","agent","name","query","auth_token","startClosed","onStateUpdate","state","rawNonThreadListAdapters","merged","Object","assign","threadList","keys","length","undefined","nonThreadListAdapters","threadListAdapter","pendingFirstMessageRef","onSwitchToNewThreadRef","onSwitchToNewThread","current","mcpToolsRef","setToolSelection","readyState","WebSocket","OPEN","result","call","error","console","localToolNames","Set","map","t","tool","Error","has","frontendTools","toolsRequiringConfirmation","requiresConfirmation","shouldAutoExecute","push","parameters","inputSchema","execute","callResult","chat","tools","experimental_automaticToolResolution","autoContinueAfterToolResult","resume","hasExecutingTools","values","some","s","type","isRunning","status","messages","useThreadMessages","metadata","message","runtimeRef","getTools","thread","getModelContext","onResult","toolInvocations","useToolInvocations","completePendingToolCalls","pendingToolIds","entries","filter","toolCallId","abort","msg","part","parts","addToolOutput","output","prev","next","pendingText","sendPending","sendMessage","text","catch","onNew","messageWithMetadata","isVoiceMessage","custom","firstContent","content","voiceUIMessage","id","Date","now","Math","random","toString","slice","role","createdAt","const","setMessages","onEdit","newMessages","parentId","onReload","regenerate","onCancel","stop","onAddToolResult","isError","onResumeToolCall","payload","store","clearHistory","createContext","Suspense","useCallback","useContext","useMemo","useRef","ReactNode","AssistantRuntimeProvider","CallToolResult","ToolApprovalMode","ToolWithSource","useAgent","ThreadManagerState","ErrorScreen","Skeleton","useCloudflareThreadAdapter","useThreadRuntime","ToolExecutionProvider","ToolSelectionProvider","CloudflareThreadRuntimeProviderProps","children","host","authToken","mcpTools","executeMCPTool","toolName","args","Record","Promise","approvalMode","cancelPendingToolCallsOnSend","dashboardBaseUrl","docsBaseUrl","CloudflareThreadContextValue","isInitialized","isReady","endUserId","organizationId","currentThreadId","setCurrentThreadId","threadId","reset","startNew","authError","AuthError","CloudflareThreadContext","useCloudflareThread","context","Error","useOptionalCloudflareThread","ThreadRuntimeSkeleton","$","_c","t0","Symbol","for","t1","ThreadRuntimeBridgeProps","manager","ReturnType","threadListAdapter","toolSources","onResetChange","ThreadRuntimeBridge","runtime","resetThread","toolExecution","toolSelection","adapters","threadList","resetThreadRef","current","stableReset","onResetChangeRef","CloudflareThreadRuntimeProvider","resetRef","handleResetChange","newReset","onSwitchToNewThreadRef","onSwitchToNewThread","contextValue","useThread","useThreadRuntime","useMemo","ThreadAssistantMessage","PendingToolCallInfo","usePendingToolCalls","$","_c","messages","_temp","result","msg","role","assistantMsg","status","type","part","content","undefined","push","messageId","id","toolCallId","toolName","args","Record","t","useAssistantApi","useAssistantState","useThread","useThreadRuntime","useWebMCP","useCallback","useRef","z","useOptionalAgentUI","useOptionalMCPTools","useOptionalToolApproval","useOptionalToolSelection","useOptionalVoiceThread","usePendingToolCalls","resolvePendingToolCall","ToolApprovalMode","ToolSourceSelector","PillMode","DEBUG_TOOL_PREFIX","DEBUG_STATE_SCHEMA","const","DEBUG_UI_SCHEMA","action","enum","describe","mode","optional","text","string","DEBUG_TOOLS_SCHEMA","toolCallId","reason","sourceIds","array","DEBUG_SESSION_SCHEMA","threadId","DEBUG_STATE_DESCRIPTION","DEBUG_UI_DESCRIPTION","DEBUG_TOOLS_DESCRIPTION","DEBUG_SESSION_DESCRIPTION","UseWebMCPDebugToolsOptions","additionalState","cloudflareThread","isInitialized","isReady","currentThreadId","endUserId","organizationId","managerState","readyState","readyStateLabel","TOOL_DENIED_MESSAGE","useWebMCPDebugTools","options","agentUI","mcpTools","toolApproval","toolSelection","voiceThread","pendingToolCalls","threadRuntime","assistantApi","threadMessages","t","messages","isRunning","threadsLoading","threads","isLoading","mainThreadId","threadIds","stateRef","current","handleDebugState","state","ui","userMode","isFullScreen","hasUnread","position","error","map","msg","contentPreview","part","content","type","slice","toolCalls","filter","tc","toolCallPart","toolName","result","name","status","undefined","id","role","selectedSourceIds","selection","selectedSources","s","sourceId","thread","isEmpty","length","messageCount","pendingApprovals","messageId","args","currentAction","voice","isActive","isConnecting","isMuted","isSupported","transcript","tools","approvalMode","localTools","description","_sourceId","mcpSources","Array","from","sources","entries","source","toolCount","message","remoteSources","tabId","title","url","isSelected","includes","currentSourceId","connection","managerReadyState","managerReadyStateLabel","inputSchema","handler","handleDebugUi","success","setUserMode","expand","collapse","toggleFullScreen","resetPosition","x","y","markRead","composer","setText","send","e","Error","reset","handleDebugTools","target","find","callTool","resultString","JSON","stringify","errorMsg","denyMessage","denied","setMode","setSelection","currentSelected","newSelected","allSources","handleDebugSession","switchToNewThread","switchToThread","start","stop","toggleMute","isDebugTool","startsWith","ToolApprovalMode","ToolWithSource","React","useCallback","useEffect","FC","ReactNode","AssistantRuntimeProvider","ExportedMessageRepository","useThreadRuntime","injectStyles","WEBMCP_PRODUCTION_API_BASE","AuthErrorBoundary","MCPToolRegistry","MCPToolsProvider","useMCPTools","ToolApprovalProvider","useToolApproval","ToolExclusionProvider","ToolExclusionFilter","VoiceThreadBridge","useStatelessRuntime","AgentUIProvider","PillMode","CloudflareThreadRuntimeProvider","useCloudflareThread","useOptionalCloudflareThread","ThreadControlProvider","useWebMCPDebugTools","AgentProviderConfig","apiBase","authToken","anthropicApiKey","devMode","openaiApiKey","useLocalApi","host","agent","tokenEndpoint","autoConnectLocal","open","defaultOpen","defaultMode","defaultApprovalMode","onToolsChange","tools","onVoiceError","error","onVoiceConnect","onVoiceDisconnect","duration","onOpenChange","onModeChange","mode","onApprovalModeChange","excludeTools","excludeToolNames","excludeToolPrefixes","enableDebugTools","dashboardBaseUrl","docsBaseUrl","onAuthError","Error","errorInfo","ErrorInfo","showErrorDebug","AgentProviderProps","children","AgentRuntimeProps","DebugToolsRegistrar","$","_c","cloudflareThread","refreshTools","t0","isInitialized","isReady","currentThreadId","endUserId","organizationId","undefined","t1","additionalState","t2","t3","timer","setTimeout","clearTimeout","StatefulRuntimeBridgeProps","StatefulRuntimeBridge","reset","startNew","Symbol","for","t4","StatefulRuntime","mcpTools","callTool","approvalMode","resolvedApiBase","url","URL","resolvedHost","resolvedTokenEndpoint","StatelessRuntimeBridgeProps","StatelessRuntimeBridge","threadRuntime","console","log","import","fromArray","t5","StatelessRuntime","Omit","runtime","AgentRuntime","AgentProvider","anthropicApiKeyProp","t6","_temp","hasExclusions","t7","t8","content","t9","t10","t11","t12","c","_c","useCallback","useEffect","useRef","useState","FC","ArrowLeft","Plus","X","Thread","TooltipIconButton","AgentThreadList","useAgent","useAgentThreads","AgentProvider","AgentProviderConfig","cn","Screen","AgentThreadProps","className","onClose","AgentThread","t0","$","providerConfig","t1","t2","AgentThreadInnerProps","AgentThreadInner","isLoading","threadIds","switchToNewThread","agent","screen","setScreen","Symbol","for","showThreadList","showThreadView","t3","thread","startNew","catch","_temp","startNewThread","t4","handleSelectThread","didAutoCreateThreadRef","t5","t6","length","current","t7","error","console","t8","glassmorphicButtonClass","t9","c","_c","useEffect","useRef","useState","createPortal","FC","ReactNode","CSS_VARIABLE_NAMES","const","extractCssVariables","hostElement","Element","hostStyles","getComputedStyle","varsWithImportant","map","name","value","getPropertyValue","trim","filter","Boolean","join","ShadowRootProps","children","styles","className","mode","ShadowRoot","t0","$","t1","undefined","hostRef","portalContainer","setPortalContainer","t2","t3","Symbol","for","host","current","syncTheme","html","document","documentElement","isDark","classList","contains","window","matchMedia","matches","toggle","observer","MutationObserver","observe","attributes","attributeFilter","mediaQuery","addEventListener","disconnect","removeEventListener","t4","t5","host_0","shadow","shadowRoot","attachShadow","webComponentHost","parentElement","cssVariables","styleElement","querySelector","createElement","setAttribute","insertBefore","firstChild","textContent","container","appendChild","t6","t7","r2wc","AgentThread","ShadowRoot","WEBMCP_SHADOW_STYLES","WEBMCP_PRODUCTION_API_BASE","FC","getDefaultApiBase","useLocalApi","window","location","origin","DevModeConfig","anthropicApiKey","openaiApiKey","EmbeddedAgentProps","authToken","open","className","onClose","devMode","enableDebugTools","EmbeddedAgent","t0","$","_c","t1","undefined","apiBase","authMode","console","debug","hasAuthToken","mode","voiceEnabled","t2","t3","t4","WebMCPAgentElement","Parameters","props","registerWebMCPAgent","tagName","customElements","get","define"],"sources":["../src/utils/cn.ts","../src/components/ui/tooltip.tsx","../src/components/ui/dialog.tsx","../src/components/ui/avatar.tsx","../src/components/ui/button.tsx","../src/components/assistant-ui/tooltip-icon-button.tsx","../src/components/assistant-ui/attachment.tsx","../src/components/assistant-ui/markdown-text.tsx","../../../../../../node_modules/@radix-ui/primitive/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-context/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-primitive/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-presence/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-id/dist/index.mjs","../../../../../../node_modules/@radix-ui/react-collapsible/dist/index.mjs","../src/components/ui/collapsible.tsx","../src/components/assistant-ui/reasoning.tsx","../src/hooks/useDelayedState.ts","../src/utils/constants.ts","../src/utils/mcp-transport.ts","../src/utils/tool-names.ts","../src/providers/MCPToolsProvider.tsx","../src/utils/tool-approval.ts","../src/providers/ToolApprovalProvider.tsx","../src/providers/ToolExclusionProvider.tsx","../src/providers/MCPToolRegistry.tsx","../src/providers/ToolExecutionProvider.tsx","../src/utils/format.ts","../src/components/pill/ActivityIndicator.tsx","../src/components/pill/UnifiedToolFallback.tsx","../src/hooks/usePrompts.ts","../src/providers/ToolSelectionProvider.tsx","../src/utils/thread-utils.ts","../src/services/realtime/audio-analyzer.ts","../src/services/realtime/event-emitter.ts","../src/services/realtime/message-handler.ts","../src/services/realtime/tool-manager.ts","../src/services/realtime/webrtc-manager.ts","../src/services/realtime/openai-realtime-service.ts","../src/services/realtime/types.ts","../src/hooks/useVoiceMode.ts","../src/providers/VoiceModeProvider.tsx","../src/providers/VoiceToolApprovalProvider.tsx","../src/providers/VoiceThreadBridge.tsx","../src/components/assistant-ui/thread.tsx","../src/components/agent/AgentThreadList.tsx","../src/hooks/useActions.ts","../src/hooks/useLatestSummary.ts","../src/providers/ThreadControlProvider.tsx","../src/hooks/useAgent.ts","../src/hooks/useAgentThreads.ts","../src/generated/inline-styles.ts","../src/utils/inject-styles.ts","../src/components/errors/ErrorScreen.tsx","../src/components/errors/AuthErrorBoundary.tsx","../src/hooks/useStatelessRuntime.tsx","../src/providers/AgentUIProvider.tsx","../src/components/ui/skeleton.tsx","../src/utils/convert-init-error.ts","../src/hooks/thread-runtime-utils.ts","../src/hooks/useToolSourceMetadata.tsx","../src/hooks/useToolSourceRegistration.tsx","../src/utils/jwt.ts","../src/hooks/useCloudflareThreadAdapter.tsx","../src/utils/converter.ts","../src/hooks/useThreadRuntime.tsx","../src/providers/CloudflareThreadRuntimeProvider.tsx","../src/hooks/usePendingToolCalls.ts","../src/hooks/use-webmcp-debug-tools.ts","../src/providers/AgentProvider.tsx","../src/public/AgentThread.tsx","../src/components/agent/ShadowRoot.tsx","../src/web-component.tsx"],"sourcesContent":["import { clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nimport type { ClassValue } from 'clsx'\n\n/**\n * Merges Tailwind CSS classes with proper precedence handling.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]): string {\n\treturn twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"@/utils/cn\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"fade-in-0 zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in text-balance rounded-md bg-foreground px-3 py-1.5 text-background text-xs data-[state=closed]:animate-out\",\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\n\nimport { cn } from \"@/utils/cn\";\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg outline-none duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg\",\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\"\n >\n <XIcon />\n <span className=\"wm:sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"font-semibold text-lg leading-none\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\n\nimport { cn } from \"@/utils/cn\";\n\nfunction Avatar({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn(\"aspect-square size-full\", className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n \"flex size-full items-center justify-center rounded-full bg-muted\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/utils/cn\";\n\nconst buttonVariants = cva(\n \"wm:inline-flex wm:shrink-0 wm:items-center wm:justify-center wm:gap-2 wm:whitespace-nowrap wm:rounded-md wm:font-medium wm:text-sm wm:outline-none wm:transition-all focus-visible:wm:border-ring focus-visible:wm:ring-[3px] focus-visible:wm:ring-ring/50 disabled:wm:pointer-events-none disabled:wm:opacity-50 aria-invalid:wm:border-destructive aria-invalid:wm:ring-destructive/20 dark:aria-invalid:wm:ring-destructive/40 [&_svg:not([class*='size-'])]:wm:size-4 [&_svg]:wm:pointer-events-none [&_svg]:wm:shrink-0\",\n {\n variants: {\n variant: {\n default: \"wm:bg-primary wm:text-primary-foreground hover:wm:bg-primary/90\",\n destructive:\n \"wm:bg-destructive wm:text-white hover:wm:bg-destructive/90 focus-visible:wm:ring-destructive/20 dark:wm:bg-destructive/60 dark:focus-visible:wm:ring-destructive/40\",\n outline:\n \"wm:border wm:bg-background wm:shadow-xs hover:wm:bg-accent hover:wm:text-accent-foreground dark:wm:border-input dark:wm:bg-input/30 dark:hover:wm:bg-input/50\",\n secondary:\n \"wm:bg-secondary wm:text-secondary-foreground hover:wm:bg-secondary/80\",\n ghost:\n \"hover:wm:bg-accent hover:wm:text-accent-foreground dark:hover:wm:bg-accent/50\",\n link: \"wm:text-primary wm:underline-offset-4 hover:wm:underline\",\n },\n size: {\n default: \"wm:h-9 wm:px-4 wm:py-2 has-[>svg]:wm:px-3\",\n sm: \"wm:h-8 wm:gap-1.5 wm:rounded-md wm:px-3 has-[>svg]:wm:px-2.5\",\n lg: \"wm:h-10 wm:rounded-md wm:px-6 has-[>svg]:wm:px-4\",\n icon: \"wm:size-9\",\n \"icon-sm\": \"wm:size-8\",\n \"icon-lg\": \"wm:size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport { forwardRef } from \"react\";\nimport type { ComponentPropsWithRef } from \"react\";\nimport { Slottable } from \"@radix-ui/react-slot\";\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/utils/cn\";\n\nexport type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {\n tooltip: string;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n};\n\nexport const TooltipIconButton = forwardRef<\n HTMLButtonElement,\n TooltipIconButtonProps\n>(({ children, tooltip, side = \"bottom\", className, ...rest }, ref) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n {...rest}\n className={cn(\"aui-button-icon wm:size-6 wm:p-1\", className)}\n ref={ref}\n >\n <Slottable>{children}</Slottable>\n <span className=\"aui-sr-only wm:sr-only\">{tooltip}</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side={side}>{tooltip}</TooltipContent>\n </Tooltip>\n );\n});\n\nTooltipIconButton.displayName = \"TooltipIconButton\";\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { FC, PropsWithChildren } from \"react\";\nimport { XIcon, PlusIcon, FileText } from \"lucide-react\";\nimport {\n AttachmentPrimitive,\n ComposerPrimitive,\n MessagePrimitive,\n useAssistantState,\n useAssistantApi,\n} from \"@assistant-ui/react\";\nimport { useShallow } from \"zustand/shallow\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Avatar, AvatarImage, AvatarFallback } from \"@/components/ui/avatar\";\nimport { TooltipIconButton } from \"@/components/assistant-ui/tooltip-icon-button\";\nimport { cn } from \"@/utils/cn\";\n\nconst useFileSrc = (file: File | undefined) => {\n const [src, setSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!file) {\n setSrc(undefined);\n return;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [file]);\n\n return src;\n};\n\nconst useAttachmentSrc = () => {\n const { file, src } = useAssistantState(\n useShallow(({ attachment }): { file?: File; src?: string } => {\n if (attachment.type !== \"image\") return {};\n if (attachment.file) return { file: attachment.file };\n const src = attachment.content?.filter((c) => c.type === \"image\")[0]\n ?.image;\n if (!src) return {};\n return { src };\n }),\n );\n\n return useFileSrc(file) ?? src;\n};\n\ntype AttachmentPreviewProps = {\n src: string;\n};\n\nconst AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {\n const [isLoaded, setIsLoaded] = useState(false);\n return (\n <img\n src={src}\n alt=\"Image Preview\"\n className={\n isLoaded\n ? \"aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain\"\n : \"aui-attachment-preview-image-loading hidden\"\n }\n onLoad={() => setIsLoaded(true)}\n />\n );\n};\n\nconst AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {\n const src = useAttachmentSrc();\n\n if (!src) return children;\n\n return (\n <Dialog>\n <DialogTrigger\n className=\"aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50\"\n asChild\n >\n {children}\n </DialogTrigger>\n <DialogContent className=\"aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0! [&_svg]:text-background [&>button]:hover:[&_svg]:text-destructive\">\n <DialogTitle className=\"aui-sr-only wm:sr-only\">\n Image Attachment Preview\n </DialogTitle>\n <div className=\"aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background\">\n <AttachmentPreview src={src} />\n </div>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst AttachmentThumb: FC = () => {\n const isImage = useAssistantState(\n ({ attachment }) => attachment.type === \"image\",\n );\n const src = useAttachmentSrc();\n\n return (\n <Avatar className=\"aui-attachment-tile-avatar h-full w-full rounded-none\">\n <AvatarImage\n src={src}\n alt=\"Attachment preview\"\n className=\"aui-attachment-tile-image object-cover\"\n />\n <AvatarFallback delayMs={isImage ? 200 : 0}>\n <FileText className=\"aui-attachment-tile-fallback-icon wm:size-8 wm:text-muted-foreground\" />\n </AvatarFallback>\n </Avatar>\n );\n};\n\nconst AttachmentUI: FC = () => {\n const api = useAssistantApi();\n const isComposer = api.attachment.source === \"composer\";\n\n const isImage = useAssistantState(\n ({ attachment }) => attachment.type === \"image\",\n );\n const typeLabel = useAssistantState(({ attachment }) => {\n const type = attachment.type;\n switch (type) {\n case \"image\":\n return \"Image\";\n case \"document\":\n return \"Document\";\n case \"file\":\n return \"File\";\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);\n }\n });\n\n return (\n <Tooltip>\n <AttachmentPrimitive.Root\n className={cn(\n \"aui-attachment-root relative\",\n isImage &&\n \"aui-attachment-root-composer only:[&>#attachment-tile]:size-24\",\n )}\n >\n <AttachmentPreviewDialog>\n <TooltipTrigger asChild>\n <div\n className={cn(\n \"aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75\",\n isComposer &&\n \"aui-attachment-tile-composer border-foreground/20\",\n )}\n role=\"button\"\n id=\"attachment-tile\"\n aria-label={`${typeLabel} attachment`}\n >\n <AttachmentThumb />\n </div>\n </TooltipTrigger>\n </AttachmentPreviewDialog>\n {isComposer && <AttachmentRemove />}\n </AttachmentPrimitive.Root>\n <TooltipContent side=\"top\">\n <AttachmentPrimitive.Name />\n </TooltipContent>\n </Tooltip>\n );\n};\n\nconst AttachmentRemove: FC = () => {\n return (\n <AttachmentPrimitive.Remove asChild>\n <TooltipIconButton\n tooltip=\"Remove file\"\n className=\"aui-attachment-tile-remove wm:absolute wm:top-1.5 wm:right-1.5 wm:size-3.5 wm:rounded-full wm:bg-white wm:text-muted-foreground wm:opacity-100 wm:shadow-sm hover:wm:bg-white! [&_svg]:wm:text-black hover:[&_svg]:wm:text-destructive\"\n side=\"top\"\n >\n <XIcon className=\"aui-attachment-remove-icon wm:size-3 dark:wm:stroke-[2.5px]\" />\n </TooltipIconButton>\n </AttachmentPrimitive.Remove>\n );\n};\n\nexport const UserMessageAttachments: FC = () => {\n return (\n <div className=\"aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2\">\n <MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />\n </div>\n );\n};\n\nexport const ComposerAttachments: FC = () => {\n return (\n <div className=\"aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden\">\n <ComposerPrimitive.Attachments\n components={{ Attachment: AttachmentUI }}\n />\n </div>\n );\n};\n\nexport const ComposerAddAttachment: FC = () => {\n return (\n <ComposerPrimitive.AddAttachment asChild>\n <TooltipIconButton\n tooltip=\"Add Attachment\"\n side=\"bottom\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"aui-composer-add-attachment wm:size-[34px] wm:rounded-full wm:p-1 wm:font-semibold wm:text-xs hover:wm:bg-muted-foreground/15 dark:wm:border-muted-foreground/15 dark:hover:wm:bg-muted-foreground/30\"\n aria-label=\"Add Attachment\"\n >\n <PlusIcon className=\"aui-attachment-add-icon wm:size-5 wm:stroke-[1.5px]\" />\n </TooltipIconButton>\n </ComposerPrimitive.AddAttachment>\n );\n};\n","\"use client\";\n\nimport \"@assistant-ui/react-markdown/styles/dot.css\";\n\nimport {\n type CodeHeaderProps,\n MarkdownTextPrimitive,\n unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,\n useIsMarkdownCodeBlock,\n} from \"@assistant-ui/react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { type FC, memo, useState } from \"react\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\n\nimport { TooltipIconButton } from \"@/components/assistant-ui/tooltip-icon-button\";\nimport { cn } from \"@/utils/cn\";\n\nconst MarkdownTextImpl = () => {\n return (\n <MarkdownTextPrimitive\n remarkPlugins={[remarkGfm]}\n className=\"aui-md\"\n components={defaultComponents}\n />\n );\n};\n\nexport const MarkdownText = memo(MarkdownTextImpl);\n\nconst CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {\n const { isCopied, copyToClipboard } = useCopyToClipboard();\n const onCopy = () => {\n if (!code || isCopied) return;\n copyToClipboard(code);\n };\n\n return (\n <div className=\"aui-code-header-root wm:mt-4 wm:flex wm:items-center wm:justify-between wm:gap-4 wm:rounded-t-lg wm:bg-code-header-bg wm:px-4 wm:py-2 wm:font-semibold wm:text-foreground wm:text-sm\">\n <span className=\"aui-code-header-language wm:lowercase [&>span]:wm:text-xs\">\n {language}\n </span>\n <TooltipIconButton tooltip=\"Copy\" onClick={onCopy}>\n {!isCopied && <CopyIcon className=\"wm:size-4\" />}\n {isCopied && <CheckIcon className=\"wm:size-4\" />}\n </TooltipIconButton>\n </div>\n );\n};\n\nconst useCopyToClipboard = ({\n copiedDuration = 3000,\n}: {\n copiedDuration?: number;\n} = {}) => {\n const [isCopied, setIsCopied] = useState<boolean>(false);\n\n const copyToClipboard = (value: string) => {\n if (!value) return;\n\n navigator.clipboard.writeText(value).then(() => {\n setIsCopied(true);\n setTimeout(() => setIsCopied(false), copiedDuration);\n });\n };\n\n return { isCopied, copyToClipboard };\n};\n\nconst defaultComponents = memoizeMarkdownComponents({\n h1: ({ className, ...props }) => (\n <h1\n className={cn(\n \"aui-md-h1 wm:mb-6 wm:scroll-m-20 wm:font-extrabold wm:text-2xl wm:tracking-tight last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n h2: ({ className, ...props }) => (\n <h2\n className={cn(\n \"aui-md-h2 wm:mt-6 wm:mb-3 wm:scroll-m-20 wm:font-semibold wm:text-xl wm:tracking-tight first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n h3: ({ className, ...props }) => (\n <h3\n className={cn(\n \"aui-md-h3 wm:mt-5 wm:mb-3 wm:scroll-m-20 wm:font-semibold wm:text-lg wm:tracking-tight first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n h4: ({ className, ...props }) => (\n <h4\n className={cn(\n \"aui-md-h4 wm:mt-4 wm:mb-2 wm:scroll-m-20 wm:font-semibold wm:text-base wm:tracking-tight first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n h5: ({ className, ...props }) => (\n <h5\n className={cn(\n \"aui-md-h5 wm:my-3 wm:font-semibold wm:text-sm first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n h6: ({ className, ...props }) => (\n <h6\n className={cn(\n \"aui-md-h6 wm:my-4 wm:font-semibold first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n p: ({ className, ...props }) => (\n <p\n className={cn(\n \"aui-md-p wm:mt-5 wm:mb-5 wm:leading-7 first:wm:mt-0 last:wm:mb-0\",\n className,\n )}\n {...props}\n />\n ),\n a: ({ className, ...props }) => (\n <a\n className={cn(\n \"aui-md-a wm:font-medium wm:text-primary wm:underline wm:underline-offset-4\",\n className,\n )}\n {...props}\n />\n ),\n blockquote: ({ className, ...props }) => (\n <blockquote\n className={cn(\"aui-md-blockquote wm:border-l-2 wm:pl-6 wm:italic\", className)}\n {...props}\n />\n ),\n ul: ({ className, ...props }) => (\n <ul\n className={cn(\"aui-md-ul wm:my-5 wm:ml-6 wm:list-disc [&>li]:wm:mt-2\", className)}\n {...props}\n />\n ),\n ol: ({ className, ...props }) => (\n <ol\n className={cn(\"aui-md-ol wm:my-5 wm:ml-6 wm:list-decimal [&>li]:wm:mt-2\", className)}\n {...props}\n />\n ),\n hr: ({ className, ...props }) => (\n <hr className={cn(\"aui-md-hr wm:my-5 wm:border-b\", className)} {...props} />\n ),\n table: ({ className, ...props }) => (\n <table\n className={cn(\n \"aui-md-table wm:my-5 wm:w-full wm:border-separate wm:border-spacing-0 wm:overflow-y-auto\",\n className,\n )}\n {...props}\n />\n ),\n th: ({ className, ...props }) => (\n <th\n className={cn(\n \"aui-md-th wm:bg-muted wm:px-4 wm:py-2 wm:text-left wm:font-bold first:wm:rounded-tl-lg last:wm:rounded-tr-lg [[align=center]]:wm:text-center [[align=right]]:wm:text-right\",\n className,\n )}\n {...props}\n />\n ),\n td: ({ className, ...props }) => (\n <td\n className={cn(\n \"aui-md-td wm:border-b wm:border-l wm:px-4 wm:py-2 wm:text-left last:wm:border-r [[align=center]]:wm:text-center [[align=right]]:wm:text-right\",\n className,\n )}\n {...props}\n />\n ),\n tr: ({ className, ...props }) => (\n <tr\n className={cn(\n \"aui-md-tr wm:m-0 wm:border-b wm:p-0 first:wm:border-t [&:last-child>td:first-child]:wm:rounded-bl-lg [&:last-child>td:last-child]:wm:rounded-br-lg\",\n className,\n )}\n {...props}\n />\n ),\n sup: ({ className, ...props }) => (\n <sup\n className={cn(\"aui-md-sup [&>a]:wm:text-xs [&>a]:wm:no-underline\", className)}\n {...props}\n />\n ),\n pre: ({ className, ...props }) => (\n <pre\n className={cn(\n \"aui-md-pre wm:overflow-x-auto wm:rounded-t-none! wm:rounded-b-lg wm:bg-code-bg wm:p-4 wm:text-code-text\",\n className,\n )}\n {...props}\n />\n ),\n code: function Code({ className, ...props }) {\n const isCodeBlock = useIsMarkdownCodeBlock();\n return (\n <code\n className={cn(\n !isCodeBlock &&\n \"aui-md-inline-code wm:rounded wm:border wm:bg-muted wm:font-semibold\",\n className,\n )}\n {...props}\n />\n );\n },\n CodeHeader,\n});\n","// src/primitive.tsx\nvar canUseDOM = !!(typeof window !== \"undefined\" && window.document && window.document.createElement);\nfunction composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {\n return function handleEvent(event) {\n originalEventHandler?.(event);\n if (checkForDefaultPrevented === false || !event.defaultPrevented) {\n return ourEventHandler?.(event);\n }\n };\n}\nfunction getOwnerWindow(element) {\n if (!canUseDOM) {\n throw new Error(\"Cannot access window outside of the DOM\");\n }\n return element?.ownerDocument?.defaultView ?? window;\n}\nfunction getOwnerDocument(element) {\n if (!canUseDOM) {\n throw new Error(\"Cannot access document outside of the DOM\");\n }\n return element?.ownerDocument ?? document;\n}\nfunction getActiveElement(node, activeDescendant = false) {\n const { activeElement } = getOwnerDocument(node);\n if (!activeElement?.nodeName) {\n return null;\n }\n if (isFrame(activeElement) && activeElement.contentDocument) {\n return getActiveElement(activeElement.contentDocument.body, activeDescendant);\n }\n if (activeDescendant) {\n const id = activeElement.getAttribute(\"aria-activedescendant\");\n if (id) {\n const element = getOwnerDocument(activeElement).getElementById(id);\n if (element) {\n return element;\n }\n }\n }\n return activeElement;\n}\nfunction isFrame(element) {\n return element.tagName === \"IFRAME\";\n}\nexport {\n canUseDOM,\n composeEventHandlers,\n getActiveElement,\n getOwnerDocument,\n getOwnerWindow,\n isFrame\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/context/src/create-context.tsx\nimport * as React from \"react\";\nimport { jsx } from \"react/jsx-runtime\";\nfunction createContext2(rootComponentName, defaultContext) {\n const Context = React.createContext(defaultContext);\n const Provider = (props) => {\n const { children, ...context } = props;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n };\n Provider.displayName = rootComponentName + \"Provider\";\n function useContext2(consumerName) {\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n return [Provider, useContext2];\n}\nfunction createContextScope(scopeName, createContextScopeDeps = []) {\n let defaultContexts = [];\n function createContext3(rootComponentName, defaultContext) {\n const BaseContext = React.createContext(defaultContext);\n const index = defaultContexts.length;\n defaultContexts = [...defaultContexts, defaultContext];\n const Provider = (props) => {\n const { scope, children, ...context } = props;\n const Context = scope?.[scopeName]?.[index] || BaseContext;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n };\n Provider.displayName = rootComponentName + \"Provider\";\n function useContext2(consumerName, scope) {\n const Context = scope?.[scopeName]?.[index] || BaseContext;\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n return [Provider, useContext2];\n }\n const createScope = () => {\n const scopeContexts = defaultContexts.map((defaultContext) => {\n return React.createContext(defaultContext);\n });\n return function useScope(scope) {\n const contexts = scope?.[scopeName] || scopeContexts;\n return React.useMemo(\n () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),\n [scope, contexts]\n );\n };\n };\n createScope.scopeName = scopeName;\n return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];\n}\nfunction composeContextScopes(...scopes) {\n const baseScope = scopes[0];\n if (scopes.length === 1) return baseScope;\n const createScope = () => {\n const scopeHooks = scopes.map((createScope2) => ({\n useScope: createScope2(),\n scopeName: createScope2.scopeName\n }));\n return function useComposedScopes(overrideScopes) {\n const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {\n const scopeProps = useScope(overrideScopes);\n const currentScope = scopeProps[`__scope${scopeName}`];\n return { ...nextScopes2, ...currentScope };\n }, {});\n return React.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);\n };\n };\n createScope.scopeName = baseScope.scopeName;\n return createScope;\n}\nexport {\n createContext2 as createContext,\n createContextScope\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/use-layout-effect/src/use-layout-effect.tsx\nimport * as React from \"react\";\nvar useLayoutEffect2 = globalThis?.document ? React.useLayoutEffect : () => {\n};\nexport {\n useLayoutEffect2 as useLayoutEffect\n};\n//# sourceMappingURL=index.mjs.map\n","// src/use-controllable-state.tsx\nimport * as React from \"react\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nvar useInsertionEffect = React[\" useInsertionEffect \".trim().toString()] || useLayoutEffect;\nfunction useControllableState({\n prop,\n defaultProp,\n onChange = () => {\n },\n caller\n}) {\n const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({\n defaultProp,\n onChange\n });\n const isControlled = prop !== void 0;\n const value = isControlled ? prop : uncontrolledProp;\n if (true) {\n const isControlledRef = React.useRef(prop !== void 0);\n React.useEffect(() => {\n const wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled) {\n const from = wasControlled ? \"controlled\" : \"uncontrolled\";\n const to = isControlled ? \"controlled\" : \"uncontrolled\";\n console.warn(\n `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`\n );\n }\n isControlledRef.current = isControlled;\n }, [isControlled, caller]);\n }\n const setValue = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;\n if (value2 !== prop) {\n onChangeRef.current?.(value2);\n }\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, onChangeRef]\n );\n return [value, setValue];\n}\nfunction useUncontrolledState({\n defaultProp,\n onChange\n}) {\n const [value, setValue] = React.useState(defaultProp);\n const prevValueRef = React.useRef(value);\n const onChangeRef = React.useRef(onChange);\n useInsertionEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n onChangeRef.current?.(value);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef]);\n return [value, setValue, onChangeRef];\n}\nfunction isFunction(value) {\n return typeof value === \"function\";\n}\n\n// src/use-controllable-state-reducer.tsx\nimport * as React2 from \"react\";\nimport { useEffectEvent } from \"@radix-ui/react-use-effect-event\";\nvar SYNC_STATE = Symbol(\"RADIX:SYNC_STATE\");\nfunction useControllableStateReducer(reducer, userArgs, initialArg, init) {\n const { prop: controlledState, defaultProp, onChange: onChangeProp, caller } = userArgs;\n const isControlled = controlledState !== void 0;\n const onChange = useEffectEvent(onChangeProp);\n if (true) {\n const isControlledRef = React2.useRef(controlledState !== void 0);\n React2.useEffect(() => {\n const wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled) {\n const from = wasControlled ? \"controlled\" : \"uncontrolled\";\n const to = isControlled ? \"controlled\" : \"uncontrolled\";\n console.warn(\n `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`\n );\n }\n isControlledRef.current = isControlled;\n }, [isControlled, caller]);\n }\n const args = [{ ...initialArg, state: defaultProp }];\n if (init) {\n args.push(init);\n }\n const [internalState, dispatch] = React2.useReducer(\n (state2, action) => {\n if (action.type === SYNC_STATE) {\n return { ...state2, state: action.state };\n }\n const next = reducer(state2, action);\n if (isControlled && !Object.is(next.state, state2.state)) {\n onChange(next.state);\n }\n return next;\n },\n ...args\n );\n const uncontrolledState = internalState.state;\n const prevValueRef = React2.useRef(uncontrolledState);\n React2.useEffect(() => {\n if (prevValueRef.current !== uncontrolledState) {\n prevValueRef.current = uncontrolledState;\n if (!isControlled) {\n onChange(uncontrolledState);\n }\n }\n }, [onChange, uncontrolledState, prevValueRef, isControlled]);\n const state = React2.useMemo(() => {\n const isControlled2 = controlledState !== void 0;\n if (isControlled2) {\n return { ...internalState, state: controlledState };\n }\n return internalState;\n }, [internalState, controlledState]);\n React2.useEffect(() => {\n if (isControlled && !Object.is(controlledState, internalState.state)) {\n dispatch({ type: SYNC_STATE, state: controlledState });\n }\n }, [controlledState, internalState.state, isControlled]);\n return [state, dispatch];\n}\nexport {\n useControllableState,\n useControllableStateReducer\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/compose-refs/src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","// src/primitive.tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { jsx } from \"react/jsx-runtime\";\nvar NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\"\n];\nvar Primitive = NODES.reduce((primitive, node) => {\n const Slot = createSlot(`Primitive.${node}`);\n const Node = React.forwardRef((props, forwardedRef) => {\n const { asChild, ...primitiveProps } = props;\n const Comp = asChild ? Slot : node;\n if (typeof window !== \"undefined\") {\n window[Symbol.for(\"radix-ui\")] = true;\n }\n return /* @__PURE__ */ jsx(Comp, { ...primitiveProps, ref: forwardedRef });\n });\n Node.displayName = `Primitive.${node}`;\n return { ...primitive, [node]: Node };\n}, {});\nfunction dispatchDiscreteCustomEvent(target, event) {\n if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));\n}\nvar Root = Primitive;\nexport {\n Primitive,\n Root,\n dispatchDiscreteCustomEvent\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/presence.tsx\nimport * as React2 from \"react\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\n\n// src/use-state-machine.tsx\nimport * as React from \"react\";\nfunction useStateMachine(initialState, machine) {\n return React.useReducer((state, event) => {\n const nextState = machine[state][event];\n return nextState ?? state;\n }, initialState);\n}\n\n// src/presence.tsx\nvar Presence = (props) => {\n const { present, children } = props;\n const presence = usePresence(present);\n const child = typeof children === \"function\" ? children({ present: presence.isPresent }) : React2.Children.only(children);\n const ref = useComposedRefs(presence.ref, getElementRef(child));\n const forceMount = typeof children === \"function\";\n return forceMount || presence.isPresent ? React2.cloneElement(child, { ref }) : null;\n};\nPresence.displayName = \"Presence\";\nfunction usePresence(present) {\n const [node, setNode] = React2.useState();\n const stylesRef = React2.useRef(null);\n const prevPresentRef = React2.useRef(present);\n const prevAnimationNameRef = React2.useRef(\"none\");\n const initialState = present ? \"mounted\" : \"unmounted\";\n const [state, send] = useStateMachine(initialState, {\n mounted: {\n UNMOUNT: \"unmounted\",\n ANIMATION_OUT: \"unmountSuspended\"\n },\n unmountSuspended: {\n MOUNT: \"mounted\",\n ANIMATION_END: \"unmounted\"\n },\n unmounted: {\n MOUNT: \"mounted\"\n }\n });\n React2.useEffect(() => {\n const currentAnimationName = getAnimationName(stylesRef.current);\n prevAnimationNameRef.current = state === \"mounted\" ? currentAnimationName : \"none\";\n }, [state]);\n useLayoutEffect(() => {\n const styles = stylesRef.current;\n const wasPresent = prevPresentRef.current;\n const hasPresentChanged = wasPresent !== present;\n if (hasPresentChanged) {\n const prevAnimationName = prevAnimationNameRef.current;\n const currentAnimationName = getAnimationName(styles);\n if (present) {\n send(\"MOUNT\");\n } else if (currentAnimationName === \"none\" || styles?.display === \"none\") {\n send(\"UNMOUNT\");\n } else {\n const isAnimating = prevAnimationName !== currentAnimationName;\n if (wasPresent && isAnimating) {\n send(\"ANIMATION_OUT\");\n } else {\n send(\"UNMOUNT\");\n }\n }\n prevPresentRef.current = present;\n }\n }, [present, send]);\n useLayoutEffect(() => {\n if (node) {\n let timeoutId;\n const ownerWindow = node.ownerDocument.defaultView ?? window;\n const handleAnimationEnd = (event) => {\n const currentAnimationName = getAnimationName(stylesRef.current);\n const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));\n if (event.target === node && isCurrentAnimation) {\n send(\"ANIMATION_END\");\n if (!prevPresentRef.current) {\n const currentFillMode = node.style.animationFillMode;\n node.style.animationFillMode = \"forwards\";\n timeoutId = ownerWindow.setTimeout(() => {\n if (node.style.animationFillMode === \"forwards\") {\n node.style.animationFillMode = currentFillMode;\n }\n });\n }\n }\n };\n const handleAnimationStart = (event) => {\n if (event.target === node) {\n prevAnimationNameRef.current = getAnimationName(stylesRef.current);\n }\n };\n node.addEventListener(\"animationstart\", handleAnimationStart);\n node.addEventListener(\"animationcancel\", handleAnimationEnd);\n node.addEventListener(\"animationend\", handleAnimationEnd);\n return () => {\n ownerWindow.clearTimeout(timeoutId);\n node.removeEventListener(\"animationstart\", handleAnimationStart);\n node.removeEventListener(\"animationcancel\", handleAnimationEnd);\n node.removeEventListener(\"animationend\", handleAnimationEnd);\n };\n } else {\n send(\"ANIMATION_END\");\n }\n }, [node, send]);\n return {\n isPresent: [\"mounted\", \"unmountSuspended\"].includes(state),\n ref: React2.useCallback((node2) => {\n stylesRef.current = node2 ? getComputedStyle(node2) : null;\n setNode(node2);\n }, [])\n };\n}\nfunction getAnimationName(styles) {\n return styles?.animationName || \"none\";\n}\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\nvar Root = Presence;\nexport {\n Presence,\n Root\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/id/src/id.tsx\nimport * as React from \"react\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nvar useReactId = React[\" useId \".trim().toString()] || (() => void 0);\nvar count = 0;\nfunction useId(deterministicId) {\n const [id, setId] = React.useState(useReactId());\n useLayoutEffect(() => {\n if (!deterministicId) setId((reactId) => reactId ?? String(count++));\n }, [deterministicId]);\n return deterministicId || (id ? `radix-${id}` : \"\");\n}\nexport {\n useId\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/collapsible.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { jsx } from \"react/jsx-runtime\";\nvar COLLAPSIBLE_NAME = \"Collapsible\";\nvar [createCollapsibleContext, createCollapsibleScope] = createContextScope(COLLAPSIBLE_NAME);\nvar [CollapsibleProvider, useCollapsibleContext] = createCollapsibleContext(COLLAPSIBLE_NAME);\nvar Collapsible = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeCollapsible,\n open: openProp,\n defaultOpen,\n disabled,\n onOpenChange,\n ...collapsibleProps\n } = props;\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: COLLAPSIBLE_NAME\n });\n return /* @__PURE__ */ jsx(\n CollapsibleProvider,\n {\n scope: __scopeCollapsible,\n disabled,\n contentId: useId(),\n open,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(open),\n \"data-disabled\": disabled ? \"\" : void 0,\n ...collapsibleProps,\n ref: forwardedRef\n }\n )\n }\n );\n }\n);\nCollapsible.displayName = COLLAPSIBLE_NAME;\nvar TRIGGER_NAME = \"CollapsibleTrigger\";\nvar CollapsibleTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeCollapsible, ...triggerProps } = props;\n const context = useCollapsibleContext(TRIGGER_NAME, __scopeCollapsible);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-controls\": context.contentId,\n \"aria-expanded\": context.open || false,\n \"data-state\": getState(context.open),\n \"data-disabled\": context.disabled ? \"\" : void 0,\n disabled: context.disabled,\n ...triggerProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nCollapsibleTrigger.displayName = TRIGGER_NAME;\nvar CONTENT_NAME = \"CollapsibleContent\";\nvar CollapsibleContent = React.forwardRef(\n (props, forwardedRef) => {\n const { forceMount, ...contentProps } = props;\n const context = useCollapsibleContext(CONTENT_NAME, props.__scopeCollapsible);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: ({ present }) => /* @__PURE__ */ jsx(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });\n }\n);\nCollapsibleContent.displayName = CONTENT_NAME;\nvar CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {\n const { __scopeCollapsible, present, children, ...contentProps } = props;\n const context = useCollapsibleContext(CONTENT_NAME, __scopeCollapsible);\n const [isPresent, setIsPresent] = React.useState(present);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const heightRef = React.useRef(0);\n const height = heightRef.current;\n const widthRef = React.useRef(0);\n const width = widthRef.current;\n const isOpen = context.open || isPresent;\n const isMountAnimationPreventedRef = React.useRef(isOpen);\n const originalStylesRef = React.useRef(void 0);\n React.useEffect(() => {\n const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);\n return () => cancelAnimationFrame(rAF);\n }, []);\n useLayoutEffect(() => {\n const node = ref.current;\n if (node) {\n originalStylesRef.current = originalStylesRef.current || {\n transitionDuration: node.style.transitionDuration,\n animationName: node.style.animationName\n };\n node.style.transitionDuration = \"0s\";\n node.style.animationName = \"none\";\n const rect = node.getBoundingClientRect();\n heightRef.current = rect.height;\n widthRef.current = rect.width;\n if (!isMountAnimationPreventedRef.current) {\n node.style.transitionDuration = originalStylesRef.current.transitionDuration;\n node.style.animationName = originalStylesRef.current.animationName;\n }\n setIsPresent(present);\n }\n }, [context.open, present]);\n return /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n \"data-disabled\": context.disabled ? \"\" : void 0,\n id: context.contentId,\n hidden: !isOpen,\n ...contentProps,\n ref: composedRefs,\n style: {\n [`--radix-collapsible-content-height`]: height ? `${height}px` : void 0,\n [`--radix-collapsible-content-width`]: width ? `${width}px` : void 0,\n ...props.style\n },\n children: isOpen && children\n }\n );\n});\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar Root = Collapsible;\nvar Trigger = CollapsibleTrigger;\nvar Content = CollapsibleContent;\nexport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n Content,\n Root,\n Trigger,\n createCollapsibleScope\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\";\n\nfunction Collapsible({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-trigger\"\n {...props}\n />\n );\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return (\n <CollapsiblePrimitive.CollapsibleContent\n data-slot=\"collapsible-content\"\n {...props}\n />\n );\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","\"use client\";\n\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\";\nimport {\n memo,\n useCallback,\n useRef,\n useState,\n type FC,\n type PropsWithChildren,\n} from \"react\";\n\nimport {\n useScrollLock,\n useAssistantState,\n type ReasoningMessagePartComponent,\n type ReasoningGroupComponent,\n} from \"@assistant-ui/react\";\n\nimport { MarkdownText } from \"@/components/assistant-ui/markdown-text\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/utils/cn\";\n\nconst ANIMATION_DURATION = 200;\n\n/**\n * Root collapsible container that manages open/closed state and scroll lock.\n * Provides animation timing via CSS variable and prevents scroll jumps on collapse.\n */\nconst ReasoningRoot: FC<\n PropsWithChildren<{\n className?: string;\n }>\n> = ({ className, children }) => {\n const collapsibleRef = useRef<HTMLDivElement>(null);\n const [isOpen, setIsOpen] = useState(false);\n const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) {\n lockScroll();\n }\n setIsOpen(open);\n },\n [lockScroll],\n );\n\n return (\n <Collapsible\n ref={collapsibleRef}\n open={isOpen}\n onOpenChange={handleOpenChange}\n className={cn(\"aui-reasoning-root mb-4 w-full\", className)}\n style={\n {\n \"--animation-duration\": `${ANIMATION_DURATION}ms`,\n } as React.CSSProperties\n }\n >\n {children}\n </Collapsible>\n );\n};\n\nReasoningRoot.displayName = \"ReasoningRoot\";\n\n/**\n * Gradient overlay that softens the bottom edge during expand/collapse animations.\n * Animation: Fades out with delay when opening and fades back in when closing.\n */\nconst GradientFade: FC<{ className?: string }> = ({ className }) => (\n <div\n className={cn(\n \"aui-reasoning-fade pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16\",\n \"bg-[linear-gradient(to_top,var(--color-background),transparent)]\",\n \"fade-in-0 animate-in\",\n \"group-data-[state=open]/collapsible-content:animate-out\",\n \"group-data-[state=open]/collapsible-content:fade-out-0\",\n \"group-data-[state=open]/collapsible-content:delay-[calc(var(--animation-duration)*0.75)]\", // calc for timing the delay\n \"group-data-[state=open]/collapsible-content:fill-mode-forwards\",\n \"duration-(--animation-duration)\",\n \"group-data-[state=open]/collapsible-content:duration-(--animation-duration)\",\n className,\n )}\n />\n);\n\n/**\n * Trigger button for the Reasoning collapsible.\n * Composed of icons, label, and text shimmer animation when reasoning is being streamed.\n */\nconst ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({\n active,\n className,\n}) => (\n <CollapsibleTrigger\n className={cn(\n \"aui-reasoning-trigger group/trigger -mb-2 flex max-w-[75%] items-center gap-2 py-2 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n >\n <BrainIcon className=\"aui-reasoning-trigger-icon wm:size-4 wm:shrink-0\" />\n <span className=\"aui-reasoning-trigger-label-wrapper relative inline-block leading-none\">\n <span>Reasoning</span>\n {active ? (\n <span\n aria-hidden\n className=\"aui-reasoning-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none\"\n >\n Reasoning\n </span>\n ) : null}\n </span>\n <ChevronDownIcon\n className={cn(\n \"aui-reasoning-trigger-chevron wm:mt-0.5 wm:size-4 wm:shrink-0\",\n \"wm:transition-transform wm:duration-(--animation-duration) wm:ease-out\",\n \"group-data-[state=closed]/trigger:wm:-rotate-90\",\n \"group-data-[state=open]/trigger:wm:rotate-0\",\n )}\n />\n </CollapsibleTrigger>\n);\n\n/**\n * Collapsible content wrapper that handles height expand/collapse animation.\n * Animation: Height animates up (collapse) and down (expand).\n * Also provides group context for child animations via data-state attributes.\n */\nconst ReasoningContent: FC<\n PropsWithChildren<{\n className?: string;\n \"aria-busy\"?: boolean;\n }>\n> = ({ className, children, \"aria-busy\": ariaBusy }) => (\n <CollapsibleContent\n className={cn(\n \"aui-reasoning-content relative overflow-hidden text-muted-foreground text-sm outline-none\",\n \"group/collapsible-content ease-out\",\n \"data-[state=closed]:animate-collapsible-up\",\n \"data-[state=open]:animate-collapsible-down\",\n \"data-[state=closed]:fill-mode-forwards\",\n \"data-[state=closed]:pointer-events-none\",\n \"data-[state=open]:duration-(--animation-duration)\",\n \"data-[state=closed]:duration-(--animation-duration)\",\n className,\n )}\n aria-busy={ariaBusy}\n >\n {children}\n <GradientFade />\n </CollapsibleContent>\n);\n\nReasoningContent.displayName = \"ReasoningContent\";\n\n/**\n * Text content wrapper that animates the reasoning text visibility.\n * Animation: Slides in from top + fades in when opening, reverses when closing.\n * Reacts to parent ReasoningContent's data-state via Radix group selectors.\n */\nconst ReasoningText: FC<\n PropsWithChildren<{\n className?: string;\n }>\n> = ({ className, children }) => (\n <div\n className={cn(\n \"aui-reasoning-text relative z-0 space-y-4 pt-4 pl-6 leading-relaxed\",\n \"transform-gpu transition-[transform,opacity]\",\n \"group-data-[state=open]/collapsible-content:animate-in\",\n \"group-data-[state=closed]/collapsible-content:animate-out\",\n \"group-data-[state=open]/collapsible-content:fade-in-0\",\n \"group-data-[state=closed]/collapsible-content:fade-out-0\",\n \"group-data-[state=open]/collapsible-content:slide-in-from-top-4\",\n \"group-data-[state=closed]/collapsible-content:slide-out-to-top-4\",\n \"group-data-[state=open]/collapsible-content:duration-(--animation-duration)\",\n \"group-data-[state=closed]/collapsible-content:duration-(--animation-duration)\",\n \"[&_p]:-mb-2\",\n className,\n )}\n >\n {children}\n </div>\n);\n\nReasoningText.displayName = \"ReasoningText\";\n\n/**\n * Renders a single reasoning part's text with markdown support.\n * Consecutive reasoning parts are automatically grouped by ReasoningGroup.\n *\n * Pass Reasoning to MessagePrimitive.Parts in thread.tsx\n *\n * @example:\n * ```tsx\n * <MessagePrimitive.Parts\n * components={{\n * Reasoning: Reasoning,\n * ReasoningGroup: ReasoningGroup,\n * }}\n * />\n * ```\n */\nconst ReasoningImpl: ReasoningMessagePartComponent = () => <MarkdownText />;\n\n/**\n * Collapsible wrapper that groups consecutive reasoning parts together.\n * Includes scroll lock to prevent page jumps during collapse animation.\n *\n * Pass ReasoningGroup to MessagePrimitive.Parts in thread.tsx\n *\n * @example:\n * ```tsx\n * <MessagePrimitive.Parts\n * components={{\n * Reasoning: Reasoning,\n * ReasoningGroup: ReasoningGroup,\n * }}\n * />\n * ```\n */\nconst ReasoningGroupImpl: ReasoningGroupComponent = ({\n children,\n startIndex,\n endIndex,\n}) => {\n /**\n * Detects if reasoning is currently streaming within this group's range.\n */\n const isReasoningStreaming = useAssistantState(({ message }) => {\n if (message.status?.type !== \"running\") return false;\n const lastIndex = message.parts.length - 1;\n if (lastIndex < 0) return false;\n const lastType = message.parts[lastIndex]?.type;\n if (lastType !== \"reasoning\") return false;\n return lastIndex >= startIndex && lastIndex <= endIndex;\n });\n\n return (\n <ReasoningRoot>\n <ReasoningTrigger active={isReasoningStreaming} />\n\n <ReasoningContent aria-busy={isReasoningStreaming}>\n <ReasoningText>{children}</ReasoningText>\n </ReasoningContent>\n </ReasoningRoot>\n );\n};\n\nexport const Reasoning = memo(ReasoningImpl);\nReasoning.displayName = \"Reasoning\";\n\nexport const ReasoningGroup = memo(ReasoningGroupImpl);\nReasoningGroup.displayName = \"ReasoningGroup\";\n","import { useEffect, useState } from 'react'\n\n/**\n * Hook that delays state updates by a specified duration.\n * Useful for preventing UI flash when state changes rapidly.\n *\n * @param value - The value to delay\n * @param delay - Delay in milliseconds\n * @returns The delayed value\n *\n * @example\n * ```tsx\n * // Delay showing approval UI to prevent flash\n * const hasPendingApproval = useDelayedState(hasPendingApprovalRaw, 100)\n * ```\n */\nexport function useDelayedState<T>(value: T, delay: number): T {\n\tconst [delayedValue, setDelayedValue] = useState(value)\n\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => setDelayedValue(value), delay)\n\t\treturn () => clearTimeout(timer)\n\t}, [value, delay])\n\n\treturn delayedValue\n}\n","/**\n * Shared Constants\n *\n * Centralized location for all magic numbers, timeouts, and configuration values.\n * Having these in one place makes the codebase more maintainable and easier to tune.\n */\n\n// ============================================================================\n// Mobile UX Constants\n// ============================================================================\n\n/**\n * Gesture configuration for touch interactions.\n *\n * Mobile swipe-to-dismiss requires an AGGRESSIVE upward swipe to prevent\n * accidental dismisses while allowing intentional quick swipes.\n */\nexport const GESTURE_CONFIG = {\n\t/** Minimum drag distance (px) before it counts as a drag (prevents tap interference) */\n\tdragActivationDistance: 15,\n\n\t/** Swipe-to-dismiss thresholds (mobile only) */\n\tswipe: {\n\t\t/** Must swipe at least this far (px) AND this fast to dismiss */\n\t\tminDistance: 100,\n\t\t/** Minimum velocity (px/s) required with minDistance */\n\t\tminVelocity: 800,\n\t\t/** OR swipe this fast (px/s) regardless of distance for quick flicks */\n\t\tvelocityOnlyThreshold: 1200,\n\t},\n} as const\n\n/**\n * Container sizing for different pill modes.\n * Uses CSS clamp() for fluid responsive sizing.\n *\n * Format: { min, preferred (vw), max }\n *\n * WCAG 2.5.8 (Level AA): Touch targets must be at least 24x24 CSS pixels\n * WCAG 2.5.5 (Level AAA): Touch targets should be at least 44x44 CSS pixels\n * We use 24px minimum for collapsed state to meet AA compliance.\n */\nexport const PILL_CONTAINER_SIZES = {\n\tcollapsed: { width: { min: 44, vw: 12, max: 56 }, height: { min: 24, vw: 6, max: 28 } },\n\thovered: { width: { min: 160, vw: 45, max: 180 }, height: { min: 36, vw: 9, max: 40 } },\n\tcomposing: { width: { min: 260, vw: 80, max: 340 } },\n\tactive: { width: { min: 260, vw: 80, max: 340 } },\n\texpanded: { width: { min: 280, vw: 85, max: 400 } },\n} as const\n\n/** Helper to generate CSS clamp() string from sizing config */\nexport function clampSize(config: { min: number; vw: number; max: number }): string {\n\treturn `clamp(${config.min}px, ${config.vw}vw, ${config.max}px)`\n}\n\n/** Auto-collapse timeout in milliseconds (inactivity before pill collapses) */\nexport const AUTO_COLLAPSE_TIMEOUT_MS = 30000\n\n/** Maximum character limit for composer input */\nexport const COMPOSER_MAX_CHARS = 4000\n\n/** Border radius values for pill states */\nexport const PILL_BORDER_RADIUS = {\n\t/** Pill shape (collapsed/hovered) */\n\tpill: '9999px',\n\t/** Rounded rectangle (expanded states) */\n\trounded: '16px',\n\t/** Inner elements (cards, buttons, etc.) */\n\tinner: '10px',\n\t/** Small elements (chips, badges) */\n\tsmall: '6px',\n} as const\n\n/**\n * Spacing scale for consistent padding/margins.\n * Uses a compact scale optimized for mobile information density.\n * Values in pixels - use with template literals: `${PILL_SPACING.sm}px`\n */\nexport const PILL_SPACING = {\n\t/** Extra small: 4px - minimal gaps */\n\txs: 4,\n\t/** Small: 6px - tight spacing */\n\tsm: 6,\n\t/** Medium: 8px - default spacing */\n\tmd: 8,\n\t/** Large: 10px - section spacing */\n\tlg: 10,\n\t/** Extra large: 12px - container padding */\n\txl: 12,\n} as const\n\n/**\n * Max heights for scrollable sections.\n * Mobile-first values (larger on mobile for easier touch scrolling).\n */\nexport const PILL_MAX_HEIGHTS = {\n\t/** Tools section: 160px mobile, 128px desktop */\n\ttools: { mobile: 160, desktop: 128 },\n\t/** Summary block: 128px mobile, 96px desktop */\n\tsummary: { mobile: 128, desktop: 96 },\n\t/** Composer input: 120px mobile, 96px desktop */\n\tcomposer: { mobile: 120, desktop: 96 },\n} as const\n\n/** Maximum number of prompt bubbles to show above collapsed pill */\nexport const MAX_PROMPT_BUBBLES = 3\n\n/** Debounce/delay values in milliseconds */\nexport const UI_TIMING = {\n\t/** Hover debounce before expanding */\n\thoverDebounce: 100,\n\t/** Delay before collapsing after mouse leave */\n\tcollapseDelay: 50,\n\t/** Copy button feedback duration */\n\tcopyFeedback: 2000,\n} as const\n\n/** Minimum height difference (px) to consider keyboard visible (avoids browser chrome false positives) */\nexport const KEYBOARD_VISIBILITY_THRESHOLD_PX = 100\n\n/** Gap (px) between pill and keyboard when keyboard is visible */\nexport const KEYBOARD_GAP_PX = 16\n\n/**\n * Drag interaction opacity configuration.\n * Lower opacity allows seeing content underneath while dragging (useful for mobile).\n */\nexport const DRAG_OPACITY = {\n\t/** Opacity while actively dragging (0.3 = mostly transparent to see underlying content) */\n\tdragging: 0.3,\n\t/** Normal opacity when not dragging */\n\tnormal: 1,\n} as const\n\n// ============================================================================\n// Full-Screen Mode Constants\n// ============================================================================\n\n/**\n * Full-screen mode sizing configuration.\n * Uses viewport units for responsive full-screen layout.\n */\nexport const FULL_SCREEN_CONFIG = {\n\t/** Maximum width of full-screen container */\n\tmaxWidth: '640px',\n\t/** Width as percentage of viewport */\n\twidthPercent: 95,\n\t/** Height as percentage of viewport */\n\theightPercent: 85,\n\t/** Padding inside the container */\n\tpadding: 16,\n} as const\n\n/**\n * Pinch gesture configuration for two-finger expand/collapse.\n */\nexport const PINCH_GESTURE_CONFIG = {\n\t/** Minimum scale change to trigger expand/collapse (30% = 0.3) */\n\tthreshold: 0.3,\n\t/** Minimum distance between fingers to start tracking (px) */\n\tminInitialDistance: 50,\n} as const\n\n// ============================================================================\n// Accessibility Constants\n// ============================================================================\n\n/** ARIA label IDs for accessibility */\nexport const ARIA_IDS = {\n\t/** ID for the pill dialog title (used with aria-labelledby) */\n\tpillTitle: 'agent-pill-title',\n\t/** ID for the pill dialog description (used with aria-describedby) */\n\tpillDescription: 'agent-pill-description',\n\t/** ID for the live region announcements */\n\tliveRegion: 'agent-pill-live-region',\n} as const\n\n/** ARIA labels for various UI elements */\nexport const ARIA_LABELS = {\n\topenAssistant: 'Open assistant',\n\tcloseAssistant: 'Close assistant',\n\tendVoiceSession: 'End voice session',\n\tdragHandle: 'Drag to reposition',\n\tsendMessage: 'Send message',\n\tvoiceInput: 'Start voice input',\n\texpandFullScreen: 'Expand to full screen',\n\tcollapseFullScreen: 'Collapse from full screen',\n} as const\n\n// ============================================================================\n// API Configuration\n// ============================================================================\n\n/** Production API base URL for WebMCP chat and token server */\nexport const WEBMCP_PRODUCTION_API_BASE = 'https://staging.meetchar.ai'\n\n// ============================================================================\n// MCP Connection Constants\n// ============================================================================\n\n/** Maximum number of reconnection attempts before giving up */\nexport const MCP_MAX_RECONNECT_ATTEMPTS = 5\n\n/** Base delay in milliseconds for exponential backoff reconnection */\nexport const MCP_BASE_RECONNECT_DELAY_MS = 1000\n\n/** Maximum reconnect delay in milliseconds (caps exponential backoff) */\nexport const MCP_MAX_RECONNECT_DELAY_MS = 30000\n\n/** Delay before auto-connecting to tab-based MCP sources (allows server initialization) */\nexport const MCP_TAB_CONNECT_DELAY_MS = 100\n\n// ============================================================================\n// Voice Mode / Realtime API Constants\n// ============================================================================\n\n/** Number of frequency bins for audio visualization */\nexport const AUDIO_FREQUENCY_BINS = 32\n\n/** Default OpenAI Realtime model */\nexport const REALTIME_DEFAULT_MODEL = 'gpt-realtime'\n\n/** Default voice for OpenAI Realtime */\nexport const REALTIME_DEFAULT_VOICE = 'echo'\n\n/** Default OpenAI Realtime API URL */\nexport const REALTIME_DEFAULT_API_URL = 'https://api.openai.com/v1/realtime'\n\n/** Interval in milliseconds for audio visualization updates (~60fps) */\nexport const AUDIO_VISUALIZATION_INTERVAL_MS = 16\n\n/** Delay in milliseconds before requesting response after tool execution */\nexport const RESPONSE_REQUEST_DELAY_MS = 150\n\n/** Duration to show completed tool calls before clearing (success) */\nexport const TOOL_CALL_DISPLAY_DURATION_MS = 1500\n\n/** Duration to show failed tool calls before clearing (error) */\nexport const TOOL_CALL_ERROR_DISPLAY_DURATION_MS = 3000\n\n/** Duration to retain voice actions after session ends (for display) */\nexport const VOICE_ACTIONS_RETENTION_MS = 3000\n\n/** Duration to retain voice summary after session ends */\nexport const VOICE_SUMMARY_RETENTION_MS = 30000\n\n// ============================================================================\n// Voice Tool Approval Constants\n// ============================================================================\n\n/** Timeout before auto-deny when waiting for voice approval (30 seconds) */\nexport const VOICE_APPROVAL_TIMEOUT_MS = 30000\n\n/** Interval for countdown timer updates */\nexport const VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS = 1000\n\n/**\n * Keywords that trigger approval or denial.\n * Uses word boundary matching for safety (prevents \"yesterday\" matching \"yes\").\n */\nexport const VOICE_APPROVAL_KEYWORDS = {\n\tapprove: ['approve', 'yes', 'confirm', 'allow', 'go ahead', 'do it', 'proceed'],\n\tdeny: ['deny', 'no', 'cancel', 'stop', 'reject', \"don't\", 'dont'],\n} as const\n\n/**\n * Tool result messages for voice mode approvals.\n * Used when syncing voice approval results to the thread.\n */\nexport const VOICE_TOOL_RESULT_MESSAGES = {\n\t/** Message when tool was approved and executed in voice mode */\n\thandled: '[Handled in voice mode]',\n\t/** Message when voice session ended with pending approvals */\n\tsessionEnded: '[Voice session ended]',\n} as const\n\n// ============================================================================\n// Waveform Visualization Constants\n// ============================================================================\n\n/** Default history size for scrolling waveform mode */\nexport const WAVEFORM_HISTORY_SIZE = 60\n\n/** Update rate in milliseconds for waveform visualization */\nexport const WAVEFORM_UPDATE_RATE_MS = 30\n\n// ============================================================================\n// WebSocket States (for type-safe comparisons)\n// ============================================================================\n\n/** WebSocket OPEN state value */\nexport const WEBSOCKET_OPEN = 1\n\n// ============================================================================\n// Logging Configuration\n// ============================================================================\n\n/**\n * Enable debug logging for development.\n * Can be enabled by setting window.__WEBMCP_DEBUG__ = true in the browser console.\n * In production builds, this defaults to false.\n */\nexport const DEBUG_LOGGING_ENABLED =\n\ttypeof window !== 'undefined' &&\n\t(window as { __WEBMCP_DEBUG__?: boolean }).__WEBMCP_DEBUG__ === true\n\n/**\n * Conditional debug logger that only logs when DEBUG_LOGGING_ENABLED is true.\n * Can be enabled at runtime by setting window.__WEBMCP_DEBUG__ = true\n *\n * @param component - The component or service name for the log prefix\n * @param message - The log message\n * @param data - Optional data to include in the log\n */\nexport function debugLog(component: string, message: string, data?: unknown): void {\n\t// Check the flag at runtime to allow enabling after page load\n\tconst isDebugEnabled =\n\t\ttypeof window !== 'undefined' &&\n\t\t(window as { __WEBMCP_DEBUG__?: boolean }).__WEBMCP_DEBUG__ === true\n\n\tif (isDebugEnabled) {\n\t\tif (data !== undefined) {\n\t\t\tconsole.log(`[${component}] ${message}`, data)\n\t\t} else {\n\t\t\tconsole.log(`[${component}] ${message}`)\n\t\t}\n\t}\n}\n","/**\n * MCP Transport Utilities\n *\n * Shared transport creation logic for MCP sources.\n * This eliminates duplication between MCPToolsProvider and useMCPSource.\n */\nimport { TabClientTransport } from '@mcp-b/transports'\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\n\nimport type { MCPSourceConfig } from '@mcp-b/cloud-mirror-types'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\n\n/**\n * Transport type options for HTTP-based connections\n */\nexport type TransportType = 'http' | 'sse'\n\n/**\n * Creates the appropriate MCP transport based on source configuration.\n *\n * @param config - The MCP source configuration\n * @param transportType - For HTTP sources, specifies whether to use HTTP or SSE transport\n * @returns A configured MCP Transport instance\n *\n * @example Tab-based transport (same-tab or iframe)\n * ```ts\n * const transport = createMCPTransport({ type: 'tab' })\n * ```\n *\n * @example HTTP transport with auth\n * ```ts\n * const transport = createMCPTransport({\n * type: 'http',\n * url: 'https://example.com/mcp',\n * authToken: 'secret'\n * }, 'http')\n * ```\n */\nexport function createMCPTransport(\n\tconfig: MCPSourceConfig,\n\ttransportType: TransportType = 'http'\n): Transport {\n\tif (config.type === 'tab') {\n\t\treturn new TabClientTransport({\n\t\t\ttargetOrigin: config.targetOrigin ?? window.location.origin,\n\t\t\tchannelId: config.channelId ?? 'mcp-default',\n\t\t})\n\t}\n\n\t// HTTP/SSE transport configuration\n\tconst serverUrl = new URL(config.url)\n\tconst headers: Record<string, string> = {\n\t\tAccept: 'application/json, text/event-stream',\n\t\t...(config.customHeaders ?? {}),\n\t}\n\n\tif (config.authToken) {\n\t\theaders.Authorization = `Bearer ${config.authToken}`\n\t}\n\n\tconst transportOptions = {\n\t\trequestInit: { headers },\n\t}\n\n\tif (transportType === 'sse') {\n\t\treturn new SSEClientTransport(serverUrl, transportOptions)\n\t}\n\n\treturn new StreamableHTTPClientTransport(serverUrl, transportOptions)\n}\n\n/**\n * Check if an error indicates we should try SSE fallback.\n *\n * This handles cases where HTTP streaming isn't supported (404/405) or\n * when the connection fails due to CORS/network issues.\n *\n * @param error - The error from the failed HTTP connection\n * @returns true if the error suggests trying SSE transport instead\n */\nexport function shouldFallbackToSSE(error: Error): boolean {\n\tconst message = error.message\n\treturn (\n\t\tmessage.includes('404') ||\n\t\tmessage.includes('Not Found') ||\n\t\tmessage.includes('405') ||\n\t\tmessage.includes('Method Not Allowed') ||\n\t\tmessage === 'Failed to fetch' || // Chrome CORS\n\t\tmessage === 'NetworkError when attempting to fetch resource.' || // Firefox\n\t\tmessage === 'Load failed' // Safari\n\t)\n}\n\n/**\n * Calculate exponential backoff delay for reconnection attempts.\n *\n * @param attempt - The current attempt number (0-based)\n * @param baseDelay - Base delay in milliseconds\n * @param maxDelay - Maximum delay cap in milliseconds\n * @returns The calculated delay in milliseconds\n */\nexport function calculateReconnectDelay(\n\tattempt: number,\n\tbaseDelay: number,\n\tmaxDelay: number\n): number {\n\treturn Math.min(baseDelay * Math.pow(2, attempt), maxDelay)\n}\n","const SOURCE_ID_RE = /^[0-9a-z]{4}$/i\n\n/**\n * ThreadManager namespaces tools as: `${sourceId}_${toolName}`.\n * sourceId is the 4-character connection identifier (ephemeral, changes on reconnect).\n * For UI and local execution, we usually want the original tool name.\n */\nexport function parseSourceScopedToolName(\n\tname: string,\n): { sourceId: string; toolName: string } | null {\n\tconst separatorIndex = name.indexOf('_')\n\tif (separatorIndex === -1) return null\n\n\tconst sourceId = name.slice(0, separatorIndex)\n\tconst toolName = name.slice(separatorIndex + 1)\n\n\tif (!sourceId || !toolName) return null\n\tif (!SOURCE_ID_RE.test(sourceId)) return null\n\n\treturn { sourceId, toolName }\n}\n\nexport function stripSourceScopedToolName(name: string): string {\n\treturn parseSourceScopedToolName(name)?.toolName ?? name\n}\n","/**\n * MCP Tools Provider\n *\n * Simplified provider for managing tools from multiple MCP sources.\n * Sources can be tab-based (same-tab, iframes) or HTTP-based (remote servers).\n *\n * @example Basic usage\n * ```tsx\n * <MCPToolsProvider>\n * <App />\n * </MCPToolsProvider>\n * ```\n *\n * @example Using the hook\n * ```tsx\n * const { tools, addSource, callTool } = useMCPTools()\n * await addSource('remote', { type: 'http', url: 'http://localhost:8888/mcp' })\n * ```\n */\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport {\n\tPromptListChangedNotificationSchema,\n\tToolListChangedNotificationSchema,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { MCP_TAB_CONNECT_DELAY_MS } from '../utils/constants'\nimport { createMCPTransport } from '../utils/mcp-transport'\nimport { stripSourceScopedToolName } from '../utils/tool-names'\n\nimport type {\n\tCallToolResult,\n\tGetPromptResult,\n\tMCPSource,\n\tMCPSourceConfig,\n\tPrompt,\n\tResource,\n\tResourceTemplate,\n\tToolWithSource,\n} from '@mcp-b/cloud-mirror-types'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport type { ReactNode } from 'react'\n\n/** Well-known source IDs */\nexport const SOURCE_LOCAL = 'local'\nexport const SOURCE_REMOTE = 'remote'\n\n/** Internal source state with client reference */\ninterface SourceState extends Omit<MCPSource, 'resources' | 'resourceTemplates' | 'prompts'> {\n\tclient: Client | null\n\ttransport: Transport | null\n\tresources: Resource[]\n\tresourceTemplates: ResourceTemplate[]\n\tprompts: Prompt[]\n}\n\n/**\n * Tracks an in-flight tool call with its abort controller.\n *\n * Note: Aborting a call only affects the caller side (the promise race).\n * The underlying tool execution in the MCP server/handler may continue\n * to completion - this is a limitation of the MCP protocol which doesn't\n * support cancellation. The abort ensures the caller gets a timely error\n * response rather than waiting for a tool that's no longer relevant.\n */\ninterface InflightToolCall {\n\t/** The tool name being called */\n\ttoolName: string\n\t/** The source ID the tool belongs to */\n\tsourceId: string\n\t/** Abort controller to cancel the call */\n\tabortController: AbortController\n}\n\n/**\n * MCP Tools Context Value\n */\nexport interface MCPToolsContextValue {\n\t/** All tools from all sources, tagged with _sourceId */\n\ttools: ToolWithSource[]\n\n\t/** All prompts from all sources */\n\tprompts: Prompt[]\n\n\t/** All sources and their states */\n\tsources: Map<string, MCPSource>\n\n\t/** Add a new source */\n\taddSource: (id: string, config: MCPSourceConfig) => Promise<void>\n\n\t/** Remove a source */\n\tremoveSource: (id: string) => Promise<void>\n\n\t/** Get a specific source */\n\tgetSource: (id: string) => MCPSource | undefined\n\n\t/** Check if a source is connected */\n\tisConnected: (id: string) => boolean\n\n\t/** Call a tool (auto-routes based on tool name lookup) */\n\tcallTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\n\t/** Call a tool on a specific source */\n\tcallToolOnSource: (\n\t\tsourceId: string,\n\t\tname: string,\n\t\targs: Record<string, unknown>\n\t) => Promise<CallToolResult>\n\n\t/** Get a prompt's expanded content (auto-routes based on prompt name lookup) */\n\tgetPrompt: (name: string, args?: Record<string, string>) => Promise<GetPromptResult>\n\n\t/**\n\t * Refresh tools from all connected sources.\n\t * Call this after dynamically registering tools via useWebMCP inside the provider tree.\n\t */\n\trefreshTools: () => Promise<void>\n}\n\nconst MCPToolsContext = createContext<MCPToolsContextValue | null>(null)\n\nexport interface MCPToolsProviderProps {\n\tchildren: ReactNode\n\t/** Auto-connect to same-tab source on mount (default: true) */\n\tautoConnectLocal?: boolean\n\t/** Callback when tools change */\n\tonToolsChange?: (tools: ToolWithSource[]) => void\n\t/** Callback when prompts change */\n\tonPromptsChange?: (prompts: Prompt[]) => void\n}\n\nexport function MCPToolsProvider({\n\tchildren,\n\tautoConnectLocal = true,\n\tonToolsChange,\n\tonPromptsChange,\n}: MCPToolsProviderProps) {\n\t// Sources map (internal state with client references)\n\tconst sourcesRef = useRef<Map<string, SourceState>>(new Map())\n\n\t// Track in-flight tool calls for abort handling\n\tconst inflightCallsRef = useRef<Map<string, InflightToolCall>>(new Map())\n\n\t// Counter for generating unique call IDs\n\tconst callIdCounterRef = useRef(0)\n\n\t// Trigger re-renders when sources change\n\tconst [, forceUpdate] = useState({})\n\n\t// Derived tools list\n\tconst [toolsList, setToolsList] = useState<ToolWithSource[]>([])\n\n\t// Derived prompts list\n\tconst [promptsList, setPromptsList] = useState<Prompt[]>([])\n\n\t/**\n\t * Abort in-flight tool calls for tools that are no longer available.\n\t * Called after the tool list changes to clean up orphaned calls.\n\t */\n\tconst abortOrphanedCalls = useCallback((currentTools: ToolWithSource[]) => {\n\t\tconst currentToolNames = new Set(currentTools.map((t) => t.name))\n\n\t\tinflightCallsRef.current.forEach((call, callId) => {\n\t\t\tif (!currentToolNames.has(call.toolName)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[MCPToolsProvider] Aborting orphaned tool call: ${call.toolName} (call ID: ${callId})`\n\t\t\t\t)\n\t\t\t\tcall.abortController.abort(new Error(`Tool '${call.toolName}' is no longer available`))\n\t\t\t\tinflightCallsRef.current.delete(callId)\n\t\t\t}\n\t\t})\n\t}, [])\n\n\t/**\n\t * Rebuild tools list from all sources\n\t */\n\tconst rebuildTools = useCallback(() => {\n\t\tconst allTools: ToolWithSource[] = []\n\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tsource.tools.forEach((tool) => {\n\t\t\t\tallTools.push({\n\t\t\t\t\t...tool,\n\t\t\t\t\t_sourceId: source.id,\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\t// Abort any in-flight calls for tools that are no longer in the list\n\t\tabortOrphanedCalls(allTools)\n\n\t\tsetToolsList(allTools)\n\t}, [abortOrphanedCalls])\n\n\t/**\n\t * Rebuild prompts list from all sources\n\t */\n\tconst rebuildPrompts = useCallback(() => {\n\t\tconst allPrompts: Prompt[] = []\n\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tsource.prompts.forEach((prompt) => {\n\t\t\t\tallPrompts.push(prompt)\n\t\t\t})\n\t\t})\n\n\t\tsetPromptsList(allPrompts)\n\t}, [])\n\n\t/**\n\t * Get public source state (without client reference)\n\t */\n\tconst getPublicSource = useCallback((source: SourceState): MCPSource => {\n\t\treturn {\n\t\t\tid: source.id,\n\t\t\tconfig: source.config,\n\t\t\tstate: source.state,\n\t\t\terror: source.error,\n\t\t\ttools: source.tools,\n\t\t\tresources: source.resources,\n\t\t\tresourceTemplates: source.resourceTemplates,\n\t\t\tprompts: source.prompts,\n\t\t}\n\t}, [])\n\n\t/**\n\t * Add a new source\n\t */\n\tconst addSource = useCallback(\n\t\tasync (id: string, config: MCPSourceConfig): Promise<void> => {\n\t\t\t// Remove existing source if any\n\t\t\tif (sourcesRef.current.has(id)) {\n\t\t\t\tawait removeSource(id)\n\t\t\t}\n\n\t\t\t// Create initial state\n\t\t\tconst sourceState: SourceState = {\n\t\t\t\tid,\n\t\t\t\tconfig,\n\t\t\t\tstate: 'connecting',\n\t\t\t\terror: null,\n\t\t\t\ttools: [],\n\t\t\t\tresources: [],\n\t\t\t\tresourceTemplates: [],\n\t\t\t\tprompts: [],\n\t\t\t\tclient: null,\n\t\t\t\ttransport: null,\n\t\t\t}\n\n\t\t\tsourcesRef.current.set(id, sourceState)\n\t\t\tforceUpdate({})\n\n\t\t\ttry {\n\t\t\t\t// Create client and transport\n\t\t\t\tconst client = new Client({\n\t\t\t\t\tname: `MCP-Source-${id}`,\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t})\n\n\t\t\t\tconst transport = createMCPTransport(config)\n\n\t\t\t\t// Connect\n\t\t\t\tawait client.connect(transport)\n\n\t\t\t\t// Update state with client\n\t\t\t\tsourceState.client = client\n\t\t\t\tsourceState.transport = transport\n\n\t\t\t\t// Get initial tools and prompts\n\t\t\t\tconst { tools } = await client.listTools()\n\t\t\t\tsourceState.tools = tools\n\n\t\t\t\t// Get initial prompts (wrapped in try-catch as some servers may not support prompts)\n\t\t\t\ttry {\n\t\t\t\t\tconst { prompts } = await client.listPrompts()\n\t\t\t\t\tsourceState.prompts = prompts\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.warn(`[MCPToolsProvider:${id}] Server does not support prompts:`, err)\n\t\t\t\t\tsourceState.prompts = []\n\t\t\t\t}\n\n\t\t\t\tsourceState.state = 'connected'\n\n\t\t\t\t// Listen for tool updates\n\t\t\t\tclient.setNotificationHandler(ToolListChangedNotificationSchema, async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst updated = await client.listTools()\n\t\t\t\t\t\tsourceState.tools = updated.tools\n\t\t\t\t\t\trebuildTools()\n\t\t\t\t\t\tforceUpdate({})\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Failed to update tools:`, err)\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\t// Listen for prompt updates\n\t\t\t\tclient.setNotificationHandler(PromptListChangedNotificationSchema, async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst updated = await client.listPrompts()\n\t\t\t\t\t\tsourceState.prompts = updated.prompts\n\t\t\t\t\t\trebuildPrompts()\n\t\t\t\t\t\tforceUpdate({})\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Failed to update prompts:`, err)\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\trebuildTools()\n\t\t\t\trebuildPrompts()\n\t\t\t\tforceUpdate({})\n\t\t\t} catch (err) {\n\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err))\n\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Connection failed:`, error)\n\n\t\t\t\tsourceState.state = 'error'\n\t\t\t\tsourceState.error = error\n\t\t\t\tforceUpdate({})\n\t\t\t}\n\t\t},\n\t\t[rebuildTools, rebuildPrompts]\n\t)\n\n\t/**\n\t * Remove a source\n\t */\n\tconst removeSource = useCallback(\n\t\tasync (id: string): Promise<void> => {\n\t\t\tconst source = sourcesRef.current.get(id)\n\t\t\tif (!source) return\n\n\t\t\t// Close client and transport\n\t\t\tif (source.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.client.close()\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Error closing client:`, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (source.transport) {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.transport.close()\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(`[MCPToolsProvider:${id}] Error closing transport:`, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsourcesRef.current.delete(id)\n\t\t\trebuildTools()\n\t\t\trebuildPrompts()\n\t\t\tforceUpdate({})\n\t\t},\n\t\t[rebuildTools, rebuildPrompts]\n\t)\n\n\t/**\n\t * Get a source by ID\n\t */\n\tconst getSource = useCallback(\n\t\t(id: string): MCPSource | undefined => {\n\t\t\tconst source = sourcesRef.current.get(id)\n\t\t\treturn source ? getPublicSource(source) : undefined\n\t\t},\n\t\t[getPublicSource]\n\t)\n\n\t/**\n\t * Check if a source is connected\n\t */\n\tconst isConnected = useCallback((id: string): boolean => {\n\t\tconst source = sourcesRef.current.get(id)\n\t\treturn source?.state === 'connected'\n\t}, [])\n\n\t/**\n\t * Call a tool on a specific source with in-flight tracking and abort support.\n\t * If the tool is removed while the call is in progress, the call will be aborted.\n\t */\n\tconst callToolOnSource = useCallback(\n\t\tasync (\n\t\t\tsourceId: string,\n\t\t\tname: string,\n\t\t\targs: Record<string, unknown>\n\t\t): Promise<CallToolResult> => {\n\t\t\tconst source = sourcesRef.current.get(sourceId)\n\t\t\tif (!source?.client) {\n\t\t\t\tthrow new Error(`Source '${sourceId}' not connected`)\n\t\t\t}\n\n\t\t\t// Generate unique call ID and create abort controller\n\t\t\tconst callId = `${sourceId}-${name}-${++callIdCounterRef.current}`\n\t\t\tconst abortController = new AbortController()\n\n\t\t\t// Register in-flight call\n\t\t\tinflightCallsRef.current.set(callId, {\n\t\t\t\ttoolName: name,\n\t\t\t\tsourceId,\n\t\t\t\tabortController,\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\t// Create a promise that rejects when aborted\n\t\t\t\tconst abortPromise = new Promise<never>((_, reject) => {\n\t\t\t\t\tconst signal = abortController.signal\n\n\t\t\t\t\t// Handle already-aborted signal (race condition prevention)\n\t\t\t\t\tif (signal.aborted) {\n\t\t\t\t\t\treject(signal.reason || new Error(`Tool '${name}' call was aborted`))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// Use { once: true } to auto-cleanup the listener\n\t\t\t\t\tsignal.addEventListener(\n\t\t\t\t\t\t'abort',\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\treject(signal.reason || new Error(`Tool '${name}' call was aborted`))\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ once: true }\n\t\t\t\t\t)\n\t\t\t\t})\n\n\t\t\t\t// Race between the actual tool call and the abort signal\n\t\t\t\tconst result = await Promise.race([\n\t\t\t\t\tsource.client.callTool({ name, arguments: args }),\n\t\t\t\t\tabortPromise,\n\t\t\t\t])\n\n\t\t\t\treturn result as CallToolResult\n\t\t\t} catch (error) {\n\t\t\t\t// Check if this was an abort\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\t// Return an error result for aborted calls\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\t\t\ttext: `Tool call aborted: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\t// Clean up the in-flight tracking\n\t\t\t\tinflightCallsRef.current.delete(callId)\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\t/**\n\t * Call a tool (auto-routes based on tool name)\n\t */\n\t\tconst callTool = useCallback(\n\t\t\tasync (name: string, args: Record<string, unknown>): Promise<CallToolResult> => {\n\t\t\t\t// Find which source has this tool.\n\t\t\t\t// When running against thread-based runtimes, tools may be namespaced as `${sourceId}_${toolName}`.\n\t\t\t\tconst tool =\n\t\t\t\t\ttoolsList.find((t) => t.name === name) ??\n\t\t\t\t\t(() => {\n\t\t\t\t\t\tconst stripped = stripSourceScopedToolName(name)\n\t\t\t\t\t\treturn stripped === name ? undefined : toolsList.find((t) => t.name === stripped)\n\t\t\t\t\t})()\n\t\t\t\tif (!tool) {\n\t\t\t\t\tthrow new Error(`Tool '${name}' not found`)\n\t\t\t\t}\n\n\t\t\t\treturn callToolOnSource(tool._sourceId, tool.name, args)\n\t\t\t},\n\t\t\t[toolsList, callToolOnSource]\n\t\t)\n\n\t/**\n\t * Get a prompt's expanded content (auto-routes based on prompt name)\n\t */\n\tconst getPrompt = useCallback(\n\t\tasync (name: string, args?: Record<string, string>): Promise<GetPromptResult> => {\n\t\t\t// Find which source has this prompt\n\t\t\tfor (const source of sourcesRef.current.values()) {\n\t\t\t\tconst hasPrompt = source.prompts.some((p) => p.name === name)\n\t\t\t\tif (hasPrompt && source.client) {\n\t\t\t\t\treturn (await source.client.getPrompt({ name, arguments: args })) as GetPromptResult\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(`Prompt '${name}' not found`)\n\t\t},\n\t\t[]\n\t)\n\n\t/**\n\t * Refresh tools from all connected sources.\n\t * Call this after dynamically registering tools via useWebMCP inside the provider tree.\n\t * This is needed because tools registered after the initial connection may not\n\t * trigger a ToolListChangedNotification that the client receives.\n\t */\n\tconst refreshTools = useCallback(async () => {\n\t\tconsole.debug('[MCPToolsProvider] Refreshing tools from all sources')\n\t\tfor (const source of sourcesRef.current.values()) {\n\t\t\tif (source.client && source.state === 'connected') {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await source.client.listTools()\n\t\t\t\t\tsource.tools = tools\n\t\t\t\t\tconsole.debug(`[MCPToolsProvider:${source.id}] Refreshed ${tools.length} tools`)\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(`[MCPToolsProvider:${source.id}] Failed to refresh tools:`, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\trebuildTools()\n\t}, [rebuildTools])\n\n\t/**\n\t * Get sources map for context (public view).\n\t *\n\t * Note: This useMemo reads from sourcesRef but depends on toolsList/promptsList.\n\t * This is intentional - toolsList and promptsList are derived from sourcesRef,\n\t * so when they change, it means sourcesRef has changed and we need to rebuild\n\t * the public view. This avoids exposing sourcesRef as a dependency while still\n\t * triggering recomputation when source data changes.\n\t */\n\tconst sources = useMemo(() => {\n\t\tconst publicSources = new Map<string, MCPSource>()\n\t\tsourcesRef.current.forEach((source) => {\n\t\t\tpublicSources.set(source.id, getPublicSource(source))\n\t\t})\n\t\treturn publicSources\n\t}, [toolsList, promptsList, getPublicSource])\n\n\t// Auto-connect to local source on mount\n\tuseEffect(() => {\n\t\tif (autoConnectLocal) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tvoid addSource(SOURCE_LOCAL, { type: 'tab' })\n\t\t\t}, MCP_TAB_CONNECT_DELAY_MS)\n\t\t\treturn () => clearTimeout(timer)\n\t\t}\n\t}, [autoConnectLocal, addSource])\n\n\t// Notify on tools change\n\tuseEffect(() => {\n\t\tonToolsChange?.(toolsList)\n\t}, [toolsList, onToolsChange])\n\n\t// Notify on prompts change\n\tuseEffect(() => {\n\t\tonPromptsChange?.(promptsList)\n\t}, [promptsList, onPromptsChange])\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\tconst sources = sourcesRef\n\t\tconst inflightCalls = inflightCallsRef\n\t\treturn () => {\n\t\t\t// Abort all in-flight tool calls\n\t\t\t// Note: We iterate first, then clear - don't mutate during iteration\n\t\t\tinflightCalls.current.forEach((call) => {\n\t\t\t\tcall.abortController.abort(new Error('Provider unmounted'))\n\t\t\t})\n\t\t\tinflightCalls.current.clear()\n\n\t\t\t// Close all source connections\n\t\t\tsources.current.forEach((source) => {\n\t\t\t\tif (source.client) {\n\t\t\t\t\tvoid source.client.close().catch(console.error)\n\t\t\t\t}\n\t\t\t\tif (source.transport) {\n\t\t\t\t\tvoid source.transport.close().catch(console.error)\n\t\t\t\t}\n\t\t\t})\n\t\t\tsources.current.clear()\n\t\t}\n\t}, [])\n\n\tconst value = useMemo<MCPToolsContextValue>(\n\t\t() => ({\n\t\t\ttools: toolsList,\n\t\t\tprompts: promptsList,\n\t\t\tsources,\n\t\t\taddSource,\n\t\t\tremoveSource,\n\t\t\tgetSource,\n\t\t\tisConnected,\n\t\t\tcallTool,\n\t\t\tcallToolOnSource,\n\t\t\tgetPrompt,\n\t\t\trefreshTools,\n\t\t}),\n\t\t[\n\t\t\ttoolsList,\n\t\t\tpromptsList,\n\t\t\tsources,\n\t\t\taddSource,\n\t\t\tremoveSource,\n\t\t\tgetSource,\n\t\t\tisConnected,\n\t\t\tcallTool,\n\t\t\tcallToolOnSource,\n\t\t\tgetPrompt,\n\t\t\trefreshTools,\n\t\t]\n\t)\n\n\treturn <MCPToolsContext.Provider value={value}>{children}</MCPToolsContext.Provider>\n}\n\n/**\n * Hook to access MCP Tools context\n */\nexport function useMCPTools(): MCPToolsContextValue {\n\tconst context = useContext(MCPToolsContext)\n\tif (!context) {\n\t\tthrow new Error('useMCPTools must be used within an MCPToolsProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access MCP Tools context\n */\nexport function useOptionalMCPTools(): MCPToolsContextValue | null {\n\treturn useContext(MCPToolsContext)\n}\n","import type { Tool } from '@mcp-b/cloud-mirror-types'\n\n/**\n * Determine whether a tool should be considered destructive.\n *\n * Defaults to destructive when annotations are missing to follow MCP defaults.\n */\nexport function isToolDestructive(annotations?: Tool['annotations'] | null): boolean {\n\tif (!annotations) return true\n\tif (annotations.readOnlyHint === true) return false\n\tif (typeof annotations.destructiveHint === 'boolean') return annotations.destructiveHint\n\treturn true\n}\n","/**\n * Tool Approval Provider\n *\n * Manages user preferences for destructive tool approval.\n * When mode is 'ask', tools with destructiveHint: true require user confirmation.\n * When mode is 'auto', all tools execute immediately.\n *\n * @example\n * ```tsx\n * <ToolApprovalProvider>\n * <App />\n * </ToolApprovalProvider>\n *\n * // In a component:\n * const { mode, setMode, requiresApproval } = useToolApproval()\n * ```\n */\nimport { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'\n\nimport type { Tool, ToolApprovalMode, ToolApprovalSettings } from '@mcp-b/cloud-mirror-types'\nimport type { ReactNode } from 'react'\n\nimport { isToolDestructive } from '../utils/tool-approval'\n\nconst STORAGE_KEY = 'webmcp-tool-approval-mode'\nconst DEFAULT_MODE: ToolApprovalMode = 'ask'\n\n/**\n * Tool Approval Context Value\n */\nexport interface ToolApprovalContextValue extends ToolApprovalSettings {\n\t/** Set the approval mode */\n\tsetMode: (mode: ToolApprovalMode) => void\n\t/** Toggle between 'auto' and 'ask' modes */\n\ttoggleMode: () => void\n\t/** Check if a specific tool requires approval based on its annotations */\n\trequiresApproval: (tool: Tool) => boolean\n\t/** Check if a tool is considered destructive based on its annotations */\n\tisDestructive: (tool: Tool) => boolean\n}\n\nconst ToolApprovalContext = createContext<ToolApprovalContextValue | null>(null)\n\nexport interface ToolApprovalProviderProps {\n\tchildren: ReactNode\n\t/** Initial mode (overrides stored preference) */\n\tdefaultMode?: ToolApprovalMode\n\t/** Disable localStorage persistence */\n\tdisablePersistence?: boolean\n\t/** Callback when mode changes */\n\tonModeChange?: (mode: ToolApprovalMode) => void\n}\n\nexport function ToolApprovalProvider({\n\tchildren,\n\tdefaultMode,\n\tdisablePersistence = false,\n\tonModeChange,\n}: ToolApprovalProviderProps) {\n\t// Initialize mode from storage or default\n\tconst [mode, setModeState] = useState<ToolApprovalMode>(() => {\n\t\tif (defaultMode) return defaultMode\n\t\tif (disablePersistence) return DEFAULT_MODE\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem(STORAGE_KEY)\n\t\t\tif (stored === 'auto' || stored === 'ask') {\n\t\t\t\treturn stored\n\t\t\t}\n\t\t} catch {\n\t\t\t// localStorage not available\n\t\t}\n\t\treturn DEFAULT_MODE\n\t})\n\n\t// Persist mode changes\n\tuseEffect(() => {\n\t\tif (disablePersistence) return\n\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_KEY, mode)\n\t\t} catch {\n\t\t\t// localStorage not available\n\t\t}\n\t}, [mode, disablePersistence])\n\n\t// Set mode with callback\n\tconst setMode = useCallback(\n\t\t(newMode: ToolApprovalMode) => {\n\t\t\tsetModeState(newMode)\n\t\t\tonModeChange?.(newMode)\n\t\t},\n\t\t[onModeChange]\n\t)\n\n\t// Toggle between modes\n\tconst toggleMode = useCallback(() => {\n\t\tsetMode(mode === 'auto' ? 'ask' : 'auto')\n\t}, [mode, setMode])\n\n\t// Check if a tool is destructive\n\tconst isDestructive = useCallback((tool: Tool): boolean => {\n\t\treturn isToolDestructive(tool.annotations)\n\t}, [])\n\n\t// Check if a tool requires approval (destructive + ask mode)\n\tconst requiresApproval = useCallback(\n\t\t(tool: Tool): boolean => {\n\t\t\tif (mode === 'auto') return false\n\t\t\treturn isDestructive(tool)\n\t\t},\n\t\t[mode, isDestructive]\n\t)\n\n\tconst value = useMemo<ToolApprovalContextValue>(\n\t\t() => ({\n\t\t\tmode,\n\t\t\tsetMode,\n\t\t\ttoggleMode,\n\t\t\trequiresApproval,\n\t\t\tisDestructive,\n\t\t}),\n\t\t[mode, setMode, toggleMode, requiresApproval, isDestructive]\n\t)\n\n\treturn <ToolApprovalContext.Provider value={value}>{children}</ToolApprovalContext.Provider>\n}\n\n/**\n * Hook to access tool approval settings\n */\nexport function useToolApproval(): ToolApprovalContextValue {\n\tconst context = useContext(ToolApprovalContext)\n\tif (!context) {\n\t\tthrow new Error('useToolApproval must be used within a ToolApprovalProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access tool approval settings\n */\nexport function useOptionalToolApproval(): ToolApprovalContextValue | null {\n\treturn useContext(ToolApprovalContext)\n}\n","/**\n * Tool Exclusion Provider\n *\n * Provides a mechanism to exclude certain tools from the embedded agent's visible tool list.\n * This is useful for:\n * - Filtering out internal/development tools\n * - Creating tool scoping for different use cases\n *\n * Usage:\n * ```tsx\n * import { ToolExclusionProvider } from '@mcp-b/embedded-agent'\n *\n * // Exclude tools by prefix\n * <ToolExclusionProvider excludePrefixes={['internal_']}>\n * <AgentProvider>...</AgentProvider>\n * </ToolExclusionProvider>\n *\n * // Exclude specific tools by name\n * <ToolExclusionProvider exclude={(name) => ['tool1', 'tool2'].includes(name)}>\n * <AgentProvider>...</AgentProvider>\n * </ToolExclusionProvider>\n * ```\n */\nimport { createContext, useCallback, useContext, useMemo, type FC, type ReactNode } from 'react'\n\nimport type { ToolWithSource } from '@mcp-b/cloud-mirror-types'\n\n/**\n * Filter function to determine if a tool should be excluded\n */\nexport type ToolExclusionFilter = (toolName: string, tool: ToolWithSource) => boolean\n\nexport interface ToolExclusionContextValue {\n\t/**\n\t * Check if a tool should be excluded from the agent\n\t */\n\tshouldExclude: (tool: ToolWithSource) => boolean\n\n\t/**\n\t * Filter an array of tools, removing excluded ones\n\t */\n\tfilterTools: (tools: ToolWithSource[]) => ToolWithSource[]\n}\n\nconst ToolExclusionContext = createContext<ToolExclusionContextValue | null>(null)\n\nexport interface ToolExclusionProviderProps {\n\tchildren: ReactNode\n\n\t/**\n\t * Filter function to determine which tools to exclude.\n\t * Return true to exclude the tool, false to include it.\n\t *\n\t * @example Exclude by prefix\n\t * ```tsx\n\t * exclude={(name) => name.startsWith('internal_')}\n\t * ```\n\t *\n\t * @example Exclude by list\n\t * ```tsx\n\t * exclude={(name) => ['dev_tool', 'internal_tool'].includes(name)}\n\t * ```\n\t */\n\texclude?: ToolExclusionFilter\n\n\t/**\n\t * Array of specific tool names to exclude\n\t * (convenience alternative to `exclude` function)\n\t */\n\texcludeNames?: string[]\n\n\t/**\n\t * Array of prefixes - tools starting with any of these will be excluded\n\t * (convenience alternative to `exclude` function)\n\t */\n\texcludePrefixes?: string[]\n}\n\nexport const ToolExclusionProvider: FC<ToolExclusionProviderProps> = ({\n\tchildren,\n\texclude,\n\texcludeNames,\n\texcludePrefixes,\n}) => {\n\tconst shouldExclude = useCallback(\n\t\t(tool: ToolWithSource): boolean => {\n\t\t\t// Check custom exclude function first\n\t\t\tif (exclude?.(tool.name, tool)) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\t// Check excludeNames\n\t\t\tif (excludeNames?.includes(tool.name)) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\t// Check excludePrefixes\n\t\t\tif (excludePrefixes?.some((prefix) => tool.name.startsWith(prefix))) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\treturn false\n\t\t},\n\t\t[exclude, excludeNames, excludePrefixes]\n\t)\n\n\tconst filterTools = useCallback(\n\t\t(tools: ToolWithSource[]): ToolWithSource[] => {\n\t\t\treturn tools.filter((tool) => !shouldExclude(tool))\n\t\t},\n\t\t[shouldExclude]\n\t)\n\n\tconst value = useMemo<ToolExclusionContextValue>(\n\t\t() => ({\n\t\t\tshouldExclude,\n\t\t\tfilterTools,\n\t\t}),\n\t\t[shouldExclude, filterTools]\n\t)\n\n\treturn <ToolExclusionContext.Provider value={value}>{children}</ToolExclusionContext.Provider>\n}\n\n/**\n * Hook to access tool exclusion context\n * Throws if used outside ToolExclusionProvider\n */\nexport function useToolExclusion(): ToolExclusionContextValue {\n\tconst context = useContext(ToolExclusionContext)\n\tif (!context) {\n\t\tthrow new Error('useToolExclusion must be used within a ToolExclusionProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access tool exclusion context\n * Returns null if used outside ToolExclusionProvider\n */\nexport function useOptionalToolExclusion(): ToolExclusionContextValue | null {\n\treturn useContext(ToolExclusionContext)\n}\n","/**\n * MCP Tool Registry Component\n *\n * Registers all MCP tools with the assistant-ui runtime.\n * Uses the unified callTool function which auto-routes based on tool source.\n *\n * Supports destructive tool approval when ToolApprovalProvider is present:\n * - Tools with destructiveHint: true require user confirmation before execution\n * - Approval mode can be 'ask' (require confirmation) or 'auto' (execute immediately)\n * - Approval UI is handled by UnifiedToolFallback using the HITL pattern\n *\n * Supports tool exclusion when ToolExclusionProvider is present:\n * - Excluded tools are not registered with assistant-ui\n * - Useful for hiding test tools from the agent\n *\n * Tool execution captures metadata (timing, source info) and stores it in the\n * assistant-ui thread via ToolResponse artifacts. This enables:\n * - Performance monitoring (duration tracking)\n * - Source attribution (which MCP server handled the call)\n * - Error tracking (including abort status)\n *\n * Usage:\n * <MCPToolRegistry />\n *\n * This component should be placed inside both MCPToolsProvider and AssistantRuntimeProvider.\n */\nimport { useAssistantTool } from '@assistant-ui/react'\nimport { ToolResponse } from 'assistant-stream'\nimport { memo, useMemo } from 'react'\n\nimport { useMCPTools } from '../providers/MCPToolsProvider'\nimport { useOptionalToolApproval } from '../providers/ToolApprovalProvider'\nimport { useOptionalToolExclusion } from '../providers/ToolExclusionProvider'\n\nimport type { CallToolResult, ToolCallMetadata, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { ReadonlyJSONValue } from 'assistant-stream/utils'\nimport type { FC } from 'react'\n\n// ============================================================================\n// Tool Result Formatting\n// ============================================================================\n\n/**\n * Format tool result content for the assistant\n */\nexport function formatToolResult(result: CallToolResult): string {\n\tconst textContent = result.content\n\t\t.map((c: { type: string; text?: string }) => {\n\t\t\tif ('text' in c && typeof c.text === 'string') {\n\t\t\t\treturn c.text\n\t\t\t}\n\t\t\treturn JSON.stringify(c)\n\t\t})\n\t\t.join('\\n')\n\n\treturn textContent || 'Tool executed successfully'\n}\n\n// ============================================================================\n// Tool Bridge Components\n// ============================================================================\n\n/**\n * Bridge component that registers a single tool with assistant-ui.\n * Executes the tool immediately via MCP.\n * Captures execution metadata (timing, source) and stores in thread artifacts.\n *\n * Memoized to prevent re-registration when parent re-renders.\n */\nconst ToolBridge: FC<{\n\ttool: ToolWithSource\n\tcallTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n}> = memo(({ tool, callTool }) => {\n\tuseAssistantTool({\n\t\ttoolName: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tparameters: (tool.inputSchema ?? {}) as Record<string, unknown>,\n\t\texecute: async (args) => {\n\t\t\tconst startedAt = Date.now()\n\t\t\tlet isError = false\n\t\t\tlet wasAborted = false\n\n\t\t\ttry {\n\t\t\t\tconst result = await callTool(tool.name, args)\n\n\t\t\t\t// Check if the result indicates an error\n\t\t\t\tisError = result.isError === true\n\n\t\t\t\t// Check if the call was aborted (tool removed during execution)\n\t\t\t\twasAborted = result.content.some(\n\t\t\t\t\t(c) =>\n\t\t\t\t\t\tc.type === 'text' && typeof c.text === 'string' && c.text.includes('Tool call aborted')\n\t\t\t\t)\n\n\t\t\t\t// Build metadata artifact for thread persistence\n\t\t\t\tconst metadata = {\n\t\t\t\t\tstartedAt,\n\t\t\t\t\tduration: Date.now() - startedAt,\n\t\t\t\t\tsourceId: tool._sourceId,\n\t\t\t\t\tisError,\n\t\t\t\t\twasAborted,\n\t\t\t\t} satisfies ToolCallMetadata\n\n\t\t\t\t// Return ToolResponse with artifact for thread storage\n\t\t\t\treturn new ToolResponse({\n\t\t\t\t\tresult: formatToolResult(result),\n\t\t\t\t\tartifact: metadata as unknown as ReadonlyJSONValue,\n\t\t\t\t\tisError,\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`[ToolBridge] Tool '${tool.name}' execution failed:`, error)\n\n\t\t\t\t// Still capture metadata for failed calls\n\t\t\t\tconst metadata = {\n\t\t\t\t\tstartedAt,\n\t\t\t\t\tduration: Date.now() - startedAt,\n\t\t\t\t\tsourceId: tool._sourceId,\n\t\t\t\t\tisError: true,\n\t\t\t\t\twasAborted: false,\n\t\t\t\t} satisfies ToolCallMetadata\n\n\t\t\t\t// Return error as ToolResponse with metadata\n\t\t\t\treturn new ToolResponse({\n\t\t\t\t\tresult: `Error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\tartifact: metadata as unknown as ReadonlyJSONValue,\n\t\t\t\t\tisError: true,\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t})\n\n\treturn null\n})\n\n/**\n * Bridge component for destructive tools that require approval.\n *\n * IMPORTANT: No execute function is provided!\n * This makes assistant-ui wait for the fallback to call addResult().\n * The model pauses until the user approves/denies via the fallback UI.\n *\n * Memoized to prevent re-registration when parent re-renders.\n */\nconst DestructiveToolBridge: FC<{\n\ttool: ToolWithSource\n}> = memo(({ tool }) => {\n\t// Register tool WITHOUT execute - this is key for HITL!\n\t// The fallback component handles execution via addResult()\n\tuseAssistantTool({\n\t\ttoolName: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tparameters: (tool.inputSchema ?? {}) as Record<string, unknown>,\n\t\t// No execute function = model waits for addResult()\n\t})\n\n\treturn null\n})\n\n// ============================================================================\n// Main Registry Component\n// ============================================================================\n\n/**\n * Tool registry that registers all MCP tools with assistant-ui.\n * Routes tool calls automatically based on _sourceId.\n * Uses DestructiveToolBridge for tools that require approval.\n * Respects ToolExclusionProvider to filter out excluded tools.\n */\nexport const MCPToolRegistry: FC = () => {\n\tconst { tools, callTool } = useMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\tconst toolExclusion = useOptionalToolExclusion()\n\n\t// Filter tools based on exclusion rules\n\tconst visibleTools = useMemo(() => {\n\t\tif (!toolExclusion) {\n\t\t\tconsole.debug('[MCPToolRegistry] No exclusion provider, registering all tools:', tools.map(t => t.name))\n\t\t\treturn tools\n\t\t}\n\t\tconst filtered = toolExclusion.filterTools(tools)\n\t\tconst excluded = tools.filter(t => !filtered.includes(t))\n\t\tif (excluded.length > 0) {\n\t\t\tconsole.debug('[MCPToolRegistry] Excluded tools:', excluded.map(t => t.name))\n\t\t}\n\t\tconsole.debug('[MCPToolRegistry] Registering visible tools:', filtered.map(t => t.name))\n\t\treturn filtered\n\t}, [tools, toolExclusion])\n\n\treturn (\n\t\t<>\n\t\t\t{visibleTools.map((tool) => {\n\t\t\t\t// Check if this tool requires approval\n\t\t\t\tconst needsApproval = toolApproval?.requiresApproval(tool) ?? false\n\n\t\t\t\tif (needsApproval) {\n\t\t\t\t\treturn <DestructiveToolBridge key={`${tool._sourceId}-${tool.name}`} tool={tool} />\n\t\t\t\t}\n\n\t\t\t\treturn <ToolBridge key={`${tool._sourceId}-${tool.name}`} tool={tool} callTool={callTool} />\n\t\t\t})}\n\t\t</>\n\t)\n}\n","import { createContext, useContext } from 'react'\n\nimport type { CallToolResult, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { FC, ReactNode } from 'react'\n\nexport interface ToolExecutionContextValue {\n\texecuteTool: (toolName: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\tgetToolMetadata: (\n\t\ttoolName: string,\n\t) => { description?: string; annotations?: ToolWithSource['annotations'] } | null\n}\n\nconst ToolExecutionContext = createContext<ToolExecutionContextValue | null>(null)\n\nexport interface ToolExecutionProviderProps {\n\tvalue: ToolExecutionContextValue\n\tchildren: ReactNode\n}\n\nexport const ToolExecutionProvider: FC<ToolExecutionProviderProps> = ({ value, children }) => {\n\treturn <ToolExecutionContext.Provider value={value}>{children}</ToolExecutionContext.Provider>\n}\n\nexport function useToolExecution(): ToolExecutionContextValue {\n\tconst context = useContext(ToolExecutionContext)\n\tif (!context) {\n\t\tthrow new Error('useToolExecution must be used within a ToolExecutionProvider')\n\t}\n\treturn context\n}\n\nexport function useOptionalToolExecution(): ToolExecutionContextValue | null {\n\treturn useContext(ToolExecutionContext)\n}\n","/**\n * Formatting utilities for tool display\n *\n * Shared helpers for formatting tool names and arguments across components.\n */\n\nimport { stripSourceScopedToolName } from './tool-names'\n\n/**\n * Humanize tool name for display\n * Converts snake_case and camelCase to readable text.\n *\n * @param name - The tool name to humanize\n * @param progressive - If true, converts verb to progressive tense (e.g., \"searching\")\n *\n * @example\n * humanizeToolName('get_current_time') // 'Get current time'\n * humanizeToolName('deleteNote') // 'Delete note'\n * humanizeToolName('search_files', true) // 'Searching files'\n */\nexport function humanizeToolName(name: string, progressive = false): string {\n\tconst normalizedName = stripSourceScopedToolName(name)\n\n\t// Convert camelCase or snake_case to words\n\tconst words = normalizedName\n\t\t.replace(/([a-z])([A-Z])/g, '$1 $2')\n\t\t.replace(/_/g, ' ')\n\t\t.toLowerCase()\n\t\t.split(' ')\n\n\tif (words.length === 0) return normalizedName\n\n\tif (progressive) {\n\t\t// Make first word progressive (e.g., \"search\" -> \"Searching\")\n\t\tconst verb = words[0]\n\t\tconst progressiveVerb = verb.endsWith('e') ? verb.slice(0, -1) + 'ing' : verb + 'ing'\n\t\twords[0] = progressiveVerb.charAt(0).toUpperCase() + progressiveVerb.slice(1)\n\t} else {\n\t\t// Just capitalize first word\n\t\twords[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1)\n\t}\n\n\treturn words.join(' ')\n}\n\n/**\n * Format tool arguments for display\n * Truncates long strings and formats objects as JSON\n *\n * @example\n * formatArgs({ name: 'test', count: 5 }) // 'name: \"test\"\\ncount: 5'\n */\nexport function formatArgs(args: Record<string, unknown>): string {\n\tconst entries = Object.entries(args)\n\tif (entries.length === 0) return 'No arguments'\n\n\treturn entries\n\t\t.map(([key, value]) => {\n\t\t\tconst displayValue =\n\t\t\t\ttypeof value === 'string'\n\t\t\t\t\t? value.length > 50\n\t\t\t\t\t\t? `\"${value.slice(0, 50)}...\"`\n\t\t\t\t\t\t: `\"${value}\"`\n\t\t\t\t\t: JSON.stringify(value)\n\t\t\treturn `${key}: ${displayValue}`\n\t\t})\n\t\t.join('\\n')\n}\n\n/**\n * Denial message constant\n * Used when user denies a tool execution\n */\nexport const TOOL_DENIED_MESSAGE = 'Tool execution denied by user'\n\n/**\n * Format a denial message with a user-provided reason.\n * Used when user wants to tell the agent what to do differently.\n *\n * @param reason - The user's feedback explaining what to do differently\n * @returns Formatted denial message with reason\n */\nexport function formatToolDenialWithReason(reason: string): string {\n\treturn `Tool denied: ${reason}`\n}\n","/**\n * ActivityIndicator Component\n *\n * Shows what the agent is currently doing based on thread state.\n * Displays in the composer area when the agent is running.\n *\n * Activity states:\n * - \"Thinking...\" - Agent is processing, no tools called yet\n * - \"Running {toolName}...\" - Single tool is executing\n * - \"Running {n} tools...\" - Multiple tools executing in parallel\n * - Shows streaming text preview when available\n */\n'use client'\n\nimport { useThread } from '@assistant-ui/react'\nimport {\n\tCamera,\n\tFileText,\n\tLoader2,\n\tMousePointer,\n\tNavigation,\n\tPenLine,\n\tSearch,\n\tTrash2,\n\tWrench,\n} from 'lucide-react'\nimport { useMemo } from 'react'\n\nimport { humanizeToolName } from '../../utils/format'\nimport { stripSourceScopedToolName } from '../../utils/tool-names'\nimport { cn } from '../../utils/cn'\n\nimport type { LucideIcon } from 'lucide-react'\nimport type { FC } from 'react'\n\n// ============================================================================\n// Tool Icon Mapping\n// ============================================================================\n\n/**\n * Get an appropriate icon for a tool based on its name.\n * Uses pattern matching to categorize tools.\n */\nexport function getToolIcon(toolName: string): LucideIcon {\n\tconst name = stripSourceScopedToolName(toolName).toLowerCase()\n\n\t// Search/find operations\n\tif (\n\t\tname.includes('search') ||\n\t\tname.includes('find') ||\n\t\tname.includes('grep') ||\n\t\tname.includes('glob')\n\t) {\n\t\treturn Search\n\t}\n\n\t// Read/get operations\n\tif (\n\t\tname.includes('read') ||\n\t\tname.includes('get') ||\n\t\tname.includes('fetch') ||\n\t\tname.includes('list')\n\t) {\n\t\treturn FileText\n\t}\n\n\t// Write/create operations\n\tif (\n\t\tname.includes('write') ||\n\t\tname.includes('create') ||\n\t\tname.includes('add') ||\n\t\tname.includes('insert')\n\t) {\n\t\treturn PenLine\n\t}\n\n\t// Delete/remove operations\n\tif (name.includes('delete') || name.includes('remove') || name.includes('clear')) {\n\t\treturn Trash2\n\t}\n\n\t// Navigation operations\n\tif (name.includes('navigate') || name.includes('goto') || name.includes('open')) {\n\t\treturn Navigation\n\t}\n\n\t// UI interaction operations\n\tif (\n\t\tname.includes('click') ||\n\t\tname.includes('fill') ||\n\t\tname.includes('type') ||\n\t\tname.includes('hover')\n\t) {\n\t\treturn MousePointer\n\t}\n\n\t// Screenshot/snapshot operations\n\tif (name.includes('screenshot') || name.includes('snapshot') || name.includes('capture')) {\n\t\treturn Camera\n\t}\n\n\t// Default\n\treturn Wrench\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface ActivityState {\n\ttype: 'idle' | 'thinking' | 'tool' | 'parallel_tools' | 'streaming'\n\tlabel: string\n\ticon: LucideIcon\n\ttoolNames?: string[]\n\tstreamingText?: string\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook to derive current activity state from the thread.\n */\nexport function useActivityState(): ActivityState | null {\n\tconst messages = useThread((thread) => thread.messages)\n\tconst isRunning = useThread((thread) => thread.isRunning)\n\n\treturn useMemo(() => {\n\t\tif (!isRunning) return null\n\n\t\t// Find the last assistant message\n\t\tconst lastAssistantMessage = messages\n\t\t\t? [...messages].reverse().find((m) => m.role === 'assistant')\n\t\t\t: null\n\n\t\tif (!lastAssistantMessage) {\n\t\t\t// No assistant message yet - thinking\n\t\t\treturn {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tlabel: 'Thinking...',\n\t\t\t\ticon: Loader2,\n\t\t\t}\n\t\t}\n\n\t\t// Get running tool calls from the message\n\t\tconst runningToolNames: string[] = []\n\t\tlet lastText: string | undefined\n\n\t\tfor (const part of lastAssistantMessage.content) {\n\t\t\tif (part.type === 'tool-call') {\n\t\t\t\t// Check if this tool call is running (no status means running, or status.type === 'running')\n\t\t\t\tconst toolPart = part as { toolName: string; status?: { type: string } }\n\t\t\t\tif (!toolPart.status || toolPart.status.type === 'running') {\n\t\t\t\t\trunningToolNames.push(toolPart.toolName)\n\t\t\t\t}\n\t\t\t} else if (part.type === 'text') {\n\t\t\t\tconst textPart = part as { text: string }\n\t\t\t\tlastText = textPart.text\n\t\t\t}\n\t\t}\n\n\t\t// Determine activity state\n\t\tif (runningToolNames.length === 0) {\n\t\t\t// No running tools\n\t\t\tif (lastText && lastText.length > 0) {\n\t\t\t\t// Has text content - streaming response\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'streaming',\n\t\t\t\t\tlabel: 'Writing response...',\n\t\t\t\t\ticon: PenLine,\n\t\t\t\t\tstreamingText: lastText,\n\t\t\t\t}\n\t\t\t}\n\t\t\t// No text either - still thinking\n\t\t\treturn {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tlabel: 'Thinking...',\n\t\t\t\ticon: Loader2,\n\t\t\t}\n\t\t}\n\n\t\tif (runningToolNames.length === 1) {\n\t\t\t// Single tool running\n\t\t\tconst toolName = runningToolNames[0]\n\t\t\treturn {\n\t\t\t\ttype: 'tool',\n\t\t\t\tlabel: humanizeToolName(toolName, true),\n\t\t\t\ticon: getToolIcon(toolName),\n\t\t\t\ttoolNames: [toolName],\n\t\t\t}\n\t\t}\n\n\t\t// Multiple tools running in parallel\n\t\treturn {\n\t\t\ttype: 'parallel_tools',\n\t\t\tlabel: `Running ${runningToolNames.length} tools...`,\n\t\t\ticon: Loader2,\n\t\t\ttoolNames: runningToolNames,\n\t\t}\n\t}, [messages, isRunning])\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\ninterface ActivityIndicatorProps {\n\tclassName?: string\n}\n\n/**\n * Displays the current agent activity.\n * Shows in the composer area when the agent is running.\n */\nexport const ActivityIndicator: FC<ActivityIndicatorProps> = ({ className }) => {\n\tconst activity = useActivityState()\n\n\tif (!activity) return null\n\n\tconst Icon = activity.icon\n\tconst isSpinning = activity.type === 'thinking' || activity.type === 'parallel_tools'\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'wm:flex wm:items-center wm:gap-2 wm:px-3 wm:py-2',\n\t\t\t\t'wm:rounded-lg wm:bg-blue-500/10 wm:border wm:border-blue-500/20',\n\t\t\t\t'wm:text-sm wm:text-blue-400',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t<Icon className={cn('wm:h-4 wm:w-4 wm:flex-shrink-0', isSpinning && 'wm:animate-spin')} />\n\t\t\t<span className=\"wm:truncate\">{activity.label}</span>\n\n\t\t\t{/* Show parallel tool names on hover/expand */}\n\t\t\t{activity.type === 'parallel_tools' && activity.toolNames && (\n\t\t\t\t<div className=\"wm:hidden wm:sm:flex wm:items-center wm:gap-1 wm:ml-1\">\n\t\t\t\t\t{activity.toolNames.slice(0, 3).map((name, i) => {\n\t\t\t\t\t\tconst ToolIcon = getToolIcon(name)\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span key={i} title={humanizeToolName(name, true)}>\n\t\t\t\t\t\t\t\t<ToolIcon className=\"wm:h-3 wm:w-3 wm:text-blue-400/60\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t\t{activity.toolNames.length > 3 && (\n\t\t\t\t\t\t<span className=\"wm:text-xs wm:text-blue-400/60\">+{activity.toolNames.length - 3}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nexport default ActivityIndicator\n","/**\n * UnifiedToolFallback Component\n *\n * A unified fallback component that handles ALL tool call states:\n * - Running: Shows activity indicator with tool name\n * - Pending approval: Shows approval dialog for destructive tools\n * - Completed: Shows success indicator with collapsible args/result\n * - Error: Shows error state\n *\n * This provides an alternative to separate ActionList/CurrentActivity components\n * by rendering tool states directly in the message thread.\n */\n'use client'\n\nimport { AlertCircle, AlertTriangle, Check, ChevronDownIcon, ChevronUpIcon, X } from 'lucide-react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { ToolResponse } from 'assistant-stream'\n\nimport { useDelayedState } from '../../hooks/useDelayedState'\nimport { useMCPTools } from '../../providers/MCPToolsProvider'\nimport { formatToolResult } from '../../providers/MCPToolRegistry'\nimport { useOptionalToolApproval } from '../../providers/ToolApprovalProvider'\nimport { useOptionalToolExecution } from '../../providers/ToolExecutionProvider'\nimport { cn } from '../../utils/cn'\nimport { formatArgs, humanizeToolName, TOOL_DENIED_MESSAGE } from '../../utils/format'\nimport { isToolDestructive } from '../../utils/tool-approval'\nimport { stripSourceScopedToolName } from '../../utils/tool-names'\nimport { getToolIcon } from './ActivityIndicator'\n\nimport type { ToolCallMessagePartComponent } from '@assistant-ui/react'\n\n// ============================================================================\n// Approval Result Types\n// ============================================================================\n\ninterface ApprovedResult {\n\tapproved: true\n\tresult: string\n}\n\nfunction isApprovedResult(result: unknown): result is ApprovedResult {\n\treturn (\n\t\ttypeof result === 'object' &&\n\t\tresult !== null &&\n\t\t'approved' in result &&\n\t\t(result as ApprovedResult).approved === true &&\n\t\t'result' in result\n\t)\n}\n\n/**\n * Check if result indicates a denied tool execution.\n * Handles both string format (legacy) and structured format.\n */\nfunction isDeniedResult(result: unknown): boolean {\n\t// Check for string denial message\n\tif (typeof result === 'string' && result === TOOL_DENIED_MESSAGE) {\n\t\treturn true\n\t}\n\t// Check for structured denial (future-proofing)\n\tif (\n\t\ttypeof result === 'object' &&\n\t\tresult !== null &&\n\t\t'approved' in result &&\n\t\t(result as { approved: boolean }).approved === false\n\t) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * Type guard for status with error property\n */\nfunction hasStatusError(status: { type: string }): status is { type: string; error: string } {\n\treturn 'error' in status && typeof (status as { error?: unknown }).error === 'string'\n}\n\n// ============================================================================\n// Sub-Components for Each State\n// ============================================================================\n\n/**\n * Running state - tool is currently executing\n */\nconst RunningToolDisplay: React.FC<{\n\ttoolName: string\n}> = ({ toolName }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"wm:my-1 wm:flex wm:items-center wm:gap-1.5 wm:rounded-lg wm:bg-muted/50 wm:px-2 wm:py-1.5 wm:text-sm wm:text-foreground/70\">\n\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:animate-pulse wm:text-muted-foreground\" />\n\t\t\t<span>\n\t\t\t\t<strong className=\"wm:text-foreground\">{humanizeToolName(toolName)}</strong>\n\t\t\t</span>\n\t\t</div>\n\t)\n}\n\n/**\n * Approval dialog for destructive tools (HITL pattern)\n * Used when a tool has no execute function and requires user approval.\n */\nconst ApprovalDialog: React.FC<{\n\ttoolName: string\n\ttoolDescription?: string\n\tinputArgs: Record<string, unknown>\n\tonApprove: () => void\n\tonDeny: () => void\n\tisExecuting: boolean\n}> = ({ toolName, toolDescription, inputArgs, onApprove, onDeny, isExecuting }) => {\n\tconst [isHovered, setIsHovered] = useState<'approve' | 'deny' | null>(null)\n\tconst ToolIcon = getToolIcon(toolName)\n\n\tif (isExecuting) {\n\t\treturn (\n\t\t\t<div className=\"wm:my-1 wm:flex wm:items-center wm:gap-1.5 wm:rounded-lg wm:bg-muted/50 wm:px-2 wm:py-1.5 wm:text-sm wm:text-foreground/70\">\n\t\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:animate-pulse wm:text-muted-foreground\" />\n\t\t\t\t<span>\n\t\t\t\t\t<strong className=\"wm:text-foreground\">{humanizeToolName(toolName)}</strong>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t)\n\t}\n\n\treturn (\n\t\t<div className={cn('wm:my-1 wm:overflow-hidden wm:rounded-lg', 'wm:bg-muted/50')}>\n\t\t\t{/* Header - compact */}\n\t\t\t<div className=\"wm:flex wm:items-center wm:gap-1.5 wm:px-2 wm:py-1.5 wm:border-b wm:border-border\">\n\t\t\t\t<div className=\"wm:relative\">\n\t\t\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:text-foreground/70\" />\n\t\t\t\t\t<AlertTriangle className=\"wm:absolute wm:-bottom-0.5 wm:-right-0.5 wm:h-2 wm:w-2 wm:text-foreground/70\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"wm:text-xs wm:font-medium wm:text-foreground\">{humanizeToolName(toolName)}</span>\n\t\t\t</div>\n\n\t\t\t{/* Content */}\n\t\t\t<div className=\"wm:px-2 wm:py-2\">\n\t\t\t\t{toolDescription && (\n\t\t\t\t\t<div className=\"wm:mb-2 wm:line-clamp-3 wm:text-xs wm:text-muted-foreground\">{toolDescription}</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Arguments - compact */}\n\t\t\t\t{inputArgs && Object.keys(inputArgs).length > 0 && (\n\t\t\t\t\t<div className=\"wm:mb-2 wm:rounded wm:bg-muted/50 wm:p-1.5\">\n\t\t\t\t\t\t<pre className=\"wm:whitespace-pre-wrap wm:text-[11px] wm:text-muted-foreground\">\n\t\t\t\t\t\t\t{formatArgs(inputArgs)}\n\t\t\t\t\t\t</pre>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Action buttons - compact */}\n\t\t\t\t<div className=\"wm:flex wm:justify-end wm:gap-1.5\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onDeny}\n\t\t\t\t\t\tonMouseEnter={() => setIsHovered('deny')}\n\t\t\t\t\t\tonMouseLeave={() => setIsHovered(null)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'wm:flex wm:items-center wm:gap-1 wm:rounded wm:px-2.5 wm:py-1.5 wm:text-xs wm:font-medium wm:sm:px-2 wm:sm:py-1',\n\t\t\t\t\t\t\t'wm:border wm:border-border wm:text-muted-foreground',\n\t\t\t\t\t\t\t'wm:transition-colors wm:duration-150',\n\t\t\t\t\t\t\tisHovered === 'deny' ? 'wm:bg-muted wm:text-foreground/80' : 'wm:hover:bg-muted/50'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X className=\"wm:h-3.5 wm:w-3.5 wm:sm:h-3 wm:sm:w-3\" />\n\t\t\t\t\t\tDeny\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onApprove}\n\t\t\t\t\t\tonMouseEnter={() => setIsHovered('approve')}\n\t\t\t\t\t\tonMouseLeave={() => setIsHovered(null)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'wm:flex wm:items-center wm:gap-1 wm:rounded wm:px-2.5 wm:py-1.5 wm:text-xs wm:font-medium wm:sm:px-2 wm:sm:py-1',\n\t\t\t\t\t\t\t'wm:bg-primary wm:text-primary-foreground',\n\t\t\t\t\t\t\t'wm:transition-colors wm:duration-150',\n\t\t\t\t\t\t\tisHovered === 'approve' ? 'wm:bg-primary/90' : 'wm:hover:bg-primary/90'\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Check className=\"wm:h-3.5 wm:w-3.5 wm:sm:h-3 wm:sm:w-3\" />\n\t\t\t\t\t\tOK\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/**\n * Completed tool display - success state with collapsible details\n */\nconst CompletedToolDisplay: React.FC<{\n\ttoolName: string\n\targsText: string\n\tresult: unknown\n}> = ({ toolName, argsText, result }) => {\n\tconst [isExpanded, setIsExpanded] = useState(false)\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"wm:my-1 wm:overflow-hidden wm:rounded-lg wm:bg-muted/50\">\n\t\t\t{/* Header - compact */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={() => setIsExpanded(!isExpanded)}\n\t\t\t\tclassName=\"wm:flex wm:w-full wm:items-center wm:gap-1.5 wm:px-2 wm:py-1.5 wm:text-left wm:transition-colors wm:hover:bg-muted/50\"\n\t\t\t>\n\t\t\t\t<div className=\"wm:relative\">\n\t\t\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:text-muted-foreground\" />\n\t\t\t\t\t<Check className=\"wm:absolute wm:-bottom-0.5 wm:-right-0.5 wm:h-2 wm:w-2 wm:text-muted-foreground\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"wm:flex-grow wm:text-xs wm:font-medium wm:text-foreground/80\">\n\t\t\t\t\t{humanizeToolName(toolName)}\n\t\t\t\t</span>\n\t\t\t\t<span className=\"wm:inline-flex wm:h-5 wm:w-5 wm:items-center wm:justify-center wm:p-0\">\n\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t<ChevronUpIcon className=\"wm:h-3 wm:w-3 wm:text-muted-foreground/70\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ChevronDownIcon className=\"wm:h-3 wm:w-3 wm:text-muted-foreground/70\" />\n\t\t\t\t\t)}\n\t\t\t\t</span>\n\t\t\t</button>\n\n\t\t\t{/* Expandable content */}\n\t\t\t{isExpanded && (\n\t\t\t\t<div className=\"wm:border-t wm:border-border wm:px-2 wm:py-1.5\">\n\t\t\t\t\t{/* Input args */}\n\t\t\t\t\t{argsText && (\n\t\t\t\t\t\t<div className=\"wm:mb-1.5\">\n\t\t\t\t\t\t\t<div className=\"wm:mb-0.5 wm:text-[10px] wm:font-medium wm:uppercase wm:tracking-wide wm:text-muted-foreground/70\">\n\t\t\t\t\t\t\t\tInput\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<pre className=\"wm:max-h-24 wm:overflow-auto wm:whitespace-pre-wrap wm:rounded wm:bg-muted/50 wm:p-1.5 wm:font-mono wm:text-[11px] wm:text-muted-foreground\">\n\t\t\t\t\t\t\t\t{argsText}\n\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Output result */}\n\t\t\t\t\t{result !== undefined && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div className=\"wm:mb-0.5 wm:text-[10px] wm:font-medium wm:uppercase wm:tracking-wide wm:text-muted-foreground/70\">\n\t\t\t\t\t\t\t\tOutput\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<pre className=\"wm:max-h-32 wm:overflow-auto wm:whitespace-pre-wrap wm:rounded wm:bg-muted/50 wm:p-1.5 wm:font-mono wm:text-[11px] wm:text-muted-foreground\">\n\t\t\t\t\t\t\t\t{typeof result === 'string' ? result : JSON.stringify(result, null, 2)}\n\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/**\n * Error state display\n */\nconst ErrorToolDisplay: React.FC<{\n\ttoolName: string\n\terror?: string\n}> = ({ toolName, error }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"wm:my-1 wm:overflow-hidden wm:rounded-lg wm:bg-muted/50\">\n\t\t\t<div className=\"wm:flex wm:items-center wm:gap-1.5 wm:px-2 wm:py-1.5\">\n\t\t\t\t<div className=\"wm:relative\">\n\t\t\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:text-muted-foreground\" />\n\t\t\t\t\t<AlertCircle className=\"wm:absolute wm:-bottom-0.5 wm:-right-0.5 wm:h-2 wm:w-2 wm:text-muted-foreground\" />\n\t\t\t\t</div>\n\t\t\t\t<span className=\"wm:text-xs wm:font-medium wm:text-foreground/70\">\n\t\t\t\t\t{humanizeToolName(toolName)} failed\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t{error && (\n\t\t\t\t<div className=\"wm:border-t wm:border-border wm:px-2 wm:py-1.5\">\n\t\t\t\t\t<pre className=\"wm:whitespace-pre-wrap wm:font-mono wm:text-[11px] wm:text-muted-foreground\">{error}</pre>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/**\n * Denied approval display\n */\nconst DeniedToolDisplay: React.FC<{\n\ttoolName: string\n}> = ({ toolName }) => {\n\tconst ToolIcon = getToolIcon(toolName)\n\n\treturn (\n\t\t<div className=\"wm:my-1 wm:flex wm:items-center wm:gap-1.5 wm:rounded-lg wm:bg-muted/50 wm:px-2 wm:py-1.5 wm:text-xs wm:text-muted-foreground\">\n\t\t\t<div className=\"wm:relative\">\n\t\t\t\t<ToolIcon className=\"wm:h-3.5 wm:w-3.5 wm:text-muted-foreground/70\" />\n\t\t\t\t<X className=\"wm:absolute wm:-bottom-0.5 wm:-right-0.5 wm:h-2 wm:w-2 wm:text-muted-foreground/70\" />\n\t\t\t</div>\n\t\t\t<span>\n\t\t\t\t<strong className=\"wm:text-foreground/70\">{humanizeToolName(toolName)}</strong> denied\n\t\t\t</span>\n\t\t</div>\n\t)\n}\n\n// ============================================================================\n// Main Unified Fallback Component\n// ============================================================================\n\n/**\n * Unified fallback component that handles all tool call states.\n * This is the single source of truth for tool rendering in the thread.\n *\n * HITL Pattern: For tools without an execute function (destructive tools),\n * the model pauses and waits for addResult() to be called. This component\n * shows an approval dialog and handles the execution on user approval.\n */\nexport const UnifiedToolFallback: ToolCallMessagePartComponent = ({\n\ttoolCallId: _toolCallId,\n\ttoolName,\n\targsText,\n\targs,\n\tstatus,\n\tresult,\n\taddResult,\n}) => {\n\tconst { callTool, tools } = useMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\tconst toolExecution = useOptionalToolExecution()\n\tconst [isExecuting, setIsExecuting] = useState(false)\n\n\t// Parse args - use args prop if available, otherwise parse from argsText\n\tconst parsedArgs: Record<string, unknown> =\n\t\targs ??\n\t\t(() => {\n\t\t\ttry {\n\t\t\t\treturn argsText ? JSON.parse(argsText) : {}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn(`[UnifiedToolFallback] Failed to parse args for tool \"${toolName}\":`, e)\n\t\t\t\treturn {}\n\t\t\t}\n\t\t})()\n\n\t// Get tool metadata from registry (thread-aware if available)\n\tconst strippedToolName = stripSourceScopedToolName(toolName)\n\tconst toolMetadata = toolExecution?.getToolMetadata(toolName)\n\tconst localTool = tools.find((t) => t.name === strippedToolName)\n\tconst toolDescription = toolMetadata?.description ?? localTool?.description\n\tconst toolAnnotations = toolMetadata?.annotations ?? localTool?.annotations\n\tconst requiresApproval = toolApproval\n\t\t? toolApproval.mode !== 'auto' && isToolDestructive(toolAnnotations)\n\t\t: status.type === 'requires-action'\n\tconst executeTool = toolExecution?.executeTool ?? callTool\n\n\t// Handle approval - execute the tool and add result\n\t// Uses ToolResponse to properly communicate error state to both:\n\t// 1. Assistant-UI (for error display/styling)\n\t// 2. The model (so it knows the tool failed, not just sees \"Error: \" text)\n\tconst handleApprove = useCallback(async () => {\n\t\tsetIsExecuting(true)\n\t\ttry {\n\t\t\tconst toolResult = await executeTool(toolName, parsedArgs)\n\t\t\tconst resultText = formatToolResult(toolResult)\n\n\t\t\t// Use ToolResponse to properly communicate error state semantically\n\t\t\taddResult(\n\t\t\t\tnew ToolResponse({\n\t\t\t\t\tresult: resultText,\n\t\t\t\t\tisError: toolResult.isError === true,\n\t\t\t\t})\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\t\taddResult(\n\t\t\t\tnew ToolResponse({\n\t\t\t\t\tresult: errorMessage,\n\t\t\t\t\tisError: true,\n\t\t\t\t})\n\t\t\t)\n\t\t} finally {\n\t\t\tsetIsExecuting(false)\n\t\t}\n\t}, [toolName, parsedArgs, executeTool, addResult])\n\n\t// Handle denial - add denial result using shared constant\n\tconst handleDeny = useCallback(() => {\n\t\taddResult(TOOL_DENIED_MESSAGE)\n\t}, [addResult])\n\n\t// Determine the current state and render accordingly\n\tconst statusType = status.type\n\n\t// Check if this is a pending approval\n\tconst isPendingApproval = result === undefined && requiresApproval\n\n\t// Delay showing approval dialog to prevent flash when state transitions quickly\n\tconst showApprovalDialog = useDelayedState(isPendingApproval, 100)\n\n\t// Case 1: HITL - Tool requires action (no execute function, waiting for approval)\n\t// This is the key case for destructive tools!\n\t// We delay showing the dialog by 100ms to prevent flash when state transitions quickly\n\tif (isPendingApproval) {\n\t\t// During the delay, show the running state to prevent a blank flash\n\t\tif (!showApprovalDialog) {\n\t\t\treturn <RunningToolDisplay toolName={toolName} />\n\t\t}\n\t\treturn (\n\t\t\t<ApprovalDialog\n\t\t\t\ttoolName={toolName}\n\t\t\t\ttoolDescription={toolDescription}\n\t\t\t\tinputArgs={parsedArgs}\n\t\t\t\tonApprove={handleApprove}\n\t\t\t\tonDeny={handleDeny}\n\t\t\t\tisExecuting={isExecuting}\n\t\t\t/>\n\t\t)\n\t}\n\n\t// Case 2: Tool was denied (result contains denial message)\n\tif (isDeniedResult(result)) {\n\t\treturn <DeniedToolDisplay toolName={toolName} />\n\t}\n\n\t// Case 3: Tool is currently running (has execute function)\n\tif (statusType === 'running') {\n\t\treturn <RunningToolDisplay toolName={toolName} />\n\t}\n\n\t// Case 4: Tool completed with error\n\tif (statusType === 'incomplete' || hasStatusError(status)) {\n\t\tconst errorMessage = hasStatusError(status) ? status.error : 'Tool execution failed'\n\t\treturn <ErrorToolDisplay toolName={toolName} error={errorMessage} />\n\t}\n\n\t// Case 5: Tool completed successfully\n\t// Also handle transition state where result is set but status hasn't updated yet\n\tif (statusType === 'complete' || (result !== undefined && !isDeniedResult(result))) {\n\t\t// If it's an approved result object, show the actual result\n\t\tconst displayResult = isApprovedResult(result) ? result.result : result\n\n\t\treturn <CompletedToolDisplay toolName={toolName} argsText={argsText} result={displayResult} />\n\t}\n\n\t// Fallback - show running state to prevent flash during state transitions\n\treturn <RunningToolDisplay toolName={toolName} />\n}\n\nexport default UnifiedToolFallback\n","/**\n * usePrompts Hook\n *\n * Easy access to MCP prompts from any component.\n * Provides prompts list and getPrompt function from MCPToolsProvider context.\n */\nimport { useCallback } from 'react'\n\nimport { useOptionalMCPTools } from '../providers/MCPToolsProvider'\n\nimport type { GetPromptResult, Prompt } from '@mcp-b/cloud-mirror-types'\n\nexport interface UsePromptsResult {\n\t/** Available prompts from all MCP sources */\n\tprompts: Prompt[]\n\t/** Whether prompts are available (MCPToolsProvider is present and has prompts) */\n\thasPrompts: boolean\n\t/** Get expanded prompt content by name */\n\tgetPrompt: (name: string, args?: Record<string, string>) => Promise<GetPromptResult>\n}\n\n/**\n * Hook to access MCP prompts.\n *\n * @example Basic usage\n * ```tsx\n * function MyComponent() {\n * const { prompts, hasPrompts, getPrompt } = usePrompts()\n *\n * const handleClick = async (prompt: Prompt) => {\n * const result = await getPrompt(prompt.name)\n * console.log(result.messages)\n * }\n *\n * if (!hasPrompts) return null\n *\n * return (\n * <div>\n * {prompts.map(p => (\n * <button key={p.name} onClick={() => handleClick(p)}>\n * {p.name}\n * </button>\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function usePrompts(): UsePromptsResult {\n\tconst mcpTools = useOptionalMCPTools()\n\n\tconst prompts = mcpTools?.prompts ?? []\n\tconst hasPrompts = prompts.length > 0\n\n\tconst getPrompt = useCallback(\n\t\tasync (name: string, args?: Record<string, string>): Promise<GetPromptResult> => {\n\t\t\tif (!mcpTools?.getPrompt) {\n\t\t\t\tthrow new Error('MCPToolsProvider not found or getPrompt not available')\n\t\t\t}\n\t\t\treturn mcpTools.getPrompt(name, args)\n\t\t},\n\t\t[mcpTools]\n\t)\n\n\treturn {\n\t\tprompts,\n\t\thasPrompts,\n\t\tgetPrompt,\n\t}\n}\n","import { createContext, useContext } from 'react'\n\nimport type { ThreadToolSelection, ToolSourceInfo } from '@mcp-b/cloud-mirror-types'\nimport type { FC, ReactNode } from 'react'\n\nexport interface ToolSelectionContextValue {\n\tsources: ToolSourceInfo[]\n\tselection: ThreadToolSelection | null\n\tsetSelection: (selection: ThreadToolSelection | null) => Promise<void>\n\tcurrentSourceId?: string\n}\n\nconst ToolSelectionContext = createContext<ToolSelectionContextValue | null>(null)\n\nexport interface ToolSelectionProviderProps {\n\tvalue: ToolSelectionContextValue\n\tchildren: ReactNode\n}\n\nexport const ToolSelectionProvider: FC<ToolSelectionProviderProps> = ({ value, children }) => {\n\treturn <ToolSelectionContext.Provider value={value}>{children}</ToolSelectionContext.Provider>\n}\n\nexport function useToolSelection(): ToolSelectionContextValue {\n\tconst context = useContext(ToolSelectionContext)\n\tif (!context) {\n\t\tthrow new Error('useToolSelection must be used within a ToolSelectionProvider')\n\t}\n\treturn context\n}\n\nexport function useOptionalToolSelection(): ToolSelectionContextValue | null {\n\treturn useContext(ToolSelectionContext)\n}\n","/**\n * Thread Utilities\n *\n * Shared utilities for working with assistant-ui thread state.\n * These functions provide a non-reactive way to query and modify thread state,\n * suitable for use in callbacks and effects.\n *\n * For reactive hooks, see usePendingToolCalls.ts which wraps these utilities.\n */\n\nimport type { ThreadAssistantMessage, ThreadRuntime } from '@assistant-ui/react'\n\n/**\n * Information about a pending tool call that requires user approval\n */\nexport interface PendingToolCallInfo {\n\tmessageId: string\n\ttoolCallId: string\n\ttoolName: string\n\targs: Record<string, unknown>\n}\n\n/**\n * Find all pending tool calls in a thread.\n *\n * This is a non-reactive utility for use in callbacks.\n * For reactive state, use usePendingToolCalls() hook instead.\n *\n * @param threadRuntime - The thread runtime to query\n * @returns Array of pending tool calls with their metadata\n */\nexport function getPendingToolCalls(threadRuntime: ThreadRuntime): PendingToolCallInfo[] {\n\tconst messages = threadRuntime.getState().messages\n\tconst result: PendingToolCallInfo[] = []\n\n\tfor (const msg of messages) {\n\t\t// Only assistant messages can have tool calls\n\t\tif (msg.role !== 'assistant') continue\n\n\t\t// Cast to assistant message to access status\n\t\tconst assistantMsg = msg as ThreadAssistantMessage\n\n\t\t// Only process messages waiting for tool results\n\t\tif (assistantMsg.status?.type !== 'requires-action') continue\n\n\t\t// Find tool-call parts without results\n\t\tfor (const part of assistantMsg.content) {\n\t\t\tif (part.type !== 'tool-call') continue\n\t\t\tif (part.result !== undefined) continue\n\n\t\t\tresult.push({\n\t\t\t\tmessageId: msg.id,\n\t\t\t\ttoolCallId: part.toolCallId,\n\t\t\t\ttoolName: part.toolName,\n\t\t\t\targs: (part.args as Record<string, unknown>) ?? {},\n\t\t\t})\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Find pending tool calls matching a specific tool name.\n *\n * @param threadRuntime - The thread runtime to query\n * @param toolName - The tool name to filter by\n * @returns Array of matching pending tool calls\n */\nexport function getPendingToolCallsByName(\n\tthreadRuntime: ThreadRuntime,\n\ttoolName: string\n): PendingToolCallInfo[] {\n\treturn getPendingToolCalls(threadRuntime).filter((tc) => tc.toolName === toolName)\n}\n\n/**\n * Resolve a pending tool call by adding a result.\n *\n * @param threadRuntime - The thread runtime\n * @param messageId - The message ID containing the tool call\n * @param toolCallId - The specific tool call ID to resolve\n * @param result - The result string to add\n * @returns true if resolved successfully, false if tool call not found\n */\nexport function resolvePendingToolCall(\n\tthreadRuntime: ThreadRuntime,\n\tmessageId: string,\n\ttoolCallId: string,\n\tresult: string\n): boolean {\n\tconst messageRuntime = threadRuntime.getMessageById(messageId)\n\tif (!messageRuntime) {\n\t\treturn false\n\t}\n\n\tconst messageState = messageRuntime.getState()\n\tconst hasPendingPart = messageState.content.some(\n\t\t(part) =>\n\t\t\tpart.type === 'tool-call' && part.toolCallId === toolCallId && part.result === undefined\n\t)\n\tif (!hasPendingPart) {\n\t\treturn false\n\t}\n\n\ttry {\n\t\tconst partRuntime = messageRuntime.getMessagePartByToolCallId(toolCallId)\n\t\tpartRuntime.addToolResult(result)\n\t\treturn true\n\t} catch (error) {\n\t\t// Message parts can disappear between the state check and runtime lookup when voice-mode\n\t\t// threads race with the assistant-ui runtime. Treat it as a no-op so we don't crash voice mode.\n\t\tif (error instanceof Error && error.message === 'Entry not available in the store') {\n\t\t\treturn false\n\t\t}\n\t\tthrow error\n\t}\n}\n\n/**\n * Resolve all pending tool calls matching a tool name.\n *\n * @param threadRuntime - The thread runtime\n * @param toolName - The tool name to match\n * @param result - The result string to add to all matches\n * @returns Number of tool calls resolved\n */\nexport function resolveAllPendingToolCallsByName(\n\tthreadRuntime: ThreadRuntime,\n\ttoolName: string,\n\tresult: string\n): number {\n\tconst pendingCalls = getPendingToolCallsByName(threadRuntime, toolName)\n\tlet resolved = 0\n\n\tfor (const call of pendingCalls) {\n\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\tresolved++\n\t\t}\n\t}\n\n\treturn resolved\n}\n\n/**\n * Resolve all pending tool calls in the thread.\n *\n * @param threadRuntime - The thread runtime\n * @param result - The result string to add to all pending calls\n * @returns Number of tool calls resolved\n */\nexport function resolveAllPendingToolCalls(threadRuntime: ThreadRuntime, result: string): number {\n\tconst pendingCalls = getPendingToolCalls(threadRuntime)\n\tlet resolved = 0\n\n\tfor (const call of pendingCalls) {\n\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\tresolved++\n\t\t}\n\t}\n\n\treturn resolved\n}\n","import { debugLog } from '../../utils/constants'\n\n/**\n * Audio analyzer for processing microphone and speaker audio streams.\n * Uses Web Audio API to analyze audio levels and frequency data.\n */\nexport class AudioAnalyzer {\n\tprivate audioContext: AudioContext | null = null\n\tprivate analyser: AnalyserNode | null = null\n\tprivate source: MediaStreamAudioSourceNode | null = null\n\tprivate dataArray: Uint8Array<ArrayBuffer> | null = null\n\tprivate animationId: number | null = null\n\n\t/**\n\t * Initialize the audio analyzer with a media stream\n\t * @param stream - MediaStream to analyze (typically from microphone or speaker)\n\t */\n\tasync initialize(stream: MediaStream): Promise<void> {\n\t\t// Log stream info for debugging\n\t\tconst audioTracks = stream.getAudioTracks()\n\t\tdebugLog('AudioAnalyzer', 'Initializing with stream', {\n\t\t\tstreamId: stream.id,\n\t\t\taudioTracks: audioTracks.length,\n\t\t\ttrackInfo: audioTracks.map((t) => ({\n\t\t\t\tid: t.id,\n\t\t\t\tlabel: t.label,\n\t\t\t\tenabled: t.enabled,\n\t\t\t\tmuted: t.muted,\n\t\t\t\treadyState: t.readyState,\n\t\t\t})),\n\t\t})\n\n\t\tthis.audioContext = new AudioContext()\n\t\tdebugLog('AudioAnalyzer', `AudioContext created, initial state: ${this.audioContext.state}`)\n\n\t\t// Always try to resume - some browsers need this regardless of reported state\n\t\ttry {\n\t\t\tawait this.audioContext.resume()\n\t\t\tdebugLog('AudioAnalyzer', `AudioContext after resume: ${this.audioContext.state}`)\n\t\t} catch (err) {\n\t\t\tconsole.warn('[AudioAnalyzer] Failed to resume AudioContext:', err)\n\t\t}\n\n\t\tthis.analyser = this.audioContext.createAnalyser()\n\t\tthis.analyser.fftSize = 256\n\t\tthis.analyser.smoothingTimeConstant = 0.8\n\n\t\tthis.source = this.audioContext.createMediaStreamSource(stream)\n\t\tthis.source.connect(this.analyser)\n\n\t\tconst bufferLength = this.analyser.frequencyBinCount\n\t\tthis.dataArray = new Uint8Array(new ArrayBuffer(bufferLength))\n\n\t\tdebugLog('AudioAnalyzer', 'Setup complete', {\n\t\t\tsampleRate: this.audioContext.sampleRate,\n\t\t\tfrequencyBinCount: bufferLength,\n\t\t\tcontextState: this.audioContext.state,\n\t\t})\n\t}\n\n\tgetAudioLevel(): number {\n\t\tif (!this.analyser || !this.dataArray) return 0\n\n\t\tthis.analyser.getByteFrequencyData(this.dataArray)\n\n\t\t// Calculate average volume\n\t\tlet sum = 0\n\t\tfor (let i = 0; i < this.dataArray.length; i++) {\n\t\t\tsum += this.dataArray[i]\n\t\t}\n\t\tconst average = sum / this.dataArray.length\n\n\t\t// Normalize to 0-1 range\n\t\treturn Math.min(1, average / 128)\n\t}\n\n\tgetFrequencyData(bins = 16): number[] {\n\t\tif (!this.analyser || !this.dataArray) return new Array(bins).fill(0)\n\n\t\tthis.analyser.getByteFrequencyData(this.dataArray)\n\n\t\tconst result: number[] = []\n\t\tconst samplesPerBin = Math.floor(this.dataArray.length / bins)\n\n\t\tfor (let i = 0; i < bins; i++) {\n\t\t\tlet sum = 0\n\t\t\tfor (let j = 0; j < samplesPerBin; j++) {\n\t\t\t\tsum += this.dataArray[i * samplesPerBin + j]\n\t\t\t}\n\t\t\t// Normalize to 0-1 range\n\t\t\tresult.push(Math.min(1, sum / samplesPerBin / 255))\n\t\t}\n\n\t\treturn result\n\t}\n\n\tstartAnalysis(callback: (level: number, frequencies: number[]) => void): void {\n\t\tconst analyze = () => {\n\t\t\tconst level = this.getAudioLevel()\n\t\t\tconst frequencies = this.getFrequencyData()\n\t\t\tcallback(level, frequencies)\n\t\t\tthis.animationId = requestAnimationFrame(analyze)\n\t\t}\n\t\tanalyze()\n\t}\n\n\tstopAnalysis(): void {\n\t\tif (this.animationId !== null) {\n\t\t\tcancelAnimationFrame(this.animationId)\n\t\t\tthis.animationId = null\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.stopAnalysis()\n\n\t\tif (this.source) {\n\t\t\tthis.source.disconnect()\n\t\t\tthis.source = null\n\t\t}\n\n\t\tif (this.analyser) {\n\t\t\tthis.analyser.disconnect()\n\t\t\tthis.analyser = null\n\t\t}\n\n\t\tif (this.audioContext) {\n\t\t\tvoid this.audioContext.close()\n\t\t\tthis.audioContext = null\n\t\t}\n\n\t\tthis.dataArray = null\n\t}\n}\n","import type { EventCallback, IEventEmitter } from './types'\n\nexport class EventEmitter implements IEventEmitter {\n\tprivate listeners = new Map<string, Set<EventCallback>>()\n\n\ton(event: string, callback: EventCallback): void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set())\n\t\t}\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tlisteners.add(callback)\n\t\t}\n\t}\n\n\toff(event: string, callback: EventCallback): void {\n\t\tthis.listeners.get(event)?.delete(callback)\n\t}\n\n\temit(event: string, data: unknown): void {\n\t\tthis.listeners.get(event)?.forEach((callback) => {\n\t\t\ttry {\n\t\t\t\tcallback(data)\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`Error in event listener for ${event}:`, error)\n\t\t\t}\n\t\t})\n\t}\n\n\tremoveAllListeners(event?: string): void {\n\t\tif (event) {\n\t\t\tthis.listeners.delete(event)\n\t\t} else {\n\t\t\tthis.listeners.clear()\n\t\t}\n\t}\n\n\tlistenerCount(event: string): number {\n\t\treturn this.listeners.get(event)?.size || 0\n\t}\n}\n","import { RESPONSE_REQUEST_DELAY_MS } from '../../utils/constants'\n\nimport type { EventEmitter } from './event-emitter'\nimport type { ToolManager } from './tool-manager'\nimport type { FunctionCall, RealtimeMessage } from './types'\n\n/**\n * Type for response output items from OpenAI Realtime API\n */\ninterface ResponseOutputItem {\n\ttype: string\n\tstatus?: string\n\tname?: string\n\tcall_id?: string\n\targuments?: string\n}\n\n/**\n * Type guard to check if an output item is a completed function call\n */\nfunction isCompletedFunctionCall(item: ResponseOutputItem): item is ResponseOutputItem & {\n\tname: string\n\tcall_id: string\n\targuments: string\n} {\n\treturn (\n\t\titem.type === 'function_call' &&\n\t\titem.status === 'completed' &&\n\t\ttypeof item.name === 'string' &&\n\t\ttypeof item.call_id === 'string'\n\t)\n}\n\nexport class MessageHandler {\n\tprivate isProcessingResponse = false\n\tprivate pendingFunctionCalls = new Set<string>()\n\tprivate responseRequestTimer: ReturnType<typeof setTimeout> | null = null\n\tprivate hasRequestedResponse = false\n\n\tconstructor(\n\t\tprivate toolManager: ToolManager,\n\t\tprivate eventEmitter: EventEmitter\n\t) {}\n\n\tasync handleMessage(data: string, dataChannel: RTCDataChannel): Promise<void> {\n\t\tlet msg: RealtimeMessage\n\n\t\ttry {\n\t\t\tmsg = JSON.parse(data) as RealtimeMessage\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to parse realtime message:', error)\n\t\t\treturn\n\t\t}\n\n\t\t// Log all incoming events for debugging\n\t\tconsole.log('[MessageHandler] Received event:', msg.type)\n\n\t\t// Route message to appropriate handler\n\t\tswitch (msg.type) {\n\t\t\tcase 'response.created':\n\t\t\t\tthis.handleResponseCreated(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'response.done':\n\t\t\t\tawait this.handleResponseDone(msg, dataChannel)\n\t\t\t\tbreak\n\n\t\t\tcase 'response.function_call_arguments.done':\n\t\t\t\tthis.handleFunctionCallArguments()\n\t\t\t\tbreak\n\n\t\t\tcase 'input_audio_buffer.speech_started':\n\t\t\tcase 'input_audio_buffer.speech_stopped':\n\t\t\t\tthis.handleSpeechEvents(msg)\n\t\t\t\tbreak\n\n\t\t\t// GA API: response.output_audio events\n\t\t\tcase 'response.output_audio.delta':\n\t\t\tcase 'response.output_audio.done':\n\t\t\t\tthis.handleAudioEvents(msg)\n\t\t\t\tbreak\n\n\t\t\t// Model audio transcript events (assistant speech -> text)\n\t\t\tcase 'response.audio_transcript.delta':\n\t\t\tcase 'response.audio_transcript.done':\n\t\t\t// Text response events\n\t\t\tcase 'response.text.delta':\n\t\t\tcase 'response.text.done':\n\t\t\t\tthis.handleTranscriptEvents(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'conversation.item.input_audio_transcription.completed':\n\t\t\t\tthis.handleUserTranscript(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'error':\n\t\t\t\tthis.handleError(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'session.created':\n\t\t\tcase 'session.updated':\n\t\t\t\tthis.handleSessionEvents(msg)\n\t\t\t\tbreak\n\n\t\t\tcase 'conversation.item.created':\n\t\t\tcase 'input_audio_buffer.committed':\n\t\t\t\t// Log only, no action needed\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tconsole.log('[MessageHandler] Unhandled event type:', msg.type, msg)\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate handleResponseCreated(_msg: RealtimeMessage): void {\n\t\tthis.isProcessingResponse = true\n\t\tthis.hasRequestedResponse = false\n\t}\n\n\tprivate async handleResponseDone(\n\t\tmsg: RealtimeMessage,\n\t\tdataChannel: RTCDataChannel\n\t): Promise<void> {\n\t\t// Safely extract response output with proper type checking\n\t\tconst outputItems = this.extractResponseOutput(msg.response)\n\n\t\t// Check if there are function calls to process\n\t\tconst hasFunctionCalls = outputItems.some(isCompletedFunctionCall)\n\n\t\t// Only set isProcessingResponse to false if there are no function calls\n\t\tif (!hasFunctionCalls) {\n\t\t\tthis.isProcessingResponse = false\n\t\t\tthis.hasRequestedResponse = false\n\t\t}\n\n\t\t// Process any function calls in the response\n\t\tif (outputItems.length > 0) {\n\t\t\t// Extract function calls with proper type narrowing\n\t\t\tconst functionCalls: FunctionCall[] = outputItems\n\t\t\t\t.filter(isCompletedFunctionCall)\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tname: item.name,\n\t\t\t\t\tcall_id: item.call_id,\n\t\t\t\t\targuments: item.arguments ?? '',\n\t\t\t\t}))\n\n\t\t\tfor (const functionCall of functionCalls) {\n\t\t\t\tif (!this.pendingFunctionCalls.has(functionCall.call_id)) {\n\t\t\t\t\tthis.pendingFunctionCalls.add(functionCall.call_id)\n\t\t\t\t\tawait this.executeFunctionCall(functionCall, dataChannel)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[MessageHandler] Skipping duplicate function call: ${functionCall.name} (${functionCall.call_id})`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// After all function calls are processed, check if we need to request a response\n\t\t\tif (functionCalls.length > 0 && this.pendingFunctionCalls.size === 0) {\n\t\t\t\tthis.requestResponseIfNeeded(dataChannel)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Safely extract response output array from response object\n\t */\n\tprivate extractResponseOutput(response: unknown): ResponseOutputItem[] {\n\t\tif (!response || typeof response !== 'object') {\n\t\t\treturn []\n\t\t}\n\n\t\tconst r = response as Record<string, unknown>\n\t\tif (!Array.isArray(r.output)) {\n\t\t\treturn []\n\t\t}\n\n\t\t// Filter to only valid output items\n\t\treturn r.output.filter(\n\t\t\t(item): item is ResponseOutputItem =>\n\t\t\t\titem !== null &&\n\t\t\t\ttypeof item === 'object' &&\n\t\t\t\ttypeof (item as ResponseOutputItem).type === 'string'\n\t\t)\n\t}\n\n\tprivate handleFunctionCallArguments(): void {\n\t\t// Function call arguments are being accumulated\n\t\t// Actual execution happens in handleResponseDone\n\t}\n\n\tprivate handleSpeechEvents(msg: RealtimeMessage): void {\n\t\tconst eventType =\n\t\t\tmsg.type === 'input_audio_buffer.speech_started' ? 'speech_started' : 'speech_stopped'\n\t\tthis.eventEmitter.emit(eventType, msg)\n\t}\n\n\tprivate handleAudioEvents(msg: RealtimeMessage): void {\n\t\tconst eventType = msg.type === 'response.output_audio.delta' ? 'audio_started' : 'audio_stopped'\n\t\tconsole.log(`[MessageHandler] Assistant ${eventType}`, {\n\t\t\ttype: msg.type,\n\t\t\thasAudio: !!(msg as { delta?: unknown }).delta,\n\t\t})\n\t\tthis.eventEmitter.emit(eventType, msg)\n\t}\n\n\tprivate handleTranscriptEvents(msg: RealtimeMessage): void {\n\t\t// Event name mappings for transcript events\n\t\tconst eventMap: Record<string, string> = {\n\t\t\t'response.audio_transcript.delta': 'assistant_transcript',\n\t\t\t'response.audio_transcript.done': 'assistant_transcript_done',\n\t\t\t'response.text.delta': 'text',\n\t\t\t'response.text.done': 'text_done',\n\t\t}\n\n\t\tconst eventType = eventMap[msg.type]\n\t\tconsole.log('[MessageHandler] Transcript event:', msg.type, {\n\t\t\teventType,\n\t\t\tdelta: (msg as { delta?: string }).delta,\n\t\t\ttranscript: (msg as { transcript?: string }).transcript,\n\t\t})\n\t\tif (eventType) {\n\t\t\tthis.eventEmitter.emit(eventType, msg)\n\t\t}\n\t}\n\n\tprivate handleUserTranscript(msg: RealtimeMessage): void {\n\t\tthis.eventEmitter.emit('user_transcript_done', { text: msg.transcript })\n\t}\n\n\tprivate handleSessionEvents(msg: RealtimeMessage): void {\n\t\t// Log session configuration for debugging\n\t\tconst session = msg.session as Record<string, unknown> | undefined\n\t\tif (session) {\n\t\t\tconst tools = session.tools as unknown[] | undefined\n\t\t\tconsole.log('[MessageHandler] Session event:', msg.type, {\n\t\t\t\ttoolCount: tools?.length ?? 0,\n\t\t\t\ttoolNames: tools?.slice(0, 5).map((t) => (t as { name?: string }).name),\n\t\t\t\thasOutputTranscription: !!session.output_audio_transcription,\n\t\t\t\thasInputTranscription: !!session.input_audio_transcription,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate handleError(msg: RealtimeMessage): void {\n\t\tconsole.error('Realtime API error:', msg)\n\t\tthis.eventEmitter.emit('error', msg)\n\t\tthis.isProcessingResponse = false\n\t\tthis.hasRequestedResponse = false\n\n\t\t// Clear any pending response timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\t}\n\n\tprivate async executeFunctionCall(\n\t\tfunctionCall: FunctionCall,\n\t\tdataChannel: RTCDataChannel\n\t): Promise<void> {\n\t\tconst { name, call_id } = functionCall\n\n\t\ttry {\n\t\t\t// Emit start event\n\t\t\tthis.eventEmitter.emit('tool_call_started', { name })\n\n\t\t\t// Execute tool\n\t\t\tconst result = await this.toolManager.executeToolCall(functionCall)\n\n\t\t\t// Check if data channel is still open before sending\n\t\t\tif (dataChannel.readyState !== 'open') {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[MessageHandler] Cannot send tool result for ${name}: DataChannel is ${dataChannel.readyState}`\n\t\t\t\t)\n\t\t\t\tthis.eventEmitter.emit('tool_call_completed', {\n\t\t\t\t\tname,\n\t\t\t\t\terror: 'DataChannel closed during tool execution',\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Send result back\n\t\t\tconst response = {\n\t\t\t\ttype: 'conversation.item.create',\n\t\t\t\titem: {\n\t\t\t\t\ttype: 'function_call_output',\n\t\t\t\t\tcall_id: call_id,\n\t\t\t\t\toutput: JSON.stringify(\n\t\t\t\t\t\tresult.success\n\t\t\t\t\t\t\t? result.data\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\terror: result.error,\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tdataChannel.send(JSON.stringify(response))\n\n\t\t\t// Emit completion event\n\t\t\tthis.eventEmitter.emit('tool_call_completed', {\n\t\t\t\tname,\n\t\t\t\terror: result.success ? undefined : result.error,\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tconsole.error(`[MessageHandler] Tool execution failed for ${name}:`, error)\n\t\t\tthis.sendToolError(call_id, String(error), dataChannel)\n\t\t} finally {\n\t\t\tthis.pendingFunctionCalls.delete(call_id)\n\n\t\t\t// After removing this function call, check if all are complete\n\t\t\tif (this.pendingFunctionCalls.size === 0) {\n\t\t\t\t// All function calls are done, now we can request a response\n\t\t\t\tthis.isProcessingResponse = false\n\t\t\t\tthis.hasRequestedResponse = false\n\t\t\t\tthis.requestResponseIfNeeded(dataChannel)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendToolError(call_id: string, error: string, dataChannel: RTCDataChannel): void {\n\t\t// Check if data channel is still open before sending error\n\t\tif (dataChannel.readyState !== 'open') {\n\t\t\tconsole.error(\n\t\t\t\t`[MessageHandler] Cannot send tool error: DataChannel is ${dataChannel.readyState}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\tconst errorResponse = {\n\t\t\ttype: 'conversation.item.create',\n\t\t\titem: {\n\t\t\t\ttype: 'function_call_output',\n\t\t\t\tcall_id: call_id,\n\t\t\t\toutput: JSON.stringify({ error, success: false }),\n\t\t\t},\n\t\t}\n\n\t\tdataChannel.send(JSON.stringify(errorResponse))\n\t}\n\n\tprivate requestResponseIfNeeded(dataChannel: RTCDataChannel): void {\n\t\t// Clear any existing timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\n\t\t// Set a new timer to request response (delay prevents race conditions)\n\t\tthis.responseRequestTimer = setTimeout(() => {\n\t\t\tif (\n\t\t\t\t!this.isProcessingResponse &&\n\t\t\t\t!this.hasRequestedResponse &&\n\t\t\t\tdataChannel.readyState === 'open' &&\n\t\t\t\tthis.pendingFunctionCalls.size === 0\n\t\t\t) {\n\t\t\t\tthis.hasRequestedResponse = true\n\t\t\t\tthis.isProcessingResponse = true\n\t\t\t\tdataChannel.send(JSON.stringify({ type: 'response.create' }))\n\t\t\t}\n\t\t\tthis.responseRequestTimer = null\n\t\t}, RESPONSE_REQUEST_DELAY_MS)\n\t}\n\n\treset(): void {\n\t\tthis.isProcessingResponse = false\n\t\tthis.hasRequestedResponse = false\n\t\tthis.pendingFunctionCalls.clear()\n\n\t\t// Clear any pending response timer\n\t\tif (this.responseRequestTimer) {\n\t\t\tclearTimeout(this.responseRequestTimer)\n\t\t\tthis.responseRequestTimer = null\n\t\t}\n\t}\n}\n","import { jsonrepair } from 'jsonrepair'\n\nimport type { FunctionCall, OpenAITool, ToolExecutionResult } from './types'\n\nexport interface RegisteredTool {\n\tname: string\n\tdescription: string\n\tinputSchema?: Record<string, unknown>\n}\n\nexport type ToolExecutor = (name: string, args: Record<string, unknown>) => Promise<unknown>\n\nexport class ToolManager {\n\tprivate tools: RegisteredTool[] = []\n\tprivate executor: ToolExecutor | null = null\n\tprivate lastSentToolSignature = ''\n\n\tsetTools(tools: RegisteredTool[]): void {\n\t\tconsole.log(\n\t\t\t'[ToolManager] setTools called:',\n\t\t\ttools.length,\n\t\t\t'tools,',\n\t\t\t'signature:',\n\t\t\tthis.getToolSignature(tools).slice(0, 100)\n\t\t)\n\t\tthis.tools = tools\n\t}\n\n\tsetExecutor(executor: ToolExecutor): void {\n\t\tthis.executor = executor\n\t}\n\n\tresetSession(): void {\n\t\tconsole.log('[ToolManager] resetSession called (lastSentToolSignature preserved)')\n\t}\n\n\tprivate getToolSignature(tools: RegisteredTool[]): string {\n\t\treturn tools\n\t\t\t.map((t) => t.name)\n\t\t\t.sort()\n\t\t\t.join('|')\n\t}\n\n\thasToolsChanged(): boolean {\n\t\tconst currentSignature = this.getToolSignature(this.tools)\n\t\tconst changed = currentSignature !== this.lastSentToolSignature\n\t\tconsole.log('[ToolManager] hasToolsChanged:', changed, {\n\t\t\tcurrentSignatureLength: currentSignature.length,\n\t\t\tlastSentSignatureLength: this.lastSentToolSignature.length,\n\t\t\tcurrentFirst50: currentSignature.slice(0, 50),\n\t\t\tlastSentFirst50: this.lastSentToolSignature.slice(0, 50),\n\t\t})\n\t\treturn changed\n\t}\n\n\tmarkToolsSent(): void {\n\t\tthis.lastSentToolSignature = this.getToolSignature(this.tools)\n\t}\n\n\tformatToolsForOpenAI(): OpenAITool[] {\n\t\t// Built-in tools\n\t\tconst builtInTools: OpenAITool[] = [\n\t\t\t{\n\t\t\t\ttype: 'function',\n\t\t\t\tname: 'list_available_tools',\n\t\t\t\tdescription:\n\t\t\t\t\t'List all currently available tools that can be called. Use this when you need to know what tools are available or when the user asks about available capabilities.',\n\t\t\t\tparameters: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {},\n\t\t\t\t\trequired: [],\n\t\t\t\t},\n\t\t\t},\n\t\t]\n\n\t\t// Registered tools\n\t\tconst registeredTools = this.tools.map((tool) => ({\n\t\t\ttype: 'function' as const,\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description || `Execute ${tool.name} action`,\n\t\t\tparameters: this.validateToolSchema(tool.inputSchema),\n\t\t}))\n\n\t\treturn [...builtInTools, ...registeredTools]\n\t}\n\n\tprivate validateToolSchema(schema: Record<string, unknown> | undefined): {\n\t\ttype: string\n\t\tproperties?: Record<string, unknown>\n\t\trequired?: string[]\n\t} {\n\t\tif (!schema) {\n\t\t\treturn { type: 'object', properties: {}, required: [] }\n\t\t}\n\n\t\tconst result: {\n\t\t\ttype: string\n\t\t\tproperties?: Record<string, unknown>\n\t\t\trequired?: string[]\n\t\t} = { type: 'object', ...schema }\n\n\t\tif (result.type === 'object') {\n\t\t\tresult.properties = (result.properties as Record<string, unknown>) || {}\n\n\t\t\t// Validate and fix nested schemas (especially arrays missing 'items')\n\t\t\tresult.properties = this.validateNestedSchemas(result.properties)\n\n\t\t\t// Generate required array if not present\n\t\t\tif (!result.required && result.properties) {\n\t\t\t\tresult.required = Object.entries(result.properties)\n\t\t\t\t\t.filter(([, prop]) => {\n\t\t\t\t\t\tif (prop && typeof prop === 'object') {\n\t\t\t\t\t\t\tconst p = prop as { optional?: boolean; nullable?: boolean; type?: string }\n\t\t\t\t\t\t\treturn !p.optional && !p.nullable && p.type !== 'null'\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false\n\t\t\t\t\t})\n\t\t\t\t\t.map(([key]) => key)\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Recursively validate nested schemas, ensuring array types have 'items'.\n\t * The OpenAI Realtime API requires array schemas to have an 'items' field.\n\t */\n\tprivate validateNestedSchemas(properties: Record<string, unknown>): Record<string, unknown> {\n\t\tconst validated: Record<string, unknown> = {}\n\n\t\tfor (const [key, value] of Object.entries(properties)) {\n\t\t\tif (!value || typeof value !== 'object') {\n\t\t\t\tvalidated[key] = value\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst prop = value as Record<string, unknown>\n\t\t\tconst propType = prop.type as string | undefined\n\n\t\t\tif (propType === 'array') {\n\t\t\t\t// Ensure array schemas have 'items' - required by OpenAI Realtime API\n\t\t\t\tif (!prop.items) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[ToolManager] Array property '${key}' missing 'items' - adding default string items`\n\t\t\t\t\t)\n\t\t\t\t\tvalidated[key] = {\n\t\t\t\t\t\t...prop,\n\t\t\t\t\t\titems: { type: 'string' },\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof prop.items === 'object') {\n\t\t\t\t\t// Recursively validate items schema\n\t\t\t\t\tconst items = prop.items as Record<string, unknown>\n\t\t\t\t\tif (items.type === 'object' && items.properties) {\n\t\t\t\t\t\tvalidated[key] = {\n\t\t\t\t\t\t\t...prop,\n\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t...items,\n\t\t\t\t\t\t\t\tproperties: this.validateNestedSchemas(items.properties as Record<string, unknown>),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalidated[key] = prop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalidated[key] = prop\n\t\t\t\t}\n\t\t\t} else if (propType === 'object' && prop.properties) {\n\t\t\t\t// Recursively validate nested object properties\n\t\t\t\tvalidated[key] = {\n\t\t\t\t\t...prop,\n\t\t\t\t\tproperties: this.validateNestedSchemas(prop.properties as Record<string, unknown>),\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvalidated[key] = prop\n\t\t\t}\n\t\t}\n\n\t\treturn validated\n\t}\n\n\tasync executeToolCall(functionCall: FunctionCall): Promise<ToolExecutionResult> {\n\t\tconst { name, arguments: argsString } = functionCall\n\n\t\t// Handle built-in tools\n\t\tif (name === 'list_available_tools') {\n\t\t\treturn this.executeListTools()\n\t\t}\n\n\t\t// Check if executor is set\n\t\tif (!this.executor) {\n\t\t\tconsole.error('[ToolManager] Tool executor not configured')\n\t\t\treturn { success: false, error: 'Tool executor not configured' }\n\t\t}\n\n\t\t// Parse arguments - use jsonrepair to handle malformed JSON from OpenAI\n\t\tlet args: Record<string, unknown>\n\t\ttry {\n\t\t\tconst repaired = argsString ? jsonrepair(argsString) : '{}'\n\t\t\targs = JSON.parse(repaired) as Record<string, unknown>\n\t\t} catch (error) {\n\t\t\tconsole.error('[ToolManager] Failed to parse arguments:', error)\n\t\t\tconsole.error('[ToolManager] Raw argsString:', argsString?.slice(0, 200))\n\t\t\treturn { success: false, error: 'Invalid arguments format' }\n\t\t}\n\n\t\t// Execute via the executor - it handles tool lookup from the current MCP context\n\t\t// Note: We intentionally don't verify the tool exists in this.tools first because\n\t\t// the executor has access to the latest tool list via React context/closure, which\n\t\t// may be more up-to-date than our cached copy (avoiding stale closure issues).\n\t\t// The executor will throw if the tool is not found.\n\t\ttry {\n\t\t\tconst result = await this.executor(name, args)\n\t\t\treturn { success: true, data: result }\n\t\t} catch (error) {\n\t\t\tconsole.error(`[ToolManager] Tool execution error for ${name}:`, error)\n\t\t\treturn { success: false, error: String(error) }\n\t\t}\n\t}\n\n\tprivate executeListTools(): ToolExecutionResult {\n\t\tconst toolList = this.tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description || 'No description available',\n\t\t\tparameters: tool.inputSchema || {},\n\t\t}))\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\ttools: toolList,\n\t\t\t\tcount: toolList.length,\n\t\t\t\tmessage:\n\t\t\t\t\ttoolList.length > 0\n\t\t\t\t\t\t? `Found ${toolList.length} available tools`\n\t\t\t\t\t\t: 'No tools currently available',\n\t\t\t},\n\t\t}\n\t}\n\n\tgetChangesSummary(): { added: string[]; removed: string[]; total: number } | null {\n\t\tif (!this.hasToolsChanged()) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst prevTools = this.lastSentToolSignature.split('|').filter(Boolean)\n\t\tconst currTools = this.tools.map((t) => t.name)\n\n\t\tconst prevSet = new Set(prevTools)\n\t\tconst currSet = new Set(currTools)\n\n\t\tconst added = currTools.filter((name) => !prevSet.has(name))\n\t\tconst removed = prevTools.filter((name) => !currSet.has(name))\n\n\t\treturn {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\ttotal: this.tools.length,\n\t\t}\n\t}\n}\n","import {\n\tdebugLog,\n\tREALTIME_DEFAULT_API_URL,\n\tREALTIME_DEFAULT_MODEL,\n\tREALTIME_DEFAULT_VOICE,\n} from '../../utils/constants'\n\nimport type { RealtimeConfig, RealtimeSession } from './types'\n\ninterface EphemeralTokenResponse {\n\tclient_secret?: {\n\t\tvalue?: string\n\t}\n}\n\nfunction hasClientSecret(response: unknown): response is {\n\tclient_secret: { value: string }\n} {\n\tif (!response || typeof response !== 'object') {\n\t\treturn false\n\t}\n\tconst secret = (response as EphemeralTokenResponse).client_secret\n\treturn typeof secret?.value === 'string'\n}\n\nexport class WebRTCManager {\n\tprivate tokenEndpoint: string\n\n\tconstructor(tokenEndpoint: string) {\n\t\tthis.tokenEndpoint = tokenEndpoint\n\t}\n\n\tasync createSession(config: RealtimeConfig = {}): Promise<RealtimeSession> {\n\t\tconst model = config.model || REALTIME_DEFAULT_MODEL\n\t\tconst voice = config.voice || REALTIME_DEFAULT_VOICE\n\t\tconst apiUrl = config.apiUrl || REALTIME_DEFAULT_API_URL\n\n\t\t// Get ephemeral token from our backend\n\t\tconst ephemeralKey = await this.getEphemeralToken(model, voice)\n\n\t\t// Create peer connection\n\t\tconst pc = new RTCPeerConnection()\n\n\t\t// Set up audio playback\n\t\tconst audioElement = this.createAudioElement()\n\t\t// Track streams\n\t\tlet remoteStream: MediaStream | null = null\n\t\tpc.ontrack = (e) => {\n\t\t\tremoteStream = e.streams[0]\n\t\t\taudioElement.srcObject = remoteStream\n\t\t\tdebugLog('WebRTC', 'Remote audio stream received and connected to audio element', {\n\t\t\t\tstreamId: remoteStream.id,\n\t\t\t\ttracks: remoteStream.getTracks().length,\n\t\t\t})\n\t\t}\n\n\t\t// Add microphone\n\t\tconst localStream = await this.getUserMedia()\n\t\tdebugLog('WebRTC', 'Local microphone stream acquired', {\n\t\t\tstreamId: localStream.id,\n\t\t\ttracks: localStream.getTracks().map((t) => ({\n\t\t\t\tkind: t.kind,\n\t\t\t\tenabled: t.enabled,\n\t\t\t\tmuted: t.muted,\n\t\t\t\treadyState: t.readyState,\n\t\t\t})),\n\t\t})\n\n\t\tlocalStream.getTracks().forEach((track) => {\n\t\t\tpc.addTrack(track, localStream)\n\t\t})\n\n\t\t// Create data channel for events\n\t\tconst dataChannel = pc.createDataChannel('oai-events')\n\n\t\t// Create offer and establish connection\n\t\tconst offer = await pc.createOffer()\n\t\tawait pc.setLocalDescription(offer)\n\n\t\t// Connect to OpenAI\n\t\tif (!offer.sdp) {\n\t\t\tthrow new Error('Failed to create offer SDP')\n\t\t}\n\t\tconst answer = await this.connectToOpenAI(apiUrl, model, offer.sdp, ephemeralKey)\n\t\tawait pc.setRemoteDescription(answer)\n\n\t\t// Create cleanup function\n\t\tconst cleanup = () => {\n\t\t\tlocalStream.getTracks().forEach((track) => {\n\t\t\t\ttrack.stop()\n\t\t\t})\n\t\t\taudioElement.remove()\n\t\t\tdataChannel.close()\n\t\t\tpc.close()\n\t\t}\n\n\t\treturn {\n\t\t\tpc,\n\t\t\tdataChannel,\n\t\t\taudioElement,\n\t\t\tlocalStream,\n\t\t\tremoteStream,\n\t\t\tcleanup,\n\t\t}\n\t}\n\n\tprivate async getEphemeralToken(model: string, voice: string): Promise<string> {\n\t\tconst response = await fetch(this.tokenEndpoint, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t},\n\t\t\tbody: JSON.stringify({ model, voice }),\n\t\t})\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text()\n\t\t\tconsole.error('Failed to get ephemeral token:', errorText)\n\t\t\tthrow new Error(`Failed to get ephemeral token: ${response.statusText}`)\n\t\t}\n\n\t\tconst data: unknown = await response.json()\n\n\t\tif (!hasClientSecret(data)) {\n\t\t\tthrow new Error('Invalid token response format')\n\t\t}\n\n\t\treturn data.client_secret.value\n\t}\n\n\tprivate createAudioElement(): HTMLAudioElement {\n\t\tconst audioElement = document.createElement('audio')\n\t\taudioElement.autoplay = true\n\t\taudioElement.style.display = 'none'\n\t\tdocument.body.appendChild(audioElement)\n\t\treturn audioElement\n\t}\n\n\tprivate async getUserMedia(): Promise<MediaStream> {\n\t\ttry {\n\t\t\treturn await navigator.mediaDevices.getUserMedia({\n\t\t\t\taudio: {\n\t\t\t\t\techoCancellation: true,\n\t\t\t\t\tnoiseSuppression: true,\n\t\t\t\t\tautoGainControl: true,\n\t\t\t\t},\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to access microphone: ${error}`)\n\t\t}\n\t}\n\n\tprivate async connectToOpenAI(\n\t\tbaseUrl: string,\n\t\tmodel: string,\n\t\tsdp: string,\n\t\tephemeralKey: string\n\t): Promise<RTCSessionDescriptionInit> {\n\t\tconst response = await fetch(`${baseUrl}?model=${model}`, {\n\t\t\tmethod: 'POST',\n\t\t\tbody: sdp,\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${ephemeralKey}`,\n\t\t\t\t'Content-Type': 'application/sdp',\n\t\t\t},\n\t\t})\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to establish WebRTC connection: ${response.statusText}`)\n\t\t}\n\n\t\tconst answerSdp = await response.text()\n\t\treturn {\n\t\t\ttype: 'answer' as const,\n\t\t\tsdp: answerSdp,\n\t\t}\n\t}\n}\n","import {\n\tAUDIO_FREQUENCY_BINS,\n\tAUDIO_VISUALIZATION_INTERVAL_MS,\n\tdebugLog,\n} from '../../utils/constants'\nimport { AudioAnalyzer } from './audio-analyzer'\nimport { EventEmitter } from './event-emitter'\nimport { MessageHandler } from './message-handler'\nimport { ToolManager } from './tool-manager'\nimport { WebRTCManager } from './webrtc-manager'\n\nimport type { RegisteredTool, ToolExecutor } from './tool-manager'\nimport type { EventCallback, RealtimeConfig, RealtimeSession, SessionConfig } from './types'\n\n/** Pre-allocated zero frequency array for performance */\nconst EMPTY_FREQUENCY_TEMPLATE = Object.freeze(new Array(AUDIO_FREQUENCY_BINS).fill(0))\nconst createZeroFrequencyArray = (): number[] => [...EMPTY_FREQUENCY_TEMPLATE]\n\n/**\n * OpenAI Realtime API Service\n *\n * Manages voice conversations with OpenAI's Realtime API,\n * including WebRTC connections, tool integration, and message handling.\n */\nexport class OpenAIRealtimeService {\n\tprivate session: RealtimeSession | null = null\n\tprivate webrtcManager: WebRTCManager\n\tprivate toolManager: ToolManager\n\tprivate messageHandler: MessageHandler\n\tprivate eventEmitter: EventEmitter\n\tprivate muted = false\n\tprivate lastState: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'\n\tprivate localAnalyzer: AudioAnalyzer | null = null\n\tprivate remoteAnalyzer: AudioAnalyzer | null = null\n\tprivate visualizationInterval: ReturnType<typeof setInterval> | null = null\n\tprivate sessionStartTime: number | null = null\n\tprivate onToolsChangedCallback: (() => void) | null = null\n\n\tconstructor(tokenEndpoint: string) {\n\t\tthis.webrtcManager = new WebRTCManager(tokenEndpoint)\n\t\tthis.toolManager = new ToolManager()\n\t\tthis.eventEmitter = new EventEmitter()\n\t\tthis.messageHandler = new MessageHandler(this.toolManager, this.eventEmitter)\n\t}\n\n\t/**\n\t * Set the tools available for the voice session\n\t */\n\tsetTools(tools: RegisteredTool[]): void {\n\t\tconsole.log(\n\t\t\t'[OpenAIRealtimeService] setTools called with',\n\t\t\ttools.length,\n\t\t\t'tools:',\n\t\t\ttools.slice(0, 5).map((t) => t.name).join(', '),\n\t\t\ttools.length > 5 ? `... and ${tools.length - 5} more` : ''\n\t\t)\n\t\tthis.toolManager.setTools(tools)\n\t\tif (this.isSessionActive()) {\n\t\t\tconsole.log('[OpenAIRealtimeService] Session is active, updating tools')\n\t\t\tthis.updateSessionTools()\n\t\t} else {\n\t\t\tconsole.log('[OpenAIRealtimeService] Session not active yet, tools will be included at session start')\n\t\t}\n\t}\n\n\t/**\n\t * Set the tool executor function\n\t */\n\tsetToolExecutor(executor: ToolExecutor): void {\n\t\tthis.toolManager.setExecutor(executor)\n\t}\n\n\t/**\n\t * Register callback for when tools change\n\t */\n\tonToolsChanged(callback: () => void): void {\n\t\tthis.onToolsChangedCallback = callback\n\t}\n\n\t/**\n\t * Start a new realtime session\n\t */\n\tasync startSession(config: RealtimeConfig = {}): Promise<RealtimeSession> {\n\t\ttry {\n\t\t\t// Clean up existing session\n\t\t\tif (this.session) {\n\t\t\t\tthis.stopSession()\n\t\t\t}\n\n\t\t\tthis.muted = false\n\t\t\tthis.sessionStartTime = Date.now()\n\t\t\tthis.emitSessionState('connecting')\n\n\t\t\t// Create new WebRTC session\n\t\t\tthis.session = await this.webrtcManager.createSession(config)\n\n\t\t\t// Setup data channel handlers\n\t\t\tthis.setupDataChannel(this.session.dataChannel)\n\n\t\t\t// Monitor peer connection state\n\t\t\tthis.setupPeerConnectionMonitoring(this.session.pc)\n\n\t\t\tif (this.session.localStream) {\n\t\t\t\tawait this.initializeLocalAnalyzer(this.session.localStream)\n\t\t\t}\n\n\t\t\tif (this.session.remoteStream) {\n\t\t\t\tvoid this.initializeRemoteAnalyzer(this.session.remoteStream)\n\t\t\t}\n\n\t\t\t// Update session reference for remote stream\n\t\t\tconst originalOntrack = this.session.pc.ontrack\n\t\t\tconst session = this.session\n\t\t\tthis.session.pc.ontrack = (e) => {\n\t\t\t\tif (originalOntrack) originalOntrack.call(session.pc, e)\n\t\t\t\tif (this.session) {\n\t\t\t\t\tthis.session.remoteStream = e.streams[0]\n\t\t\t\t}\n\n\t\t\t\tconst remoteStream = e.streams[0]\n\t\t\t\tif (!remoteStream) {\n\t\t\t\t\tconsole.warn('[OpenAIRealtimeService] Received ontrack event without stream')\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvoid this.initializeRemoteAnalyzer(remoteStream)\n\t\t\t}\n\n\t\t\treturn this.session\n\t\t} catch (error) {\n\t\t\tthis.handleSessionError(error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Stop the current session\n\t */\n\tstopSession(): void {\n\t\t// Calculate session duration for usage tracking\n\t\tlet durationSeconds = 0\n\t\tif (this.sessionStartTime) {\n\t\t\tdurationSeconds = Math.floor((Date.now() - this.sessionStartTime) / 1000)\n\t\t}\n\n\t\tif (this.visualizationInterval) {\n\t\t\tclearInterval(this.visualizationInterval)\n\t\t\tthis.visualizationInterval = null\n\t\t}\n\n\t\tif (this.localAnalyzer) {\n\t\t\tthis.localAnalyzer.destroy()\n\t\t\tthis.localAnalyzer = null\n\t\t}\n\n\t\tif (this.remoteAnalyzer) {\n\t\t\tthis.remoteAnalyzer.destroy()\n\t\t\tthis.remoteAnalyzer = null\n\t\t}\n\t\tif (this.session) {\n\t\t\tthis.session.cleanup()\n\t\t\tthis.session = null\n\t\t}\n\t\tthis.messageHandler.reset()\n\t\tthis.toolManager.resetSession()\n\n\t\t// Emit disconnected state with session duration\n\t\tthis.muted = false\n\t\tthis.emitSessionState('disconnected', { durationSeconds })\n\n\t\t// Reset session start time\n\t\tthis.sessionStartTime = null\n\t}\n\n\t/**\n\t * Send a text message to the assistant\n\t */\n\tsendUserMessage(text: string): void {\n\t\tif (!this.isSessionActive()) {\n\t\t\tthrow new Error('No active session')\n\t\t}\n\n\t\tconst message = {\n\t\t\ttype: 'conversation.item.create',\n\t\t\titem: {\n\t\t\t\ttype: 'message',\n\t\t\t\trole: 'user',\n\t\t\t\tcontent: [{ type: 'input_text', text }],\n\t\t\t},\n\t\t}\n\n\t\tif (!this.session) {\n\t\t\tthrow new Error('Session is not active')\n\t\t}\n\t\tthis.session.dataChannel.send(JSON.stringify(message))\n\t\tthis.session.dataChannel.send(JSON.stringify({ type: 'response.create' }))\n\t}\n\n\t/**\n\t * Check if session is active\n\t */\n\tisSessionActive(): boolean {\n\t\treturn this.session !== null && this.session.dataChannel.readyState === 'open'\n\t}\n\n\t/**\n\t * Get the local audio stream\n\t */\n\tgetLocalStream(): MediaStream | null {\n\t\treturn this.session?.localStream || null\n\t}\n\n\t/**\n\t * Get the remote audio stream\n\t */\n\tgetRemoteStream(): MediaStream | null {\n\t\treturn this.session?.remoteStream || null\n\t}\n\n\t/**\n\t * Toggle audio mute\n\t */\n\ttoggleMute(muted: boolean): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.muted = muted\n\t\t}\n\t\tthis.muted = muted\n\t\tthis.emitSessionState(this.lastState, { isMuted: this.muted })\n\t}\n\n\t/**\n\t * Pause audio playback (for approval flow)\n\t * This pauses the audio element without stopping the WebRTC stream.\n\t */\n\tpauseAudio(): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.pause()\n\t\t}\n\t}\n\n\t/**\n\t * Resume audio playback (after approval flow)\n\t */\n\tresumeAudio(): void {\n\t\tif (this.session?.audioElement) {\n\t\t\tthis.session.audioElement.play().catch((error) => {\n\t\t\t\t// Handle autoplay restrictions gracefully\n\t\t\t\tconsole.warn('[OpenAIRealtimeService] Failed to resume audio:', error)\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Event handling\n\t */\n\ton(event: string, callback: EventCallback): void {\n\t\tthis.eventEmitter.on(event, callback)\n\t}\n\n\toff(event: string, callback: EventCallback): void {\n\t\tthis.eventEmitter.off(event, callback)\n\t}\n\n\tgetSessionStatus(): {\n\t\tstate: 'connecting' | 'connected' | 'disconnected' | 'error'\n\t\tisActive: boolean\n\t\tisMuted: boolean\n\t} {\n\t\treturn {\n\t\t\tstate: this.lastState,\n\t\t\tisActive: this.lastState === 'connected',\n\t\t\tisMuted: this.muted,\n\t\t}\n\t}\n\n\t/**\n\t * Private methods\n\t */\n\tprivate setupDataChannel(dataChannel: RTCDataChannel): void {\n\t\t// Configure session when channel opens\n\t\tdataChannel.addEventListener('open', () => {\n\t\t\tthis.configureSession(dataChannel)\n\t\t\tthis.muted = false\n\t\t\tthis.emitSessionState('connected')\n\t\t})\n\n\t\t// Handle incoming messages\n\t\tdataChannel.addEventListener('message', (event: MessageEvent<string>) => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.messageHandler.handleMessage(event.data, dataChannel)\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Error handling message:', error)\n\t\t\t\t}\n\t\t\t})()\n\t\t})\n\n\t\t// Handle errors\n\t\tdataChannel.addEventListener('error', (error) => {\n\t\t\tconsole.error('DataChannel error:', error)\n\t\t\tthis.eventEmitter.emit('error', { type: 'datachannel_error', error })\n\t\t})\n\n\t\t// Handle close\n\t\tdataChannel.addEventListener('close', () => {\n\t\t\tthis.messageHandler.reset()\n\t\t\tthis.eventEmitter.emit('session_closed', {})\n\t\t})\n\t}\n\n\tprivate setupPeerConnectionMonitoring(pc: RTCPeerConnection): void {\n\t\t// Monitor connection state changes\n\t\tpc.addEventListener('connectionstatechange', () => {\n\t\t\tif (pc.connectionState === 'failed' || pc.connectionState === 'disconnected') {\n\t\t\t\tconsole.error('Peer connection failed or disconnected')\n\t\t\t\tthis.messageHandler.reset()\n\t\t\t\tthis.eventEmitter.emit('error', {\n\t\t\t\t\ttype: 'connection_error',\n\t\t\t\t\tmessage: `Connection ${pc.connectionState}`,\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\t// Monitor ICE connection state\n\t\tpc.addEventListener('iceconnectionstatechange', () => {\n\t\t\tif (pc.iceConnectionState === 'failed' || pc.iceConnectionState === 'disconnected') {\n\t\t\t\tconsole.error('ICE connection failed or disconnected')\n\t\t\t}\n\t\t})\n\n\t\t// Monitor signaling state\n\t\tpc.addEventListener('signalingstatechange', () => {})\n\t}\n\n\tprivate configureSession(dataChannel: RTCDataChannel): void {\n\t\tconsole.log('🎤🔧 [VOICE-DEBUG] configureSession CALLED - about to configure tools')\n\n\t\t// Reset per-session state\n\t\tthis.toolManager.resetSession()\n\n\t\t// Get initial tools\n\t\tconst tools = this.toolManager.formatToolsForOpenAI()\n\t\t// Mark tools as sent\n\t\tthis.toolManager.markToolsSent()\n\n\t\tconsole.log(\n\t\t\t'🎤🔧 [VOICE-DEBUG] CONFIGURING SESSION WITH',\n\t\t\ttools.length,\n\t\t\t'TOOLS:',\n\t\t\ttools.map((t) => t.name).join(', ')\n\t\t)\n\n\t\tconst sessionConfig: SessionConfig = {\n\t\t\tmodalities: ['text', 'audio'],\n\t\t\tinstructions: this.getSessionInstructions(),\n\t\t\tvoice: 'echo',\n\t\t\ttools: tools,\n\t\t\ttool_choice: 'auto',\n\t\t\tturn_detection: {\n\t\t\t\ttype: 'server_vad',\n\t\t\t\tthreshold: 0.5,\n\t\t\t\tprefix_padding_ms: 300,\n\t\t\t\tsilence_duration_ms: 500,\n\t\t\t},\n\t\t\tinput_audio_transcription: {\n\t\t\t\tmodel: 'whisper-1',\n\t\t\t},\n\t\t\toutput_audio_transcription: {\n\t\t\t\tmodel: 'whisper-1',\n\t\t\t},\n\t\t}\n\n\t\tconst sessionUpdate = {\n\t\t\ttype: 'session.update',\n\t\t\tsession: sessionConfig,\n\t\t}\n\n\t\tconsole.log('🎤🔧 [VOICE-DEBUG] SENDING session.update to OpenAI with tool_choice:', sessionConfig.tool_choice)\n\t\tdataChannel.send(JSON.stringify(sessionUpdate))\n\t\tconsole.log('🎤🔧 [VOICE-DEBUG] session.update SENT successfully')\n\t}\n\n\tprivate updateSessionTools(): void {\n\t\tif (!this.session) {\n\t\t\tconsole.warn('[OpenAIRealtimeService] Cannot update tools: no active session')\n\t\t\treturn\n\t\t}\n\n\t\tif (this.session.dataChannel.readyState !== 'open') {\n\t\t\tconsole.warn(\n\t\t\t\t`[OpenAIRealtimeService] Cannot update tools: DataChannel is ${this.session.dataChannel.readyState}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\t// Check if tools have actually changed\n\t\tconst changesSummary = this.toolManager.getChangesSummary()\n\t\tif (!changesSummary) {\n\t\t\tconsole.log('[OpenAIRealtimeService] updateSessionTools: No changes detected, skipping update')\n\t\t\treturn\n\t\t}\n\n\t\t// Get the full tool list\n\t\tconst tools = this.toolManager.formatToolsForOpenAI()\n\n\t\tconsole.log(\n\t\t\t'[OpenAIRealtimeService] Sending tool update to OpenAI:',\n\t\t\t`${changesSummary.total} total tools,`,\n\t\t\tchangesSummary.added.length > 0\n\t\t\t\t? `+${changesSummary.added.length} added (${changesSummary.added.slice(0, 3).join(', ')}${changesSummary.added.length > 3 ? '...' : ''})`\n\t\t\t\t: '',\n\t\t\tchangesSummary.removed.length > 0 ? `-${changesSummary.removed.length} removed` : ''\n\t\t)\n\n\t\t// Mark tools as sent\n\t\tthis.toolManager.markToolsSent()\n\n\t\tconst sessionUpdate = {\n\t\t\ttype: 'session.update',\n\t\t\tsession: {\n\t\t\t\ttools: tools,\n\t\t\t\ttool_choice: 'auto',\n\t\t\t},\n\t\t}\n\n\t\tthis.session.dataChannel.send(JSON.stringify(sessionUpdate))\n\t}\n\n\tprivate getSessionInstructions(): string {\n\t\treturn `You are a helpful assistant with access to tools.\n Use the available tools to help users with their tasks.\n You can use the list_available_tools function to see what tools are currently available.\n Be concise and helpful in your responses.`\n\t}\n\n\tprivate handleSessionError(error: unknown): void {\n\t\tconsole.error('Session error:', error)\n\t\tthis.emitSessionState('error', {\n\t\t\ttype: 'session_error',\n\t\t\terror: String(error),\n\t\t})\n\t\tthis.stopSession()\n\t}\n\n\tprivate async initializeLocalAnalyzer(stream: MediaStream): Promise<void> {\n\t\tif (this.localAnalyzer) {\n\t\t\tthis.localAnalyzer.destroy()\n\t\t}\n\n\t\tthis.localAnalyzer = new AudioAnalyzer()\n\t\ttry {\n\t\t\t// Clone the stream to avoid conflicts with WebRTC which consumes the original\n\t\t\tconst clonedStream = new MediaStream(stream.getAudioTracks().map((t) => t.clone()))\n\t\t\tawait this.localAnalyzer.initialize(clonedStream)\n\t\t\tthis.startAudioVisualization()\n\t\t} catch (error) {\n\t\t\tconsole.error('[OpenAIRealtimeService] Failed to initialize local audio analyzer', error)\n\t\t\tif (this.localAnalyzer) {\n\t\t\t\tthis.localAnalyzer.destroy()\n\t\t\t\tthis.localAnalyzer = null\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async initializeRemoteAnalyzer(stream: MediaStream): Promise<void> {\n\t\tif (this.remoteAnalyzer) {\n\t\t\tthis.remoteAnalyzer.destroy()\n\t\t}\n\n\t\tthis.remoteAnalyzer = new AudioAnalyzer()\n\t\ttry {\n\t\t\t// Clone the stream to avoid conflicts with WebRTC\n\t\t\tconst clonedStream = new MediaStream(stream.getAudioTracks().map((t) => t.clone()))\n\t\t\tawait this.remoteAnalyzer.initialize(clonedStream)\n\t\t\tthis.startAudioVisualization()\n\t\t} catch (error) {\n\t\t\tconsole.error('[OpenAIRealtimeService] Failed to initialize remote audio analyzer', error)\n\t\t\tif (this.remoteAnalyzer) {\n\t\t\t\tthis.remoteAnalyzer.destroy()\n\t\t\t\tthis.remoteAnalyzer = null\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startAudioVisualization(): void {\n\t\tif (!this.localAnalyzer && !this.remoteAnalyzer) {\n\t\t\tdebugLog('OpenAIRealtimeService', 'Audio visualization not started: no analyzers ready')\n\t\t\treturn\n\t\t}\n\n\t\tif (this.visualizationInterval) {\n\t\t\tclearInterval(this.visualizationInterval)\n\t\t}\n\n\t\tlet logCounter = 0\n\t\tthis.visualizationInterval = setInterval(() => {\n\t\t\tconst micLevel = this.localAnalyzer?.getAudioLevel() ?? 0\n\t\t\tconst micFrequency =\n\t\t\t\tthis.localAnalyzer?.getFrequencyData(AUDIO_FREQUENCY_BINS) ?? createZeroFrequencyArray()\n\t\t\tconst speakerLevel = this.remoteAnalyzer?.getAudioLevel() ?? 0\n\t\t\tconst speakerFrequency =\n\t\t\t\tthis.remoteAnalyzer?.getFrequencyData(AUDIO_FREQUENCY_BINS) ?? createZeroFrequencyArray()\n\n\t\t\t// Log audio levels periodically for debugging (every ~1 second)\n\t\t\tlogCounter++\n\t\t\tif (logCounter % 60 === 0) {\n\t\t\t\tdebugLog('OpenAIRealtimeService', 'Audio levels', {\n\t\t\t\t\tmic: micLevel.toFixed(3),\n\t\t\t\t\tspeaker: speakerLevel.toFixed(3),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis.eventEmitter.emit('audio_level', {\n\t\t\t\tmicLevel,\n\t\t\t\tmicFrequency,\n\t\t\t\tspeakerLevel,\n\t\t\t\tspeakerFrequency,\n\t\t\t})\n\t\t}, AUDIO_VISUALIZATION_INTERVAL_MS)\n\t}\n\n\tprivate emitSessionState(\n\t\tstate: 'connecting' | 'connected' | 'disconnected' | 'error',\n\t\textra: Record<string, unknown> = {}\n\t): void {\n\t\tthis.lastState = state\n\t\tconst payload = {\n\t\t\tstate,\n\t\t\tisActive: state === 'connected',\n\t\t\tisMuted: this.muted,\n\t\t\t...extra,\n\t\t}\n\n\t\tthis.eventEmitter.emit('session_state', payload)\n\n\t\tswitch (state) {\n\t\t\tcase 'connecting':\n\t\t\t\tthis.eventEmitter.emit('session_connecting', payload)\n\t\t\t\tbreak\n\t\t\tcase 'connected':\n\t\t\t\tthis.eventEmitter.emit('session_connected', payload)\n\t\t\t\tbreak\n\t\t\tcase 'disconnected':\n\t\t\t\tthis.eventEmitter.emit('session_closed', payload)\n\t\t\t\tbreak\n\t\t\tcase 'error':\n\t\t\t\tthis.eventEmitter.emit('error', payload)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Re-export types for convenience\nexport type { RealtimeConfig, RealtimeSession } from './types'\n","/**\n * Types for OpenAI Realtime API integration\n */\n\nexport interface RealtimeConfig {\n\tmodel?: string\n\tvoice?: string\n\tapiUrl?: string\n\ttokenEndpoint?: string\n}\n\nexport interface RealtimeSession {\n\tpc: RTCPeerConnection\n\tdataChannel: RTCDataChannel\n\taudioElement: HTMLAudioElement\n\tlocalStream: MediaStream | null\n\tremoteStream: MediaStream | null\n\tcleanup: () => void\n}\n\nexport interface OpenAITool {\n\ttype: 'function'\n\tname: string\n\tdescription: string\n\tparameters: {\n\t\ttype: string\n\t\tproperties?: Record<string, unknown>\n\t\trequired?: string[]\n\t}\n}\n\nexport interface SessionConfig {\n\tmodalities: string[]\n\tinstructions: string\n\tvoice?: string\n\ttools: OpenAITool[]\n\ttool_choice: string\n\tturn_detection: {\n\t\ttype: string\n\t\tthreshold: number\n\t\tprefix_padding_ms: number\n\t\tsilence_duration_ms: number\n\t}\n\tinput_audio_transcription?: {\n\t\tmodel: string\n\t}\n\toutput_audio_transcription?: {\n\t\tmodel: string\n\t}\n}\n\nexport interface FunctionCall {\n\tname: string\n\targuments: string\n\tcall_id: string\n\ttype?: string\n\tstatus?: string\n}\n\nexport interface ConversationItem {\n\ttype: string\n\trole?: string\n\tcontent?: unknown[]\n\tcall_id?: string\n\toutput?: string\n}\n\nexport interface RealtimeMessage {\n\ttype: string\n\t[key: string]: unknown\n}\n\nexport interface ToolExecutionResult {\n\tsuccess: boolean\n\tdata?: unknown\n\terror?: string\n}\n\nexport type EventCallback = (data: unknown) => void\n\nexport interface IEventEmitter {\n\ton(event: string, callback: EventCallback): void\n\toff(event: string, callback: EventCallback): void\n\temit(event: string, data: unknown): void\n}\n\nexport interface AudioLevelData {\n\tmicLevel: number\n\tmicFrequency: number[]\n\tspeakerLevel: number\n\tspeakerFrequency: number[]\n}\n\nexport interface TranscriptData {\n\ttype: 'user' | 'assistant'\n\ttext: string\n\tisDone: boolean\n}\n\nexport interface ToolCallData {\n\tstatus: 'started' | 'completed'\n\ttoolName: string\n\terror?: string\n}\n\nexport interface VoiceModeState {\n\tisActive: boolean\n\tisConnecting: boolean\n\tisMuted: boolean\n\tisError: boolean\n\tconnectionState: string\n\taudioLevel?: AudioLevelData\n\ttranscript?: TranscriptData\n\ttoolCall?: ToolCallData\n\terror?: string\n}\n\n// ============================================================================\n// Event Data Types - For type-safe event handling\n// ============================================================================\n\n/**\n * Session state event data from the realtime service\n */\nexport interface SessionStateEventData {\n\tstate: 'connecting' | 'connected' | 'disconnected' | 'error'\n\tisActive: boolean\n\tisMuted: boolean\n\tdurationSeconds?: number\n}\n\n/**\n * User transcript event data\n */\nexport interface UserTranscriptEventData {\n\ttext: string\n}\n\n/**\n * Assistant transcript streaming event data\n */\nexport interface AssistantTranscriptEventData {\n\tdelta?: string\n\ttranscript?: string\n}\n\n/**\n * Tool call started event data\n */\nexport interface ToolCallStartedEventData {\n\tname: string\n}\n\n/**\n * Tool call completed event data\n */\nexport interface ToolCallCompletedEventData {\n\tname: string\n\terror?: string\n}\n\n/**\n * Nested error object from OpenAI Realtime API\n */\nexport interface NestedErrorObject {\n\tcode?: string\n\tmessage?: string\n\tparam?: string\n\tevent_id?: string | null\n\ttype?: string\n}\n\n/**\n * Error event data\n * The 'error' field can be either a string or a nested error object from OpenAI\n */\nexport interface ErrorEventData {\n\terror?: string | NestedErrorObject\n\tmessage?: string\n\ttype?: string\n}\n\n// ============================================================================\n// Type Guards - Runtime type checking for event data\n// ============================================================================\n\n/**\n * Type guard for SessionStateEventData\n */\nexport function isSessionStateEventData(data: unknown): data is SessionStateEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn (\n\t\ttypeof d.state === 'string' &&\n\t\t['connecting', 'connected', 'disconnected', 'error'].includes(d.state) &&\n\t\ttypeof d.isActive === 'boolean' &&\n\t\ttypeof d.isMuted === 'boolean'\n\t)\n}\n\n/**\n * Type guard for UserTranscriptEventData\n */\nexport function isUserTranscriptEventData(data: unknown): data is UserTranscriptEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.text === 'string'\n}\n\n/**\n * Type guard for AssistantTranscriptEventData\n */\nexport function isAssistantTranscriptEventData(\n\tdata: unknown\n): data is AssistantTranscriptEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn d.delta === undefined || typeof d.delta === 'string'\n}\n\n/**\n * Type guard for ToolCallStartedEventData\n */\nexport function isToolCallStartedEventData(data: unknown): data is ToolCallStartedEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.name === 'string'\n}\n\n/**\n * Type guard for ToolCallCompletedEventData\n */\nexport function isToolCallCompletedEventData(data: unknown): data is ToolCallCompletedEventData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn typeof d.name === 'string'\n}\n\n/**\n * Type guard for ErrorEventData\n */\nexport function isErrorEventData(data: unknown): data is ErrorEventData {\n\tif (!data || typeof data !== 'object') return false\n\t// Error events must have at least one of these fields\n\tconst d = data as Record<string, unknown>\n\t// error can be a string OR an object with a message\n\tconst hasError = typeof d.error === 'string' || (typeof d.error === 'object' && d.error !== null)\n\treturn hasError || typeof d.message === 'string' || typeof d.type === 'string'\n}\n\n/**\n * Extract a string error message from ErrorEventData.\n * Handles both string errors and nested error objects from OpenAI Realtime API.\n */\nexport function extractErrorMessage(data: ErrorEventData): string {\n\t// Handle nested error object (OpenAI Realtime API format)\n\tif (data.error && typeof data.error === 'object') {\n\t\tconst nestedError = data.error as NestedErrorObject\n\t\treturn nestedError.message || nestedError.code || 'Unknown error'\n\t}\n\n\t// Handle string error\n\tif (typeof data.error === 'string') {\n\t\treturn data.error\n\t}\n\n\t// Fallback to message field\n\tif (typeof data.message === 'string') {\n\t\treturn data.message\n\t}\n\n\treturn 'Unknown error'\n}\n\n/**\n * Type guard for AudioLevelData\n */\nexport function isAudioLevelData(data: unknown): data is AudioLevelData {\n\tif (!data || typeof data !== 'object') return false\n\tconst d = data as Record<string, unknown>\n\treturn (\n\t\ttypeof d.micLevel === 'number' &&\n\t\tArray.isArray(d.micFrequency) &&\n\t\ttypeof d.speakerLevel === 'number' &&\n\t\tArray.isArray(d.speakerFrequency)\n\t)\n}\n","/**\n * Voice Mode Hook\n *\n * Manages OpenAI Realtime API voice sessions with WebRTC.\n * Provides audio level streaming, transcript events, and tool call tracking.\n *\n * @example Basic usage\n * ```tsx\n * const {\n * isActive,\n * startSession,\n * stopSession,\n * toggleMute\n * } = useVoiceMode({\n * tokenEndpoint: '/api/realtime/session'\n * })\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport {\n\tTOOL_CALL_DISPLAY_DURATION_MS,\n\tTOOL_CALL_ERROR_DISPLAY_DURATION_MS,\n} from '../utils/constants'\nimport {\n\textractErrorMessage,\n\tisAssistantTranscriptEventData,\n\tisAudioLevelData,\n\tisErrorEventData,\n\tisSessionStateEventData,\n\tisToolCallCompletedEventData,\n\tisToolCallStartedEventData,\n\tisUserTranscriptEventData,\n\tOpenAIRealtimeService,\n} from '../services/realtime'\n\nimport type {\n\tAudioLevelData,\n\tRealtimeConfig,\n\tRegisteredTool,\n\tToolCallData,\n\tToolExecutor,\n\tTranscriptData,\n\tVoiceModeState,\n} from '../services/realtime'\n\nexport interface UseVoiceModeOptions {\n\t/** Endpoint to get ephemeral tokens from */\n\ttokenEndpoint: string\n\t/** Tools available for the voice session */\n\ttools?: RegisteredTool[]\n\t/** Tool executor function */\n\ttoolExecutor?: ToolExecutor\n\t/** Callback when session connects */\n\tonConnect?: () => void\n\t/** Callback when session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when error occurs */\n\tonError?: (error: string) => void\n\t/** Callback when user transcript is complete */\n\tonUserTranscript?: (text: string) => void\n\t/** Callback when assistant transcript is complete */\n\tonAssistantTranscript?: (text: string) => void\n}\n\nexport interface UseVoiceModeReturn extends VoiceModeState {\n\t/** Start voice session */\n\tstartSession: (config?: RealtimeConfig) => Promise<void>\n\t/** Stop voice session */\n\tstopSession: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send text message while in voice mode */\n\tsendMessage: (text: string) => void\n\t/** Pause audio playback (for approval flow) */\n\tpauseAudio: () => void\n\t/** Resume audio playback (after approval flow) */\n\tresumeAudio: () => void\n}\n\nexport function useVoiceMode(options: UseVoiceModeOptions): UseVoiceModeReturn {\n\tconst {\n\t\ttokenEndpoint,\n\t\ttools,\n\t\ttoolExecutor,\n\t\tonConnect,\n\t\tonDisconnect,\n\t\tonError,\n\t\tonUserTranscript,\n\t\tonAssistantTranscript,\n\t} = options\n\n\t// State\n\tconst [isActive, setIsActive] = useState(false)\n\tconst [isConnecting, setIsConnecting] = useState(false)\n\tconst [isMuted, setIsMuted] = useState(false)\n\tconst [isError, setIsError] = useState(false)\n\tconst [connectionState, setConnectionState] = useState('disconnected')\n\tconst [audioLevel, setAudioLevel] = useState<AudioLevelData | undefined>()\n\tconst [transcript, setTranscript] = useState<TranscriptData | undefined>()\n\tconst [toolCall, setToolCall] = useState<ToolCallData | undefined>()\n\tconst [error, setError] = useState<string | undefined>()\n\n\t// Service ref\n\tconst serviceRef = useRef<OpenAIRealtimeService | null>(null)\n\n\t// Callbacks refs to avoid stale closures\n\tconst onConnectRef = useRef(onConnect)\n\tconst onDisconnectRef = useRef(onDisconnect)\n\tconst onErrorRef = useRef(onError)\n\tconst onUserTranscriptRef = useRef(onUserTranscript)\n\tconst onAssistantTranscriptRef = useRef(onAssistantTranscript)\n\n\tuseEffect(() => {\n\t\tonConnectRef.current = onConnect\n\t\tonDisconnectRef.current = onDisconnect\n\t\tonErrorRef.current = onError\n\t\tonUserTranscriptRef.current = onUserTranscript\n\t\tonAssistantTranscriptRef.current = onAssistantTranscript\n\t}, [onConnect, onDisconnect, onError, onUserTranscript, onAssistantTranscript])\n\n\t// Get or create service instance\n\tconst getService = useCallback(() => {\n\t\tif (!serviceRef.current) {\n\t\t\tserviceRef.current = new OpenAIRealtimeService(tokenEndpoint)\n\t\t}\n\t\treturn serviceRef.current\n\t}, [tokenEndpoint])\n\n\t// Update tools when they change\n\tuseEffect(() => {\n\t\tif (tools) {\n\t\t\tconst service = getService()\n\t\t\tservice.setTools(tools)\n\t\t}\n\t}, [tools, getService])\n\n\t// Update tool executor when it changes\n\tuseEffect(() => {\n\t\tif (toolExecutor) {\n\t\t\tconst service = getService()\n\t\t\tservice.setToolExecutor(toolExecutor)\n\t\t}\n\t}, [toolExecutor, getService])\n\n\t// Set up event listeners\n\tuseEffect(() => {\n\t\tconst service = getService()\n\n\t\t// Session state handler - uses type guard for safe access\n\t\tconst handleSessionState = (data: unknown) => {\n\t\t\tif (!isSessionStateEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid session state event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tsetConnectionState(data.state)\n\t\t\tsetIsActive(data.isActive)\n\t\t\tsetIsMuted(data.isMuted)\n\t\t\tsetIsConnecting(data.state === 'connecting')\n\t\t\tsetIsError(data.state === 'error')\n\n\t\t\tif (data.state === 'connected') {\n\t\t\t\tonConnectRef.current?.()\n\t\t\t} else if (data.state === 'disconnected') {\n\t\t\t\tonDisconnectRef.current?.(data.durationSeconds ?? 0)\n\t\t\t}\n\t\t}\n\n\t\t// Audio level handler - uses type guard for safe access\n\t\tconst handleAudioLevel = (data: unknown) => {\n\t\t\tif (isAudioLevelData(data)) {\n\t\t\t\tsetAudioLevel(data)\n\t\t\t}\n\t\t}\n\n\t\t// User transcript handler - uses type guard for safe access\n\t\tconst handleUserTranscript = (data: unknown) => {\n\t\t\tif (!isUserTranscriptEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid user transcript event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetTranscript({ type: 'user', text: data.text, isDone: true })\n\t\t\tonUserTranscriptRef.current?.(data.text)\n\t\t}\n\n\t\t// Assistant transcript handler (streaming) - uses type guard for safe access\n\t\tconst handleAssistantTranscript = (data: unknown) => {\n\t\t\tif (!isAssistantTranscriptEventData(data)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst text = data.delta || data.transcript || ''\n\t\t\tsetTranscript((prev) => ({\n\t\t\t\ttype: 'assistant',\n\t\t\t\ttext: prev?.type === 'assistant' ? prev.text + text : text,\n\t\t\t\tisDone: false,\n\t\t\t}))\n\t\t}\n\n\t\t// Assistant transcript done handler - uses type guard for safe access\n\t\tconst handleAssistantTranscriptDone = (data: unknown) => {\n\t\t\tif (!isAssistantTranscriptEventData(data)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst text = data.transcript || ''\n\t\t\tsetTranscript({ type: 'assistant', text, isDone: true })\n\t\t\tonAssistantTranscriptRef.current?.(text)\n\t\t}\n\n\t\t// Tool call started handler - uses type guard for safe access\n\t\tconst handleToolCallStarted = (data: unknown) => {\n\t\t\tif (!isToolCallStartedEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid tool call started event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetToolCall({ status: 'started', toolName: data.name })\n\t\t}\n\n\t\t// Tool call completed handler - uses type guard for safe access\n\t\tconst handleToolCallCompleted = (data: unknown) => {\n\t\t\tif (!isToolCallCompletedEventData(data)) {\n\t\t\t\tconsole.warn('[useVoiceMode] Invalid tool call completed event data:', data)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetToolCall({ status: 'completed', toolName: data.name, error: data.error })\n\n\t\t\t// Clear tool call after a delay (longer for errors)\n\t\t\tsetTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tsetToolCall(undefined)\n\t\t\t\t},\n\t\t\t\tdata.error ? TOOL_CALL_ERROR_DISPLAY_DURATION_MS : TOOL_CALL_DISPLAY_DURATION_MS\n\t\t\t)\n\t\t}\n\n\t\t// Error handler - uses type guard for safe access\n\t\tconst handleError = (data: unknown) => {\n\t\t\tif (!isErrorEventData(data)) {\n\t\t\t\tsetError('Unknown error')\n\t\t\t\tsetIsError(true)\n\t\t\t\tonErrorRef.current?.('Unknown error')\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Use extractErrorMessage to handle both string and nested object errors\n\t\t\tconst errorMsg = extractErrorMessage(data)\n\t\t\tsetError(errorMsg)\n\t\t\tsetIsError(true)\n\t\t\tonErrorRef.current?.(errorMsg)\n\t\t}\n\n\t\t// Register listeners\n\t\tservice.on('session_state', handleSessionState)\n\t\tservice.on('audio_level', handleAudioLevel)\n\t\tservice.on('user_transcript_done', handleUserTranscript)\n\t\tservice.on('assistant_transcript', handleAssistantTranscript)\n\t\tservice.on('assistant_transcript_done', handleAssistantTranscriptDone)\n\t\tservice.on('tool_call_started', handleToolCallStarted)\n\t\tservice.on('tool_call_completed', handleToolCallCompleted)\n\t\tservice.on('error', handleError)\n\n\t\t// Cleanup\n\t\treturn () => {\n\t\t\tservice.off('session_state', handleSessionState)\n\t\t\tservice.off('audio_level', handleAudioLevel)\n\t\t\tservice.off('user_transcript_done', handleUserTranscript)\n\t\t\tservice.off('assistant_transcript', handleAssistantTranscript)\n\t\t\tservice.off('assistant_transcript_done', handleAssistantTranscriptDone)\n\t\t\tservice.off('tool_call_started', handleToolCallStarted)\n\t\t\tservice.off('tool_call_completed', handleToolCallCompleted)\n\t\t\tservice.off('error', handleError)\n\t\t}\n\t}, [getService])\n\n\t// Start session\n\tconst startSession = useCallback(\n\t\tasync (config?: RealtimeConfig) => {\n\t\t\ttry {\n\t\t\t\tsetIsConnecting(true)\n\t\t\t\tsetIsError(false)\n\t\t\t\tsetError(undefined)\n\n\t\t\t\tconst service = getService()\n\t\t\t\tawait service.startSession(config)\n\t\t\t} catch (err) {\n\t\t\t\tsetIsConnecting(false)\n\t\t\t\tsetIsError(true)\n\t\t\t\tconst errorMsg = err instanceof Error ? err.message : 'Failed to start session'\n\t\t\t\tsetError(errorMsg)\n\t\t\t\tonErrorRef.current?.(errorMsg)\n\t\t\t}\n\t\t},\n\t\t[getService]\n\t)\n\n\t// Stop session\n\tconst stopSession = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.stopSession()\n\t\tsetAudioLevel(undefined)\n\t\tsetTranscript(undefined)\n\t\tsetToolCall(undefined)\n\t}, [getService])\n\n\t// Toggle mute\n\tconst toggleMute = useCallback(\n\t\t(muted?: boolean) => {\n\t\t\tconst service = getService()\n\t\t\tconst newMuted = muted !== undefined ? muted : !isMuted\n\t\t\tservice.toggleMute(newMuted)\n\t\t\tsetIsMuted(newMuted)\n\t\t},\n\t\t[getService, isMuted]\n\t)\n\n\t// Send message\n\tconst sendMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tconst service = getService()\n\t\t\tif (service.isSessionActive()) {\n\t\t\t\tservice.sendUserMessage(text)\n\t\t\t}\n\t\t},\n\t\t[getService]\n\t)\n\n\t// Pause audio (for approval flow)\n\tconst pauseAudio = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.pauseAudio()\n\t}, [getService])\n\n\t// Resume audio (after approval flow)\n\tconst resumeAudio = useCallback(() => {\n\t\tconst service = getService()\n\t\tservice.resumeAudio()\n\t}, [getService])\n\n\t// Memoize return value\n\treturn useMemo(\n\t\t() => ({\n\t\t\tisActive,\n\t\t\tisConnecting,\n\t\t\tisMuted,\n\t\t\tisError,\n\t\t\tconnectionState,\n\t\t\taudioLevel,\n\t\t\ttranscript,\n\t\t\ttoolCall,\n\t\t\terror,\n\t\t\tstartSession,\n\t\t\tstopSession,\n\t\t\ttoggleMute,\n\t\t\tsendMessage,\n\t\t\tpauseAudio,\n\t\t\tresumeAudio,\n\t\t}),\n\t\t[\n\t\t\tisActive,\n\t\t\tisConnecting,\n\t\t\tisMuted,\n\t\t\tisError,\n\t\t\tconnectionState,\n\t\t\taudioLevel,\n\t\t\ttranscript,\n\t\t\ttoolCall,\n\t\t\terror,\n\t\t\tstartSession,\n\t\t\tstopSession,\n\t\t\ttoggleMute,\n\t\t\tsendMessage,\n\t\t\tpauseAudio,\n\t\t\tresumeAudio,\n\t\t]\n\t)\n}\n","import { createContext, useContext, useMemo } from 'react'\n\nimport { useVoiceMode } from '../hooks/useVoiceMode'\n\nimport type { ReactNode } from 'react'\nimport type { UseVoiceModeReturn } from '../hooks/useVoiceMode'\nimport type { RegisteredTool, ToolExecutor } from '../services/realtime'\n\n/**\n * Voice Mode Provider\n *\n * Provides voice mode state and controls to the component tree.\n */\n\nexport interface VoiceModeContextValue extends UseVoiceModeReturn {\n\tisSupported: boolean\n}\n\nconst VoiceModeContext = createContext<VoiceModeContextValue | null>(null)\n\nexport interface VoiceModeProviderProps {\n\tchildren: ReactNode\n\t/** Backend endpoint for ephemeral tokens */\n\ttokenEndpoint: string\n\t/** Tools available for voice mode */\n\ttools?: RegisteredTool[]\n\t/** Tool executor function */\n\ttoolExecutor?: ToolExecutor\n\t/** Callback when session connects */\n\tonConnect?: () => void\n\t/** Callback when session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when error occurs */\n\tonError?: (error: string) => void\n\t/** Callback when user transcript is complete */\n\tonUserTranscript?: (text: string) => void\n\t/** Callback when assistant transcript is complete */\n\tonAssistantTranscript?: (text: string) => void\n}\n\n/**\n * Check if the browser supports WebRTC and getUserMedia\n */\nfunction checkVoiceModeSupport(): boolean {\n\treturn !!(\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.RTCPeerConnection &&\n\t\tnavigator.mediaDevices?.getUserMedia\n\t)\n}\n\nexport function VoiceModeProvider({\n\tchildren,\n\ttokenEndpoint,\n\ttools,\n\ttoolExecutor,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n\tonUserTranscript,\n\tonAssistantTranscript,\n}: VoiceModeProviderProps) {\n\tconst voiceMode = useVoiceMode({\n\t\ttokenEndpoint,\n\t\ttools,\n\t\ttoolExecutor,\n\t\tonConnect,\n\t\tonDisconnect,\n\t\tonError,\n\t\tonUserTranscript,\n\t\tonAssistantTranscript,\n\t})\n\n\tconst isSupported = useMemo(() => checkVoiceModeSupport(), [])\n\n\tconst value = useMemo(\n\t\t() => ({\n\t\t\t...voiceMode,\n\t\t\tisSupported,\n\t\t}),\n\t\t[voiceMode, isSupported]\n\t)\n\n\treturn <VoiceModeContext.Provider value={value}>{children}</VoiceModeContext.Provider>\n}\n\n/**\n * Hook to access voice mode context\n */\nexport function useVoiceModeContext(): VoiceModeContextValue {\n\tconst context = useContext(VoiceModeContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceModeContext must be used within a VoiceModeProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice mode context (returns null if not in provider)\n */\nexport function useOptionalVoiceModeContext(): VoiceModeContextValue | null {\n\treturn useContext(VoiceModeContext)\n}\n","/**\n * Voice Tool Approval Provider\n *\n * Manages tool approval state for voice mode. When a destructive tool is called\n * during a voice session, this provider pauses execution and waits for the user\n * to approve or deny (via voice keywords or button tap).\n *\n * Key features:\n * - 30-second timeout with auto-deny (safe default)\n * - Support for both voice keyword detection and button tap\n * - Single pending approval at a time (voice mode is sequential)\n *\n * @example\n * ```tsx\n * <VoiceToolApprovalProvider>\n * <VoiceMode />\n * </VoiceToolApprovalProvider>\n *\n * // In a component:\n * const { pendingApproval, approve, deny, requestApproval } = useVoiceToolApproval()\n * ```\n */\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS, VOICE_APPROVAL_TIMEOUT_MS } from '../utils/constants'\n\nimport type { FC, ReactNode } from 'react'\n\n/**\n * Pending approval request\n */\nexport interface VoicePendingApproval {\n\t/** Unique call ID from OpenAI Realtime */\n\tcallId: string\n\t/** Name of the tool being requested */\n\ttoolName: string\n\t/** Arguments passed to the tool */\n\targs: Record<string, unknown>\n\t/** Timestamp when approval was requested */\n\ttimestamp: number\n}\n\n/**\n * Voice Tool Approval Context Value\n */\nexport interface VoiceToolApprovalContextValue {\n\t/** Current pending approval (null if none) */\n\tpendingApproval: VoicePendingApproval | null\n\t/** Approve the current pending tool call */\n\tapprove: () => void\n\t/** Deny the current pending tool call */\n\tdeny: () => void\n\t/** Seconds remaining before auto-deny */\n\ttimeoutRemaining: number\n\t/** Whether we're currently waiting for approval */\n\tisWaitingForApproval: boolean\n\t/**\n\t * Request approval for a tool call.\n\t * Returns a Promise that resolves to true (approved) or false (denied/timeout).\n\t */\n\trequestApproval: (\n\t\tcallId: string,\n\t\ttoolName: string,\n\t\targs: Record<string, unknown>\n\t) => Promise<boolean>\n\t/** Clear any pending approval without resolving (e.g., when voice session ends) */\n\tclearPendingApproval: () => void\n}\n\nconst VoiceToolApprovalContext = createContext<VoiceToolApprovalContextValue | null>(null)\n\nexport interface VoiceToolApprovalProviderProps {\n\tchildren: ReactNode\n\t/** Custom timeout in milliseconds (defaults to VOICE_APPROVAL_TIMEOUT_MS) */\n\ttimeout?: number\n\t/** Callback when approval times out */\n\tonTimeout?: (toolName: string) => void\n\t/** Callback when user approves */\n\tonApprove?: (toolName: string) => void\n\t/** Callback when user denies */\n\tonDeny?: (toolName: string) => void\n}\n\n/**\n * Provider for voice mode tool approval.\n *\n * Wraps voice mode components to enable approval workflow for destructive tools.\n */\nexport const VoiceToolApprovalProvider: FC<VoiceToolApprovalProviderProps> = ({\n\tchildren,\n\ttimeout = VOICE_APPROVAL_TIMEOUT_MS,\n\tonTimeout,\n\tonApprove,\n\tonDeny,\n}) => {\n\t// Current pending approval\n\tconst [pendingApproval, setPendingApproval] = useState<VoicePendingApproval | null>(null)\n\n\t// Time remaining for countdown\n\tconst [timeoutRemaining, setTimeoutRemaining] = useState(0)\n\n\t// Refs for the resolve function and timeout\n\tconst resolveRef = useRef<((approved: boolean) => void) | null>(null)\n\tconst timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\tconst countdownIdRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n\t// Callback refs to avoid stale closures\n\tconst onTimeoutRef = useRef(onTimeout)\n\tconst onApproveRef = useRef(onApprove)\n\tconst onDenyRef = useRef(onDeny)\n\tonTimeoutRef.current = onTimeout\n\tonApproveRef.current = onApprove\n\tonDenyRef.current = onDeny\n\n\t/**\n\t * Clear all timers\n\t */\n\tconst clearTimers = useCallback(() => {\n\t\tif (timeoutIdRef.current) {\n\t\t\tclearTimeout(timeoutIdRef.current)\n\t\t\ttimeoutIdRef.current = null\n\t\t}\n\t\tif (countdownIdRef.current) {\n\t\t\tclearInterval(countdownIdRef.current)\n\t\t\tcountdownIdRef.current = null\n\t\t}\n\t}, [])\n\n\t/**\n\t * Resolve the pending approval and clean up\n\t */\n\tconst resolveApproval = useCallback(\n\t\t(approved: boolean, reason: 'approve' | 'deny' | 'timeout' = approved ? 'approve' : 'deny') => {\n\t\t\tconst toolName = pendingApproval?.toolName\n\n\t\t\t// Resolve the promise\n\t\t\tif (resolveRef.current) {\n\t\t\t\tresolveRef.current(approved)\n\t\t\t\tresolveRef.current = null\n\t\t\t}\n\n\t\t\t// Clear state\n\t\t\tclearTimers()\n\t\t\tsetPendingApproval(null)\n\t\t\tsetTimeoutRemaining(0)\n\n\t\t\t// Fire callbacks\n\t\t\tif (toolName) {\n\t\t\t\tif (reason === 'timeout') {\n\t\t\t\t\tonTimeoutRef.current?.(toolName)\n\t\t\t\t} else if (reason === 'approve') {\n\t\t\t\t\tonApproveRef.current?.(toolName)\n\t\t\t\t} else {\n\t\t\t\t\tonDenyRef.current?.(toolName)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[pendingApproval?.toolName, clearTimers]\n\t)\n\n\t/**\n\t * Approve the current pending tool call\n\t */\n\tconst approve = useCallback(() => {\n\t\tif (pendingApproval) {\n\t\t\tresolveApproval(true, 'approve')\n\t\t}\n\t}, [pendingApproval, resolveApproval])\n\n\t/**\n\t * Deny the current pending tool call\n\t */\n\tconst deny = useCallback(() => {\n\t\tif (pendingApproval) {\n\t\t\tresolveApproval(false, 'deny')\n\t\t}\n\t}, [pendingApproval, resolveApproval])\n\n\t/**\n\t * Clear pending approval without resolving (for cleanup)\n\t */\n\tconst clearPendingApproval = useCallback(() => {\n\t\tif (resolveRef.current) {\n\t\t\tresolveRef.current(false)\n\t\t\tresolveRef.current = null\n\t\t}\n\t\tclearTimers()\n\t\tsetPendingApproval(null)\n\t\tsetTimeoutRemaining(0)\n\t}, [clearTimers])\n\n\t/**\n\t * Request approval for a tool call.\n\t * Returns a Promise that resolves when the user approves/denies or timeout occurs.\n\t */\n\tconst requestApproval = useCallback(\n\t\t(callId: string, toolName: string, args: Record<string, unknown>): Promise<boolean> => {\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\t// If there's already a pending approval, deny it first\n\t\t\t\tif (resolveRef.current) {\n\t\t\t\t\tresolveRef.current(false)\n\t\t\t\t}\n\t\t\t\tclearTimers()\n\n\t\t\t\t// Store the resolve function\n\t\t\t\tresolveRef.current = resolve\n\n\t\t\t\t// Set pending approval state\n\t\t\t\tsetPendingApproval({\n\t\t\t\t\tcallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\targs,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t})\n\n\t\t\t\t// Set initial timeout remaining\n\t\t\t\tconst timeoutSeconds = Math.ceil(timeout / 1000)\n\t\t\t\tsetTimeoutRemaining(timeoutSeconds)\n\n\t\t\t\t// Start countdown interval\n\t\t\t\tcountdownIdRef.current = setInterval(() => {\n\t\t\t\t\tsetTimeoutRemaining((prev) => {\n\t\t\t\t\t\tif (prev <= 1) {\n\t\t\t\t\t\t\treturn 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn prev - 1\n\t\t\t\t\t})\n\t\t\t\t}, VOICE_APPROVAL_COUNTDOWN_INTERVAL_MS)\n\n\t\t\t\t// Set auto-deny timeout\n\t\t\t\ttimeoutIdRef.current = setTimeout(() => {\n\t\t\t\t\t// Auto-deny on timeout\n\t\t\t\t\tif (resolveRef.current) {\n\t\t\t\t\t\tresolveRef.current(false)\n\t\t\t\t\t\tresolveRef.current = null\n\t\t\t\t\t}\n\t\t\t\t\tclearTimers()\n\t\t\t\t\tsetPendingApproval(null)\n\t\t\t\t\tsetTimeoutRemaining(0)\n\t\t\t\t\tonTimeoutRef.current?.(toolName)\n\t\t\t\t}, timeout)\n\t\t\t})\n\t\t},\n\t\t[timeout, clearTimers]\n\t)\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tclearTimers()\n\t\t\tif (resolveRef.current) {\n\t\t\t\tresolveRef.current(false)\n\t\t\t\tresolveRef.current = null\n\t\t\t}\n\t\t}\n\t}, [clearTimers])\n\n\tconst value = useMemo<VoiceToolApprovalContextValue>(\n\t\t() => ({\n\t\t\tpendingApproval,\n\t\t\tapprove,\n\t\t\tdeny,\n\t\t\ttimeoutRemaining,\n\t\t\tisWaitingForApproval: pendingApproval !== null,\n\t\t\trequestApproval,\n\t\t\tclearPendingApproval,\n\t\t}),\n\t\t[pendingApproval, approve, deny, timeoutRemaining, requestApproval, clearPendingApproval]\n\t)\n\n\treturn (\n\t\t<VoiceToolApprovalContext.Provider value={value}>{children}</VoiceToolApprovalContext.Provider>\n\t)\n}\n\n/**\n * Hook to access voice tool approval context.\n * @throws Error if used outside VoiceToolApprovalProvider\n */\nexport function useVoiceToolApproval(): VoiceToolApprovalContextValue {\n\tconst context = useContext(VoiceToolApprovalContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceToolApproval must be used within a VoiceToolApprovalProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice tool approval context.\n * Returns null if not within provider.\n */\nexport function useOptionalVoiceToolApproval(): VoiceToolApprovalContextValue | null {\n\treturn useContext(VoiceToolApprovalContext)\n}\n","/**\n * VoiceThreadBridge\n *\n * Bridges voice mode events to the assistant-ui thread.\n * When voice transcripts and tool calls occur, they are pushed into the thread\n * as real messages, making assistant-ui the single source of truth.\n *\n * This replaces the separate voice state tracking (useVoiceActions, useVoiceSummary)\n * with unified thread state.\n *\n * Voice messages are tagged with metadata to distinguish them from text messages:\n * - metadata.source: 'voice'\n * - metadata.voiceSessionId: unique session identifier\n *\n * Tool calls from voice mode are also added to the thread with full metadata\n * (timing, source attribution) matching the text mode behavior.\n */\n\nimport { useThread, useThreadRuntime } from '@assistant-ui/react'\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { VOICE_TOOL_RESULT_MESSAGES } from '../utils/constants'\nimport { TOOL_DENIED_MESSAGE } from '../utils/format'\nimport {\n\tgetPendingToolCallsByName,\n\tresolveAllPendingToolCalls,\n\tresolveAllPendingToolCallsByName,\n\tresolvePendingToolCall,\n} from '../utils/thread-utils'\nimport { useOptionalMCPTools } from './MCPToolsProvider'\nimport { useOptionalToolApproval } from './ToolApprovalProvider'\nimport { useOptionalVoiceModeContext, VoiceModeProvider } from './VoiceModeProvider'\nimport {\n\tuseOptionalVoiceToolApproval,\n\tVoiceToolApprovalProvider,\n} from './VoiceToolApprovalProvider'\n\nimport type { ToolCallMetadata, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { FC, MutableRefObject, ReactNode } from 'react'\nimport type { RegisteredTool, ToolExecutor } from '../services/realtime'\n\n/**\n * Data needed to add a voice tool call to the thread\n */\ninterface VoiceToolCallData {\n\ttoolCallId: string\n\ttoolName: string\n\targs: Record<string, unknown>\n\tresult: string\n\tisError: boolean\n\tartifact: ToolCallMetadata\n}\n\n/**\n * Callback type for adding tool calls to thread\n */\ntype AddToolCallToThread = (data: VoiceToolCallData) => void\n\n/**\n * Voice session metadata attached to messages\n */\nexport interface VoiceMessageMetadata {\n\tsource: 'voice'\n\tvoiceSessionId: string\n\ttimestamp: number\n}\n\n/**\n * Voice thread context - provides voice controls and current session info\n */\nexport interface VoiceThreadContextValue {\n\t/** Whether a voice session is active */\n\tisActive: boolean\n\t/** Whether voice is connecting */\n\tisConnecting: boolean\n\t/** Whether there's a voice error */\n\tisError: boolean\n\t/** Whether microphone is muted */\n\tisMuted: boolean\n\t/** Whether voice mode is supported in this browser */\n\tisSupported: boolean\n\t/** Current error message */\n\terror?: string\n\t/** Current voice session ID (null if no active session) */\n\tsessionId: string | null\n\t/** Start a voice session */\n\tstart: () => Promise<void>\n\t/** Stop the voice session */\n\tstop: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send a text message in voice mode */\n\tsendMessage: (text: string) => void\n\t/** Pause audio playback (for approval flow) */\n\tpauseAudio: () => void\n\t/** Resume audio playback (after approval flow) */\n\tresumeAudio: () => void\n\t/** Audio level data for visualization */\n\taudioLevel?: {\n\t\tmicLevel: number\n\t\tspeakerLevel: number\n\t}\n\t/** Current transcript being spoken */\n\ttranscript?: {\n\t\ttype: 'user' | 'assistant'\n\t\ttext: string\n\t\tisDone: boolean\n\t}\n\t/** Current tool call being executed */\n\ttoolCall?: {\n\t\tstatus: 'started' | 'completed'\n\t\ttoolName: string\n\t\terror?: string\n\t}\n}\n\nconst VoiceThreadContext = createContext<VoiceThreadContextValue | null>(null)\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n\treturn `voice-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Convert MCP tools to the format expected by the voice service\n */\nfunction convertToRegisteredTool(tool: ToolWithSource): RegisteredTool {\n\treturn {\n\t\tname: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tinputSchema: (tool.inputSchema ?? { type: 'object', properties: {} }) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>,\n\t}\n}\n\nexport interface VoiceThreadBridgeProps {\n\tchildren: ReactNode\n\t/** Token endpoint for voice sessions */\n\ttokenEndpoint: string\n\t/** Callback when voice session connects */\n\tonConnect?: () => void\n\t/** Callback when voice session disconnects */\n\tonDisconnect?: (durationSeconds: number) => void\n\t/** Callback when voice error occurs */\n\tonError?: (error: string) => void\n}\n\n/**\n * Internal component that bridges voice events to the thread.\n * Must be used inside both VoiceModeProvider and AssistantRuntimeProvider.\n */\nconst VoiceThreadIntegrator: FC<{\n\tchildren: ReactNode\n\tsessionId: string | null\n\tsetSessionId: (id: string | null) => void\n\taddToolCallRef: MutableRefObject<AddToolCallToThread | null>\n\tonConnect?: () => void\n\tonDisconnect?: (durationSeconds: number) => void\n\tonError?: (error: string) => void\n}> = ({ children, sessionId, setSessionId, addToolCallRef, onConnect, onDisconnect, onError }) => {\n\tconst threadRuntime = useThreadRuntime()\n\tconst voiceMode = useOptionalVoiceModeContext()\n\n\t// Track last transcript to detect changes\n\tconst lastUserTranscriptRef = useRef<string>('')\n\tconst lastAssistantTranscriptRef = useRef<string>('')\n\tconst wasActiveRef = useRef(false)\n\n\t// Refs for callbacks\n\tconst onConnectRef = useRef(onConnect)\n\tconst onDisconnectRef = useRef(onDisconnect)\n\tconst onErrorRef = useRef(onError)\n\tonConnectRef.current = onConnect\n\tonDisconnectRef.current = onDisconnect\n\tonErrorRef.current = onError\n\n\t/**\n\t * Set up the callback for adding tool calls to thread.\n\t * This is called by toolExecutor when a voice tool call completes.\n\t */\n\tuseEffect(() => {\n\t\taddToolCallRef.current = (data: VoiceToolCallData) => {\n\t\t\tif (!sessionId) {\n\t\t\t\tconsole.warn('[VoiceThreadIntegrator] Cannot add tool call - no active session')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Append complete tool-call message to thread\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool-call',\n\t\t\t\t\t\ttoolCallId: data.toolCallId,\n\t\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\t\targs: data.args,\n\t\t\t\t\t\targsText: JSON.stringify(data.args),\n\t\t\t\t\t\tresult: data.result,\n\t\t\t\t\t\tisError: data.isError,\n\t\t\t\t\t\tartifact: data.artifact,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tmetadata: {\n\t\t\t\t\tcustom: {\n\t\t\t\t\t\tsource: 'voice',\n\t\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t} as any)\n\t\t}\n\n\t\treturn () => {\n\t\t\taddToolCallRef.current = null\n\t\t}\n\t}, [threadRuntime, sessionId, addToolCallRef])\n\n\t/**\n\t * Add a user message to the thread (from voice transcript)\n\t */\n\tconst addUserMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tif (!sessionId || !text.trim()) return\n\n\t\t\t// Use custom metadata for voice messages\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst metadata: any = {\n\t\t\t\tcustom: {\n\t\t\t\t\tsource: 'voice',\n\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'user',\n\t\t\t\tcontent: [{ type: 'text', text }],\n\t\t\t\tmetadata,\n\t\t\t})\n\t\t},\n\t\t[threadRuntime, sessionId]\n\t)\n\n\t/**\n\t * Add an assistant message to the thread (from voice transcript)\n\t */\n\tconst addAssistantMessage = useCallback(\n\t\t(text: string) => {\n\t\t\tif (!sessionId || !text.trim()) return\n\n\t\t\t// Use custom metadata for voice messages\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst metadata: any = {\n\t\t\t\tcustom: {\n\t\t\t\t\tsource: 'voice',\n\t\t\t\t\tvoiceSessionId: sessionId,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tthreadRuntime.append({\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: [{ type: 'text', text }],\n\t\t\t\tmetadata,\n\t\t\t})\n\t\t},\n\t\t[threadRuntime, sessionId]\n\t)\n\n\t// Track session state changes\n\tuseEffect(() => {\n\t\tif (!voiceMode) return\n\n\t\tconst isActive = voiceMode.isActive || voiceMode.isConnecting\n\n\t\t// Session just started\n\t\tif (!wasActiveRef.current && isActive && !sessionId) {\n\t\t\tconst newSessionId = generateSessionId()\n\t\t\tsetSessionId(newSessionId)\n\t\t}\n\n\t\t// Session just connected\n\t\tif (!wasActiveRef.current && voiceMode.isActive) {\n\t\t\tonConnectRef.current?.()\n\t\t}\n\n\t\t// Session just ended\n\t\tif (wasActiveRef.current && !isActive) {\n\t\t\t// Add final assistant message if we have one\n\t\t\t// CRITICAL: Clear refs immediately after use to prevent race condition with transcript effect\n\t\t\t// Both effects can fire in the same render cycle, causing duplicate message IDs\n\t\t\tif (lastAssistantTranscriptRef.current) {\n\t\t\t\taddAssistantMessage(lastAssistantTranscriptRef.current)\n\t\t\t\tlastAssistantTranscriptRef.current = ''\n\t\t\t}\n\t\t\tlastUserTranscriptRef.current = ''\n\n\t\t\t// Clear any remaining pending thread elicitations to prevent duplicate approval UI\n\t\t\tresolveAllPendingToolCalls(threadRuntime, VOICE_TOOL_RESULT_MESSAGES.sessionEnded)\n\n\t\t\t// Clear session\n\t\t\tsetSessionId(null)\n\n\t\t\t// Notify disconnect (duration is not easily available here, use 0)\n\t\t\tonDisconnectRef.current?.(0)\n\t\t}\n\n\t\twasActiveRef.current = isActive\n\t}, [\n\t\tvoiceMode?.isActive,\n\t\tvoiceMode?.isConnecting,\n\t\tsessionId,\n\t\tsetSessionId,\n\t\taddAssistantMessage,\n\t\tthreadRuntime,\n\t])\n\n\t// Track transcript changes and push to thread\n\tuseEffect(() => {\n\t\tif (!voiceMode?.transcript || !sessionId) return\n\n\t\tconst { type, text, isDone } = voiceMode.transcript\n\n\t\tif (type === 'user' && isDone && text !== lastUserTranscriptRef.current) {\n\t\t\t// If we had a pending assistant message, add it first to maintain order\n\t\t\tif (lastAssistantTranscriptRef.current) {\n\t\t\t\taddAssistantMessage(lastAssistantTranscriptRef.current)\n\t\t\t\tlastAssistantTranscriptRef.current = ''\n\t\t\t}\n\n\t\t\t// User finished speaking - add to thread\n\t\t\taddUserMessage(text)\n\t\t\tlastUserTranscriptRef.current = text\n\t\t} else if (type === 'assistant' && isDone && text !== lastAssistantTranscriptRef.current) {\n\t\t\t// Store assistant transcript - we'll add it to thread when:\n\t\t\t// 1. User speaks next (to maintain conversation order)\n\t\t\t// 2. Session ends\n\t\t\tlastAssistantTranscriptRef.current = text\n\t\t}\n\t}, [voiceMode?.transcript, sessionId, addUserMessage, addAssistantMessage])\n\n\t// Track errors\n\tuseEffect(() => {\n\t\tif (voiceMode?.isError && voiceMode?.error) {\n\t\t\tonErrorRef.current?.(voiceMode.error)\n\t\t}\n\t}, [voiceMode?.isError, voiceMode?.error])\n\n\treturn <>{children}</>\n}\n\n/**\n * Inner component that creates the approval-aware tool executor.\n * Must be inside VoiceToolApprovalProvider to access the approval context.\n */\nconst ApprovalAwareVoiceBridge: FC<{\n\tchildren: ReactNode\n\ttokenEndpoint: string\n\tvoiceTools: RegisteredTool[]\n\tsessionId: string | null\n\tsetSessionId: (id: string | null) => void\n\taddToolCallRef: MutableRefObject<AddToolCallToThread | null>\n\tonConnect?: () => void\n\tonDisconnect?: (durationSeconds: number) => void\n\tonError?: (error: string) => void\n}> = ({\n\tchildren,\n\ttokenEndpoint,\n\tvoiceTools,\n\tsessionId,\n\tsetSessionId,\n\taddToolCallRef,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst mcpTools = useOptionalMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\tconst voiceToolApproval = useOptionalVoiceToolApproval()\n\tconst threadRuntime = useThreadRuntime()\n\tconst threadMessages = useThread((t) => t.messages)\n\n\t// Track voice approval decisions keyed by tool name with a queue of decisions\n\t// so multiple approvals for the same tool don't collide when replaying.\n\tconst pendingVoiceResolutions = useRef<Map<string, Array<{ result: string; timestamp: number }>>>(\n\t\tnew Map()\n\t)\n\tconst VOICE_RESOLUTION_TTL_MS = 30_000\n\n\t// Tool executor that routes to MCP with approval checking\n\tconst toolExecutor: ToolExecutor = useCallback(\n\t\tasync (name: string, args: Record<string, unknown>) => {\n\t\t\tif (!mcpTools?.callTool) {\n\t\t\t\tthrow new Error('MCP tools not available')\n\t\t\t}\n\n\t\t\t// Check if tool requires approval\n\t\t\tconst tool = mcpTools.tools.find((t) => t.name === name)\n\t\t\tconst needsApproval = tool && toolApproval?.requiresApproval(tool)\n\n\t\t\tif (needsApproval && voiceToolApproval) {\n\t\t\t\t// Generate a call ID for this approval request\n\t\t\t\tconst callId = `voice-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n\n\t\t\t\t// Request approval and wait for response\n\t\t\t\tconst approved = await voiceToolApproval.requestApproval(callId, name, args)\n\n\t\t\t\t// Sync voice approval to thread to prevent duplicate approval UI in text mode\n\t\t\t\tconst resultMessage = approved ? VOICE_TOOL_RESULT_MESSAGES.handled : TOOL_DENIED_MESSAGE\n\t\t\t\tconst resolvedNow = resolveAllPendingToolCallsByName(threadRuntime, name, resultMessage)\n\n\t\t\t\t// If nothing was resolved (pending call hasn't reached the thread yet), remember it\n\t\t\t\t// so we can auto-resolve when the pending tool-call message appears.\n\t\t\t\tif (resolvedNow === 0) {\n\t\t\t\t\tconst queue = pendingVoiceResolutions.current.get(name) ?? []\n\t\t\t\t\tqueue.push({ result: resultMessage, timestamp: Date.now() })\n\t\t\t\t\tpendingVoiceResolutions.current.set(name, queue)\n\t\t\t\t}\n\n\t\t\t\tif (!approved) {\n\t\t\t\t\t// User denied or timeout - return denial message\n\t\t\t\t\treturn TOOL_DENIED_MESSAGE\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Execute the tool\n\t\t\tconst result = await mcpTools.callTool(name, args)\n\n\t\t\t// Extract text content from MCP result\n\t\t\tconst textContent = result.content?.find(\n\t\t\t\t(c: { type: string; text?: string }): c is { type: 'text'; text: string } =>\n\t\t\t\t\tc.type === 'text'\n\t\t\t)\n\t\t\treturn textContent?.text ?? JSON.stringify(result)\n\t\t},\n\t\t[mcpTools, toolApproval, voiceToolApproval, threadRuntime]\n\t)\n\n\t// Apply queued voice approvals once the thread emits matching pending tool calls.\n\tuseEffect(() => {\n\t\tif (pendingVoiceResolutions.current.size === 0) return\n\n\t\tconst now = Date.now()\n\t\tfor (const [toolName, queue] of [...pendingVoiceResolutions.current.entries()]) {\n\t\t\tconst freshQueue = queue.filter(({ timestamp }) => now - timestamp <= VOICE_RESOLUTION_TTL_MS)\n\t\t\tif (freshQueue.length === 0) {\n\t\t\t\tpendingVoiceResolutions.current.delete(toolName)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst pendingCalls = getPendingToolCallsByName(threadRuntime, toolName)\n\n\t\t\t// Resolve approvals in FIFO order against pending calls\n\t\t\tlet queueIndex = 0\n\t\t\tfor (const call of pendingCalls) {\n\t\t\t\tif (queueIndex >= freshQueue.length) break\n\t\t\t\tconst { result } = freshQueue[queueIndex]\n\t\t\t\tif (resolvePendingToolCall(threadRuntime, call.messageId, call.toolCallId, result)) {\n\t\t\t\t\tqueueIndex++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (queueIndex >= freshQueue.length) {\n\t\t\t\tpendingVoiceResolutions.current.delete(toolName)\n\t\t\t} else {\n\t\t\t\tpendingVoiceResolutions.current.set(toolName, freshQueue.slice(queueIndex))\n\t\t\t}\n\t\t}\n\t}, [threadMessages, threadRuntime])\n\n\treturn (\n\t\t<VoiceModeProvider tokenEndpoint={tokenEndpoint} tools={voiceTools} toolExecutor={toolExecutor}>\n\t\t\t<VoiceThreadIntegrator\n\t\t\t\tsessionId={sessionId}\n\t\t\t\tsetSessionId={setSessionId}\n\t\t\t\taddToolCallRef={addToolCallRef}\n\t\t\t\tonConnect={onConnect}\n\t\t\t\tonDisconnect={onDisconnect}\n\t\t\t\tonError={onError}\n\t\t\t>\n\t\t\t\t<VoiceThreadContextProvider sessionId={sessionId}>{children}</VoiceThreadContextProvider>\n\t\t\t</VoiceThreadIntegrator>\n\t\t</VoiceModeProvider>\n\t)\n}\n\n/**\n * Bridge component that integrates voice mode with the assistant-ui thread.\n *\n * When voice events occur:\n * 1. User transcripts are added as user messages to the thread\n * 2. Assistant transcripts are added as assistant messages\n * 3. Tool calls are added as tool-call parts with full metadata (timing, source)\n * This ensures the thread is the single source of truth for all conversation history,\n * including tool calls from voice mode with the same metadata as text mode.\n *\n * Voice tool approval:\n * When a destructive tool is called during voice mode, the VoiceToolApprovalProvider\n * pauses execution and shows an approval UI. User can approve via voice keywords\n * (\"approve\", \"yes\") or by tapping buttons.\n */\nexport const VoiceThreadBridge: FC<VoiceThreadBridgeProps> = ({\n\tchildren,\n\ttokenEndpoint,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst mcpTools = useOptionalMCPTools()\n\n\t// Session ID managed at this level so it persists across voice mode restarts\n\tconst [sessionId, setSessionId] = useState<string | null>(null)\n\n\t// Ref for adding tool calls to thread (set by VoiceThreadIntegrator)\n\tconst addToolCallRef = useRef<AddToolCallToThread | null>(null)\n\n\t// Convert MCP tools for voice mode\n\tconst voiceTools = useMemo<RegisteredTool[]>(() => {\n\t\tif (!mcpTools?.tools) return []\n\t\treturn mcpTools.tools.map(convertToRegisteredTool)\n\t}, [mcpTools?.tools])\n\n\treturn (\n\t\t<VoiceToolApprovalProvider>\n\t\t\t<ApprovalAwareVoiceBridge\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tvoiceTools={voiceTools}\n\t\t\t\tsessionId={sessionId}\n\t\t\t\tsetSessionId={setSessionId}\n\t\t\t\taddToolCallRef={addToolCallRef}\n\t\t\t\tonConnect={onConnect}\n\t\t\t\tonDisconnect={onDisconnect}\n\t\t\t\tonError={onError}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</ApprovalAwareVoiceBridge>\n\t\t</VoiceToolApprovalProvider>\n\t)\n}\n\n/**\n * Internal provider that exposes voice thread context\n */\nconst VoiceThreadContextProvider: FC<{ children: ReactNode; sessionId: string | null }> = ({\n\tchildren,\n\tsessionId,\n}) => {\n\tconst voiceMode = useOptionalVoiceModeContext()\n\n\t// Build context value from voice mode\n\tconst contextValue = useMemo<VoiceThreadContextValue | null>(() => {\n\t\tif (!voiceMode) return null\n\n\t\treturn {\n\t\t\tisActive: voiceMode.isActive,\n\t\t\tisConnecting: voiceMode.isConnecting,\n\t\t\tisError: voiceMode.isError,\n\t\t\tisMuted: voiceMode.isMuted,\n\t\t\tisSupported: voiceMode.isSupported,\n\t\t\terror: voiceMode.error,\n\t\t\tsessionId,\n\t\t\taudioLevel: voiceMode.audioLevel\n\t\t\t\t? {\n\t\t\t\t\t\tmicLevel: voiceMode.audioLevel.micLevel,\n\t\t\t\t\t\tspeakerLevel: voiceMode.audioLevel.speakerLevel,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\ttranscript: voiceMode.transcript\n\t\t\t\t? {\n\t\t\t\t\t\ttype: voiceMode.transcript.type,\n\t\t\t\t\t\ttext: voiceMode.transcript.text,\n\t\t\t\t\t\tisDone: voiceMode.transcript.isDone,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\ttoolCall: voiceMode.toolCall\n\t\t\t\t? {\n\t\t\t\t\t\tstatus: voiceMode.toolCall.status,\n\t\t\t\t\t\ttoolName: voiceMode.toolCall.toolName,\n\t\t\t\t\t\terror: voiceMode.toolCall.error,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tstart: voiceMode.startSession,\n\t\t\tstop: voiceMode.stopSession,\n\t\t\ttoggleMute: voiceMode.toggleMute,\n\t\t\tsendMessage: voiceMode.sendMessage,\n\t\t\tpauseAudio: voiceMode.pauseAudio,\n\t\t\tresumeAudio: voiceMode.resumeAudio,\n\t\t}\n\t}, [voiceMode, sessionId])\n\n\tif (!contextValue) {\n\t\treturn <>{children}</>\n\t}\n\n\treturn <VoiceThreadContext.Provider value={contextValue}>{children}</VoiceThreadContext.Provider>\n}\n\n/**\n * Hook to access voice thread controls\n * @throws Error if used outside VoiceThreadBridge\n */\nexport function useVoiceThread(): VoiceThreadContextValue {\n\tconst context = useContext(VoiceThreadContext)\n\tif (!context) {\n\t\tthrow new Error('useVoiceThread must be used within a VoiceThreadBridge')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access voice thread controls\n */\nexport function useOptionalVoiceThread(): VoiceThreadContextValue | null {\n\treturn useContext(VoiceThreadContext)\n}\n\n/**\n * Hook to check if voice mode is available and active\n */\nexport function useIsVoiceActive(): boolean {\n\tconst context = useOptionalVoiceThread()\n\treturn context?.isActive ?? false\n}\n","import {\n ComposerAddAttachment,\n ComposerAttachments,\n UserMessageAttachments,\n} from \"@/components/assistant-ui/attachment\";\nimport { MarkdownText } from \"@/components/assistant-ui/markdown-text\";\nimport { Reasoning, ReasoningGroup } from \"@/components/assistant-ui/reasoning\";\n// import { ToolFallback } from \"@/components/assistant-ui/tool-fallback\";\nimport { TooltipIconButton } from \"@/components/assistant-ui/tooltip-icon-button\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/utils/cn\";\nimport {\n ActionBarPrimitive,\n AssistantIf,\n BranchPickerPrimitive,\n ComposerPrimitive,\n ErrorPrimitive,\n MessagePrimitive,\n ThreadPrimitive,\n} from \"@assistant-ui/react\";\nimport {\n ArrowDownIcon,\n ArrowUpIcon,\n CheckIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n CopyIcon,\n DownloadIcon,\n History,\n Mic,\n PencilIcon,\n Plus,\n RefreshCwIcon,\n Shield,\n ShieldOff,\n SquareIcon,\n X,\n} from \"lucide-react\";\nimport { useCallback, useMemo, type FC } from \"react\";\nimport UnifiedToolFallback from \"../pill/UnifiedToolFallback\";\nimport { usePrompts } from \"@/hooks/usePrompts\";\nimport { useOptionalToolSelection } from \"@/providers/ToolSelectionProvider\";\nimport { useOptionalToolApproval } from \"@/providers/ToolApprovalProvider\";\nimport { useOptionalVoiceThread } from \"@/providers/VoiceThreadBridge\";\nimport type { ThreadToolSelection, ToolSourceInfo } from \"@mcp-b/cloud-mirror-types\";\n\nexport interface ThreadProps {\n /** Callback when threads/history button is clicked */\n onThreadsClick?: () => void;\n /** Callback when new thread button is clicked */\n onNewThread?: () => void;\n /** Callback when close button is clicked */\n onClose?: () => void;\n}\n\n/** Glassmorphic button styles (from WebMCP extension) - theme-aware */\nconst glassmorphicButtonClass =\n \"wm:h-8 wm:w-8 wm:rounded-full wm:border wm:border-border wm:backdrop-blur-sm wm:shadow-lg wm:shadow-black/20 wm:bg-muted/50 wm:transition-all wm:duration-200 hover:wm:border-border hover:wm:bg-muted\";\n\nexport const Thread: FC<ThreadProps> = ({\n onThreadsClick,\n onNewThread,\n onClose,\n}) => {\n return (\n <ThreadPrimitive.Root\n className=\"aui-root aui-thread-root @container wm:relative wm:flex wm:h-full wm:min-h-0 wm:flex-col wm:bg-background\"\n style={{\n [\"--thread-max-width\" as string]: \"44rem\",\n }}\n >\n {/* Floating top bar */}\n <div className=\"wm:absolute wm:top-2 wm:left-2 wm:right-2 wm:z-50 wm:flex wm:items-center wm:gap-2\">\n {/* Left side - New thread and History icons */}\n <div className=\"wm:flex wm:gap-1\">\n {onNewThread && (\n <TooltipIconButton\n variant=\"ghost\"\n size=\"icon\"\n className={glassmorphicButtonClass}\n onClick={onNewThread}\n tooltip=\"New chat\"\n side=\"bottom\"\n >\n <Plus className=\"wm:h-4 wm:w-4\" />\n </TooltipIconButton>\n )}\n {onThreadsClick && (\n <TooltipIconButton\n variant=\"ghost\"\n size=\"icon\"\n className={glassmorphicButtonClass}\n onClick={onThreadsClick}\n tooltip=\"View all threads\"\n side=\"bottom\"\n >\n <History className=\"wm:h-4 wm:w-4\" />\n </TooltipIconButton>\n )}\n </div>\n\n {/* Right side - Close button only (voice/approval moved to composer) */}\n {onClose && (\n <div className=\"wm:ml-auto wm:flex wm:gap-1\">\n <TooltipIconButton\n variant=\"ghost\"\n size=\"icon\"\n className={glassmorphicButtonClass}\n onClick={onClose}\n tooltip=\"Close\"\n side=\"bottom\"\n >\n <X className=\"wm:h-4 wm:w-4\" />\n </TooltipIconButton>\n </div>\n )}\n </div>\n\n <ThreadPrimitive.Viewport className=\"aui-thread-viewport wm:relative wm:flex wm:min-h-0 wm:flex-1 wm:flex-col wm:overflow-x-hidden wm:overflow-y-scroll wm:scroll-smooth wm:px-4 wm:pt-14\">\n <AssistantIf condition={({ thread }) => thread.isEmpty}>\n <ThreadWelcome />\n </AssistantIf>\n\n <ThreadPrimitive.Messages\n components={{\n UserMessage,\n EditComposer,\n AssistantMessage,\n }}\n />\n\n <ThreadPrimitive.ViewportFooter className=\"aui-thread-viewport-footer wm:sticky wm:bottom-0 wm:mx-auto wm:mt-auto wm:flex wm:w-full wm:max-w-(--thread-max-width) wm:flex-col wm:gap-4 wm:overflow-visible wm:bg-transparent wm:pt-2 wm:pb-4 md:wm:pb-6\">\n <ThreadScrollToBottom />\n <Composer />\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n </ThreadPrimitive.Root>\n );\n};\n\nconst ThreadScrollToBottom: FC = () => {\n return (\n <ThreadPrimitive.ScrollToBottom asChild>\n <TooltipIconButton\n tooltip=\"Scroll to bottom\"\n variant=\"outline\"\n className=\"aui-thread-scroll-to-bottom wm:absolute wm:-top-12 wm:z-10 wm:self-center wm:rounded-full wm:p-4 wm:disabled:invisible wm:border-border wm:bg-background wm:text-muted-foreground dark:wm:bg-muted dark:wm:text-foreground\"\n >\n <ArrowDownIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </ThreadPrimitive.ScrollToBottom>\n );\n};\n\nconst ThreadWelcome: FC = () => {\n return (\n <div className=\"aui-thread-welcome-root wm:mx-auto wm:my-auto wm:flex wm:w-full wm:max-w-(--thread-max-width) wm:grow wm:flex-col\">\n <div className=\"aui-thread-welcome-center wm:flex wm:w-full wm:grow wm:flex-col wm:items-center wm:justify-center\">\n <div className=\"aui-thread-welcome-message wm:flex wm:size-full wm:flex-col wm:justify-center wm:px-4\">\n <h1 className=\"aui-thread-welcome-message-inner wm:fade-in wm:slide-in-from-bottom-1 wm:animate-in wm:font-semibold wm:text-lg wm:duration-200\">\n Hello there!\n </h1>\n <p className=\"aui-thread-welcome-message-inner wm:fade-in wm:slide-in-from-bottom-1 wm:animate-in wm:text-muted-foreground wm:text-sm wm:delay-75 wm:duration-200\">\n How can I help you today?\n </p>\n </div>\n </div>\n <ThreadSuggestions />\n </div>\n );\n};\n\nconst ThreadSuggestions: FC = () => {\n const { prompts, hasPrompts } = usePrompts();\n\n if (!hasPrompts) {\n return null;\n }\n\n return (\n <div className=\"aui-thread-welcome-suggestions wm:grid wm:w-full @md:wm:grid-cols-2 wm:gap-2 wm:pb-4\">\n {prompts.slice(0, 4).map((prompt, index) => (\n <div\n key={prompt.name}\n className=\"aui-thread-welcome-suggestion-display wm:fade-in wm:slide-in-from-bottom-2 @md:wm:nth-[n+3]:block wm:nth-[n+3]:hidden wm:animate-in wm:fill-mode-both wm:duration-200\"\n style={{ animationDelay: `${100 + index * 50}ms` }}\n >\n <ThreadPrimitive.Suggestion\n prompt={prompt.description || prompt.name}\n send\n asChild\n >\n <Button\n variant=\"ghost\"\n className=\"aui-thread-welcome-suggestion wm:h-auto wm:w-full @md:wm:flex-col wm:flex-wrap wm:items-start wm:justify-start wm:gap-1 wm:rounded-2xl wm:border wm:px-4 wm:py-3 wm:text-left wm:text-sm wm:transition-colors hover:wm:bg-muted\"\n aria-label={prompt.description || prompt.name}\n >\n <span className=\"aui-thread-welcome-suggestion-text-1 wm:font-medium\">\n {prompt.name}\n </span>\n {prompt.description && (\n <span className=\"aui-thread-welcome-suggestion-text-2 wm:text-muted-foreground\">\n {prompt.description}\n </span>\n )}\n </Button>\n </ThreadPrimitive.Suggestion>\n </div>\n ))}\n </div>\n );\n};\n\nconst Composer: FC = () => {\n const voiceThread = useOptionalVoiceThread();\n const isVoiceActive = voiceThread?.isActive ?? false;\n const isVoiceConnecting = voiceThread?.isConnecting ?? false;\n\n return (\n <ComposerPrimitive.Root className=\"aui-composer-root wm:relative wm:flex wm:w-full wm:flex-col\">\n <ComposerPrimitive.AttachmentDropzone className=\"aui-composer-attachment-dropzone wm:flex wm:w-full wm:flex-col wm:rounded-2xl wm:border wm:border-composer-border wm:bg-composer-bg wm:shadow-none wm:px-1 wm:pt-2 wm:outline-none has-[textarea:focus-visible]:wm:border-ring has-[textarea:focus-visible]:wm:ring-2 has-[textarea:focus-visible]:wm:ring-ring/20 data-[dragging=true]:wm:border-ring data-[dragging=true]:wm:border-dashed data-[dragging=true]:wm:bg-accent/50\">\n <ComposerAttachments />\n <ComposerToolSources />\n <ComposerPrimitive.Input\n placeholder={isVoiceActive ? \"Voice mode active...\" : \"Send a message...\"}\n className={cn(\n \"aui-composer-input wm:mb-1 wm:max-h-32 wm:min-h-14 wm:w-full wm:resize-none wm:bg-transparent wm:px-4 wm:pt-2 wm:pb-3 wm:text-sm wm:text-composer-text wm:outline-none placeholder:wm:text-composer-placeholder focus-visible:wm:ring-0\",\n isVoiceActive && \"wm:opacity-50 wm:cursor-not-allowed\"\n )}\n rows={1}\n autoFocus={!isVoiceActive}\n disabled={isVoiceActive || isVoiceConnecting}\n aria-label=\"Message input\"\n />\n <ComposerAction />\n </ComposerPrimitive.AttachmentDropzone>\n </ComposerPrimitive.Root>\n );\n};\n\nconst getSourceLabel = (source: ToolSourceInfo): string => {\n const title = source.title?.trim();\n if (title) return title;\n\n const fallback = source.url ?? source.origin ?? \"Tab\";\n try {\n return new URL(fallback).hostname || fallback;\n } catch {\n return fallback;\n }\n};\n\nconst getSourceKey = (source: ToolSourceInfo): string => {\n return source.sourceId;\n};\n\nconst getSelectionKey = (\n selection: ThreadToolSelection[\"selectedSources\"][number],\n): string => {\n return selection.sourceId;\n};\n\nconst buildSelection = (\n selection: ThreadToolSelection | null,\n source: ToolSourceInfo,\n): ThreadToolSelection => {\n const current = selection?.selectedSources ?? [];\n const selectedSet = new Set(current.map(getSelectionKey));\n const key = getSourceKey(source);\n const nextSelector = { sourceId: source.sourceId, tabId: source.tabId };\n\n const next =\n selectedSet.has(key)\n ? current.filter((item) => getSelectionKey(item) !== key)\n : [...current, nextSelector];\n\n return { selectedSources: next };\n};\n\nconst ComposerToolSources: FC = () => {\n const toolSelection = useOptionalToolSelection();\n const sources = toolSelection?.sources ?? [];\n\n const selectedSources = toolSelection?.selection?.selectedSources ?? [];\n const selectedKeys = useMemo(\n () => new Set(selectedSources.map(getSelectionKey)),\n [selectedSources],\n );\n const currentSourceId = toolSelection?.currentSourceId;\n\n const handleToggle = useCallback(\n (source: ToolSourceInfo) => {\n if (!toolSelection) return;\n const nextSelection = buildSelection(toolSelection.selection, source);\n void toolSelection.setSelection(nextSelection);\n },\n [toolSelection],\n );\n\n if (!toolSelection || sources.length === 0) {\n return null;\n }\n\n return (\n <div className=\"aui-composer-tool-sources wm:flex wm:flex-wrap wm:gap-1 wm:px-3 wm:pb-1\">\n {sources.map((source) => {\n const key = getSourceKey(source);\n const isSelected = selectedKeys.has(key);\n const label = getSourceLabel(source);\n const isLocal = currentSourceId === source.sourceId;\n return (\n <button\n key={key}\n type=\"button\"\n onClick={() => handleToggle(source)}\n className={cn(\n \"wm:flex wm:items-center wm:gap-1.5 wm:rounded-full wm:border wm:px-2 wm:py-1 wm:text-[11px] wm:transition-colors\",\n isSelected\n ? \"wm:border-primary/50 wm:bg-primary/10 wm:text-primary\"\n : \"wm:border-border/50 wm:bg-muted/40 wm:text-muted-foreground hover:wm:bg-muted/60\",\n )}\n aria-pressed={isSelected}\n title={label}\n >\n {source.iconUrl ? (\n <img\n src={source.iconUrl}\n alt=\"\"\n className=\"wm:h-3 wm:w-3 wm:rounded-sm\"\n loading=\"lazy\"\n />\n ) : (\n <span className=\"wm:h-2 wm:w-2 wm:rounded-sm wm:bg-muted-foreground/40\" />\n )}\n <span className=\"wm:max-w-[140px] wm:truncate\">{label}</span>\n {isLocal ? (\n <span className=\"wm:text-[10px] wm:text-primary/80\">This tab</span>\n ) : null}\n <span className=\"wm:text-[10px] wm:text-muted-foreground\">\n {source.toolCount}\n </span>\n </button>\n );\n })}\n </div>\n );\n};\n\n/**\n * Compact approval mode button for the composer footer.\n */\nconst ComposerApprovalButton: FC = () => {\n const toolApproval = useOptionalToolApproval();\n\n if (!toolApproval) return null;\n\n const { mode, toggleMode } = toolApproval;\n const isAskMode = mode === \"ask\";\n\n return (\n <TooltipIconButton\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n \"wm:size-7 wm:rounded-full wm:transition-colors\",\n isAskMode\n ? \"wm:text-amber-500 hover:wm:text-amber-400 hover:wm:bg-amber-500/10\"\n : \"wm:text-muted-foreground hover:wm:text-foreground hover:wm:bg-muted/50\"\n )}\n onClick={toggleMode}\n tooltip={\n isAskMode\n ? \"Ask before destructive actions (click to auto-approve)\"\n : \"Auto-approve all actions (click to ask first)\"\n }\n side=\"top\"\n >\n {isAskMode ? (\n <Shield className=\"wm:h-3.5 wm:w-3.5\" />\n ) : (\n <ShieldOff className=\"wm:h-3.5 wm:w-3.5\" />\n )}\n </TooltipIconButton>\n );\n};\n\n/**\n * Compact voice mode button for the composer footer.\n */\nconst ComposerVoiceButton: FC = () => {\n const voiceThread = useOptionalVoiceThread();\n\n if (!voiceThread || !voiceThread.isSupported) return null;\n\n const { isActive, isConnecting, start, stop } = voiceThread;\n\n const handleClick = useCallback(() => {\n if (isActive || isConnecting) {\n stop();\n } else {\n void start();\n }\n }, [isActive, isConnecting, start, stop]);\n\n return (\n <TooltipIconButton\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n \"wm:size-7 wm:rounded-full wm:transition-colors\",\n isActive\n ? \"wm:bg-green-500/20 wm:text-green-500 hover:wm:bg-green-500/30\"\n : isConnecting\n ? \"wm:bg-amber-500/20 wm:text-amber-500\"\n : \"wm:text-muted-foreground hover:wm:text-foreground hover:wm:bg-muted/50\"\n )}\n onClick={handleClick}\n tooltip={\n isActive\n ? \"End voice session\"\n : isConnecting\n ? \"Connecting...\"\n : \"Start voice session\"\n }\n side=\"top\"\n disabled={isConnecting}\n >\n <Mic className=\"wm:h-3.5 wm:w-3.5\" />\n </TooltipIconButton>\n );\n};\n\nconst ComposerAction: FC = () => {\n return (\n <div className=\"aui-composer-action-wrapper wm:relative wm:mx-2 wm:mb-2 wm:flex wm:items-center wm:justify-between\">\n {/* Left side - Attachments, Voice, Approval */}\n <div className=\"wm:flex wm:items-center wm:gap-1\">\n <ComposerAddAttachment />\n <ComposerVoiceButton />\n <ComposerApprovalButton />\n </div>\n\n {/* Right side - Send/Cancel */}\n <div className=\"wm:flex wm:items-center wm:gap-1\">\n <AssistantIf condition={({ thread }) => !thread.isRunning}>\n <ComposerPrimitive.Send asChild>\n <TooltipIconButton\n tooltip=\"Send message\"\n side=\"top\"\n type=\"submit\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-send wm:size-8 wm:rounded-full\"\n aria-label=\"Send message\"\n >\n <ArrowUpIcon className=\"aui-composer-send-icon wm:size-4\" />\n </TooltipIconButton>\n </ComposerPrimitive.Send>\n </AssistantIf>\n\n <AssistantIf condition={({ thread }) => thread.isRunning}>\n <ComposerPrimitive.Cancel asChild>\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-cancel wm:size-8 wm:rounded-full\"\n aria-label=\"Stop generating\"\n >\n <SquareIcon className=\"aui-composer-cancel-icon wm:size-3 wm:fill-current\" />\n </Button>\n </ComposerPrimitive.Cancel>\n </AssistantIf>\n </div>\n </div>\n );\n};\n\nconst MessageError: FC = () => {\n return (\n <MessagePrimitive.Error>\n <ErrorPrimitive.Root className=\"aui-message-error-root wm:mt-2 wm:rounded-md wm:border wm:border-destructive wm:bg-destructive/10 wm:p-3 wm:text-destructive wm:text-sm dark:wm:bg-destructive/5 dark:wm:text-red-200\">\n <ErrorPrimitive.Message className=\"aui-message-error-message wm:line-clamp-2\" />\n </ErrorPrimitive.Root>\n </MessagePrimitive.Error>\n );\n};\n\nconst AssistantMessage: FC = () => {\n return (\n <MessagePrimitive.Root\n className=\"aui-assistant-message-root wm:fade-in wm:slide-in-from-bottom-1 wm:relative wm:mx-auto wm:w-full wm:max-w-(--thread-max-width) wm:animate-in wm:py-3 wm:duration-150\"\n data-role=\"assistant\"\n >\n <div className=\"aui-assistant-message-content wm:wrap-break-word wm:px-2 wm:text-assistant-bubble-text wm:leading-relaxed\">\n <MessagePrimitive.Parts\n components={{\n Text: MarkdownText,\n Reasoning: Reasoning,\n ReasoningGroup: ReasoningGroup,\n tools: { Fallback: UnifiedToolFallback },\n }}\n />\n <MessageError />\n </div>\n\n <div className=\"aui-assistant-message-footer wm:mt-1 wm:ml-2 wm:flex\">\n <BranchPicker />\n <AssistantActionBar />\n </div>\n </MessagePrimitive.Root>\n );\n};\n\nconst AssistantActionBar: FC = () => {\n return (\n <ActionBarPrimitive.Root\n hideWhenRunning\n autohide=\"not-last\"\n autohideFloat=\"single-branch\"\n className=\"aui-assistant-action-bar-root wm:col-start-3 wm:row-start-2 wm:-ml-1 wm:flex wm:gap-1 wm:text-muted-foreground data-floating:wm:absolute data-floating:wm:rounded-md data-floating:wm:border data-floating:wm:bg-background data-floating:wm:p-1 data-floating:wm:shadow-sm\"\n >\n <ActionBarPrimitive.Copy asChild>\n <TooltipIconButton tooltip=\"Copy\">\n <AssistantIf condition={({ message }) => message.isCopied}>\n <CheckIcon className=\"wm:size-4\" />\n </AssistantIf>\n <AssistantIf condition={({ message }) => !message.isCopied}>\n <CopyIcon className=\"wm:size-4\" />\n </AssistantIf>\n </TooltipIconButton>\n </ActionBarPrimitive.Copy>\n <ActionBarPrimitive.ExportMarkdown asChild>\n <TooltipIconButton tooltip=\"Export as Markdown\">\n <DownloadIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </ActionBarPrimitive.ExportMarkdown>\n <ActionBarPrimitive.Reload asChild>\n <TooltipIconButton tooltip=\"Refresh\">\n <RefreshCwIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </ActionBarPrimitive.Reload>\n </ActionBarPrimitive.Root>\n );\n};\n\nconst UserMessage: FC = () => {\n return (\n <MessagePrimitive.Root\n className=\"aui-user-message-root wm:fade-in wm:slide-in-from-bottom-1 wm:mx-auto wm:grid wm:w-full wm:max-w-(--thread-max-width) wm:animate-in wm:auto-rows-auto wm:grid-cols-[minmax(72px,1fr)_auto] wm:justify-items-end wm:content-start wm:gap-y-2 wm:px-2 wm:py-3 wm:duration-150 [&:where(>*)]:wm:col-start-2\"\n data-role=\"user\"\n >\n <UserMessageAttachments />\n\n <div className=\"aui-user-message-content-wrapper wm:relative wm:col-start-2 wm:min-w-0\">\n <div className=\"aui-user-message-content wm:wrap-break-word wm:rounded-2xl wm:bg-user-bubble-bg wm:px-4 wm:py-2.5 wm:text-user-bubble-text\">\n <MessagePrimitive.Parts />\n </div>\n <div className=\"aui-user-action-bar-wrapper wm:absolute wm:top-1/2 wm:left-0 wm:-translate-x-full wm:-translate-y-1/2 wm:pr-2\">\n <UserActionBar />\n </div>\n </div>\n\n <BranchPicker className=\"aui-user-branch-picker wm:col-span-full wm:col-start-1 wm:row-start-3 wm:-mr-1 wm:justify-end\" />\n </MessagePrimitive.Root>\n );\n};\n\nconst UserActionBar: FC = () => {\n return (\n <ActionBarPrimitive.Root\n hideWhenRunning\n autohide=\"not-last\"\n className=\"aui-user-action-bar-root wm:flex wm:flex-col wm:items-end\"\n >\n <ActionBarPrimitive.Edit asChild>\n <TooltipIconButton tooltip=\"Edit\" className=\"aui-user-action-edit wm:p-4\">\n <PencilIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </ActionBarPrimitive.Edit>\n </ActionBarPrimitive.Root>\n );\n};\n\nconst EditComposer: FC = () => {\n return (\n <MessagePrimitive.Root className=\"aui-edit-composer-wrapper wm:mx-auto wm:flex wm:w-full wm:max-w-(--thread-max-width) wm:flex-col wm:px-2 wm:py-3\">\n <ComposerPrimitive.Root className=\"aui-edit-composer-root wm:ml-auto wm:flex wm:w-full wm:max-w-[85%] wm:flex-col wm:rounded-2xl wm:bg-user-bubble-bg\">\n <ComposerPrimitive.Input\n className=\"aui-edit-composer-input wm:min-h-14 wm:w-full wm:resize-none wm:bg-transparent wm:p-4 wm:text-user-bubble-text wm:text-sm wm:outline-none\"\n autoFocus\n />\n <div className=\"aui-edit-composer-footer wm:mx-3 wm:mb-3 wm:flex wm:items-center wm:gap-2 wm:self-end\">\n <ComposerPrimitive.Cancel asChild>\n <Button variant=\"ghost\" size=\"sm\">\n Cancel\n </Button>\n </ComposerPrimitive.Cancel>\n <ComposerPrimitive.Send asChild>\n <Button size=\"sm\">Update</Button>\n </ComposerPrimitive.Send>\n </div>\n </ComposerPrimitive.Root>\n </MessagePrimitive.Root>\n );\n};\n\nconst BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({\n className,\n ...rest\n}) => {\n return (\n <BranchPickerPrimitive.Root\n hideWhenSingleBranch\n className={cn(\n \"aui-branch-picker-root wm:mr-2 wm:-ml-2 wm:inline-flex wm:items-center wm:text-muted-foreground wm:text-xs\",\n className,\n )}\n {...rest}\n >\n <BranchPickerPrimitive.Previous asChild>\n <TooltipIconButton tooltip=\"Previous\">\n <ChevronLeftIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </BranchPickerPrimitive.Previous>\n <span className=\"aui-branch-picker-state wm:font-medium\">\n <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />\n </span>\n <BranchPickerPrimitive.Next asChild>\n <TooltipIconButton tooltip=\"Next\">\n <ChevronRightIcon className=\"wm:size-4\" />\n </TooltipIconButton>\n </BranchPickerPrimitive.Next>\n </BranchPickerPrimitive.Root>\n );\n};\n","'use client'\n\nimport { AssistantIf, ThreadListItemPrimitive, ThreadListPrimitive } from '@assistant-ui/react'\nimport { Archive, Plus } from 'lucide-react'\n\nimport { cn } from '../../utils/cn'\n\nimport { useMemo } from 'react'\nimport type { FC } from 'react'\n\nexport interface AgentThreadListProps {\n\tclassName?: string\n\tonSelectThread?: () => void\n}\n\nexport const AgentThreadList: FC<AgentThreadListProps> = ({ className, onSelectThread }) => {\n\tconst ThreadListItem = useMemo(() => {\n\t\tconst Item: FC = () => <ThreadListItemBase onSelectThread={onSelectThread} />\n\t\tItem.displayName = 'AgentThreadListItem'\n\t\treturn Item\n\t}, [onSelectThread])\n\n\treturn (\n\t\t<ThreadListPrimitive.Root className={cn('wm:flex wm:flex-col wm:gap-2', className)}>\n\t\t\t<ThreadListNew />\n\t\t\t<AssistantIf condition={({ threads }) => threads.isLoading}>\n\t\t\t\t<ThreadListSkeleton />\n\t\t\t</AssistantIf>\n\t\t\t<AssistantIf condition={({ threads }) => !threads.isLoading}>\n\t\t\t\t<ThreadListPrimitive.Items components={{ ThreadListItem }} />\n\t\t\t</AssistantIf>\n\t\t</ThreadListPrimitive.Root>\n\t)\n}\n\nconst ThreadListNew: FC = () => {\n\treturn (\n\t\t<ThreadListPrimitive.New asChild>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'wm:flex wm:h-9 wm:w-full wm:items-center wm:justify-start wm:gap-2 wm:rounded-md wm:px-3 wm:text-sm',\n\t\t\t\t\t'wm:border wm:border-border wm:bg-muted/50 wm:text-foreground/80',\n\t\t\t\t\t'wm:transition-colors wm:hover:bg-muted wm:hover:text-foreground',\n\t\t\t\t\t'wm:data-[active=true]:bg-muted'\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<Plus className=\"wm:size-4\" />\n\t\t\t\tNew thread\n\t\t\t</button>\n\t\t</ThreadListPrimitive.New>\n\t)\n}\n\nconst ThreadListSkeleton: FC = () => {\n\treturn (\n\t\t<div className=\"wm:flex wm:flex-col wm:gap-1\" aria-label=\"Loading threads\">\n\t\t\t{Array.from({ length: 6 }, (_, idx) => (\n\t\t\t\t<div\n\t\t\t\t\t// eslint-disable-next-line react/no-array-index-key\n\t\t\t\t\tkey={`thread-skeleton-${idx}`}\n\t\t\t\t\tclassName=\"wm:h-8 wm:rounded-md wm:bg-muted/50 wm:animate-pulse\"\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\nconst ThreadListItemBase: FC<{ onSelectThread?: () => void }> = ({ onSelectThread }) => {\n\treturn (\n\t\t<ThreadListItemPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\t'wm:group wm:flex wm:h-9 wm:items-center wm:rounded-lg wm:transition-colors',\n\t\t\t\t'wm:hover:bg-muted wm:focus-visible:bg-muted wm:focus-visible:outline-none',\n\t\t\t\t'wm:data-[active=true]:bg-muted'\n\t\t\t)}\n\t\t>\n\t\t\t<ThreadListItemPrimitive.Trigger\n\t\t\t\tonClick={onSelectThread}\n\t\t\t\tclassName=\"wm:flex wm:h-full wm:flex-1 wm:items-center wm:truncate wm:px-3 wm:text-start wm:text-sm wm:text-foreground/80\"\n\t\t\t>\n\t\t\t\t<ThreadListItemPrimitive.Title fallback=\"New chat\" />\n\t\t\t</ThreadListItemPrimitive.Trigger>\n\t\t\t<div className=\"wm:flex wm:items-center wm:pr-2\">\n\t\t\t\t<ThreadListItemArchive />\n\t\t\t</div>\n\t\t</ThreadListItemPrimitive.Root>\n\t)\n}\n\nconst ThreadListItemArchive: FC = () => {\n\treturn (\n\t\t<ThreadListItemPrimitive.Archive asChild>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\ttitle=\"Archive thread\"\n\t\t\t\taria-label=\"Archive thread\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'wm:inline-flex wm:size-7 wm:items-center wm:justify-center wm:rounded-md wm:p-0',\n\t\t\t\t\t'wm:text-muted-foreground wm:hover:text-foreground',\n\t\t\t\t\t'wm:opacity-0 wm:transition-opacity wm:group-hover:opacity-100 wm:focus-visible:opacity-100'\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<Archive className=\"wm:size-4\" />\n\t\t\t</button>\n\t\t</ThreadListItemPrimitive.Archive>\n\t)\n}\n","import { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport { humanizeToolName } from '../utils/format'\n\nimport type { ToolCallMetadata } from '@mcp-b/cloud-mirror-types'\n\n/**\n * Represents a single action derived from a tool call.\n * Metadata (timing, source) is extracted from thread artifacts.\n */\nexport interface Action {\n\tid: string\n\tlabel: string\n\ttoolName: string\n\tstatus: 'running' | 'pending' | 'success' | 'error'\n\targs?: unknown\n\tresult?: unknown\n\terror?: string\n\t/** Timestamp when the tool call started (ms since epoch) */\n\tstartedAt?: number\n\t/** Duration of the tool call in milliseconds */\n\tduration?: number\n\t/** Source ID of the MCP server that handled the call */\n\tsourceId?: string\n\t/** Whether the tool call was aborted (e.g., tool removed during execution) */\n\twasAborted?: boolean\n}\n\ninterface ToolCallPart {\n\ttype: 'tool-call'\n\ttoolCallId: string\n\ttoolName: string\n\targs: unknown\n\tresult?: unknown\n\t// Status from assistant-ui\n\tstatus?: {\n\t\ttype: 'running' | 'complete' | 'incomplete' | 'requires-action'\n\t\terror?: unknown\n\t}\n\t/** Artifact containing ToolCallMetadata (timing, source info) */\n\tartifact?: unknown\n\tisError?: boolean\n}\n\n/**\n * Type guard to check if an artifact is ToolCallMetadata\n */\nfunction isToolCallMetadata(artifact: unknown): artifact is ToolCallMetadata {\n\tif (!artifact || typeof artifact !== 'object') return false\n\tconst a = artifact as Record<string, unknown>\n\treturn (\n\t\ttypeof a.startedAt === 'number' &&\n\t\ttypeof a.duration === 'number' &&\n\t\ttypeof a.sourceId === 'string'\n\t)\n}\n\n/**\n * Hook to derive actions from the current thread's tool calls\n *\n * Actions are a view of tool calls - not separate state.\n * This maintains compatibility with assistant-ui's data model.\n *\n * Metadata (timing, source info) is extracted from the artifact field\n * which is populated by MCPToolRegistry during tool execution.\n */\nexport function useActions(): Action[] {\n\t// Use selector pattern to get messages reactively\n\tconst messages = useThread((thread) => thread.messages)\n\n\treturn useMemo(() => {\n\t\tif (!messages || messages.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\tconst actions: Action[] = []\n\n\t\tfor (const message of messages) {\n\t\t\tif (message.role !== 'assistant') continue\n\n\t\t\tfor (const part of message.content) {\n\t\t\t\tif (part.type !== 'tool-call') continue\n\n\t\t\t\tconst toolPart = part as ToolCallPart\n\t\t\t\tconst isComplete = toolPart.result !== undefined\n\t\t\t\tconst hasError =\n\t\t\t\t\ttoolPart.isError === true ||\n\t\t\t\t\t(toolPart.result &&\n\t\t\t\t\t\ttypeof toolPart.result === 'object' &&\n\t\t\t\t\t\t'error' in (toolPart.result as Record<string, unknown>))\n\n\t\t\t\t// Check for requires-action status (HITL pattern)\n\t\t\t\tconst requiresAction = toolPart.status?.type === 'requires-action'\n\n\t\t\t\tlet status: Action['status']\n\t\t\t\tif (hasError) {\n\t\t\t\t\tstatus = 'error'\n\t\t\t\t} else if (isComplete) {\n\t\t\t\t\tstatus = 'success'\n\t\t\t\t} else if (requiresAction) {\n\t\t\t\t\tstatus = 'pending' // Waiting for user approval\n\t\t\t\t} else {\n\t\t\t\t\tstatus = 'running'\n\t\t\t\t}\n\n\t\t\t\t// Extract metadata from artifact if available\n\t\t\t\tconst metadata = isToolCallMetadata(toolPart.artifact) ? toolPart.artifact : undefined\n\n\t\t\t\tactions.push({\n\t\t\t\t\tid: toolPart.toolCallId,\n\t\t\t\t\ttoolName: toolPart.toolName,\n\t\t\t\t\tlabel: humanizeToolName(toolPart.toolName, status === 'running'),\n\t\t\t\t\tstatus,\n\t\t\t\t\targs: toolPart.args,\n\t\t\t\t\tresult: toolPart.result,\n\t\t\t\t\terror: hasError ? String((toolPart.result as Record<string, unknown>).error) : undefined,\n\t\t\t\t\t// Populate from artifact metadata\n\t\t\t\t\tstartedAt: metadata?.startedAt,\n\t\t\t\t\tduration: metadata?.duration,\n\t\t\t\t\tsourceId: metadata?.sourceId,\n\t\t\t\t\twasAborted: metadata?.wasAborted,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn actions\n\t}, [messages])\n}\n\n","'use client'\n\nimport { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\ninterface TextPart {\n\ttype: 'text'\n\ttext: string\n}\n\n/**\n * Returns the last text part from the most recent assistant message (if any).\n */\nexport function useLatestSummary(): string | null {\n\tconst messages = useThread((thread) => thread.messages)\n\n\treturn useMemo(() => {\n\t\tif (!messages || messages.length === 0) return null\n\n\t\tconst lastAssistantMessage = [...messages].reverse().find((m) => m.role === 'assistant')\n\t\tif (!lastAssistantMessage) return null\n\n\t\tconst textParts = lastAssistantMessage.content.filter((c): c is TextPart => c.type === 'text')\n\t\treturn textParts.at(-1)?.text ?? null\n\t}, [messages])\n}\n\n","/**\n * ThreadControlProvider\n *\n * Provides thread control operations (reset, startNew) to child components.\n * This bridges the active runtime's reset/startNew functions to the UI layer.\n *\n * Thread controls allow consumers to:\n * - Reset the current conversation (clear all messages)\n * - Start a new conversation (alias for reset in single-thread model)\n *\n * @example Basic usage\n * ```tsx\n * import { useThreadControl } from '@mcp-b/embedded-agent'\n *\n * function ChatControls() {\n * const { reset } = useThreadControl()\n *\n * return (\n * <button onClick={reset}>\n * New Conversation\n * </button>\n * )\n * }\n * ```\n */\n\nimport { createContext, useContext, useMemo } from 'react'\n\nimport type { FC, ReactNode } from 'react'\n\n/**\n * Thread control context value\n */\nexport interface ThreadControlContextValue {\n\t/** Reset the conversation - clears all messages on frontend and backend */\n\treset: () => Promise<void>\n\t/** Start a new conversation (multi-thread aware) */\n\tstartNew: () => Promise<void>\n}\n\nconst ThreadControlContext = createContext<ThreadControlContextValue | null>(null)\n\nexport interface ThreadControlProviderProps {\n\tchildren: ReactNode\n\t/** Reset function from the active runtime */\n\treset: () => Promise<void>\n\t/** Start-new function (defaults to reset) */\n\tstartNew?: () => Promise<void>\n}\n\n/**\n * Provider for thread control operations.\n *\n * This provider is used internally by AgentProvider to expose\n * the reset/startNew functions from the active runtime to child components.\n */\nexport const ThreadControlProvider: FC<ThreadControlProviderProps> = ({\n\tchildren,\n\treset,\n\tstartNew,\n}) => {\n\tconst value = useMemo<ThreadControlContextValue>(\n\t\t() => ({\n\t\t\treset,\n\t\t\tstartNew: startNew ?? reset,\n\t\t}),\n\t\t[reset, startNew]\n\t)\n\n\treturn <ThreadControlContext.Provider value={value}>{children}</ThreadControlContext.Provider>\n}\n\n/**\n * Hook to access thread control operations\n * @throws Error if used outside ThreadControlProvider\n */\nexport function useThreadControl(): ThreadControlContextValue {\n\tconst context = useContext(ThreadControlContext)\n\tif (!context) {\n\t\tthrow new Error('useThreadControl must be used within a ThreadControlProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access thread control operations (returns null if not in provider)\n */\nexport function useOptionalThreadControl(): ThreadControlContextValue | null {\n\treturn useContext(ThreadControlContext)\n}\n","/**\n * useAgent - Unified Agent Hook\n *\n * The main hook for accessing agent state and capabilities.\n * This is a thin facade over assistant-ui's thread state.\n *\n * Thread state (messages, actions) comes from @assistant-ui/react.\n * Voice transcripts and tool calls are also stored in the thread\n * (via VoiceThreadBridge), making assistant-ui the single source of truth.\n *\n * @example Basic usage\n * ```tsx\n * function MyComponent() {\n * const agent = useAgent()\n *\n * return (\n * <div>\n * {agent.isRunning && <p>Processing...</p>}\n * {agent.messages.map(m => <Message key={m.id} {...m} />)}\n * {agent.voice?.isActive && <p>Voice active</p>}\n * </div>\n * )\n * }\n * ```\n *\n * @example Thread controls (clear/new conversation)\n * ```tsx\n * function ChatControls() {\n * const agent = useAgent()\n *\n * return (\n * <button onClick={() => agent.thread?.startNew()}>\n * New Conversation\n * </button>\n * )\n * }\n * ```\n */\n\nimport { useThread } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport { useActions } from './useActions'\nimport { useLatestSummary } from './useLatestSummary'\nimport { useOptionalMCPTools } from '../providers/MCPToolsProvider'\nimport { useOptionalVoiceThread } from '../providers/VoiceThreadBridge'\nimport { useOptionalThreadControl } from '../providers/ThreadControlProvider'\n\nimport type { CallToolResult, Prompt, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { Action } from './useActions'\n\n/**\n * Voice mode state and controls\n */\nexport interface AgentVoice {\n\t/** Whether voice session is active */\n\tisActive: boolean\n\t/** Whether voice is connecting */\n\tisConnecting: boolean\n\t/** Whether there's an error */\n\tisError: boolean\n\t/** Whether microphone is muted */\n\tisMuted: boolean\n\t/** Whether voice mode is supported */\n\tisSupported: boolean\n\t/** Current error message */\n\terror?: string\n\t/** Current voice session ID */\n\tsessionId: string | null\n\t/** Audio level for visualization */\n\taudioLevel?: { micLevel: number; speakerLevel: number }\n\t/** Current transcript being spoken */\n\ttranscript?: { type: 'user' | 'assistant'; text: string; isDone: boolean }\n\t/** Start voice session */\n\tstart: () => Promise<void>\n\t/** Stop voice session */\n\tstop: () => void\n\t/** Toggle microphone mute */\n\ttoggleMute: (muted?: boolean) => void\n\t/** Send text message while in voice mode */\n\tsendMessage: (text: string) => void\n}\n\n/**\n * Thread controls for conversation management\n */\nexport interface AgentThread {\n\t/** Reset the conversation - clears all messages on frontend and backend */\n\treset: () => Promise<void>\n\t/** Start a new conversation (alias for reset in single-thread model) */\n\tstartNew: () => Promise<void>\n}\n\n/**\n * MCP tools state and controls\n */\nexport interface AgentTools {\n\t/** All available tools */\n\tlist: ToolWithSource[]\n\t/** Call a tool by name */\n\tcall: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\t/** Available prompts */\n\tprompts: Prompt[]\n\t/** Get expanded prompt content */\n\tgetPrompt: ((name: string) => Promise<GetPromptResult>) | undefined\n}\n\n/**\n * Thread message type (simplified for external consumers)\n */\nexport interface AgentMessage {\n\tid: string\n\trole: 'user' | 'assistant' | 'system'\n\tcontent: readonly unknown[]\n\tstatus?: { type: string }\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tmetadata?: Record<string, any>\n}\n\n/**\n * Agent state and controls returned by useAgent\n */\nexport interface AgentState {\n\t// Thread state (from assistant-ui - single source of truth)\n\t/** All messages in the thread (includes both text and voice messages) */\n\tmessages: readonly AgentMessage[]\n\t/** Whether the agent is currently processing */\n\tisRunning: boolean\n\t/** Whether thread has any messages */\n\thasMessages: boolean\n\n\t// Actions (derived from thread messages - both text and voice)\n\t/** All actions derived from tool calls in the thread */\n\tactions: Action[]\n\t/** Currently running action (if any) */\n\tcurrentAction: Action | null\n\t/** Recently completed actions */\n\trecentActions: Action[]\n\t/** Last completed action (success or error) */\n\tlastCompletedAction: Action | null\n\n\t// Summary (derived from last assistant message)\n\t/** Summary text from the last assistant message */\n\tsummary: string | null\n\n\t// Voice mode (null if not configured)\n\tvoice: AgentVoice | null\n\n\t// MCP tools (null if not in MCP context)\n\ttools: AgentTools | null\n\n\t// Thread controls (null if not in AgentProvider context)\n\t/** Thread controls for conversation management */\n\tthread: AgentThread | null\n\n\t// Derived state\n\t/** Whether voice mode is currently active */\n\tisVoiceActive: boolean\n}\n\n/**\n * Main agent hook - provides unified access to all agent capabilities\n *\n * This is a thin facade over assistant-ui. All thread state comes from\n * the assistant-ui runtime, including voice messages (which are pushed\n * into the thread by VoiceThreadBridge).\n */\nexport function useAgent(): AgentState {\n\t// Thread state from assistant-ui (single source of truth)\n\tconst threadMessages = useThread((thread) => thread.messages)\n\tconst isRunning = useThread((thread) => thread.isRunning)\n\n\t// Actions derived from thread messages (includes both text and voice tool calls)\n\tconst actions = useActions()\n\n\t// Derive action states inline (previously separate hooks)\n\tconst currentAction = useMemo(\n\t\t() => actions.find((a) => a.status === 'running') ?? null,\n\t\t[actions]\n\t)\n\tconst recentActions = useMemo(\n\t\t() => actions.filter((a) => a.status === 'success' || a.status === 'error').slice(-3),\n\t\t[actions]\n\t)\n\tconst lastCompletedAction = useMemo(() => {\n\t\tconst completed = actions.filter((a) => a.status === 'success' || a.status === 'error')\n\t\treturn completed.at(-1) ?? null\n\t}, [actions])\n\n\t// Summary from last assistant message\n\tconst summary = useLatestSummary()\n\n\t// Voice controls from VoiceThreadBridge\n\tconst voiceThread = useOptionalVoiceThread()\n\n\t// MCP tools (optional - may not be in MCP context)\n\tconst mcpContext = useOptionalMCPTools()\n\n\t// Derived: is voice active\n\tconst isVoiceActive = !!(\n\t\tvoiceThread?.isActive ||\n\t\tvoiceThread?.isConnecting ||\n\t\tvoiceThread?.isError\n\t)\n\n\t// Has messages\n\tconst hasMessages = (threadMessages?.length ?? 0) > 0\n\n\t// Build voice interface\n\tconst voice: AgentVoice | null = useMemo(() => {\n\t\tif (!voiceThread) return null\n\n\t\treturn {\n\t\t\tisActive: voiceThread.isActive,\n\t\t\tisConnecting: voiceThread.isConnecting,\n\t\t\tisError: voiceThread.isError,\n\t\t\tisMuted: voiceThread.isMuted,\n\t\t\tisSupported: voiceThread.isSupported,\n\t\t\terror: voiceThread.error,\n\t\t\tsessionId: voiceThread.sessionId,\n\t\t\taudioLevel: voiceThread.audioLevel,\n\t\t\ttranscript: voiceThread.transcript,\n\t\t\tstart: voiceThread.start,\n\t\t\tstop: voiceThread.stop,\n\t\t\ttoggleMute: voiceThread.toggleMute,\n\t\t\tsendMessage: voiceThread.sendMessage,\n\t\t}\n\t}, [voiceThread])\n\n\t// Build tools interface\n\tconst tools: AgentTools | null = useMemo(() => {\n\t\tif (!mcpContext) return null\n\n\t\treturn {\n\t\t\tlist: mcpContext.tools,\n\t\t\tcall: mcpContext.callTool,\n\t\t\tprompts: mcpContext.prompts ?? [],\n\t\t\tgetPrompt: mcpContext.getPrompt,\n\t\t}\n\t}, [mcpContext])\n\n\t// Thread controls from ThreadControlProvider\n\tconst threadControl = useOptionalThreadControl()\n\n\t// Build thread interface\n\t\tconst thread: AgentThread | null = useMemo(() => {\n\t\t\tif (!threadControl) return null\n\n\t\t\treturn {\n\t\t\t\treset: threadControl.reset,\n\t\t\t\tstartNew: threadControl.startNew,\n\t\t\t}\n\t\t}, [threadControl])\n\n\t// Build the full agent state\n\treturn useMemo<AgentState>(\n\t\t() => ({\n\t\t\t// Thread (single source of truth)\n\t\t\tmessages: (threadMessages ?? []) as readonly AgentMessage[],\n\t\t\tisRunning,\n\t\t\thasMessages,\n\n\t\t\t// Actions (derived from thread)\n\t\t\tactions,\n\t\t\tcurrentAction,\n\t\t\trecentActions,\n\t\t\tlastCompletedAction,\n\n\t\t\t// Summary\n\t\t\tsummary,\n\n\t\t\t// Voice\n\t\t\tvoice,\n\n\t\t\t// Tools\n\t\t\ttools,\n\n\t\t\t// Thread controls\n\t\t\tthread,\n\n\t\t\t// Derived\n\t\t\tisVoiceActive,\n\t\t}),\n\t\t[\n\t\t\tthreadMessages,\n\t\t\tisRunning,\n\t\t\thasMessages,\n\t\t\tactions,\n\t\t\tcurrentAction,\n\t\t\trecentActions,\n\t\t\tlastCompletedAction,\n\t\t\tsummary,\n\t\t\tvoice,\n\t\t\ttools,\n\t\t\tthread,\n\t\t\tisVoiceActive,\n\t\t]\n\t)\n}\n","/**\n * useAgentThreads\n *\n * Facade for assistant-ui thread list state + actions.\n *\n * Why this exists:\n * - Keep embedded-agent UI components from depending directly on assistant-ui internals.\n * - Provide a stable API surface for swapping UIs (pill, sidebar, mobile takeover).\n *\n * Note: In stateless mode, thread list features may be limited to a single \"main\" thread.\n */\n\nimport { useAssistantApi, useAssistantState } from '@assistant-ui/react'\nimport { useCallback, useMemo } from 'react'\n\nexport type AgentThreadStatus = 'regular' | 'archived'\n\nexport interface AgentThreadListItem {\n\tid: string\n\ttitle?: string\n\tstatus: AgentThreadStatus\n\tremoteId?: string\n\texternalId?: string\n}\n\nexport interface AgentThreadsState {\n\tisLoading: boolean\n\tcurrentThreadId: string\n\tthreadIds: readonly string[]\n\tarchivedThreadIds: readonly string[]\n\titemsById: Readonly<Record<string, AgentThreadListItem>>\n\n\tswitchToThread: (threadId: string) => void\n\tswitchToNewThread: () => void\n\trename: (threadId: string, title: string) => void\n\tarchive: (threadId: string) => void\n}\n\nexport function useAgentThreads(): AgentThreadsState {\n\tconst api = useAssistantApi()\n\n\tconst isLoading = useAssistantState(({ threads }) => threads.isLoading)\n\tconst currentThreadId = useAssistantState(({ threads }) => threads.mainThreadId)\n\tconst threadIds = useAssistantState(({ threads }) => threads.threadIds)\n\tconst archivedThreadIds = useAssistantState(({ threads }) => threads.archivedThreadIds)\n\tconst threadItems = useAssistantState(({ threads }) => threads.threadItems)\n\n\tconst itemsById = useMemo(() => {\n\t\tconst entries = threadItems.map((item) => {\n\t\t\tconst normalized: AgentThreadListItem = {\n\t\t\t\tid: item.id,\n\t\t\t\ttitle: item.title,\n\t\t\t\tstatus: item.status as AgentThreadStatus,\n\t\t\t\tremoteId: item.remoteId,\n\t\t\t\texternalId: item.externalId,\n\t\t\t}\n\t\t\treturn [item.id, normalized] as const\n\t\t})\n\t\treturn Object.fromEntries(entries) as Readonly<Record<string, AgentThreadListItem>>\n\t}, [threadItems])\n\n\tconst switchToThread = useCallback(\n\t\t(threadId: string) => {\n\t\t\tapi.threads().switchToThread(threadId)\n\t\t},\n\t\t[api],\n\t)\n\n\tconst switchToNewThread = useCallback(() => {\n\t\tapi.threads().switchToNewThread()\n\t}, [api])\n\n\tconst rename = useCallback(\n\t\t(threadId: string, title: string) => {\n\t\t\tapi.threads().item({ id: threadId }).rename(title)\n\t\t},\n\t\t[api],\n\t)\n\n\tconst archive = useCallback(\n\t\t(threadId: string) => {\n\t\t\tapi.threads().item({ id: threadId }).archive()\n\t\t},\n\t\t[api],\n\t)\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\tisLoading,\n\t\t\tcurrentThreadId,\n\t\t\tthreadIds,\n\t\t\tarchivedThreadIds,\n\t\t\titemsById,\n\t\t\tswitchToThread,\n\t\t\tswitchToNewThread,\n\t\t\trename,\n\t\t\tarchive,\n\t\t}),\n\t\t[\n\t\t\tisLoading,\n\t\t\tcurrentThreadId,\n\t\t\tthreadIds,\n\t\t\tarchivedThreadIds,\n\t\t\titemsById,\n\t\t\tswitchToThread,\n\t\t\tswitchToNewThread,\n\t\t\trename,\n\t\t\tarchive,\n\t\t],\n\t)\n}\n","/**\n * Auto-generated file - DO NOT EDIT\n * Generated by scripts/generate-inline-styles.js\n *\n * Contains the compiled CSS for the web component standalone build.\n */\n\n/**\n * Full CSS styles for global injection.\n * Use this when NOT using shadow DOM isolation.\n * @deprecated Prefer using WEBMCP_SHADOW_STYLES with the ShadowRoot component for style isolation.\n */\nexport const WEBMCP_STYLES = \"/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--wm-font-sans:var(--wm-font-sans);--wm-font-mono:var(--wm-font-mono);--wm-color-red-200:oklch(88.5% .062 18.334);--wm-color-red-300:oklch(80.8% .114 19.571);--wm-color-red-400:oklch(70.4% .191 22.216);--wm-color-red-500:oklch(63.7% .237 25.331);--wm-color-orange-500:oklch(70.5% .213 47.604);--wm-color-orange-600:oklch(64.6% .222 41.116);--wm-color-amber-400:oklch(82.8% .189 84.429);--wm-color-amber-500:oklch(76.9% .188 70.08);--wm-color-green-400:oklch(79.2% .209 151.711);--wm-color-green-500:oklch(72.3% .219 149.579);--wm-color-blue-400:oklch(70.7% .165 254.624);--wm-color-blue-500:oklch(62.3% .214 259.815);--wm-color-blue-600:oklch(54.6% .245 262.881);--wm-color-slate-900:oklch(20.8% .042 265.755);--wm-color-zinc-50:oklch(98.5% 0 0);--wm-color-zinc-100:oklch(96.7% .001 286.375);--wm-color-zinc-200:oklch(92% .004 286.32);--wm-color-zinc-400:oklch(70.5% .015 286.067);--wm-color-zinc-600:oklch(44.2% .017 285.786);--wm-color-zinc-700:oklch(37% .013 285.805);--wm-color-zinc-800:oklch(27.4% .006 286.033);--wm-color-black:#000;--wm-color-white:#fff;--wm-spacing:.25rem;--wm-container-lg:32rem;--wm-text-xs:.75rem;--wm-text-xs--line-height:calc(1/.75);--wm-text-sm:.875rem;--wm-text-sm--line-height:calc(1.25/.875);--wm-text-base:1rem;--wm-text-base--line-height:calc(1.5/1);--wm-text-lg:1.125rem;--wm-text-lg--line-height:calc(1.75/1.125);--wm-text-xl:1.25rem;--wm-text-xl--line-height:calc(1.75/1.25);--wm-text-2xl:1.5rem;--wm-text-2xl--line-height:calc(2/1.5);--wm-font-weight-medium:500;--wm-font-weight-semibold:600;--wm-font-weight-bold:700;--wm-font-weight-extrabold:800;--wm-tracking-tight:-.025em;--wm-tracking-wide:.025em;--wm-leading-normal:1.5;--wm-leading-relaxed:1.625;--wm-radius-sm:var(--wm-radius-sm);--wm-radius-md:var(--wm-radius-md);--wm-radius-lg:var(--wm-radius-lg);--wm-radius-xl:var(--wm-radius-xl);--wm-radius-2xl:1rem;--wm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--wm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--wm-ease-out:cubic-bezier(0,0,.2,1);--wm-animate-spin:spin 1s linear infinite;--wm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--wm-blur-sm:8px;--wm-blur-md:12px;--wm-blur-lg:16px;--wm-default-transition-duration:.15s;--wm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--wm-default-font-family:var(--wm-font-sans);--wm-default-mono-font-family:var(--wm-font-mono);--wm-color-background:var(--wm-color-background);--wm-color-foreground:var(--wm-color-foreground);--wm-color-card:var(--wm-color-card);--wm-color-card-foreground:var(--wm-color-card-foreground);--wm-color-popover:var(--wm-color-popover);--wm-color-popover-foreground:var(--wm-color-popover-foreground);--wm-color-primary:var(--wm-color-primary);--wm-color-primary-foreground:var(--wm-color-primary-foreground);--wm-color-secondary:var(--wm-color-secondary);--wm-color-secondary-foreground:var(--wm-color-secondary-foreground);--wm-color-muted:var(--wm-color-muted);--wm-color-muted-foreground:var(--wm-color-muted-foreground);--wm-color-accent:var(--wm-color-accent);--wm-color-accent-foreground:var(--wm-color-accent-foreground);--wm-color-destructive:var(--wm-color-destructive);--wm-color-destructive-foreground:var(--wm-color-destructive-foreground);--wm-color-border:var(--wm-color-border);--wm-color-input:var(--wm-color-input);--wm-color-ring:var(--wm-color-ring);--wm-color-success:var(--wm-color-success);--wm-color-warning:var(--wm-color-warning);--wm-color-error:var(--wm-color-error);--wm-font-size-xs:var(--wm-font-size-xs);--wm-font-size-sm:var(--wm-font-size-sm);--wm-font-size-base:var(--wm-font-size-base);--wm-font-size-lg:var(--wm-font-size-lg)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--wm-default-font-family,ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\");font-feature-settings:var(--wm-default-font-feature-settings,normal);font-variation-settings:var(--wm-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--wm-default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace);font-feature-settings:var(--wm-default-mono-font-feature-settings,normal);font-variation-settings:var(--wm-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:host,:root{--wm-color-background:oklch(100% 0 0);--wm-color-foreground:oklch(14.1% .005 285.823);--wm-color-primary:oklch(21% .006 285.885);--wm-color-primary-foreground:oklch(98.5% 0 0);--wm-color-muted:oklch(96.7% .001 286.375);--wm-color-muted-foreground:oklch(55.2% .016 285.938);--wm-color-border:oklch(92% .004 286.32);--wm-color-success:oklch(70% .2 145);--wm-color-warning:oklch(75% .15 85);--wm-color-error:oklch(65% .25 25);--wm-color-card:var(--wm-color-background);--wm-color-card-foreground:var(--wm-color-foreground);--wm-color-popover:var(--wm-color-background);--wm-color-popover-foreground:var(--wm-color-foreground);--wm-color-secondary:var(--wm-color-muted);--wm-color-secondary-foreground:var(--wm-color-foreground);--wm-color-accent:var(--wm-color-muted);--wm-color-accent-foreground:var(--wm-color-foreground);--wm-color-destructive:var(--wm-color-error);--wm-color-destructive-foreground:var(--wm-color-primary-foreground);--wm-color-input:var(--wm-color-border);--wm-color-ring:var(--wm-color-muted-foreground);--wm-user-bubble-bg:var(--wm-color-muted);--wm-user-bubble-text:var(--wm-color-foreground);--wm-assistant-bubble-bg:transparent;--wm-assistant-bubble-text:var(--wm-color-foreground);--wm-composer-bg:var(--wm-color-background);--wm-composer-border:var(--wm-color-input);--wm-composer-text:var(--wm-color-foreground);--wm-composer-placeholder:var(--wm-color-muted-foreground);--wm-composer-button-bg:var(--wm-color-primary);--wm-composer-button-text:var(--wm-color-primary-foreground);--wm-tool-bg:var(--wm-color-muted);--wm-tool-border:var(--wm-color-border);--wm-tool-text:var(--wm-color-foreground);--wm-tool-header-bg:var(--wm-color-muted);--wm-tool-approve-bg:var(--wm-color-primary);--wm-tool-approve-text:var(--wm-color-primary-foreground);--wm-tool-deny-bg:transparent;--wm-tool-deny-text:var(--wm-color-muted-foreground);--wm-code-bg:oklch(14.1% .005 285.823);--wm-code-text:oklch(98.5% 0 0);--wm-code-header-bg:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){:host,:root{--wm-code-header-bg:color-mix(in oklch,var(--wm-color-muted-foreground),transparent 85%)}}:host,:root{--wm-radius:.75rem;--wm-radius-sm:calc(var(--wm-radius) - 4px);--wm-radius-md:calc(var(--wm-radius) - 2px);--wm-radius-lg:var(--wm-radius);--wm-radius-xl:calc(var(--wm-radius) + 4px);--wm-radius-full:9999px;--wm-spacing-unit:.25rem;--wm-font-sans:ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";--wm-font-mono:ui-monospace,SFMono-Regular,\\\"SF Mono\\\",Menlo,Consolas,monospace;--wm-font-size-xs:.6875rem;--wm-font-size-sm:.75rem;--wm-font-size-base:.875rem;--wm-font-size-lg:1rem;--wm-duration-fast:.15s;--wm-duration-normal:.25s;--wm-duration-slow:.4s;--wm-easing-default:cubic-bezier(.4,0,.2,1);--wm-easing-spring:cubic-bezier(.34,1.56,.64,1);--wm-z-base:0;--wm-z-content:10;--wm-z-overlay:50;--wm-z-max:2147480000;--wm-shadow-sm:0 1px 2px #0000000d;--wm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--wm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--wm-blur-sm:8px;--wm-blur-md:12px;--wm-blur-lg:20px}:host(.dark),.dark{--wm-color-background:oklch(14.1% .005 285.823);--wm-color-foreground:oklch(98.5% 0 0);--wm-color-primary:oklch(92% .004 286.32);--wm-color-primary-foreground:oklch(21% .006 285.885);--wm-color-muted:oklch(27.4% .006 286.033);--wm-color-muted-foreground:oklch(70.5% .015 286.067);--wm-color-border:oklch(100% 0 0/.1);--wm-color-input:oklch(100% 0 0/.15);--wm-color-ring:oklch(55.2% .016 285.938);--wm-color-success:oklch(75% .18 145);--wm-color-warning:oklch(80% .14 85);--wm-color-error:oklch(70% .22 25)}*{border-color:var(--wm-color-border);outline-color:var(--wm-color-ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklch,var(--wm-color-ring),transparent 50%)}}}@layer components{.wm-animate-fade-in-up{opacity:0;animation:.5s ease-out forwards wm-fade-in-up}.wm-animate-gradient-shift{background-size:200% 200%;animation:20s ease-in-out infinite wm-gradient-shift}.wm-animate-float-slow{animation:20s ease-in-out infinite wm-float}.wm-animate-float-delayed{animation:25s ease-in-out 5s infinite wm-float-delayed}.wm-animate-shimmer{animation:2s linear infinite wm-shimmer}.wm-animate-pulse-success{animation:.6s ease-out wm-pulse-success}.wm-animate-shake{animation:.3s ease-out wm-shake}.wm-animate-pulse-glow{animation:2s ease-in-out infinite wm-pulse-glow}.wm-animate-gradient-x{animation:8s ease-in-out infinite wm-gradient-x}.wm-transition-spring{transition:all var(--wm-duration-slow)var(--wm-easing-spring)}.wm-transition-smooth{transition:all var(--wm-duration-normal)var(--wm-easing-default)}.wm-app-shell{z-index:var(--wm-z-base);background-color:var(--wm-color-background);background-image:radial-gradient(80% 60% at -10% -10%,oklch(82% .15 270/.15),#0000),radial-gradient(60% 50% at 110% 10%,oklch(85% .1 220/.12),#0000),radial-gradient(50% 45% at 50% 120%,oklch(95% .02 250/.08),#0000);position:relative}.dark .wm-app-shell{background-image:radial-gradient(80% 60% at -10% -10%,oklch(55% .14 270/.25),#0000),radial-gradient(60% 50% at 110% 15%,oklch(60% .12 220/.22),#0000),radial-gradient(50% 45% at 50% 120%,oklch(35% .04 250/.16),#0000)}.wm-app-shell:before,.wm-app-shell:after{content:\\\"\\\";pointer-events:none;border-radius:var(--wm-radius-full);filter:blur(32px);opacity:.6;z-index:-1;position:absolute;inset:auto}.wm-app-shell:before{background:radial-gradient(60% 60% at 40% 40%,oklch(80% .12 270/.3),#0000);width:260px;height:260px;top:-60px;left:-80px}.wm-app-shell:after{background:radial-gradient(60% 60% at 60% 60%,oklch(84% .1 220/.25),#0000);width:300px;height:300px;bottom:-80px;right:-60px}.wm-toolbar-surface{border-top:1px solid var(--wm-color-border);background:linear-gradient(to right,var(--wm-color-background),var(--wm-color-background),var(--wm-color-background))}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface{background:linear-gradient(to right,var(--wm-color-background),color-mix(in oklch,var(--wm-color-background),transparent 5%),var(--wm-color-background))}}.wm-toolbar-surface{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md))}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.wm-toolbar-surface{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}}.wm-toolbar-surface-top{border-bottom:1px solid var(--wm-color-border);background:linear-gradient(to right,var(--wm-color-background),var(--wm-color-background),var(--wm-color-background))}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface-top{background:linear-gradient(to right,var(--wm-color-background),color-mix(in oklch,var(--wm-color-background),transparent 5%),var(--wm-color-background))}}.wm-toolbar-surface-top{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md))}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.wm-toolbar-surface-top{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface-top{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}}.wm-toolbar-inner{justify-content:space-between;align-items:center;padding:.5rem .75rem;display:flex}.wm-toolbar-card{background:var(--wm-color-card);justify-content:space-between;align-items:center;gap:.5rem;display:flex}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-card{background:color-mix(in oklch,var(--wm-color-card),transparent 60%)}}.wm-toolbar-card{border:1px solid var(--wm-color-border);border-radius:var(--wm-radius-lg);padding:.5rem .75rem}.wm-toolbar-group{align-items:center;gap:.25rem;display:flex}.wm-btn-toolbar-primary{border-radius:var(--wm-radius-lg);background:linear-gradient(to right,var(--wm-color-primary),var(--wm-color-primary));align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;display:flex}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary{background:linear-gradient(to right,color-mix(in oklch,var(--wm-color-primary),transparent 95%),color-mix(in oklch,var(--wm-color-primary),transparent 90%))}}.wm-btn-toolbar-primary{border:1px solid var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary{border:1px solid color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}.wm-btn-toolbar-primary{transition:all var(--wm-duration-fast)}.wm-btn-toolbar-primary:hover{background:linear-gradient(to right,var(--wm-color-primary),var(--wm-color-primary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary:hover{background:linear-gradient(to right,color-mix(in oklch,var(--wm-color-primary),transparent 90%),color-mix(in oklch,var(--wm-color-primary),transparent 80%))}}.wm-btn-toolbar-icon-primary{border-radius:var(--wm-radius-full);background:linear-gradient(to bottom right,var(--wm-color-primary),var(--wm-color-primary));width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-primary),transparent 90%),color-mix(in oklch,var(--wm-color-primary),transparent 80%))}}.wm-btn-toolbar-icon-primary{border:1px solid var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary{border:1px solid color-mix(in oklch,var(--wm-color-primary),transparent 70%)}}.wm-btn-toolbar-icon-primary{box-shadow:var(--wm-shadow-sm);transition:all var(--wm-duration-fast)}.wm-btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,var(--wm-color-primary),var(--wm-color-primary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-primary),transparent 80%),color-mix(in oklch,var(--wm-color-primary),transparent 70%))}}.wm-btn-toolbar-icon-secondary{border-radius:var(--wm-radius-full);background:linear-gradient(to bottom right,var(--wm-color-secondary),var(--wm-color-secondary));width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-secondary),transparent 90%),color-mix(in oklch,var(--wm-color-secondary),transparent 80%))}}.wm-btn-toolbar-icon-secondary{border:1px solid var(--wm-color-secondary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary{border:1px solid color-mix(in oklch,var(--wm-color-secondary),transparent 70%)}}.wm-btn-toolbar-icon-secondary{box-shadow:var(--wm-shadow-sm);transition:all var(--wm-duration-fast)}.wm-btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,var(--wm-color-secondary),var(--wm-color-secondary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-secondary),transparent 80%),color-mix(in oklch,var(--wm-color-secondary),transparent 70%))}}.wm-badge-compact{height:1.25rem;padding:0 .5rem;font-size:10px}.wm-badge-mini{height:1rem;padding:0 .375rem;font-size:10px}.wm-shimmer{background:linear-gradient(90deg,transparent,var(--wm-color-foreground),transparent);animation:3s linear infinite wm-shimmer}@supports (color:color-mix(in lab, red, red)){.wm-shimmer{background:linear-gradient(90deg,transparent,color-mix(in oklch,var(--wm-color-foreground),transparent 90%),transparent)}}.wm-shimmer{background-size:1000px 100%}.wm-gradient-text{background:linear-gradient(to right,var(--wm-color-foreground),var(--wm-color-foreground))}@supports (color:color-mix(in lab, red, red)){.wm-gradient-text{background:linear-gradient(to right,var(--wm-color-foreground),color-mix(in oklch,var(--wm-color-foreground),transparent 30%))}}.wm-gradient-text{-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text}.wm-glass{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass{background:color-mix(in oklch,var(--wm-color-background),transparent 50%)}}.wm-glass{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md));border:1px solid var(--wm-color-border)}@supports (color:color-mix(in lab, red, red)){.wm-glass{border:1px solid color-mix(in oklch,var(--wm-color-border),transparent 50%)}}.wm-tool-card{transition:all .3s ease-out}.wm-tool-card:hover{box-shadow:var(--wm-shadow-lg);transform:scale(1.02)}.wm-tool-border-calling{position:relative;overflow:hidden}.wm-tool-border-calling:before{content:\\\"\\\";background:conic-gradient(from 0deg,transparent 0deg,transparent 60deg,var(--wm-color-primary)90deg,var(--wm-color-primary)120deg,var(--wm-color-primary)150deg,transparent 180deg,transparent 360deg);position:absolute;inset:-50%}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-calling:before{background:conic-gradient(from 0deg,transparent 0deg,transparent 60deg,color-mix(in oklch,var(--wm-color-primary),transparent 50%)90deg,color-mix(in oklch,var(--wm-color-primary),transparent 30%)120deg,color-mix(in oklch,var(--wm-color-primary),transparent 50%)150deg,transparent 180deg,transparent 360deg)}}.wm-tool-border-calling:before{animation:1.5s linear infinite wm-border-rotate}.wm-tool-border-success{background:var(--wm-color-success)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-success{background:color-mix(in oklch,var(--wm-color-success),transparent 60%)}}.wm-tool-border-success{box-shadow:0 0 12px var(--wm-color-success),inset 0 0 8px var(--wm-color-success)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-success{box-shadow:0 0 12px color-mix(in oklch,var(--wm-color-success),transparent 70%),inset 0 0 8px color-mix(in oklch,var(--wm-color-success),transparent 90%)}}.wm-tool-border-error{background:var(--wm-color-error)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-error{background:color-mix(in oklch,var(--wm-color-error),transparent 60%)}}.wm-tool-border-error{box-shadow:0 0 12px var(--wm-color-error),inset 0 0 8px var(--wm-color-error)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-error{box-shadow:0 0 12px color-mix(in oklch,var(--wm-color-error),transparent 70%),inset 0 0 8px color-mix(in oklch,var(--wm-color-error),transparent 90%)}}.wm-scrollbar-thin{scrollbar-width:thin;scrollbar-color:var(--wm-color-primary)transparent}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin{scrollbar-color:color-mix(in oklch,var(--wm-color-primary),transparent 80%)transparent}}.wm-scrollbar-thin::-webkit-scrollbar{width:6px;height:6px}.wm-scrollbar-thin::-webkit-scrollbar-track{background:0 0}.wm-scrollbar-thin::-webkit-scrollbar-thumb{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin::-webkit-scrollbar-thumb{background-color:color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}.wm-scrollbar-thin::-webkit-scrollbar-thumb{border-radius:3px}.wm-scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:color-mix(in oklch,var(--wm-color-primary),transparent 70%)}}.wm-glass-pill{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{background:color-mix(in oklch,var(--wm-color-background),transparent 15%)}}.wm-glass-pill{-webkit-backdrop-filter:blur(var(--wm-blur-lg))saturate(150%);box-shadow:0 4px 16px var(--wm-color-foreground),inset 0 .5px 0 var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{box-shadow:0 4px 16px color-mix(in oklch,var(--wm-color-foreground),transparent 80%),inset 0 .5px 0 color-mix(in oklch,var(--wm-color-foreground),transparent 92%)}}.wm-glass-pill{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-pill:before{content:\\\"\\\";border-radius:inherit;background:linear-gradient(180deg,var(--wm-color-foreground)0%,transparent 40%);position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill:before{background:linear-gradient(180deg,color-mix(in oklch,var(--wm-color-foreground),transparent 96%)0%,transparent 40%)}}.wm-glass-pill:before{pointer-events:none;z-index:1}.wm-glass-pill-collapsed{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{background:color-mix(in oklch,var(--wm-color-background),transparent 15%)}}.wm-glass-pill-collapsed{-webkit-backdrop-filter:blur(var(--wm-blur-lg))saturate(150%);box-shadow:0 2px 8px var(--wm-color-foreground),inset 0 .5px 0 var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{box-shadow:0 2px 8px color-mix(in oklch,var(--wm-color-foreground),transparent 80%),inset 0 .5px 0 color-mix(in oklch,var(--wm-color-foreground),transparent 92%)}}.wm-glass-pill-collapsed{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-pill-hovered{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}.wm-glass-pill-hovered{-webkit-backdrop-filter:blur(16px)saturate(140%);box-shadow:0 2px 12px var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{box-shadow:0 2px 12px color-mix(in oklch,var(--wm-color-foreground),transparent 82%)}}.wm-glass-pill-hovered{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-shimmer{background:linear-gradient(90deg,var(--wm-color-foreground)0%,var(--wm-color-foreground)50%,var(--wm-color-foreground)100%)}@supports (color:color-mix(in lab, red, red)){.wm-glass-shimmer{background:linear-gradient(90deg,color-mix(in oklch,var(--wm-color-foreground),transparent 92%)0%,color-mix(in oklch,var(--wm-color-foreground),transparent 85%)50%,color-mix(in oklch,var(--wm-color-foreground),transparent 92%)100%)}}.wm-glass-shimmer{background-size:200% 100%;animation:4s ease-in-out infinite wm-glass-shimmer}.wm-scroll-touch{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.wm-scroll-fade-y{-webkit-mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000);mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000)}.wm-pb-safe{padding-bottom:env(safe-area-inset-bottom,0px)}.wm-mb-safe{margin-bottom:env(safe-area-inset-bottom,0px)}.wm-bottom-safe{bottom:max(1rem,env(safe-area-inset-bottom,0px))}@supports (padding-bottom:env(safe-area-inset-bottom)){.wm-pill-safe-bottom{padding-bottom:calc(env(safe-area-inset-bottom,0px) + .5rem)}}}@layer utilities{.wm\\\\:pointer-events-auto{pointer-events:auto}.wm\\\\:pointer-events-none{pointer-events:none}.wm\\\\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.wm\\\\:absolute{position:absolute}.wm\\\\:fixed{position:fixed}.wm\\\\:relative{position:relative}.wm\\\\:sticky{position:sticky}.wm\\\\:-inset-\\\\[1px\\\\]{inset:-1px}.wm\\\\:inset-0{inset:calc(var(--wm-spacing)*0)}.wm\\\\:-top-1{top:calc(var(--wm-spacing)*-1)}.wm\\\\:-top-1\\\\.5{top:calc(var(--wm-spacing)*-1.5)}.wm\\\\:-top-12{top:calc(var(--wm-spacing)*-12)}.wm\\\\:top-1\\\\.5{top:calc(var(--wm-spacing)*1.5)}.wm\\\\:top-1\\\\/2{top:50%}.wm\\\\:top-2{top:calc(var(--wm-spacing)*2)}.wm\\\\:-right-0\\\\.5{right:calc(var(--wm-spacing)*-.5)}.wm\\\\:-right-1{right:calc(var(--wm-spacing)*-1)}.wm\\\\:-right-1\\\\.5{right:calc(var(--wm-spacing)*-1.5)}.wm\\\\:right-0{right:calc(var(--wm-spacing)*0)}.wm\\\\:right-1\\\\.5{right:calc(var(--wm-spacing)*1.5)}.wm\\\\:right-2{right:calc(var(--wm-spacing)*2)}.wm\\\\:right-4{right:calc(var(--wm-spacing)*4)}.wm\\\\:-bottom-0\\\\.5{bottom:calc(var(--wm-spacing)*-.5)}.wm\\\\:bottom-0{bottom:calc(var(--wm-spacing)*0)}.wm\\\\:bottom-full{bottom:100%}.wm\\\\:left-0{left:calc(var(--wm-spacing)*0)}.wm\\\\:left-1\\\\/2{left:50%}.wm\\\\:left-2{left:calc(var(--wm-spacing)*2)}.wm\\\\:z-10{z-index:10}.wm\\\\:z-20{z-index:20}.wm\\\\:z-50{z-index:50}.wm\\\\:col-span-full{grid-column:1/-1}.wm\\\\:col-start-1{grid-column-start:1}.wm\\\\:col-start-2{grid-column-start:2}.wm\\\\:col-start-3{grid-column-start:3}.wm\\\\:row-start-2{grid-row-start:2}.wm\\\\:row-start-3{grid-row-start:3}.wm\\\\:-m-1{margin:calc(var(--wm-spacing)*-1)}.wm\\\\:m-0{margin:calc(var(--wm-spacing)*0)}.wm\\\\:mx-2{margin-inline:calc(var(--wm-spacing)*2)}.wm\\\\:mx-3{margin-inline:calc(var(--wm-spacing)*3)}.wm\\\\:mx-auto{margin-inline:auto}.wm\\\\:my-1{margin-block:calc(var(--wm-spacing)*1)}.wm\\\\:my-2{margin-block:calc(var(--wm-spacing)*2)}.wm\\\\:my-3{margin-block:calc(var(--wm-spacing)*3)}.wm\\\\:my-4{margin-block:calc(var(--wm-spacing)*4)}.wm\\\\:my-5{margin-block:calc(var(--wm-spacing)*5)}.wm\\\\:my-auto{margin-block:auto}.wm\\\\:-mt-1{margin-top:calc(var(--wm-spacing)*-1)}.wm\\\\:mt-0\\\\.5{margin-top:calc(var(--wm-spacing)*.5)}.wm\\\\:mt-1{margin-top:calc(var(--wm-spacing)*1)}.wm\\\\:mt-1\\\\.5{margin-top:calc(var(--wm-spacing)*1.5)}.wm\\\\:mt-2{margin-top:calc(var(--wm-spacing)*2)}.wm\\\\:mt-3{margin-top:calc(var(--wm-spacing)*3)}.wm\\\\:mt-4{margin-top:calc(var(--wm-spacing)*4)}.wm\\\\:mt-5{margin-top:calc(var(--wm-spacing)*5)}.wm\\\\:mt-6{margin-top:calc(var(--wm-spacing)*6)}.wm\\\\:mt-auto{margin-top:auto}.wm\\\\:-mr-1{margin-right:calc(var(--wm-spacing)*-1)}.wm\\\\:mr-1\\\\.5{margin-right:calc(var(--wm-spacing)*1.5)}.wm\\\\:mr-2{margin-right:calc(var(--wm-spacing)*2)}.wm\\\\:-mb-1{margin-bottom:calc(var(--wm-spacing)*-1)}.wm\\\\:mb-0\\\\.5{margin-bottom:calc(var(--wm-spacing)*.5)}.wm\\\\:mb-1{margin-bottom:calc(var(--wm-spacing)*1)}.wm\\\\:mb-1\\\\.5{margin-bottom:calc(var(--wm-spacing)*1.5)}.wm\\\\:mb-2{margin-bottom:calc(var(--wm-spacing)*2)}.wm\\\\:mb-3{margin-bottom:calc(var(--wm-spacing)*3)}.wm\\\\:mb-5{margin-bottom:calc(var(--wm-spacing)*5)}.wm\\\\:mb-6{margin-bottom:calc(var(--wm-spacing)*6)}.wm\\\\:-ml-1{margin-left:calc(var(--wm-spacing)*-1)}.wm\\\\:-ml-2{margin-left:calc(var(--wm-spacing)*-2)}.wm\\\\:ml-0\\\\.5{margin-left:calc(var(--wm-spacing)*.5)}.wm\\\\:ml-1{margin-left:calc(var(--wm-spacing)*1)}.wm\\\\:ml-2{margin-left:calc(var(--wm-spacing)*2)}.wm\\\\:ml-4{margin-left:calc(var(--wm-spacing)*4)}.wm\\\\:ml-6{margin-left:calc(var(--wm-spacing)*6)}.wm\\\\:ml-auto{margin-left:auto}.wm\\\\:line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.wm\\\\:line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.wm\\\\:block{display:block}.wm\\\\:flex{display:flex}.wm\\\\:grid{display:grid}.wm\\\\:hidden{display:none}.wm\\\\:inline-block{display:inline-block}.wm\\\\:inline-flex{display:inline-flex}.wm\\\\:size-3{width:calc(var(--wm-spacing)*3);height:calc(var(--wm-spacing)*3)}.wm\\\\:size-3\\\\.5{width:calc(var(--wm-spacing)*3.5);height:calc(var(--wm-spacing)*3.5)}.wm\\\\:size-4{width:calc(var(--wm-spacing)*4);height:calc(var(--wm-spacing)*4)}.wm\\\\:size-5{width:calc(var(--wm-spacing)*5);height:calc(var(--wm-spacing)*5)}.wm\\\\:size-6{width:calc(var(--wm-spacing)*6);height:calc(var(--wm-spacing)*6)}.wm\\\\:size-7{width:calc(var(--wm-spacing)*7);height:calc(var(--wm-spacing)*7)}.wm\\\\:size-8{width:calc(var(--wm-spacing)*8);height:calc(var(--wm-spacing)*8)}.wm\\\\:size-9{width:calc(var(--wm-spacing)*9);height:calc(var(--wm-spacing)*9)}.wm\\\\:size-10{width:calc(var(--wm-spacing)*10);height:calc(var(--wm-spacing)*10)}.wm\\\\:size-\\\\[34px\\\\]{width:34px;height:34px}.wm\\\\:size-full{width:100%;height:100%}.wm\\\\:h-1\\\\.5{height:calc(var(--wm-spacing)*1.5)}.wm\\\\:h-2{height:calc(var(--wm-spacing)*2)}.wm\\\\:h-2\\\\.5{height:calc(var(--wm-spacing)*2.5)}.wm\\\\:h-3{height:calc(var(--wm-spacing)*3)}.wm\\\\:h-3\\\\.5{height:calc(var(--wm-spacing)*3.5)}.wm\\\\:h-4{height:calc(var(--wm-spacing)*4)}.wm\\\\:h-4\\\\.5{height:calc(var(--wm-spacing)*4.5)}.wm\\\\:h-5{height:calc(var(--wm-spacing)*5)}.wm\\\\:h-6{height:calc(var(--wm-spacing)*6)}.wm\\\\:h-7{height:calc(var(--wm-spacing)*7)}.wm\\\\:h-8{height:calc(var(--wm-spacing)*8)}.wm\\\\:h-9{height:calc(var(--wm-spacing)*9)}.wm\\\\:h-10{height:calc(var(--wm-spacing)*10)}.wm\\\\:h-11{height:calc(var(--wm-spacing)*11)}.wm\\\\:h-auto{height:auto}.wm\\\\:h-full{height:100%}.wm\\\\:max-h-24{max-height:calc(var(--wm-spacing)*24)}.wm\\\\:max-h-32{max-height:calc(var(--wm-spacing)*32)}.wm\\\\:max-h-40{max-height:calc(var(--wm-spacing)*40)}.wm\\\\:max-h-64{max-height:calc(var(--wm-spacing)*64)}.wm\\\\:max-h-\\\\[30vh\\\\]{max-height:30vh}.wm\\\\:max-h-\\\\[90vh\\\\]{max-height:90vh}.wm\\\\:min-h-0{min-height:calc(var(--wm-spacing)*0)}.wm\\\\:min-h-7{min-height:calc(var(--wm-spacing)*7)}.wm\\\\:min-h-14{min-height:calc(var(--wm-spacing)*14)}.wm\\\\:min-h-40{min-height:calc(var(--wm-spacing)*40)}.wm\\\\:w-0\\\\.5{width:calc(var(--wm-spacing)*.5)}.wm\\\\:w-1\\\\.5{width:calc(var(--wm-spacing)*1.5)}.wm\\\\:w-2{width:calc(var(--wm-spacing)*2)}.wm\\\\:w-2\\\\.5{width:calc(var(--wm-spacing)*2.5)}.wm\\\\:w-2\\\\/3{width:66.6667%}.wm\\\\:w-3{width:calc(var(--wm-spacing)*3)}.wm\\\\:w-3\\\\.5{width:calc(var(--wm-spacing)*3.5)}.wm\\\\:w-3\\\\/5{width:60%}.wm\\\\:w-4{width:calc(var(--wm-spacing)*4)}.wm\\\\:w-4\\\\.5{width:calc(var(--wm-spacing)*4.5)}.wm\\\\:w-4\\\\/5{width:80%}.wm\\\\:w-5{width:calc(var(--wm-spacing)*5)}.wm\\\\:w-6{width:calc(var(--wm-spacing)*6)}.wm\\\\:w-8{width:calc(var(--wm-spacing)*8)}.wm\\\\:w-11{width:calc(var(--wm-spacing)*11)}.wm\\\\:w-full{width:100%}.wm\\\\:w-px{width:1px}.wm\\\\:max-w-\\\\(--thread-max-width\\\\){max-width:var(--thread-max-width)}.wm\\\\:max-w-24{max-width:calc(var(--wm-spacing)*24)}.wm\\\\:max-w-32{max-width:calc(var(--wm-spacing)*32)}.wm\\\\:max-w-\\\\[85\\\\%\\\\]{max-width:85%}.wm\\\\:max-w-\\\\[100px\\\\]{max-width:100px}.wm\\\\:max-w-\\\\[140px\\\\]{max-width:140px}.wm\\\\:max-w-full{max-width:100%}.wm\\\\:max-w-lg{max-width:var(--wm-container-lg)}.wm\\\\:min-w-0{min-width:calc(var(--wm-spacing)*0)}.wm\\\\:min-w-7{min-width:calc(var(--wm-spacing)*7)}.wm\\\\:flex-1{flex:1}.wm\\\\:flex-shrink-0,.wm\\\\:shrink-0{flex-shrink:0}.wm\\\\:flex-grow,.wm\\\\:grow{flex-grow:1}.wm\\\\:border-separate{border-collapse:separate}.wm\\\\:border-spacing-0{--tw-border-spacing-x:calc(var(--wm-spacing)*0);--tw-border-spacing-y:calc(var(--wm-spacing)*0);border-spacing:var(--tw-border-spacing-x)var(--tw-border-spacing-y)}.wm\\\\:-translate-x-1\\\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:-translate-y-1\\\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:rotate-180{rotate:180deg}.wm\\\\:animate-in{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.wm\\\\:animate-pulse{animation:var(--wm-animate-pulse)}.wm\\\\:animate-spin{animation:var(--wm-animate-spin)}.wm\\\\:cursor-grab{cursor:grab}.wm\\\\:cursor-not-allowed{cursor:not-allowed}.wm\\\\:cursor-pointer{cursor:pointer}.wm\\\\:resize-none{resize:none}.wm\\\\:scroll-m-20{scroll-margin:calc(var(--wm-spacing)*20)}.wm\\\\:list-inside{list-style-position:inside}.wm\\\\:list-decimal{list-style-type:decimal}.wm\\\\:list-disc{list-style-type:disc}.wm\\\\:auto-rows-auto{grid-auto-rows:auto}.wm\\\\:grid-cols-\\\\[minmax\\\\(72px\\\\,1fr\\\\)_auto\\\\]{grid-template-columns:minmax(72px,1fr) auto}.wm\\\\:grid-rows-\\\\[0fr\\\\]{grid-template-rows:0fr}.wm\\\\:grid-rows-\\\\[1fr\\\\]{grid-template-rows:1fr}.wm\\\\:flex-col{flex-direction:column}.wm\\\\:flex-wrap{flex-wrap:wrap}.wm\\\\:content-start{align-content:flex-start}.wm\\\\:items-center{align-items:center}.wm\\\\:items-end{align-items:flex-end}.wm\\\\:items-start{align-items:flex-start}.wm\\\\:justify-between{justify-content:space-between}.wm\\\\:justify-center{justify-content:center}.wm\\\\:justify-end{justify-content:flex-end}.wm\\\\:justify-start{justify-content:flex-start}.wm\\\\:justify-items-end{justify-items:end}.wm\\\\:gap-1{gap:calc(var(--wm-spacing)*1)}.wm\\\\:gap-1\\\\.5{gap:calc(var(--wm-spacing)*1.5)}.wm\\\\:gap-2{gap:calc(var(--wm-spacing)*2)}.wm\\\\:gap-2\\\\.5{gap:calc(var(--wm-spacing)*2.5)}.wm\\\\:gap-3{gap:calc(var(--wm-spacing)*3)}.wm\\\\:gap-4{gap:calc(var(--wm-spacing)*4)}:where(.wm\\\\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-2\\\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.wm\\\\:gap-y-2{row-gap:calc(var(--wm-spacing)*2)}.wm\\\\:self-center{align-self:center}.wm\\\\:self-end{align-self:flex-end}.wm\\\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.wm\\\\:overflow-auto{overflow:auto}.wm\\\\:overflow-hidden{overflow:hidden}.wm\\\\:overflow-visible{overflow:visible}.wm\\\\:overflow-x-auto{overflow-x:auto}.wm\\\\:overflow-x-hidden{overflow-x:hidden}.wm\\\\:overflow-y-auto{overflow-y:auto}.wm\\\\:overflow-y-scroll{overflow-y:scroll}.wm\\\\:scroll-smooth{scroll-behavior:smooth}.wm\\\\:rounded{border-radius:.25rem}.wm\\\\:rounded-2xl{border-radius:var(--wm-radius-2xl)}.wm\\\\:rounded-full{border-radius:3.40282e38px}.wm\\\\:rounded-lg{border-radius:var(--wm-radius-lg)}.wm\\\\:rounded-md{border-radius:var(--wm-radius-md)}.wm\\\\:rounded-sm{border-radius:var(--wm-radius-sm)}.wm\\\\:rounded-xl{border-radius:var(--wm-radius-xl)}.wm\\\\:rounded-t-lg{border-top-left-radius:var(--wm-radius-lg);border-top-right-radius:var(--wm-radius-lg)}.wm\\\\:rounded-t-none\\\\!{border-top-left-radius:0!important;border-top-right-radius:0!important}.wm\\\\:rounded-b-lg{border-bottom-right-radius:var(--wm-radius-lg);border-bottom-left-radius:var(--wm-radius-lg)}.wm\\\\:border{border-style:var(--tw-border-style);border-width:1px}.wm\\\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.wm\\\\:border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.wm\\\\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.wm\\\\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.wm\\\\:border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.wm\\\\:border-dotted{--tw-border-style:dotted;border-style:dotted}.wm\\\\:border-amber-500\\\\/30{border-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-amber-500\\\\/30{border-color:color-mix(in oklab,var(--wm-color-amber-500)30%,transparent)}}.wm\\\\:border-amber-500\\\\/50{border-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-amber-500\\\\/50{border-color:color-mix(in oklab,var(--wm-color-amber-500)50%,transparent)}}.wm\\\\:border-blue-500\\\\/20{border-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-blue-500\\\\/20{border-color:color-mix(in oklab,var(--wm-color-blue-500)20%,transparent)}}.wm\\\\:border-blue-500\\\\/30{border-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-blue-500\\\\/30{border-color:color-mix(in oklab,var(--wm-color-blue-500)30%,transparent)}}.wm\\\\:border-border,.wm\\\\:border-border\\\\/50{border-color:var(--wm-color-border)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-border\\\\/50{border-color:color-mix(in oklab,var(--wm-color-border)50%,transparent)}}.wm\\\\:border-composer-border{border-color:var(--wm-composer-border)}.wm\\\\:border-destructive,.wm\\\\:border-destructive\\\\/20{border-color:var(--wm-color-destructive)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-destructive\\\\/20{border-color:color-mix(in oklab,var(--wm-color-destructive)20%,transparent)}}.wm\\\\:border-muted-foreground\\\\/20{border-color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-muted-foreground\\\\/20{border-color:color-mix(in oklab,var(--wm-color-muted-foreground)20%,transparent)}}.wm\\\\:border-orange-500\\\\/20{border-color:var(--wm-color-orange-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-orange-500\\\\/20{border-color:color-mix(in oklab,var(--wm-color-orange-500)20%,transparent)}}.wm\\\\:border-primary\\\\/50{border-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-primary\\\\/50{border-color:color-mix(in oklab,var(--wm-color-primary)50%,transparent)}}.wm\\\\:border-white\\\\/5{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/5{border-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:border-white\\\\/8{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/8{border-color:color-mix(in oklab,var(--wm-color-white)8%,transparent)}}.wm\\\\:border-white\\\\/10{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/10{border-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:border-white\\\\/20{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/20{border-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:border-zinc-200,.wm\\\\:border-zinc-200\\\\/80{border-color:var(--wm-color-zinc-200)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-zinc-200\\\\/80{border-color:color-mix(in oklab,var(--wm-color-zinc-200)80%,transparent)}}.wm\\\\:border-zinc-600{border-color:var(--wm-color-zinc-600)}.wm\\\\:bg-\\\\[color-mix\\\\(in_oklab\\\\,rgb\\\\(var\\\\(--background\\\\)\\\\)_20\\\\%\\\\,transparent\\\\)\\\\]{background-color:rgb(var(--background))}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-\\\\[color-mix\\\\(in_oklab\\\\,rgb\\\\(var\\\\(--background\\\\)\\\\)_20\\\\%\\\\,transparent\\\\)\\\\]{background-color:color-mix(in oklab,rgb(var(--background))20%,transparent)}}.wm\\\\:bg-amber-500,.wm\\\\:bg-amber-500\\\\/10{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-amber-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-amber-500)10%,transparent)}}.wm\\\\:bg-amber-500\\\\/20{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-amber-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-amber-500)20%,transparent)}}.wm\\\\:bg-background,.wm\\\\:bg-background\\\\/80{background-color:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-background\\\\/80{background-color:color-mix(in oklab,var(--wm-color-background)80%,transparent)}}.wm\\\\:bg-black\\\\/30{background-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-black\\\\/30{background-color:color-mix(in oklab,var(--wm-color-black)30%,transparent)}}.wm\\\\:bg-blue-400{background-color:var(--wm-color-blue-400)}.wm\\\\:bg-blue-500,.wm\\\\:bg-blue-500\\\\/10{background-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-blue-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-blue-500)10%,transparent)}}.wm\\\\:bg-code-bg{background-color:var(--wm-code-bg)}.wm\\\\:bg-code-header-bg{background-color:var(--wm-code-header-bg)}.wm\\\\:bg-composer-bg{background-color:var(--wm-composer-bg)}.wm\\\\:bg-destructive,.wm\\\\:bg-destructive\\\\/10{background-color:var(--wm-color-destructive)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-destructive\\\\/10{background-color:color-mix(in oklab,var(--wm-color-destructive)10%,transparent)}}.wm\\\\:bg-green-400,.wm\\\\:bg-green-400\\\\/60{background-color:var(--wm-color-green-400)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-400\\\\/60{background-color:color-mix(in oklab,var(--wm-color-green-400)60%,transparent)}}.wm\\\\:bg-green-500,.wm\\\\:bg-green-500\\\\/10{background-color:var(--wm-color-green-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-green-500)10%,transparent)}}.wm\\\\:bg-green-500\\\\/20{background-color:var(--wm-color-green-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-green-500)20%,transparent)}}.wm\\\\:bg-muted{background-color:var(--wm-color-muted)}.wm\\\\:bg-muted-foreground\\\\/40{background-color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted-foreground\\\\/40{background-color:color-mix(in oklab,var(--wm-color-muted-foreground)40%,transparent)}}.wm\\\\:bg-muted\\\\/40{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted\\\\/40{background-color:color-mix(in oklab,var(--wm-color-muted)40%,transparent)}}.wm\\\\:bg-muted\\\\/50{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted\\\\/50{background-color:color-mix(in oklab,var(--wm-color-muted)50%,transparent)}}.wm\\\\:bg-orange-500\\\\/10{background-color:var(--wm-color-orange-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-orange-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-orange-500)10%,transparent)}}.wm\\\\:bg-primary,.wm\\\\:bg-primary\\\\/10{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-primary\\\\/10{background-color:color-mix(in oklab,var(--wm-color-primary)10%,transparent)}}.wm\\\\:bg-primary\\\\/90{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-primary\\\\/90{background-color:color-mix(in oklab,var(--wm-color-primary)90%,transparent)}}.wm\\\\:bg-red-500,.wm\\\\:bg-red-500\\\\/10{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-red-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-red-500)10%,transparent)}}.wm\\\\:bg-red-500\\\\/20{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-red-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-red-500)20%,transparent)}}.wm\\\\:bg-secondary{background-color:var(--wm-color-secondary)}.wm\\\\:bg-transparent{background-color:#0000}.wm\\\\:bg-user-bubble-bg{background-color:var(--wm-user-bubble-bg)}.wm\\\\:bg-white,.wm\\\\:bg-white\\\\/5{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/5{background-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:bg-white\\\\/8{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/8{background-color:color-mix(in oklab,var(--wm-color-white)8%,transparent)}}.wm\\\\:bg-white\\\\/10{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/10{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:bg-white\\\\/20{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/20{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:bg-white\\\\/60{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/60{background-color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:bg-white\\\\/90{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/90{background-color:color-mix(in oklab,var(--wm-color-white)90%,transparent)}}.wm\\\\:bg-zinc-100{background-color:var(--wm-color-zinc-100)}.wm\\\\:bg-zinc-700\\\\/50{background-color:var(--wm-color-zinc-700)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-zinc-700\\\\/50{background-color:color-mix(in oklab,var(--wm-color-zinc-700)50%,transparent)}}.wm\\\\:fill-current{fill:currentColor}.wm\\\\:stroke-\\\\[1\\\\.5px\\\\]{stroke-width:1.5px}.wm\\\\:p-0{padding:calc(var(--wm-spacing)*0)}.wm\\\\:p-1{padding:calc(var(--wm-spacing)*1)}.wm\\\\:p-1\\\\.5{padding:calc(var(--wm-spacing)*1.5)}.wm\\\\:p-2{padding:calc(var(--wm-spacing)*2)}.wm\\\\:p-3{padding:calc(var(--wm-spacing)*3)}.wm\\\\:p-4{padding:calc(var(--wm-spacing)*4)}.wm\\\\:px-1{padding-inline:calc(var(--wm-spacing)*1)}.wm\\\\:px-1\\\\.5{padding-inline:calc(var(--wm-spacing)*1.5)}.wm\\\\:px-2{padding-inline:calc(var(--wm-spacing)*2)}.wm\\\\:px-2\\\\.5{padding-inline:calc(var(--wm-spacing)*2.5)}.wm\\\\:px-3{padding-inline:calc(var(--wm-spacing)*3)}.wm\\\\:px-4{padding-inline:calc(var(--wm-spacing)*4)}.wm\\\\:px-6{padding-inline:calc(var(--wm-spacing)*6)}.wm\\\\:py-0\\\\.5{padding-block:calc(var(--wm-spacing)*.5)}.wm\\\\:py-1{padding-block:calc(var(--wm-spacing)*1)}.wm\\\\:py-1\\\\.5{padding-block:calc(var(--wm-spacing)*1.5)}.wm\\\\:py-2{padding-block:calc(var(--wm-spacing)*2)}.wm\\\\:py-2\\\\.5{padding-block:calc(var(--wm-spacing)*2.5)}.wm\\\\:py-3{padding-block:calc(var(--wm-spacing)*3)}.wm\\\\:py-4{padding-block:calc(var(--wm-spacing)*4)}.wm\\\\:py-8{padding-block:calc(var(--wm-spacing)*8)}.wm\\\\:pt-1\\\\.5{padding-top:calc(var(--wm-spacing)*1.5)}.wm\\\\:pt-2{padding-top:calc(var(--wm-spacing)*2)}.wm\\\\:pt-3{padding-top:calc(var(--wm-spacing)*3)}.wm\\\\:pt-14{padding-top:calc(var(--wm-spacing)*14)}.wm\\\\:pr-2{padding-right:calc(var(--wm-spacing)*2)}.wm\\\\:pb-1{padding-bottom:calc(var(--wm-spacing)*1)}.wm\\\\:pb-3{padding-bottom:calc(var(--wm-spacing)*3)}.wm\\\\:pb-4{padding-bottom:calc(var(--wm-spacing)*4)}.wm\\\\:pl-3{padding-left:calc(var(--wm-spacing)*3)}.wm\\\\:pl-6{padding-left:calc(var(--wm-spacing)*6)}.wm\\\\:text-center{text-align:center}.wm\\\\:text-left{text-align:left}.wm\\\\:text-start{text-align:start}.wm\\\\:align-middle{vertical-align:middle}.wm\\\\:font-mono{font-family:var(--wm-font-mono)}.wm\\\\:text-2xl{font-size:var(--wm-text-2xl);line-height:var(--tw-leading,var(--wm-text-2xl--line-height))}.wm\\\\:text-base{font-size:var(--wm-text-base);line-height:var(--tw-leading,var(--wm-text-base--line-height))}.wm\\\\:text-lg{font-size:var(--wm-text-lg);line-height:var(--tw-leading,var(--wm-text-lg--line-height))}.wm\\\\:text-sm{font-size:var(--wm-text-sm);line-height:var(--tw-leading,var(--wm-text-sm--line-height))}.wm\\\\:text-xl{font-size:var(--wm-text-xl);line-height:var(--tw-leading,var(--wm-text-xl--line-height))}.wm\\\\:text-xs{font-size:var(--wm-text-xs);line-height:var(--tw-leading,var(--wm-text-xs--line-height))}.wm\\\\:text-\\\\[10px\\\\]{font-size:10px}.wm\\\\:text-\\\\[11px\\\\]{font-size:11px}.wm\\\\:text-\\\\[15px\\\\]{font-size:15px}.wm\\\\:leading-7{--tw-leading:calc(var(--wm-spacing)*7);line-height:calc(var(--wm-spacing)*7)}.wm\\\\:leading-\\\\[21px\\\\]{--tw-leading:21px;line-height:21px}.wm\\\\:leading-normal{--tw-leading:var(--wm-leading-normal);line-height:var(--wm-leading-normal)}.wm\\\\:leading-relaxed{--tw-leading:var(--wm-leading-relaxed);line-height:var(--wm-leading-relaxed)}.wm\\\\:font-bold{--tw-font-weight:var(--wm-font-weight-bold);font-weight:var(--wm-font-weight-bold)}.wm\\\\:font-extrabold{--tw-font-weight:var(--wm-font-weight-extrabold);font-weight:var(--wm-font-weight-extrabold)}.wm\\\\:font-medium{--tw-font-weight:var(--wm-font-weight-medium);font-weight:var(--wm-font-weight-medium)}.wm\\\\:font-semibold{--tw-font-weight:var(--wm-font-weight-semibold);font-weight:var(--wm-font-weight-semibold)}.wm\\\\:tracking-tight{--tw-tracking:var(--wm-tracking-tight);letter-spacing:var(--wm-tracking-tight)}.wm\\\\:tracking-wide{--tw-tracking:var(--wm-tracking-wide);letter-spacing:var(--wm-tracking-wide)}.wm\\\\:wrap-break-word{overflow-wrap:break-word}.wm\\\\:break-all{word-break:break-all}.wm\\\\:whitespace-nowrap{white-space:nowrap}.wm\\\\:whitespace-pre-wrap{white-space:pre-wrap}.wm\\\\:text-amber-400{color:var(--wm-color-amber-400)}.wm\\\\:text-amber-500{color:var(--wm-color-amber-500)}.wm\\\\:text-assistant-bubble-text{color:var(--wm-assistant-bubble-text)}.wm\\\\:text-blue-400,.wm\\\\:text-blue-400\\\\/60{color:var(--wm-color-blue-400)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-blue-400\\\\/60{color:color-mix(in oklab,var(--wm-color-blue-400)60%,transparent)}}.wm\\\\:text-blue-600{color:var(--wm-color-blue-600)}.wm\\\\:text-code-text{color:var(--wm-code-text)}.wm\\\\:text-composer-text{color:var(--wm-composer-text)}.wm\\\\:text-destructive{color:var(--wm-color-destructive)}.wm\\\\:text-foreground,.wm\\\\:text-foreground\\\\/70{color:var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-foreground\\\\/70{color:color-mix(in oklab,var(--wm-color-foreground)70%,transparent)}}.wm\\\\:text-foreground\\\\/80{color:var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-foreground\\\\/80{color:color-mix(in oklab,var(--wm-color-foreground)80%,transparent)}}.wm\\\\:text-green-400{color:var(--wm-color-green-400)}.wm\\\\:text-green-500{color:var(--wm-color-green-500)}.wm\\\\:text-muted-foreground,.wm\\\\:text-muted-foreground\\\\/70{color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-muted-foreground\\\\/70{color:color-mix(in oklab,var(--wm-color-muted-foreground)70%,transparent)}}.wm\\\\:text-orange-600{color:var(--wm-color-orange-600)}.wm\\\\:text-primary{color:var(--wm-color-primary)}.wm\\\\:text-primary-foreground{color:var(--wm-color-primary-foreground)}.wm\\\\:text-primary\\\\/80{color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-primary\\\\/80{color:color-mix(in oklab,var(--wm-color-primary)80%,transparent)}}.wm\\\\:text-red-300{color:var(--wm-color-red-300)}.wm\\\\:text-red-400{color:var(--wm-color-red-400)}.wm\\\\:text-secondary-foreground{color:var(--wm-color-secondary-foreground)}.wm\\\\:text-slate-900{color:var(--wm-color-slate-900)}.wm\\\\:text-user-bubble-text{color:var(--wm-user-bubble-text)}.wm\\\\:text-white,.wm\\\\:text-white\\\\/30{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/30{color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:text-white\\\\/40{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/40{color:color-mix(in oklab,var(--wm-color-white)40%,transparent)}}.wm\\\\:text-white\\\\/50{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/50{color:color-mix(in oklab,var(--wm-color-white)50%,transparent)}}.wm\\\\:text-white\\\\/60{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/60{color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:text-white\\\\/70{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/70{color:color-mix(in oklab,var(--wm-color-white)70%,transparent)}}.wm\\\\:text-white\\\\/80{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/80{color:color-mix(in oklab,var(--wm-color-white)80%,transparent)}}.wm\\\\:text-white\\\\/90{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/90{color:color-mix(in oklab,var(--wm-color-white)90%,transparent)}}.wm\\\\:text-zinc-400{color:var(--wm-color-zinc-400)}.wm\\\\:text-zinc-700{color:var(--wm-color-zinc-700)}.wm\\\\:lowercase{text-transform:lowercase}.wm\\\\:uppercase{text-transform:uppercase}.wm\\\\:italic{font-style:italic}.wm\\\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.wm\\\\:underline{text-decoration-line:underline}.wm\\\\:underline-offset-4{text-underline-offset:4px}.wm\\\\:opacity-0{opacity:0}.wm\\\\:opacity-50{opacity:.5}.wm\\\\:opacity-90{opacity:.9}.wm\\\\:opacity-100{opacity:1}.wm\\\\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-black\\\\/10{--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:shadow-black\\\\/10{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)10%,transparent)var(--tw-shadow-alpha),transparent)}}.wm\\\\:shadow-black\\\\/20{--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:shadow-black\\\\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)20%,transparent)var(--tw-shadow-alpha),transparent)}}.wm\\\\:backdrop-blur-sm{--tw-backdrop-blur:blur(var(--wm-blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.wm\\\\:transition-\\\\[grid-template-rows\\\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:delay-75{transition-delay:75ms}.wm\\\\:duration-\\\\(--animation-duration\\\\){--tw-duration:var(--animation-duration);transition-duration:var(--animation-duration)}.wm\\\\:duration-100{--tw-duration:.1s;transition-duration:.1s}.wm\\\\:duration-150{--tw-duration:.15s;transition-duration:.15s}.wm\\\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.wm\\\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.wm\\\\:ease-out{--tw-ease:var(--wm-ease-out);transition-timing-function:var(--wm-ease-out)}.wm\\\\:will-change-transform{will-change:transform}.wm\\\\:delay-75{--tw-animation-delay:75ms;animation-delay:75ms}.wm\\\\:fill-mode-both{--tw-animation-fill-mode:both;animation-fill-mode:both}.wm\\\\:outline-none{--tw-outline-style:none;outline-style:none}.wm\\\\:fade-in{--tw-enter-opacity:0}.wm\\\\:slide-in-from-bottom-1{--tw-enter-translate-y:calc(1*var(--spacing))}.wm\\\\:slide-in-from-bottom-2{--tw-enter-translate-y:calc(2*var(--spacing))}@media (hover:hover){.wm\\\\:group-hover\\\\:opacity-100:is(:where(.wm\\\\:group):hover *){opacity:1}}.wm\\\\:placeholder\\\\:text-white\\\\/40::placeholder{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:placeholder\\\\:text-white\\\\/40::placeholder{color:color-mix(in oklab,var(--wm-color-white)40%,transparent)}}.wm\\\\:first\\\\:mt-0:first-child{margin-top:calc(var(--wm-spacing)*0)}.wm\\\\:last\\\\:mb-0:last-child{margin-bottom:calc(var(--wm-spacing)*0)}.wm\\\\:focus-within\\\\:border-white\\\\/15:focus-within{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-within\\\\:border-white\\\\/15:focus-within{border-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:focus-within\\\\:bg-white\\\\/10:focus-within{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-within\\\\:bg-white\\\\/10:focus-within{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}@media (hover:hover){.wm\\\\:hover\\\\:border-amber-500:hover{border-color:var(--wm-color-amber-500)}.wm\\\\:hover\\\\:border-red-500\\\\/50:hover{border-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:border-red-500\\\\/50:hover{border-color:color-mix(in oklab,var(--wm-color-red-500)50%,transparent)}}.wm\\\\:hover\\\\:border-white\\\\/20:hover{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:border-white\\\\/20:hover{border-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:hover\\\\:bg-amber-500\\\\/20:hover{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-amber-500\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-amber-500)20%,transparent)}}.wm\\\\:hover\\\\:bg-amber-500\\\\/30:hover{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-amber-500\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-amber-500)30%,transparent)}}.wm\\\\:hover\\\\:bg-muted:hover,.wm\\\\:hover\\\\:bg-muted\\\\/50:hover{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-muted\\\\/50:hover{background-color:color-mix(in oklab,var(--wm-color-muted)50%,transparent)}}.wm\\\\:hover\\\\:bg-primary\\\\/90:hover{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-primary\\\\/90:hover{background-color:color-mix(in oklab,var(--wm-color-primary)90%,transparent)}}.wm\\\\:hover\\\\:bg-red-500\\\\/20:hover{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-red-500\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-red-500)20%,transparent)}}.wm\\\\:hover\\\\:bg-red-500\\\\/30:hover{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-red-500\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-red-500)30%,transparent)}}.wm\\\\:hover\\\\:bg-white:hover,.wm\\\\:hover\\\\:bg-white\\\\/5:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/5:hover{background-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/10:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/10:hover{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/15:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/15:hover{background-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/20:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/30:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:hover\\\\:bg-zinc-50:hover{background-color:var(--wm-color-zinc-50)}.wm\\\\:hover\\\\:bg-zinc-200:hover{background-color:var(--wm-color-zinc-200)}.wm\\\\:hover\\\\:bg-zinc-700:hover{background-color:var(--wm-color-zinc-700)}.wm\\\\:hover\\\\:text-foreground:hover{color:var(--wm-color-foreground)}.wm\\\\:hover\\\\:text-primary\\\\/80:hover{color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-primary\\\\/80:hover{color:color-mix(in oklab,var(--wm-color-primary)80%,transparent)}}.wm\\\\:hover\\\\:text-red-200:hover{color:var(--wm-color-red-200)}.wm\\\\:hover\\\\:text-red-300:hover{color:var(--wm-color-red-300)}.wm\\\\:hover\\\\:text-red-400:hover{color:var(--wm-color-red-400)}.wm\\\\:hover\\\\:text-white:hover,.wm\\\\:hover\\\\:text-white\\\\/50:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/50:hover{color:color-mix(in oklab,var(--wm-color-white)50%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/60:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/60:hover{color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/70:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/70:hover{color:color-mix(in oklab,var(--wm-color-white)70%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/80:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/80:hover{color:color-mix(in oklab,var(--wm-color-white)80%,transparent)}}.wm\\\\:hover\\\\:text-zinc-600:hover{color:var(--wm-color-zinc-600)}}.wm\\\\:focus\\\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.wm\\\\:focus-visible\\\\:bg-muted:focus-visible{background-color:var(--wm-color-muted)}.wm\\\\:focus-visible\\\\:opacity-100:focus-visible{opacity:1}.wm\\\\:focus-visible\\\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:focus-visible\\\\:ring-blue-500:focus-visible{--tw-ring-color:var(--wm-color-blue-500)}.wm\\\\:focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:focus-visible\\\\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.wm\\\\:focus-visible\\\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.wm\\\\:focus-visible\\\\:ring-offset-transparent:focus-visible{--tw-ring-offset-color:transparent}.wm\\\\:focus-visible\\\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.wm\\\\:active\\\\:scale-\\\\[0\\\\.98\\\\]:active{scale:.98}.wm\\\\:active\\\\:cursor-grabbing:active{cursor:grabbing}.wm\\\\:active\\\\:bg-white\\\\/15:active{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:active\\\\:bg-white\\\\/15:active{background-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:active\\\\:bg-white\\\\/20:active{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:active\\\\:bg-white\\\\/20:active{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:disabled\\\\:invisible:disabled{visibility:hidden}.wm\\\\:disabled\\\\:cursor-not-allowed:disabled{cursor:not-allowed}.wm\\\\:disabled\\\\:opacity-40:disabled{opacity:.4}.wm\\\\:data-\\\\[active\\\\=true\\\\]\\\\:bg-muted[data-active=true]{background-color:var(--wm-color-muted)}.wm\\\\:nth-\\\\[n\\\\+3\\\\]\\\\:hidden:nth-child(n+3){display:none}@media (min-width:40rem){.wm\\\\:sm\\\\:flex{display:flex}.wm\\\\:sm\\\\:h-3{height:calc(var(--wm-spacing)*3)}.wm\\\\:sm\\\\:h-3\\\\.5{height:calc(var(--wm-spacing)*3.5)}.wm\\\\:sm\\\\:h-4{height:calc(var(--wm-spacing)*4)}.wm\\\\:sm\\\\:h-7{height:calc(var(--wm-spacing)*7)}.wm\\\\:sm\\\\:max-h-24{max-height:calc(var(--wm-spacing)*24)}.wm\\\\:sm\\\\:max-h-32{max-height:calc(var(--wm-spacing)*32)}.wm\\\\:sm\\\\:max-h-48{max-height:calc(var(--wm-spacing)*48)}.wm\\\\:sm\\\\:w-3{width:calc(var(--wm-spacing)*3)}.wm\\\\:sm\\\\:w-3\\\\.5{width:calc(var(--wm-spacing)*3.5)}.wm\\\\:sm\\\\:w-4{width:calc(var(--wm-spacing)*4)}.wm\\\\:sm\\\\:w-7{width:calc(var(--wm-spacing)*7)}.wm\\\\:sm\\\\:max-w-16{max-width:calc(var(--wm-spacing)*16)}.wm\\\\:sm\\\\:max-w-24{max-width:calc(var(--wm-spacing)*24)}.wm\\\\:sm\\\\:gap-1{gap:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:gap-1\\\\.5{gap:calc(var(--wm-spacing)*1.5)}.wm\\\\:sm\\\\:p-1{padding:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:p-1\\\\.5{padding:calc(var(--wm-spacing)*1.5)}.wm\\\\:sm\\\\:px-2{padding-inline:calc(var(--wm-spacing)*2)}.wm\\\\:sm\\\\:py-1{padding-block:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:opacity-0{opacity:0}@media (hover:hover){.wm\\\\:sm\\\\:group-hover\\\\:opacity-100:is(:where(.wm\\\\:group):hover *){opacity:1}}}.wm\\\\:dark\\\\:border-zinc-600:is(.dark *){border-color:var(--wm-color-zinc-600)}.wm\\\\:dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:var(--wm-color-zinc-700)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:color-mix(in oklab,var(--wm-color-zinc-700)80%,transparent)}}.wm\\\\:dark\\\\:bg-zinc-700:is(.dark *){background-color:var(--wm-color-zinc-700)}.wm\\\\:dark\\\\:bg-zinc-800:is(.dark *){background-color:var(--wm-color-zinc-800)}.wm\\\\:dark\\\\:text-zinc-200:is(.dark *){color:var(--wm-color-zinc-200)}.wm\\\\:dark\\\\:text-zinc-400:is(.dark *){color:var(--wm-color-zinc-400)}.wm\\\\:dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)30%,transparent)var(--tw-shadow-alpha),transparent)}}@media (hover:hover){.wm\\\\:dark\\\\:hover\\\\:bg-zinc-600:is(.dark *):hover{background-color:var(--wm-color-zinc-600)}.wm\\\\:dark\\\\:hover\\\\:bg-zinc-700:is(.dark *):hover{background-color:var(--wm-color-zinc-700)}.wm\\\\:dark\\\\:hover\\\\:text-zinc-200:is(.dark *):hover{color:var(--wm-color-zinc-200)}}.wm\\\\:\\\\[\\\\&\\\\>li\\\\]\\\\:mt-0\\\\.5>li{margin-top:calc(var(--wm-spacing)*.5)}}@property --tw-animation-delay{syntax:\\\"*\\\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\\\"*\\\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\\\"*\\\";inherits:false}@property --tw-animation-fill-mode{syntax:\\\"*\\\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\\\"*\\\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\\\"*\\\";inherits:false;initial-value:0}@keyframes aui-pulse{50%{opacity:.5}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;animation:2s cubic-bezier(.4,0,.6,1) infinite aui-pulse}@keyframes wm-shimmer{0%{transform:translate(-100%)}to{transform:translate(200%)}}@keyframes wm-subtle-pulse{0%,to{opacity:1}50%{opacity:.85}}@keyframes wm-slide-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes wm-fade-in-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes wm-gradient-shift{0%,to{transform:translate(0%)translateY(0%)}25%{transform:translate(100%)translateY(100%)}50%{transform:translate(100%)translateY(0%)}75%{transform:translate(0%)translateY(100%)}}@keyframes wm-float{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(-30px)translate(20px)}66%{transform:translateY(20px)translate(-20px)}}@keyframes wm-float-delayed{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(30px)translate(-30px)}66%{transform:translateY(-20px)translate(20px)}}@keyframes wm-border-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes wm-pulse-success{0%,to{box-shadow:0 0 0 0 color-mix(in oklch,var(--wm-color-success),transparent 60%)}50%{box-shadow:0 0 0 8px #0000}}@keyframes wm-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}@keyframes wm-pulse-glow{0%,to{box-shadow:0 0 20px color-mix(in oklch,var(--wm-color-primary),transparent 90%)}50%{box-shadow:0 0 30px color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}@keyframes wm-gradient-x{0%,to{background-position:0%}50%{background-position:100%}}@keyframes wm-glass-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes wm-aui-pulse{50%{opacity:.5}}.wm-no-scrollbar::-webkit-scrollbar{display:none}.wm-no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@media (hover:none){.wm-scrollbar-thin{scrollbar-width:none}.wm-scrollbar-thin::-webkit-scrollbar{display:none}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{font-family:var(--wm-font-sans);--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;animation:2s cubic-bezier(.4,0,.6,1) infinite wm-aui-pulse}@property --tw-border-spacing-x{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-translate-x{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:\\\"*\\\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\\\"*\\\";inherits:false;initial-value:solid}@property --tw-leading{syntax:\\\"*\\\";inherits:false}@property --tw-font-weight{syntax:\\\"*\\\";inherits:false}@property --tw-tracking{syntax:\\\"*\\\";inherits:false}@property --tw-ordinal{syntax:\\\"*\\\";inherits:false}@property --tw-slashed-zero{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-figure{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-spacing{syntax:\\\"*\\\";inherits:false}@property --tw-numeric-fraction{syntax:\\\"*\\\";inherits:false}@property --tw-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\\\"*\\\";inherits:false}@property --tw-shadow-alpha{syntax:\\\"<percentage>\\\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\\\"*\\\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\\\"<percentage>\\\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\\\"*\\\";inherits:false}@property --tw-ring-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\\\"*\\\";inherits:false}@property --tw-inset-ring-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\\\"*\\\";inherits:false}@property --tw-ring-offset-width{syntax:\\\"<length>\\\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\\\"*\\\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\\\"*\\\";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-brightness{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-contrast{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-grayscale{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-hue-rotate{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-invert{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-opacity{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-saturate{syntax:\\\"*\\\";inherits:false}@property --tw-backdrop-sepia{syntax:\\\"*\\\";inherits:false}@property --tw-duration{syntax:\\\"*\\\";inherits:false}@property --tw-ease{syntax:\\\"*\\\";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}\";\n\n/**\n * CSS styles optimized for shadow DOM injection.\n * Use this with the ShadowRoot component for complete style isolation.\n *\n * Differences from WEBMCP_STYLES:\n * - No body styles (shadow DOM doesn't have a body element)\n * - No @property declarations (not supported in shadow DOM)\n * - Uses :host selector for theming (in addition to :root)\n */\nexport const WEBMCP_SHADOW_STYLES = \"/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--wm-font-sans:var(--wm-font-sans);--wm-font-mono:var(--wm-font-mono);--wm-color-red-200:oklch(88.5% .062 18.334);--wm-color-red-300:oklch(80.8% .114 19.571);--wm-color-red-400:oklch(70.4% .191 22.216);--wm-color-red-500:oklch(63.7% .237 25.331);--wm-color-orange-500:oklch(70.5% .213 47.604);--wm-color-orange-600:oklch(64.6% .222 41.116);--wm-color-amber-400:oklch(82.8% .189 84.429);--wm-color-amber-500:oklch(76.9% .188 70.08);--wm-color-green-400:oklch(79.2% .209 151.711);--wm-color-green-500:oklch(72.3% .219 149.579);--wm-color-blue-400:oklch(70.7% .165 254.624);--wm-color-blue-500:oklch(62.3% .214 259.815);--wm-color-blue-600:oklch(54.6% .245 262.881);--wm-color-slate-900:oklch(20.8% .042 265.755);--wm-color-zinc-50:oklch(98.5% 0 0);--wm-color-zinc-100:oklch(96.7% .001 286.375);--wm-color-zinc-200:oklch(92% .004 286.32);--wm-color-zinc-400:oklch(70.5% .015 286.067);--wm-color-zinc-600:oklch(44.2% .017 285.786);--wm-color-zinc-700:oklch(37% .013 285.805);--wm-color-zinc-800:oklch(27.4% .006 286.033);--wm-color-black:#000;--wm-color-white:#fff;--wm-spacing:.25rem;--wm-container-lg:32rem;--wm-text-xs:.75rem;--wm-text-xs--line-height:calc(1/.75);--wm-text-sm:.875rem;--wm-text-sm--line-height:calc(1.25/.875);--wm-text-base:1rem;--wm-text-base--line-height:calc(1.5/1);--wm-text-lg:1.125rem;--wm-text-lg--line-height:calc(1.75/1.125);--wm-text-xl:1.25rem;--wm-text-xl--line-height:calc(1.75/1.25);--wm-text-2xl:1.5rem;--wm-text-2xl--line-height:calc(2/1.5);--wm-font-weight-medium:500;--wm-font-weight-semibold:600;--wm-font-weight-bold:700;--wm-font-weight-extrabold:800;--wm-tracking-tight:-.025em;--wm-tracking-wide:.025em;--wm-leading-normal:1.5;--wm-leading-relaxed:1.625;--wm-radius-sm:var(--wm-radius-sm);--wm-radius-md:var(--wm-radius-md);--wm-radius-lg:var(--wm-radius-lg);--wm-radius-xl:var(--wm-radius-xl);--wm-radius-2xl:1rem;--wm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--wm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--wm-ease-out:cubic-bezier(0,0,.2,1);--wm-animate-spin:spin 1s linear infinite;--wm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--wm-blur-sm:8px;--wm-blur-md:12px;--wm-blur-lg:16px;--wm-default-transition-duration:.15s;--wm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--wm-default-font-family:var(--wm-font-sans);--wm-default-mono-font-family:var(--wm-font-mono);--wm-color-background:var(--wm-color-background);--wm-color-foreground:var(--wm-color-foreground);--wm-color-card:var(--wm-color-card);--wm-color-card-foreground:var(--wm-color-card-foreground);--wm-color-popover:var(--wm-color-popover);--wm-color-popover-foreground:var(--wm-color-popover-foreground);--wm-color-primary:var(--wm-color-primary);--wm-color-primary-foreground:var(--wm-color-primary-foreground);--wm-color-secondary:var(--wm-color-secondary);--wm-color-secondary-foreground:var(--wm-color-secondary-foreground);--wm-color-muted:var(--wm-color-muted);--wm-color-muted-foreground:var(--wm-color-muted-foreground);--wm-color-accent:var(--wm-color-accent);--wm-color-accent-foreground:var(--wm-color-accent-foreground);--wm-color-destructive:var(--wm-color-destructive);--wm-color-destructive-foreground:var(--wm-color-destructive-foreground);--wm-color-border:var(--wm-color-border);--wm-color-input:var(--wm-color-input);--wm-color-ring:var(--wm-color-ring);--wm-color-success:var(--wm-color-success);--wm-color-warning:var(--wm-color-warning);--wm-color-error:var(--wm-color-error);--wm-font-size-xs:var(--wm-font-size-xs);--wm-font-size-sm:var(--wm-font-size-sm);--wm-font-size-base:var(--wm-font-size-base);--wm-font-size-lg:var(--wm-font-size-lg)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--wm-default-font-family,ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\");font-feature-settings:var(--wm-default-font-feature-settings,normal);font-variation-settings:var(--wm-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--wm-default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace);font-feature-settings:var(--wm-default-mono-font-feature-settings,normal);font-variation-settings:var(--wm-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:host,:root{--wm-color-background:oklch(100% 0 0);--wm-color-foreground:oklch(14.1% .005 285.823);--wm-color-primary:oklch(21% .006 285.885);--wm-color-primary-foreground:oklch(98.5% 0 0);--wm-color-muted:oklch(96.7% .001 286.375);--wm-color-muted-foreground:oklch(55.2% .016 285.938);--wm-color-border:oklch(92% .004 286.32);--wm-color-success:oklch(70% .2 145);--wm-color-warning:oklch(75% .15 85);--wm-color-error:oklch(65% .25 25);--wm-color-card:var(--wm-color-background);--wm-color-card-foreground:var(--wm-color-foreground);--wm-color-popover:var(--wm-color-background);--wm-color-popover-foreground:var(--wm-color-foreground);--wm-color-secondary:var(--wm-color-muted);--wm-color-secondary-foreground:var(--wm-color-foreground);--wm-color-accent:var(--wm-color-muted);--wm-color-accent-foreground:var(--wm-color-foreground);--wm-color-destructive:var(--wm-color-error);--wm-color-destructive-foreground:var(--wm-color-primary-foreground);--wm-color-input:var(--wm-color-border);--wm-color-ring:var(--wm-color-muted-foreground);--wm-user-bubble-bg:var(--wm-color-muted);--wm-user-bubble-text:var(--wm-color-foreground);--wm-assistant-bubble-bg:transparent;--wm-assistant-bubble-text:var(--wm-color-foreground);--wm-composer-bg:var(--wm-color-background);--wm-composer-border:var(--wm-color-input);--wm-composer-text:var(--wm-color-foreground);--wm-composer-placeholder:var(--wm-color-muted-foreground);--wm-composer-button-bg:var(--wm-color-primary);--wm-composer-button-text:var(--wm-color-primary-foreground);--wm-tool-bg:var(--wm-color-muted);--wm-tool-border:var(--wm-color-border);--wm-tool-text:var(--wm-color-foreground);--wm-tool-header-bg:var(--wm-color-muted);--wm-tool-approve-bg:var(--wm-color-primary);--wm-tool-approve-text:var(--wm-color-primary-foreground);--wm-tool-deny-bg:transparent;--wm-tool-deny-text:var(--wm-color-muted-foreground);--wm-code-bg:oklch(14.1% .005 285.823);--wm-code-text:oklch(98.5% 0 0);--wm-code-header-bg:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){:host,:root{--wm-code-header-bg:color-mix(in oklch,var(--wm-color-muted-foreground),transparent 85%)}}:host,:root{--wm-radius:.75rem;--wm-radius-sm:calc(var(--wm-radius) - 4px);--wm-radius-md:calc(var(--wm-radius) - 2px);--wm-radius-lg:var(--wm-radius);--wm-radius-xl:calc(var(--wm-radius) + 4px);--wm-radius-full:9999px;--wm-spacing-unit:.25rem;--wm-font-sans:ui-sans-serif,system-ui,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";--wm-font-mono:ui-monospace,SFMono-Regular,\\\"SF Mono\\\",Menlo,Consolas,monospace;--wm-font-size-xs:.6875rem;--wm-font-size-sm:.75rem;--wm-font-size-base:.875rem;--wm-font-size-lg:1rem;--wm-duration-fast:.15s;--wm-duration-normal:.25s;--wm-duration-slow:.4s;--wm-easing-default:cubic-bezier(.4,0,.2,1);--wm-easing-spring:cubic-bezier(.34,1.56,.64,1);--wm-z-base:0;--wm-z-content:10;--wm-z-overlay:50;--wm-z-max:2147480000;--wm-shadow-sm:0 1px 2px #0000000d;--wm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--wm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--wm-blur-sm:8px;--wm-blur-md:12px;--wm-blur-lg:20px}:host(.dark),.dark{--wm-color-background:oklch(14.1% .005 285.823);--wm-color-foreground:oklch(98.5% 0 0);--wm-color-primary:oklch(92% .004 286.32);--wm-color-primary-foreground:oklch(21% .006 285.885);--wm-color-muted:oklch(27.4% .006 286.033);--wm-color-muted-foreground:oklch(70.5% .015 286.067);--wm-color-border:oklch(100% 0 0/.1);--wm-color-input:oklch(100% 0 0/.15);--wm-color-ring:oklch(55.2% .016 285.938);--wm-color-success:oklch(75% .18 145);--wm-color-warning:oklch(80% .14 85);--wm-color-error:oklch(70% .22 25)}*{border-color:var(--wm-color-border);outline-color:var(--wm-color-ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklch,var(--wm-color-ring),transparent 50%)}}}@layer components{.wm-animate-fade-in-up{opacity:0;animation:.5s ease-out forwards wm-fade-in-up}.wm-animate-gradient-shift{background-size:200% 200%;animation:20s ease-in-out infinite wm-gradient-shift}.wm-animate-float-slow{animation:20s ease-in-out infinite wm-float}.wm-animate-float-delayed{animation:25s ease-in-out 5s infinite wm-float-delayed}.wm-animate-shimmer{animation:2s linear infinite wm-shimmer}.wm-animate-pulse-success{animation:.6s ease-out wm-pulse-success}.wm-animate-shake{animation:.3s ease-out wm-shake}.wm-animate-pulse-glow{animation:2s ease-in-out infinite wm-pulse-glow}.wm-animate-gradient-x{animation:8s ease-in-out infinite wm-gradient-x}.wm-transition-spring{transition:all var(--wm-duration-slow)var(--wm-easing-spring)}.wm-transition-smooth{transition:all var(--wm-duration-normal)var(--wm-easing-default)}.wm-app-shell{z-index:var(--wm-z-base);background-color:var(--wm-color-background);background-image:radial-gradient(80% 60% at -10% -10%,oklch(82% .15 270/.15),#0000),radial-gradient(60% 50% at 110% 10%,oklch(85% .1 220/.12),#0000),radial-gradient(50% 45% at 50% 120%,oklch(95% .02 250/.08),#0000);position:relative}.dark .wm-app-shell{background-image:radial-gradient(80% 60% at -10% -10%,oklch(55% .14 270/.25),#0000),radial-gradient(60% 50% at 110% 15%,oklch(60% .12 220/.22),#0000),radial-gradient(50% 45% at 50% 120%,oklch(35% .04 250/.16),#0000)}.wm-app-shell:before,.wm-app-shell:after{content:\\\"\\\";pointer-events:none;border-radius:var(--wm-radius-full);filter:blur(32px);opacity:.6;z-index:-1;position:absolute;inset:auto}.wm-app-shell:before{background:radial-gradient(60% 60% at 40% 40%,oklch(80% .12 270/.3),#0000);width:260px;height:260px;top:-60px;left:-80px}.wm-app-shell:after{background:radial-gradient(60% 60% at 60% 60%,oklch(84% .1 220/.25),#0000);width:300px;height:300px;bottom:-80px;right:-60px}.wm-toolbar-surface{border-top:1px solid var(--wm-color-border);background:linear-gradient(to right,var(--wm-color-background),var(--wm-color-background),var(--wm-color-background))}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface{background:linear-gradient(to right,var(--wm-color-background),color-mix(in oklch,var(--wm-color-background),transparent 5%),var(--wm-color-background))}}.wm-toolbar-surface{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md))}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.wm-toolbar-surface{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}}.wm-toolbar-surface-top{border-bottom:1px solid var(--wm-color-border);background:linear-gradient(to right,var(--wm-color-background),var(--wm-color-background),var(--wm-color-background))}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface-top{background:linear-gradient(to right,var(--wm-color-background),color-mix(in oklch,var(--wm-color-background),transparent 5%),var(--wm-color-background))}}.wm-toolbar-surface-top{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md))}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.wm-toolbar-surface-top{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-surface-top{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}}.wm-toolbar-inner{justify-content:space-between;align-items:center;padding:.5rem .75rem;display:flex}.wm-toolbar-card{background:var(--wm-color-card);justify-content:space-between;align-items:center;gap:.5rem;display:flex}@supports (color:color-mix(in lab, red, red)){.wm-toolbar-card{background:color-mix(in oklch,var(--wm-color-card),transparent 60%)}}.wm-toolbar-card{border:1px solid var(--wm-color-border);border-radius:var(--wm-radius-lg);padding:.5rem .75rem}.wm-toolbar-group{align-items:center;gap:.25rem;display:flex}.wm-btn-toolbar-primary{border-radius:var(--wm-radius-lg);background:linear-gradient(to right,var(--wm-color-primary),var(--wm-color-primary));align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;display:flex}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary{background:linear-gradient(to right,color-mix(in oklch,var(--wm-color-primary),transparent 95%),color-mix(in oklch,var(--wm-color-primary),transparent 90%))}}.wm-btn-toolbar-primary{border:1px solid var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary{border:1px solid color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}.wm-btn-toolbar-primary{transition:all var(--wm-duration-fast)}.wm-btn-toolbar-primary:hover{background:linear-gradient(to right,var(--wm-color-primary),var(--wm-color-primary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-primary:hover{background:linear-gradient(to right,color-mix(in oklch,var(--wm-color-primary),transparent 90%),color-mix(in oklch,var(--wm-color-primary),transparent 80%))}}.wm-btn-toolbar-icon-primary{border-radius:var(--wm-radius-full);background:linear-gradient(to bottom right,var(--wm-color-primary),var(--wm-color-primary));width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-primary),transparent 90%),color-mix(in oklch,var(--wm-color-primary),transparent 80%))}}.wm-btn-toolbar-icon-primary{border:1px solid var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary{border:1px solid color-mix(in oklch,var(--wm-color-primary),transparent 70%)}}.wm-btn-toolbar-icon-primary{box-shadow:var(--wm-shadow-sm);transition:all var(--wm-duration-fast)}.wm-btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,var(--wm-color-primary),var(--wm-color-primary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-primary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-primary),transparent 80%),color-mix(in oklch,var(--wm-color-primary),transparent 70%))}}.wm-btn-toolbar-icon-secondary{border-radius:var(--wm-radius-full);background:linear-gradient(to bottom right,var(--wm-color-secondary),var(--wm-color-secondary));width:2rem;height:2rem;padding:0}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-secondary),transparent 90%),color-mix(in oklch,var(--wm-color-secondary),transparent 80%))}}.wm-btn-toolbar-icon-secondary{border:1px solid var(--wm-color-secondary)}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary{border:1px solid color-mix(in oklch,var(--wm-color-secondary),transparent 70%)}}.wm-btn-toolbar-icon-secondary{box-shadow:var(--wm-shadow-sm);transition:all var(--wm-duration-fast)}.wm-btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,var(--wm-color-secondary),var(--wm-color-secondary))}@supports (color:color-mix(in lab, red, red)){.wm-btn-toolbar-icon-secondary:hover{background:linear-gradient(to bottom right,color-mix(in oklch,var(--wm-color-secondary),transparent 80%),color-mix(in oklch,var(--wm-color-secondary),transparent 70%))}}.wm-badge-compact{height:1.25rem;padding:0 .5rem;font-size:10px}.wm-badge-mini{height:1rem;padding:0 .375rem;font-size:10px}.wm-shimmer{background:linear-gradient(90deg,transparent,var(--wm-color-foreground),transparent);animation:3s linear infinite wm-shimmer}@supports (color:color-mix(in lab, red, red)){.wm-shimmer{background:linear-gradient(90deg,transparent,color-mix(in oklch,var(--wm-color-foreground),transparent 90%),transparent)}}.wm-shimmer{background-size:1000px 100%}.wm-gradient-text{background:linear-gradient(to right,var(--wm-color-foreground),var(--wm-color-foreground))}@supports (color:color-mix(in lab, red, red)){.wm-gradient-text{background:linear-gradient(to right,var(--wm-color-foreground),color-mix(in oklch,var(--wm-color-foreground),transparent 30%))}}.wm-gradient-text{-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text}.wm-glass{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass{background:color-mix(in oklch,var(--wm-color-background),transparent 50%)}}.wm-glass{-webkit-backdrop-filter:blur(var(--wm-blur-md));backdrop-filter:blur(var(--wm-blur-md));border:1px solid var(--wm-color-border)}@supports (color:color-mix(in lab, red, red)){.wm-glass{border:1px solid color-mix(in oklch,var(--wm-color-border),transparent 50%)}}.wm-tool-card{transition:all .3s ease-out}.wm-tool-card:hover{box-shadow:var(--wm-shadow-lg);transform:scale(1.02)}.wm-tool-border-calling{position:relative;overflow:hidden}.wm-tool-border-calling:before{content:\\\"\\\";background:conic-gradient(from 0deg,transparent 0deg,transparent 60deg,var(--wm-color-primary)90deg,var(--wm-color-primary)120deg,var(--wm-color-primary)150deg,transparent 180deg,transparent 360deg);position:absolute;inset:-50%}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-calling:before{background:conic-gradient(from 0deg,transparent 0deg,transparent 60deg,color-mix(in oklch,var(--wm-color-primary),transparent 50%)90deg,color-mix(in oklch,var(--wm-color-primary),transparent 30%)120deg,color-mix(in oklch,var(--wm-color-primary),transparent 50%)150deg,transparent 180deg,transparent 360deg)}}.wm-tool-border-calling:before{animation:1.5s linear infinite wm-border-rotate}.wm-tool-border-success{background:var(--wm-color-success)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-success{background:color-mix(in oklch,var(--wm-color-success),transparent 60%)}}.wm-tool-border-success{box-shadow:0 0 12px var(--wm-color-success),inset 0 0 8px var(--wm-color-success)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-success{box-shadow:0 0 12px color-mix(in oklch,var(--wm-color-success),transparent 70%),inset 0 0 8px color-mix(in oklch,var(--wm-color-success),transparent 90%)}}.wm-tool-border-error{background:var(--wm-color-error)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-error{background:color-mix(in oklch,var(--wm-color-error),transparent 60%)}}.wm-tool-border-error{box-shadow:0 0 12px var(--wm-color-error),inset 0 0 8px var(--wm-color-error)}@supports (color:color-mix(in lab, red, red)){.wm-tool-border-error{box-shadow:0 0 12px color-mix(in oklch,var(--wm-color-error),transparent 70%),inset 0 0 8px color-mix(in oklch,var(--wm-color-error),transparent 90%)}}.wm-scrollbar-thin{scrollbar-width:thin;scrollbar-color:var(--wm-color-primary)transparent}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin{scrollbar-color:color-mix(in oklch,var(--wm-color-primary),transparent 80%)transparent}}.wm-scrollbar-thin::-webkit-scrollbar{width:6px;height:6px}.wm-scrollbar-thin::-webkit-scrollbar-track{background:0 0}.wm-scrollbar-thin::-webkit-scrollbar-thumb{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin::-webkit-scrollbar-thumb{background-color:color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}.wm-scrollbar-thin::-webkit-scrollbar-thumb{border-radius:3px}.wm-scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm-scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:color-mix(in oklch,var(--wm-color-primary),transparent 70%)}}.wm-glass-pill{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{background:color-mix(in oklch,var(--wm-color-background),transparent 15%)}}.wm-glass-pill{-webkit-backdrop-filter:blur(var(--wm-blur-lg))saturate(150%);box-shadow:0 4px 16px var(--wm-color-foreground),inset 0 .5px 0 var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{box-shadow:0 4px 16px color-mix(in oklch,var(--wm-color-foreground),transparent 80%),inset 0 .5px 0 color-mix(in oklch,var(--wm-color-foreground),transparent 92%)}}.wm-glass-pill{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-pill:before{content:\\\"\\\";border-radius:inherit;background:linear-gradient(180deg,var(--wm-color-foreground)0%,transparent 40%);position:absolute;inset:0}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill:before{background:linear-gradient(180deg,color-mix(in oklch,var(--wm-color-foreground),transparent 96%)0%,transparent 40%)}}.wm-glass-pill:before{pointer-events:none;z-index:1}.wm-glass-pill-collapsed{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{background:color-mix(in oklch,var(--wm-color-background),transparent 15%)}}.wm-glass-pill-collapsed{-webkit-backdrop-filter:blur(var(--wm-blur-lg))saturate(150%);box-shadow:0 2px 8px var(--wm-color-foreground),inset 0 .5px 0 var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{box-shadow:0 2px 8px color-mix(in oklch,var(--wm-color-foreground),transparent 80%),inset 0 .5px 0 color-mix(in oklch,var(--wm-color-foreground),transparent 92%)}}.wm-glass-pill-collapsed{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-collapsed{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-pill-hovered{background:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{background:color-mix(in oklch,var(--wm-color-background),transparent 20%)}}.wm-glass-pill-hovered{-webkit-backdrop-filter:blur(16px)saturate(140%);box-shadow:0 2px 12px var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{box-shadow:0 2px 12px color-mix(in oklch,var(--wm-color-foreground),transparent 82%)}}.wm-glass-pill-hovered{border:1px solid var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm-glass-pill-hovered{border:1px solid color-mix(in oklch,var(--wm-color-foreground),transparent 94%)}}.wm-glass-shimmer{background:linear-gradient(90deg,var(--wm-color-foreground)0%,var(--wm-color-foreground)50%,var(--wm-color-foreground)100%)}@supports (color:color-mix(in lab, red, red)){.wm-glass-shimmer{background:linear-gradient(90deg,color-mix(in oklch,var(--wm-color-foreground),transparent 92%)0%,color-mix(in oklch,var(--wm-color-foreground),transparent 85%)50%,color-mix(in oklch,var(--wm-color-foreground),transparent 92%)100%)}}.wm-glass-shimmer{background-size:200% 100%;animation:4s ease-in-out infinite wm-glass-shimmer}.wm-scroll-touch{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.wm-scroll-fade-y{-webkit-mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000);mask-image:linear-gradient(#0000,#000 8px calc(100% - 8px),#0000)}.wm-pb-safe{padding-bottom:env(safe-area-inset-bottom,0px)}.wm-mb-safe{margin-bottom:env(safe-area-inset-bottom,0px)}.wm-bottom-safe{bottom:max(1rem,env(safe-area-inset-bottom,0px))}@supports (padding-bottom:env(safe-area-inset-bottom)){.wm-pill-safe-bottom{padding-bottom:calc(env(safe-area-inset-bottom,0px) + .5rem)}}}@layer utilities{.wm\\\\:pointer-events-auto{pointer-events:auto}.wm\\\\:pointer-events-none{pointer-events:none}.wm\\\\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.wm\\\\:absolute{position:absolute}.wm\\\\:fixed{position:fixed}.wm\\\\:relative{position:relative}.wm\\\\:sticky{position:sticky}.wm\\\\:-inset-\\\\[1px\\\\]{inset:-1px}.wm\\\\:inset-0{inset:calc(var(--wm-spacing)*0)}.wm\\\\:-top-1{top:calc(var(--wm-spacing)*-1)}.wm\\\\:-top-1\\\\.5{top:calc(var(--wm-spacing)*-1.5)}.wm\\\\:-top-12{top:calc(var(--wm-spacing)*-12)}.wm\\\\:top-1\\\\.5{top:calc(var(--wm-spacing)*1.5)}.wm\\\\:top-1\\\\/2{top:50%}.wm\\\\:top-2{top:calc(var(--wm-spacing)*2)}.wm\\\\:-right-0\\\\.5{right:calc(var(--wm-spacing)*-.5)}.wm\\\\:-right-1{right:calc(var(--wm-spacing)*-1)}.wm\\\\:-right-1\\\\.5{right:calc(var(--wm-spacing)*-1.5)}.wm\\\\:right-0{right:calc(var(--wm-spacing)*0)}.wm\\\\:right-1\\\\.5{right:calc(var(--wm-spacing)*1.5)}.wm\\\\:right-2{right:calc(var(--wm-spacing)*2)}.wm\\\\:right-4{right:calc(var(--wm-spacing)*4)}.wm\\\\:-bottom-0\\\\.5{bottom:calc(var(--wm-spacing)*-.5)}.wm\\\\:bottom-0{bottom:calc(var(--wm-spacing)*0)}.wm\\\\:bottom-full{bottom:100%}.wm\\\\:left-0{left:calc(var(--wm-spacing)*0)}.wm\\\\:left-1\\\\/2{left:50%}.wm\\\\:left-2{left:calc(var(--wm-spacing)*2)}.wm\\\\:z-10{z-index:10}.wm\\\\:z-20{z-index:20}.wm\\\\:z-50{z-index:50}.wm\\\\:col-span-full{grid-column:1/-1}.wm\\\\:col-start-1{grid-column-start:1}.wm\\\\:col-start-2{grid-column-start:2}.wm\\\\:col-start-3{grid-column-start:3}.wm\\\\:row-start-2{grid-row-start:2}.wm\\\\:row-start-3{grid-row-start:3}.wm\\\\:-m-1{margin:calc(var(--wm-spacing)*-1)}.wm\\\\:m-0{margin:calc(var(--wm-spacing)*0)}.wm\\\\:mx-2{margin-inline:calc(var(--wm-spacing)*2)}.wm\\\\:mx-3{margin-inline:calc(var(--wm-spacing)*3)}.wm\\\\:mx-auto{margin-inline:auto}.wm\\\\:my-1{margin-block:calc(var(--wm-spacing)*1)}.wm\\\\:my-2{margin-block:calc(var(--wm-spacing)*2)}.wm\\\\:my-3{margin-block:calc(var(--wm-spacing)*3)}.wm\\\\:my-4{margin-block:calc(var(--wm-spacing)*4)}.wm\\\\:my-5{margin-block:calc(var(--wm-spacing)*5)}.wm\\\\:my-auto{margin-block:auto}.wm\\\\:-mt-1{margin-top:calc(var(--wm-spacing)*-1)}.wm\\\\:mt-0\\\\.5{margin-top:calc(var(--wm-spacing)*.5)}.wm\\\\:mt-1{margin-top:calc(var(--wm-spacing)*1)}.wm\\\\:mt-1\\\\.5{margin-top:calc(var(--wm-spacing)*1.5)}.wm\\\\:mt-2{margin-top:calc(var(--wm-spacing)*2)}.wm\\\\:mt-3{margin-top:calc(var(--wm-spacing)*3)}.wm\\\\:mt-4{margin-top:calc(var(--wm-spacing)*4)}.wm\\\\:mt-5{margin-top:calc(var(--wm-spacing)*5)}.wm\\\\:mt-6{margin-top:calc(var(--wm-spacing)*6)}.wm\\\\:mt-auto{margin-top:auto}.wm\\\\:-mr-1{margin-right:calc(var(--wm-spacing)*-1)}.wm\\\\:mr-1\\\\.5{margin-right:calc(var(--wm-spacing)*1.5)}.wm\\\\:mr-2{margin-right:calc(var(--wm-spacing)*2)}.wm\\\\:-mb-1{margin-bottom:calc(var(--wm-spacing)*-1)}.wm\\\\:mb-0\\\\.5{margin-bottom:calc(var(--wm-spacing)*.5)}.wm\\\\:mb-1{margin-bottom:calc(var(--wm-spacing)*1)}.wm\\\\:mb-1\\\\.5{margin-bottom:calc(var(--wm-spacing)*1.5)}.wm\\\\:mb-2{margin-bottom:calc(var(--wm-spacing)*2)}.wm\\\\:mb-3{margin-bottom:calc(var(--wm-spacing)*3)}.wm\\\\:mb-5{margin-bottom:calc(var(--wm-spacing)*5)}.wm\\\\:mb-6{margin-bottom:calc(var(--wm-spacing)*6)}.wm\\\\:-ml-1{margin-left:calc(var(--wm-spacing)*-1)}.wm\\\\:-ml-2{margin-left:calc(var(--wm-spacing)*-2)}.wm\\\\:ml-0\\\\.5{margin-left:calc(var(--wm-spacing)*.5)}.wm\\\\:ml-1{margin-left:calc(var(--wm-spacing)*1)}.wm\\\\:ml-2{margin-left:calc(var(--wm-spacing)*2)}.wm\\\\:ml-4{margin-left:calc(var(--wm-spacing)*4)}.wm\\\\:ml-6{margin-left:calc(var(--wm-spacing)*6)}.wm\\\\:ml-auto{margin-left:auto}.wm\\\\:line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.wm\\\\:line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.wm\\\\:block{display:block}.wm\\\\:flex{display:flex}.wm\\\\:grid{display:grid}.wm\\\\:hidden{display:none}.wm\\\\:inline-block{display:inline-block}.wm\\\\:inline-flex{display:inline-flex}.wm\\\\:size-3{width:calc(var(--wm-spacing)*3);height:calc(var(--wm-spacing)*3)}.wm\\\\:size-3\\\\.5{width:calc(var(--wm-spacing)*3.5);height:calc(var(--wm-spacing)*3.5)}.wm\\\\:size-4{width:calc(var(--wm-spacing)*4);height:calc(var(--wm-spacing)*4)}.wm\\\\:size-5{width:calc(var(--wm-spacing)*5);height:calc(var(--wm-spacing)*5)}.wm\\\\:size-6{width:calc(var(--wm-spacing)*6);height:calc(var(--wm-spacing)*6)}.wm\\\\:size-7{width:calc(var(--wm-spacing)*7);height:calc(var(--wm-spacing)*7)}.wm\\\\:size-8{width:calc(var(--wm-spacing)*8);height:calc(var(--wm-spacing)*8)}.wm\\\\:size-9{width:calc(var(--wm-spacing)*9);height:calc(var(--wm-spacing)*9)}.wm\\\\:size-10{width:calc(var(--wm-spacing)*10);height:calc(var(--wm-spacing)*10)}.wm\\\\:size-\\\\[34px\\\\]{width:34px;height:34px}.wm\\\\:size-full{width:100%;height:100%}.wm\\\\:h-1\\\\.5{height:calc(var(--wm-spacing)*1.5)}.wm\\\\:h-2{height:calc(var(--wm-spacing)*2)}.wm\\\\:h-2\\\\.5{height:calc(var(--wm-spacing)*2.5)}.wm\\\\:h-3{height:calc(var(--wm-spacing)*3)}.wm\\\\:h-3\\\\.5{height:calc(var(--wm-spacing)*3.5)}.wm\\\\:h-4{height:calc(var(--wm-spacing)*4)}.wm\\\\:h-4\\\\.5{height:calc(var(--wm-spacing)*4.5)}.wm\\\\:h-5{height:calc(var(--wm-spacing)*5)}.wm\\\\:h-6{height:calc(var(--wm-spacing)*6)}.wm\\\\:h-7{height:calc(var(--wm-spacing)*7)}.wm\\\\:h-8{height:calc(var(--wm-spacing)*8)}.wm\\\\:h-9{height:calc(var(--wm-spacing)*9)}.wm\\\\:h-10{height:calc(var(--wm-spacing)*10)}.wm\\\\:h-11{height:calc(var(--wm-spacing)*11)}.wm\\\\:h-auto{height:auto}.wm\\\\:h-full{height:100%}.wm\\\\:max-h-24{max-height:calc(var(--wm-spacing)*24)}.wm\\\\:max-h-32{max-height:calc(var(--wm-spacing)*32)}.wm\\\\:max-h-40{max-height:calc(var(--wm-spacing)*40)}.wm\\\\:max-h-64{max-height:calc(var(--wm-spacing)*64)}.wm\\\\:max-h-\\\\[30vh\\\\]{max-height:30vh}.wm\\\\:max-h-\\\\[90vh\\\\]{max-height:90vh}.wm\\\\:min-h-0{min-height:calc(var(--wm-spacing)*0)}.wm\\\\:min-h-7{min-height:calc(var(--wm-spacing)*7)}.wm\\\\:min-h-14{min-height:calc(var(--wm-spacing)*14)}.wm\\\\:min-h-40{min-height:calc(var(--wm-spacing)*40)}.wm\\\\:w-0\\\\.5{width:calc(var(--wm-spacing)*.5)}.wm\\\\:w-1\\\\.5{width:calc(var(--wm-spacing)*1.5)}.wm\\\\:w-2{width:calc(var(--wm-spacing)*2)}.wm\\\\:w-2\\\\.5{width:calc(var(--wm-spacing)*2.5)}.wm\\\\:w-2\\\\/3{width:66.6667%}.wm\\\\:w-3{width:calc(var(--wm-spacing)*3)}.wm\\\\:w-3\\\\.5{width:calc(var(--wm-spacing)*3.5)}.wm\\\\:w-3\\\\/5{width:60%}.wm\\\\:w-4{width:calc(var(--wm-spacing)*4)}.wm\\\\:w-4\\\\.5{width:calc(var(--wm-spacing)*4.5)}.wm\\\\:w-4\\\\/5{width:80%}.wm\\\\:w-5{width:calc(var(--wm-spacing)*5)}.wm\\\\:w-6{width:calc(var(--wm-spacing)*6)}.wm\\\\:w-8{width:calc(var(--wm-spacing)*8)}.wm\\\\:w-11{width:calc(var(--wm-spacing)*11)}.wm\\\\:w-full{width:100%}.wm\\\\:w-px{width:1px}.wm\\\\:max-w-\\\\(--thread-max-width\\\\){max-width:var(--thread-max-width)}.wm\\\\:max-w-24{max-width:calc(var(--wm-spacing)*24)}.wm\\\\:max-w-32{max-width:calc(var(--wm-spacing)*32)}.wm\\\\:max-w-\\\\[85\\\\%\\\\]{max-width:85%}.wm\\\\:max-w-\\\\[100px\\\\]{max-width:100px}.wm\\\\:max-w-\\\\[140px\\\\]{max-width:140px}.wm\\\\:max-w-full{max-width:100%}.wm\\\\:max-w-lg{max-width:var(--wm-container-lg)}.wm\\\\:min-w-0{min-width:calc(var(--wm-spacing)*0)}.wm\\\\:min-w-7{min-width:calc(var(--wm-spacing)*7)}.wm\\\\:flex-1{flex:1}.wm\\\\:flex-shrink-0,.wm\\\\:shrink-0{flex-shrink:0}.wm\\\\:flex-grow,.wm\\\\:grow{flex-grow:1}.wm\\\\:border-separate{border-collapse:separate}.wm\\\\:border-spacing-0{--tw-border-spacing-x:calc(var(--wm-spacing)*0);--tw-border-spacing-y:calc(var(--wm-spacing)*0);border-spacing:var(--tw-border-spacing-x)var(--tw-border-spacing-y)}.wm\\\\:-translate-x-1\\\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:-translate-y-1\\\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.wm\\\\:rotate-180{rotate:180deg}.wm\\\\:animate-in{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.wm\\\\:animate-pulse{animation:var(--wm-animate-pulse)}.wm\\\\:animate-spin{animation:var(--wm-animate-spin)}.wm\\\\:cursor-grab{cursor:grab}.wm\\\\:cursor-not-allowed{cursor:not-allowed}.wm\\\\:cursor-pointer{cursor:pointer}.wm\\\\:resize-none{resize:none}.wm\\\\:scroll-m-20{scroll-margin:calc(var(--wm-spacing)*20)}.wm\\\\:list-inside{list-style-position:inside}.wm\\\\:list-decimal{list-style-type:decimal}.wm\\\\:list-disc{list-style-type:disc}.wm\\\\:auto-rows-auto{grid-auto-rows:auto}.wm\\\\:grid-cols-\\\\[minmax\\\\(72px\\\\,1fr\\\\)_auto\\\\]{grid-template-columns:minmax(72px,1fr) auto}.wm\\\\:grid-rows-\\\\[0fr\\\\]{grid-template-rows:0fr}.wm\\\\:grid-rows-\\\\[1fr\\\\]{grid-template-rows:1fr}.wm\\\\:flex-col{flex-direction:column}.wm\\\\:flex-wrap{flex-wrap:wrap}.wm\\\\:content-start{align-content:flex-start}.wm\\\\:items-center{align-items:center}.wm\\\\:items-end{align-items:flex-end}.wm\\\\:items-start{align-items:flex-start}.wm\\\\:justify-between{justify-content:space-between}.wm\\\\:justify-center{justify-content:center}.wm\\\\:justify-end{justify-content:flex-end}.wm\\\\:justify-start{justify-content:flex-start}.wm\\\\:justify-items-end{justify-items:end}.wm\\\\:gap-1{gap:calc(var(--wm-spacing)*1)}.wm\\\\:gap-1\\\\.5{gap:calc(var(--wm-spacing)*1.5)}.wm\\\\:gap-2{gap:calc(var(--wm-spacing)*2)}.wm\\\\:gap-2\\\\.5{gap:calc(var(--wm-spacing)*2.5)}.wm\\\\:gap-3{gap:calc(var(--wm-spacing)*3)}.wm\\\\:gap-4{gap:calc(var(--wm-spacing)*4)}:where(.wm\\\\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-2\\\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.wm\\\\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--wm-spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--wm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.wm\\\\:gap-y-2{row-gap:calc(var(--wm-spacing)*2)}.wm\\\\:self-center{align-self:center}.wm\\\\:self-end{align-self:flex-end}.wm\\\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.wm\\\\:overflow-auto{overflow:auto}.wm\\\\:overflow-hidden{overflow:hidden}.wm\\\\:overflow-visible{overflow:visible}.wm\\\\:overflow-x-auto{overflow-x:auto}.wm\\\\:overflow-x-hidden{overflow-x:hidden}.wm\\\\:overflow-y-auto{overflow-y:auto}.wm\\\\:overflow-y-scroll{overflow-y:scroll}.wm\\\\:scroll-smooth{scroll-behavior:smooth}.wm\\\\:rounded{border-radius:.25rem}.wm\\\\:rounded-2xl{border-radius:var(--wm-radius-2xl)}.wm\\\\:rounded-full{border-radius:3.40282e38px}.wm\\\\:rounded-lg{border-radius:var(--wm-radius-lg)}.wm\\\\:rounded-md{border-radius:var(--wm-radius-md)}.wm\\\\:rounded-sm{border-radius:var(--wm-radius-sm)}.wm\\\\:rounded-xl{border-radius:var(--wm-radius-xl)}.wm\\\\:rounded-t-lg{border-top-left-radius:var(--wm-radius-lg);border-top-right-radius:var(--wm-radius-lg)}.wm\\\\:rounded-t-none\\\\!{border-top-left-radius:0!important;border-top-right-radius:0!important}.wm\\\\:rounded-b-lg{border-bottom-right-radius:var(--wm-radius-lg);border-bottom-left-radius:var(--wm-radius-lg)}.wm\\\\:border{border-style:var(--tw-border-style);border-width:1px}.wm\\\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.wm\\\\:border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.wm\\\\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.wm\\\\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.wm\\\\:border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.wm\\\\:border-dotted{--tw-border-style:dotted;border-style:dotted}.wm\\\\:border-amber-500\\\\/30{border-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-amber-500\\\\/30{border-color:color-mix(in oklab,var(--wm-color-amber-500)30%,transparent)}}.wm\\\\:border-amber-500\\\\/50{border-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-amber-500\\\\/50{border-color:color-mix(in oklab,var(--wm-color-amber-500)50%,transparent)}}.wm\\\\:border-blue-500\\\\/20{border-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-blue-500\\\\/20{border-color:color-mix(in oklab,var(--wm-color-blue-500)20%,transparent)}}.wm\\\\:border-blue-500\\\\/30{border-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-blue-500\\\\/30{border-color:color-mix(in oklab,var(--wm-color-blue-500)30%,transparent)}}.wm\\\\:border-border,.wm\\\\:border-border\\\\/50{border-color:var(--wm-color-border)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-border\\\\/50{border-color:color-mix(in oklab,var(--wm-color-border)50%,transparent)}}.wm\\\\:border-composer-border{border-color:var(--wm-composer-border)}.wm\\\\:border-destructive,.wm\\\\:border-destructive\\\\/20{border-color:var(--wm-color-destructive)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-destructive\\\\/20{border-color:color-mix(in oklab,var(--wm-color-destructive)20%,transparent)}}.wm\\\\:border-muted-foreground\\\\/20{border-color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-muted-foreground\\\\/20{border-color:color-mix(in oklab,var(--wm-color-muted-foreground)20%,transparent)}}.wm\\\\:border-orange-500\\\\/20{border-color:var(--wm-color-orange-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-orange-500\\\\/20{border-color:color-mix(in oklab,var(--wm-color-orange-500)20%,transparent)}}.wm\\\\:border-primary\\\\/50{border-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-primary\\\\/50{border-color:color-mix(in oklab,var(--wm-color-primary)50%,transparent)}}.wm\\\\:border-white\\\\/5{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/5{border-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:border-white\\\\/8{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/8{border-color:color-mix(in oklab,var(--wm-color-white)8%,transparent)}}.wm\\\\:border-white\\\\/10{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/10{border-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:border-white\\\\/20{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-white\\\\/20{border-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:border-zinc-200,.wm\\\\:border-zinc-200\\\\/80{border-color:var(--wm-color-zinc-200)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:border-zinc-200\\\\/80{border-color:color-mix(in oklab,var(--wm-color-zinc-200)80%,transparent)}}.wm\\\\:border-zinc-600{border-color:var(--wm-color-zinc-600)}.wm\\\\:bg-\\\\[color-mix\\\\(in_oklab\\\\,rgb\\\\(var\\\\(--background\\\\)\\\\)_20\\\\%\\\\,transparent\\\\)\\\\]{background-color:rgb(var(--background))}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-\\\\[color-mix\\\\(in_oklab\\\\,rgb\\\\(var\\\\(--background\\\\)\\\\)_20\\\\%\\\\,transparent\\\\)\\\\]{background-color:color-mix(in oklab,rgb(var(--background))20%,transparent)}}.wm\\\\:bg-amber-500,.wm\\\\:bg-amber-500\\\\/10{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-amber-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-amber-500)10%,transparent)}}.wm\\\\:bg-amber-500\\\\/20{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-amber-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-amber-500)20%,transparent)}}.wm\\\\:bg-background,.wm\\\\:bg-background\\\\/80{background-color:var(--wm-color-background)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-background\\\\/80{background-color:color-mix(in oklab,var(--wm-color-background)80%,transparent)}}.wm\\\\:bg-black\\\\/30{background-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-black\\\\/30{background-color:color-mix(in oklab,var(--wm-color-black)30%,transparent)}}.wm\\\\:bg-blue-400{background-color:var(--wm-color-blue-400)}.wm\\\\:bg-blue-500,.wm\\\\:bg-blue-500\\\\/10{background-color:var(--wm-color-blue-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-blue-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-blue-500)10%,transparent)}}.wm\\\\:bg-code-bg{background-color:var(--wm-code-bg)}.wm\\\\:bg-code-header-bg{background-color:var(--wm-code-header-bg)}.wm\\\\:bg-composer-bg{background-color:var(--wm-composer-bg)}.wm\\\\:bg-destructive,.wm\\\\:bg-destructive\\\\/10{background-color:var(--wm-color-destructive)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-destructive\\\\/10{background-color:color-mix(in oklab,var(--wm-color-destructive)10%,transparent)}}.wm\\\\:bg-green-400,.wm\\\\:bg-green-400\\\\/60{background-color:var(--wm-color-green-400)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-400\\\\/60{background-color:color-mix(in oklab,var(--wm-color-green-400)60%,transparent)}}.wm\\\\:bg-green-500,.wm\\\\:bg-green-500\\\\/10{background-color:var(--wm-color-green-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-green-500)10%,transparent)}}.wm\\\\:bg-green-500\\\\/20{background-color:var(--wm-color-green-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-green-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-green-500)20%,transparent)}}.wm\\\\:bg-muted{background-color:var(--wm-color-muted)}.wm\\\\:bg-muted-foreground\\\\/40{background-color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted-foreground\\\\/40{background-color:color-mix(in oklab,var(--wm-color-muted-foreground)40%,transparent)}}.wm\\\\:bg-muted\\\\/40{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted\\\\/40{background-color:color-mix(in oklab,var(--wm-color-muted)40%,transparent)}}.wm\\\\:bg-muted\\\\/50{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-muted\\\\/50{background-color:color-mix(in oklab,var(--wm-color-muted)50%,transparent)}}.wm\\\\:bg-orange-500\\\\/10{background-color:var(--wm-color-orange-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-orange-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-orange-500)10%,transparent)}}.wm\\\\:bg-primary,.wm\\\\:bg-primary\\\\/10{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-primary\\\\/10{background-color:color-mix(in oklab,var(--wm-color-primary)10%,transparent)}}.wm\\\\:bg-primary\\\\/90{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-primary\\\\/90{background-color:color-mix(in oklab,var(--wm-color-primary)90%,transparent)}}.wm\\\\:bg-red-500,.wm\\\\:bg-red-500\\\\/10{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-red-500\\\\/10{background-color:color-mix(in oklab,var(--wm-color-red-500)10%,transparent)}}.wm\\\\:bg-red-500\\\\/20{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-red-500\\\\/20{background-color:color-mix(in oklab,var(--wm-color-red-500)20%,transparent)}}.wm\\\\:bg-secondary{background-color:var(--wm-color-secondary)}.wm\\\\:bg-transparent{background-color:#0000}.wm\\\\:bg-user-bubble-bg{background-color:var(--wm-user-bubble-bg)}.wm\\\\:bg-white,.wm\\\\:bg-white\\\\/5{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/5{background-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:bg-white\\\\/8{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/8{background-color:color-mix(in oklab,var(--wm-color-white)8%,transparent)}}.wm\\\\:bg-white\\\\/10{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/10{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:bg-white\\\\/20{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/20{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:bg-white\\\\/60{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/60{background-color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:bg-white\\\\/90{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-white\\\\/90{background-color:color-mix(in oklab,var(--wm-color-white)90%,transparent)}}.wm\\\\:bg-zinc-100{background-color:var(--wm-color-zinc-100)}.wm\\\\:bg-zinc-700\\\\/50{background-color:var(--wm-color-zinc-700)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:bg-zinc-700\\\\/50{background-color:color-mix(in oklab,var(--wm-color-zinc-700)50%,transparent)}}.wm\\\\:fill-current{fill:currentColor}.wm\\\\:stroke-\\\\[1\\\\.5px\\\\]{stroke-width:1.5px}.wm\\\\:p-0{padding:calc(var(--wm-spacing)*0)}.wm\\\\:p-1{padding:calc(var(--wm-spacing)*1)}.wm\\\\:p-1\\\\.5{padding:calc(var(--wm-spacing)*1.5)}.wm\\\\:p-2{padding:calc(var(--wm-spacing)*2)}.wm\\\\:p-3{padding:calc(var(--wm-spacing)*3)}.wm\\\\:p-4{padding:calc(var(--wm-spacing)*4)}.wm\\\\:px-1{padding-inline:calc(var(--wm-spacing)*1)}.wm\\\\:px-1\\\\.5{padding-inline:calc(var(--wm-spacing)*1.5)}.wm\\\\:px-2{padding-inline:calc(var(--wm-spacing)*2)}.wm\\\\:px-2\\\\.5{padding-inline:calc(var(--wm-spacing)*2.5)}.wm\\\\:px-3{padding-inline:calc(var(--wm-spacing)*3)}.wm\\\\:px-4{padding-inline:calc(var(--wm-spacing)*4)}.wm\\\\:px-6{padding-inline:calc(var(--wm-spacing)*6)}.wm\\\\:py-0\\\\.5{padding-block:calc(var(--wm-spacing)*.5)}.wm\\\\:py-1{padding-block:calc(var(--wm-spacing)*1)}.wm\\\\:py-1\\\\.5{padding-block:calc(var(--wm-spacing)*1.5)}.wm\\\\:py-2{padding-block:calc(var(--wm-spacing)*2)}.wm\\\\:py-2\\\\.5{padding-block:calc(var(--wm-spacing)*2.5)}.wm\\\\:py-3{padding-block:calc(var(--wm-spacing)*3)}.wm\\\\:py-4{padding-block:calc(var(--wm-spacing)*4)}.wm\\\\:py-8{padding-block:calc(var(--wm-spacing)*8)}.wm\\\\:pt-1\\\\.5{padding-top:calc(var(--wm-spacing)*1.5)}.wm\\\\:pt-2{padding-top:calc(var(--wm-spacing)*2)}.wm\\\\:pt-3{padding-top:calc(var(--wm-spacing)*3)}.wm\\\\:pt-14{padding-top:calc(var(--wm-spacing)*14)}.wm\\\\:pr-2{padding-right:calc(var(--wm-spacing)*2)}.wm\\\\:pb-1{padding-bottom:calc(var(--wm-spacing)*1)}.wm\\\\:pb-3{padding-bottom:calc(var(--wm-spacing)*3)}.wm\\\\:pb-4{padding-bottom:calc(var(--wm-spacing)*4)}.wm\\\\:pl-3{padding-left:calc(var(--wm-spacing)*3)}.wm\\\\:pl-6{padding-left:calc(var(--wm-spacing)*6)}.wm\\\\:text-center{text-align:center}.wm\\\\:text-left{text-align:left}.wm\\\\:text-start{text-align:start}.wm\\\\:align-middle{vertical-align:middle}.wm\\\\:font-mono{font-family:var(--wm-font-mono)}.wm\\\\:text-2xl{font-size:var(--wm-text-2xl);line-height:var(--tw-leading,var(--wm-text-2xl--line-height))}.wm\\\\:text-base{font-size:var(--wm-text-base);line-height:var(--tw-leading,var(--wm-text-base--line-height))}.wm\\\\:text-lg{font-size:var(--wm-text-lg);line-height:var(--tw-leading,var(--wm-text-lg--line-height))}.wm\\\\:text-sm{font-size:var(--wm-text-sm);line-height:var(--tw-leading,var(--wm-text-sm--line-height))}.wm\\\\:text-xl{font-size:var(--wm-text-xl);line-height:var(--tw-leading,var(--wm-text-xl--line-height))}.wm\\\\:text-xs{font-size:var(--wm-text-xs);line-height:var(--tw-leading,var(--wm-text-xs--line-height))}.wm\\\\:text-\\\\[10px\\\\]{font-size:10px}.wm\\\\:text-\\\\[11px\\\\]{font-size:11px}.wm\\\\:text-\\\\[15px\\\\]{font-size:15px}.wm\\\\:leading-7{--tw-leading:calc(var(--wm-spacing)*7);line-height:calc(var(--wm-spacing)*7)}.wm\\\\:leading-\\\\[21px\\\\]{--tw-leading:21px;line-height:21px}.wm\\\\:leading-normal{--tw-leading:var(--wm-leading-normal);line-height:var(--wm-leading-normal)}.wm\\\\:leading-relaxed{--tw-leading:var(--wm-leading-relaxed);line-height:var(--wm-leading-relaxed)}.wm\\\\:font-bold{--tw-font-weight:var(--wm-font-weight-bold);font-weight:var(--wm-font-weight-bold)}.wm\\\\:font-extrabold{--tw-font-weight:var(--wm-font-weight-extrabold);font-weight:var(--wm-font-weight-extrabold)}.wm\\\\:font-medium{--tw-font-weight:var(--wm-font-weight-medium);font-weight:var(--wm-font-weight-medium)}.wm\\\\:font-semibold{--tw-font-weight:var(--wm-font-weight-semibold);font-weight:var(--wm-font-weight-semibold)}.wm\\\\:tracking-tight{--tw-tracking:var(--wm-tracking-tight);letter-spacing:var(--wm-tracking-tight)}.wm\\\\:tracking-wide{--tw-tracking:var(--wm-tracking-wide);letter-spacing:var(--wm-tracking-wide)}.wm\\\\:wrap-break-word{overflow-wrap:break-word}.wm\\\\:break-all{word-break:break-all}.wm\\\\:whitespace-nowrap{white-space:nowrap}.wm\\\\:whitespace-pre-wrap{white-space:pre-wrap}.wm\\\\:text-amber-400{color:var(--wm-color-amber-400)}.wm\\\\:text-amber-500{color:var(--wm-color-amber-500)}.wm\\\\:text-assistant-bubble-text{color:var(--wm-assistant-bubble-text)}.wm\\\\:text-blue-400,.wm\\\\:text-blue-400\\\\/60{color:var(--wm-color-blue-400)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-blue-400\\\\/60{color:color-mix(in oklab,var(--wm-color-blue-400)60%,transparent)}}.wm\\\\:text-blue-600{color:var(--wm-color-blue-600)}.wm\\\\:text-code-text{color:var(--wm-code-text)}.wm\\\\:text-composer-text{color:var(--wm-composer-text)}.wm\\\\:text-destructive{color:var(--wm-color-destructive)}.wm\\\\:text-foreground,.wm\\\\:text-foreground\\\\/70{color:var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-foreground\\\\/70{color:color-mix(in oklab,var(--wm-color-foreground)70%,transparent)}}.wm\\\\:text-foreground\\\\/80{color:var(--wm-color-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-foreground\\\\/80{color:color-mix(in oklab,var(--wm-color-foreground)80%,transparent)}}.wm\\\\:text-green-400{color:var(--wm-color-green-400)}.wm\\\\:text-green-500{color:var(--wm-color-green-500)}.wm\\\\:text-muted-foreground,.wm\\\\:text-muted-foreground\\\\/70{color:var(--wm-color-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-muted-foreground\\\\/70{color:color-mix(in oklab,var(--wm-color-muted-foreground)70%,transparent)}}.wm\\\\:text-orange-600{color:var(--wm-color-orange-600)}.wm\\\\:text-primary{color:var(--wm-color-primary)}.wm\\\\:text-primary-foreground{color:var(--wm-color-primary-foreground)}.wm\\\\:text-primary\\\\/80{color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-primary\\\\/80{color:color-mix(in oklab,var(--wm-color-primary)80%,transparent)}}.wm\\\\:text-red-300{color:var(--wm-color-red-300)}.wm\\\\:text-red-400{color:var(--wm-color-red-400)}.wm\\\\:text-secondary-foreground{color:var(--wm-color-secondary-foreground)}.wm\\\\:text-slate-900{color:var(--wm-color-slate-900)}.wm\\\\:text-user-bubble-text{color:var(--wm-user-bubble-text)}.wm\\\\:text-white,.wm\\\\:text-white\\\\/30{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/30{color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:text-white\\\\/40{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/40{color:color-mix(in oklab,var(--wm-color-white)40%,transparent)}}.wm\\\\:text-white\\\\/50{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/50{color:color-mix(in oklab,var(--wm-color-white)50%,transparent)}}.wm\\\\:text-white\\\\/60{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/60{color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:text-white\\\\/70{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/70{color:color-mix(in oklab,var(--wm-color-white)70%,transparent)}}.wm\\\\:text-white\\\\/80{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/80{color:color-mix(in oklab,var(--wm-color-white)80%,transparent)}}.wm\\\\:text-white\\\\/90{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:text-white\\\\/90{color:color-mix(in oklab,var(--wm-color-white)90%,transparent)}}.wm\\\\:text-zinc-400{color:var(--wm-color-zinc-400)}.wm\\\\:text-zinc-700{color:var(--wm-color-zinc-700)}.wm\\\\:lowercase{text-transform:lowercase}.wm\\\\:uppercase{text-transform:uppercase}.wm\\\\:italic{font-style:italic}.wm\\\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.wm\\\\:underline{text-decoration-line:underline}.wm\\\\:underline-offset-4{text-underline-offset:4px}.wm\\\\:opacity-0{opacity:0}.wm\\\\:opacity-50{opacity:.5}.wm\\\\:opacity-90{opacity:.9}.wm\\\\:opacity-100{opacity:1}.wm\\\\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:shadow-black\\\\/10{--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:shadow-black\\\\/10{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)10%,transparent)var(--tw-shadow-alpha),transparent)}}.wm\\\\:shadow-black\\\\/20{--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:shadow-black\\\\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)20%,transparent)var(--tw-shadow-alpha),transparent)}}.wm\\\\:backdrop-blur-sm{--tw-backdrop-blur:blur(var(--wm-blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.wm\\\\:transition-\\\\[grid-template-rows\\\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--wm-default-transition-timing-function));transition-duration:var(--tw-duration,var(--wm-default-transition-duration))}.wm\\\\:delay-75{transition-delay:75ms}.wm\\\\:duration-\\\\(--animation-duration\\\\){--tw-duration:var(--animation-duration);transition-duration:var(--animation-duration)}.wm\\\\:duration-100{--tw-duration:.1s;transition-duration:.1s}.wm\\\\:duration-150{--tw-duration:.15s;transition-duration:.15s}.wm\\\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.wm\\\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.wm\\\\:ease-out{--tw-ease:var(--wm-ease-out);transition-timing-function:var(--wm-ease-out)}.wm\\\\:will-change-transform{will-change:transform}.wm\\\\:delay-75{--tw-animation-delay:75ms;animation-delay:75ms}.wm\\\\:fill-mode-both{--tw-animation-fill-mode:both;animation-fill-mode:both}.wm\\\\:outline-none{--tw-outline-style:none;outline-style:none}.wm\\\\:fade-in{--tw-enter-opacity:0}.wm\\\\:slide-in-from-bottom-1{--tw-enter-translate-y:calc(1*var(--spacing))}.wm\\\\:slide-in-from-bottom-2{--tw-enter-translate-y:calc(2*var(--spacing))}@media (hover:hover){.wm\\\\:group-hover\\\\:opacity-100:is(:where(.wm\\\\:group):hover *){opacity:1}}.wm\\\\:placeholder\\\\:text-white\\\\/40::placeholder{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:placeholder\\\\:text-white\\\\/40::placeholder{color:color-mix(in oklab,var(--wm-color-white)40%,transparent)}}.wm\\\\:first\\\\:mt-0:first-child{margin-top:calc(var(--wm-spacing)*0)}.wm\\\\:last\\\\:mb-0:last-child{margin-bottom:calc(var(--wm-spacing)*0)}.wm\\\\:focus-within\\\\:border-white\\\\/15:focus-within{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-within\\\\:border-white\\\\/15:focus-within{border-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:focus-within\\\\:bg-white\\\\/10:focus-within{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-within\\\\:bg-white\\\\/10:focus-within{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}@media (hover:hover){.wm\\\\:hover\\\\:border-amber-500:hover{border-color:var(--wm-color-amber-500)}.wm\\\\:hover\\\\:border-red-500\\\\/50:hover{border-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:border-red-500\\\\/50:hover{border-color:color-mix(in oklab,var(--wm-color-red-500)50%,transparent)}}.wm\\\\:hover\\\\:border-white\\\\/20:hover{border-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:border-white\\\\/20:hover{border-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:hover\\\\:bg-amber-500\\\\/20:hover{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-amber-500\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-amber-500)20%,transparent)}}.wm\\\\:hover\\\\:bg-amber-500\\\\/30:hover{background-color:var(--wm-color-amber-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-amber-500\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-amber-500)30%,transparent)}}.wm\\\\:hover\\\\:bg-muted:hover,.wm\\\\:hover\\\\:bg-muted\\\\/50:hover{background-color:var(--wm-color-muted)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-muted\\\\/50:hover{background-color:color-mix(in oklab,var(--wm-color-muted)50%,transparent)}}.wm\\\\:hover\\\\:bg-primary\\\\/90:hover{background-color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-primary\\\\/90:hover{background-color:color-mix(in oklab,var(--wm-color-primary)90%,transparent)}}.wm\\\\:hover\\\\:bg-red-500\\\\/20:hover{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-red-500\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-red-500)20%,transparent)}}.wm\\\\:hover\\\\:bg-red-500\\\\/30:hover{background-color:var(--wm-color-red-500)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-red-500\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-red-500)30%,transparent)}}.wm\\\\:hover\\\\:bg-white:hover,.wm\\\\:hover\\\\:bg-white\\\\/5:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/5:hover{background-color:color-mix(in oklab,var(--wm-color-white)5%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/10:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/10:hover{background-color:color-mix(in oklab,var(--wm-color-white)10%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/15:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/15:hover{background-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/20:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/20:hover{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:hover\\\\:bg-white\\\\/30:hover{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:bg-white\\\\/30:hover{background-color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:hover\\\\:bg-zinc-50:hover{background-color:var(--wm-color-zinc-50)}.wm\\\\:hover\\\\:bg-zinc-200:hover{background-color:var(--wm-color-zinc-200)}.wm\\\\:hover\\\\:bg-zinc-700:hover{background-color:var(--wm-color-zinc-700)}.wm\\\\:hover\\\\:text-foreground:hover{color:var(--wm-color-foreground)}.wm\\\\:hover\\\\:text-primary\\\\/80:hover{color:var(--wm-color-primary)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-primary\\\\/80:hover{color:color-mix(in oklab,var(--wm-color-primary)80%,transparent)}}.wm\\\\:hover\\\\:text-red-200:hover{color:var(--wm-color-red-200)}.wm\\\\:hover\\\\:text-red-300:hover{color:var(--wm-color-red-300)}.wm\\\\:hover\\\\:text-red-400:hover{color:var(--wm-color-red-400)}.wm\\\\:hover\\\\:text-white:hover,.wm\\\\:hover\\\\:text-white\\\\/50:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/50:hover{color:color-mix(in oklab,var(--wm-color-white)50%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/60:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/60:hover{color:color-mix(in oklab,var(--wm-color-white)60%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/70:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/70:hover{color:color-mix(in oklab,var(--wm-color-white)70%,transparent)}}.wm\\\\:hover\\\\:text-white\\\\/80:hover{color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:hover\\\\:text-white\\\\/80:hover{color:color-mix(in oklab,var(--wm-color-white)80%,transparent)}}.wm\\\\:hover\\\\:text-zinc-600:hover{color:var(--wm-color-zinc-600)}}.wm\\\\:focus\\\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.wm\\\\:focus-visible\\\\:bg-muted:focus-visible{background-color:var(--wm-color-muted)}.wm\\\\:focus-visible\\\\:opacity-100:focus-visible{opacity:1}.wm\\\\:focus-visible\\\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.wm\\\\:focus-visible\\\\:ring-blue-500:focus-visible{--tw-ring-color:var(--wm-color-blue-500)}.wm\\\\:focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:focus-visible\\\\:ring-white\\\\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--wm-color-white)30%,transparent)}}.wm\\\\:focus-visible\\\\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.wm\\\\:focus-visible\\\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.wm\\\\:focus-visible\\\\:ring-offset-transparent:focus-visible{--tw-ring-offset-color:transparent}.wm\\\\:focus-visible\\\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.wm\\\\:active\\\\:scale-\\\\[0\\\\.98\\\\]:active{scale:.98}.wm\\\\:active\\\\:cursor-grabbing:active{cursor:grabbing}.wm\\\\:active\\\\:bg-white\\\\/15:active{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:active\\\\:bg-white\\\\/15:active{background-color:color-mix(in oklab,var(--wm-color-white)15%,transparent)}}.wm\\\\:active\\\\:bg-white\\\\/20:active{background-color:var(--wm-color-white)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:active\\\\:bg-white\\\\/20:active{background-color:color-mix(in oklab,var(--wm-color-white)20%,transparent)}}.wm\\\\:disabled\\\\:invisible:disabled{visibility:hidden}.wm\\\\:disabled\\\\:cursor-not-allowed:disabled{cursor:not-allowed}.wm\\\\:disabled\\\\:opacity-40:disabled{opacity:.4}.wm\\\\:data-\\\\[active\\\\=true\\\\]\\\\:bg-muted[data-active=true]{background-color:var(--wm-color-muted)}.wm\\\\:nth-\\\\[n\\\\+3\\\\]\\\\:hidden:nth-child(n+3){display:none}@media (min-width:40rem){.wm\\\\:sm\\\\:flex{display:flex}.wm\\\\:sm\\\\:h-3{height:calc(var(--wm-spacing)*3)}.wm\\\\:sm\\\\:h-3\\\\.5{height:calc(var(--wm-spacing)*3.5)}.wm\\\\:sm\\\\:h-4{height:calc(var(--wm-spacing)*4)}.wm\\\\:sm\\\\:h-7{height:calc(var(--wm-spacing)*7)}.wm\\\\:sm\\\\:max-h-24{max-height:calc(var(--wm-spacing)*24)}.wm\\\\:sm\\\\:max-h-32{max-height:calc(var(--wm-spacing)*32)}.wm\\\\:sm\\\\:max-h-48{max-height:calc(var(--wm-spacing)*48)}.wm\\\\:sm\\\\:w-3{width:calc(var(--wm-spacing)*3)}.wm\\\\:sm\\\\:w-3\\\\.5{width:calc(var(--wm-spacing)*3.5)}.wm\\\\:sm\\\\:w-4{width:calc(var(--wm-spacing)*4)}.wm\\\\:sm\\\\:w-7{width:calc(var(--wm-spacing)*7)}.wm\\\\:sm\\\\:max-w-16{max-width:calc(var(--wm-spacing)*16)}.wm\\\\:sm\\\\:max-w-24{max-width:calc(var(--wm-spacing)*24)}.wm\\\\:sm\\\\:gap-1{gap:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:gap-1\\\\.5{gap:calc(var(--wm-spacing)*1.5)}.wm\\\\:sm\\\\:p-1{padding:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:p-1\\\\.5{padding:calc(var(--wm-spacing)*1.5)}.wm\\\\:sm\\\\:px-2{padding-inline:calc(var(--wm-spacing)*2)}.wm\\\\:sm\\\\:py-1{padding-block:calc(var(--wm-spacing)*1)}.wm\\\\:sm\\\\:opacity-0{opacity:0}@media (hover:hover){.wm\\\\:sm\\\\:group-hover\\\\:opacity-100:is(:where(.wm\\\\:group):hover *){opacity:1}}}.wm\\\\:dark\\\\:border-zinc-600:is(.dark *){border-color:var(--wm-color-zinc-600)}.wm\\\\:dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:var(--wm-color-zinc-700)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:dark\\\\:border-zinc-700\\\\/80:is(.dark *){border-color:color-mix(in oklab,var(--wm-color-zinc-700)80%,transparent)}}.wm\\\\:dark\\\\:bg-zinc-700:is(.dark *){background-color:var(--wm-color-zinc-700)}.wm\\\\:dark\\\\:bg-zinc-800:is(.dark *){background-color:var(--wm-color-zinc-800)}.wm\\\\:dark\\\\:text-zinc-200:is(.dark *){color:var(--wm-color-zinc-200)}.wm\\\\:dark\\\\:text-zinc-400:is(.dark *){color:var(--wm-color-zinc-400)}.wm\\\\:dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:var(--wm-color-black)}@supports (color:color-mix(in lab, red, red)){.wm\\\\:dark\\\\:shadow-black\\\\/30:is(.dark *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--wm-color-black)30%,transparent)var(--tw-shadow-alpha),transparent)}}@media (hover:hover){.wm\\\\:dark\\\\:hover\\\\:bg-zinc-600:is(.dark *):hover{background-color:var(--wm-color-zinc-600)}.wm\\\\:dark\\\\:hover\\\\:bg-zinc-700:is(.dark *):hover{background-color:var(--wm-color-zinc-700)}.wm\\\\:dark\\\\:hover\\\\:text-zinc-200:is(.dark *):hover{color:var(--wm-color-zinc-200)}}.wm\\\\:\\\\[\\\\&\\\\>li\\\\]\\\\:mt-0\\\\.5>li{margin-top:calc(var(--wm-spacing)*.5)}}@keyframes aui-pulse{50%{opacity:.5}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;animation:2s cubic-bezier(.4,0,.6,1) infinite aui-pulse}@keyframes wm-shimmer{0%{transform:translate(-100%)}to{transform:translate(200%)}}@keyframes wm-subtle-pulse{0%,to{opacity:1}50%{opacity:.85}}@keyframes wm-slide-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes wm-fade-in-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes wm-gradient-shift{0%,to{transform:translate(0%)translateY(0%)}25%{transform:translate(100%)translateY(100%)}50%{transform:translate(100%)translateY(0%)}75%{transform:translate(0%)translateY(100%)}}@keyframes wm-float{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(-30px)translate(20px)}66%{transform:translateY(20px)translate(-20px)}}@keyframes wm-float-delayed{0%,to{transform:translateY(0)translate(0)}33%{transform:translateY(30px)translate(-30px)}66%{transform:translateY(-20px)translate(20px)}}@keyframes wm-border-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes wm-pulse-success{0%,to{box-shadow:0 0 0 0 color-mix(in oklch,var(--wm-color-success),transparent 60%)}50%{box-shadow:0 0 0 8px #0000}}@keyframes wm-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}@keyframes wm-pulse-glow{0%,to{box-shadow:0 0 20px color-mix(in oklch,var(--wm-color-primary),transparent 90%)}50%{box-shadow:0 0 30px color-mix(in oklch,var(--wm-color-primary),transparent 80%)}}@keyframes wm-gradient-x{0%,to{background-position:0%}50%{background-position:100%}}@keyframes wm-glass-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes wm-aui-pulse{50%{opacity:.5}}.wm-no-scrollbar::-webkit-scrollbar{display:none}.wm-no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@media (hover:none){.wm-scrollbar-thin{scrollbar-width:none}.wm-scrollbar-thin::-webkit-scrollbar{display:none}}:where(.aui-md[data-status=running]):empty:after,:where(.aui-md[data-status=running])>:where(:not(ol):not(ul):not(pre)):last-child:after,:where(.aui-md[data-status=running])>pre:last-child code:after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child:not(:has(*>li))):after,:where(.aui-md[data-status=running])>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child)>:where(:is(ol,ul):last-child)>:where(li:last-child):after{font-family:var(--wm-font-sans);--aui-content:\\\"●\\\";content:var(--aui-content);margin-left:.25rem;margin-right:.25rem;animation:2s cubic-bezier(.4,0,.6,1) infinite wm-aui-pulse}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}\";\n\n/**\n * Inject the WebMCP styles into the document head.\n * This is called automatically when registering the web component without shadow DOM.\n *\n * @deprecated For new implementations, use the ShadowRoot component with WEBMCP_SHADOW_STYLES\n * instead of global style injection for better isolation.\n */\nexport function injectStyles(): void {\n\tif (typeof document === 'undefined') return\n\n\tconst styleId = 'webmcp-agent-styles'\n\tif (document.getElementById(styleId)) return\n\n\tconst style = document.createElement('style')\n\tstyle.id = styleId\n\tstyle.textContent = WEBMCP_STYLES\n\tdocument.head.appendChild(style)\n}\n\n/**\n * Get the shadow DOM compatible styles.\n * Use this when manually creating a shadow root.\n *\n * @example\n * const shadow = element.attachShadow({ mode: 'open' })\n * const style = document.createElement('style')\n * style.textContent = getShadowStyles()\n * shadow.appendChild(style)\n */\nexport function getShadowStyles(): string {\n\treturn WEBMCP_SHADOW_STYLES\n}\n","/**\n * Auto-inject styles for React components\n *\n * This ensures styles are automatically available when using AgentThread or AgentPill\n * without requiring a separate CSS import.\n *\n * Styles are injected once (idempotent) into the document head.\n * Host apps can override via CSS variables or higher specificity rules.\n */\n\nimport { WEBMCP_STYLES } from '../generated/inline-styles'\n\nlet injected = false\n\n/**\n * Injects the embedded-agent styles into the document head.\n * Safe to call multiple times - only injects once.\n *\n * @returns true if styles were injected, false if already injected or SSR\n */\nexport function injectStyles(): boolean {\n\t// Skip if already injected or in SSR\n\tif (injected || typeof document === 'undefined') {\n\t\treturn false\n\t}\n\n\t// Check if already injected (e.g., by another instance)\n\tif (document.getElementById('webmcp-styles')) {\n\t\tinjected = true\n\t\treturn false\n\t}\n\n\t// Create and inject style element\n\tconst style = document.createElement('style')\n\tstyle.id = 'webmcp-styles'\n\tstyle.textContent = WEBMCP_STYLES\n\tdocument.head.appendChild(style)\n\n\tinjected = true\n\treturn true\n}\n","/**\n * ErrorScreen Component\n *\n * Full-screen blocking error display for critical authentication failures.\n * Rendered inside the widget's shadow DOM, replaces entire widget content.\n * Used for configuration errors, unauthorized domains, and non-recoverable issues.\n *\n * Design: Professional, spacious, responsive. Works in sidebars and various UI contexts.\n */\n\nimport * as React from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/utils/cn\";\nimport type { AuthError } from \"@/utils/auth-errors\";\n\nexport interface ErrorScreenProps {\n /** Authentication error with educational content */\n error: AuthError;\n /** Base URL for dashboard (e.g., \"https://app.char.ai\") */\n dashboardBaseUrl?: string;\n /** Base URL for documentation (e.g., \"https://docs.char.ai\") */\n docsBaseUrl?: string;\n /** Retry handler */\n onRetry?: () => void;\n /** Contact support handler */\n onContact?: () => void;\n /** Show debug info (dev mode) */\n showDebug?: boolean;\n /** Additional className */\n className?: string;\n}\n\nexport function ErrorScreen({\n error,\n dashboardBaseUrl = \"\",\n docsBaseUrl = \"\",\n onRetry,\n onContact,\n showDebug = false,\n className,\n}: ErrorScreenProps) {\n const [isDebugExpanded, setIsDebugExpanded] = React.useState(false);\n\n const dashboardUrl = error.dashboardLink && dashboardBaseUrl\n ? `${dashboardBaseUrl}${error.dashboardLink}`\n : undefined;\n\n const docsUrl = error.docsLink\n ? error.docsLink.startsWith(\"http\")\n ? error.docsLink\n : `${docsBaseUrl}${error.docsLink}`\n : undefined;\n\n return (\n <div\n className={cn(\n \"wm:flex wm:flex-col wm:items-center wm:justify-center wm:h-full wm:w-full wm:p-4\",\n className\n )}\n data-error-screen\n data-error-code={error.code}\n >\n {/* Error Card */}\n <div className=\"wm:w-full wm:max-w-lg wm:bg-background wm:border wm:border-border wm:rounded-xl wm:shadow-xl wm:overflow-hidden wm:flex wm:flex-col wm:max-h-[90vh]\">\n {/* Content Container */}\n <div className=\"wm:flex-1 wm:overflow-y-auto wm:px-6 wm:py-8 wm:space-y-6\">\n {/* Title and message */}\n <div className=\"wm:space-y-3\">\n <h1 className=\"wm:text-lg wm:font-semibold wm:text-foreground\">\n {error.title}\n </h1>\n <p className=\"wm:text-sm wm:text-muted-foreground wm:leading-relaxed\">\n {error.message}\n </p>\n </div>\n\n {/* Context information */}\n {error.context && Object.keys(error.context).length > 0 && (\n <div className=\"wm:rounded-lg wm:bg-muted/50 wm:p-4 wm:space-y-4 wm:border wm:border-border/50\">\n {error.context.currentDomain && (\n <div>\n <p className=\"wm:text-xs wm:font-medium wm:text-muted-foreground wm:mb-2\">\n Current Domain\n </p>\n <code className=\"wm:block wm:text-xs wm:bg-background wm:px-3 wm:py-2 wm:rounded wm:font-mono wm:break-all\">\n {error.context.currentDomain}\n </code>\n </div>\n )}\n {error.context.missingField && (\n <div>\n <p className=\"wm:text-xs wm:font-medium wm:text-muted-foreground wm:mb-2\">\n Missing Configuration\n </p>\n <p className=\"wm:text-sm wm:text-foreground\">{error.context.missingField}</p>\n </div>\n )}\n {error.context.expectedIssuer && error.context.actualIssuer && (\n <>\n <div>\n <p className=\"wm:text-xs wm:font-medium wm:text-muted-foreground wm:mb-2\">\n Expected Issuer\n </p>\n <code className=\"wm:block wm:text-xs wm:bg-background wm:px-3 wm:py-2 wm:rounded wm:font-mono wm:break-all\">\n {error.context.expectedIssuer}\n </code>\n </div>\n <div>\n <p className=\"wm:text-xs wm:font-medium wm:text-muted-foreground wm:mb-2\">\n Token Issuer\n </p>\n <code className=\"wm:block wm:text-xs wm:bg-background wm:px-3 wm:py-2 wm:rounded wm:font-mono wm:break-all\">\n {error.context.actualIssuer}\n </code>\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Call to action steps */}\n {error.callToAction && error.callToAction.steps.length > 0 && (\n <div className=\"wm:space-y-3\">\n <h2 className=\"wm:text-sm wm:font-semibold wm:text-foreground\">\n How to Fix\n </h2>\n <ol className=\"wm:space-y-2.5 wm:text-sm wm:text-foreground wm:list-decimal wm:list-inside wm:leading-relaxed\">\n {error.callToAction.steps.map((step, index) => (\n <li key={index} className=\"wm:leading-relaxed\">\n {step}\n </li>\n ))}\n </ol>\n </div>\n )}\n\n {/* Examples */}\n {error.callToAction?.examples && error.callToAction.examples.length > 0 && (\n <div className=\"wm:rounded-lg wm:bg-muted/50 wm:p-4 wm:border wm:border-border/50 wm:space-y-2\">\n <p className=\"wm:text-xs wm:font-medium wm:text-muted-foreground\">\n Examples\n </p>\n <div className=\"wm:space-y-2\">\n {error.callToAction.examples.map((example, index) => (\n <code\n key={index}\n className=\"wm:block wm:text-xs wm:bg-background wm:px-3 wm:py-2 wm:rounded wm:font-mono wm:break-all\"\n >\n {example}\n </code>\n ))}\n </div>\n </div>\n )}\n\n {/* Debug info */}\n {showDebug && error.debugInfo && (\n <details\n className=\"wm:rounded-lg wm:bg-muted/50 wm:border wm:border-border/50 wm:overflow-hidden\"\n open={isDebugExpanded}\n onToggle={(e) => setIsDebugExpanded(e.currentTarget.open)}\n >\n <summary className=\"wm:cursor-pointer wm:px-3 wm:py-2 wm:text-xs wm:font-medium wm:text-muted-foreground hover:wm:bg-muted/70\">\n Debug Information\n </summary>\n <pre className=\"wm:text-xs wm:whitespace-pre-wrap wm:bg-background wm:p-3 wm:font-mono wm:leading-normal\">\n {error.debugInfo}\n </pre>\n </details>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"wm:border-t wm:border-border wm:p-4 wm:space-y-2\">\n {dashboardUrl && (\n <Button\n asChild\n className=\"wm:w-full\"\n size=\"sm\"\n >\n <a href={dashboardUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n Open Dashboard\n </a>\n </Button>\n )}\n\n {error.recoverable && onRetry && !dashboardUrl && (\n <Button\n onClick={onRetry}\n className=\"wm:w-full\"\n size=\"sm\"\n >\n Retry\n </Button>\n )}\n\n <div className=\"wm:flex wm:flex-col sm:wm:flex-row wm:gap-2\">\n {docsUrl && (\n <Button\n asChild\n variant=\"outline\"\n size=\"sm\"\n className=\"wm:flex-1\"\n >\n <a href={docsUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n View Guide\n </a>\n </Button>\n )}\n {onContact && (\n <Button\n onClick={onContact}\n variant=\"outline\"\n size=\"sm\"\n className=\"wm:flex-1\"\n >\n Contact Support\n </Button>\n )}\n {error.recoverable && onRetry && dashboardUrl && (\n <Button\n onClick={onRetry}\n variant=\"outline\"\n size=\"sm\"\n className=\"wm:flex-1\"\n >\n Retry\n </Button>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * AuthErrorBoundary Component\n *\n * React Error Boundary that catches all errors within the widget.\n * Prevents errors from propagating past the shadow DOM boundary to the host page.\n * Displays ErrorScreen for caught errors instead of crashing the widget.\n */\n\nimport * as React from \"react\";\nimport { ErrorScreen } from \"./ErrorScreen\";\nimport type { AuthError } from \"@/utils/auth-errors\";\n\nexport interface AuthErrorBoundaryProps {\n /** Child components to protect */\n children: React.ReactNode;\n /** Base URL for dashboard */\n dashboardBaseUrl?: string;\n /** Base URL for documentation */\n docsBaseUrl?: string;\n /** Fallback UI (optional, defaults to ErrorScreen) */\n fallback?: React.ComponentType<{ error: AuthError; reset: () => void }>;\n /** Callback when error is caught (for logging/analytics) */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n /** Show debug info */\n showDebug?: boolean;\n}\n\ninterface AuthErrorBoundaryState {\n hasError: boolean;\n error: AuthError | null;\n}\n\n/**\n * Error boundary for authentication errors.\n * Catches all errors and displays ErrorScreen instead of crashing.\n */\nexport class AuthErrorBoundary extends React.Component<\n AuthErrorBoundaryProps,\n AuthErrorBoundaryState\n> {\n constructor(props: AuthErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<AuthErrorBoundaryState> {\n // Convert generic Error to AuthError\n const authError: AuthError = isAuthError(error)\n ? error\n : {\n code: \"UNKNOWN_ERROR\",\n title: \"Something Went Wrong\",\n message: \"An unexpected error occurred. Please try refreshing the page.\",\n recoverable: true,\n debugInfo: error.message,\n };\n\n return {\n hasError: true,\n error: authError,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n // Log error but don't let it propagate to host page\n console.error(\"[Widget Error Boundary] Caught error:\", error, errorInfo);\n\n // Call optional error handler\n if (this.props.onError) {\n try {\n this.props.onError(error, errorInfo);\n } catch (handlerError) {\n console.error(\"[Widget Error Boundary] Error in onError handler:\", handlerError);\n }\n }\n }\n\n handleReset = () => {\n this.setState({\n hasError: false,\n error: null,\n });\n };\n\n handleContact = () => {\n // Open support email or contact page\n // This can be customized based on your support system\n window.open(\"mailto:support@char.ai?subject=Widget%20Error\", \"_blank\");\n };\n\n render() {\n if (this.state.hasError && this.state.error) {\n const { fallback: FallbackComponent, dashboardBaseUrl, docsBaseUrl, showDebug } = this.props;\n\n // Use custom fallback if provided\n if (FallbackComponent) {\n return <FallbackComponent error={this.state.error} reset={this.handleReset} />;\n }\n\n // Default to ErrorScreen\n return (\n <ErrorScreen\n error={this.state.error}\n dashboardBaseUrl={dashboardBaseUrl}\n docsBaseUrl={docsBaseUrl}\n onRetry={this.handleReset}\n onContact={this.handleContact}\n showDebug={showDebug}\n />\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Type guard to check if an error is an AuthError\n */\nfunction isAuthError(error: unknown): error is AuthError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n \"title\" in error &&\n \"message\" in error &&\n \"recoverable\" in error &&\n // Check for AuthErrorException class\n (error instanceof Error && error.name === \"AuthErrorException\" ||\n // Check for plain AuthError object\n typeof (error as any).code === \"string\")\n );\n}\n","/**\n * useStatelessRuntime\n *\n * Creates an Assistant UI runtime backed by HTTP streaming (no WebSocket/Durable Object).\n * Uses @assistant-ui/react-ai-sdk's useChatRuntime with AssistantChatTransport.\n *\n * This follows the assistant-ui documentation pattern:\n * @see https://www.assistant-ui.com/docs/runtimes/ai-sdk/use-chat\n *\n * Use this runtime when:\n * - In development mode without API key setup\n * - When authToken is not provided (anonymous chat)\n * - For testing/playground scenarios\n *\n * Messages are NOT persisted - the frontend maintains full conversation history.\n * AssistantChatTransport automatically forwards system messages and frontend tools\n * from the assistant-ui context to the backend.\n *\n * **Frontend tools (WebMCP tools registered via useWebMCP)** ARE supported in stateless mode.\n * The AssistantChatTransport automatically forwards tool definitions to the backend.\n */\n\nimport { AssistantChatTransport, useChatRuntime } from '@assistant-ui/react-ai-sdk'\nimport { lastAssistantMessageIsCompleteWithToolCalls } from 'ai'\nimport { useMemo } from 'react'\n\nimport type { AssistantRuntime } from '@assistant-ui/react'\n\n/**\n * Result type for useStatelessRuntime hook.\n */\nexport interface UseStatelessRuntimeResult {\n\t/** The Assistant UI runtime for rendering the chat interface */\n\truntime: AssistantRuntime\n}\n\n/**\n * Options for the useStatelessRuntime hook.\n */\nexport interface UseStatelessRuntimeOptions {\n\t/**\n\t * The API base URL for the chat endpoint.\n\t * @default 'http://localhost:3000'\n\t */\n\tapiBase?: string\n\n\t/**\n\t * Optional system prompt to include with requests.\n\t */\n\tsystem?: string\n\n\t/**\n\t * Optional Anthropic API key for devMode.\n\t * When provided, the backend will use Claude instead of Gemini.\n\t */\n\tanthropicApiKey?: string\n}\n\n/**\n * Hook that provides Assistant UI runtime with HTTP streaming (stateless).\n *\n * Unlike the stateful thread runtime, this does NOT:\n * - Use WebSocket connections\n * - Persist messages to a Durable Object\n * - Support refresh-safe streaming\n *\n * This hook IS for:\n * - Development/testing with your own Anthropic API key (devMode)\n * - Anonymous users without authToken\n * - Simple deployments without Durable Objects\n *\n * @param options - Configuration options\n * @returns Assistant UI runtime configured with HTTP streaming\n *\n * @example\n * ```tsx\n * import { AssistantRuntimeProvider } from '@assistant-ui/react'\n *\n * function ChatApp() {\n * const { runtime } = useStatelessRuntime({\n * apiBase: 'http://localhost:3000',\n * });\n *\n * return (\n * <AssistantRuntimeProvider runtime={runtime}>\n * <Thread />\n * </AssistantRuntimeProvider>\n * );\n * }\n * ```\n */\nexport function useStatelessRuntime(options: UseStatelessRuntimeOptions = {}): UseStatelessRuntimeResult {\n\tconst { apiBase = 'http://localhost:3000', anthropicApiKey } = options\n\n\t// Create transport for stateless chat endpoint.\n\t// AssistantChatTransport automatically forwards system messages and\n\t// frontend tools from the assistant-ui context to the backend.\n\tconst transport = useMemo(() => {\n\t\tconst chatApi = `${apiBase}/widget/stateless/chat`\n\n\t\t// Pass Anthropic API key as header when provided (devMode)\n\t\tconst headers = anthropicApiKey\n\t\t\t? { 'X-Anthropic-Api-Key': anthropicApiKey }\n\t\t\t: undefined\n\n\t\treturn new AssistantChatTransport({ api: chatApi, headers })\n\t}, [apiBase, anthropicApiKey])\n\n\t// Use the chat runtime from @assistant-ui/react-ai-sdk\n\t// This handles all the complexity of message state, streaming, etc.\n\tconst runtime = useChatRuntime({\n\t\ttransport,\n\t\t// Auto-send when the last assistant message has completed tool calls\n\t\t// This enables the agentic loop where tool results trigger continuation\n\t\tsendAutomaticallyWhen: (messages) => {\n\t\t\treturn lastAssistantMessageIsCompleteWithToolCalls(messages)\n\t\t},\n\t})\n\n\treturn { runtime }\n}\n","/**\n * AgentUIProvider\n *\n * Manages non-thread UI state that persists across thread switches.\n * This includes open/close status, pill mode, position, and unread indicators.\n *\n * Thread-level state (messages, tool calls, etc.) is managed by @assistant-ui/react.\n * This provider only handles UI-specific state that is independent of the current thread.\n *\n * @example Basic usage\n * ```tsx\n * import { AgentUIProvider, useAgentUI } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return (\n * <AgentUIProvider>\n * <MyComponent />\n * </AgentUIProvider>\n * )\n * }\n *\n * function MyComponent() {\n * const { isOpen, setOpen, userMode, setUserMode } = useAgentUI()\n * // ...\n * }\n * ```\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react'\n\nimport type { FC, ReactNode } from 'react'\n\n/** UI mode for the pill widget */\nexport type PillMode = 'collapsed' | 'hovered' | 'composing' | 'active' | 'expanded'\n\n/** Position for draggable elements */\nexport interface Position {\n\tx: number\n\ty: number\n}\n\n/**\n * Agent UI state - non-thread state that persists across sessions\n */\nexport interface AgentUIState {\n\t/** Whether the agent UI is open (modal or expanded pill) */\n\tisOpen: boolean\n\n\t/** Current pill mode */\n\tuserMode: PillMode\n\n\t/** Drag position offset for the pill */\n\tposition: Position\n\n\t/** Whether there are unread messages */\n\thasUnread: boolean\n\n\t/** Whether voice mode is currently active */\n\tisVoiceActive: boolean\n\n\t/** Whether the pill is in full-screen mode */\n\tisFullScreen: boolean\n}\n\n/**\n * Agent UI context value with state and actions\n */\nexport interface AgentUIContextValue extends AgentUIState {\n\t/** Set the open state */\n\tsetOpen: (open: boolean) => void\n\n\t/** Toggle the open state */\n\ttoggleOpen: () => void\n\n\t/** Set the pill mode */\n\tsetUserMode: (mode: PillMode) => void\n\n\t/** Set the drag position */\n\tsetPosition: (position: Position) => void\n\n\t/** Reset position to default */\n\tresetPosition: () => void\n\n\t/** Mark messages as read */\n\tmarkRead: () => void\n\n\t/** Mark messages as unread */\n\tmarkUnread: () => void\n\n\t/** Set voice active state */\n\tsetVoiceActive: (active: boolean) => void\n\n\t/** Collapse the pill to its default state */\n\tcollapse: () => void\n\n\t/** Expand the pill to composing mode */\n\texpand: () => void\n\n\t/** Enter full-screen mode */\n\tenterFullScreen: () => void\n\n\t/** Exit full-screen mode */\n\texitFullScreen: () => void\n\n\t/** Toggle full-screen mode */\n\ttoggleFullScreen: () => void\n}\n\nconst AgentUIContext = createContext<AgentUIContextValue | null>(null)\n\nconst DEFAULT_POSITION: Position = { x: 0, y: 0 }\n\nexport interface AgentUIProviderProps {\n\tchildren: ReactNode\n\n\t/**\n\t * Controlled open state. When provided, the component is controlled.\n\t * Use with `onOpenChange` to handle state changes.\n\t */\n\topen?: boolean\n\n\t/** Initial open state for uncontrolled usage (default: false) */\n\tdefaultOpen?: boolean\n\n\t/** Initial pill mode (default: 'collapsed') */\n\tdefaultMode?: PillMode\n\n\t/** Callback when open state changes */\n\tonOpenChange?: (open: boolean) => void\n\n\t/** Callback when mode changes */\n\tonModeChange?: (mode: PillMode) => void\n}\n\n/**\n * Provider for non-thread UI state.\n *\n * This state persists across:\n * - Thread switches\n * - Modal open/close\n * - Component remounts\n *\n * Supports both controlled (with `open` prop) and uncontrolled (with `defaultOpen`) usage.\n */\nexport const AgentUIProvider: FC<AgentUIProviderProps> = ({\n\tchildren,\n\topen: controlledOpen,\n\tdefaultOpen = false,\n\tdefaultMode = 'collapsed',\n\tonOpenChange,\n\tonModeChange,\n}) => {\n\t// Determine if we're in controlled mode\n\tconst isControlled = controlledOpen !== undefined\n\n\t// Core UI state - use controlled value if provided, otherwise internal state\n\tconst [internalOpen, setInternalOpen] = useState(defaultOpen)\n\tconst isOpen = isControlled ? controlledOpen : internalOpen\n\n\tconst [userMode, setUserModeState] = useState<PillMode>(defaultMode)\n\tconst [position, setPositionState] = useState<Position>(DEFAULT_POSITION)\n\tconst [hasUnread, setHasUnread] = useState(false)\n\tconst [isVoiceActive, setIsVoiceActiveState] = useState(false)\n\tconst [isFullScreen, setIsFullScreen] = useState(false)\n\n\t// Callback refs to avoid stale closures\n\tconst onOpenChangeRef = useRef(onOpenChange)\n\tconst onModeChangeRef = useRef(onModeChange)\n\tonOpenChangeRef.current = onOpenChange\n\tonModeChangeRef.current = onModeChange\n\n\t// Actions\n\tconst setOpen = useCallback((open: boolean) => {\n\t\t// Always update internal state (for uncontrolled mode)\n\t\tsetInternalOpen(open)\n\t\t// Always call callback (for controlled mode to sync)\n\t\tonOpenChangeRef.current?.(open)\n\t}, [])\n\n\tconst toggleOpen = useCallback(() => {\n\t\tconst next = !isOpen\n\t\tsetInternalOpen(next)\n\t\tonOpenChangeRef.current?.(next)\n\t}, [isOpen])\n\n\tconst setUserMode = useCallback((mode: PillMode) => {\n\t\tsetUserModeState(mode)\n\t\tonModeChangeRef.current?.(mode)\n\t}, [])\n\n\tconst setPosition = useCallback((pos: Position) => {\n\t\tsetPositionState(pos)\n\t}, [])\n\n\tconst resetPosition = useCallback(() => {\n\t\tsetPositionState(DEFAULT_POSITION)\n\t}, [])\n\n\tconst markRead = useCallback(() => {\n\t\tsetHasUnread(false)\n\t}, [])\n\n\tconst markUnread = useCallback(() => {\n\t\tsetHasUnread(true)\n\t}, [])\n\n\tconst setVoiceActive = useCallback((active: boolean) => {\n\t\tsetIsVoiceActiveState(active)\n\t}, [])\n\n\tconst collapse = useCallback(() => {\n\t\tsetUserModeState('collapsed')\n\t\tsetPositionState(DEFAULT_POSITION)\n\t\tsetIsFullScreen(false)\n\t\tonModeChangeRef.current?.('collapsed')\n\t}, [])\n\n\tconst expand = useCallback(() => {\n\t\tsetUserModeState('composing')\n\t\tonModeChangeRef.current?.('composing')\n\t}, [])\n\n\tconst enterFullScreen = useCallback(() => {\n\t\tsetIsFullScreen(true)\n\t}, [])\n\n\tconst exitFullScreen = useCallback(() => {\n\t\tsetIsFullScreen(false)\n\t}, [])\n\n\tconst toggleFullScreen = useCallback(() => {\n\t\tsetIsFullScreen((prev) => !prev)\n\t}, [])\n\n\t// Memoized context value\n\tconst value = useMemo<AgentUIContextValue>(\n\t\t() => ({\n\t\t\t// State\n\t\t\tisOpen,\n\t\t\tuserMode,\n\t\t\tposition,\n\t\t\thasUnread,\n\t\t\tisVoiceActive,\n\t\t\tisFullScreen,\n\n\t\t\t// Actions\n\t\t\tsetOpen,\n\t\t\ttoggleOpen,\n\t\t\tsetUserMode,\n\t\t\tsetPosition,\n\t\t\tresetPosition,\n\t\t\tmarkRead,\n\t\t\tmarkUnread,\n\t\t\tsetVoiceActive,\n\t\t\tcollapse,\n\t\t\texpand,\n\t\t\tenterFullScreen,\n\t\t\texitFullScreen,\n\t\t\ttoggleFullScreen,\n\t\t}),\n\t\t[\n\t\t\tisOpen,\n\t\t\tuserMode,\n\t\t\tposition,\n\t\t\thasUnread,\n\t\t\tisVoiceActive,\n\t\t\tisFullScreen,\n\t\t\tsetOpen,\n\t\t\ttoggleOpen,\n\t\t\tsetUserMode,\n\t\t\tsetPosition,\n\t\t\tresetPosition,\n\t\t\tmarkRead,\n\t\t\tmarkUnread,\n\t\t\tsetVoiceActive,\n\t\t\tcollapse,\n\t\t\texpand,\n\t\t\tenterFullScreen,\n\t\t\texitFullScreen,\n\t\t\ttoggleFullScreen,\n\t\t]\n\t)\n\n\treturn <AgentUIContext.Provider value={value}>{children}</AgentUIContext.Provider>\n}\n\n/**\n * Hook to access agent UI state and actions\n * @throws Error if used outside AgentUIProvider\n */\nexport function useAgentUI(): AgentUIContextValue {\n\tconst context = useContext(AgentUIContext)\n\tif (!context) {\n\t\tthrow new Error('useAgentUI must be used within an AgentUIProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access agent UI state (returns null if not in provider)\n */\nexport function useOptionalAgentUI(): AgentUIContextValue | null {\n\treturn useContext(AgentUIContext)\n}\n\n/**\n * Hook to get just the pill mode (for components that only need mode)\n */\nexport function usePillMode(): PillMode {\n\tconst { userMode } = useAgentUI()\n\treturn userMode\n}\n\n/**\n * Hook to check if agent has unread messages\n */\nexport function useHasUnread(): boolean {\n\tconst { hasUnread } = useAgentUI()\n\treturn hasUnread\n}\n","import { cn } from \"@/utils/cn\";\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"animate-pulse rounded-md bg-accent\", className)}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n","/**\n * Convert InitContextResult error to AuthError\n *\n * Takes the structured error response from the backend and converts it\n * to an AuthError that the error boundary can display properly.\n */\n\nimport type { InitContextResult } from \"@mcp-b/cloud-mirror-types\";\nimport type { AuthError, AuthErrorCode } from \"./auth-errors\";\n\n/**\n * Map backend error codes to frontend error codes\n */\nfunction mapErrorCode(\n backendCode: InitContextResult[\"errorCode\"]\n): AuthErrorCode {\n if (!backendCode) {\n return \"UNKNOWN_ERROR\";\n }\n\n // Most codes map directly\n if (\n [\n \"TOKEN_REQUIRED\",\n \"TOKEN_EXPIRED\",\n \"INVALID_TOKEN\",\n \"INVALID_SIGNATURE\",\n \"INVALID_ISSUER\",\n \"INVALID_AUDIENCE\",\n \"KEY_NOT_FOUND\",\n \"IDP_NOT_CONFIGURED\",\n \"JWKS_FETCH_FAILED\",\n \"ORG_NOT_FOUND\",\n \"ORIGIN_NOT_ALLOWED\",\n ].includes(backendCode)\n ) {\n return backendCode as AuthErrorCode;\n }\n\n return \"UNKNOWN_ERROR\";\n}\n\n/**\n * Convert InitContextResult failure to AuthError\n */\nexport function convertInitErrorToAuthError(\n result: InitContextResult\n): AuthError {\n if (result.success) {\n throw new Error(\"Cannot convert successful result to error\");\n }\n\n const code = mapErrorCode(result.errorCode);\n\n return {\n code,\n title: result.errorTitle || \"Authentication Error\",\n message: result.message,\n callToAction: result.callToAction,\n dashboardLink: result.dashboardLink,\n docsLink: result.docsLink,\n context: result.context,\n recoverable: result.recoverable ?? false,\n debugInfo: result.debugInfo,\n };\n}\n\n/**\n * AuthError class that can be thrown and caught\n */\nexport class AuthErrorException extends Error implements AuthError {\n code: AuthErrorCode;\n title: string;\n callToAction?: AuthError[\"callToAction\"];\n dashboardLink?: string;\n docsLink?: string;\n context?: AuthError[\"context\"];\n recoverable: boolean;\n debugInfo?: string;\n\n constructor(authError: AuthError) {\n super(authError.message);\n this.name = \"AuthErrorException\";\n this.code = authError.code;\n this.title = authError.title;\n this.message = authError.message;\n this.callToAction = authError.callToAction;\n this.dashboardLink = authError.dashboardLink;\n this.docsLink = authError.docsLink;\n this.context = authError.context;\n this.recoverable = authError.recoverable;\n this.debugInfo = authError.debugInfo;\n\n // Maintain proper stack trace\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AuthErrorException);\n }\n }\n}\n\n/**\n * Create and throw an AuthErrorException from InitContextResult\n */\nexport function throwInitError(result: InitContextResult): never {\n const authError = convertInitErrorToAuthError(result);\n throw new AuthErrorException(authError);\n}\n","import { useRef } from 'react'\n\nimport stableStringifyImpl from 'fast-json-stable-stringify'\n\nimport type {\n\tCallToolResult,\n\tHubToSiteMessage,\n\tSyncedToolSchema,\n\tToolSourcesUpdateMessage,\n} from '@mcp-b/cloud-mirror-types'\n\n/**\n * Small internal helpers for `useThreadRuntime`.\n *\n * Keep these React-safe (no module-level mutable state) and dependency-light.\n */\nexport function stableStringify(value: unknown): string {\n\treturn stableStringifyImpl(value ?? null)\n}\n\n/**\n * Generate a short 4-character tab ID.\n * Used for tool name prefixing to ensure unique routing between embedded agent instances.\n *\n * Format: 4 base36 characters (0-9, a-z) giving 1.6M+ possible combinations.\n * Example: \"a3x9\", \"5k2p\", \"zz99\"\n */\nfunction generateShortTabId(): string {\n\tif (typeof window === 'undefined') return 'srvr'\n\n\t// Generate 4-char base36 hash (a-z, 0-9)\n\t// 36^4 = 1,679,616 possible combinations\n\tconst random = Math.floor(Math.random() * 1679616)\n\treturn random.toString(36).padStart(4, '0')\n}\n\n/**\n * Unique tab ID for this embedded agent instance.\n * Generated once at module load time - lives in memory only.\n * Each import of this module gets its own unique ID.\n */\nconst EMBEDDED_AGENT_TAB_ID = generateShortTabId()\n\n/**\n * Get the tab ID for this embedded agent instance.\n * This ID is generated once when the module loads and remains constant.\n *\n * @returns 4-character tab ID unique to this module instance\n */\nexport function getEmbeddedAgentTabId(): string {\n\treturn EMBEDDED_AGENT_TAB_ID\n}\n\nexport function areSyncedToolSchemasEquivalent(\n\ta: readonly SyncedToolSchema[],\n\tb: readonly SyncedToolSchema[],\n): boolean {\n\tif (a === b) return true\n\tif (a.length !== b.length) return false\n\n\tconst byName = new Map<string, SyncedToolSchema>()\n\tfor (const schema of a) byName.set(schema.name, schema)\n\n\tfor (const next of b) {\n\t\tconst prev = byName.get(next.name)\n\t\tif (!prev) return false\n\t\tif ((prev.description ?? '') !== (next.description ?? '')) return false\n\t\tif (stableStringify(prev.inputSchema) !== stableStringify(next.inputSchema)) return false\n\t\tif (stableStringify(prev.annotations ?? null) !== stableStringify(next.annotations ?? null))\n\t\t\treturn false\n\t\tif (stableStringify(prev.sources ?? null) !== stableStringify(next.sources ?? null))\n\t\t\treturn false\n\t}\n\n\treturn true\n}\n\nexport function safeParseHubToSiteMessage(data: unknown): HubToSiteMessage | null {\n\tif (typeof data !== 'string') return null\n\n\ttry {\n\t\tconst parsed = JSON.parse(data) as unknown\n\t\tif (!parsed || typeof parsed !== 'object') return null\n\n\t\tconst msg = parsed as Partial<HubToSiteMessage>\n\t\tif (msg.type === 'ping') return { type: 'ping' }\n\t\tif (\n\t\t\tmsg.type === 'invoke' &&\n\t\t\ttypeof msg.callId === 'string' &&\n\t\t\ttypeof msg.toolName === 'string'\n\t\t) {\n\t\t\treturn {\n\t\t\t\ttype: 'invoke',\n\t\t\t\tcallId: msg.callId,\n\t\t\t\ttoolName: msg.toolName,\n\t\t\t\targs: msg.args as Record<string, unknown> | undefined,\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t} catch {\n\t\treturn null\n\t}\n}\n\nexport function safeParseToolSourcesMessage(data: unknown): ToolSourcesUpdateMessage | null {\n\tif (typeof data !== 'string') return null\n\n\ttry {\n\t\tconst parsed = JSON.parse(data) as unknown\n\t\tif (!parsed || typeof parsed !== 'object') return null\n\n\t\tconst msg = parsed as Partial<ToolSourcesUpdateMessage>\n\t\tif (msg.type !== 'tool_sources' || !Array.isArray(msg.sources)) return null\n\t\treturn { type: 'tool_sources', sources: msg.sources }\n\t} catch {\n\t\treturn null\n\t}\n}\n\nconst SOURCE_ID_RE = /^[0-9a-z]{4}$/i\n\n/**\n * Parse a namespaced tool name of the form `${sourceId}_${toolName}`.\n * sourceId is the 4-character connection identifier.\n *\n * @param name - Tool name, possibly prefixed with sourceId\n * @returns Parsed sourceId and toolName, or null if not namespaced\n */\nexport function parseNamespacedTool(name: string): { sourceId: string; toolName: string } | null {\n\tconst idx = name.indexOf('_')\n\tif (idx === -1) return null\n\tconst sourceId = name.slice(0, idx)\n\tconst toolName = name.slice(idx + 1)\n\tif (!sourceId || !toolName) return null\n\tif (!SOURCE_ID_RE.test(sourceId)) return null\n\treturn { sourceId, toolName }\n}\n\nexport function formatToolResult(result: CallToolResult): string {\n\tconst textContent = result.content.find((c) => c.type === 'text')\n\treturn textContent?.text ?? JSON.stringify(result.content)\n}\n\nexport function sliceMessagesUntil<T extends { id: string }>(\n\tmessages: T[],\n\tparentId: string | null,\n): T[] {\n\tif (parentId === null) return []\n\tconst index = messages.findIndex((m) => m.id === parentId)\n\tif (index === -1) return messages\n\treturn messages.slice(0, index + 1)\n}\n\nfunction shallowEqualRecords(\n\ta: Record<string, unknown> | undefined,\n\tb: Record<string, unknown> | undefined,\n): boolean {\n\tif (a === b) return true\n\tif (!a || !b) return false\n\n\tconst aKeys = Object.keys(a)\n\tconst bKeys = Object.keys(b)\n\tif (aKeys.length !== bKeys.length) return false\n\n\tfor (const key of aKeys) {\n\t\tif (!Object.prototype.hasOwnProperty.call(b, key)) return false\n\t\tif (a[key] !== b[key]) return false\n\t}\n\n\treturn true\n}\n\nexport function useShallowStableObject<T extends Record<string, unknown> | undefined>(value: T): T {\n\tconst ref = useRef(value)\n\tif (!shallowEqualRecords(ref.current, value)) {\n\t\tref.current = value\n\t}\n\treturn ref.current\n}\n","/**\n * useToolSourceMetadata\n *\n * Tracks page metadata (URL, title, favicon) for tool source identification.\n * This metadata helps identify which site tools come from in cross-app RPC scenarios.\n *\n * Simplified version - removed history API patching for safety when embedded on other sites.\n */\n\nimport { useCallback, useEffect, useState } from 'react'\n\nimport type { ToolConnectionMetadata } from '@mcp-b/cloud-mirror-types'\n\nimport { getEmbeddedAgentTabId } from './thread-runtime-utils'\n\n/**\n * Options for useToolSourceMetadata hook.\n */\nexport interface UseToolSourceMetadataOptions {\n\t/**\n\t * Whether to actively track metadata.\n\t * Should be enabled when manager is connected.\n\t */\n\tenabled: boolean\n}\n\n/**\n * Result from useToolSourceMetadata hook.\n */\nexport interface UseToolSourceMetadataResult {\n\t/**\n\t * Current page metadata (URL, title, icon, etc.)\n\t */\n\tmetadata: ToolConnectionMetadata | undefined\n}\n\n/**\n * Hook that tracks page metadata for tool source identification.\n *\n * Tracks:\n * - Page URL and origin\n * - Document title (with observer for SPA title changes)\n * - Favicon URL (with observer for dynamic icon updates)\n * - Tab session ID\n *\n * Simplified from original implementation:\n * - No history API patching (safer for embedded contexts)\n * - No popstate/hashchange listeners (not needed for metadata)\n * - Keeps title/favicon observers for SPA support\n * - Keeps focus/visibilitychange for reconnection scenarios\n *\n * @param options - Configuration options\n * @returns Current page metadata\n */\nexport function useToolSourceMetadata(\n\toptions: UseToolSourceMetadataOptions,\n): UseToolSourceMetadataResult {\n\tconst { enabled } = options\n\tconst tabId = getEmbeddedAgentTabId()\n\n\tconst getMetadata = useCallback((): ToolConnectionMetadata | undefined => {\n\t\tif (typeof window === 'undefined') return undefined\n\n\t\tconst iconUrl = (() => {\n\t\t\ttry {\n\t\t\t\tconst link = document.querySelector(\"link[rel~='icon']\") as HTMLLinkElement | null\n\t\t\t\tconst href = link?.getAttribute('href')\n\t\t\t\tif (!href) return undefined\n\t\t\t\treturn new URL(href, window.location.href).toString()\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t})()\n\n\t\treturn {\n\t\t\turl: window.location.href,\n\t\t\torigin: window.location.origin,\n\t\t\ttitle: document.title?.trim() || undefined,\n\t\t\ticonUrl,\n\t\t\ttabId,\n\t\t}\n\t}, [tabId])\n\n\tconst [metadata, setMetadata] = useState<ToolConnectionMetadata | undefined>(() =>\n\t\tenabled ? getMetadata() : undefined,\n\t)\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\tsetMetadata(undefined)\n\t\t\treturn\n\t\t}\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst updateMetadata = () => {\n\t\t\tsetMetadata(getMetadata())\n\t\t}\n\n\t\t// Set initial metadata\n\t\tupdateMetadata()\n\n\t\t// Listen for focus and visibility changes (for reconnection scenarios)\n\t\twindow.addEventListener('focus', updateMetadata)\n\t\tdocument.addEventListener('visibilitychange', updateMetadata)\n\n\t\t// Watch for title changes (common in SPAs)\n\t\tconst titleObserver = new MutationObserver(updateMetadata)\n\t\tconst titleElement = document.querySelector('title')\n\t\tif (titleElement) {\n\t\t\ttitleObserver.observe(titleElement, { childList: true })\n\t\t}\n\n\t\t// Watch for favicon changes (less common but possible)\n\t\tconst headObserver = new MutationObserver(updateMetadata)\n\t\theadObserver.observe(document.head, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributes: true,\n\t\t\tattributeFilter: ['rel', 'href'],\n\t\t})\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener('focus', updateMetadata)\n\t\t\tdocument.removeEventListener('visibilitychange', updateMetadata)\n\t\t\ttitleObserver.disconnect()\n\t\t\theadObserver.disconnect()\n\t\t}\n\t}, [enabled, getMetadata])\n\n\treturn { metadata }\n}\n","/**\n * useToolSourceRegistration\n *\n * Registers local MCP tools with ThreadManager for cross-app RPC.\n * This allows other sites to discover and invoke tools from this embedding site.\n */\n\nimport { useEffect, useMemo, useRef } from 'react'\n\nimport type { SyncedToolSchema, ToolConnectionMetadata, ToolWithSource, ThreadManagerState } from '@mcp-b/cloud-mirror-types'\nimport type { useAgent } from 'agents/react'\n\nimport { stableStringify } from './thread-runtime-utils'\n\n/**\n * Options for useToolSourceRegistration hook.\n */\nexport interface UseToolSourceRegistrationOptions {\n\t/**\n\t * ThreadManager agent connection.\n\t */\n\tmanager: ReturnType<typeof useAgent<ThreadManagerState>>\n\n\t/**\n\t * MCP tools to register with ThreadManager.\n\t */\n\ttools: ToolWithSource[]\n\n\t/**\n\t * Page metadata for tool source identification.\n\t */\n\tmetadata: ToolConnectionMetadata | undefined\n}\n\n/**\n * Hook that registers local MCP tools with ThreadManager.\n *\n * When tools are registered:\n * - Other sites can discover these tools via ThreadManager\n * - Cross-app RPC can invoke tools from this site\n * - UI can display tool source information (site name, icon, URL)\n *\n * @param options - Configuration options\n */\nexport function useToolSourceRegistration(options: UseToolSourceRegistrationOptions): void {\n\tconst { manager, tools, metadata } = options\n\n\tconst toolsRef = useRef(tools)\n\ttoolsRef.current = tools\n\n\t// Create stable key for tools to detect changes\n\tconst localToolSchemasKey = useMemo(() => {\n\t\tif (!metadata?.tabId) return 'no-tab-id'\n\n\t\tconst schemas: SyncedToolSchema[] =\n\t\t\ttools.map((t) => ({\n\t\t\t\tname: `${metadata.tabId}_${t.name}`, // Prefix with tabId for unique routing\n\t\t\t\tdescription: t.description,\n\t\t\t\tinputSchema: t.inputSchema,\n\t\t\t\tannotations: t.annotations,\n\t\t\t}))\n\n\t\tschemas.sort((a, b) => a.name.localeCompare(b.name))\n\t\treturn stableStringify(schemas)\n\t}, [tools, metadata?.tabId])\n\n\t// Register tools with ThreadManager\n\tuseEffect(() => {\n\t\tconsole.debug('[useToolSourceRegistration] Effect triggered', {\n\t\t\treadyState: manager.readyState,\n\t\t\thasMetadata: !!metadata,\n\t\t\ttoolCount: toolsRef.current.length,\n\t\t\ttoolNames: toolsRef.current.map((t) => t.name),\n\t\t\tlocalToolSchemasKey: localToolSchemasKey.slice(0, 50) + '...',\n\t\t})\n\n\t\tif (manager.readyState !== WebSocket.OPEN) {\n\t\t\tconsole.debug('[useToolSourceRegistration] Skipping: WebSocket not open', manager.readyState)\n\t\t\treturn\n\t\t}\n\n\t\tconst registerTools = async () => {\n\t\t\ttry {\n\t\t\t\tif (!metadata) {\n\t\t\t\t\tconsole.warn('[useToolSourceRegistration] Missing tab metadata; skipping tool registration.')\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst localTools = toolsRef.current\n\t\t\t\tconst toolSchemas: SyncedToolSchema[] = localTools.map((t) => ({\n\t\t\t\t\tname: `${metadata.tabId}_${t.name}`, // Prefix with tabId for unique routing\n\t\t\t\t\tdescription: t.description,\n\t\t\t\t\tinputSchema: t.inputSchema,\n\t\t\t\t\tannotations: t.annotations,\n\t\t\t\t}))\n\n\t\t\t\tconsole.debug('[useToolSourceRegistration] Registering tools with ThreadManager', {\n\t\t\t\t\ttoolCount: toolSchemas.length,\n\t\t\t\t\ttoolNames: toolSchemas.map((t) => t.name),\n\t\t\t\t})\n\n\t\t\t\tif (toolSchemas.length > 0) {\n\t\t\t\t\tawait manager.call('registerTools', [{ tools: toolSchemas, metadata }])\n\t\t\t\t\tconsole.debug('[useToolSourceRegistration] Successfully registered tools')\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[useToolSourceRegistration] Tool registration error:', error)\n\t\t\t}\n\t\t}\n\n\t\tregisterTools()\n\t}, [manager, manager.readyState, localToolSchemasKey, metadata])\n}\n","/**\n * JWT utilities for client-side token handling.\n *\n * SECURITY NOTE: These functions DO NOT validate tokens.\n * Token validation happens server-side in initContextWithIdp.\n * Client-side decoding is only used for DO routing (extracting sub claim).\n */\n\ninterface JWTPayload {\n\tsub?: string\n\t[key: string]: unknown\n}\n\n/**\n * Decode a JWT token to extract the payload.\n * Does NOT validate the signature or claims - use only for routing purposes.\n * Actual validation happens on the backend.\n *\n * @param token - The JWT token to decode\n * @returns The decoded payload, or null if decoding fails\n */\nexport function decodeJWT(token: string): JWTPayload | null {\n\ttry {\n\t\t// JWT format: header.payload.signature\n\t\tconst parts = token.split('.')\n\t\tif (parts.length !== 3) return null\n\n\t\t// Decode the payload (second part)\n\t\tconst payload = parts[1]\n\t\tif (!payload) return null\n\n\t\t// Base64URL decode\n\t\tconst base64 = payload.replace(/-/g, '+').replace(/_/g, '/')\n\t\tconst jsonPayload = decodeURIComponent(\n\t\t\tatob(base64)\n\t\t\t\t.split('')\n\t\t\t\t.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n\t\t\t\t.join(''),\n\t\t)\n\n\t\treturn JSON.parse(jsonPayload) as JWTPayload\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/**\n * Extract the user ID from a JWT token's sub claim.\n * Used for DO routing - actual token validation happens on the backend.\n *\n * @param token - The JWT token\n * @returns The sub claim value, or null if extraction fails (malformed token)\n */\nexport function extractUserIdFromToken(token: string): string | null {\n\tconst payload = decodeJWT(token)\n\treturn payload?.sub ?? null\n}\n","/**\n * useCloudflareThreadAdapter\n *\n * Connects to the ThreadManager Durable Object, initializes context, syncs thread state,\n * and exposes an assistant-ui `ExternalStoreThreadListAdapter` for thread list primitives.\n */\n\nimport type { ExternalStoreThreadListAdapter } from '@assistant-ui/react'\nimport { useAgent } from 'agents/react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport type {\n\tCallToolResult,\n\tCreateThreadParams,\n\tCreateThreadResult,\n\tInitContextResult,\n\tSiteToHubMessage,\n\tThreadManagerState,\n\tThreadSummary,\n\tThreadUpdateParams,\n\tThreadWithDeleted,\n\tToolSourceInfo,\n\tToolWithSource,\n} from '@mcp-b/cloud-mirror-types'\n\nimport { throwInitError } from '../utils/convert-init-error'\nimport { useToolSourceMetadata } from './useToolSourceMetadata'\nimport { useToolSourceRegistration } from './useToolSourceRegistration'\nimport {\n\tgetEmbeddedAgentTabId,\n\tsafeParseHubToSiteMessage,\n\tsafeParseToolSourcesMessage,\n\tstableStringify,\n} from './thread-runtime-utils'\nimport { extractUserIdFromToken } from '../utils/jwt'\n\n/**\n * Options for the useCloudflareThreadAdapter hook.\n */\nexport interface UseCloudflareThreadAdapterOptions {\n\t/**\n\t * The host for the Cloudflare Agent WebSocket connection.\n\t * @default 'localhost:8787'\n\t */\n\thost?: string\n\n\t/**\n\t * IDP token for SSO-first authentication (required).\n\t * The backend validates the token against the org's configured IDP\n\t * and extracts the user ID from the token's sub claim.\n\t *\n\t * The sub claim is also used client-side to route to the correct\n\t * ThreadManager DO instance (one per user).\n\t */\n\tauthToken: string\n\n\t/**\n\t * MCP tools to register with ThreadManager.\n\t * These tools will be available for cross-app RPC.\n\t */\n\tmcpTools?: ToolWithSource[]\n\n\t/**\n\t * Function to execute MCP tools locally.\n\t */\n\texecuteMCPTool?: (\n\t\ttoolName: string,\n\t\targs: Record<string, unknown>,\n\t) => Promise<CallToolResult>\n\n\t/**\n\t * Persist the last-selected thread in localStorage.\n\t * @default true\n\t */\n\tpersistSelection?: boolean\n\n\t/**\n\t * Override the localStorage key used for selection persistence.\n\t * If omitted, a key is derived from the resolved endUserId.\n\t */\n\tselectionStorageKey?: string\n}\n\n/**\n * Result from useCloudflareThreadAdapter.\n */\nexport interface UseCloudflareThreadAdapterResult {\n\t/**\n\t * Current selected thread ID.\n\t */\n\tcurrentThreadId: string | undefined\n\n\t/**\n\t * Set the current selected thread ID.\n\t */\n\tsetCurrentThreadId: (threadId: string | undefined) => void\n\n\t/**\n\t * assistant-ui adapter for thread list primitives.\n\t */\n\tthreadListAdapter: ExternalStoreThreadListAdapter\n\n\t/**\n\t * Whether initContext() has completed successfully.\n\t */\n\tisInitialized: boolean\n\n\t/**\n\t * Whether the WebSocket is currently connected.\n\t */\n\tisConnected: boolean\n\n\t/**\n\t * Whether the thread list has synced at least once and initContext is ready.\n\t */\n\tisReady: boolean\n\n\t/**\n\t * The internal end_users.id resolved from initContext().\n\t */\n\tendUserId: string | null\n\n\t/**\n\t * Organization ID resolved from initContext.\n\t * SSO-First: Org-level only (no site concept).\n\t */\n\torganizationId: string | null\n\n\t/**\n\t * The ThreadManager agent connection (for tool registration, etc.).\n\t */\n\tmanager: ReturnType<typeof useAgent<ThreadManagerState>>\n\n\t/**\n\t * Available tool sources from ThreadManager.\n\t * Used for cross-app RPC tool routing.\n\t */\n\ttoolSources: ToolSourceInfo[]\n\n\t/**\n\t * Authentication error from initContext (if failed).\n\t * Used to display error UI when IDP token validation fails.\n\t */\n\tauthError: import('../utils/auth-errors').AuthError | null\n}\n\nfunction sortThreadsByRecency<\n\tT extends { lastMessageAt: number | null; createdAt: number },\n>(list: readonly T[]): T[] {\n\treturn [...list].sort((a, b) => {\n\t\tconst aTime = a.lastMessageAt ?? a.createdAt\n\t\tconst bTime = b.lastMessageAt ?? b.createdAt\n\t\treturn bTime - aTime\n\t})\n}\n\nfunction isRegularThread(thread: ThreadSummary): thread is ThreadSummary & { status: 'regular' } {\n\treturn thread.status === 'regular'\n}\n\nfunction isArchivedThread(\n\tthread: ThreadSummary,\n): thread is ThreadSummary & { status: 'archived' } {\n\treturn thread.status === 'archived'\n}\n\nfunction areThreadListsEquivalent(\n\ta: readonly ThreadWithDeleted[],\n\tb: readonly ThreadWithDeleted[],\n): boolean {\n\tif (a === b) return true\n\tif (a.length !== b.length) return false\n\n\tconst byId = new Map<string, ThreadWithDeleted>()\n\tfor (const thread of a) byId.set(thread.id, thread)\n\n\tfor (const next of b) {\n\t\tconst prev = byId.get(next.id)\n\t\tif (!prev) return false\n\n\t\tif (prev.status !== next.status) return false\n\t\tif ((prev.title ?? '') !== (next.title ?? '')) return false\n\t\tif ((prev.remoteId ?? '') !== (next.remoteId ?? '')) return false\n\t\tif ((prev.externalId ?? '') !== (next.externalId ?? '')) return false\n\t\tif (prev.organizationId !== next.organizationId) return false\n\t\tif (prev.messageCount !== next.messageCount) return false\n\t\tif ((prev.totalTokens ?? 0) !== (next.totalTokens ?? 0)) return false\n\t\tif (prev.lastMessageAt !== next.lastMessageAt) return false\n\t\tif (prev.createdAt !== next.createdAt) return false\n\t}\n\n\treturn true\n}\n\n/**\n * Hook that manages thread list state and syncs with ThreadManager DO.\n *\n * This hook:\n * 1. Connects to ThreadManager via WebSocket\n * 2. Calls initContextWithIdp() to resolve internal IDs from the IDP token\n * 3. Subscribes to state updates (thread list changes)\n * 4. Exposes assistant-ui thread list adapter\n */\nexport function useCloudflareThreadAdapter(\n\toptions: UseCloudflareThreadAdapterOptions,\n): UseCloudflareThreadAdapterResult {\n\tconst {\n\t\thost,\n\t\tauthToken,\n\t\tmcpTools,\n\t\texecuteMCPTool,\n\t\tpersistSelection = true,\n\t\tselectionStorageKey,\n\t} = options\n\n\t// Extract user ID from token's sub claim for DO routing\n\t// The backend will validate the full token in initContextWithIdp\n\tconst userId = extractUserIdFromToken(authToken)\n\tconst fallbackUserIdRef = useRef(\n\t\t`anon-${Math.random().toString(36).slice(2, 10)}`,\n\t)\n\tconst effectiveUserId = userId ?? fallbackUserIdRef.current\n\n\tconst [isInitialized, setIsInitialized] = useState(false)\n\tconst [initialSyncComplete, setInitialSyncComplete] = useState(false)\n\tconst [endUserId, setEndUserId] = useState<string | null>(null)\n\tconst [organizationId, setOrganizationId] = useState<string | null>(null)\n\tconst [authError, setAuthError] = useState<import('../utils/auth-errors').AuthError | null>(null)\n\tconst [threads, setThreads] = useState<ThreadWithDeleted[]>([])\n\tconst [currentThreadId, setCurrentThreadId] = useState<string | undefined>(undefined)\n\tconst [persistedThreadId, setPersistedThreadId] = useState<string | null>(null)\n\n\tconst initPromiseRef = useRef<Promise<InitContextResult> | null>(null)\n\tconst didApplyPersistedSelectionRef = useRef(false)\n\n\tconst effectiveSelectionStorageKey = useMemo(() => {\n\t\tif (!persistSelection) return null\n\t\tif (selectionStorageKey) return selectionStorageKey\n\t\tif (!endUserId) return null\n\t\treturn `webmcp:threads:lastThreadId:${endUserId}`\n\t}, [persistSelection, selectionStorageKey, endUserId])\n\n\t// Connect to ThreadManager DO (one per user, keyed by token sub claim)\n\t// The DO name must be stable - we extract it from the token without validation.\n\t// Actual token validation happens server-side in initContextWithIdp.\n\tconst manager = useAgent<ThreadManagerState>({\n\t\tagent: 'ThreadManager',\n\t\tname: effectiveUserId,\n\t\thost,\n\t\tquery: { auth_token: authToken },\n\t\tonStateUpdate: (state, source) => {\n\t\t\tsetThreads((prev) =>\n\t\t\t\tareThreadListsEquivalent(prev, state.threads) ? prev : state.threads,\n\t\t\t)\n\t\t\tif (source === 'server') setInitialSyncComplete(true)\n\t\t},\n\t})\n\n\t// Get unique ID for this embedded agent instance\n\t// Generated at module load time - lives in memory only\n\tconst tabId = getEmbeddedAgentTabId()\n\n\t// Track tool sources from ThreadManager\n\tconst [toolSources, setToolSources] = useState<ToolSourceInfo[]>([])\n\tuseEffect(() => {\n\t\tconst handleMessage = (event: MessageEvent) => {\n\t\t\tconst message = safeParseToolSourcesMessage(event.data)\n\t\t\tif (!message) return\n\t\t\tsetToolSources((prev) =>\n\t\t\t\tstableStringify(prev) === stableStringify(message.sources) ? prev : message.sources,\n\t\t\t)\n\t\t}\n\t\tmanager.addEventListener('message', handleMessage)\n\t\treturn () => manager.removeEventListener('message', handleMessage)\n\t}, [manager])\n\n\t// Track page metadata for tool source identification\n\tconst { metadata } = useToolSourceMetadata({\n\t\tenabled: manager.readyState === WebSocket.OPEN && isInitialized,\n\t})\n\n\t// Register local tools with ThreadManager\n\tuseToolSourceRegistration({\n\t\tmanager,\n\t\ttools: mcpTools ?? [],\n\t\tmetadata,\n\t})\n\n\t// Widget-level tool invocation handler\n\tuseEffect(() => {\n\t\tif (!executeMCPTool) return\n\t\tif (!tabId) return\n\n\t\tconst handleMessage = async (event: MessageEvent) => {\n\t\t\tconst msg = safeParseHubToSiteMessage(event.data)\n\t\t\tif (!msg) return\n\n\t\t\tif (msg.type === 'invoke') {\n\t\t\t\t// Server already targeted us - just execute\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await executeMCPTool(msg.toolName, msg.args ?? {})\n\t\t\t\t\tconst response: SiteToHubMessage = {\n\t\t\t\t\t\ttype: 'result',\n\t\t\t\t\t\tcallId: msg.callId,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t}\n\t\t\t\t\tmanager.send(JSON.stringify(response))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst response: SiteToHubMessage = {\n\t\t\t\t\t\ttype: 'result',\n\t\t\t\t\t\tcallId: msg.callId,\n\t\t\t\t\t\tresult: {\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\ttext: error instanceof Error ? error.message : 'Tool execution failed',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\tmanager.send(JSON.stringify(response))\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (msg.type === 'ping') {\n\t\t\t\tconst response: SiteToHubMessage = { type: 'pong' }\n\t\t\t\tmanager.send(JSON.stringify(response))\n\t\t\t}\n\t\t}\n\n\t\tmanager.addEventListener('message', handleMessage)\n\t\treturn () => manager.removeEventListener('message', handleMessage)\n\t}, [executeMCPTool, tabId, manager])\n\n\t// Reset local state when identity inputs change\n\tuseEffect(() => {\n\t\tinitPromiseRef.current = null\n\t\tdidApplyPersistedSelectionRef.current = false\n\t\tsetIsInitialized(false)\n\t\tsetInitialSyncComplete(false)\n\t\tsetEndUserId(null)\n\t\tsetOrganizationId(null)\n\t\tsetThreads([])\n\t\tsetCurrentThreadId(undefined)\n\t\tsetPersistedThreadId(null)\n\t}, [authToken])\n\n\t// If the ThreadManager connection drops, force initContext() again on the next reconnect.\n\t// Durable Objects and WebSocket sessions can restart independently of client state.\n\tuseEffect(() => {\n\t\tif (manager.readyState === WebSocket.OPEN) return\n\n\t\tinitPromiseRef.current = null\n\t\tsetIsInitialized(false)\n\t\tsetInitialSyncComplete(false)\n\t}, [manager.readyState])\n\n\t// Load persisted selection once we can derive a stable storage key.\n\tuseEffect(() => {\n\t\tif (!effectiveSelectionStorageKey) return\n\t\ttry {\n\t\t\tsetPersistedThreadId(localStorage.getItem(effectiveSelectionStorageKey))\n\t\t} catch {\n\t\t\tsetPersistedThreadId(null)\n\t\t}\n\t}, [effectiveSelectionStorageKey])\n\n\tconst ensureInitialized = useCallback(async (): Promise<void> => {\n\t\tif (manager.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new Error('ThreadManager is not connected')\n\t\t}\n\n\t\tif (!initPromiseRef.current) {\n\t\t\t// SSO-first: use IDP token authentication\n\t\t\t// Origin is automatically included by the browser in WebSocket handshake\n\t\t\tconst origin = typeof window !== 'undefined' ? window.location.origin : undefined\n\t\t\tinitPromiseRef.current = manager.call<InitContextResult>('initContextWithIdp', [\n\t\t\t\t{ authToken, origin },\n\t\t\t])\n\t\t}\n\n\t\tconst initResult = await initPromiseRef.current\n\t\tif (!initResult.success) {\n\t\t\tthrowInitError(initResult)\n\t\t}\n\n\t\tsetEndUserId(initResult.endUserId)\n\t\tif (initResult.organizationId) setOrganizationId(initResult.organizationId)\n\t\tsetIsInitialized(true)\n\t}, [manager, authToken])\n\n\tuseEffect(() => {\n\t\tif (manager.readyState !== WebSocket.OPEN) return\n\t\tif (isInitialized) return\n\t\tif (authError) return // Don't retry if we already have an error\n\n\t\tensureInitialized().catch((error) => {\n\t\t\tconsole.error('[useCloudflareThreadAdapter] initContext error:', error)\n\t\t\t// If it's an AuthErrorException, extract the error details\n\t\t\tif (error && typeof error === 'object' && 'code' in error && 'title' in error) {\n\t\t\t\tsetAuthError(error as import('../utils/auth-errors').AuthError)\n\t\t\t}\n\t\t})\n\t}, [manager.readyState, isInitialized, authError, ensureInitialized])\n\n\tconst filteredNonDeleted = useMemo((): ThreadSummary[] => {\n\t\t// SSO-First: Org-level threads only (no site filtering)\n\t\treturn threads.filter((t): t is ThreadSummary => t.status !== 'deleted')\n\t}, [threads])\n\n\tconst activeThreads = useMemo(\n\t\t() => sortThreadsByRecency(filteredNonDeleted.filter(isRegularThread)),\n\t\t[filteredNonDeleted],\n\t)\n\n\tconst archivedThreads = useMemo(\n\t\t() => sortThreadsByRecency(filteredNonDeleted.filter(isArchivedThread)),\n\t\t[filteredNonDeleted],\n\t)\n\n\tuseEffect(() => {\n\t\t// Selection policy for embedded agent:\n\t\t// - Prefer the persisted thread if it's still active\n\t\t// - Otherwise pick the most recent active thread\n\t\t// - Do NOT auto-select archived threads (archive is one-way hide in v1)\n\t\tif (currentThreadId) return\n\t\tconst preferred =\n\t\t\tpersistedThreadId && activeThreads.some((t) => t.id === persistedThreadId)\n\t\t\t\t? persistedThreadId\n\t\t\t\t: null\n\t\tconst fallback = activeThreads[0]?.id ?? undefined\n\t\tif (preferred) setCurrentThreadId(preferred)\n\t\telse if (fallback) setCurrentThreadId(fallback)\n\t}, [currentThreadId, activeThreads, persistedThreadId])\n\n\tuseEffect(() => {\n\t\t// If the selected thread disappears (deleted elsewhere), pick a new one.\n\t\tif (!currentThreadId) return\n\t\tconst exists = filteredNonDeleted.some((t) => t.id === currentThreadId)\n\t\tif (exists) return\n\t\tsetCurrentThreadId(activeThreads[0]?.id ?? undefined)\n\t}, [currentThreadId, filteredNonDeleted, activeThreads])\n\n\tconst isConnected = manager.readyState === WebSocket.OPEN\n\tconst isReady = isConnected && isInitialized && initialSyncComplete\n\tconst isLoading = !isReady\n\n\t// If we loaded a persisted selection after a fallback was chosen, apply it once.\n\tuseEffect(() => {\n\t\tif (!isReady) return\n\t\tif (!persistedThreadId) return\n\t\tif (!activeThreads.some((t) => t.id === persistedThreadId)) return\n\t\tif (didApplyPersistedSelectionRef.current) return\n\n\t\tdidApplyPersistedSelectionRef.current = true\n\t\tif (currentThreadId !== persistedThreadId) setCurrentThreadId(persistedThreadId)\n\t}, [isReady, persistedThreadId, activeThreads, currentThreadId])\n\n\tconst createThread = useCallback(async (): Promise<string> => {\n\t\tawait ensureInitialized()\n\n\t\tconst params = {\n\t\t\t...(organizationId ? { organizationId } : {}),\n\t\t} satisfies CreateThreadParams\n\n\t\tconst result = await manager.call<CreateThreadResult>('createThread', [params])\n\t\tsetCurrentThreadId(result.threadId)\n\t\treturn result.threadId\n\t}, [ensureInitialized, manager, organizationId])\n\n\tconst threadListAdapter: ExternalStoreThreadListAdapter = useMemo(\n\t\t() => ({\n\t\t\tthreadId: currentThreadId,\n\t\t\tisLoading,\n\t\t\tthreads: activeThreads,\n\t\t\tarchivedThreads,\n\n\t\t\tonSwitchToNewThread: async () => {\n\t\t\t\tawait createThread()\n\t\t\t},\n\n\t\t\tonSwitchToThread: (threadId: string) => {\n\t\t\t\tsetCurrentThreadId(threadId)\n\t\t\t},\n\n\t\t\tonRename: async (threadId: string, newTitle: string) => {\n\t\t\t\tawait ensureInitialized()\n\t\t\t\tawait manager.call('updateThread', [\n\t\t\t\t\tthreadId,\n\t\t\t\t\t{ title: newTitle } satisfies ThreadUpdateParams,\n\t\t\t\t])\n\t\t\t},\n\n\t\t\tonArchive: async (threadId: string) => {\n\t\t\t\tawait ensureInitialized()\n\t\t\t\tawait manager.call('archiveThread', [threadId])\n\t\t\t\tif (threadId === currentThreadId) {\n\t\t\t\t\tconst nextActive = activeThreads.filter((t) => t.id !== threadId)[0]?.id\n\t\t\t\t\tif (nextActive) {\n\t\t\t\t\t\tsetCurrentThreadId(nextActive)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// If the user archived their last active thread, immediately create a new one.\n\t\t\t\t\tawait createThread()\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonUnarchive: async (threadId: string) => {\n\t\t\t\tawait ensureInitialized()\n\t\t\t\tawait manager.call('restoreThread', [threadId])\n\t\t\t},\n\n\t\t\tonDelete: async (threadId: string) => {\n\t\t\t\tawait ensureInitialized()\n\t\t\t\tawait manager.call('deleteThread', [threadId])\n\t\t\t\tif (threadId === currentThreadId) {\n\t\t\t\t\tsetCurrentThreadId(activeThreads.filter((t) => t.id !== threadId)[0]?.id)\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\t[\n\t\t\tcurrentThreadId,\n\t\t\tisLoading,\n\t\t\tactiveThreads,\n\t\t\tarchivedThreads,\n\t\t\tcreateThread,\n\t\t\tensureInitialized,\n\t\t\tmanager,\n\t\t],\n\t)\n\n\t// Persist selection once ready and we have a stable key.\n\tuseEffect(() => {\n\t\tif (!effectiveSelectionStorageKey) return\n\t\tif (!isReady) return\n\t\tif (!currentThreadId) return\n\t\tif (!activeThreads.some((t) => t.id === currentThreadId)) return\n\n\t\ttry {\n\t\t\tlocalStorage.setItem(effectiveSelectionStorageKey, currentThreadId)\n\t\t} catch {\n\t\t\t// Ignore storage failures (private browsing, quota, etc.)\n\t\t}\n\t}, [effectiveSelectionStorageKey, isReady, currentThreadId, activeThreads])\n\n\treturn {\n\t\tcurrentThreadId,\n\t\tsetCurrentThreadId,\n\t\tthreadListAdapter,\n\t\tisInitialized,\n\t\tisConnected,\n\t\tisReady,\n\t\tendUserId,\n\t\torganizationId,\n\t\tauthError,\n\t\tmanager,\n\t\ttoolSources,\n\t}\n}\n","import {\n\tunstable_createMessageConverter,\n\ttype useExternalMessageConverter,\n\ttype ReasoningMessagePart,\n\ttype ToolCallMessagePart,\n\ttype TextMessagePart,\n\ttype SourceMessagePart,\n} from '@assistant-ui/react'\nimport { getToolName, isToolUIPart } from 'ai'\n\nimport type { UIMessage } from 'ai'\n\n// Type for message parts from the AI SDK\ntype MessagePart = NonNullable<UIMessage['parts']>[number]\n\n// JSON object type for tool args\ntype JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue }\ntype JSONObject = { [key: string]: JSONValue }\n\n/**\n * Strips incomplete JSON closing delimiters for streaming args.\n * The AI SDK's fix-json adds these during streaming, but they're not final.\n */\nfunction stripClosingDelimiters(json: string) {\n\treturn json.replace(/[}\\]\"]+$/, '')\n}\n\nfunction getRawInput(part: unknown): string | null {\n\tconst rawInput = (part as { rawInput?: unknown } | null)?.rawInput\n\treturn typeof rawInput === 'string' && rawInput.length > 0 ? rawInput : null\n}\n\n/**\n * Converts message parts from Cloudflare Agents SDK format to Assistant UI format.\n *\n * Key differences from simple conversion:\n * - Receives metadata with toolStatuses for interrupt/requires-action handling\n * - Properly handles all tool states: input-streaming, input-available, output-available, output-error\n * - Adds status: { type: 'requires-action' } when tool has interrupt status\n */\nconst convertParts = (\n\tmessage: UIMessage,\n\tmetadata: useExternalMessageConverter.Metadata\n): Array<\n\tTextMessagePart | ReasoningMessagePart | ToolCallMessagePart | SourceMessagePart\n> => {\n\tif (!message.parts || message.parts.length === 0) {\n\t\treturn []\n\t}\n\n\treturn message.parts\n\t\t.filter((p) => p.type !== 'step-start' && p.type !== 'file')\n\t\t.map((part: MessagePart) => {\n\t\t\tconst type = part.type\n\n\t\t\t// Handle text parts\n\t\t\tif (type === 'text') {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\ttext: part.text,\n\t\t\t\t} satisfies TextMessagePart\n\t\t\t}\n\n\t\t\t// Handle reasoning parts\n\t\t\tif (type === 'reasoning') {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'reasoning',\n\t\t\t\t\ttext: part.text,\n\t\t\t\t} satisfies ReasoningMessagePart\n\t\t\t}\n\n\t\t\t// Handle tool-* parts (AI SDK v5 tool calls)\n\t\t\tif (isToolUIPart(part)) {\n\t\t\t\tconst toolName = getToolName(part)\n\t\t\t\tconst toolCallId = part.toolCallId\n\n\t\t\t\t// Extract args and result based on state\n\t\t\t\tlet args: JSONObject = {}\n\t\t\t\tlet argsText: string\n\t\t\t\tlet result: unknown\n\t\t\t\tlet isError = false\n\n\t\t\t\t// Always prefer rawInput when present to keep argsText append-only across streaming.\n\t\t\t\t// This avoids assistant-ui errors like:\n\t\t\t\t// \"Tool call argsText can only be appended, not updated\"\n\t\t\t\tconst rawInput = getRawInput(part)\n\n\t\t\t\tif (part.state === 'input-streaming' || part.state === 'input-available') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t} else if (part.state === 'output-available') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t\tresult = part.output\n\t\t\t\t} else if (part.state === 'output-error') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t\tisError = true\n\t\t\t\t\tresult = { error: part.errorText }\n\t\t\t\t}\n\n\t\t\t\tif (rawInput) {\n\t\t\t\t\targsText = rawInput\n\t\t\t\t} else if (part.state === 'input-streaming') {\n\t\t\t\t\t// Avoid non-append-only transitions like \"{}\" -> \"{...}\".\n\t\t\t\t\t// assistant-ui requires argsText to only ever append during streaming.\n\t\t\t\t\targsText = ''\n\t\t\t\t} else {\n\t\t\t\t\targsText = JSON.stringify(part.input ?? args)\n\t\t\t\t}\n\t\t\t\tif (part.state === 'input-streaming') {\n\t\t\t\t\t// The argsText is not complete during streaming\n\t\t\t\t\targsText = stripClosingDelimiters(argsText)\n\t\t\t\t}\n\n\t\t\t\t// Check tool status from metadata - this is the key for requires-action\n\t\t\t\tconst toolStatus = metadata.toolStatuses?.[toolCallId]\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool-call',\n\t\t\t\t\ttoolName,\n\t\t\t\t\ttoolCallId,\n\t\t\t\t\targsText,\n\t\t\t\t\targs,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\t// Add interrupt and requires-action status if tool is interrupted\n\t\t\t\t\t...(toolStatus?.type === 'interrupt' && {\n\t\t\t\t\t\tinterrupt: toolStatus.payload,\n\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\ttype: 'requires-action' as const,\n\t\t\t\t\t\t\treason: 'interrupt',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t} satisfies ToolCallMessagePart\n\t\t\t}\n\n\t\t\t// Handle dynamic-tool parts\n\t\t\tif (type === 'dynamic-tool') {\n\t\t\t\tconst toolName = part.toolName\n\t\t\t\tconst toolCallId = part.toolCallId\n\n\t\t\t\tlet args: JSONObject = {}\n\t\t\t\tlet argsText: string\n\t\t\t\tlet result: unknown\n\t\t\t\tlet isError = false\n\n\t\t\t\tif (part.state === 'input-streaming' || part.state === 'input-available') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t} else if (part.state === 'output-available') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t\tresult = part.output\n\t\t\t\t} else if (part.state === 'output-error') {\n\t\t\t\t\targs = (part.input as JSONObject) || {}\n\t\t\t\t\tisError = true\n\t\t\t\t\tresult = { error: part.errorText }\n\t\t\t\t}\n\n\t\t\t\tconst rawInput = getRawInput(part)\n\t\t\t\tif (rawInput) {\n\t\t\t\t\targsText = rawInput\n\t\t\t\t} else if (part.state === 'input-streaming') {\n\t\t\t\t\targsText = ''\n\t\t\t\t} else {\n\t\t\t\t\targsText = JSON.stringify(part.input ?? args)\n\t\t\t\t}\n\t\t\t\tif (part.state === 'input-streaming') {\n\t\t\t\t\targsText = stripClosingDelimiters(argsText)\n\t\t\t\t}\n\n\t\t\t\tconst toolStatus = metadata.toolStatuses?.[toolCallId]\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool-call',\n\t\t\t\t\ttoolName,\n\t\t\t\t\ttoolCallId,\n\t\t\t\t\targsText,\n\t\t\t\t\targs,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\t...(toolStatus?.type === 'interrupt' && {\n\t\t\t\t\t\tinterrupt: toolStatus.payload,\n\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\ttype: 'requires-action' as const,\n\t\t\t\t\t\t\treason: 'interrupt',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t} satisfies ToolCallMessagePart\n\t\t\t}\n\n\t\t\t// Handle source-url parts\n\t\t\tif (type === 'source-url') {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'source',\n\t\t\t\t\tsourceType: 'url',\n\t\t\t\t\tid: part.sourceId,\n\t\t\t\t\turl: part.url,\n\t\t\t\t\ttitle: part.title || '',\n\t\t\t\t} satisfies SourceMessagePart\n\t\t\t}\n\n\t\t\t// Handle source-document parts (not yet fully supported)\n\t\t\tif (type === 'source-document') {\n\t\t\t\tconsole.warn(`Source document part type ${type} is not yet supported in conversion`)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// For unsupported types, skip them\n\t\t\tconsole.warn(`Unsupported message part type: ${type}`)\n\t\t\treturn null\n\t\t})\n\t\t.filter(Boolean) as Array<\n\t\tTextMessagePart | ReasoningMessagePart | ToolCallMessagePart | SourceMessagePart\n\t>\n}\n\n/**\n * Message converter for Cloudflare Agents SDK messages.\n *\n * Uses unstable_createMessageConverter to receive metadata including toolStatuses,\n * which is required for the requires-action status to work with Assistant UI's\n * native tool confirmation flow.\n *\n * Usage:\n * ```ts\n * const messages = CloudflareMessageConverter.useThreadMessages({\n * isRunning,\n * messages: chat.messages,\n * metadata: useMemo(() => ({\n * toolStatuses,\n * ...(chat.error && { error: chat.error.message }),\n * }), [toolStatuses, chat.error]),\n * })\n * ```\n */\nexport const CloudflareMessageConverter = unstable_createMessageConverter(\n\t(message: UIMessage, metadata: useExternalMessageConverter.Metadata) => {\n\t\tconst createdAt = new Date()\n\n\t\tswitch (message.role) {\n\t\t\tcase 'user': {\n\t\t\t\tconst fileParts = message.parts?.filter(\n\t\t\t\t\t(p): p is Extract<MessagePart, { type: 'file' }> => p.type === 'file'\n\t\t\t\t)\n\t\t\t\tconst attachments = fileParts?.map((part, idx) => ({\n\t\t\t\t\tid: idx.toString(),\n\t\t\t\t\ttype: part.mediaType?.startsWith('image/') ? ('image' as const) : ('file' as const),\n\t\t\t\t\tname: part.filename ?? 'file',\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\tpart.mediaType?.startsWith('image/')\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttype: 'image' as const,\n\t\t\t\t\t\t\t\t\timage: part.url,\n\t\t\t\t\t\t\t\t\tfilename: part.filename ?? 'file',\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\ttype: 'file' as const,\n\t\t\t\t\t\t\t\t\tfilename: part.filename ?? 'file',\n\t\t\t\t\t\t\t\t\tdata: part.url,\n\t\t\t\t\t\t\t\t\tmimeType: part.mediaType ?? 'application/octet-stream',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tcontentType: part.mediaType ?? 'application/octet-stream',\n\t\t\t\t\tstatus: { type: 'complete' as const },\n\t\t\t\t}))\n\t\t\t\treturn {\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tcreatedAt,\n\t\t\t\t\tcontent: convertParts(message, metadata),\n\t\t\t\t\tattachments,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcase 'system':\n\t\t\t\treturn {\n\t\t\t\t\trole: 'system',\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tcreatedAt,\n\t\t\t\t\tcontent: convertParts(message, metadata),\n\t\t\t\t}\n\n\t\t\tcase 'assistant': {\n\t\t\t\t// Type cast is safe: message comes from Vercel AI SDK's UIMessage type.\n\t\t\t\t// The `annotations` and `data` properties are optional AI SDK extensions\n\t\t\t\t// that may or may not be present. Cast allows access without runtime errors.\n\t\t\t\t// No security risk since we're only reading optional fields from a trusted source.\n\t\t\t\tconst msgWithMeta = message as unknown as {\n\t\t\t\t\tannotations?: JSONValue[]\n\t\t\t\t\tdata?: JSONValue | JSONValue[]\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tcreatedAt,\n\t\t\t\t\tcontent: convertParts(message, metadata),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tunstable_annotations: msgWithMeta.annotations,\n\t\t\t\t\t\tunstable_data: Array.isArray(msgWithMeta.data)\n\t\t\t\t\t\t\t? msgWithMeta.data\n\t\t\t\t\t\t\t: msgWithMeta.data\n\t\t\t\t\t\t\t\t? [msgWithMeta.data]\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tcustom: {},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tconsole.warn(`Unsupported message role: ${message.role}`)\n\t\t\t\treturn []\n\t\t}\n\t}\n)\n\nexport { CloudflareMessageConverter as default }\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport {\n\tINTERNAL,\n\tuseExternalStoreRuntime,\n\tuseRuntimeAdapters,\n\ttype AppendMessage,\n\ttype AssistantRuntime,\n\ttype ThreadMessage,\n\ttype ToolExecutionStatus,\n} from '@assistant-ui/react'\nimport {\n\ttype CallToolResult,\n\ttype ThreadMetadata,\n\ttype ThreadManagerState,\n\ttype ThreadToolSelection,\n\ttype ToolApprovalMode,\n\ttype ToolSourceInfo,\n\ttype ToolWithSource,\n} from '@mcp-b/cloud-mirror-types'\nimport { useAgentChat, type AITool } from 'agents/ai-react'\nimport { useAgent } from 'agents/react'\nimport { getToolName, isToolUIPart, type UIMessage } from 'ai'\n\nimport { CloudflareMessageConverter } from '../utils/converter'\nimport { isToolDestructive } from '../utils/tool-approval'\nimport {\n\tformatToolResult,\n\tgetEmbeddedAgentTabId,\n\tsliceMessagesUntil,\n\tuseShallowStableObject,\n} from './thread-runtime-utils'\n\nconst DISCONNECTED_THREAD_ID = '__disconnected__'\n\n/**\n * State for ThreadAgent DO.\n */\ninterface ThreadAgentState {\n\tthreadMetadata: ThreadMetadata | null\n\ttoolSelection: ThreadToolSelection | null\n}\n\n/**\n * Frontend tool definition.\n */\nexport type FrontendTool<TInput = unknown, TOutput = unknown> = AITool<TInput, TOutput>\nexport type FrontendTools = Record<string, FrontendTool>\n\n/**\n * Options for the useThreadRuntime hook.\n */\nexport interface UseThreadRuntimeOptions {\n\t/**\n\t * The thread ID to connect to.\n\t * When null/undefined, the hook returns a minimal disconnected runtime.\n\t */\n\tthreadId: string | null | undefined\n\n\t/**\n\t * The host for Cloudflare Agent WebSocket connections.\n\t */\n\thost?: string\n\n\t/**\n\t * IDP token for SSO-first authentication (required).\n\t * Used for WebSocket authentication to ThreadAgent DO.\n\t */\n\tauthToken: string\n\n\t/**\n\t * ThreadManager agent instance (reused from parent adapter).\n\t * NOTE: Not currently used in frontend. Reserved for future server-side tool routing.\n\t */\n\tmanager: ReturnType<typeof useAgent<ThreadManagerState>>\n\n\t/**\n\t * MCP tools to sync to the backend.\n\t */\n\tmcpTools?: ToolWithSource[]\n\n\t/**\n\t * Function to execute MCP tools locally.\n\t */\n\texecuteMCPTool?: (\n\t\ttoolName: string,\n\t\targs: Record<string, unknown>,\n\t) => Promise<CallToolResult>\n\n\t/**\n\t * Tool approval mode.\n\t * @default 'ask'\n\t */\n\tapprovalMode?: ToolApprovalMode\n\n\t/**\n\t * Cancel pending tool calls on new message.\n\t * @default true\n\t */\n\tcancelPendingToolCallsOnSend?: boolean\n\n\t/**\n\t * Available tool sources from ThreadManager.\n\t * Received from adapter - used for cross-app RPC tool routing.\n\t */\n\ttoolSources: ToolSourceInfo[]\n\n\t/**\n\t * Additional adapters to use with the runtime.\n\t */\n\tadapters?: NonNullable<Parameters<typeof useExternalStoreRuntime>[0]['adapters']>\n}\n\n/**\n * Result from useThreadRuntime.\n */\nexport interface UseThreadRuntimeResult {\n\t/**\n\t * The Assistant UI runtime.\n\t */\n\truntime: AssistantRuntime\n\n\t/**\n\t * Reset the thread (clears messages).\n\t */\n\treset: () => Promise<void>\n\n\t/**\n\t * Tool execution helpers for manual approvals.\n\t */\n\ttoolExecution: {\n\t\texecuteTool: (toolName: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\t\tgetToolMetadata: (\n\t\t\ttoolName: string,\n\t\t) => { description?: string; annotations?: ToolWithSource['annotations'] } | null\n\t}\n\n\t/**\n\t * Tool source selection.\n\t */\n\ttoolSelection: {\n\t\tsources: ToolSourceInfo[]\n\t\tselection: ThreadToolSelection | null\n\t\tsetSelection: (selection: ThreadToolSelection | null) => Promise<void>\n\t\tcurrentSourceId?: string\n\t}\n}\n\n/**\n * Hook that provides Assistant UI runtime for a single thread.\n *\n * This hook:\n * 1. Connects to ThreadAgent DO for the specified thread\n * 2. Exposes local MCP tools to the AI (via frontendTools)\n * 3. Handles local tool execution (executeMCPTool)\n * 4. Provides runtime for assistant-ui components\n *\n * NOTE: Remote tool execution is handled server-side. The AI only sees local tools.\n * Future: Server will route multi-source tool calls via ThreadManager.\n *\n * @param options - Configuration options\n * @returns Assistant UI runtime for the thread\n */\nexport function useThreadRuntime(options: UseThreadRuntimeOptions): UseThreadRuntimeResult {\n\tconst {\n\t\tthreadId,\n\t\thost,\n\t\tauthToken,\n\t\tmanager,\n\t\tmcpTools,\n\t\texecuteMCPTool,\n\t\tapprovalMode = 'ask',\n\t\tcancelPendingToolCallsOnSend = true,\n\t\ttoolSources,\n\t\tadapters: customAdapters,\n\t} = options\n\n\tconst contextAdapters = useRuntimeAdapters()\n\tconst [toolStatuses, setToolStatuses] = useState<Record<string, ToolExecutionStatus>>({})\n\n\t// Tool selection state - synced with ThreadAgent\n\t// NOTE: Currently not used for frontend execution. In the future, server-side tool routing\n\t// will use this to determine which tabs/sources to invoke for cross-site RPC.\n\t// Tool calls will be: AI → Server → Routes to tab → Executes → Returns to server → Continues stream\n\tconst [toolSelection, setToolSelectionState] = useState<ThreadToolSelection | null>(null)\n\tconst tabId = getEmbeddedAgentTabId()\n\tconst currentSourceId = useMemo(() => {\n\t\tconst match = toolSources.find((source) => source.tabId === tabId)\n\t\treturn match?.sourceId\n\t}, [toolSources, tabId])\n\n\t// Connect to ThreadAgent DO for this thread\n\t// Include auth token for cross-origin WebSocket handshakes\n\tconst threadAgent = useAgent<ThreadAgentState>({\n\t\tagent: 'ThreadAgent',\n\t\tname: threadId ?? DISCONNECTED_THREAD_ID,\n\t\thost,\n\t\tquery: { auth_token: authToken },\n\t\tstartClosed: threadId == null,\n\t\tonStateUpdate: (state) => {\n\t\t\tsetToolSelectionState(state?.toolSelection ?? null)\n\t\t},\n\t})\n\n\tconst rawNonThreadListAdapters = useMemo(() => {\n\t\tconst merged: NonNullable<Parameters<typeof useExternalStoreRuntime>[0]['adapters']> = {}\n\t\tif (contextAdapters) Object.assign(merged, contextAdapters)\n\t\tif (customAdapters) Object.assign(merged, customAdapters)\n\t\tdelete merged.threadList\n\t\treturn Object.keys(merged).length > 0 ? merged : undefined\n\t}, [contextAdapters, customAdapters])\n\n\tconst nonThreadListAdapters = useShallowStableObject(\n\t\trawNonThreadListAdapters as Record<string, unknown> | undefined,\n\t) as typeof rawNonThreadListAdapters\n\n\tconst threadListAdapter = customAdapters?.threadList\n\tconst pendingFirstMessageRef = useRef<string | null>(null)\n\tconst onSwitchToNewThreadRef = useRef(threadListAdapter?.onSwitchToNewThread)\n\tonSwitchToNewThreadRef.current = threadListAdapter?.onSwitchToNewThread\n\n\tconst mcpToolsRef = useRef(mcpTools)\n\tmcpToolsRef.current = mcpTools\n\n\tuseEffect(() => {\n\t\tsetToolSelectionState(null)\n\t}, [threadId])\n\n\tconst setToolSelection = useCallback(\n\t\tasync (selection: ThreadToolSelection | null) => {\n\t\t\tif (!threadId) return\n\t\t\tif (threadAgent.readyState !== WebSocket.OPEN) return\n\n\t\t\ttry {\n\t\t\t\tconst result = await threadAgent.call<ThreadToolSelection | null>('setToolSelection', [\n\t\t\t\t\tselection,\n\t\t\t\t])\n\t\t\t\tsetToolSelectionState(result ?? null)\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[useThreadRuntime] Failed to set tool selection:', error)\n\t\t\t}\n\t\t},\n\t\t[threadId, threadAgent],\n\t)\n\n\t// NOTE: Removed dead remote tool schema fetching effect.\n\t// Previously fetched tools from ThreadManager based on selection, but:\n\t// - Remote tools never execute on frontend (server handles cross-site RPC)\n\t// - Only local tools are exposed to AI\n\t// - Server will provide complete tool list when implementing server-side routing\n\n\t// Build local tools set for quick lookup\n\tconst localToolNames = useMemo(() => {\n\t\tconst current = mcpToolsRef.current\n\t\treturn new Set(current?.map((t) => t.name) ?? [])\n\t}, [mcpTools])\n\n\t// Get tool metadata for approval UI\n\tconst getToolMetadata = useCallback(\n\t\t(toolName: string): { description?: string; annotations?: ToolWithSource['annotations'] } | null => {\n\t\t\tconst tool = mcpTools?.find((t) => t.name === toolName)\n\t\t\tif (!tool) return null\n\t\t\treturn {\n\t\t\t\tdescription: tool.description,\n\t\t\t\tannotations: tool.annotations,\n\t\t\t}\n\t\t},\n\t\t[mcpTools],\n\t)\n\n\t// Simplified tool execution - only local tools\n\tconst executeTool = useCallback(\n\t\tasync (toolName: string, args: Record<string, unknown>): Promise<CallToolResult> => {\n\t\t\tif (!executeMCPTool) {\n\t\t\t\tthrow new Error('Tool execution not available')\n\t\t\t}\n\n\t\t\tif (!localToolNames.has(toolName)) {\n\t\t\t\tthrow new Error(`Tool \"${toolName}\" is not available in this context`)\n\t\t\t}\n\n\t\t\treturn executeMCPTool(toolName, args ?? {})\n\t\t},\n\t\t[executeMCPTool, localToolNames],\n\t)\n\n\t// Build frontend tools with conditional execute\n\t// Only includes local MCP tools - remote tools will be handled by server-side routing in the future\n\tconst { frontendTools, toolsRequiringConfirmation } = useMemo((): {\n\t\tfrontendTools: FrontendTools\n\t\ttoolsRequiringConfirmation: string[]\n\t} => {\n\t\tconst result: FrontendTools = {}\n\t\tconst requiresConfirmation: string[] = []\n\n\t\t// Add local MCP tools (unprefixed names for AI)\n\t\tfor (const tool of mcpTools ?? []) {\n\t\t\tconst shouldAutoExecute = approvalMode === 'auto' || !isToolDestructive(tool.annotations)\n\n\t\t\t// Track tools that require confirmation (destructive tools when not in auto mode)\n\t\t\tif (!shouldAutoExecute) {\n\t\t\t\trequiresConfirmation.push(tool.name)\n\t\t\t}\n\n\t\t\t// All tools need execute functions so they're sent to the server as clientTools.\n\t\t\t// The toolsRequiringConfirmation list controls which tools need user approval -\n\t\t\t// useAgentChat's automatic resolution skips those tools, showing approval UI instead.\n\t\t\t// When user approves, UnifiedToolFallback.handleApprove() executes via MCP and calls addResult().\n\t\t\tresult[tool.name] = {\n\t\t\t\tdescription: tool.description ?? '',\n\t\t\t\tparameters: tool.inputSchema ?? {},\n\t\t\t\texecute: async (args: unknown) => {\n\t\t\t\t\tconst callResult = await executeTool(tool.name, args as Record<string, unknown>)\n\t\t\t\t\treturn formatToolResult(callResult)\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\treturn { frontendTools: result, toolsRequiringConfirmation: requiresConfirmation }\n\t}, [mcpTools, executeTool, approvalMode])\n\n\t// Chat hook with ThreadAgent\n\t// HITL (Human-in-the-Loop) Pattern:\n\t// - All tools have execute functions and are sent to server as clientTools\n\t// - experimental_automaticToolResolution: auto-executes tools NOT in toolsRequiringConfirmation\n\t// - Tools in toolsRequiringConfirmation stay in 'input-available' state until user approves\n\t// - autoContinueAfterToolResult: server continues conversation after receiving tool result\n\tconst chat = useAgentChat<ThreadAgentState, UIMessage>({\n\t\tagent: threadAgent,\n\t\ttools: frontendTools,\n\t\ttoolsRequiringConfirmation,\n\t\texperimental_automaticToolResolution: true,\n\t\tautoContinueAfterToolResult: true,\n\t\tresume: true,\n\t})\n\n\tconst hasExecutingTools = Object.values(toolStatuses).some((s) => s?.type === 'executing')\n\tconst isRunning =\n\t\tchat.status === 'submitted' || chat.status === 'streaming' || hasExecutingTools\n\n\tconst messages = CloudflareMessageConverter.useThreadMessages({\n\t\tisRunning,\n\t\tmessages: chat.messages,\n\t\tmetadata: useMemo(\n\t\t\t() => ({\n\t\t\t\ttoolStatuses,\n\t\t\t\t...(chat.error && { error: chat.error.message }),\n\t\t\t}),\n\t\t\t[toolStatuses, chat.error],\n\t\t),\n\t})\n\n\tconst [runtimeRef] = useState<{ current: AssistantRuntime | null }>(() => ({ current: null }))\n\n\tconst getTools = useCallback(\n\t\t() => runtimeRef.current?.thread.getModelContext().tools ?? {},\n\t\t[runtimeRef],\n\t)\n\tconst onResult = useCallback(() => {}, [])\n\n\tconst toolInvocations = INTERNAL.useToolInvocations({\n\t\tstate: { messages, isRunning },\n\t\tgetTools,\n\t\tonResult,\n\t\tsetToolStatuses,\n\t})\n\n\tconst completePendingToolCalls = useCallback(async () => {\n\t\tif (!cancelPendingToolCallsOnSend) return\n\n\t\tconst pendingToolIds = Object.entries(toolStatuses)\n\t\t\t.filter(([, status]) => status?.type === 'interrupt')\n\t\t\t.map(([toolCallId]) => toolCallId)\n\n\t\tif (pendingToolIds.length === 0) {\n\t\t\tawait toolInvocations.abort()\n\t\t\treturn\n\t\t}\n\n\t\tfor (const toolCallId of pendingToolIds) {\n\t\t\tfor (const msg of chat.messages) {\n\t\t\t\tfor (const part of msg.parts ?? []) {\n\t\t\t\t\tif (isToolUIPart(part) && part.toolCallId === toolCallId) {\n\t\t\t\t\t\tchat.addToolOutput({\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\ttool: getToolName(part),\n\t\t\t\t\t\t\toutput: 'Error: User cancelled tool call',\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetToolStatuses((prev) => {\n\t\t\tconst next = { ...prev }\n\t\t\tfor (const toolCallId of pendingToolIds) {\n\t\t\t\tdelete next[toolCallId]\n\t\t\t}\n\t\t\treturn next\n\t\t})\n\n\t\tawait toolInvocations.abort()\n\t}, [cancelPendingToolCallsOnSend, toolStatuses, chat, toolInvocations])\n\n\tuseEffect(() => {\n\t\tconst pendingText = pendingFirstMessageRef.current\n\t\tif (!pendingText) return\n\t\tif (!threadId) return\n\t\tif (threadAgent.readyState !== WebSocket.OPEN) return\n\n\t\tconst sendPending = async () => {\n\t\t\tpendingFirstMessageRef.current = null\n\t\t\tawait chat.sendMessage({ text: pendingText })\n\t\t}\n\n\t\tsendPending().catch((error) => {\n\t\t\tconsole.error('[useThreadRuntime] Failed to send pending first message:', error)\n\t\t})\n\t}, [threadId, threadAgent.readyState, chat, threadAgent])\n\n\tconst onNew = useCallback(\n\t\tasync (message: AppendMessage) => {\n\t\t\t// Voice messages should only be added to thread history, not trigger a chat agent run.\n\t\t\t// Voice mode has its own agent (OpenAI Realtime) that handles the conversation.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst messageWithMetadata = message as any\n\t\t\tconst isVoiceMessage = messageWithMetadata.metadata?.custom?.source === 'voice'\n\n\t\t\tif (isVoiceMessage) {\n\t\t\t\t// Convert AppendMessage to UIMessage format and add to chat history\n\t\t\t\t// without triggering a new AI run. The voice agent handles responses.\n\t\t\t\tconst firstContent = message.content[0]\n\t\t\t\tif (!firstContent || firstContent.type !== 'text') return\n\n\t\t\t\t// UIMessage uses 'parts' array for content, not a 'content' string\n\t\t\t\tconst voiceUIMessage = {\n\t\t\t\t\tid: `voice-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n\t\t\t\t\trole: message.role,\n\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\tparts: [{ type: 'text' as const, text: firstContent.text }],\n\t\t\t\t} as UIMessage\n\n\t\t\t\t// Add to chat history without triggering AI run\n\t\t\t\tchat.setMessages([...chat.messages, voiceUIMessage])\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tawait completePendingToolCalls()\n\n\t\t\tconst firstContent = message.content[0]\n\t\t\tif (!firstContent || firstContent.type !== 'text') return\n\n\t\t\t// If no thread is selected, create one first and send after we connect.\n\t\t\tif (!threadId) {\n\t\t\t\tconst onSwitchToNewThread = onSwitchToNewThreadRef.current\n\t\t\t\tif (!onSwitchToNewThread) {\n\t\t\t\t\tconsole.error('[useThreadRuntime] No thread selected and threadList adapter is missing')\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tpendingFirstMessageRef.current = firstContent.text\n\t\t\t\tawait onSwitchToNewThread()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tawait chat.sendMessage({ text: firstContent.text })\n\t\t},\n\t\t[threadId, chat, completePendingToolCalls],\n\t)\n\n\tconst onEdit = useCallback(\n\t\tasync (message: AppendMessage) => {\n\t\t\tif (!threadId) return\n\n\t\t\tawait completePendingToolCalls()\n\n\t\t\tconst newMessages = sliceMessagesUntil(chat.messages, message.parentId ?? null)\n\t\t\tchat.setMessages(newMessages)\n\n\t\t\tconst firstContent = message.content[0]\n\t\t\tif (!firstContent || firstContent.type !== 'text') return\n\n\t\t\tawait chat.sendMessage({ text: firstContent.text })\n\t\t},\n\t\t[threadId, chat, completePendingToolCalls],\n\t)\n\n\tconst onReload = useCallback(\n\t\tasync (parentId: string | null): Promise<void> => {\n\t\t\tif (!threadId) return\n\n\t\t\tawait completePendingToolCalls()\n\n\t\t\tconst newMessages = sliceMessagesUntil(chat.messages, parentId)\n\t\t\tchat.setMessages(newMessages)\n\n\t\t\tawait chat.regenerate()\n\t\t},\n\t\t[threadId, chat, completePendingToolCalls],\n\t)\n\n\tconst onCancel = useCallback(async (): Promise<void> => {\n\t\tchat.stop()\n\t\tawait toolInvocations.abort()\n\t}, [chat, toolInvocations])\n\n\tconst onAddToolResult = useCallback(\n\t\t(options: { toolCallId: string; result: unknown; isError?: boolean }) => {\n\t\t\tif (!threadId) return\n\n\t\t\tlet toolName = ''\n\t\t\tfor (const msg of chat.messages) {\n\t\t\t\tfor (const part of msg.parts ?? []) {\n\t\t\t\t\tif (isToolUIPart(part) && part.toolCallId === options.toolCallId) {\n\t\t\t\t\t\ttoolName = getToolName(part)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (toolName) break\n\t\t\t}\n\n\t\t\tchat.addToolOutput({\n\t\t\t\ttoolCallId: options.toolCallId,\n\t\t\t\ttool: toolName,\n\t\t\t\toutput: options.isError ? `Error: ${options.result}` : options.result,\n\t\t\t})\n\t\t},\n\t\t[threadId, chat],\n\t)\n\n\tconst onResumeToolCall = useCallback(\n\t\t(options: { toolCallId: string; payload?: unknown }) => {\n\t\t\tif (!threadId) return\n\t\t\ttoolInvocations.resume(options.toolCallId, options.payload)\n\t\t},\n\t\t[threadId, toolInvocations],\n\t)\n\n\tconst setMessages = useCallback(\n\t\t(messages: readonly ThreadMessage[]) => {\n\t\t\tif (!threadId) return\n\t\t\tchat.setMessages(messages as unknown as UIMessage[])\n\t\t},\n\t\t[threadId, chat],\n\t)\n\n\tconst store = useMemo(\n\t\t() => ({\n\t\t\tmessages,\n\t\t\tisRunning,\n\t\t\tonNew,\n\t\t\tonEdit,\n\t\t\tonReload,\n\t\t\tonCancel,\n\t\t\tonAddToolResult,\n\t\t\tonResumeToolCall,\n\t\t\tsetMessages,\n\t\t\tadapters: { ...(nonThreadListAdapters ?? {}) },\n\t\t}),\n\t\t[\n\t\t\tmessages,\n\t\t\tisRunning,\n\t\t\tonNew,\n\t\t\tonEdit,\n\t\t\tonReload,\n\t\t\tonCancel,\n\t\t\tonAddToolResult,\n\t\t\tonResumeToolCall,\n\t\t\tsetMessages,\n\t\t\tnonThreadListAdapters,\n\t\t],\n\t)\n\n\tstore.adapters.threadList = threadListAdapter\n\n\tconst runtime = useExternalStoreRuntime(store)\n\n\truntimeRef.current = runtime\n\n\tconst reset = useCallback(async () => {\n\t\tawait toolInvocations.abort()\n\t\tsetToolStatuses({})\n\t\tchat.clearHistory()\n\t}, [chat, toolInvocations])\n\n\treturn {\n\t\truntime,\n\t\treset,\n\t\ttoolExecution: {\n\t\t\texecuteTool,\n\t\t\tgetToolMetadata,\n\t\t},\n\t\ttoolSelection: {\n\t\t\tsources: toolSources,\n\t\t\tselection: toolSelection,\n\t\t\tsetSelection: setToolSelection,\n\t\t\tcurrentSourceId,\n\t\t},\n\t}\n}\n","/**\n * CloudflareThreadRuntimeProvider\n *\n * Provider that combines ThreadManager (thread list) and ThreadAgent (chat) functionality.\n *\n * This provider:\n * 1. Connects to ThreadManager for thread list management\n * 2. Provides thread selection and creation\n * 3. Connects to ThreadAgent for the selected thread's chat\n * 4. Handles tool execution (local and cross-site)\n *\n * Architecture:\n * - ThreadManager DO: One per user, manages thread list and tool registry\n * - ThreadAgent DO: One per thread, handles chat messages\n * - useCloudflareThreadAdapter: Manages ThreadManager connection and thread list state\n * - useThreadRuntime: Manages ThreadAgent connection for selected thread\n */\n\nimport {\n\tcreateContext,\n\tSuspense,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\ttype ReactNode,\n} from 'react'\n\nimport { AssistantRuntimeProvider } from '@assistant-ui/react'\nimport type { CallToolResult, ToolApprovalMode, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport type { useAgent } from 'agents/react'\nimport type { ThreadManagerState } from '@mcp-b/cloud-mirror-types'\n\nimport { ErrorScreen } from '../components/errors/ErrorScreen'\nimport { Skeleton } from '../components/ui/skeleton'\nimport { useCloudflareThreadAdapter } from '../hooks/useCloudflareThreadAdapter'\nimport { useThreadRuntime } from '../hooks/useThreadRuntime'\nimport { ToolExecutionProvider } from './ToolExecutionProvider'\nimport { ToolSelectionProvider } from './ToolSelectionProvider'\n\n/**\n * Props for CloudflareThreadRuntimeProvider.\n */\nexport interface CloudflareThreadRuntimeProviderProps {\n\tchildren: ReactNode\n\n\t/**\n\t * The host for Cloudflare Agent WebSocket connections.\n\t * @default 'localhost:8787'\n\t */\n\thost?: string\n\n\t/**\n\t * IDP token for SSO-first authentication (required).\n\t * The backend validates the token against the org's configured IDP\n\t * and extracts the user ID from the token's sub claim.\n\t *\n\t * This provider only runs in stateful mode. For stateless mode,\n\t * use useStatelessRuntime instead (handled by AgentProvider).\n\t */\n\tauthToken: string\n\n\t/**\n\t * MCP tools to sync to the backend.\n\t */\n\tmcpTools?: ToolWithSource[]\n\n\t/**\n\t * Function to execute MCP tools locally.\n\t */\n\texecuteMCPTool?: (\n\t\ttoolName: string,\n\t\targs: Record<string, unknown>,\n\t) => Promise<CallToolResult>\n\n\t/**\n\t * Tool approval mode.\n\t * @default 'ask'\n\t */\n\tapprovalMode?: ToolApprovalMode\n\n\t/**\n\t * Cancel pending tool calls on new message.\n\t * @default true\n\t */\n\tcancelPendingToolCallsOnSend?: boolean\n\n\t/**\n\t * Base URL for dashboard (e.g., \"https://app.char.ai\")\n\t * Used to generate dashboard links in error messages\n\t */\n\tdashboardBaseUrl?: string\n\n\t/**\n\t * Base URL for documentation (e.g., \"https://docs.char.ai\")\n\t * Used to generate documentation links in error messages\n\t */\n\tdocsBaseUrl?: string\n}\n\n/**\n * Context value for CloudflareThreadRuntimeProvider.\n */\ninterface CloudflareThreadContextValue {\n\t/** Whether the context has been initialized */\n\tisInitialized: boolean\n\t/** Whether the thread list has synced and context is ready */\n\tisReady: boolean\n\t/** The internal end_user ID */\n\tendUserId: string | null\n\t/** The resolved organization ID (SSO-First: org-level only) */\n\torganizationId: string | null\n\t/** Current selected thread ID */\n\tcurrentThreadId: string | undefined\n\t/** Set current selected thread ID */\n\tsetCurrentThreadId: (threadId: string | undefined) => void\n\t/** Reset the current thread (clears messages) */\n\treset: () => Promise<void>\n\t/** Start a new thread */\n\tstartNew: () => Promise<void>\n\t/** Authentication error (if initialization failed) */\n\tauthError: import('../utils/auth-errors').AuthError | null\n}\n\nconst CloudflareThreadContext = createContext<CloudflareThreadContextValue | null>(null)\n\n/**\n * Hook to access CloudflareThreadRuntime context.\n */\nexport function useCloudflareThread(): CloudflareThreadContextValue {\n\tconst context = useContext(CloudflareThreadContext)\n\tif (!context) {\n\t\tthrow new Error('useCloudflareThread must be used within a CloudflareThreadRuntimeProvider')\n\t}\n\treturn context\n}\n\n/**\n * Hook to optionally access CloudflareThreadRuntime context.\n * Returns null if used outside of CloudflareThreadRuntimeProvider.\n */\nexport function useOptionalCloudflareThread(): CloudflareThreadContextValue | null {\n\treturn useContext(CloudflareThreadContext)\n}\n\n/**\n * Skeleton fallback shown during thread runtime suspension.\n * Mimics the thread layout with message bubbles and composer.\n * Sizes match real components: StreamingResponse, SummaryBlock, PillComposer.\n */\nfunction ThreadRuntimeSkeleton() {\n\treturn (\n\t\t<div\n\t\t\tclassName=\"wm:flex wm:flex-col wm:justify-between wm:h-full wm:min-h-40 wm:p-3\"\n\t\t\taria-label=\"Loading thread\"\n\t\t>\n\t\t\t{/* Mock message - matches StreamingResponse/SummaryBlock styling */}\n\t\t\t<div className=\"wm:rounded-lg wm:bg-white/5 wm:p-3\">\n\t\t\t\t<div className=\"wm:flex wm:flex-col wm:gap-2\">\n\t\t\t\t\t<Skeleton className=\"wm:h-3.5 wm:w-4/5\" />\n\t\t\t\t\t<Skeleton className=\"wm:h-3.5 wm:w-3/5\" />\n\t\t\t\t\t<Skeleton className=\"wm:h-3.5 wm:w-2/3\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{/* Mock composer - matches PillComposer styling */}\n\t\t\t<div className=\"wm:mt-3\">\n\t\t\t\t<Skeleton className=\"wm:h-9 wm:w-full wm:rounded-xl\" />\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/**\n * Internal bridge component that uses useThreadRuntime.\n * This is separated so Suspense can wrap it - when useAgentChat suspends,\n * only this component unmounts, not the entire provider tree.\n */\ninterface ThreadRuntimeBridgeProps {\n\tchildren: ReactNode\n\tthreadId: string | undefined\n\thost?: string\n\tauthToken: string\n\tmanager: ReturnType<typeof useAgent<ThreadManagerState>>\n\tmcpTools?: ToolWithSource[]\n\texecuteMCPTool?: (toolName: string, args: Record<string, unknown>) => Promise<CallToolResult>\n\tapprovalMode: ToolApprovalMode\n\tcancelPendingToolCallsOnSend: boolean\n\tthreadListAdapter: ReturnType<typeof useCloudflareThreadAdapter>['threadListAdapter']\n\ttoolSources: ReturnType<typeof useCloudflareThreadAdapter>['toolSources']\n\tonResetChange: (reset: () => Promise<void>) => void\n}\n\nfunction ThreadRuntimeBridge({\n\tchildren,\n\tthreadId,\n\thost,\n\tauthToken,\n\tmanager,\n\tmcpTools,\n\texecuteMCPTool,\n\tapprovalMode,\n\tcancelPendingToolCallsOnSend,\n\tthreadListAdapter,\n\ttoolSources,\n\tonResetChange,\n}: ThreadRuntimeBridgeProps) {\n\t// Connect to ThreadAgent for the selected thread\n\t// This can suspend via useAgentChat -> use()\n\tconst { runtime, reset: resetThread, toolExecution, toolSelection } = useThreadRuntime({\n\t\tthreadId,\n\t\thost,\n\t\tauthToken,\n\t\tmanager,\n\t\tmcpTools,\n\t\texecuteMCPTool,\n\t\tapprovalMode,\n\t\tcancelPendingToolCallsOnSend,\n\t\ttoolSources,\n\t\tadapters: {\n\t\t\tthreadList: threadListAdapter,\n\t\t},\n\t})\n\n\t// Notify parent of reset function changes\n\tconst resetThreadRef = useRef(resetThread)\n\tresetThreadRef.current = resetThread\n\tconst stableReset = useCallback(async () => {\n\t\tawait resetThreadRef.current()\n\t}, [])\n\n\t// Update parent's reset ref\n\tconst onResetChangeRef = useRef(onResetChange)\n\tonResetChangeRef.current = onResetChange\n\tuseMemo(() => {\n\t\tonResetChangeRef.current(stableReset)\n\t}, [stableReset])\n\n\treturn (\n\t\t<ToolSelectionProvider value={toolSelection}>\n\t\t\t<ToolExecutionProvider value={toolExecution}>\n\t\t\t\t<AssistantRuntimeProvider runtime={runtime}>\n\t\t\t\t\t{children}\n\t\t\t\t</AssistantRuntimeProvider>\n\t\t\t</ToolExecutionProvider>\n\t\t</ToolSelectionProvider>\n\t)\n}\n\n/**\n * Provider that combines ThreadManager (thread list) and ThreadAgent (chat) functionality.\n *\n * @example\n * ```tsx\n * function ChatApp() {\n * const { session } = useOktaAuth(); // or Azure AD, Auth0, etc.\n *\n * return (\n * <CloudflareThreadRuntimeProvider\n * authToken={session.idToken}\n * mcpTools={tools}\n * executeMCPTool={callTool}\n * >\n * <div className=\"flex h-screen\">\n * <Sidebar>\n * <ThreadListUI />\n * </Sidebar>\n * <Thread />\n * </div>\n * </CloudflareThreadRuntimeProvider>\n * );\n * }\n *\n * function ThreadListUI() {\n * const { startNew } = useCloudflareThread();\n * return <button onClick={() => void startNew()}>New Thread</button>;\n * }\n * ```\n */\nexport function CloudflareThreadRuntimeProvider({\n\tchildren,\n\thost,\n\tauthToken,\n\tmcpTools,\n\texecuteMCPTool,\n\tapprovalMode = 'ask',\n\tcancelPendingToolCallsOnSend = true,\n\tdashboardBaseUrl,\n\tdocsBaseUrl,\n}: CloudflareThreadRuntimeProviderProps) {\n\t// Connect to ThreadManager for thread list management\n\t// This does NOT suspend - it stays stable across thread switches\n\tconst {\n\t\tcurrentThreadId,\n\t\tsetCurrentThreadId,\n\t\tthreadListAdapter,\n\t\tisInitialized,\n\t\tisReady,\n\t\tendUserId,\n\t\torganizationId,\n\t\tauthError,\n\t\tmanager,\n\t\ttoolSources,\n\t} = useCloudflareThreadAdapter({\n\t\thost,\n\t\tauthToken,\n\t\tmcpTools,\n\t\texecuteMCPTool,\n\t})\n\n\t// Reset function from ThreadRuntimeBridge (updated via callback)\n\tconst resetRef = useRef<() => Promise<void>>(async () => {})\n\tconst handleResetChange = useCallback((newReset: () => Promise<void>) => {\n\t\tresetRef.current = newReset\n\t}, [])\n\n\tconst reset = useCallback(async () => {\n\t\tawait resetRef.current()\n\t}, [])\n\n\t// Start a new thread\n\tconst onSwitchToNewThreadRef = useRef(threadListAdapter.onSwitchToNewThread)\n\tonSwitchToNewThreadRef.current = threadListAdapter.onSwitchToNewThread\n\tconst startNew = useCallback(async () => {\n\t\tawait onSwitchToNewThreadRef.current?.()\n\t}, [])\n\n\t// Build context value\n\tconst contextValue = useMemo<CloudflareThreadContextValue>(\n\t\t() => ({\n\t\t\tisInitialized,\n\t\t\tisReady,\n\t\t\tendUserId,\n\t\t\torganizationId,\n\t\t\tcurrentThreadId,\n\t\t\tsetCurrentThreadId,\n\t\t\treset,\n\t\t\tstartNew,\n\t\t\tauthError,\n\t\t}),\n\t\t[\n\t\t\tisInitialized,\n\t\t\tisReady,\n\t\t\tendUserId,\n\t\t\torganizationId,\n\t\t\tcurrentThreadId,\n\t\t\tsetCurrentThreadId,\n\t\t\treset,\n\t\t\tstartNew,\n\t\t\tauthError,\n\t\t],\n\t)\n\n\treturn (\n\t\t<CloudflareThreadContext.Provider value={contextValue}>\n\t\t\t<div className=\"wm:relative wm:h-full wm:w-full\">\n\t\t\t\t<Suspense fallback={<ThreadRuntimeSkeleton />}>\n\t\t\t\t\t<ThreadRuntimeBridge\n\t\t\t\t\t\tthreadId={currentThreadId}\n\t\t\t\t\t\thost={host}\n\t\t\t\t\t\tauthToken={authToken}\n\t\t\t\t\t\tmanager={manager}\n\t\t\t\t\t\tmcpTools={mcpTools}\n\t\t\t\t\t\texecuteMCPTool={executeMCPTool}\n\t\t\t\t\t\tapprovalMode={approvalMode}\n\t\t\t\t\t\tcancelPendingToolCallsOnSend={cancelPendingToolCallsOnSend}\n\t\t\t\t\t\tthreadListAdapter={threadListAdapter}\n\t\t\t\t\t\ttoolSources={toolSources}\n\t\t\t\t\t\tonResetChange={handleResetChange}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</ThreadRuntimeBridge>\n\t\t\t\t</Suspense>\n\t\t\t\t{authError && (\n\t\t\t\t\t<div className=\"wm:absolute wm:inset-0 wm:bg-background/80 wm:backdrop-blur-sm wm:z-50\">\n\t\t\t\t\t\t<ErrorScreen\n\t\t\t\t\t\t\terror={authError}\n\t\t\t\t\t\t\tdashboardBaseUrl={dashboardBaseUrl}\n\t\t\t\t\t\t\tdocsBaseUrl={docsBaseUrl}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</CloudflareThreadContext.Provider>\n\t)\n}\n","/**\n * usePendingToolCalls Hook\n *\n * Derives pending tool call state from assistant-ui's thread state.\n * This replaces the external pendingApprovalStore by using the single source of truth.\n *\n * Benefits:\n * - No external store synchronization needed\n * - No registration/unregistration logic\n * - No infinite loop issues from useSyncExternalStore\n * - Naturally reactive to thread state changes\n *\n * For non-reactive utilities (callbacks/effects), see utils/thread-utils.ts\n */\nimport { useThread, useThreadRuntime } from '@assistant-ui/react'\nimport { useMemo } from 'react'\n\nimport type { ThreadAssistantMessage } from '@assistant-ui/react'\nimport type { PendingToolCallInfo } from '../utils/thread-utils'\n\n/**\n * Hook to get all pending tool calls that require user approval.\n * Derives state from assistant-ui's thread messages.\n *\n * This is a reactive hook - it will re-render when thread state changes.\n * For non-reactive access in callbacks, use getPendingToolCalls() from utils/thread-utils.ts\n */\nexport function usePendingToolCalls(): PendingToolCallInfo[] {\n\tconst messages = useThread((t) => t.messages)\n\n\treturn useMemo(() => {\n\t\tconst result: PendingToolCallInfo[] = []\n\n\t\tfor (const msg of messages) {\n\t\t\t// Only assistant messages can have tool calls\n\t\t\tif (msg.role !== 'assistant') continue\n\n\t\t\t// Cast to assistant message to access status\n\t\t\tconst assistantMsg = msg as ThreadAssistantMessage\n\n\t\t\t// Only process messages waiting for tool results\n\t\t\t// Check for requires-action status (don't check reason - it may vary)\n\t\t\tif (assistantMsg.status?.type !== 'requires-action') continue\n\n\t\t\t// Find tool-call parts without results\n\t\t\tfor (const part of assistantMsg.content) {\n\t\t\t\tif (part.type !== 'tool-call') continue\n\t\t\t\tif (part.result !== undefined) continue\n\n\t\t\t\tresult.push({\n\t\t\t\t\tmessageId: msg.id,\n\t\t\t\t\ttoolCallId: part.toolCallId,\n\t\t\t\t\ttoolName: part.toolName,\n\t\t\t\t\targs: (part.args as Record<string, unknown>) ?? {},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}, [messages])\n}\n\n/**\n * Hook to get the thread runtime for calling addToolResult.\n * Re-exported for convenience.\n */\nexport { useThreadRuntime }\n","/**\n * Debug Tools V2 for Embedded Agent\n *\n * Provides 4 powerful debug tools for browser automation and testing:\n * - debug_state: Complete application state snapshot (READ)\n * - debug_ui: UI and composer control (ACTION)\n * - debug_tools: Tool approval and source management (ACTION)\n * - debug_session: Thread and voice control (ACTION)\n *\n * All tools are prefixed with `debug_` and should be excluded from production.\n *\n * @example Usage in Storybook or development\n * ```tsx\n * <DebugToolsProvider enabled={isDevelopment}>\n * {children}\n * </DebugToolsProvider>\n * ```\n */\n\nimport { useAssistantApi, useAssistantState, useThread, useThreadRuntime } from '@assistant-ui/react'\nimport { useWebMCP } from '@mcp-b/react-webmcp'\nimport { useCallback, useRef } from 'react'\nimport { z } from 'zod'\n\nimport { useOptionalAgentUI } from '../providers/AgentUIProvider'\nimport { useOptionalMCPTools } from '../providers/MCPToolsProvider'\nimport { useOptionalToolApproval } from '../providers/ToolApprovalProvider'\nimport { useOptionalToolSelection } from '../providers/ToolSelectionProvider'\nimport { useOptionalVoiceThread } from '../providers/VoiceThreadBridge'\nimport { usePendingToolCalls } from './usePendingToolCalls'\nimport { resolvePendingToolCall } from '../utils/thread-utils'\n\nimport type { ToolApprovalMode, ToolSourceSelector } from '@mcp-b/cloud-mirror-types'\nimport type { PillMode } from '../providers/AgentUIProvider'\n\n/**\n * Prefix for debug tools - these should be excluded from production\n */\nexport const DEBUG_TOOL_PREFIX = 'debug_'\n\n// =============================================================================\n// STABLE SCHEMA DEFINITIONS\n// These must be defined outside the hook to prevent re-registration loops.\n// useWebMCP compares inputSchema by reference, so inline objects cause issues.\n// =============================================================================\n\n/** Schema for debug_state tool - no inputs needed */\nconst DEBUG_STATE_SCHEMA = {} as const\n\n/** Schema for debug_ui tool */\nconst DEBUG_UI_SCHEMA = {\n\taction: z.enum(['setMode', 'expand', 'collapse', 'toggleFullScreen', 'resetPosition', 'markRead', 'sendMessage', 'setText', 'clearComposer'])\n\t\t.describe('The action to perform'),\n\tmode: z.enum(['collapsed', 'hovered', 'composing', 'active', 'expanded']).optional()\n\t\t.describe('Required for setMode action. The pill mode to set.'),\n\ttext: z.string().optional()\n\t\t.describe('Required for sendMessage and setText actions. The message or text to use.'),\n} as const\n\n/** Schema for debug_tools tool */\nconst DEBUG_TOOLS_SCHEMA = {\n\taction: z.enum(['approve', 'deny', 'setApprovalMode', 'selectSources', 'deselectSources', 'selectAllSources', 'deselectAllSources'])\n\t\t.describe('The action to perform'),\n\ttoolCallId: z.string().optional()\n\t\t.describe('For approve/deny: specific tool call ID. If omitted, uses the first pending approval.'),\n\treason: z.string().optional()\n\t\t.describe('For deny: feedback explaining why the tool was denied.'),\n\tmode: z.enum(['ask', 'auto']).optional()\n\t\t.describe('For setApprovalMode: \"ask\" requires approval for destructive tools, \"auto\" approves all.'),\n\tsourceIds: z.array(z.string()).optional()\n\t\t.describe('For selectSources/deselectSources: array of source IDs to select or deselect.'),\n} as const\n\n/** Schema for debug_session tool */\nconst DEBUG_SESSION_SCHEMA = {\n\taction: z.enum(['startNewThread', 'switchThread', 'listThreads', 'voiceStart', 'voiceStop', 'voiceToggleMute'])\n\t\t.describe('The action to perform'),\n\tthreadId: z.string().optional()\n\t\t.describe('For switchThread: the ID of the thread to switch to.'),\n} as const\n\n/** Description for debug_state tool */\nconst DEBUG_STATE_DESCRIPTION = `Get a complete snapshot of the embedded agent's current state. Returns everything in one call: UI state (pill mode, fullscreen, position), thread state (messages, running status, pending approvals), voice state (active, muted, transcript), tool state (approval mode, local/remote sources, connections), and WebSocket connection status. Call this first to understand the current application state before taking actions.`\n\n/** Description for debug_ui tool */\nconst DEBUG_UI_DESCRIPTION = `Control the embedded agent's UI and composer.\n\nActions:\n• setMode - Change pill mode. Requires 'mode' param: 'collapsed' | 'hovered' | 'composing' | 'active' | 'expanded'\n• expand - Expand the pill (equivalent to setMode with 'expanded')\n• collapse - Collapse the pill immediately\n• toggleFullScreen - Enter or exit full-screen mode\n• resetPosition - Reset pill to default position\n• markRead - Clear the unread indicator\n• sendMessage - Send a message to the agent. Requires 'text' param with the message content\n• setText - Set composer text without sending. Requires 'text' param\n• clearComposer - Clear the composer input\n\nExamples:\n { action: 'sendMessage', text: 'What tools do you have?' }\n { action: 'setMode', mode: 'expanded' }\n { action: 'collapse' }`\n\n/** Description for debug_tools tool */\nconst DEBUG_TOOLS_DESCRIPTION = `Manage tool approvals and tool source selection.\n\nActions:\n• approve - Approve a pending tool call. Optional 'toolCallId' param (defaults to first pending)\n• deny - Deny a pending tool call. Optional 'toolCallId' and 'reason' params\n• setApprovalMode - Change approval mode. Requires 'mode' param: 'ask' | 'auto'\n• selectSources - Select specific tool sources. Requires 'sourceIds' array\n• deselectSources - Deselect specific tool sources. Requires 'sourceIds' array\n• selectAllSources - Select all available tool sources\n• deselectAllSources - Deselect all tool sources (use only local tools)\n\nExamples:\n { action: 'approve' }\n { action: 'deny', reason: 'Try a different approach' }\n { action: 'setApprovalMode', mode: 'auto' }\n { action: 'selectSources', sourceIds: ['source-abc', 'source-xyz'] }`\n\n/** Description for debug_session tool */\nconst DEBUG_SESSION_DESCRIPTION = `Control thread and voice session.\n\nActions:\n• startNewThread - Clear the current conversation and start fresh\n• switchThread - Switch to a different thread. Requires 'threadId' param\n• listThreads - List all available threads and current thread ID\n• voiceStart - Start a voice session (requires microphone access)\n• voiceStop - End the current voice session\n• voiceToggleMute - Toggle microphone mute state\n\nExamples:\n { action: 'startNewThread' }\n { action: 'switchThread', threadId: 'thread-abc123' }\n { action: 'listThreads' }\n { action: 'voiceStart' }`\n\n/**\n * Options for the debug tools hook\n */\nexport interface UseWebMCPDebugToolsOptions {\n\t/**\n\t * Additional state to include in debug output.\n\t * Useful for exposing provider-level state not accessible via hooks.\n\t */\n\tadditionalState?: {\n\t\t/** CloudflareThread context values */\n\t\tcloudflareThread?: {\n\t\t\tisInitialized: boolean\n\t\t\tisReady: boolean\n\t\t\tcurrentThreadId: string | undefined\n\t\t\tendUserId: string | null\n\t\t\torganizationId: string | null\n\t\t}\n\t\t/** ThreadManager WebSocket state */\n\t\tmanagerState?: {\n\t\t\treadyState: number\n\t\t\treadyStateLabel: string\n\t\t}\n\t}\n}\n\n// Tool denied message constant\nconst TOOL_DENIED_MESSAGE = 'Tool execution was denied by the user.'\n\n/**\n * Hook that registers debug tools for the embedded agent.\n *\n * Tools provided:\n * - `debug_state`: Complete application state snapshot\n * - `debug_ui`: Control UI and composer\n * - `debug_tools`: Manage tool approvals and sources\n * - `debug_session`: Control thread and voice\n */\nexport function useWebMCPDebugTools(options?: UseWebMCPDebugToolsOptions) {\n\t// Get all contexts (using optional versions where available)\n\tconst agentUI = useOptionalAgentUI()\n\tconst mcpTools = useOptionalMCPTools()\n\tconst toolApproval = useOptionalToolApproval()\n\tconst toolSelection = useOptionalToolSelection()\n\tconst voiceThread = useOptionalVoiceThread()\n\tconst pendingToolCalls = usePendingToolCalls()\n\tconst threadRuntime = useThreadRuntime()\n\tconst additionalState = options?.additionalState\n\n\t// Get assistant-ui API for composer and threads\n\tconst assistantApi = useAssistantApi()\n\n\t// Thread state\n\tconst threadMessages = useThread((t) => t.messages)\n\tconst isRunning = useThread((t) => t.isRunning)\n\n\t// Thread list state\n\tconst threadsLoading = useAssistantState(({ threads }) => threads.isLoading)\n\tconst currentThreadId = useAssistantState(({ threads }) => threads.mainThreadId)\n\tconst threadIds = useAssistantState(({ threads }) => threads.threadIds)\n\n\t// Use refs to avoid recreating handlers when state changes\n\t// This prevents infinite re-registration loops in useWebMCP\n\tconst stateRef = useRef({\n\t\tagentUI,\n\t\tmcpTools,\n\t\ttoolApproval,\n\t\ttoolSelection,\n\t\tvoiceThread,\n\t\tpendingToolCalls,\n\t\tthreadRuntime,\n\t\tadditionalState,\n\t\tassistantApi,\n\t\tthreadMessages,\n\t\tisRunning,\n\t\tthreadsLoading,\n\t\tcurrentThreadId,\n\t\tthreadIds,\n\t})\n\t// Update ref on each render\n\tstateRef.current = {\n\t\tagentUI,\n\t\tmcpTools,\n\t\ttoolApproval,\n\t\ttoolSelection,\n\t\tvoiceThread,\n\t\tpendingToolCalls,\n\t\tthreadRuntime,\n\t\tadditionalState,\n\t\tassistantApi,\n\t\tthreadMessages,\n\t\tisRunning,\n\t\tthreadsLoading,\n\t\tcurrentThreadId,\n\t\tthreadIds,\n\t}\n\n\t// =========================================================================\n\t// Tool 1: debug_state - Complete application state snapshot\n\t// =========================================================================\n\tconst handleDebugState = useCallback(async () => {\n\t\tconst state = stateRef.current\n\t\tconst cloudflareThread = state.additionalState?.cloudflareThread\n\t\tconst managerState = state.additionalState?.managerState\n\n\t\t// Build UI state\n\t\tconst ui = state.agentUI\n\t\t\t? {\n\t\t\t\t\tmode: state.agentUI.userMode,\n\t\t\t\t\tisFullScreen: state.agentUI.isFullScreen,\n\t\t\t\t\thasUnread: state.agentUI.hasUnread,\n\t\t\t\t\tposition: state.agentUI.position,\n\t\t\t\t}\n\t\t\t: { error: 'AgentUI context not available' }\n\n\t\t// Build thread state with messages\n\t\tconst messages = (state.threadMessages ?? []).map((msg) => {\n\t\t\t// Get content preview\n\t\t\tlet contentPreview = ''\n\t\t\tfor (const part of msg.content) {\n\t\t\t\tif (part.type === 'text' && 'text' in part && typeof part.text === 'string') {\n\t\t\t\t\tcontentPreview = part.text.slice(0, 500)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get tool calls\n\t\t\tconst toolCalls = msg.content\n\t\t\t\t.filter((part) => part.type === 'tool-call')\n\t\t\t\t.map((tc) => {\n\t\t\t\t\tconst toolCallPart = tc as { type: 'tool-call'; toolName: string; result?: unknown }\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: toolCallPart.toolName,\n\t\t\t\t\t\tstatus: toolCallPart.result !== undefined ? 'completed' : 'pending',\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\treturn {\n\t\t\t\tid: msg.id,\n\t\t\t\trole: msg.role,\n\t\t\t\tcontent: contentPreview,\n\t\t\t\ttoolCalls,\n\t\t\t}\n\t\t})\n\n\t\t// Get selected source IDs from selection\n\t\tconst selectedSourceIds = state.toolSelection?.selection?.selectedSources?.map((s) => s.sourceId) ?? []\n\n\t\tconst thread = {\n\t\t\tid: state.currentThreadId ?? null,\n\t\t\tisRunning: state.isRunning,\n\t\t\tisEmpty: messages.length === 0,\n\t\t\tmessageCount: messages.length,\n\t\t\tmessages,\n\t\t\tpendingApprovals: state.pendingToolCalls.map((tc) => ({\n\t\t\t\tmessageId: tc.messageId,\n\t\t\t\ttoolCallId: tc.toolCallId,\n\t\t\t\ttoolName: tc.toolName,\n\t\t\t\targs: tc.args,\n\t\t\t})),\n\t\t\tcurrentAction: state.isRunning && state.pendingToolCalls.length > 0\n\t\t\t\t? { toolName: state.pendingToolCalls[0].toolName, status: 'pending' }\n\t\t\t\t: null,\n\t\t}\n\n\t\t// Build voice state\n\t\tconst voice = state.voiceThread\n\t\t\t? {\n\t\t\t\t\tisActive: state.voiceThread.isActive,\n\t\t\t\t\tisConnecting: state.voiceThread.isConnecting,\n\t\t\t\t\tisMuted: state.voiceThread.isMuted,\n\t\t\t\t\tisSupported: state.voiceThread.isSupported,\n\t\t\t\t\ttranscript: state.voiceThread.transcript ?? null,\n\t\t\t\t\terror: state.voiceThread.error ?? null,\n\t\t\t\t}\n\t\t\t: { error: 'Voice context not available' }\n\n\t\t// Build tools state\n\t\tconst tools = {\n\t\t\tapprovalMode: state.toolApproval?.mode ?? 'ask',\n\t\t\tlocalTools: (state.mcpTools?.tools ?? []).map((t) => ({\n\t\t\t\tname: t.name,\n\t\t\t\tdescription: t.description?.slice(0, 100) ?? '',\n\t\t\t\tsourceId: t._sourceId ?? 'unknown',\n\t\t\t})),\n\t\t\tmcpSources: state.mcpTools\n\t\t\t\t? Array.from(state.mcpTools.sources.entries()).map(([id, source]) => ({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tstate: source.state,\n\t\t\t\t\t\ttoolCount: source.tools.length,\n\t\t\t\t\t\terror: source.error?.message ?? null,\n\t\t\t\t\t}))\n\t\t\t\t: [],\n\t\t\tremoteSources: state.toolSelection\n\t\t\t\t? state.toolSelection.sources.map((s) => ({\n\t\t\t\t\t\tsourceId: s.sourceId,\n\t\t\t\t\t\ttabId: s.tabId,\n\t\t\t\t\t\ttitle: s.title ?? 'Unknown',\n\t\t\t\t\t\turl: s.url ?? '',\n\t\t\t\t\t\ttoolCount: s.toolCount,\n\t\t\t\t\t\tisSelected: selectedSourceIds.includes(s.sourceId),\n\t\t\t\t\t}))\n\t\t\t\t: [],\n\t\t\tcurrentSourceId: state.toolSelection?.currentSourceId ?? null,\n\t\t}\n\n\t\t// Build connection state\n\t\tconst connection = {\n\t\t\tmanagerReadyState: managerState?.readyState ?? -1,\n\t\t\tmanagerReadyStateLabel: managerState?.readyStateLabel ?? 'UNKNOWN',\n\t\t\tcloudflareThread: cloudflareThread ?? { error: 'CloudflareThread context not provided' },\n\t\t}\n\n\t\treturn { ui, thread, voice, tools, connection }\n\t}, [])\n\n\tuseWebMCP({\n\t\tname: `${DEBUG_TOOL_PREFIX}state`,\n\t\tdescription: DEBUG_STATE_DESCRIPTION,\n\t\tinputSchema: DEBUG_STATE_SCHEMA,\n\t\thandler: handleDebugState,\n\t})\n\n\t// =========================================================================\n\t// Tool 2: debug_ui - UI and Composer Control\n\t// =========================================================================\n\tconst handleDebugUi = useCallback(async (args: { action: string; mode?: string; text?: string }) => {\n\t\tconst { action, mode, text } = args\n\t\tconst state = stateRef.current\n\n\t\tswitch (action) {\n\t\t\tcase 'setMode':\n\t\t\t\tif (!mode) {\n\t\t\t\t\treturn { success: false, error: 'mode parameter required for setMode action' }\n\t\t\t\t}\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.setUserMode(mode as PillMode)\n\t\t\t\treturn { success: true, mode }\n\n\t\t\tcase 'expand':\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.expand()\n\t\t\t\treturn { success: true, mode: 'composing' }\n\n\t\t\tcase 'collapse':\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.collapse()\n\t\t\t\treturn { success: true, mode: 'collapsed' }\n\n\t\t\tcase 'toggleFullScreen':\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.toggleFullScreen()\n\t\t\t\treturn { success: true, isFullScreen: !state.agentUI.isFullScreen }\n\n\t\t\tcase 'resetPosition':\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.resetPosition()\n\t\t\t\treturn { success: true, position: { x: 0, y: 0 } }\n\n\t\t\tcase 'markRead':\n\t\t\t\tif (!state.agentUI) {\n\t\t\t\t\treturn { success: false, error: 'AgentUI context not available' }\n\t\t\t\t}\n\t\t\t\tstate.agentUI.markRead()\n\t\t\t\treturn { success: true, hasUnread: false }\n\n\t\t\tcase 'sendMessage':\n\t\t\t\tif (!text) {\n\t\t\t\t\treturn { success: false, error: 'text parameter required for sendMessage action' }\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst composer = state.assistantApi.composer()\n\t\t\t\t\tcomposer.setText(text)\n\t\t\t\t\tcomposer.send()\n\t\t\t\t\treturn { success: true, message: text }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to send message' }\n\t\t\t\t}\n\n\t\t\tcase 'setText':\n\t\t\t\tif (text === undefined) {\n\t\t\t\t\treturn { success: false, error: 'text parameter required for setText action' }\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tstate.assistantApi.composer().setText(text)\n\t\t\t\t\treturn { success: true, text }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to set text' }\n\t\t\t\t}\n\n\t\t\tcase 'clearComposer':\n\t\t\t\ttry {\n\t\t\t\t\tstate.assistantApi.composer().reset()\n\t\t\t\t\treturn { success: true }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to clear composer' }\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn { success: false, error: `Unknown action: ${action}` }\n\t\t}\n\t}, [])\n\n\tuseWebMCP({\n\t\tname: `${DEBUG_TOOL_PREFIX}ui`,\n\t\tdescription: DEBUG_UI_DESCRIPTION,\n\t\tinputSchema: DEBUG_UI_SCHEMA,\n\t\thandler: handleDebugUi,\n\t})\n\n\t// =========================================================================\n\t// Tool 3: debug_tools - Tool Approval and Source Management\n\t// =========================================================================\n\tconst handleDebugTools = useCallback(async (args: {\n\t\taction: string\n\t\ttoolCallId?: string\n\t\treason?: string\n\t\tmode?: string\n\t\tsourceIds?: string[]\n\t}) => {\n\t\tconst { action, toolCallId, reason, mode, sourceIds } = args\n\t\tconst state = stateRef.current\n\n\t\tswitch (action) {\n\t\t\tcase 'approve': {\n\t\t\t\tif (state.pendingToolCalls.length === 0) {\n\t\t\t\t\treturn { success: false, error: 'No pending tool calls to approve' }\n\t\t\t\t}\n\n\t\t\t\tconst target = toolCallId\n\t\t\t\t\t? state.pendingToolCalls.find((tc) => tc.toolCallId === toolCallId)\n\t\t\t\t\t: state.pendingToolCalls[0]\n\n\t\t\t\tif (!target) {\n\t\t\t\t\treturn { success: false, error: `Tool call not found: ${toolCallId}` }\n\t\t\t\t}\n\n\t\t\t\t// Execute the tool via MCP and add result\n\t\t\t\tif (!state.mcpTools) {\n\t\t\t\t\treturn { success: false, error: 'MCP tools context not available' }\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await state.mcpTools.callTool(target.toolName, target.args)\n\t\t\t\t\tconst resultString = JSON.stringify(result.content ?? result)\n\t\t\t\t\tresolvePendingToolCall(state.threadRuntime, target.messageId, target.toolCallId, resultString)\n\t\t\t\t\treturn { success: true, toolName: target.toolName, result: resultString }\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst errorMsg = e instanceof Error ? e.message : 'Tool execution failed'\n\t\t\t\t\tresolvePendingToolCall(state.threadRuntime, target.messageId, target.toolCallId, `Error: ${errorMsg}`)\n\t\t\t\t\treturn { success: false, error: errorMsg }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcase 'deny': {\n\t\t\t\tif (state.pendingToolCalls.length === 0) {\n\t\t\t\t\treturn { success: false, error: 'No pending tool calls to deny' }\n\t\t\t\t}\n\n\t\t\t\tconst target = toolCallId\n\t\t\t\t\t? state.pendingToolCalls.find((tc) => tc.toolCallId === toolCallId)\n\t\t\t\t\t: state.pendingToolCalls[0]\n\n\t\t\t\tif (!target) {\n\t\t\t\t\treturn { success: false, error: `Tool call not found: ${toolCallId}` }\n\t\t\t\t}\n\n\t\t\t\tconst denyMessage = reason\n\t\t\t\t\t? `${TOOL_DENIED_MESSAGE} Reason: ${reason}`\n\t\t\t\t\t: TOOL_DENIED_MESSAGE\n\n\t\t\t\tresolvePendingToolCall(state.threadRuntime, target.messageId, target.toolCallId, denyMessage)\n\t\t\t\treturn { success: true, toolName: target.toolName, denied: true, reason }\n\t\t\t}\n\n\t\t\tcase 'setApprovalMode':\n\t\t\t\tif (!mode) {\n\t\t\t\t\treturn { success: false, error: 'mode parameter required for setApprovalMode action' }\n\t\t\t\t}\n\t\t\t\tif (!state.toolApproval) {\n\t\t\t\t\treturn { success: false, error: 'ToolApproval context not available' }\n\t\t\t\t}\n\t\t\t\tstate.toolApproval.setMode(mode as ToolApprovalMode)\n\t\t\t\treturn { success: true, mode }\n\n\t\t\tcase 'selectSources': {\n\t\t\t\tif (!sourceIds || sourceIds.length === 0) {\n\t\t\t\t\treturn { success: false, error: 'sourceIds parameter required for selectSources action' }\n\t\t\t\t}\n\t\t\t\tif (!state.toolSelection) {\n\t\t\t\t\treturn { success: false, error: 'ToolSelection context not available' }\n\t\t\t\t}\n\n\t\t\t\t// Build ToolSourceSelector array from source IDs\n\t\t\t\tconst selectedSources: ToolSourceSelector[] = sourceIds\n\t\t\t\t\t.map((sourceId) => {\n\t\t\t\t\t\tconst source = state.toolSelection!.sources.find((s) => s.sourceId === sourceId)\n\t\t\t\t\t\tif (!source) return null\n\t\t\t\t\t\treturn { sourceId: source.sourceId, tabId: source.tabId }\n\t\t\t\t\t})\n\t\t\t\t\t.filter((s): s is ToolSourceSelector => s !== null)\n\n\t\t\t\tawait state.toolSelection.setSelection({ selectedSources })\n\t\t\t\treturn { success: true, selectedSourceIds: selectedSources.map((s) => s.sourceId) }\n\t\t\t}\n\n\t\t\tcase 'deselectSources': {\n\t\t\t\tif (!sourceIds || sourceIds.length === 0) {\n\t\t\t\t\treturn { success: false, error: 'sourceIds parameter required for deselectSources action' }\n\t\t\t\t}\n\t\t\t\tif (!state.toolSelection) {\n\t\t\t\t\treturn { success: false, error: 'ToolSelection context not available' }\n\t\t\t\t}\n\n\t\t\t\tconst currentSelected = state.toolSelection.selection?.selectedSources ?? []\n\t\t\t\tconst newSelected = currentSelected.filter((s) => !sourceIds.includes(s.sourceId))\n\t\t\t\tawait state.toolSelection.setSelection({ selectedSources: newSelected })\n\t\t\t\treturn { success: true, selectedSourceIds: newSelected.map((s) => s.sourceId) }\n\t\t\t}\n\n\t\t\tcase 'selectAllSources': {\n\t\t\t\tif (!state.toolSelection) {\n\t\t\t\t\treturn { success: false, error: 'ToolSelection context not available' }\n\t\t\t\t}\n\n\t\t\t\tconst allSources: ToolSourceSelector[] = state.toolSelection.sources.map((s) => ({\n\t\t\t\t\tsourceId: s.sourceId,\n\t\t\t\t\ttabId: s.tabId,\n\t\t\t\t}))\n\t\t\t\tawait state.toolSelection.setSelection({ selectedSources: allSources })\n\t\t\t\treturn { success: true, selectedSourceIds: allSources.map((s) => s.sourceId) }\n\t\t\t}\n\n\t\t\tcase 'deselectAllSources': {\n\t\t\t\tif (!state.toolSelection) {\n\t\t\t\t\treturn { success: false, error: 'ToolSelection context not available' }\n\t\t\t\t}\n\n\t\t\t\tawait state.toolSelection.setSelection({ selectedSources: [] })\n\t\t\t\treturn { success: true, selectedSourceIds: [] }\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn { success: false, error: `Unknown action: ${action}` }\n\t\t}\n\t}, [])\n\n\tuseWebMCP({\n\t\tname: `${DEBUG_TOOL_PREFIX}tools`,\n\t\tdescription: DEBUG_TOOLS_DESCRIPTION,\n\t\tinputSchema: DEBUG_TOOLS_SCHEMA,\n\t\thandler: handleDebugTools,\n\t})\n\n\t// =========================================================================\n\t// Tool 4: debug_session - Thread and Voice Control\n\t// =========================================================================\n\tconst handleDebugSession = useCallback(async (args: { action: string; threadId?: string }) => {\n\t\tconst { action, threadId } = args\n\t\tconst state = stateRef.current\n\n\t\tswitch (action) {\n\t\t\tcase 'startNewThread':\n\t\t\t\ttry {\n\t\t\t\t\tstate.assistantApi.threads().switchToNewThread()\n\t\t\t\t\treturn { success: true, message: 'Started new thread' }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to start new thread' }\n\t\t\t\t}\n\n\t\t\tcase 'switchThread':\n\t\t\t\tif (!threadId) {\n\t\t\t\t\treturn { success: false, error: 'threadId parameter required for switchThread action' }\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tstate.assistantApi.threads().switchToThread(threadId)\n\t\t\t\t\treturn { success: true, threadId }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to switch thread' }\n\t\t\t\t}\n\n\t\t\tcase 'listThreads':\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tisLoading: state.threadsLoading,\n\t\t\t\t\tcurrentThreadId: state.currentThreadId,\n\t\t\t\t\tthreadIds: [...state.threadIds],\n\t\t\t\t}\n\n\t\t\tcase 'voiceStart':\n\t\t\t\tif (!state.voiceThread) {\n\t\t\t\t\treturn { success: false, error: 'Voice context not available' }\n\t\t\t\t}\n\t\t\t\tif (!state.voiceThread.isSupported) {\n\t\t\t\t\treturn { success: false, error: 'Voice mode not supported in this browser' }\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait state.voiceThread.start()\n\t\t\t\t\treturn { success: true, message: 'Voice session started' }\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn { success: false, error: e instanceof Error ? e.message : 'Failed to start voice session' }\n\t\t\t\t}\n\n\t\t\tcase 'voiceStop':\n\t\t\t\tif (!state.voiceThread) {\n\t\t\t\t\treturn { success: false, error: 'Voice context not available' }\n\t\t\t\t}\n\t\t\t\tstate.voiceThread.stop()\n\t\t\t\treturn { success: true, message: 'Voice session stopped' }\n\n\t\t\tcase 'voiceToggleMute':\n\t\t\t\tif (!state.voiceThread) {\n\t\t\t\t\treturn { success: false, error: 'Voice context not available' }\n\t\t\t\t}\n\t\t\t\tstate.voiceThread.toggleMute()\n\t\t\t\treturn { success: true, isMuted: !state.voiceThread.isMuted }\n\n\t\t\tdefault:\n\t\t\t\treturn { success: false, error: `Unknown action: ${action}` }\n\t\t}\n\t}, [])\n\n\tuseWebMCP({\n\t\tname: `${DEBUG_TOOL_PREFIX}session`,\n\t\tdescription: DEBUG_SESSION_DESCRIPTION,\n\t\tinputSchema: DEBUG_SESSION_SCHEMA,\n\t\thandler: handleDebugSession,\n\t})\n}\n\n/**\n * Check if a tool name is a debug tool based on prefix\n */\nexport function isDebugTool(toolName: string): boolean {\n\treturn toolName.startsWith(DEBUG_TOOL_PREFIX)\n}\n","/**\n * AgentProvider\n *\n * Unified provider that wraps all agent infrastructure:\n * - AgentUIProvider (non-thread UI state: open/close, position)\n * - MCPToolsProvider (tool registry and execution)\n * - AssistantRuntimeProvider (chat runtime - single source of truth for thread)\n * - VoiceThreadBridge (voice mode integrated with thread)\n *\n * This is the single entry point for setting up agent capabilities.\n * Widgets (Pill, Modal) and custom UIs should be wrapped by this provider.\n *\n * Architecture:\n * ```\n * AgentUIProvider (UI state - persists across threads)\n * └── MCPToolsProvider (tools - shared across threads)\n * └── AssistantRuntimeProvider (thread state - single source of truth)\n * └── VoiceThreadBridge (voice → thread integration)\n * └── children\n * ```\n *\n * Runtime Selection:\n * - With `authToken`: Uses CloudflareThreadRuntimeProvider (WebSocket, Durable Object, persistent)\n * - Without `authToken`: Uses useStatelessRuntime (HTTP streaming, no persistence)\n *\n * Tool sync: MCP tools are synced directly to the CF agent backend via\n * the ThreadManager + ThreadAgent runtimes, similar to how voice mode syncs\n * tools to the OpenAI Realtime service.\n *\n * @example Stateful usage (SSO-first)\n * ```tsx\n * import { AgentProvider, AgentPill } from '@mcp-b/embedded-agent'\n * import { useOktaAuth } from '@okta/okta-react'\n *\n * function App() {\n * const { authState } = useOktaAuth()\n * return (\n * <AgentProvider\n * apiBase=\"https://your-worker.workers.dev\"\n * authToken={authState?.idToken?.idToken ?? ''}\n * >\n * <AgentPill />\n * </AgentProvider>\n * )\n * }\n * ```\n *\n * @example Stateless usage (no auth - dev/anonymous)\n * ```tsx\n * import { AgentProvider, AgentPill } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return (\n * <AgentProvider apiBase=\"http://localhost:3000\">\n * <AgentPill />\n * </AgentProvider>\n * )\n * }\n * ```\n *\n * @example Headless usage (custom UI)\n * ```tsx\n * import { AgentProvider, useAgent } from '@mcp-b/embedded-agent'\n *\n * function CustomUI() {\n * const agent = useAgent()\n * return <div>{agent.messages.map(m => ...)}</div>\n * }\n *\n * function App() {\n * return (\n * <AgentProvider apiBase=\"https://...\">\n * <CustomUI />\n * </AgentProvider>\n * )\n * }\n * ```\n */\n\nimport type { ToolApprovalMode, ToolWithSource } from '@mcp-b/cloud-mirror-types'\nimport * as React from 'react'\nimport { useCallback, useEffect, type FC, type ReactNode } from 'react'\n\nimport {\n\tAssistantRuntimeProvider,\n\tExportedMessageRepository,\n\tuseThreadRuntime,\n} from '@assistant-ui/react'\n\nimport { injectStyles } from '../utils/inject-styles'\n\nimport { WEBMCP_PRODUCTION_API_BASE } from '../utils/constants'\nimport { AuthErrorBoundary } from '../components/errors/AuthErrorBoundary'\nimport { MCPToolRegistry } from './MCPToolRegistry'\nimport { MCPToolsProvider, useMCPTools } from './MCPToolsProvider'\nimport { ToolApprovalProvider, useToolApproval } from './ToolApprovalProvider'\nimport {\n\tToolExclusionProvider,\n\ttype ToolExclusionFilter,\n} from './ToolExclusionProvider'\nimport { VoiceThreadBridge } from './VoiceThreadBridge'\nimport { useStatelessRuntime } from '../hooks/useStatelessRuntime'\nimport { AgentUIProvider, type PillMode } from './AgentUIProvider'\nimport {\n\tCloudflareThreadRuntimeProvider,\n\tuseCloudflareThread,\n\tuseOptionalCloudflareThread,\n} from './CloudflareThreadRuntimeProvider'\nimport { ThreadControlProvider } from './ThreadControlProvider'\nimport { useWebMCPDebugTools } from '../hooks/use-webmcp-debug-tools'\n\nexport interface AgentProviderConfig {\n\t/** API base URL for chat and token endpoints (defaults to production WebMCP API) */\n\tapiBase?: string\n\n\t/**\n\t * IDP token for SSO-first authentication.\n\t *\n\t * When provided:\n\t * - Uses WebSocket connection to Cloudflare Durable Object\n\t * - Messages are persisted and survive page refresh\n\t * - Supports refresh-safe streaming\n\t * - Backend validates token against org's configured IDP\n\t * - User ID extracted from token's sub claim\n\t *\n\t * When NOT provided:\n\t * - Uses HTTP streaming (stateless mode)\n\t * - Messages only persist in frontend memory\n\t * - Good for dev mode or anonymous users\n\t *\n\t * Benefits:\n\t * - No API keys needed\n\t * - Zero backend code for OIDC customers\n\t * - Users don't need to log in again (already authenticated)\n\t *\n\t * @example\n\t * ```tsx\n\t * // Customer's existing auth (unchanged)\n\t * const { session } = useOktaAuth()\n\t *\n\t * // Pass the token they already have\n\t * <AgentProvider authToken={session.idToken} />\n\t * ```\n\t */\n\tauthToken?: string\n\n\t/**\n\t * Anthropic API key for devMode (stateless runtime only).\n\t *\n\t * When provided WITHOUT authToken:\n\t * - Uses stateless runtime with Anthropic's Claude\n\t * - User's API key is passed to backend via header\n\t * - Good for development/testing without backend setup\n\t *\n\t * When authToken is provided, this is ignored (uses stateful runtime instead).\n\t */\n\tanthropicApiKey?: string\n\n\t/**\n\t * Development mode configuration (alternative to anthropicApiKey).\n\t * When provided, anthropicApiKey is extracted from devMode.anthropicApiKey.\n\t */\n\tdevMode?: {\n\t\tanthropicApiKey?: string\n\t\topenaiApiKey?: string\n\t\tuseLocalApi?: boolean\n\t}\n\n\t/** Host for the Cloudflare Agent WebSocket connection (defaults to apiBase hostname or localhost:8787) */\n\thost?: string\n\n\t/** Agent binding name to connect to (defaults to 'ChatAgent') */\n\tagent?: string\n\n\t/** Voice mode token endpoint (defaults to {apiBase}/api/realtime/session) */\n\ttokenEndpoint?: string\n\n\t/** Auto-connect to local MCP source (default: true) */\n\tautoConnectLocal?: boolean\n\n\t/**\n\t * Controlled open state. When provided, the host controls whether the UI is open.\n\t * Use with `onOpenChange` to handle state changes.\n\t */\n\topen?: boolean\n\n\t/** Initial open state for uncontrolled usage (default: false) */\n\tdefaultOpen?: boolean\n\n\t/** Initial pill mode (default: 'collapsed') */\n\tdefaultMode?: PillMode\n\n\t/** Initial tool approval mode: 'ask' requires confirmation, 'auto' executes immediately (default: 'ask') */\n\tdefaultApprovalMode?: ToolApprovalMode\n\n\t/** Callback when MCP tools change */\n\tonToolsChange?: (tools: ToolWithSource[]) => void\n\n\t/** Callback when voice mode errors */\n\tonVoiceError?: (error: string) => void\n\n\t/** Callback when voice mode connects */\n\tonVoiceConnect?: () => void\n\n\t/** Callback when voice mode disconnects */\n\tonVoiceDisconnect?: (duration: number) => void\n\n\t/** Callback when UI open state changes */\n\tonOpenChange?: (open: boolean) => void\n\n\t/** Callback when pill mode changes */\n\tonModeChange?: (mode: PillMode) => void\n\n\t/** Callback when tool approval mode changes */\n\tonApprovalModeChange?: (mode: ToolApprovalMode) => void\n\n\t/**\n\t * Custom filter function to exclude tools from the agent.\n\t * Return true to exclude the tool, false to include it.\n\t *\n\t * @example Exclude by prefix\n\t * ```tsx\n\t * excludeTools={(name) => name.startsWith('internal_')}\n\t * ```\n\t */\n\texcludeTools?: ToolExclusionFilter\n\n\t/**\n\t * Array of specific tool names to exclude from the agent.\n\t */\n\texcludeToolNames?: string[]\n\n\t/**\n\t * Array of prefixes - tools starting with any of these will be excluded.\n\t */\n\texcludeToolPrefixes?: string[]\n\n\t/**\n\t * Enable debug tools for inspecting embedded agent internal state.\n\t * Debug tools are prefixed with `debug_` and expose:\n\t * - Agent connection state\n\t * - Tool sources from ThreadManager\n\t * - Local MCP tools\n\t * - Cross-site tool calling diagnostics\n\t *\n\t * @default false\n\t */\n\tenableDebugTools?: boolean\n\n\t/**\n\t * Base URL for dashboard (for error screen links).\n\t * @example \"https://app.char.ai\"\n\t */\n\tdashboardBaseUrl?: string\n\n\t/**\n\t * Base URL for documentation (for error screen links).\n\t * @example \"https://docs.char.ai\"\n\t */\n\tdocsBaseUrl?: string\n\n\t/**\n\t * Callback when an authentication error occurs.\n\t * Useful for logging/analytics.\n\t */\n\tonAuthError?: (error: Error, errorInfo?: React.ErrorInfo) => void\n\n\t/**\n\t * Show debug info in error screens (dev mode).\n\t * @default false\n\t */\n\tshowErrorDebug?: boolean\n}\n\nexport interface AgentProviderProps extends AgentProviderConfig {\n\tchildren: ReactNode\n}\n\n/**\n * Internal component that sets up the chat runtime and voice bridge.\n * Must be inside MCPToolsProvider so VoiceThreadBridge can access tools.\n */\ninterface AgentRuntimeProps {\n\tchildren: ReactNode\n\tapiBase?: string\n\tauthToken?: string\n\tanthropicApiKey?: string\n\thost?: string\n\tagent?: string\n\ttokenEndpoint?: string\n\tenableDebugTools?: boolean\n\tdashboardBaseUrl?: string\n\tdocsBaseUrl?: string\n\tonVoiceError?: (error: string) => void\n\tonVoiceConnect?: () => void\n\tonVoiceDisconnect?: (duration: number) => void\n}\n\n/**\n * Component that registers debug tools when enabled.\n * Must be inside MCPToolsProvider but BEFORE AgentRuntime so that\n * debug tools are registered before mcpTools is captured.\n *\n * Note: Some debug tools query CloudflareThread context which won't be\n * available at this level, but they handle this gracefully with error messages.\n */\nconst DebugToolsRegistrar: FC = () => {\n\t// Use optional hook since this component renders BEFORE CloudflareThreadRuntimeProvider\n\tconst cloudflareThread = useOptionalCloudflareThread()\n\tconst { refreshTools } = useMCPTools()\n\n\tuseWebMCPDebugTools({\n\t\tadditionalState: cloudflareThread\n\t\t\t? {\n\t\t\t\t\tcloudflareThread: {\n\t\t\t\t\t\tisInitialized: cloudflareThread.isInitialized,\n\t\t\t\t\t\tisReady: cloudflareThread.isReady,\n\t\t\t\t\t\tcurrentThreadId: cloudflareThread.currentThreadId,\n\t\t\t\t\t\tendUserId: cloudflareThread.endUserId,\n\t\t\t\t\t\torganizationId: cloudflareThread.organizationId,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: undefined,\n\t})\n\n\t// Trigger a refresh after a short delay to allow useWebMCP to register tools.\n\t// This ensures debug tools are discovered even if registered after the initial\n\t// MCP connection. The delay accounts for the useWebMCP effects running.\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tvoid refreshTools()\n\t\t}, 200)\n\t\treturn () => clearTimeout(timer)\n\t}, [refreshTools])\n\n\treturn null\n}\n\ninterface StatefulRuntimeBridgeProps {\n\tchildren: ReactNode\n\ttokenEndpoint: string\n\tenableDebugTools?: boolean\n\tonVoiceError?: (error: string) => void\n\tonVoiceConnect?: () => void\n\tonVoiceDisconnect?: (duration: number) => void\n}\n\nconst StatefulRuntimeBridge: FC<StatefulRuntimeBridgeProps> = ({\n\tchildren,\n\ttokenEndpoint,\n\tenableDebugTools,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\tconst { reset, startNew } = useCloudflareThread()\n\n\treturn (\n\t\t<ThreadControlProvider reset={reset} startNew={startNew}>\n\t\t\t<VoiceThreadBridge\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tonError={onVoiceError}\n\t\t\t\tonConnect={onVoiceConnect}\n\t\t\t\tonDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t<MCPToolRegistry />\n\t\t\t\t{enableDebugTools && <DebugToolsRegistrar />}\n\t\t\t\t{children}\n\t\t\t</VoiceThreadBridge>\n\t\t</ThreadControlProvider>\n\t)\n}\n\n/**\n * Stateful runtime using Cloudflare Durable Objects.\n * Messages are persisted and streaming is refresh-safe.\n * Requires authToken for SSO-first authentication.\n */\nconst StatefulRuntime: FC<AgentRuntimeProps & { authToken: string }> = ({\n\tchildren,\n\tapiBase,\n\tauthToken,\n\thost,\n\ttokenEndpoint,\n\tenableDebugTools,\n\tdashboardBaseUrl,\n\tdocsBaseUrl,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\t// Get MCP tools and execution function\n\tconst { tools: mcpTools, callTool } = useMCPTools()\n\n\t// Get tool approval mode\n\tconst { mode: approvalMode } = useToolApproval()\n\n\t// Resolve API base (defaults to production)\n\tconst resolvedApiBase = apiBase ?? WEBMCP_PRODUCTION_API_BASE\n\n\t// Derive host from apiBase if not explicitly provided\n\tconst resolvedHost =\n\t\thost ??\n\t\t(() => {\n\t\t\ttry {\n\t\t\t\tconst url = new URL(resolvedApiBase)\n\t\t\t\treturn url.host\n\t\t\t} catch {\n\t\t\t\treturn 'localhost:3000'\n\t\t\t}\n\t\t})()\n\n\t// Compute token endpoint from apiBase if not explicitly provided\n\tconst resolvedTokenEndpoint = tokenEndpoint || `${resolvedApiBase}/api/realtime/session`\n\n\treturn (\n\t\t<CloudflareThreadRuntimeProvider\n\t\t\thost={resolvedHost}\n\t\t\tauthToken={authToken}\n\t\t\tmcpTools={mcpTools}\n\t\t\texecuteMCPTool={callTool}\n\t\t\tapprovalMode={approvalMode}\n\t\t\tdashboardBaseUrl={dashboardBaseUrl}\n\t\t\tdocsBaseUrl={docsBaseUrl}\n\t\t>\n\t\t\t<StatefulRuntimeBridge\n\t\t\t\ttokenEndpoint={resolvedTokenEndpoint}\n\t\t\t\tenableDebugTools={enableDebugTools}\n\t\t\t\tonVoiceError={onVoiceError}\n\t\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</StatefulRuntimeBridge>\n\t\t</CloudflareThreadRuntimeProvider>\n\t)\n}\n\n/**\n * Bridge component for stateless runtime that provides thread control.\n * Must be inside AssistantRuntimeProvider to access useThreadRuntime.\n */\ninterface StatelessRuntimeBridgeProps {\n\tchildren: ReactNode\n\ttokenEndpoint: string\n\tenableDebugTools?: boolean\n\tonVoiceError?: (error: string) => void\n\tonVoiceConnect?: () => void\n\tonVoiceDisconnect?: (duration: number) => void\n}\n\nconst StatelessRuntimeBridge: FC<StatelessRuntimeBridgeProps> = ({\n\tchildren,\n\ttokenEndpoint,\n\tenableDebugTools,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\tconst threadRuntime = useThreadRuntime()\n\n\t// Reset clears frontend messages for stateless runtime\n\tconst reset = useCallback(async () => {\n\t\tconsole.log('[StatelessRuntime] Reset called - clearing frontend messages')\n\t\tthreadRuntime.import(ExportedMessageRepository.fromArray([]))\n\t}, [threadRuntime])\n\n\treturn (\n\t\t<ThreadControlProvider reset={reset}>\n\t\t\t<VoiceThreadBridge\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tonError={onVoiceError}\n\t\t\t\tonConnect={onVoiceConnect}\n\t\t\t\tonDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t<MCPToolRegistry />\n\t\t\t\t{enableDebugTools && <DebugToolsRegistrar />}\n\t\t\t\t{children}\n\t\t\t</VoiceThreadBridge>\n\t\t</ThreadControlProvider>\n\t)\n}\n\n/**\n * Stateless runtime using HTTP streaming.\n * Messages only persist in frontend memory.\n * Good for dev mode or anonymous users.\n */\nconst StatelessRuntime: FC<Omit<AgentRuntimeProps, 'host' | 'agent'>> = ({\n\tchildren,\n\tapiBase,\n\tanthropicApiKey,\n\ttokenEndpoint,\n\tenableDebugTools,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\t// Resolve API base (defaults to production)\n\tconst resolvedApiBase = apiBase ?? WEBMCP_PRODUCTION_API_BASE\n\n\t// Create stateless runtime\n\tconst { runtime } = useStatelessRuntime({\n\t\tapiBase: resolvedApiBase,\n\t\tanthropicApiKey,\n\t})\n\n\t// Compute token endpoint from apiBase if not explicitly provided\n\tconst resolvedTokenEndpoint = tokenEndpoint || `${resolvedApiBase}/api/realtime/session`\n\n\treturn (\n\t\t<AssistantRuntimeProvider runtime={runtime}>\n\t\t\t<StatelessRuntimeBridge\n\t\t\t\ttokenEndpoint={resolvedTokenEndpoint}\n\t\t\t\tenableDebugTools={enableDebugTools}\n\t\t\t\tonVoiceError={onVoiceError}\n\t\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</StatelessRuntimeBridge>\n\t\t</AssistantRuntimeProvider>\n\t)\n}\n\n/**\n * Runtime selector - chooses between stateful and stateless based on authentication.\n *\n * Stateful mode: authToken provided (SSO-first - IDP token identifies user/org)\n * Stateless mode: no authToken (anonymous/demo - no persistence)\n */\nconst AgentRuntime: FC<AgentRuntimeProps> = ({\n\tchildren,\n\tapiBase,\n\tauthToken,\n\tanthropicApiKey,\n\thost,\n\tagent,\n\ttokenEndpoint,\n\tenableDebugTools,\n\tdashboardBaseUrl,\n\tdocsBaseUrl,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n}) => {\n\tif (authToken) {\n\t\treturn (\n\t\t\t<StatefulRuntime\n\t\t\t\tapiBase={apiBase}\n\t\t\t\tauthToken={authToken}\n\t\t\t\thost={host}\n\t\t\t\tagent={agent}\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tenableDebugTools={enableDebugTools}\n\t\t\t\tdashboardBaseUrl={dashboardBaseUrl}\n\t\t\t\tdocsBaseUrl={docsBaseUrl}\n\t\t\t\tonVoiceError={onVoiceError}\n\t\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</StatefulRuntime>\n\t\t)\n\t}\n\n\treturn (\n\t\t<StatelessRuntime\n\t\t\tapiBase={apiBase}\n\t\t\tanthropicApiKey={anthropicApiKey}\n\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\tenableDebugTools={enableDebugTools}\n\t\t\tonVoiceError={onVoiceError}\n\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t>\n\t\t\t{children}\n\t\t</StatelessRuntime>\n\t)\n}\n\n/**\n * Unified provider for all agent capabilities.\n *\n * Provides:\n * - UI state (open/close, position) via AgentUIProvider\n * - MCP tool registry and execution via MCPToolsProvider\n * - Tool approval settings via ToolApprovalProvider\n * - Chat runtime (via @assistant-ui/react) - single source of truth for thread\n * - Voice mode integrated with thread (via VoiceThreadBridge)\n *\n * Use the `useAgent` hook to access agent state and capabilities.\n * Use the `useAgentUI` hook to access UI state (open/close, mode, position).\n * Use the `useToolApproval` hook to access tool approval settings.\n */\nexport const AgentProvider: FC<AgentProviderProps> = ({\n\tchildren,\n\tapiBase,\n\tauthToken,\n\tanthropicApiKey: anthropicApiKeyProp,\n\tdevMode,\n\thost,\n\tagent,\n\ttokenEndpoint,\n\tautoConnectLocal = true,\n\topen,\n\tdefaultOpen = false,\n\tdefaultMode = 'collapsed',\n\tdefaultApprovalMode,\n\texcludeTools,\n\texcludeToolNames,\n\texcludeToolPrefixes,\n\tenableDebugTools = false,\n\tdashboardBaseUrl,\n\tdocsBaseUrl,\n\tonAuthError,\n\tshowErrorDebug = false,\n\tonToolsChange,\n\tonVoiceError,\n\tonVoiceConnect,\n\tonVoiceDisconnect,\n\tonOpenChange,\n\tonModeChange,\n\tonApprovalModeChange,\n}) => {\n\t// Merge anthropicApiKey from both sources (devMode takes precedence)\n\tconst anthropicApiKey = devMode?.anthropicApiKey ?? anthropicApiKeyProp\n\n\t// Auto-inject styles on first mount (idempotent)\n\tuseEffect(() => {\n\t\tinjectStyles()\n\t}, [])\n\n\t// Determine if we need tool exclusion\n\tconst hasExclusions = excludeTools || excludeToolNames || excludeToolPrefixes\n\n\t// Content with or without exclusion provider\n\t// Note: DebugToolsRegistrar is rendered inside the runtime components (StatefulRuntimeBridge/StatelessRuntime)\n\t// so that it has access to ThreadRuntime and other assistant-ui contexts.\n\tconst content = (\n\t\t<MCPToolsProvider autoConnectLocal={autoConnectLocal} onToolsChange={onToolsChange}>\n\t\t\t<AgentRuntime\n\t\t\t\tapiBase={apiBase}\n\t\t\t\tauthToken={authToken}\n\t\t\t\tanthropicApiKey={anthropicApiKey}\n\t\t\t\thost={host}\n\t\t\t\tagent={agent}\n\t\t\t\ttokenEndpoint={tokenEndpoint}\n\t\t\t\tenableDebugTools={enableDebugTools}\n\t\t\t\tdashboardBaseUrl={dashboardBaseUrl}\n\t\t\t\tdocsBaseUrl={docsBaseUrl}\n\t\t\t\tonVoiceError={onVoiceError}\n\t\t\t\tonVoiceConnect={onVoiceConnect}\n\t\t\t\tonVoiceDisconnect={onVoiceDisconnect}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</AgentRuntime>\n\t\t</MCPToolsProvider>\n\t)\n\n\treturn (\n\t\t<AuthErrorBoundary\n\t\t\tdashboardBaseUrl={dashboardBaseUrl}\n\t\t\tdocsBaseUrl={docsBaseUrl}\n\t\t\tonError={onAuthError}\n\t\t\tshowDebug={showErrorDebug}\n\t\t>\n\t\t\t<AgentUIProvider\n\t\t\t\topen={open}\n\t\t\t\tdefaultOpen={defaultOpen}\n\t\t\t\tdefaultMode={defaultMode}\n\t\t\t\tonOpenChange={onOpenChange}\n\t\t\t\tonModeChange={onModeChange}\n\t\t\t>\n\t\t\t\t<ToolApprovalProvider defaultMode={defaultApprovalMode} onModeChange={onApprovalModeChange}>\n\t\t\t\t\t{hasExclusions ? (\n\t\t\t\t\t\t<ToolExclusionProvider\n\t\t\t\t\t\t\texclude={excludeTools}\n\t\t\t\t\t\t\texcludeNames={excludeToolNames}\n\t\t\t\t\t\t\texcludePrefixes={excludeToolPrefixes}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t</ToolExclusionProvider>\n\t\t\t\t\t) : (\n\t\t\t\t\t\tcontent\n\t\t\t\t\t)}\n\t\t\t\t</ToolApprovalProvider>\n\t\t\t</AgentUIProvider>\n\t\t</AuthErrorBoundary>\n\t)\n}\n","'use client'\n\n/**\n * AgentThread - Self-contained thread UI component\n *\n * A full chat interface that fills its container. Includes all provider\n * infrastructure internally - no wrapper needed.\n *\n * @example Basic usage\n * ```tsx\n * import { AgentThread } from '@mcp-b/embedded-agent'\n *\n * function App() {\n * return (\n * <div className=\"h-screen\">\n * <AgentThread\n * apiBase=\"https://your-api.com\"\n * authToken={session.idToken}\n * />\n * </div>\n * )\n * }\n * ```\n *\n * @example With close button\n * ```tsx\n * <AgentThread\n * apiBase=\"https://your-api.com\"\n * authToken={session.idToken}\n * onClose={() => setShowAgent(false)}\n * />\n * ```\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { FC } from 'react'\nimport { ArrowLeft, Plus, X } from 'lucide-react'\n\nimport { Thread } from '../components/assistant-ui/thread'\nimport { TooltipIconButton } from '../components/assistant-ui/tooltip-icon-button'\nimport { AgentThreadList } from '../components/agent/AgentThreadList'\nimport { useAgent } from '../hooks/useAgent'\nimport { useAgentThreads } from '../hooks/useAgentThreads'\nimport { AgentProvider, type AgentProviderConfig } from '../providers/AgentProvider'\nimport { cn } from '../utils/cn'\n\n/** Screen types for internal navigation */\ntype Screen = 'thread-list' | 'thread-view'\n\n/**\n * Props for the AgentThread component.\n * Combines provider configuration with UI options.\n */\nexport interface AgentThreadProps extends AgentProviderConfig {\n\t/** Additional class name for the container */\n\tclassName?: string\n\n\t/** Callback when close button is clicked */\n\tonClose?: () => void\n}\n\n/**\n * AgentThread - Self-contained full thread UI\n *\n * Renders a complete chat interface with:\n * - Thread view with messages\n * - Thread list navigation\n * - New thread creation\n * - All provider infrastructure built-in\n */\nexport const AgentThread: FC<AgentThreadProps> = ({ className, onClose, ...providerConfig }) => {\n\treturn (\n\t\t<AgentProvider {...providerConfig}>\n\t\t\t<AgentThreadInner className={className} onClose={onClose} />\n\t\t</AgentProvider>\n\t)\n}\n\ninterface AgentThreadInnerProps {\n\tclassName?: string\n\tonClose?: () => void\n}\n\n/**\n * Inner component that renders the thread UI.\n * Must be inside AgentProvider to access hooks.\n */\nconst AgentThreadInner: FC<AgentThreadInnerProps> = ({ className, onClose }) => {\n\tconst { isLoading, threadIds, switchToNewThread } = useAgentThreads()\n\tconst agent = useAgent()\n\n\t// Internal screen navigation state\n\tconst [screen, setScreen] = useState<Screen>('thread-view')\n\n\t// Switch to thread list\n\tconst showThreadList = useCallback(() => {\n\t\tsetScreen('thread-list')\n\t}, [])\n\n\t// Switch to thread view\n\tconst showThreadView = useCallback(() => {\n\t\tsetScreen('thread-view')\n\t}, [])\n\n\t// Start new thread and switch to thread view\n\tconst startNewThread = useCallback(() => {\n\t\tsetScreen('thread-view')\n\t\tvoid agent.thread?.startNew()?.catch((error) => {\n\t\t\tconsole.error('[AgentThread] Failed to start new thread:', error)\n\t\t})\n\t}, [agent.thread])\n\n\t// Handle thread selection from list\n\tconst handleSelectThread = useCallback(() => {\n\t\tsetScreen('thread-view')\n\t}, [])\n\n\t// Auto-create first thread if none exist\n\tconst didAutoCreateThreadRef = useRef(false)\n\tuseEffect(() => {\n\t\tif (didAutoCreateThreadRef.current) return\n\t\tif (isLoading) return\n\t\tif (threadIds.length > 0) return\n\n\t\tdidAutoCreateThreadRef.current = true\n\t\ttry {\n\t\t\tswitchToNewThread()\n\t\t} catch (error) {\n\t\t\tconsole.error('[AgentThread] Failed to auto-create initial thread:', error)\n\t\t}\n\t}, [isLoading, threadIds.length, switchToNewThread])\n\n\t/** Glassmorphic button styles */\n\tconst glassmorphicButtonClass =\n\t\t'wm:h-8 wm:w-8 wm:rounded-full wm:border wm:border-white/10 wm:backdrop-blur-sm wm:shadow-lg wm:shadow-black/20 wm:bg-[color-mix(in_oklab,rgb(var(--background))_20%,transparent)] [box-shadow:inset_0_1px_2px_0_rgba(255,255,255,0.15)] wm:transition-all wm:duration-200 hover:wm:border-white/20 hover:wm:bg-[color-mix(in_oklab,rgb(var(--background))_30%,transparent)]'\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'wm:relative wm:flex wm:h-full wm:w-full wm:min-h-0 wm:flex-col',\n\t\t\t\t'wm:bg-background wm:text-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t{screen === 'thread-list' ? (\n\t\t\t\t<div className=\"wm:relative wm:flex wm:min-h-0 wm:flex-1 wm:flex-col\">\n\t\t\t\t\t{/* Floating top bar for thread list */}\n\t\t\t\t\t<div className=\"wm:absolute wm:top-2 wm:left-2 wm:right-2 wm:z-50 wm:flex wm:items-center wm:gap-2\">\n\t\t\t\t\t\t{/* Left side - Back button */}\n\t\t\t\t\t\t<div className=\"wm:flex wm:gap-1\">\n\t\t\t\t\t\t\t<TooltipIconButton\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\tclassName={glassmorphicButtonClass}\n\t\t\t\t\t\t\t\tonClick={showThreadView}\n\t\t\t\t\t\t\t\ttooltip=\"Back to chat\"\n\t\t\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ArrowLeft className=\"wm:h-4 wm:w-4\" />\n\t\t\t\t\t\t\t</TooltipIconButton>\n\t\t\t\t\t\t\t<TooltipIconButton\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\tclassName={glassmorphicButtonClass}\n\t\t\t\t\t\t\t\tonClick={startNewThread}\n\t\t\t\t\t\t\t\ttooltip=\"New chat\"\n\t\t\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Plus className=\"wm:h-4 wm:w-4\" />\n\t\t\t\t\t\t\t</TooltipIconButton>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Right side - Close button */}\n\t\t\t\t\t\t{onClose && (\n\t\t\t\t\t\t\t<div className=\"wm:ml-auto\">\n\t\t\t\t\t\t\t\t<TooltipIconButton\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tclassName={glassmorphicButtonClass}\n\t\t\t\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\t\t\t\ttooltip=\"Close\"\n\t\t\t\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X className=\"wm:h-4 wm:w-4\" />\n\t\t\t\t\t\t\t\t</TooltipIconButton>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"wm:flex wm:min-h-0 wm:flex-1 wm:flex-col wm:gap-3 wm:p-3 wm:pt-14\">\n\t\t\t\t\t\t<AgentThreadList className=\"wm:flex-1\" onSelectThread={handleSelectThread} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<Thread\n\t\t\t\t\tonThreadsClick={showThreadList}\n\t\t\t\t\tonNewThread={startNewThread}\n\t\t\t\t\tonClose={onClose}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n","'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { FC, ReactNode } from 'react'\n\n/**\n * CSS variable names supported for external theming.\n * These can be set on the <webmcp-agent> host element.\n */\nconst CSS_VARIABLE_NAMES = [\n\t'--wm-color-primary',\n\t'--wm-color-primary-foreground',\n\t'--wm-color-secondary',\n\t'--wm-color-secondary-foreground',\n\t'--wm-color-accent',\n\t'--wm-color-accent-foreground',\n\t'--wm-color-background',\n\t'--wm-color-foreground',\n\t'--wm-color-muted',\n\t'--wm-color-muted-foreground',\n\t'--wm-color-border',\n\t'--wm-color-input',\n\t'--wm-color-ring',\n\t'--wm-radius',\n\t'--wm-font-sans',\n\t'--wm-user-bubble-bg',\n\t'--wm-user-bubble-text',\n\t'--wm-assistant-bubble-bg',\n\t'--wm-assistant-bubble-text',\n\t'--wm-composer-bg',\n\t'--wm-composer-border',\n\t'--wm-composer-button-bg',\n\t'--wm-composer-button-text',\n\t'--wm-composer-text',\n\t'--wm-tool-bg',\n\t'--wm-tool-border',\n\t'--wm-tool-approve-bg',\n\t'--wm-tool-deny-bg',\n\t'--wm-code-bg',\n\t'--wm-code-text',\n\t'--wm-input-bg',\n\t'--wm-input-border',\n\t'--wm-input-text',\n\t'--wm-font-size-xs',\n\t'--wm-font-size-sm',\n\t'--wm-font-size-base',\n\t'--wm-font-size-lg',\n] as const\n\n/**\n * Extracts CSS variables from a host element's computed styles.\n * Returns a CSS block with !important declarations to override defaults.\n */\nfunction extractCssVariables(hostElement: Element): string {\n\tconst hostStyles = getComputedStyle(hostElement)\n\tconst varsWithImportant = CSS_VARIABLE_NAMES.map(name => {\n\t\tconst value = hostStyles.getPropertyValue(name).trim()\n\t\treturn value ? `${name}: ${value} !important;` : ''\n\t})\n\t\t.filter(Boolean)\n\t\t.join('\\n\\t\\t\\t\\t')\n\n\tif (!varsWithImportant) return ''\n\n\treturn `\n\t\t\t/* CSS variables passed through from host element */\n\t\t\t/* Using !important to ensure custom variables override built-in defaults */\n\t\t\t:host, :host(.dark) {\n\t\t\t\t${varsWithImportant}\n\t\t\t}\n\t\t`\n}\n\nexport interface ShadowRootProps {\n\t/** Children to render inside the shadow DOM */\n\tchildren: ReactNode\n\t/** CSS styles to inject into the shadow root */\n\tstyles: string\n\t/** Optional class name for the shadow host element */\n\tclassName?: string\n\t/** Mode for the shadow DOM (default: 'open') */\n\tmode?: 'open' | 'closed'\n}\n\n/**\n * ShadowRoot - Renders children inside an isolated shadow DOM\n *\n * This component creates a shadow DOM boundary that:\n * - Isolates styles from the main page (no style leakage in/out)\n * - Injects provided CSS directly into the shadow root\n * - Uses React portals to render children into the shadow DOM\n * - Fills its parent container (position: relative, width/height: 100%)\n *\n * Why shadow DOM?\n * - Prevents host page CSS from affecting the agent widget\n * - Prevents agent CSS from affecting the host page\n * - Perfect for embeddable widgets on third-party sites\n *\n * @example\n * ```tsx\n * import { WEBMCP_SHADOW_STYLES } from './generated/inline-styles'\n *\n * <ShadowRoot styles={WEBMCP_SHADOW_STYLES}>\n * <AgentPill />\n * </ShadowRoot>\n * ```\n */\nexport const ShadowRoot: FC<ShadowRootProps> = ({\n\tchildren,\n\tstyles,\n\tclassName,\n\tmode = 'open',\n}) => {\n\tconst hostRef = useRef<HTMLDivElement>(null)\n\tconst [portalContainer, setPortalContainer] = useState<Element | null>(null)\n\n\t// Theme detection: observe host page's dark mode and sync to shadow host\n\tuseEffect(() => {\n\t\tconst host = hostRef.current\n\t\tif (!host) return\n\n\t\tconst syncTheme = () => {\n\t\t\tconst html = document.documentElement\n\t\t\tconst isDark =\n\t\t\t\thtml.classList.contains('dark') ||\n\t\t\t\t(!html.classList.contains('light') && window.matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t\thost.classList.toggle('dark', isDark)\n\t\t}\n\n\t\t// Initial sync\n\t\tsyncTheme()\n\n\t\t// Observe class changes on <html>\n\t\tconst observer = new MutationObserver(syncTheme)\n\t\tobserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })\n\n\t\t// Listen to system preference changes\n\t\tconst mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n\t\tmediaQuery.addEventListener('change', syncTheme)\n\n\t\treturn () => {\n\t\t\tobserver.disconnect()\n\t\t\tmediaQuery.removeEventListener('change', syncTheme)\n\t\t}\n\t}, [])\n\n\tuseEffect(() => {\n\t\tconst host = hostRef.current\n\t\tif (!host) return\n\n\t\t// Check if shadow root already exists (strict mode / hot reload)\n\t\tlet shadow = host.shadowRoot\n\t\tif (!shadow) {\n\t\t\tshadow = host.attachShadow({ mode })\n\t\t}\n\n\t\t// Extract CSS variables from the web component host element\n\t\t// This allows external stylesheets to customize the widget theme\n\t\tconst webComponentHost = host.parentElement // This should be <webmcp-agent>\n\t\tconst cssVariables = webComponentHost ? extractCssVariables(webComponentHost) : ''\n\n\t\t// Always use contained styles - fills parent container\n\t\tconst hostCSSRules = `\n\t\t\t:host {\n\t\t\t\tposition: relative !important;\n\t\t\t\tinset: auto !important;\n\t\t\t\tdisplay: block !important;\n\t\t\t\twidth: 100% !important;\n\t\t\t\theight: 100% !important;\n\t\t\t\tpointer-events: auto !important;\n\t\t\t}\n\t\t\t[data-webmcp-container] {\n\t\t\t\tdisplay: block !important;\n\t\t\t\twidth: 100% !important;\n\t\t\t\theight: 100% !important;\n\t\t\t}\n\t\t`\n\n\t\t// Create or update the style element\n\t\tlet styleElement = shadow.querySelector('style[data-webmcp-styles]')\n\t\tif (!styleElement) {\n\t\t\tstyleElement = document.createElement('style')\n\t\t\tstyleElement.setAttribute('data-webmcp-styles', '')\n\t\t\tshadow.insertBefore(styleElement, shadow.firstChild)\n\t\t}\n\t\t// Append CSS variables AFTER component styles to ensure they override defaults\n\t\t// CSS cascade order: hostCSSRules → component styles → custom variables (highest priority)\n\t\tstyleElement.textContent = hostCSSRules + styles + cssVariables\n\n\t\t// Create container for React content if it doesn't exist\n\t\tlet container = shadow.querySelector('[data-webmcp-container]')\n\t\tif (!container) {\n\t\t\tcontainer = document.createElement('div')\n\t\t\tcontainer.setAttribute('data-webmcp-container', '')\n\t\t\tshadow.appendChild(container)\n\t\t}\n\n\t\tsetPortalContainer(container)\n\t}, [mode, styles])\n\n\treturn (\n\t\t<div ref={hostRef} className={className}>\n\t\t\t{portalContainer && createPortal(children, portalContainer)}\n\t\t</div>\n\t)\n}\n\nexport default ShadowRoot\n","/**\n * WebMCP Agent\n *\n * An Intercom-like AI chat widget with MCP tool support and voice mode.\n * Drop it into your app and you're done - uses your existing SSO token.\n *\n * Styles are isolated by default using Shadow DOM. Customize appearance\n * via CSS variables on the host element.\n *\n * @example SSO-First (production usage)\n * ```tsx\n * // Use your existing IDP token - no additional login needed\n * const { session } = useOktaAuth() // or Azure, Auth0, Google, etc.\n *\n * <webmcp-agent auth-token={session.idToken} />\n * ```\n *\n * @example React\n * ```tsx\n * import '@mcp-b/embedded-agent/web-component'\n *\n * function App() {\n * const { session } = useOktaAuth()\n * return <webmcp-agent auth-token={session.idToken} />\n * }\n * ```\n *\n * @example Stateless (dev/anonymous - no auth required)\n * ```tsx\n * // No auth token = stateless mode (messages in memory only)\n * <webmcp-agent />\n * ```\n *\n * @example CSS variable theming\n * ```css\n * webmcp-agent {\n * --wm-color-primary: #0f766e;\n * --wm-radius: 12px;\n * }\n * ```\n */\n\nimport r2wc from '@r2wc/react-to-web-component'\n\nimport { AgentThread } from './public/AgentThread'\nimport { ShadowRoot } from './components/agent/ShadowRoot'\nimport { WEBMCP_SHADOW_STYLES } from './generated/inline-styles'\nimport { WEBMCP_PRODUCTION_API_BASE } from './utils/constants'\n\nimport type { FC } from 'react'\n\n/**\n * Get the default API base URL.\n * Always uses production unless explicitly overridden with useLocalApi.\n */\nconst getDefaultApiBase = (useLocalApi?: boolean): string => {\n\tif (useLocalApi && typeof window !== 'undefined') {\n\t\treturn window.location.origin\n\t}\n\treturn WEBMCP_PRODUCTION_API_BASE\n}\n\n/**\n * Development mode configuration\n *\n * Three modes of development:\n * 1. External development (anthropicApiKey) - Use your own Anthropic API key for chat\n * - Frontend sends key to backend via X-Anthropic-Api-Key header\n * - Backend uses Claude (Haiku) for cost-effective devMode\n * - No backend setup required beyond running the server\n * 2. Voice mode (openaiApiKey) - Add voice capabilities in dev\n * 3. Internal development (useLocalApi: true) - Use localhost as API base\n */\ninterface DevModeConfig {\n\t/**\n\t * Your Anthropic API key for chat.\n\t * When provided, the stateless runtime will use Claude instead of Gemini.\n\t * The key is passed to the backend via X-Anthropic-Api-Key header.\n\t */\n\tanthropicApiKey?: string\n\t/** Your OpenAI API key for voice mode (optional) */\n\topenaiApiKey?: string\n\t/** Use window.location.origin instead of production API (for internal development) */\n\tuseLocalApi?: boolean\n}\n\n/**\n * Props for the EmbeddedAgent component\n */\ninterface EmbeddedAgentProps {\n\t/**\n\t * IDP token for SSO-first authentication.\n\t *\n\t * Pass your existing IDP token (from Okta, Azure AD, Auth0, Google, etc.)\n\t * and the backend will validate it against your organization's configured IDP.\n\t *\n\t * When provided:\n\t * - Messages persist across refreshes (Cloudflare Durable Objects)\n\t * - User ID extracted from token's sub claim\n\t * - Tools shared across all your organization's apps\n\t *\n\t * When NOT provided:\n\t * - Stateless mode (messages in memory only)\n\t * - Good for dev/testing without auth setup\n\t *\n\t * @example\n\t * ```tsx\n\t * const { session } = useOktaAuth()\n\t * <webmcp-agent auth-token={session.idToken} />\n\t * ```\n\t */\n\tauthToken?: string\n\n\t/**\n\t * Controlled open state.\n\t * When provided, the host controls whether the agent UI is open or collapsed.\n\t */\n\topen?: boolean\n\n\t/**\n\t * Additional CSS class name for the container.\n\t * Useful for applying custom container styles.\n\t */\n\tclassName?: string\n\n\t/**\n\t * Callback when the close button is clicked.\n\t * Use this to control visibility from the host app.\n\t */\n\tonClose?: () => void\n\n\t/**\n\t * Development mode - use your own API keys for testing.\n\t * In production, leave this undefined to use your WebMCP plan.\n\t */\n\tdevMode?: DevModeConfig\n\n\t/**\n\t * Enable debug tools for inspecting embedded agent internal state.\n\t * Debug tools are prefixed with `debug_` and expose:\n\t * - Agent connection state\n\t * - Tool sources from ThreadManager\n\t * - Local MCP tools\n\t * - Cross-site tool calling diagnostics\n\t *\n\t * @default false\n\t */\n\tenableDebugTools?: boolean\n}\n\n/**\n * EmbeddedAgent - Drop-in AI chat widget\n *\n * A fully self-contained chat widget with:\n * - SSO-first authentication (use your existing IDP token)\n * - MCP tool support (connect to any MCP server)\n * - Voice mode (talk to your AI assistant)\n * - Action-first UI (shows what the AI is doing, not just typing)\n * - Shadow DOM isolation (styles don't leak in or out)\n *\n * Just pass your IDP token and you're done. Everything else is handled.\n */\nconst EmbeddedAgent: FC<EmbeddedAgentProps> = ({\n\tauthToken,\n\topen,\n\tdevMode,\n\tenableDebugTools = false,\n\tclassName,\n\tonClose,\n}) => {\n\t// API base: always production unless useLocalApi is explicitly set\n\tconst apiBase = getDefaultApiBase(devMode?.useLocalApi)\n\n\t// Determine auth mode for logging\n\tconst authMode = authToken ? 'sso-first' : 'stateless'\n\n\t// Log initialization\n\tif (typeof window !== 'undefined') {\n\t\tconsole.debug('[WebMCP] Initialized', {\n\t\t\thasAuthToken: !!authToken,\n\t\t\tauthMode,\n\t\t\tmode: devMode ? 'development' : 'production',\n\t\t\tapiBase,\n\t\t})\n\t}\n\n\t// Voice is enabled if we have an OpenAI key in dev mode, or in production (uses plan)\n\tconst voiceEnabled = !devMode || !!devMode.openaiApiKey\n\n\t// Extract Anthropic API key from devMode for stateless runtime\n\tconst anthropicApiKey = devMode?.anthropicApiKey\n\n\treturn (\n\t\t<ShadowRoot styles={WEBMCP_SHADOW_STYLES}>\n\t\t\t<AgentThread\n\t\t\t\tapiBase={apiBase}\n\t\t\t\tauthToken={authToken}\n\t\t\t\tanthropicApiKey={anthropicApiKey}\n\t\t\t\ttokenEndpoint={voiceEnabled ? `${apiBase}/api/realtime/session` : undefined}\n\t\t\t\tautoConnectLocal={true}\n\t\t\t\topen={open}\n\t\t\t\tenableDebugTools={enableDebugTools}\n\t\t\t\tclassName={className ?? 'wm:h-full wm:w-full'}\n\t\t\t\tonClose={onClose}\n\t\t\t/>\n\t\t</ShadowRoot>\n\t)\n}\n\n/**\n * Web Component wrapper\n *\n * Converts EmbeddedAgent to a <webmcp-agent> custom element.\n * Attributes map to props in kebab-case (auth-token -> authToken).\n */\nconst WebMCPAgentElement = r2wc(EmbeddedAgent as unknown as Parameters<typeof r2wc>[0], {\n\tprops: {\n\t\t// IDP token for SSO-first authentication\n\t\t// <webmcp-agent auth-token=\"eyJhbGciOiJSUzI1NiI...\">\n\t\tauthToken: 'string',\n\t\t// Controlled open state\n\t\t// <webmcp-agent open=\"true\">\n\t\topen: 'boolean',\n\t\t// Note: devMode is JSON-stringified when passed as attribute\n\t\t// <webmcp-agent dev-mode='{\"anthropicApiKey\": \"sk-...\"}'>\n\t\tdevMode: 'json',\n\t\t// Enable debug tools for inspecting internal state\n\t\t// <webmcp-agent enable-debug-tools=\"true\">\n\t\tenableDebugTools: 'boolean',\n\t},\n})\n\n/**\n * Register the <webmcp-agent> custom element\n *\n * Called automatically when importing this module.\n * Styles are injected into the shadow root by ShadowRoot component.\n */\nexport function registerWebMCPAgent(tagName = 'webmcp-agent'): void {\n\tif (typeof window === 'undefined') return\n\n\tif (!customElements.get(tagName)) {\n\t\tcustomElements.define(tagName, WebMCPAgentElement)\n\t}\n}\n\n// Auto-register on import\nregisterWebMCPAgent()\n"],"x_google_ignoreList":[8,9,10,11,12,13,14,15,16],"mappings":"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"}
|