@mcp-b/embedded-agent 1.2.6 → 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.
@@ -1 +1 @@
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","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","useOptionalToolSelection","useOptionalToolApproval","useOptionalVoiceThread","ThreadToolSelection","ToolSourceInfo","ThreadProps","onThreadsClick","onNewThread","onClose","glassmorphicButtonClass","Thread","thread","isEmpty","UserMessage","EditComposer","AssistantMessage","ThreadScrollToBottom","$","_c","t0","Symbol","for","ThreadWelcome","SUGGESTIONS","title","label","prompt","const","ThreadSuggestions","map","_temp","Composer","voiceThread","isVoiceActive","isActive","isVoiceConnecting","isConnecting","t1","t2","t3","t4","t5","t6","t7","t8","t9","getSourceLabel","source","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","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","suggestion","index","animationDelay","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","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","authError","setAuthError","AuthError","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","siteId","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","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","cssVariables","webComponentHost","parentElement","hostStyles","getComputedStyle","variableNames","varsWithImportant","map","name","value","getPropertyValue","trim","filter","Boolean","join","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/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","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 { 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 SUGGESTIONS = [\n {\n title: \"What's the weather\",\n label: \"in San Francisco?\",\n prompt: \"What's the weather in San Francisco?\",\n },\n {\n title: \"Explain React hooks\",\n label: \"like useState and useEffect\",\n prompt: \"Explain React hooks like useState and useEffect\",\n },\n] as const;\n\nconst ThreadSuggestions: FC = () => {\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 {SUGGESTIONS.map((suggestion, index) => (\n <div\n key={suggestion.prompt}\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 prompt={suggestion.prompt} send asChild>\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={suggestion.prompt}\n >\n <span className=\"aui-thread-welcome-suggestion-text-1 wm:font-medium\">\n {suggestion.title}\n </span>\n <span className=\"aui-thread-welcome-suggestion-text-2 wm:text-muted-foreground\">\n {suggestion.label}\n </span>\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\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.\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\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.\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.\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 * When undefined: runs in stateless mode (no persistence, no cross-app tools)\n\t * When provided: runs in stateful mode (full SSO-first with persistence)\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\tsiteId: 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\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\tlet cssVariables = ''\n\t\tconst webComponentHost = host.parentElement // This should be <webmcp-agent>\n\t\tif (webComponentHost) {\n\t\t\tconst hostStyles = getComputedStyle(webComponentHost)\n\t\t\tconst variableNames = [\n\t\t\t\t'--wm-color-primary',\n\t\t\t\t'--wm-color-primary-foreground',\n\t\t\t\t'--wm-color-secondary',\n\t\t\t\t'--wm-color-secondary-foreground',\n\t\t\t\t'--wm-color-accent',\n\t\t\t\t'--wm-color-accent-foreground',\n\t\t\t\t'--wm-color-background',\n\t\t\t\t'--wm-color-foreground',\n\t\t\t\t'--wm-color-muted',\n\t\t\t\t'--wm-color-muted-foreground',\n\t\t\t\t'--wm-color-border',\n\t\t\t\t'--wm-color-input',\n\t\t\t\t'--wm-color-ring',\n\t\t\t\t'--wm-radius',\n\t\t\t\t'--wm-font-sans',\n\t\t\t\t'--wm-user-bubble-bg',\n\t\t\t\t'--wm-user-bubble-text',\n\t\t\t\t'--wm-assistant-bubble-bg',\n\t\t\t\t'--wm-assistant-bubble-text',\n\t\t\t\t'--wm-composer-bg',\n\t\t\t\t'--wm-composer-border',\n\t\t\t\t'--wm-composer-button-bg',\n\t\t\t\t'--wm-composer-button-text',\n\t\t\t\t'--wm-composer-text',\n\t\t\t\t'--wm-tool-bg',\n\t\t\t\t'--wm-tool-border',\n\t\t\t\t'--wm-tool-approve-bg',\n\t\t\t\t'--wm-tool-deny-bg',\n\t\t\t\t'--wm-code-bg',\n\t\t\t\t'--wm-code-text',\n\t\t\t\t'--wm-input-bg',\n\t\t\t\t'--wm-input-border',\n\t\t\t\t'--wm-input-text',\n\t\t\t\t'--wm-font-size-xs',\n\t\t\t\t'--wm-font-size-sm',\n\t\t\t\t'--wm-font-size-base',\n\t\t\t\t'--wm-font-size-lg',\n\t\t\t]\n\n\t\t\t// Extract CSS variables with !important to override built-in defaults\n\t\t\tconst varsWithImportant = variableNames\n\t\t\t\t.map(name => {\n\t\t\t\t\tconst value = hostStyles.getPropertyValue(name).trim()\n\t\t\t\t\treturn value ? `${name}: ${value} !important;` : ''\n\t\t\t\t})\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join('\\n\\t\\t\\t\\t')\n\n\t\t\tif (varsWithImportant) {\n\t\t\t\tcssVariables = `\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\t\t\t}\n\t\t}\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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"}
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,SAAgBG,GAAG,GAAGC,QAA8B;AACnD,QAAOH,QAAQD,KAAKI,OAAO,CAAC;;;;;ACH7B,SAAAM,gBAAAC,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAyB,GAAA,CAAAI,eAAAD,OAAAD,SAAAF;AAGgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAD,UAAAD,EAAA;AAAAE,OAAAF,EAAA;;CAFvD,MAAAG,gBAAAD,OAAAE,SAAA,IAAAF;CAAiB,IAAAG;AAAA,KAAAL,EAAA,OAAAG,iBAAAH,EAAA,OAAAC,OAAA;AAIfI,OAAA,oBAAA,iBAAA;GACY,aAAA;GACKF;GAAa,GACxBF;IACJ;AAAAD,IAAA,KAAAG;AAAAH,IAAA,KAAAC;AAAAD,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAJFK;;AAQJ,SAAAC,QAAAP,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAiB,GAAA,IAAAE,SAAAF;AAEoCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAEjDC,OAAA,oBAAC,6BACC,oBAAA,iBAAA;GAAiC,aAAA;GAAS,GAAKD;IACjD,GAAkB;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAFlBE;;AAMJ,SAAAK,eAAAR,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAwB,GAAA,IAAAE,SAAAF;AAEgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAC/CC,OAAA,oBAAA,iBAAA;GAAoC,aAAA;GAAiB,GAAKD;IAAS;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAnEE;;AAGT,SAAAM,eAAAT,IAAA;CAAA,MAAAC,IAAAN,EAAA,GAAA;CAAA,IAAAe;CAAA,IAAAC;CAAA,IAAAT;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAwB,GAAA,CAAAW,WAAAC,YAAAT,IAAAO,aAAAR,SAAAF;AAKgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAS;AAAAT,IAAA,KAAAU;AAAAV,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAO,aAAAT,EAAA;AAAAU,cAAAV,EAAA;AAAAC,UAAAD,EAAA;AAAAE,OAAAF,EAAA;;CAHtD,MAAAW,aAAAT,OAAAE,SAAA,IAAAF;CAAc,IAAAG;AAAA,KAAAL,EAAA,OAAAU,WAAA;AASGL,OAAAR,GACT,qaACAa,UACD;AAAAV,IAAA,KAAAU;AAAAV,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAa,OAAAC,IAAA,4BAAA,EAAA;AAIDF,OAAA,oBAAA,iBAAA,SAAkC,WAAA,uGAAuG;AAAAZ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAe;AAAA,KAAAf,EAAA,OAAAS,YAAAT,EAAA,OAAAC,SAAAD,EAAA,QAAAW,cAAAX,EAAA,QAAAK,IAAA;AAX7IU,OAAA,oBAAA,iBAAA,oBACE,qBAAA,iBAAA;GACY,aAAA;GACEJ;GACD,WAAAN;GAGV,GACGJ;cAEHQ,UACDG;IAEJ,GAA0B;AAAAZ,IAAA,KAAAS;AAAAT,IAAA,KAAAC;AAAAD,IAAA,MAAAW;AAAAX,IAAA,MAAAK;AAAAL,IAAA,MAAAe;OAAAA,MAAAf,EAAA;AAAA,QAb1Be;;;;;ACnCJ,SAAAO,OAAAC,IAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CAAA,IAAAQ;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAgB,GAAA,IAAAE,SAAAF;AAEoCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAC3CC,OAAA,oBAAA,gBAAA;GAAgC,aAAA;GAAQ,GAAKD;IAAS;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAtDE;;AAGT,SAAAC,cAAAJ,IAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CAAA,IAAAQ;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAuB,GAAA,IAAAE,SAAAF;AAEgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAC9CC,OAAA,oBAAA,gBAAA;GAAmC,aAAA;GAAgB,GAAKD;IAAS;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAjEE;;AAGT,SAAAE,aAAAL,IAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CAAA,IAAAQ;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAsB,GAAA,IAAAE,SAAAF;AAEgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAC7CC,OAAA,oBAAA,gBAAA;GAAkC,aAAA;GAAe,GAAKD;IAAS;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAA/DE;;AAST,SAAAI,cAAAP,IAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CAAA,IAAAc;CAAA,IAAAN;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAuB,GAAA,CAAAQ,cAAAN,SAAAF;AAGgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAO;AAAAP,IAAA,KAAAC;QAAA;AAAAM,cAAAP,EAAA;AAAAC,UAAAD,EAAA;;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAO,WAAA;AAItCL,OAAAL,GACT,0JACAU,UACD;AAAAP,IAAA,KAAAO;AAAAP,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAQ;AAAA,KAAAR,EAAA,OAAAC,SAAAD,EAAA,OAAAE,IAAA;AALHM,OAAA,oBAAA,gBAAA;GACY,aAAA;GACC,WAAAN;GAGV,GACGD;IACJ;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;AAAAF,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;AAAA,QAPFQ;;AAWJ,SAAAC,cAAAV,IAAA;CAAA,MAAAC,IAAAP,EAAA,GAAA;CAAA,IAAAiB;CAAA,IAAAH;CAAA,IAAAN;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAuB,GAAA,CAAAQ,WAAAG,UAAAC,iBAAAT,OAAAD,SAAAF;AAOtBC,IAAA,KAAAD;AAAAC,IAAA,KAAAU;AAAAV,IAAA,KAAAO;AAAAP,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAQ,aAAAV,EAAA;AAAAO,cAAAP,EAAA;AAAAC,UAAAD,EAAA;AAAAE,OAAAF,EAAA;;CAJC,MAAAW,kBAAAT,OAAAU,SAAA,OAAAV;CAAsB,IAAAM;AAAA,KAAAR,EAAA,OAAAa,OAAAC,IAAA,4BAAA,EAAA;AAOlBN,OAAA,oBAAC,kBAAgB;AAAAR,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CAAA,IAAAe;AAAA,KAAAf,EAAA,OAAAO,WAAA;AAGJQ,OAAAlB,GACT,4XACAU,UACD;AAAAP,IAAA,KAAAO;AAAAP,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,OAAAW,iBAAA;AAIAK,OAAAL,mBACC,qBAAA,gBAAA;GACY,aAAA;GACA,WAAA;cAEV,oBAAC,UACD,sBAAA;IAAgB,WAAA;cAAa;KAC/B;IACD;AAAAX,IAAA,KAAAW;AAAAX,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,QAAAU,YAAAV,EAAA,QAAAC,SAAAD,EAAA,QAAAe,MAAAf,EAAA,QAAAgB,IAAA;AAnBLC,OAAA,qBAAC;GAAuB,aAAA;cACtBT,IACA,qBAAA,gBAAA;IACY,aAAA;IACC,WAAAO;IAGV,GACGd;eAEHS,UACAM;KAUL;IAAe;AAAAhB,IAAA,MAAAU;AAAAV,IAAA,MAAAC;AAAAD,IAAA,MAAAe;AAAAf,IAAA,MAAAgB;AAAAhB,IAAA,MAAAiB;OAAAA,MAAAjB,EAAA;AAAA,QArBfiB;;AAgDJ,SAAAG,YAAArB,IAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CAAA,IAAAc;CAAA,IAAAN;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAqB,GAAA,CAAAQ,cAAAN,SAAAF;AAGgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAO;AAAAP,IAAA,KAAAC;QAAA;AAAAM,cAAAP,EAAA;AAAAC,UAAAD,EAAA;;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAO,WAAA;AAIpCL,OAAAL,GAAG,sCAAsCU,UAAU;AAAAP,IAAA,KAAAO;AAAAP,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAQ;AAAA,KAAAR,EAAA,OAAAC,SAAAD,EAAA,OAAAE,IAAA;AAFhEM,OAAA,oBAAA,gBAAA;GACY,aAAA;GACC,WAAAN;GAAmD,GAC1DD;IACJ;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;AAAAF,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;AAAA,QAJFQ;;;;;ACvGJ,SAAAmB,OAAAC,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAgB,GAAA,CAAAE,cAAAC,SAAAH;AAGoCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAD,cAAAD,EAAA;AAAAE,UAAAF,EAAA;;CAAA,IAAAG;AAAA,KAAAH,EAAA,OAAAC,WAAA;AAInCE,OAAAN,GACT,8DACAI,UACD;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAE,SAAAF,EAAA,OAAAG,IAAA;AALHC,OAAA,oBAAA,gBAAA;GACY,aAAA;GACC,WAAAD;GAGV,GACGD;IACJ;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAPFI;;AAWJ,SAAAC,YAAAN,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAqB,GAAA,CAAAE,cAAAC,SAAAH;AAGgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAD,cAAAD,EAAA;AAAAE,UAAAF,EAAA;;CAAA,IAAAG;AAAA,KAAAH,EAAA,OAAAC,WAAA;AAIpCE,OAAAN,GAAG,2BAA2BI,UAAU;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAE,SAAAF,EAAA,OAAAG,IAAA;AAFrDC,OAAA,oBAAA,gBAAA;GACY,aAAA;GACC,WAAAD;GAAwC,GAC/CD;IACJ;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAJFI;;AAQJ,SAAAE,eAAAP,IAAA;CAAA,MAAAC,IAAAN,EAAA,EAAA;CAAA,IAAAO;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAAwB,GAAA,CAAAE,cAAAC,SAAAH;AAGgCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;AAAAD,IAAA,KAAAE;QAAA;AAAAD,cAAAD,EAAA;AAAAE,UAAAF,EAAA;;CAAA,IAAAG;AAAA,KAAAH,EAAA,OAAAC,WAAA;AAIvCE,OAAAN,GACT,oEACAI,UACD;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAE,SAAAF,EAAA,OAAAG,IAAA;AALHC,OAAA,oBAAA,gBAAA;GACY,aAAA;GACC,WAAAD;GAGV,GACGD;IACJ;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAPFI;;;;;ACnCJ,MAAMQ,iBAAiBH,IACrB,igBACA;CACEI,UAAU;EACRC,SAAS;GACPC,SAAS;GACTC,aACE;GACFC,SACE;GACFC,WACE;GACFC,OACE;GACFC,MAAM;GACP;EACDC,MAAM;GACJN,SAAS;GACTO,IAAI;GACJC,IAAI;GACJC,MAAM;GACN,WAAW;GACX,WAAW;GACb;EACD;CACDC,iBAAiB;EACfX,SAAS;EACTO,MAAM;EACR;CAEJ,CAAC;AAED,SAAAK,OAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAN,EAAA,OAAAD,IAAA;AAAgB,GAAA,CAAAG,WAAAhB,SAAAkB,IAAAX,MAAAY,IAAAE,SAAAD,OAAAH,SAAAJ;AASbC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;AAAAL,IAAA,KAAAM;QAAA;AAAAJ,cAAAF,EAAA;AAAAG,UAAAH,EAAA;AAAAI,OAAAJ,EAAA;AAAAK,OAAAL,EAAA;AAAAM,OAAAN,EAAA;;CAPD,MAAAd,UAAAkB,OAAAI,SAAA,YAAAJ;CACA,MAAAX,OAAAY,OAAAG,SAAA,YAAAH;CAOA,MAAAI,QANAH,OAAAE,SAAA,QAAAF,MAMa1B,OAAA;CAA0B,IAAA8B;AAAA,KAAAV,EAAA,OAAAE,aAAAF,EAAA,OAAAP,QAAAO,EAAA,OAAAd,SAAA;AAOxBwB,OAAA3B,GAAGC,eAAe;GAAAE;GAAAO;GAAAS;GAA4B,CAAC,CAAC;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAP;AAAAO,IAAA,KAAAd;AAAAc,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAW;AAAA,KAAAX,EAAA,QAAAS,QAAAT,EAAA,QAAAG,SAAAH,EAAA,QAAAP,QAAAO,EAAA,QAAAU,MAAAV,EAAA,QAAAd,SAAA;AAJ7DyB,OAAA,oBAAC;GACW,aAAA;GACIzB,gBAAAA;GACHO,aAAAA;GACA,WAAAiB;GAAgD,GACvDP;IACJ;AAAAH,IAAA,MAAAS;AAAAT,IAAA,MAAAG;AAAAH,IAAA,MAAAP;AAAAO,IAAA,MAAAU;AAAAV,IAAA,MAAAd;AAAAc,IAAA,MAAAW;OAAAA,MAAAX,EAAA;AAAA,QANFW;;;;;AChCJ,MAAac,oBAAoBX,YAG/Ba,IAAAC,QAAA;CAAA,MAAAC,IAAAhB,EAAA,GAAA;CAAA,IAAAiB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAV;AAAA,KAAAM,EAAA,OAAAF,IAAA;AAAC,GAAA,CAAAG,UAAAP,SAAAC,MAAAS,IAAAF,cAAAC,QAAAL;AAA0DE,IAAA,KAAAF;AAAAE,IAAA,KAAAC;AAAAD,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAN;QAAA;AAAAO,aAAAD,EAAA;AAAAE,cAAAF,EAAA;AAAAG,SAAAH,EAAA;AAAAI,OAAAJ,EAAA;AAAAN,YAAAM,EAAA;;CAArC,MAAAL,OAAAS,OAAAC,SAAA,WAAAD;CAAe,IAAAE;AAAA,KAAAN,EAAA,OAAAE,WAAA;AAQlBI,OAAAd,GAAG,oCAAoCU,UAAU;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAO;AAAA,KAAAP,EAAA,OAAAC,UAAA;AAG5DM,OAAA,oBAAC,aAAWN,WAAqB;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAAA,IAAAQ;AAAA,KAAAR,EAAA,QAAAN,SAAA;AACjCc,OAAA,oBAAA;GAAgB,WAAA;aAA0Bd;IAAe;AAAAM,IAAA,MAAAN;AAAAM,IAAA,MAAAQ;OAAAA,MAAAR,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,QAAAD,OAAAC,EAAA,QAAAG,QAAAH,EAAA,QAAAM,MAAAN,EAAA,QAAAO,MAAAP,EAAA,QAAAQ,IAAA;AAT7DC,OAAA,oBAAC;GAAe,SAAA;aACd,qBAAC;IACS,SAAA;IACH,MAAA;IAAM,GACPN;IACO,WAAAG;IACNP;eAELQ,IACAC;KAEJ;IAAiB;AAAAR,IAAA,MAAAD;AAAAC,IAAA,MAAAG;AAAAH,IAAA,MAAAM;AAAAN,IAAA,MAAAO;AAAAP,IAAA,MAAAQ;AAAAR,IAAA,MAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,QAAAL,QAAAK,EAAA,QAAAN,SAAA;AACjBgB,OAAA,oBAAC;GAAqBf;aAAOD;IAAyB;AAAAM,IAAA,MAAAL;AAAAK,IAAA,MAAAN;AAAAM,IAAA,MAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAW;AAAA,KAAAX,EAAA,QAAAS,MAAAT,EAAA,QAAAU,IAAA;AAbxDC,OAAA,qBAAC,sBACCF,IAYAC,MACQ;AAAAV,IAAA,MAAAS;AAAAT,IAAA,MAAAU;AAAAV,IAAA,MAAAW;OAAAA,MAAAX,EAAA;AAAA,QAdVW;EAgBF;AAEFf,kBAAkBgB,cAAc;;;;ACdhC,MAAM4B,cAAaC,SAAA;CAAA,MAAAC,IAAA5B,EAAA,EAAA;CACjB,MAAA,CAAA6B,KAAAC,UAAsB5B,SAA6B6B,OAAU;CAAC,IAAAC;CAAA,IAAAC;AAAA,KAAAL,EAAA,OAAAD,MAAA;AAEpDK,aAAA;AACR,OAAI,CAACL,MAAI;AACPG,WAAOC,OAAU;AAAA;;GAInB,MAAAG,YAAkBC,IAAGC,gBAAiBT,KAAK;AAC3CG,UAAOI,UAAU;AAAA,gBAEV;AACLC,QAAGE,gBAAiBH,UAAU;;;AAE/BD,OAAA,CAACN,KAAK;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;QAAA;AAAAD,OAAAJ,EAAA;AAAAK,OAAAL,EAAA;;AAZT3B,WAAU+B,IAYPC,GAAO;AAAA,QAEHJ;;AAGT,MAAMS,yBAAmB;CACvB,MAAA,EAAAX,MAAAE,KAAAU,UAAsB5B,kBACpBE,WAAW2B,SAQb,CAAC;AAAC,QAEKd,WAAWC,KAAY,IAAvBY;;AAOT,MAAMG,qBAAgDV,OAAA;CAAA,MAAAJ,IAAA5B,EAAA,EAAA;CAAC,MAAA,EAAA6B,QAAAG;CACrD,MAAA,CAAAW,UAAAC,eAAgC1C,SAAS,MAAM;CAMzC,MAAA+B,KAAAU,WAAA,mGAAA;CAEiD,IAAAE;AAAA,KAAAjB,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAE3CF,aAAMD,YAAY,KAAK;AAAAhB,IAAA,KAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAC,OAAAD,EAAA,OAAAK,IAAA;AARjCe,OAAA,oBAAA;GACOnB;GACD,KAAA;GAEF,WAAAI;GAIM,QAAAY;IACR;AAAAjB,IAAA,KAAAC;AAAAD,IAAA,KAAAK;AAAAL,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;AAAA,QATFoB;;AAaJ,MAAMC,2BAAiDjB,OAAA;CAAA,MAAAJ,IAAA5B,EAAA,EAAA;CAAC,MAAA,EAAAkD,aAAAlB;CACtD,MAAAH,MAAYS,kBAAkB;AAE9B,KAAI,CAACT,IAAG,QAASqB;CAAS,IAAAjB;AAAA,KAAAL,EAAA,OAAAsB,UAAA;AAItBjB,OAAA,oBAAC;GACW,WAAA;GACV,SAAA;GAECiB;IACa;AAAAtB,IAAA,KAAAsB;AAAAtB,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAEdF,OAAA,oBAAC;GAAsB,WAAA;aAAyB;IAElC;AAAAjB,IAAA,KAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAC,KAAA;AAHhBmB,OAAA,qBAAC;GAAwB,WAAA;cACvBH,IAGA,oBAAA;IAAe,WAAA;cACb,oBAAC,qBAAuBhB,MAC1B;KACF;IAAgB;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAuB;AAAA,KAAAvB,EAAA,OAAAK,MAAAL,EAAA,OAAAoB,IAAA;AAdlBG,OAAA,qBAAC,qBACClB,IAMAe,MAQO;AAAApB,IAAA,KAAAK;AAAAL,IAAA,KAAAoB;AAAApB,IAAA,KAAAuB;OAAAA,MAAAvB,EAAA;AAAA,QAfTuB;;AAmBJ,MAAMC,wBAAsB;CAAA,MAAAxB,IAAA5B,EAAA,EAAA;CAC1B,MAAAqD,UAAgB1C,kBACd2C,SACD;CACD,MAAAzB,MAAYS,kBAAkB;CAAC,IAAAN;AAAA,KAAAJ,EAAA,OAAAC,KAAA;AAI3BG,OAAA,oBAAC;GACMH;GACD,KAAA;GACM,WAAA;IACV;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CACuB,MAAAK,KAAAoB,UAAA,MAAA;CAAiB,IAAAR;AAAA,KAAAjB,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AACxCF,OAAA,oBAAC,YAAmB,WAAA,yEAAyE;AAAAjB,IAAA,KAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAK,IAAA;AAD/Fe,OAAA,oBAAC;GAAwB,SAAAf;aACvBY;IACe;AAAAjB,IAAA,KAAAK;AAAAL,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAuB;AAAA,KAAAvB,EAAA,OAAAI,MAAAJ,EAAA,OAAAoB,IAAA;AARnBG,OAAA,qBAAC;GAAiB,WAAA;cAChBnB,IAKAgB;IAGO;AAAApB,IAAA,KAAAI;AAAAJ,IAAA,KAAAoB;AAAApB,IAAA,KAAAuB;OAAAA,MAAAvB,EAAA;AAAA,QATTuB;;AAaJ,MAAMI,qBAAmB;CAAA,MAAA3B,IAAA5B,EAAA,GAAA;CAEvB,MAAAyD,aADY7C,iBAAiB,CACP8C,WAAWC,WAAY;CAE7C,MAAAN,UAAgB1C,kBACdiD,SACD;CACD,MAAAC,YAAkBlD,kBAAkBmD,SAalC;CAOM,MAAA9B,KAAAqB,WAAA;CACkE,IAAApB;AAAA,KAAAL,EAAA,OAAAI,IAAA;AAHzDC,OAAAR,GACT,gCACAO,GAED;AAAAJ,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAOO,MAAAiB,KAAAY,cAAA;CACqD,IAAAT;AAAA,KAAApB,EAAA,OAAAiB,IAAA;AAH5CG,OAAAvB,GACT,iIACAoB,GAED;AAAAjB,IAAA,KAAAiB;AAAAjB,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAGW,MAAAuB,KAAA,GAAGU,UAAS;CAAa,IAAAE;AAAA,KAAAnC,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAErCgB,OAAA,oBAAC,oBAAkB;AAAAnC,IAAA,KAAAmC;OAAAA,MAAAnC,EAAA;CAAA,IAAAoC;AAAA,KAAApC,EAAA,OAAAoB,MAAApB,EAAA,OAAAuB,IAAA;AAZzBa,OAAA,oBAAC,qCACC,oBAAC;GAAe,SAAA;aACd,oBAAA;IACa,WAAAhB;IAKN,MAAA;IACF,IAAA;IACS,cAAAG;cAEZY;KAEJ;IACF,GAA0B;AAAAnC,IAAA,KAAAoB;AAAApB,IAAA,KAAAuB;AAAAvB,IAAA,KAAAoC;OAAAA,MAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,OAAA6B,YAAA;AACzBQ,OAAAR,cAAc,oBAAC,qBAAmB;AAAA7B,IAAA,KAAA6B;AAAA7B,IAAA,KAAAqC;OAAAA,MAAArC,EAAA;CAAA,IAAAsC;AAAA,KAAAtC,EAAA,QAAAK,MAAAL,EAAA,QAAAoC,MAAApC,EAAA,QAAAqC,IAAA;AAvBrCC,OAAA,qBAAA,oBAAA;GACa,WAAAjC;cAMX+B,IAgBCC;IACwB;AAAArC,IAAA,MAAAK;AAAAL,IAAA,MAAAoC;AAAApC,IAAA,MAAAqC;AAAArC,IAAA,MAAAsC;OAAAA,MAAAtC,EAAA;CAAA,IAAAuC;AAAA,KAAAvC,EAAA,QAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAC3BoB,OAAA,oBAAC;GAAoB,MAAA;aACnB,oBAAA,oBAAA,SACF;IAAiB;AAAAvC,IAAA,MAAAuC;OAAAA,MAAAvC,EAAA;CAAA,IAAAwC;AAAA,KAAAxC,EAAA,QAAAsC,IAAA;AA5BnBE,QAAA,qBAAC,sBACCF,IAyBAC,MAGQ;AAAAvC,IAAA,MAAAsC;AAAAtC,IAAA,MAAAwC;OAAAA,OAAAxC,EAAA;AAAA,QA7BVwC;;AAiCJ,MAAMC,yBAAuB;CAAA,MAAAzC,IAAA5B,EAAA,EAAA;CAAA,IAAAgC;AAAA,KAAAJ,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAEzBf,OAAA,oBAAA,oBAAA;GAA4B,SAAA;aAC1B,oBAAC;IACS,SAAA;IACE,WAAA;IACL,MAAA;cAEL,oBAAC,SAAgB,WAAA,gEACnB;KACF;IAA6B;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAR7BI;;AAYJ,MAAasC,+BAA6B;CAAA,MAAA1C,IAAA5B,EAAA,EAAA;CAAA,IAAAgC;AAAA,KAAAJ,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAEtCf,OAAA,oBAAA;GAAe,WAAA;aACb,oBAAA,iBAAA,eAA0C,YAAA,EAAAuC,YAAchB,cAAa,GACvE;IAAM;AAAA3B,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAFNI;;AAMJ,MAAawC,4BAA0B;CAAA,MAAA5C,IAAA5B,EAAA,EAAA;CAAA,IAAAgC;AAAA,KAAAJ,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAEnCf,OAAA,oBAAA;GAAe,WAAA;aACb,oBAAA,kBAAA,eACc,YAAA,EAAAuC,YAAchB,cAAa,GAE3C;IAAM;AAAA3B,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAJNI;;AAQJ,MAAayC,8BAA4B;CAAA,MAAA7C,IAAA5B,EAAA,EAAA;CAAA,IAAAgC;AAAA,KAAAJ,EAAA,OAAAkB,OAAAC,IAAA,4BAAA,EAAA;AAErCf,OAAA,oBAAA,kBAAA;GAAiC,SAAA;aAC/B,oBAAC;IACS,SAAA;IACH,MAAA;IACG,SAAA;IACH,MAAA;IACK,WAAA;IACC,cAAA;cAEX,oBAAC,YAAmB,WAAA,wDACtB;KACF;IAAkC;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAXlCI;;AA1KqB,SAAA0C,SAAA3E,KAAA;AAAA,QAK2BA,IAAC4E,SAAU;;AALtC,SAAAnC,SAAAR,IAAA;CAET,MAAA,EAAA0B,eAAA1B;AACV,KAAI0B,WAAUiB,SAAU,QAAO,QAAS,EAAE;AAC1C,KAAIjB,WAAU/B,KAAK,QAAS,EAAAA,MAAQ+B,WAAU/B,MAAO;CACrD,MAAAE,MAAY6B,WAAUkB,SAAgBC,OAACH,SAA6B,CAAA,IAC3DI;AACT,KAAI,CAACjD,IAAG,QAAS,EAAE;AAAC,QACb,EAAAA,KAAO;;AAoDQ,SAAAyB,SAAAtB,IAAA;CAEvB,MAAA,EAAA0B,eAAA1B;AAAc,QAAK0B,WAAUiB,SAAU;;AAkBnB,SAAAf,SAAA5B,IAAA;CAKpB,MAAA,EAAA0B,eAAA1B;AAAc,QAAK0B,WAAUiB,SAAU;;AALnB,SAAAb,SAAA9B,IAAA;CAOc,MAAA,EAAA0B,YAAAqB,iBAAA/C;CACnC,MAAA2C,OAAajB,aAAUiB;AACvB,SAAQA,MAAR;EAAY,KACL,QAAO,QACH;EAAO,KACX,WAAU,QACN;EAAU,KACd,OAAM,QACF;EAAM,SAAA;GAEb,MAAAK,mBAAgCL;AAChC,SAAM,IAAIM,MAAM,4BAA4BD,mBAAmB;;;;;;;ACjIvE,MAAMiB,yBAAmB;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAgB;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAErBF,OAAA,oBAAC;GACgB,eAAA,CAACV,UAAS;GACf,WAAA;GACEa,YAAAA;IACZ;AAAAJ,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QAJFC;;AAQJ,MAAaI,eAAeZ,KAAKM,iBAAiB;AAElD,MAAMO,cAAkCL,OAAA;CAAA,MAAAD,IAAAf,EAAA,GAAA;CAAC,MAAA,EAAAsB,UAAAC,SAAAP;CACvC,MAAA,EAAAQ,UAAAC,oBAAsCC,oBAAoB;CAAC,IAAAC;AAAA,KAAAZ,EAAA,OAAAQ,QAAAR,EAAA,OAAAU,mBAAAV,EAAA,OAAAS,UAAA;AAC5CG,aAAA;AACb,OAAI,CAACJ,QAADC,SAAiB;AACrBC,mBAAgBF,KAAK;;AACtBR,IAAA,KAAAQ;AAAAR,IAAA,KAAAU;AAAAV,IAAA,KAAAS;AAAAT,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAHD,MAAAa,SAAeD;CAGb,IAAAE;AAAA,KAAAd,EAAA,OAAAO,UAAA;AAIEO,OAAA,oBAAA;GAAgB,WAAA;aACbP;IACI;AAAAP,IAAA,KAAAO;AAAAP,IAAA,KAAAc;OAAAA,MAAAd,EAAA;CAAA,IAAAe;AAAA,KAAAf,EAAA,OAAAS,UAAA;AAEJM,OAAA,CAACN,YAAY,oBAAC,YAAmB,WAAA,cAAc;AAAAT,IAAA,KAAAS;AAAAT,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAAA,IAAAgB;AAAA,KAAAhB,EAAA,OAAAS,UAAA;AAC/CO,OAAAP,YAAY,oBAAC,aAAoB,WAAA,cAAc;AAAAT,IAAA,KAAAS;AAAAT,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,QAAAa,UAAAb,EAAA,QAAAe,MAAAf,EAAA,QAAAgB,IAAA;AAFlDC,OAAA,qBAAC;GAA0B,SAAA;GAAgBJ,SAAAA;cACxCE,IACAC;IACiB;AAAAhB,IAAA,MAAAa;AAAAb,IAAA,MAAAe;AAAAf,IAAA,MAAAgB;AAAAhB,IAAA,MAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,QAAAc,MAAAd,EAAA,QAAAiB,IAAA;AAPtBC,OAAA,qBAAA;GAAe,WAAA;cACbJ,IAGAG;IAII;AAAAjB,IAAA,MAAAc;AAAAd,IAAA,MAAAiB;AAAAjB,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;AAAA,QARNkB;;AAYJ,MAAMP,sBAAqBV,OAAA;CAAA,MAAAD,IAAAf,EAAA,EAAA;CAAA,IAAA2B;AAAA,KAAAZ,EAAA,OAAAC,IAAA;AAACW,OAAAX,OAAAkB,SAAA,EAItB,GAJsBlB;AAItBD,IAAA,KAAAC;AAAAD,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAJsB,MAAA,EAAAoB,gBAAAN,OAAAF;CAC1B,MAAAQ,iBAAAN,OAAAK,SAAA,MAAAL;CAIA,MAAA,CAAAL,UAAAY,eAAgC3B,SAAkB,MAAM;CAAC,IAAAqB;AAAA,KAAAf,EAAA,OAAAoB,gBAAA;AAEjCL,QAAAO,UAAA;AACtB,OAAI,CAACA,MAAK;AAEVC,aAASC,UAAUC,UAAWH,MAAM,CAAAI,WAAM;AACxCL,gBAAY,KAAK;AACjBM,qBAAiBN,YAAY,MAAM,EAAED,eAAe;KACpD;;AACHpB,IAAA,KAAAoB;AAAApB,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAPD,MAAAU,kBAAwBK;CAOtB,IAAAC;AAAA,KAAAhB,EAAA,OAAAU,mBAAAV,EAAA,OAAAS,UAAA;AAEKO,OAAA;GAAAP;GAAAC;GAA6B;AAAAV,IAAA,KAAAU;AAAAV,IAAA,KAAAS;AAAAT,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;AAAA,QAA7BgB;;AAGT,MAAMZ,oBAAoBf,mCAA0B;CAClDuC,KAAK,EAAEC,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,iGACA+B,UACD;EACD,GAAIC;GAEP;CACDC,KAAK,EAAEF,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,qHACA+B,UACD;EACD,GAAIC;GAEP;CACDE,KAAK,EAAEH,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,qHACA+B,UACD;EACD,GAAIC;GAEP;CACDG,KAAK,EAAEJ,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,uHACA+B,UACD;EACD,GAAIC;GAEP;CACDI,KAAK,EAAEL,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,4EACA+B,UACD;EACD,GAAIC;GAEP;CACDK,KAAK,EAAEN,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,iEACA+B,UACD;EACD,GAAIC;GAEP;CACDM,IAAI,EAAEP,WAAW,GAAGC,YAClB,oBAAC;EACC,WAAWhC,GACT,oEACA+B,UACD;EACD,GAAIC;GAEP;CACDO,IAAI,EAAER,WAAW,GAAGC,YAClB,oBAAC;EACC,WAAWhC,GACT,8EACA+B,UACD;EACD,GAAIC;GAEP;CACDQ,aAAa,EAAET,WAAW,GAAGC,YAC3B,oBAAC;EACC,WAAWhC,GAAG,qDAAqD+B,UAAU;EAC7E,GAAIC;GAEP;CACDS,KAAK,EAAEV,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GAAG,yDAAyD+B,UAAU;EACjF,GAAIC;GAEP;CACDU,KAAK,EAAEX,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GAAG,4DAA4D+B,UAAU;EACpF,GAAIC;GAEP;CACDW,KAAK,EAAEZ,WAAW,GAAGC,YACnB,oBAAC;EAAG,WAAWhC,GAAG,iCAAiC+B,UAAU;EAAE,GAAIC;GACpE;CACDY,QAAQ,EAAEb,WAAW,GAAGC,YACtB,oBAAC;EACC,WAAWhC,GACT,4FACA+B,UACD;EACD,GAAIC;GAEP;CACDa,KAAK,EAAEd,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,8KACA+B,UACD;EACD,GAAIC;GAEP;CACDc,KAAK,EAAEf,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,iJACA+B,UACD;EACD,GAAIC;GAEP;CACDe,KAAK,EAAEhB,WAAW,GAAGC,YACnB,oBAAC;EACC,WAAWhC,GACT,sJACA+B,UACD;EACD,GAAIC;GAEP;CACDgB,MAAM,EAAEjB,WAAW,GAAGC,YACpB,oBAAC;EACC,WAAWhC,GAAG,qDAAqD+B,UAAU;EAC7E,GAAIC;GAEP;CACDiB,MAAM,EAAElB,WAAW,GAAGC,YACpB,oBAAC;EACC,WAAWhC,GACT,2GACA+B,UACD;EACD,GAAIC;GAEP;CACDtB,MAAM,SAASwC,KAAK,EAAEnB,WAAW,GAAGC,SAAS;AAE3C,SACE,oBAAC;GACC,WAAWhC,GACT,CAJcR,wBAAwB,IAKpC,wEACFuC,UACD;GACD,GAAIC;IACJ;;CAGNxB;CACD,CAAC;;;;AClOF,IAAI,YAAY,CAAC,EAAE,OAAO,WAAW,eAAe,OAAO,YAAY,OAAO,SAAS;AACvF,SAAS,qBAAqB,sBAAsB,iBAAiB,EAAE,2BAA2B,SAAS,EAAE,EAAE;AAC7G,QAAO,SAAS,YAAY,OAAO;AACjC,yBAAuB,MAAM;AAC7B,MAAI,6BAA6B,SAAS,CAAC,MAAM,iBAC/C,QAAO,kBAAkB,MAAM;;;;;;ACarC,SAAS,mBAAmB,WAAW,yBAAyB,EAAE,EAAE;CAClE,IAAI,kBAAkB,EAAE;CACxB,SAAS,eAAe,mBAAmB,gBAAgB;EACzD,MAAM,cAAc,MAAM,cAAc,eAAe;EACvD,MAAM,QAAQ,gBAAgB;AAC9B,oBAAkB,CAAC,GAAG,iBAAiB,eAAe;EACtD,MAAM,YAAY,UAAU;GAC1B,MAAM,EAAE,OAAO,UAAU,GAAG,YAAY;GACxC,MAAM,UAAU,QAAQ,aAAa,UAAU;GAC/C,MAAM,QAAQ,MAAM,cAAc,SAAS,OAAO,OAAO,QAAQ,CAAC;AAClE,UAAuB,oBAAI,QAAQ,UAAU;IAAE;IAAO;IAAU,CAAC;;AAEnE,WAAS,cAAc,oBAAoB;EAC3C,SAAS,YAAY,cAAc,OAAO;GACxC,MAAM,UAAU,QAAQ,aAAa,UAAU;GAC/C,MAAM,UAAU,MAAM,WAAW,QAAQ;AACzC,OAAI,QAAS,QAAO;AACpB,OAAI,mBAAmB,KAAK,EAAG,QAAO;AACtC,SAAM,IAAI,MAAM,KAAK,aAAa,2BAA2B,kBAAkB,IAAI;;AAErF,SAAO,CAAC,UAAU,YAAY;;CAEhC,MAAM,oBAAoB;EACxB,MAAM,gBAAgB,gBAAgB,KAAK,mBAAmB;AAC5D,UAAO,MAAM,cAAc,eAAe;IAC1C;AACF,SAAO,SAAS,SAAS,OAAO;GAC9B,MAAM,WAAW,QAAQ,cAAc;AACvC,UAAO,MAAM,eACJ,GAAG,UAAU,cAAc;IAAE,GAAG;KAAQ,YAAY;IAAU,EAAE,GACvE,CAAC,OAAO,SAAS,CAClB;;;AAGL,aAAY,YAAY;AACxB,QAAO,CAAC,gBAAgB,qBAAqB,aAAa,GAAG,uBAAuB,CAAC;;AAEvF,SAAS,qBAAqB,GAAG,QAAQ;CACvC,MAAM,YAAY,OAAO;AACzB,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,oBAAoB;EACxB,MAAM,aAAa,OAAO,KAAK,kBAAkB;GAC/C,UAAU,cAAc;GACxB,WAAW,aAAa;GACzB,EAAE;AACH,SAAO,SAAS,kBAAkB,gBAAgB;GAChD,MAAM,aAAa,WAAW,QAAQ,aAAa,EAAE,UAAU,gBAAgB;IAE7E,MAAM,eADa,SAAS,eAAe,CACX,UAAU;AAC1C,WAAO;KAAE,GAAG;KAAa,GAAG;KAAc;MACzC,EAAE,CAAC;AACN,UAAO,MAAM,eAAe,GAAG,UAAU,UAAU,cAAc,YAAY,GAAG,CAAC,WAAW,CAAC;;;AAGjG,aAAY,YAAY,UAAU;AAClC,QAAO;;;;;ACxET,IAAI,mBAAmB,YAAY,WAAW,MAAM,wBAAwB;;;;ACC5E,IAAI,qBAAqB,MAAM,uBAAuB,MAAM,CAAC,UAAU,KAAK4C;AAC5E,SAAS,qBAAqB,EAC5B,MACA,aACA,iBAAiB,IAEjB,UACC;CACD,MAAM,CAAC,kBAAkB,qBAAqB,eAAe,qBAAqB;EAChF;EACA;EACD,CAAC;CACF,MAAM,eAAe,SAAS,KAAK;CACnC,MAAM,QAAQ,eAAe,OAAO;CAC1B;EACR,MAAM,kBAAkB,MAAM,OAAO,SAAS,KAAK,EAAE;AACrD,QAAM,gBAAgB;GACpB,MAAM,gBAAgB,gBAAgB;AACtC,OAAI,kBAAkB,cAAc;IAClC,MAAM,OAAO,gBAAgB,eAAe;IAC5C,MAAM,KAAK,eAAe,eAAe;AACzC,YAAQ,KACN,GAAG,OAAO,oBAAoB,KAAK,MAAM,GAAG,4KAC7C;;AAEH,mBAAgB,UAAU;KACzB,CAAC,cAAc,OAAO,CAAC;;AAe5B,QAAO,CAAC,OAbS,MAAM,aACpB,cAAc;AACb,MAAI,cAAc;GAChB,MAAM,SAAS,WAAW,UAAU,GAAG,UAAU,KAAK,GAAG;AACzD,OAAI,WAAW,KACb,aAAY,UAAU,OAAO;QAG/B,qBAAoB,UAAU;IAGlC;EAAC;EAAc;EAAM;EAAqB;EAAY,CACvD,CACuB;;AAE1B,SAAS,qBAAqB,EAC5B,aACA,YACC;CACD,MAAM,CAAC,OAAO,YAAY,MAAM,SAAS,YAAY;CACrD,MAAM,eAAe,MAAM,OAAO,MAAM;CACxC,MAAM,cAAc,MAAM,OAAO,SAAS;AAC1C,0BAAyB;AACvB,cAAY,UAAU;IACrB,CAAC,SAAS,CAAC;AACd,OAAM,gBAAgB;AACpB,MAAI,aAAa,YAAY,OAAO;AAClC,eAAY,UAAU,MAAM;AAC5B,gBAAa,UAAU;;IAExB,CAAC,OAAO,aAAa,CAAC;AACzB,QAAO;EAAC;EAAO;EAAU;EAAY;;AAEvC,SAAS,WAAW,OAAO;AACzB,QAAO,OAAO,UAAU;;;;;AC/D1B,SAAS,OAAO,KAAK,OAAO;AAC1B,KAAI,OAAO,QAAQ,WACjB,QAAO,IAAI,MAAM;UACR,QAAQ,QAAQ,QAAQ,KAAK,EACtC,KAAI,UAAU;;AAGlB,SAAS,YAAY,GAAG,MAAM;AAC5B,SAAQ,SAAS;EACf,IAAI,aAAa;EACjB,MAAM,WAAW,KAAK,KAAK,QAAQ;GACjC,MAAM,UAAU,OAAO,KAAK,KAAK;AACjC,OAAI,CAAC,cAAc,OAAO,WAAW,WACnC,cAAa;AAEf,UAAO;IACP;AACF,MAAI,WACF,cAAa;AACX,QAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;IACxC,MAAM,UAAU,SAAS;AACzB,QAAI,OAAO,WAAW,WACpB,UAAS;QAET,QAAO,KAAK,IAAI,KAAK;;;;;AAOjC,SAAS,gBAAgB,GAAG,MAAM;AAChC,QAAO,MAAM,YAAY,YAAY,GAAG,KAAK,EAAE,KAAK;;;;;ACVtD,IAAI,YAnBQ;CACV;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CACqB,QAAQ,WAAW,SAAS;CAChD,MAAMC,SAAO,WAAW,aAAa,OAAO;CAC5C,MAAM,OAAO,MAAM,YAAY,OAAO,iBAAiB;EACrD,MAAM,EAAE,SAAS,GAAG,mBAAmB;EACvC,MAAM,OAAO,UAAUA,SAAO;AAC9B,MAAI,OAAO,WAAW,YACpB,QAAO,OAAO,IAAI,WAAW,IAAI;AAEnC,SAAuB,oBAAI,MAAM;GAAE,GAAG;GAAgB,KAAK;GAAc,CAAC;GAC1E;AACF,MAAK,cAAc,aAAa;AAChC,QAAO;EAAE,GAAG;GAAY,OAAO;EAAM;GACpC,EAAE,CAAC;;;;AC3BN,SAAS,gBAAgB,cAAc,SAAS;AAC9C,QAAO,MAAM,YAAY,OAAO,UAAU;AAExC,SADkB,QAAQ,OAAO,UACb;IACnB,aAAa;;AAIlB,IAAI,YAAY,UAAU;CACxB,MAAM,EAAE,SAAS,aAAa;CAC9B,MAAM,WAAW,YAAY,QAAQ;CACrC,MAAM,QAAQ,OAAO,aAAa,aAAa,SAAS,EAAE,SAAS,SAAS,WAAW,CAAC,GAAGC,MAAO,SAAS,KAAK,SAAS;CACzH,MAAM,MAAM,gBAAgB,SAAS,KAAK,cAAc,MAAM,CAAC;AAE/D,QADmB,OAAO,aAAa,cAClB,SAAS,YAAYA,MAAO,aAAa,OAAO,EAAE,KAAK,CAAC,GAAG;;AAElF,SAAS,cAAc;AACvB,SAAS,YAAY,SAAS;CAC5B,MAAM,CAAC,MAAM,WAAWA,MAAO,UAAU;CACzC,MAAM,YAAYA,MAAO,OAAO,KAAK;CACrC,MAAM,iBAAiBA,MAAO,OAAO,QAAQ;CAC7C,MAAM,uBAAuBA,MAAO,OAAO,OAAO;CAElD,MAAM,CAAC,OAAO,QAAQ,gBADD,UAAU,YAAY,aACS;EAClD,SAAS;GACP,SAAS;GACT,eAAe;GAChB;EACD,kBAAkB;GAChB,OAAO;GACP,eAAe;GAChB;EACD,WAAW,EACT,OAAO,WACR;EACF,CAAC;AACF,OAAO,gBAAgB;EACrB,MAAM,uBAAuB,iBAAiB,UAAU,QAAQ;AAChE,uBAAqB,UAAU,UAAU,YAAY,uBAAuB;IAC3E,CAAC,MAAM,CAAC;AACX,wBAAsB;EACpB,MAAM,SAAS,UAAU;EACzB,MAAM,aAAa,eAAe;AAElC,MAD0B,eAAe,SAClB;GACrB,MAAM,oBAAoB,qBAAqB;GAC/C,MAAM,uBAAuB,iBAAiB,OAAO;AACrD,OAAI,QACF,MAAK,QAAQ;YACJ,yBAAyB,UAAU,QAAQ,YAAY,OAChE,MAAK,UAAU;YAGX,cADgB,sBAAsB,qBAExC,MAAK,gBAAgB;OAErB,MAAK,UAAU;AAGnB,kBAAe,UAAU;;IAE1B,CAAC,SAAS,KAAK,CAAC;AACnB,wBAAsB;AACpB,MAAI,MAAM;GACR,IAAI;GACJ,MAAM,cAAc,KAAK,cAAc,eAAe;GACtD,MAAM,sBAAsB,UAAU;IAEpC,MAAM,qBADuB,iBAAiB,UAAU,QAAQ,CAChB,SAAS,IAAI,OAAO,MAAM,cAAc,CAAC;AACzF,QAAI,MAAM,WAAW,QAAQ,oBAAoB;AAC/C,UAAK,gBAAgB;AACrB,SAAI,CAAC,eAAe,SAAS;MAC3B,MAAM,kBAAkB,KAAK,MAAM;AACnC,WAAK,MAAM,oBAAoB;AAC/B,kBAAY,YAAY,iBAAiB;AACvC,WAAI,KAAK,MAAM,sBAAsB,WACnC,MAAK,MAAM,oBAAoB;QAEjC;;;;GAIR,MAAM,wBAAwB,UAAU;AACtC,QAAI,MAAM,WAAW,KACnB,sBAAqB,UAAU,iBAAiB,UAAU,QAAQ;;AAGtE,QAAK,iBAAiB,kBAAkB,qBAAqB;AAC7D,QAAK,iBAAiB,mBAAmB,mBAAmB;AAC5D,QAAK,iBAAiB,gBAAgB,mBAAmB;AACzD,gBAAa;AACX,gBAAY,aAAa,UAAU;AACnC,SAAK,oBAAoB,kBAAkB,qBAAqB;AAChE,SAAK,oBAAoB,mBAAmB,mBAAmB;AAC/D,SAAK,oBAAoB,gBAAgB,mBAAmB;;QAG9D,MAAK,gBAAgB;IAEtB,CAAC,MAAM,KAAK,CAAC;AAChB,QAAO;EACL,WAAW,CAAC,WAAW,mBAAmB,CAAC,SAAS,MAAM;EAC1D,KAAKA,MAAO,aAAa,UAAU;AACjC,aAAU,UAAU,QAAQ,iBAAiB,MAAM,GAAG;AACtD,WAAQ,MAAM;KACb,EAAE,CAAC;EACP;;AAEH,SAAS,iBAAiB,QAAQ;AAChC,QAAO,QAAQ,iBAAiB;;AAElC,SAAS,cAAc,SAAS;CAC9B,IAAI,SAAS,OAAO,yBAAyB,QAAQ,OAAO,MAAM,EAAE;CACpE,IAAI,UAAU,UAAU,oBAAoB,UAAU,OAAO;AAC7D,KAAI,QACF,QAAO,QAAQ;AAEjB,UAAS,OAAO,yBAAyB,SAAS,MAAM,EAAE;AAC1D,WAAU,UAAU,oBAAoB,UAAU,OAAO;AACzD,KAAI,QACF,QAAO,QAAQ,MAAM;AAEvB,QAAO,QAAQ,MAAM,OAAO,QAAQ;;;;;AChItC,IAAI,aAAa,MAAM,UAAU,MAAM,CAAC,UAAU,YAAY,KAAK;AACnE,IAAI,QAAQ;AACZ,SAAS,MAAM,iBAAiB;CAC9B,MAAM,CAAC,IAAI,SAAS,MAAM,SAAS,YAAY,CAAC;AAChD,wBAAsB;AACpB,MAAI,CAAC,gBAAiB,QAAO,YAAY,WAAW,OAAO,QAAQ,CAAC;IACnE,CAAC,gBAAgB,CAAC;AACrB,QAAO,oBAAoB,KAAK,SAAS,OAAO;;;;;ACGlD,IAAI,mBAAmB;AACvB,IAAI,CAAC,0BAA0B,0BAA0B,mBAAmB,iBAAiB;AAC7F,IAAI,CAAC,qBAAqB,yBAAyB,yBAAyB,iBAAiB;AAC7F,IAAIC,gBAAc,MAAM,YACrB,OAAO,iBAAiB;CACvB,MAAM,EACJ,oBACA,MAAM,UACN,aACA,UACA,cACA,GAAG,qBACD;CACJ,MAAM,CAAC,MAAM,WAAW,qBAAqB;EAC3C,MAAM;EACN,aAAa,eAAe;EAC5B,UAAU;EACV,QAAQ;EACT,CAAC;AACF,QAAuB,oBACrB,qBACA;EACE,OAAO;EACP;EACA,WAAW,OAAO;EAClB;EACA,cAAc,MAAM,kBAAkB,SAAS,aAAa,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC;EAClF,UAA0B,oBACxB,UAAU,KACV;GACE,cAAc,SAAS,KAAK;GAC5B,iBAAiB,WAAW,KAAK,KAAK;GACtC,GAAG;GACH,KAAK;GACN,CACF;EACF,CACF;EAEJ;AACD,cAAY,cAAc;AAC1B,IAAI,eAAe;AACnB,IAAIC,uBAAqB,MAAM,YAC5B,OAAO,iBAAiB;CACvB,MAAM,EAAE,oBAAoB,GAAG,iBAAiB;CAChD,MAAM,UAAU,sBAAsB,cAAc,mBAAmB;AACvE,QAAuB,oBACrB,UAAU,QACV;EACE,MAAM;EACN,iBAAiB,QAAQ;EACzB,iBAAiB,QAAQ,QAAQ;EACjC,cAAc,SAAS,QAAQ,KAAK;EACpC,iBAAiB,QAAQ,WAAW,KAAK,KAAK;EAC9C,UAAU,QAAQ;EAClB,GAAG;EACH,KAAK;EACL,SAAS,qBAAqB,MAAM,SAAS,QAAQ,aAAa;EACnE,CACF;EAEJ;AACD,qBAAmB,cAAc;AACjC,IAAI,eAAe;AACnB,IAAIC,uBAAqB,MAAM,YAC5B,OAAO,iBAAiB;CACvB,MAAM,EAAE,YAAY,GAAG,iBAAiB;CACxC,MAAM,UAAU,sBAAsB,cAAc,MAAM,mBAAmB;AAC7E,QAAuB,oBAAI,UAAU;EAAE,SAAS,cAAc,QAAQ;EAAM,WAAW,EAAE,cAA8B,oBAAI,wBAAwB;GAAE,GAAG;GAAc,KAAK;GAAc;GAAS,CAAC;EAAE,CAAC;EAEzM;AACD,qBAAmB,cAAc;AACjC,IAAI,yBAAyB,MAAM,YAAY,OAAO,iBAAiB;CACrE,MAAM,EAAE,oBAAoB,SAAS,UAAU,GAAG,iBAAiB;CACnE,MAAM,UAAU,sBAAsB,cAAc,mBAAmB;CACvE,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAS,QAAQ;CACzD,MAAM,MAAM,MAAM,OAAO,KAAK;CAC9B,MAAM,eAAe,gBAAgB,cAAc,IAAI;CACvD,MAAM,YAAY,MAAM,OAAO,EAAE;CACjC,MAAM,SAAS,UAAU;CACzB,MAAM,WAAW,MAAM,OAAO,EAAE;CAChC,MAAM,QAAQ,SAAS;CACvB,MAAM,SAAS,QAAQ,QAAQ;CAC/B,MAAM,+BAA+B,MAAM,OAAO,OAAO;CACzD,MAAM,oBAAoB,MAAM,OAAO,KAAK,EAAE;AAC9C,OAAM,gBAAgB;EACpB,MAAM,MAAM,4BAA4B,6BAA6B,UAAU,MAAM;AACrF,eAAa,qBAAqB,IAAI;IACrC,EAAE,CAAC;AACN,wBAAsB;EACpB,MAAM,OAAO,IAAI;AACjB,MAAI,MAAM;AACR,qBAAkB,UAAU,kBAAkB,WAAW;IACvD,oBAAoB,KAAK,MAAM;IAC/B,eAAe,KAAK,MAAM;IAC3B;AACD,QAAK,MAAM,qBAAqB;AAChC,QAAK,MAAM,gBAAgB;GAC3B,MAAM,OAAO,KAAK,uBAAuB;AACzC,aAAU,UAAU,KAAK;AACzB,YAAS,UAAU,KAAK;AACxB,OAAI,CAAC,6BAA6B,SAAS;AACzC,SAAK,MAAM,qBAAqB,kBAAkB,QAAQ;AAC1D,SAAK,MAAM,gBAAgB,kBAAkB,QAAQ;;AAEvD,gBAAa,QAAQ;;IAEtB,CAAC,QAAQ,MAAM,QAAQ,CAAC;AAC3B,QAAuB,oBACrB,UAAU,KACV;EACE,cAAc,SAAS,QAAQ,KAAK;EACpC,iBAAiB,QAAQ,WAAW,KAAK,KAAK;EAC9C,IAAI,QAAQ;EACZ,QAAQ,CAAC;EACT,GAAG;EACH,KAAK;EACL,OAAO;IACJ,uCAAuC,SAAS,GAAG,OAAO,MAAM,KAAK;IACrE,sCAAsC,QAAQ,GAAG,MAAM,MAAM,KAAK;GACnE,GAAG,MAAM;GACV;EACD,UAAU,UAAU;EACrB,CACF;EACD;AACF,SAAS,SAAS,MAAM;AACtB,QAAO,OAAO,SAAS;;AAEzB,IAAI,OAAOF;;;;AC1IX,SAAAM,YAAAC,IAAA;CAAA,MAAAC,IAAAJ,EAAA,EAAA;CAAA,IAAAK;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAqB,GAAA,IAAAE,SAAAF;AAEoCC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAChDC,OAAA,oBAAA;GAAqC,aAAA;GAAa,GAAKD;IAAS;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAhEE;;AAGT,SAAAC,mBAAAJ,IAAA;CAAA,MAAAC,IAAAJ,EAAA,EAAA;CAAA,IAAAK;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAA4B,GAAA,IAAAE,SAAAF;AAE2CC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAEnEC,OAAA,oBAAA;GACY,aAAA;GAAqB,GAC3BD;IACJ;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAHFE;;AAOJ,SAAAE,mBAAAL,IAAA;CAAA,MAAAC,IAAAJ,EAAA,EAAA;CAAA,IAAAK;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAA4B,GAAA,IAAAE,SAAAF;AAE2CC,IAAA,KAAAD;AAAAC,IAAA,KAAAC;OAAAA,SAAAD,EAAA;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAC,OAAA;AAEnEC,OAAA,oBAAA;GACY,aAAA;GAAqB,GAC3BD;IACJ;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAHFE;;;;;ACEJ,MAAMsB,qBAAqB;;;;;AAM3B,MAAMC,iBAIFE,OAAA;CAAA,MAAAC,IAAAtB,EAAA,GAAA;CAAC,MAAA,EAAAoB,WAAAG,aAAAF;CACH,MAAAG,iBAAuBnB,OAAuB,KAAK;CACnD,MAAA,CAAAoB,QAAAC,aAA4BpB,SAAS,MAAM;CAC3C,MAAAqB,aAAmBlB,cAAce,gBAAgBN,mBAAmB;CAAC,IAAAU;AAAA,KAAAN,EAAA,OAAAK,YAAA;AAGnEC,QAAAC,SAAA;AACE,OAAI,CAACA,KACHF,aAAY;AAEdD,aAAUG,KAAK;;AAChBP,IAAA,KAAAK;AAAAL,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CANH,MAAAQ,mBAAyBF;CAQvB,IAAAG;AAAA,KAAAT,EAAA,OAAAF,WAAA;AAOaW,OAAAd,GAAG,kCAAkCG,UAAU;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAExDF,OAAA,EAAA,wBAC0B,GAAGd,mBAAkB,KAC9C;AAAAI,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAC,YAAAD,EAAA,OAAAQ,oBAAAR,EAAA,OAAAG,UAAAH,EAAA,OAAAS,IAAA;AARLI,OAAA,oBAAC;GACMX,KAAAA;GACCC,MAAAA;GACQK,cAAAA;GACH,WAAAC;GAET,OAAAC;GAKDT;IACW;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAQ;AAAAR,IAAA,KAAAG;AAAAH,IAAA,KAAAS;AAAAT,IAAA,KAAAa;OAAAA,MAAAb,EAAA;AAAA,QAZda;;AAgBJhB,cAAcmB,cAAc;;;;;AAM5B,MAAMC,gBAA2ClB,OAAA;CAAA,MAAAC,IAAAtB,EAAA,EAAA;CAAC,MAAA,EAAAoB,cAAAC;CAAa,IAAAO;AAAA,KAAAN,EAAA,OAAAF,WAAA;AAEhDQ,OAAAX,GACT,gFACA,oEACA,wBACA,2DACA,0DACA,4FACA,kEACA,mCACA,+EACAG,UACD;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAM,IAAA;AAZHG,OAAA,oBAAA,SACa,WAAAH,KAYX;AAAAN,IAAA,KAAAM;AAAAN,IAAA,KAAAS;OAAAA,MAAAT,EAAA;AAAA,QAbFS;;;;;;AAoBF,MAAMS,oBAAgEnB,OAAA;CAAA,MAAAC,IAAAtB,EAAA,GAAA;CAAC,MAAA,EAAAyC,QAAArB,cAAAC;CAGtE,IAAAO;AAAA,KAAAN,EAAA,OAAAF,WAAA;AAEcQ,OAAAX,GACT,4JACAG,UACD;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAEDH,OAAA,oBAAC,aAAoB,WAAA,qDAAqD;AAAAT,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAExEF,OAAA,oBAAA,oBAAM,cAAgB;AAAAV,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAmB,QAAA;AACrBN,OAAAM,SACC,oBAAA;GACE,eAAA;GACU,WAAA;aACX;IAGK,GAPP;AAOOnB,IAAA,KAAAmB;AAAAnB,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAa,IAAA;AATVO,OAAA,qBAAA;GAAgB,WAAA;cACdV,IACCG;IAQI;AAAAb,IAAA,KAAAa;AAAAb,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AACPS,OAAA,oBAAC,mBACY,WAAA1B,GACT,iEACA,0EACA,mDACA,8CACF,GACA;AAAAK,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,OAAAM,MAAAN,EAAA,QAAAoB,IAAA;AAzBJE,OAAA,qBAAC;GACY,WAAAhB;;IAKXG;IACAW;IAWAC;;IAQmB;AAAArB,IAAA,KAAAM;AAAAN,IAAA,MAAAoB;AAAApB,IAAA,MAAAsB;OAAAA,MAAAtB,EAAA;AAAA,QA1BrBsB;;;;;;;AAkCF,MAAMC,oBAKFxB,OAAA;CAAA,MAAAC,IAAAtB,EAAA,EAAA;CAAC,MAAA,EAAAoB,WAAAG,UAAA,aAAAuB,aAAAzB;CAA8C,IAAAO;AAAA,KAAAN,EAAA,OAAAF,WAAA;AAEpCQ,OAAAX,GACT,6FACA,sCACA,8CACA,8CACA,0CACA,2CACA,qDACA,uDACAG,UACD;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAIDH,OAAA,oBAAC,iBAAe;AAAAT,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,OAAAwB,YAAAxB,EAAA,OAAAC,YAAAD,EAAA,OAAAM,IAAA;AAflBI,OAAA,qBAAC;GACY,WAAAJ;GAWAkB,aAAAA;cAEVvB,UACDQ;IACmB;AAAAT,IAAA,KAAAwB;AAAAxB,IAAA,KAAAC;AAAAD,IAAA,KAAAM;AAAAN,IAAA,KAAAU;OAAAA,MAAAV,EAAA;AAAA,QAhBrBU;;AAmBFa,iBAAiBP,cAAc;;;;;;AAO/B,MAAMS,iBAIF1B,OAAA;CAAA,MAAAC,IAAAtB,EAAA,EAAA;CAAC,MAAA,EAAAoB,WAAAG,aAAAF;CAAuB,IAAAO;AAAA,KAAAN,EAAA,OAAAF,WAAA;AAEbQ,OAAAX,GACT,uEACA,gDACA,0DACA,6DACA,yDACA,4DACA,mEACA,oEACA,+EACA,iFACA,eACAG,UACD;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAS;AAAA,KAAAT,EAAA,OAAAC,YAAAD,EAAA,OAAAM,IAAA;AAdHG,OAAA,oBAAA;GACa,WAAAH;GAeVL;IACG;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAM;AAAAN,IAAA,KAAAS;OAAAA,MAAAT,EAAA;AAAA,QAjBNS;;AAoBFgB,cAAcT,cAAc;;;;;;;;;;;;;;;;;AAkB5B,MAAMU,sBAA+C;CAAA,MAAA1B,IAAAtB,EAAA,EAAA;CAAA,IAAAqB;AAAA,KAAAC,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAAMb,OAAA,oBAAC,iBAAe;AAAAC,IAAA,KAAAD;OAAAA,MAAAC,EAAA;AAAA,QAAhBD;;;;;;;;;;;;;;;;;;AAkB3D,MAAM4B,sBAA8C5B,OAAA;CAAA,MAAAC,IAAAtB,EAAA,GAAA;CAAC,MAAA,EAAAuB,UAAA2B,YAAAC,aAAA9B;CAIpD,IAAAO;AAAA,KAAAN,EAAA,OAAA6B,YAAA7B,EAAA,OAAA4B,YAAA;AAIgDtB,QAAAG,SAAA;GAAC,MAAA,EAAAqB,YAAArB;AAC9C,OAAIqB,QAAOC,QAAaC,SAAK,UAAS,QAAS;GAC/C,MAAAC,YAAkBH,QAAOI,MAAMC,SAAU;AACzC,OAAIF,YAAY,EAAC,QAAS;AAE1B,OADiBH,QAAOI,MAAOD,YAAgBD,SAC9B,YAAW,QAAS;AAAM,UACpCC,aAAaL,cAAcK,aAAaJ;;AAChD7B,IAAA,KAAA6B;AAAA7B,IAAA,KAAA4B;AAAA5B,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAPD,MAAAqC,uBAA6BjD,kBAAkBkB,GAO7C;CAAC,IAAAG;AAAA,KAAAT,EAAA,OAAAqC,sBAAA;AAIC5B,OAAA,oBAAC,oBAAyB4B,QAAAA,uBAAwB;AAAArC,IAAA,KAAAqC;AAAArC,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAAA,IAAAU;AAAA,KAAAV,EAAA,OAAAC,UAAA;AAGhDS,OAAA,oBAAC,iBAAeT,WAAyB;AAAAD,IAAA,KAAAC;AAAAD,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAqC,wBAAArC,EAAA,OAAAU,IAAA;AAD3CG,OAAA,oBAAC;GAA4BwB,aAAAA;aAC3B3B;IACiB;AAAAV,IAAA,KAAAqC;AAAArC,IAAA,KAAAU;AAAAV,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAS,MAAAT,EAAA,QAAAa,IAAA;AALrBO,OAAA,qBAAC,4BACCX,IAEAI,MAGc;AAAAb,IAAA,MAAAS;AAAAT,IAAA,MAAAa;AAAAb,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;AAAA,QANhBoB;;AAUJ,MAAakB,YAAYzD,KAAK6C,cAAc;AAC5CY,UAAUtB,cAAc;AAExB,MAAauB,iBAAiB1D,KAAK8C,mBAAmB;AACtDY,eAAevB,cAAc;;;;;;;;;;;;;;;;;;ACnP7B,SAAO0B,gBAAAC,OAAAC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CACN,MAAA,CAAAC,cAAAC,mBAAwCP,SAASE,MAAM;CAAA,IAAAM;CAAA,IAAAC;AAAA,KAAAL,EAAA,OAAAD,SAAAC,EAAA,OAAAF,OAAA;AAE7CM,aAAA;GACT,MAAAE,QAAcC,iBAAiBJ,gBAAgBL,MAAM,EAAEC,MAAM;AAAA,gBAChDS,aAAaF,MAAM;;AAC9BD,OAAA,CAACP,OAAOC,MAAM;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAF;AAAAE,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;QAAA;AAAAD,OAAAJ,EAAA;AAAAK,OAAAL,EAAA;;AAHjBL,WAAUS,IAGPC,GAAe;AAAA,QAEXH;;;;;;AC0KR,MAAa6E,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7R3C,SAAgBY,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;;;;;ACrEtE,MAAMc,eAAe;;;;;;AAOrB,SAAgBC,0BACfC,MACgD;CAChD,MAAMG,iBAAiBH,KAAKI,QAAQ,IAAI;AACxC,KAAID,mBAAmB,GAAI,QAAO;CAElC,MAAMF,WAAWD,KAAKK,MAAM,GAAGF,eAAe;CAC9C,MAAMD,WAAWF,KAAKK,MAAMF,iBAAiB,EAAE;AAE/C,KAAI,CAACF,YAAY,CAACC,SAAU,QAAO;AACnC,KAAI,CAACJ,aAAaQ,KAAKL,SAAS,CAAE,QAAO;AAEzC,QAAO;EAAEA;EAAUC;EAAU;;AAG9B,SAAgBK,0BAA0BP,MAAsB;AAC/D,QAAOD,0BAA0BC,KAAK,EAAEE,YAAYF;;;;;;;;;;;;;;;;;;;;;;;;;ACqBrD,MAAa+B,eAAe;AA2E5B,MAAMgC,kBAAkBpD,cAA2C,KAAK;AAYxE,SAAgB0D,iBAAiB,EAChCJ,UACAC,mBAAmB,MACnBC,eACAC,mBACyB;CAEzB,MAAME,aAAatD,uBAAiC,IAAIgC,KAAK,CAAC;CAG9D,MAAMuB,mBAAmBvD,uBAAsC,IAAIgC,KAAK,CAAC;CAGzE,MAAMwB,mBAAmBxD,OAAO,EAAE;CAGlC,MAAM,GAAGyD,eAAexD,SAAS,EAAE,CAAC;CAGpC,MAAM,CAACyD,WAAWC,gBAAgB1D,SAA2B,EAAE,CAAC;CAGhE,MAAM,CAAC2D,aAAaC,kBAAkB5D,SAAmB,EAAE,CAAC;;;;;CAM5D,MAAM6D,qBAAqBlE,aAAamE,iBAAmC;EAC1E,MAAMC,mBAAmB,IAAIC,IAAIF,aAAaG,KAAKC,MAAMA,EAAE1B,KAAK,CAAC;AAEjEc,mBAAiBa,QAAQC,SAASC,MAAMC,WAAW;AAClD,OAAI,CAACP,iBAAiBQ,IAAIF,KAAK7C,SAAS,EAAE;AACzCgD,YAAQC,KACP,mDAAmDJ,KAAK7C,SAAQ,aAAc8C,OAAM,GACpF;AACDD,SAAK3C,gBAAgBgD,sBAAM,IAAIC,MAAM,SAASN,KAAK7C,SAAQ,0BAA2B,CAAC;AACvF8B,qBAAiBa,QAAQS,OAAON,OAAO;;IAEvC;IACA,EAAE,CAAC;;;;CAKN,MAAMO,eAAelF,kBAAkB;EACtC,MAAMmF,WAA6B,EAAE;AAErCzB,aAAWc,QAAQC,SAASW,WAAW;AACtCA,UAAOlD,MAAMuC,SAASY,SAAS;AAC9BF,aAASG,KAAK;KACb,GAAGD;KACHE,WAAWH,OAAO9C;KAClB,CAAC;KACD;IACD;AAGF4B,qBAAmBiB,SAAS;AAE5BpB,eAAaoB,SAAS;IACpB,CAACjB,mBAAmB,CAAC;;;;CAKxB,MAAMsB,iBAAiBxF,kBAAkB;EACxC,MAAMyF,aAAuB,EAAE;AAE/B/B,aAAWc,QAAQC,SAASW,aAAW;AACtCA,YAAOzD,QAAQ8C,SAASiB,WAAW;AAClCD,eAAWH,KAAKI,OAAO;KACtB;IACD;AAEFzB,iBAAewB,WAAW;IACxB,EAAE,CAAC;;;;CAKN,MAAME,kBAAkB3F,aAAaoF,aAAmC;AACvE,SAAO;GACN9C,IAAI8C,SAAO9C;GACXC,QAAQ6C,SAAO7C;GACfqD,OAAOR,SAAOQ;GACdC,OAAOT,SAAOS;GACd3D,OAAOkD,SAAOlD;GACdT,WAAW2D,SAAO3D;GAClBC,mBAAmB0D,SAAO1D;GAC1BC,SAASyD,SAAOzD;GAChB;IACC,EAAE,CAAC;;;;CAKN,MAAMU,YAAYrC,YACjB,OAAOsC,IAAYC,WAA2C;AAE7D,MAAImB,WAAWc,QAAQI,IAAItC,GAAG,CAC7B,OAAMG,aAAaH,GAAG;EAIvB,MAAMwD,cAA2B;GAChCxD;GACAC;GACAqD,OAAO;GACPC,OAAO;GACP3D,OAAO,EAAE;GACTT,WAAW,EAAE;GACbC,mBAAmB,EAAE;GACrBC,SAAS,EAAE;GACXJ,QAAQ;GACRC,WAAW;GACX;AAEDkC,aAAWc,QAAQuB,IAAIzD,IAAIwD,YAAY;AACvCjC,cAAY,EAAE,CAAC;AAEf,MAAI;GAEH,MAAMtC,SAAS,IAAI3B,OAAO;IACzBiD,MAAM,cAAcP;IACpB0D,SAAS;IACT,CAAC;GAEF,MAAMxE,YAAYjB,mBAAmBgC,OAAO;AAG5C,SAAMhB,OAAO0E,QAAQzE,UAAU;AAG/BsE,eAAYvE,SAASA;AACrBuE,eAAYtE,YAAYA;GAGxB,MAAM,EAAEU,UAAU,MAAMX,OAAO2E,WAAW;AAC1CJ,eAAY5D,QAAQA;AAGpB,OAAI;IACH,MAAM,EAAEP,YAAY,MAAMJ,OAAO4E,aAAa;AAC9CL,gBAAYnE,UAAUA;YACdyE,OAAK;AACbvB,YAAQC,KAAK,qBAAqBxC,GAAE,qCAAsC8D,MAAI;AAC9EN,gBAAYnE,UAAU,EAAE;;AAGzBmE,eAAYF,QAAQ;AAGpBrE,UAAO8E,uBAAuBvG,mCAAmC,YAAY;AAC5E,QAAI;AAEHgG,iBAAY5D,SADI,MAAMX,OAAO2E,WAAW,EACZhE;AAC5BgD,mBAAc;AACdrB,iBAAY,EAAE,CAAC;aACPuC,OAAK;AACbvB,aAAQgB,MAAM,qBAAqBvD,GAAE,4BAA6B8D,MAAI;;KAEtE;AAGF7E,UAAO8E,uBAAuBxG,qCAAqC,YAAY;AAC9E,QAAI;AAEHiG,iBAAYnE,WADI,MAAMJ,OAAO4E,aAAa,EACZxE;AAC9B6D,qBAAgB;AAChB3B,iBAAY,EAAE,CAAC;aACPuC,OAAK;AACbvB,aAAQgB,MAAM,qBAAqBvD,GAAE,8BAA+B8D,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,qBAAqBvD,GAAE,uBAAwBuD,MAAM;AAEnEC,eAAYF,QAAQ;AACpBE,eAAYD,QAAQA;AACpBhC,eAAY,EAAE,CAAC;;IAGjB,CAACqB,cAAcM,eAChB,CAAC;;;;CAKD,MAAM/C,eAAezC,YACpB,OAAOsC,SAA8B;EACpC,MAAM8C,WAAS1B,WAAWc,QAAQgC,IAAIlE,KAAG;AACzC,MAAI,CAAC8C,SAAQ;AAGb,MAAIA,SAAO7D,OACV,KAAI;AACH,SAAM6D,SAAO7D,OAAOkF,OAAO;WACnBL,OAAK;AACbvB,WAAQgB,MAAM,qBAAqBvD,KAAE,0BAA2B8D,MAAI;;AAItE,MAAIhB,SAAO5D,UACV,KAAI;AACH,SAAM4D,SAAO5D,UAAUiF,OAAO;WACtBL,OAAK;AACbvB,WAAQgB,MAAM,qBAAqBvD,KAAE,6BAA8B8D,MAAI;;AAIzE1C,aAAWc,QAAQS,OAAO3C,KAAG;AAC7B4C,gBAAc;AACdM,kBAAgB;AAChB3B,cAAY,EAAE,CAAC;IAEhB,CAACqB,cAAcM,eAChB,CAAC;;;;CAKD,MAAM9C,YAAY1C,aAChBsC,SAAsC;EACtC,MAAM8C,WAAS1B,WAAWc,QAAQgC,IAAIlE,KAAG;AACzC,SAAO8C,WAASO,gBAAgBP,SAAO,GAAGsB;IAE3C,CAACf,gBACF,CAAC;;;;CAKD,MAAMhD,cAAc3C,aAAasC,SAAwB;AAExD,SADeoB,WAAWc,QAAQgC,IAAIlE,KAAG,EAC1BsD,UAAU;IACvB,EAAE,CAAC;;;;;CAMN,MAAM5C,mBAAmBhD,YACxB,OACC8B,UACAe,MACAC,SAC6B;EAC7B,MAAMsC,WAAS1B,WAAWc,QAAQgC,IAAI1E,SAAS;AAC/C,MAAI,CAACsD,UAAQ7D,OACZ,OAAM,IAAIyD,MAAM,WAAWlD,SAAQ,iBAAkB;EAItD,MAAM6C,WAAS,GAAG7C,SAAQ,GAAIe,KAAI,GAAI,EAAEe,iBAAiBY;EACzD,MAAMzC,kBAAkB,IAAIC,iBAAiB;AAG7C2B,mBAAiBa,QAAQuB,IAAIpB,UAAQ;GACpC9C,UAAUgB;GACVf;GACAC;GACA,CAAC;AAEF,MAAI;GAEH,MAAM4E,eAAe,IAAInE,SAAgBoE,GAAGC,WAAW;IACtD,MAAMC,SAAS/E,gBAAgB+E;AAG/B,QAAIA,OAAOC,SAAS;AACnBF,YAAOC,OAAOE,0BAAU,IAAIhC,MAAM,SAASnC,KAAI,oBAAqB,CAAC;AACrE;;AAIDiE,WAAOG,iBACN,eACM;AACLJ,YAAOC,OAAOE,0BAAU,IAAIhC,MAAM,SAASnC,KAAI,oBAAqB,CAAC;OAEtE,EAAEqE,MAAM,MACT,CAAC;KACA;AAQF,UALe,MAAM1E,QAAQ4E,KAAK,CACjChC,SAAO7D,OAAOqB,SAAS;IAAEC;IAAMwE,WAAWvE;IAAM,CAAC,EACjD6D,aACA,CAAC;WAGMd,SAAO;AAEf,OAAI9D,gBAAgB+E,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;;;;CAKA,MAAM/B,WAAW5C,YAChB,OAAO6C,QAAcC,WAA2D;EAG/E,MAAMuC,SACLvB,UAAU8D,MAAMrD,QAAMA,IAAE1B,SAASA,OAAK,WAC/B;GACN,MAAMgF,WAAWrH,0BAA0BqC,OAAK;AAChD,UAAOgF,aAAahF,SAAO6D,SAAY5C,UAAU8D,MAAMrD,QAAMA,IAAE1B,SAASgF,SAAS;MAC9E;AACL,MAAI,CAACxC,OACJ,OAAM,IAAIL,MAAM,SAASnC,OAAI,aAAc;AAG5C,SAAOG,iBAAiBqC,OAAKE,WAAWF,OAAKxC,MAAMC,OAAK;IAEzD,CAACgB,WAAWd,iBACb,CAAC;;;;CAKF,MAAMC,YAAYjD,YACjB,OAAO6C,QAAcC,WAA4D;AAEhF,OAAK,MAAMsC,YAAU1B,WAAWc,QAAQsD,QAAQ,CAE/C,KADkB1C,SAAOzD,QAAQqG,MAAMC,MAAMA,EAAEpF,SAASA,OAAK,IAC5CuC,SAAO7D,OACvB,QAAQ,MAAM6D,SAAO7D,OAAO0B,UAAU;GAAEJ,MAAAA;GAAMwE,WAAWvE;GAAM,CAAC;AAGlE,QAAM,IAAIkC,MAAM,WAAWnC,OAAI,aAAc;IAE9C,EACD,CAAC;;;;;;;CAQD,MAAMK,eAAelD,YAAY,YAAY;AAC5C6E,UAAQqD,MAAM,uDAAuD;AACrE,OAAK,MAAM9C,YAAU1B,WAAWc,QAAQsD,QAAQ,CAC/C,KAAI1C,SAAO7D,UAAU6D,SAAOQ,UAAU,YACrC,KAAI;GACH,MAAM,EAAE1D,OAAAA,YAAU,MAAMkD,SAAO7D,OAAO2E,WAAW;AACjDd,YAAOlD,QAAQA;AACf2C,WAAQqD,MAAM,qBAAqB9C,SAAO9C,GAAE,cAAeJ,QAAMiG,OAAM,QAAS;WACxE/B,OAAK;AACbvB,WAAQgB,MAAM,qBAAqBT,SAAO9C,GAAE,6BAA8B8D,MAAI;;AAIjFlB,gBAAc;IACZ,CAACA,aAAa,CAAC;;;;;;;;;;CAWlB,MAAM/C,UAAUhC,cAAc;EAC7B,MAAMiI,gCAAgB,IAAIhG,KAAwB;AAClDsB,aAAWc,QAAQC,SAASW,aAAW;AACtCgD,iBAAcrC,IAAIX,SAAO9C,IAAIqD,gBAAgBP,SAAO,CAAC;IACpD;AACF,SAAOgD;IACL;EAACtE;EAAWE;EAAa2B;EAAgB,CAAC;AAG7CzF,iBAAgB;AACf,MAAIoD,kBAAkB;GACrB,MAAM+E,QAAQC,iBAAiB;AAC9B,IAAKjG,UAAUlB,cAAc,EAAEoG,MAAM,OAAO,CAAC;MAC3CjH,yBAAyB;AAC5B,gBAAaiI,aAAaF,MAAM;;IAE/B,CAAC/E,kBAAkBjB,UAAU,CAAC;AAGjCnC,iBAAgB;AACfqD,kBAAgBO,UAAU;IACxB,CAACA,WAAWP,cAAc,CAAC;AAG9BrD,iBAAgB;AACfsD,oBAAkBQ,YAAY;IAC5B,CAACA,aAAaR,gBAAgB,CAAC;AAGlCtD,iBAAgB;EACf,MAAMiC,YAAUuB;EAChB,MAAM8E,gBAAgB7E;AACtB,eAAa;AAGZ6E,iBAAchE,QAAQC,SAASC,WAAS;AACvCA,WAAK3C,gBAAgBgD,sBAAM,IAAIC,MAAM,qBAAqB,CAAC;KAC1D;AACFwD,iBAAchE,QAAQiE,OAAO;AAG7BtG,aAAQqC,QAAQC,SAASW,aAAW;AACnC,QAAIA,SAAO7D,OACV,CAAK6D,SAAO7D,OAAOkF,OAAO,CAACiC,MAAM7D,QAAQgB,MAAM;AAEhD,QAAIT,SAAO5D,UACV,CAAK4D,SAAO5D,UAAUiF,OAAO,CAACiC,MAAM7D,QAAQgB,MAAM;KAElD;AACF1D,aAAQqC,QAAQiE,OAAO;;IAEtB,EAAE,CAAC;CAEN,MAAME,QAAQxI,eACN;EACN+B,OAAO4B;EACPnC,SAASqC;EACT7B;EACAE;EACAI;EACAC;EACAC;EACAC;EACAI;EACAC;EACAC;EACA,GACD;EACCY;EACAE;EACA7B;EACAE;EACAI;EACAC;EACAC;EACAC;EACAI;EACAC;EACAC;EAEF,CAAC;AAED,QAAO,oBAAC,gBAAgB;EAAgByF;EAAQtF;GAAoC;;;;;AAMrF,SAAOuF,cAAA;CACN,MAAAC,UAAgB5I,WAAWkD,gBAAgB;AAC3C,KAAI,CAAC0F,QACJ,OAAM,IAAI7D,MAAM,sDAAsD;AACtE,QACM6D;;;;;AAMR,SAAOC,sBAAA;AAAA,QACC7I,WAAWkD,gBAAgB;;;;;;;;;;ACtmBnC,SAAgB6F,kBAAkBC,aAAmD;AACpF,KAAI,CAACA,YAAa,QAAO;AACzB,KAAIA,YAAYC,iBAAiB,KAAM,QAAO;AAC9C,KAAI,OAAOD,YAAYE,oBAAoB,UAAW,QAAOF,YAAYE;AACzE,QAAO;;;;;;;;;;;;;;;;;;;;;;ACaR,MAAMY,cAAc;AACpB,MAAMC,eAAiC;AAgBvC,MAAMQ,sBAAsBpB,cAA+C,KAAK;AAYhF,SAAgB0B,qBAAqB,EACpCJ,UACAC,aACAC,qBAAqB,OACrBC,gBAC6B;CAE7B,MAAM,CAACV,MAAMY,gBAAgBtB,eAAiC;AAC7D,MAAIkB,YAAa,QAAOA;AACxB,MAAIC,mBAAoB,QAAOZ;AAE/B,MAAI;GACH,MAAMgB,SAASC,aAAaC,QAAQnB,YAAY;AAChD,OAAIiB,WAAW,UAAUA,WAAW,MACnC,QAAOA;UAED;AAGR,SAAOhB;GACN;AAGFT,iBAAgB;AACf,MAAIqB,mBAAoB;AAExB,MAAI;AACHK,gBAAaE,QAAQpB,aAAaI,KAAK;UAChC;IAGN,CAACA,MAAMS,mBAAmB,CAAC;CAG9B,MAAMV,UAAUb,aACd+B,YAA8B;AAC9BL,eAAaK,QAAQ;AACrBP,iBAAeO,QAAQ;IAExB,CAACP,aACF,CAAC;CAGD,MAAMT,aAAaf,kBAAkB;AACpCa,UAAQC,SAAS,SAAS,QAAQ,OAAO;IACvC,CAACA,MAAMD,QAAQ,CAAC;CAGnB,MAAMK,gBAAgBlB,aAAaiB,SAAwB;AAC1D,SAAOR,kBAAkBQ,KAAKe,YAAY;IACxC,EAAE,CAAC;CAGN,MAAMhB,mBAAmBhB,aACvBiB,WAAwB;AACxB,MAAIH,SAAS,OAAQ,QAAO;AAC5B,SAAOI,cAAcD,OAAK;IAE3B,CAACH,MAAMI,cACR,CAAC;CAED,MAAMe,QAAQ9B,eACN;EACNW;EACAD;EACAE;EACAC;EACAE;EACA,GACD;EAACJ;EAAMD;EAASE;EAAYC;EAAkBE;EAC/C,CAAC;AAED,QAAO,oBAAC,oBAAoB;EAAgBe;EAAQZ;GAAwC;;;;;AAM7F,SAAOa,kBAAA;CACN,MAAAC,UAAgBlC,WAAWkB,oBAAoB;AAC/C,KAAI,CAACgB,QACJ,OAAM,IAAIC,MAAM,6DAA6D;AAC7E,QACMD;;;;;AAMR,SAAOE,0BAAA;AAAA,QACCpC,WAAWkB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnGvC,MAAMiC,uBAAuBd,cAAgD,KAAK;AAkClF,MAAaoB,yBAAwDC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAP,UAAAC,SAAAC,cAAAC,oBAAAE;CAKrE,IAAAG;AAAA,KAAAF,EAAA,OAAAL,WAAAK,EAAA,OAAAJ,gBAAAI,EAAA,OAAAH,iBAAA;AAECK,QAAAf,SAAA;AAEC,OAAIQ,UAAUR,KAAIgB,MAAOhB,KAAK,CAAA,QACtB;AAIR,OAAIS,cAAYQ,SAAWjB,KAAIgB,KAAM,CAAA,QAC7B;AAIR,OAAIN,iBAAeQ,MAAOC,WAAYnB,KAAIgB,KAAKI,WAAYD,OAAO,CAAC,CAAA,QAC3D;AACP,UAEM;;AACPN,IAAA,KAAAL;AAAAK,IAAA,KAAAJ;AAAAI,IAAA,KAAAH;AAAAG,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAlBF,MAAAX,gBAAsBa;CAoBrB,IAAAM;AAAA,KAAAR,EAAA,OAAAX,eAAA;AAGAmB,QAAAjB,UACQA,MAAKkB,QAAQC,WAAU,CAACrB,cAAcF,OAAK,CAClD;AAAAa,IAAA,KAAAX;AAAAW,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CAHF,MAAAV,cAAoBkB;CAKnB,IAAAG;AAAA,KAAAX,EAAA,OAAAV,eAAAU,EAAA,OAAAX,eAAA;AAGOsB,OAAA;GAAAtB;GAAAC;GAGN;AAAAU,IAAA,KAAAV;AAAAU,IAAA,KAAAX;AAAAW,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAJF,MAAAY,QACQD;CAKP,IAAAE;AAAA,KAAAb,EAAA,OAAAN,YAAAM,EAAA,QAAAY,OAAA;AAEMC,OAAA,oBAAA,qBAAA;GAAsCD;GAAQlB;IAAyC;AAAAM,IAAA,KAAAN;AAAAM,IAAA,MAAAY;AAAAZ,IAAA,MAAAa;OAAAA,MAAAb,EAAA;AAAA,QAAvFa;;;;;;AAmBR,SAAOI,2BAAA;AAAA,QACCrC,WAAWY,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChGxC,SAAgBsC,mBAAiBC,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;;;;;;;;;AAcvB,MAAMC,aAGDrB,MAAK4B,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAR,MAAAC,aAAAK;CAGI,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,SAEA;IAGD,MAAAC,aAAiB;KAAAP;KAAAQ,UAENP,KAAIC,KAAM,GAAGF;KAASS,UACtBzB,KAAIe;KAAUI;KAAAC;KAGxB;AAA2B,WAGrB,IAAI3C,aAAa;KAAAY,QACfD,mBAAiBC,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,IAAI3C,aAAa;KAAAY,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;AAxDD/B,kBAAiBoD,GAwDf;AAAA,QAEK;EACN;;;;;;;;;;AAWF,MAAMS,wBAED3D,MAAK4B,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAR,SAAAM;CAKI,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;AALD/B,kBAAiBsC,GAKf;AAAA,QAEK;EACN;;;;;;;AAYF,MAAawB,wBAAsB;CAAA,MAAA/B,IAAAC,EAAA,GAAA;CAClC,MAAA,EAAA+B,OAAAtC,aAA4BrB,aAAa;CACzC,MAAA4D,eAAqB3D,yBAAyB;CAC9C,MAAA4D,gBAAsB3D,0BAA0B;CAAA,IAAAwB;AAAAoC,MAAA;AAI/C,MAAI,CAACD,eAAa;AACjBX,WAAOa,MAAO,mEAAmEJ,MAAK/C,IAAKoD,SAAY,CAAC;AACxGtC,QAAOiC;AAAP,SAAAG;;EACA,IAAAG;AAAA,MAAAtC,EAAA,OAAAkC,iBAAAlC,EAAA,OAAAgC,OAAA;AACDM,cAAiBJ,cAAaK,YAAaP,MAAM;GACjD,MAAAQ,WAAiBR,MAAKS,QAAQC,QAAK,CAACJ,SAAQK,SAAUC,IAAE,CAAC;AACzD,OAAIJ,SAAQK,SAAU,EACrBtB,SAAOa,MAAO,qCAAqCI,SAAQvD,IAAK6D,SAAY,CAAC;AAE9EvB,WAAOa,MAAO,gDAAgDE,SAAQrD,IAAK8D,SAAY,CAAC;AAAA/C,KAAA,KAAAkC;AAAAlC,KAAA,KAAAgC;AAAAhC,KAAA,KAAAsC;QAAAA,YAAAtC,EAAA;AACxFD,OAAOuC;;CAXR,MAAAU,eAAqBjD;CAYK,IAAAG;AAAA,KAAAF,EAAA,OAAAN,YAAAM,EAAA,OAAAiC,gBAAAjC,EAAA,OAAAgD,cAAA;EAAA,IAAA5C;AAAA,MAAAJ,EAAA,OAAAN,YAAAM,EAAA,OAAAiC,cAAA;AAIN7B,WAAAX,SAAA;AAIjB,QAFsBwC,cAAYiB,iBAAmBzD,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,KAAAI;QAAAA,QAAAJ,EAAA;AATAE,OAAA8C,aAAY/D,IAAKmB,KAShB;AAAAJ,IAAA,KAAAN;AAAAM,IAAA,KAAAiC;AAAAjC,IAAA,KAAAgD;AAAAhD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,QAAAE,IAAA;AAVHE,OAAA,0CACEF,KAUC;AAAAF,IAAA,MAAAE;AAAAF,IAAA,MAAAI;OAAAA,MAAAJ,EAAA;AAAA,QAXHI;;AArHQ,SAAAW,SAAA7B,KAAA;AAAA,QAmBJA,IAACC,SAAU,UAAU,OAAOD,IAACE,SAAU,YAAYF,IAACE,KAAKuD,SAAU,oBAAoB;;AA6E1D,SAAAN,SAAAO,GAAA;AAAA,QAQgEA,EAACjD;;AARjE,SAAAmD,SAAAK,KAAA;AAAA,QAcqCP,IAACjD;;AAdtC,SAAAoD,SAAAK,KAAA;AAAA,QAgB+CR,IAACjD;;;;;AC5KnF,MAAMyE,uBAAuBf,cAAgD,KAAK;AAOlF,MAAamB,yBAAwDC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAL,OAAAC,aAAAE;CAAmB,IAAAG;AAAA,KAAAF,EAAA,OAAAH,YAAAG,EAAA,OAAAJ,OAAA;AACjFM,OAAA,oBAAA,qBAAA;GAAsCN;GAAQC;IAAyC;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAJ;AAAAI,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAvFE;;AAWR,SAAOI,2BAAA;AAAA,QACC1B,WAAWc,qBAAqB;;;;;;;;;;;;;;;;;;;;;;ACZxC,SAAgBc,iBAAiBC,MAAcC,cAAc,OAAe;CAC3E,MAAMC,iBAAiBJ,0BAA0BE,KAAK;CAGtD,MAAMG,QAAQD,eACZE,QAAQ,mBAAmB,QAAQ,CACnCA,QAAQ,MAAM,IAAI,CAClBC,aAAa,CACbC,MAAM,IAAI;AAEZ,KAAIH,MAAMI,WAAW,EAAG,QAAOL;AAE/B,KAAID,aAAa;EAEhB,MAAMO,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,wBAAsB;;;;;;;;;;;;;;;;;;;;AC9BnC,SAAgBqB,YAAYC,UAA8B;CACzD,MAAMC,OAAON,0BAA0BK,SAAS,CAACE,aAAa;AAG9D,KACCD,KAAKE,SAAS,SAAS,IACvBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,CAErB,QAAOb;AAIR,KACCW,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,MAAM,IACpBF,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,OAAO,CAErB,QAAOlB;AAIR,KACCgB,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,SAAS,IACvBF,KAAKE,SAAS,MAAM,IACpBF,KAAKE,SAAS,SAAS,CAEvB,QAAOd;AAIR,KAAIY,KAAKE,SAAS,SAAS,IAAIF,KAAKE,SAAS,SAAS,IAAIF,KAAKE,SAAS,QAAQ,CAC/E,QAAOZ;AAIR,KAAIU,KAAKE,SAAS,WAAW,IAAIF,KAAKE,SAAS,OAAO,IAAIF,KAAKE,SAAS,OAAO,CAC9E,QAAOf;AAIR,KACCa,KAAKE,SAAS,QAAQ,IACtBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,OAAO,IACrBF,KAAKE,SAAS,QAAQ,CAEtB,QAAOhB;AAIR,KAAIc,KAAKE,SAAS,aAAa,IAAIF,KAAKE,SAAS,WAAW,IAAIF,KAAKE,SAAS,UAAU,CACvF,QAAOnB;AAIR,QAAOQ;;;;;;;;;;;;;;;;;AC9DR,SAAS4F,iBAAiBD,QAA2C;AACpE,QACC,OAAOA,WAAW,YAClBA,WAAW,QACX,cAAcA,UACbA,OAA0BD,aAAa,QACxC,YAAYC;;;;;;AAQd,SAASE,eAAeF,QAA0B;AAEjD,KAAI,OAAOA,WAAW,YAAYA,WAAWP,sBAC5C,QAAO;AAGR,KACC,OAAOO,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,IAAAtC,EAAA,GAAA;CAAC,MAAA,EAAAoC,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,gEAAgE;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAF,UAAA;AAE3CM,OAAAxB,iBAAiBkB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAI,IAAA;AADnEC,OAAA,oBAAA,oBACC,oBAAA;GAAkB,WAAA;aAAsBD;IACzC,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,IAAAtC,EAAA,GAAA;CAAC,MAAA,EAAAoC,UAAAU,iBAAAC,WAAAE,WAAAC,QAAAC,gBAAAd;CACL,MAAA,CAAAe,WAAAC,gBAAkC5C,SAAoC,KAAK;CAAA,IAAA8B;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,gEAAgE;AAAAH,KAAA,KAAAE;AAAAF,KAAA,KAAAG;QAAAA,QAAAH,EAAA;EAAA,IAAAI;AAAA,MAAAJ,EAAA,OAAAF,UAAA;AAE3CM,UAAAxB,iBAAiBkB,SAAS;AAAAE,KAAA,KAAAF;AAAAE,KAAA,KAAAI;QAAAA,QAAAJ,EAAA;EAAA,IAAAK;AAAA,MAAAL,EAAA,OAAAI,MAAA;AADnEC,UAAA,oBAAA,oBACC,oBAAA;IAAkB,WAAA;cAAsBD;KACzC,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,OAAAzB,GAAG,4CAA4C,iBAAiB;AAAAsB,IAAA,MAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,QAAAE,UAAA;AAI7EE,OAAA,oBAAC,YAAmB,WAAA,4CAA4C;AAAAJ,IAAA,MAAAE;AAAAF,IAAA,MAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,QAAAgB,OAAAC,IAAA,4BAAA,EAAA;AAChEZ,OAAA,oBAAC,iBAAwB,WAAA,iFAAiF;AAAAL,IAAA,MAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,QAAAI,IAAA;AAF3GE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAL,IAAA,MAAAI;AAAAJ,IAAA,MAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,QAAAF,UAAA;AAC0DoB,OAAAtC,iBAAiBkB,SAAS;AAAAE,IAAA,MAAAF;AAAAE,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,QAAAkB,IAAA;AAA1FC,OAAA,oBAAA;GAAgB,WAAA;aAAgDD;IAAkC;AAAAlB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,QAAAM,MAAAN,EAAA,QAAAmB,IAAA;AALnGC,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;aAA+DA;IAC9E;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;cACb9C,WAAW8B,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,sCAAA;CAAmF,IAAAe;AAAA,KAAA7B,EAAA,QAAA4B,KAAA;AAJzEC,QAAAnD,GACV,mHACA,uDACA,wCACAkD,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,0CAA0C;AAAA9B,IAAA,MAAA8B;OAAAA,OAAA9B,EAAA;CAAA,IAAA+B;AAAA,KAAA/B,EAAA,QAAAY,UAAAZ,EAAA,QAAA6B,KAAA;AAZxDE,QAAA,qBAAA;GACM,MAAA;GACInB,SAAAA;GACK,cAAAc;GACA,cAAAC;GACH,WAAAE;cAOXC,KAAuD;IAE/C;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,qBAAA;CAAuE,IAAAqB;AAAA,KAAAnC,EAAA,QAAAkC,KAAA;AAJ7DC,QAAAzD,GACV,mHACA,4CACA,wCACAwD,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,0CAA0C;AAAApC,IAAA,MAAAoC;OAAAA,OAAApC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,QAAAW,aAAAX,EAAA,QAAAmC,KAAA;AAZ5DE,QAAA,qBAAA;GACM,MAAA;GACI1B,SAAAA;GACK,cAAAqB;GACA,cAAAC;GACH,WAAAE;cAOXC,KAA2D;IAEnD;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,IAAAtC,EAAA,GAAA;CAAC,MAAA,EAAAoC,UAAA4C,UAAAtD,WAAAW;CACL,MAAA,CAAA4C,YAAAC,iBAAoCzE,SAAS,MAAM;CAAA,IAAA8B;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,+CAA+C;AAAAJ,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AACnEZ,OAAA,oBAAC,SAAgB,WAAA,oFAAoF;AAAAL,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAI,IAAA;AAFtGE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAL,IAAA,KAAAI;AAAAJ,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,OAAAF,UAAA;AAEJoB,OAAAtC,iBAAiBkB,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,oBAAA;GAAgB,WAAA;aACduB,aACA,oBAAC,iBAAwB,WAAA,8CAGzB,GADA,oBAAC,mBAA0B,WAAA,8CAC5B;IACM;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;AAlBRC,OAAA,qBAAA;GACM,MAAA;GACI,SAAAlB;GACC,WAAA;;IAEVG;IAIAa;IAGAC;;IAOQ;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;eAAoG;MAGnH,sBAAA;KAAe,WAAA;eACbA;MAEH;KACD,EAGCtD,WAAWyD,UACX,qBAAA,oBACC,oBAAA;IAAe,WAAA;cAAoG;KAGnH,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;AAlDFK,QAAA,qBAAA;GAAe,WAAA;cAEdL,IAsBCC;IA2BI;AAAAtB,IAAA,MAAAsB;AAAAtB,IAAA,MAAAqB;AAAArB,IAAA,MAAA0B;OAAAA,OAAA1B,EAAA;AAAA,QAnDN0B;;;;;AA0DF,MAAMsB,oBAGDjD,OAAA;CAAA,MAAAC,IAAAtC,EAAA,GAAA;CAAC,MAAA,EAAAoC,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,+CAA+C;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AACnEb,OAAA,oBAAC,eAAsB,WAAA,oFAAoF;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,IAAA;AAF5GE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAJ,IAAA,KAAAG;AAAAH,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAF,UAAA;AAEJQ,OAAA1B,iBAAiBkB,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;cAA+EA;KAC/F;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,IAAAtC,EAAA,GAAA;CAAC,MAAA,EAAAoC,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,kDAAkD;AAAAH,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAgB,OAAAC,IAAA,4BAAA,EAAA;AACtEb,OAAA,oBAAC,KAAY,WAAA,uFAAuF;AAAAJ,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,IAAA;AAFrGE,OAAA,qBAAA;GAAe,WAAA;cACdF,IACAC;IACK;AAAAJ,IAAA,KAAAG;AAAAH,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAAA,IAAAM;AAAA,KAAAN,EAAA,OAAAF,UAAA;AAEsCQ,OAAA1B,iBAAiBkB,SAAS;AAAAE,IAAA,KAAAF;AAAAE,IAAA,KAAAM;OAAAA,MAAAN,EAAA;CAAA,IAAAkB;AAAA,KAAAlB,EAAA,OAAAM,IAAA;AADtEY,OAAA,qBAAA,qBACC,oBAAA;GAAkB,WAAA;aAAyBZ;IAAoC,eACzE;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,UAAUlF,aAAa;CACzC,MAAMmF,eAAejF,yBAAyB;CAC9C,MAAMkF,gBAAgBjF,0BAA0B;CAChD,MAAM,CAACoC,aAAa8C,kBAAkBxF,SAAS,MAAM;CAGrD,MAAMyF,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,MAAMG,mBAAmBlF,0BAA0Be,SAAS;CAC5D,MAAMoE,eAAeR,eAAeS,gBAAgBrE,SAAS;CAC7D,MAAMsE,YAAYZ,MAAMa,MAAMC,MAAMA,EAAEC,SAASN,iBAAiB;CAChE,MAAMzD,kBAAkB0D,cAAcM,eAAeJ,WAAWI;CAChE,MAAMC,kBAAkBP,cAAcQ,eAAeN,WAAWM;CAChE,MAAMC,mBAAmBlB,eACtBA,aAAamB,SAAS,UAAU9F,kBAAkB2F,gBAAgB,GAClEjF,OAAOC,SAAS;CACnB,MAAMoF,cAAcnB,eAAemB,eAAetB;CAMlD,MAAMuB,gBAAgB7G,YAAY,YAAY;AAC7C0F,iBAAe,KAAK;AACpB,MAAI;GACH,MAAMoB,aAAa,MAAMF,YAAY/E,UAAU8D,WAAW;AAI1DN,aACC,IAAIlF,aAAa;IAChBgB,QALiBb,mBAAiBwG,WAAW;IAM7CE,SAASF,WAAWE,YAAY;IAChC,CACF,CAAC;WACOvF,OAAO;AAEf4D,aACC,IAAIlF,aAAa;IAChBgB,QAHmBM,iBAAiByF,QAAQzF,MAAM0F,UAAUC,OAAO3F,MAAM;IAIzEuF,SAAS;IACT,CACF,CAAC;YACQ;AACTtB,kBAAe,MAAM;;IAEpB;EAAC7D;EAAU8D;EAAYiB;EAAavB;EAAU,CAAC;CAGlD,MAAMgC,aAAarH,kBAAkB;AACpCqF,YAAUzE,sBAAoB;IAC5B,CAACyE,UAAU,CAAC;CAGf,MAAMiC,aAAa/F,OAAOC;CAG1B,MAAM+F,oBAAoBpG,WAAWyD,UAAa8B;CAGlD,MAAMc,qBAAqBpH,gBAAgBmH,mBAAmB,IAAI;AAKlE,KAAIA,mBAAmB;AAEtB,MAAI,CAACC,mBACJ,QAAO,oBAAC,sBAA6B3F,WAAY;AAElD,SACC,oBAAC;GACUA;GACOU;GACjB,WAAWoD;GACX,WAAWkB;GACX,QAAQQ;GACKzE;IACZ;;AAKJ,KAAIvB,eAAeF,OAAO,CACzB,QAAO,oBAAC,qBAA4BU,WAAY;AAIjD,KAAIyF,eAAe,UAClB,QAAO,oBAAC,sBAA6BzF,WAAY;AAIlD,KAAIyF,eAAe,gBAAgBhG,eAAeC,OAAO,CAExD,QAAO,oBAAC;EAA2BM;EAAU,OADxBP,eAAeC,OAAO,GAAGA,OAAOE,QAAQ;GACO;AAKrE,KAAI6F,eAAe,cAAenG,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;;AAGlD,kCAAeoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjZf,SAAOqD,aAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CACN,MAAAC,WAAiBd,qBAAqB;CAAA,IAAAe;AAAA,KAAAH,EAAA,OAAAE,UAAAV,SAAA;AAEtBW,OAAAD,UAAQV,WAAR,EAAuB;AAAAQ,IAAA,KAAAE,UAAAV;AAAAQ,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAAvC,MAAAR,UAAgBW;CAChB,MAAAV,aAAmBD,QAAOY,SAAU;CAAC,IAAAC;AAAA,KAAAL,EAAA,OAAAE,UAAA;AAGpCG,OAAA,OAAAV,MAAAC,SAAA;AACC,OAAI,CAACM,UAAQR,UACZ,OAAM,IAAIY,MAAM,wDAAwD;AACxE,UACMJ,SAAQR,UAAWC,MAAMC,KAAK;;AACrCI,IAAA,KAAAE;AAAAF,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CANF,MAAAN,YAAkBW;CAQjB,IAAAE;AAAA,KAAAP,EAAA,OAAAN,aAAAM,EAAA,OAAAP,cAAAO,EAAA,OAAAR,SAAA;AAEMe,OAAA;GAAAf;GAAAC;GAAAC;GAIN;AAAAM,IAAA,KAAAN;AAAAM,IAAA,KAAAP;AAAAO,IAAA,KAAAR;AAAAQ,IAAA,KAAAO;OAAAA,MAAAP,EAAA;AAAA,QAJMO;;;;;ACpDR,MAAMa,uBAAuBZ,cAAgD,KAAK;AAOlF,MAAagB,yBAAwDC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAL,OAAAC,aAAAE;CAAmB,IAAAG;AAAA,KAAAF,EAAA,OAAAH,YAAAG,EAAA,OAAAJ,OAAA;AACjFM,OAAA,oBAAA,qBAAA;GAAsCN;GAAQC;IAAyC;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAJ;AAAAI,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAAvFE;;AAWR,SAAOI,2BAAA;AAAA,QACCvB,WAAWW,qBAAqB;;;;;;;;;;;;;;ACDxC,SAAgBqB,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;;;;;;;;;AC3JR,IAAaI,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;;AAIDC,UAAQC,IAAI,oCAAoCL,IAAIvB,KAAK;AAGzD,UAAQuB,IAAIvB,MAAZ;GACC,KAAK;AACJ,SAAK6B,sBAAsBN,IAAI;AAC/B;GAED,KAAK;AACJ,UAAM,KAAKO,mBAAmBP,KAAKH,YAAY;AAC/C;GAED,KAAK;AACJ,SAAKW,6BAA6B;AAClC;GAED,KAAK;GACL,KAAK;AACJ,SAAKC,mBAAmBT,IAAI;AAC5B;GAGD,KAAK;GACL,KAAK;AACJ,SAAKU,kBAAkBV,IAAI;AAC3B;GAGD,KAAK;GACL,KAAK;GAEL,KAAK;GACL,KAAK;AACJ,SAAKW,uBAAuBX,IAAI;AAChC;GAED,KAAK;AACJ,SAAKY,qBAAqBZ,IAAI;AAC9B;GAED,KAAK;AACJ,SAAKa,YAAYb,IAAI;AACrB;GAED,KAAK;GACL,KAAK;AACJ,SAAKc,oBAAoBd,IAAI;AAC7B;GAED,KAAK;GACL,KAAK,+BAEJ;GAED;AACCI,YAAQC,IAAI,0CAA0CL,IAAIvB,MAAMuB,IAAI;AACpE;;;CAIH,AAAQM,sBAAsBS,MAA6B;AAC1D,OAAK9B,uBAAuB;AAC5B,OAAKM,uBAAuB;;CAG7B,MAAcgB,mBACbP,KACAH,aACgB;EAEhB,MAAMmB,cAAc,KAAKC,sBAAsBjB,IAAIkB,SAAS;AAM5D,MAAI,CAHqBF,YAAYI,KAAKtC,wBAAwB,EAG3C;AACtB,QAAKG,uBAAuB;AAC5B,QAAKM,uBAAuB;;AAI7B,MAAIyB,YAAYK,SAAS,GAAG;GAE3B,MAAMC,gBAAgCN,YACpCO,OAAOzC,wBAAwB,CAC/B0C,KAAKzC,UAAU;IACfJ,MAAMI,KAAKJ;IACXC,SAASG,KAAKH;IACdC,WAAWE,KAAKF,aAAa;IAC7B,EAAE;AAEJ,QAAK,MAAM4C,gBAAgBH,cAC1B,KAAI,CAAC,KAAKpC,qBAAqBwC,IAAID,aAAa7C,QAAQ,EAAE;AACzD,SAAKM,qBAAqByC,IAAIF,aAAa7C,QAAQ;AACnD,UAAM,KAAKgD,oBAAoBH,cAAc5B,YAAY;SAEzDO,SAAQyB,KACP,sDAAsDJ,aAAa9C,KAAI,IAAK8C,aAAa7C,QAAO,GAChG;AAKH,OAAI0C,cAAcD,SAAS,KAAK,KAAKnC,qBAAqB4C,SAAS,EAClE,MAAKC,wBAAwBlC,YAAY;;;;;;CAQ5C,AAAQoB,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,QACdxC,SACAA,SAAS,QACT,OAAOA,SAAS,YAChB,OAAQA,KAA4BN,SAAS,SAC9C;;CAGF,AAAQ+B,8BAAoC;CAK5C,AAAQC,mBAAmBT,KAA4B;EACtD,MAAMqC,YACLrC,IAAIvB,SAAS,sCAAsC,mBAAmB;AACvE,OAAKiB,aAAa4C,KAAKD,WAAWrC,IAAI;;CAGvC,AAAQU,kBAAkBV,KAA4B;EACrD,MAAMqC,YAAYrC,IAAIvB,SAAS,gCAAgC,kBAAkB;AACjF2B,UAAQC,IAAI,8BAA8BgC,aAAa;GACtD5D,MAAMuB,IAAIvB;GACV8D,UAAU,CAAC,CAAEvC,IAA4BwC;GACzC,CAAC;AACF,OAAK9C,aAAa4C,KAAKD,WAAWrC,IAAI;;CAGvC,AAAQW,uBAAuBX,KAA4B;EAS1D,MAAMqC,YAPmC;GACxC,mCAAmC;GACnC,kCAAkC;GAClC,uBAAuB;GACvB,sBAAsB;GACtB,CAE0BrC,IAAIvB;AAC/B2B,UAAQC,IAAI,sCAAsCL,IAAIvB,MAAM;GAC3D4D;GACAG,OAAQxC,IAA2BwC;GACnCE,YAAa1C,IAAgC0C;GAC7C,CAAC;AACF,MAAIL,UACH,MAAK3C,aAAa4C,KAAKD,WAAWrC,IAAI;;CAIxC,AAAQY,qBAAqBZ,KAA4B;AACxD,OAAKN,aAAa4C,KAAK,wBAAwB,EAAEK,MAAM3C,IAAI0C,YAAY,CAAC;;CAGzE,AAAQ5B,oBAAoBd,KAA4B;EAEvD,MAAM4C,UAAU5C,IAAI4C;AACpB,MAAIA,SAAS;GACZ,MAAMC,QAAQD,QAAQC;AACtBzC,WAAQC,IAAI,mCAAmCL,IAAIvB,MAAM;IACxDqE,WAAWD,OAAOxB,UAAU;IAC5B0B,WAAWF,OAAOG,MAAM,GAAG,EAAE,CAACxB,KAAKyB,MAAOA,EAAwBtE,KAAK;IACvEuE,wBAAwB,CAAC,CAACN,QAAQO;IAClCC,uBAAuB,CAAC,CAACR,QAAQS;IACjC,CAAC;;;CAIJ,AAAQxC,YAAYb,KAA4B;AAC/CI,UAAQD,MAAM,uBAAuBH,IAAI;AACzC,OAAKN,aAAa4C,KAAK,SAAStC,IAAI;AACpC,OAAKf,uBAAuB;AAC5B,OAAKM,uBAAuB;AAG5B,MAAI,KAAKH,sBAAsB;AAC9BkE,gBAAa,KAAKlE,qBAAqB;AACvC,QAAKA,uBAAuB;;;CAI9B,MAAcwC,oBACbH,cACA5B,aACgB;EAChB,MAAM,EAAElB,MAAMC,YAAY6C;AAE1B,MAAI;AAEH,QAAK/B,aAAa4C,KAAK,qBAAqB,EAAE3D,MAAM,CAAC;GAGrD,MAAM4E,SAAS,MAAM,KAAK9D,YAAY+D,gBAAgB/B,aAAa;AAGnE,OAAI5B,YAAY4D,eAAe,QAAQ;AACtCrD,YAAQD,MACP,gDAAgDxB,KAAI,mBAAoBkB,YAAY4D,aACpF;AACD,SAAK/D,aAAa4C,KAAK,uBAAuB;KAC7C3D;KACAwB,OAAO;KACP,CAAC;AACF;;GAID,MAAMe,WAAW;IAChBzC,MAAM;IACNM,MAAM;KACLN,MAAM;KACGG;KACTwD,QAAQnC,KAAKyD,UACZH,OAAOI,UACJJ,OAAO3D,OACP;MACAO,OAAOoD,OAAOpD;MACdwD,SAAS;MAEb,CAAA;KACD;IACA;AAED9D,eAAY+D,KAAK3D,KAAKyD,UAAUxC,SAAS,CAAC;AAG1C,QAAKxB,aAAa4C,KAAK,uBAAuB;IAC7C3D;IACAwB,OAAOoD,OAAOI,UAAUE,SAAYN,OAAOpD;IAC3C,CAAC;WACMA,OAAO;AACfC,WAAQD,MAAM,8CAA8CxB,KAAI,IAAKwB,MAAM;AAC3E,QAAK2D,cAAclF,SAASmF,OAAO5D,MAAM,EAAEN,YAAY;YAC9C;AACT,QAAKX,qBAAqB8E,OAAOpF,QAAQ;AAGzC,OAAI,KAAKM,qBAAqB4C,SAAS,GAAG;AAEzC,SAAK7C,uBAAuB;AAC5B,SAAKM,uBAAuB;AAC5B,SAAKwC,wBAAwBlC,YAAY;;;;CAK5C,AAAQiE,cAAclF,SAAiBuB,OAAeN,aAAmC;AAExF,MAAIA,YAAY4D,eAAe,QAAQ;AACtCrD,WAAQD,MACP,2DAA2DN,YAAY4D,aACvE;AACD;;EAGD,MAAMQ,gBAAgB;GACrBxF,MAAM;GACNM,MAAM;IACLN,MAAM;IACGG;IACTwD,QAAQnC,KAAKyD,UAAU;KAAEvD;KAAOwD,SAAS;KAAO,CAAA;IACjD;GACA;AAED9D,cAAY+D,KAAK3D,KAAKyD,UAAUO,cAAc,CAAC;;CAGhD,AAAQlC,wBAAwBlC,aAAmC;AAElE,MAAI,KAAKT,sBAAsB;AAC9BkE,gBAAa,KAAKlE,qBAAqB;AACvC,QAAKA,uBAAuB;;AAI7B,OAAKA,uBAAuBE,iBAAiB;AAC5C,OACC,CAAC,KAAKL,wBACN,CAAC,KAAKM,wBACNM,YAAY4D,eAAe,UAC3B,KAAKvE,qBAAqB4C,SAAS,GAClC;AACD,SAAKvC,uBAAuB;AAC5B,SAAKN,uBAAuB;AAC5BY,gBAAY+D,KAAK3D,KAAKyD,UAAU,EAAEjF,MAAM,mBAAmB,CAAC,CAAC;;AAE9D,QAAKW,uBAAuB;KAC1BjB,0BAA0B;;CAG9B+F,QAAc;AACb,OAAKjF,uBAAuB;AAC5B,OAAKM,uBAAuB;AAC5B,OAAKL,qBAAqBiF,OAAO;AAGjC,MAAI,KAAK/E,sBAAsB;AAC9BkE,gBAAa,KAAKlE,qBAAqB;AACvC,QAAKA,uBAAuB;;;;;;;AC3W/B,IAAa4F,cAAb,MAAyB;CACxB,AAAQC,QAA0B,EAAE;CACpC,AAAQC,WAAgC;CACxC,AAAQC,wBAAwB;CAEhCC,SAASH,OAA+B;AACvCI,UAAQC,IACP,kCACAL,MAAMM,QACN,UACA,cACA,KAAKC,iBAAiBP,MAAM,CAACQ,MAAM,GAAG,IACvC,CAAC;AACD,OAAKR,QAAQA;;CAGdS,YAAYR,UAA8B;AACzC,OAAKA,WAAWA;;CAGjBS,eAAqB;AACpBN,UAAQC,IAAI,sEAAsE;;CAGnF,AAAQE,iBAAiBP,OAAiC;AACzD,SAAOA,MACLW,KAAKC,MAAMA,EAAEpB,KAAK,CAClBqB,MAAM,CACNC,KAAK,IAAI;;CAGZC,kBAA2B;EAC1B,MAAMC,mBAAmB,KAAKT,iBAAiB,KAAKP,MAAM;EAC1D,MAAMiB,UAAUD,qBAAqB,KAAKd;AAC1CE,UAAQC,IAAI,kCAAkCY,SAAS;GACtDC,wBAAwBF,iBAAiBV;GACzCa,yBAAyB,KAAKjB,sBAAsBI;GACpDc,gBAAgBJ,iBAAiBR,MAAM,GAAG,GAAG;GAC7Ca,iBAAiB,KAAKnB,sBAAsBM,MAAM,GAAG,GAAE;GACvD,CAAC;AACF,SAAOS;;CAGRK,gBAAsB;AACrB,OAAKpB,wBAAwB,KAAKK,iBAAiB,KAAKP,MAAM;;CAG/DuB,uBAAqC;EAEpC,MAAMC,eAA6B,CAClC;GACCC,MAAM;GACNjC,MAAM;GACNC,aACC;GACDiC,YAAY;IACXD,MAAM;IACNE,YAAY,EAAE;IACdC,UAAU,EAAA;IACX;GACA,CACD;EAGD,MAAMC,kBAAkB,KAAK7B,MAAMW,KAAKmB,UAAU;GACjDL,MAAM;GACNjC,MAAMsC,KAAKtC;GACXC,aAAaqC,KAAKrC,eAAe,WAAWqC,KAAKtC,KAAI;GACrDkC,YAAY,KAAKM,mBAAmBF,KAAKpC,YAAW;GACpD,EAAE;AAEH,SAAO,CAAC,GAAG8B,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,CACDd,KAAK,CAACgC,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;AAChB3C,YAAQ4C,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,EAAE1D,MAAM2D,WAAWC,eAAeF;AAGxC,MAAI1D,SAAS,uBACZ,QAAO,KAAK6D,kBAAkB;AAI/B,MAAI,CAAC,KAAKpD,UAAU;AACnBG,WAAQkD,MAAM,6CAA6C;AAC3D,UAAO;IAAEC,SAAS;IAAOD,OAAO;IAAgC;;EAIjE,IAAIzD;AACJ,MAAI;GACH,MAAM2D,WAAWJ,aAAajE,WAAWiE,WAAW,GAAG;AACvDvD,UAAO4D,KAAKC,MAAMF,SAAS;WACnBF,OAAO;AACflD,WAAQkD,MAAM,4CAA4CA,MAAM;AAChElD,WAAQkD,MAAM,iCAAiCF,YAAY5C,MAAM,GAAG,IAAI,CAAC;AACzE,UAAO;IAAE+C,SAAS;IAAOD,OAAO;IAA4B;;AAQ7D,MAAI;AAEH,UAAO;IAAEC,SAAS;IAAMI,MADT,MAAM,KAAK1D,SAAST,MAAMK,KAAK;IACR;WAC9ByD,OAAO;AACflD,WAAQkD,MAAM,0CAA0C9D,KAAI,IAAK8D,MAAM;AACvE,UAAO;IAAEC,SAAS;IAAOD,OAAOM,OAAON,MAAK;IAAG;;;CAIjD,AAAQD,mBAAwC;EAC/C,MAAMQ,WAAW,KAAK7D,MAAMW,KAAKmB,UAAU;GAC1CtC,MAAMsC,KAAKtC;GACXC,aAAaqC,KAAKrC,eAAe;GACjCiC,YAAYI,KAAKpC,eAAe,EAAC;GACjC,EAAE;AAEH,SAAO;GACN6D,SAAS;GACTI,MAAM;IACL3D,OAAO6D;IACPC,OAAOD,SAASvD;IAChByD,SACCF,SAASvD,SAAS,IACf,SAASuD,SAASvD,OAAM,oBACxB;IACL;GACA;;CAGF0D,oBAAkF;AACjF,MAAI,CAAC,KAAKjD,iBAAiB,CAC1B,QAAO;EAGR,MAAMqD,YAAY,KAAKlE,sBAAsBmE,MAAM,IAAI,CAAC/B,OAAOgC,QAAQ;EACvE,MAAMC,YAAY,KAAKvE,MAAMW,KAAKC,MAAMA,EAAEpB,KAAK;EAE/C,MAAMgF,UAAU,IAAIC,IAAIL,UAAU;EAClC,MAAMM,UAAU,IAAID,IAAIF,UAAU;AAKlC,SAAO;GACNN,OAJaM,UAAUjC,QAAQ9C,SAAS,CAACgF,QAAQG,IAAInF,KAAK,CAAC;GAK3D0E,SAJeE,UAAU9B,QAAQ9C,SAAS,CAACkF,QAAQC,IAAInF,KAAK,CAAC;GAK7D2E,OAAO,KAAKnE,MAAMM;GAClB;;;;;;ACnPH,SAAS+E,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;AACvCC,UAAQC,IACP,gDACAF,MAAMG,QACN,UACAH,MAAMI,MAAM,GAAG,EAAE,CAACC,KAAKC,MAAMA,EAAEC,KAAK,CAACC,KAAK,KAAK,EAC/CR,MAAMG,SAAS,IAAI,WAAWH,MAAMG,SAAS,EAAC,SAAU,GACxD;AACD,OAAKlB,YAAYc,SAASC,MAAM;AAChC,MAAI,KAAKS,iBAAiB,EAAE;AAC3BR,WAAQC,IAAI,4DAA4D;AACxE,QAAKQ,oBAAoB;QAEzBT,SAAQC,IAAI,0FAA0F;;;;;CAOxGS,gBAAgBC,UAA8B;AAC7C,OAAK3B,YAAY4B,YAAYD,SAAS;;;;;CAMvCE,eAAeC,UAA4B;AAC1C,OAAKnB,yBAAyBmB;;;;;CAM/B,MAAMC,aAAaC,SAAyB,EAAE,EAA4B;AACzE,MAAI;AAEH,OAAI,KAAKlC,QACR,MAAKoC,aAAa;AAGnB,QAAK/B,QAAQ;AACb,QAAKO,mBAAmByB,KAAKC,KAAK;AAClC,QAAKC,iBAAiB,aAAa;AAGnC,QAAKvC,UAAU,MAAM,KAAKC,cAAcuC,cAAcN,OAAO;AAG7D,QAAKO,iBAAiB,KAAKzC,QAAQ0C,YAAY;AAG/C,QAAKC,8BAA8B,KAAK3C,QAAQ4C,GAAG;AAEnD,OAAI,KAAK5C,QAAQ6C,YAChB,OAAM,KAAKC,wBAAwB,KAAK9C,QAAQ6C,YAAY;AAG7D,OAAI,KAAK7C,QAAQ+C,aAChB,CAAK,KAAKC,yBAAyB,KAAKhD,QAAQ+C,aAAa;GAI9D,MAAME,kBAAkB,KAAKjD,QAAQ4C,GAAGM;GACxC,MAAMlD,UAAU,KAAKA;AACrB,QAAKA,QAAQ4C,GAAGM,WAAWC,MAAM;AAChC,QAAIF,gBAAiBA,iBAAgBG,KAAKpD,QAAQ4C,IAAIO,EAAE;AACxD,QAAI,KAAKnD,QACR,MAAKA,QAAQ+C,eAAeI,EAAEE,QAAQ;IAGvC,MAAMN,eAAeI,EAAEE,QAAQ;AAC/B,QAAI,CAACN,cAAc;AAClB7B,aAAQoC,KAAK,gEAAgE;AAC7E;;AAGD,IAAK,KAAKN,yBAAyBD,aAAa;;AAGjD,UAAO,KAAK/C;WACJuD,OAAO;AACf,QAAKC,mBAAmBD,MAAM;AAC9B,SAAMA;;;;;;CAORnB,cAAoB;EAEnB,IAAIqB,kBAAkB;AACtB,MAAI,KAAK7C,iBACR6C,mBAAkBC,KAAKC,OAAOtB,KAAKC,KAAK,GAAG,KAAK1B,oBAAoB,IAAK;AAG1E,MAAI,KAAKH,uBAAuB;AAC/BmD,iBAAc,KAAKnD,sBAAsB;AACzC,QAAKA,wBAAwB;;AAG9B,MAAI,KAAKF,eAAe;AACvB,QAAKA,cAAcsD,SAAS;AAC5B,QAAKtD,gBAAgB;;AAGtB,MAAI,KAAKC,gBAAgB;AACxB,QAAKA,eAAeqD,SAAS;AAC7B,QAAKrD,iBAAiB;;AAEvB,MAAI,KAAKR,SAAS;AACjB,QAAKA,QAAQ8D,SAAS;AACtB,QAAK9D,UAAU;;AAEhB,OAAKG,eAAe4D,OAAO;AAC3B,OAAK7D,YAAY8D,cAAc;AAG/B,OAAK3D,QAAQ;AACb,OAAKkC,iBAAiB,gBAAgB,EAAEkB,iBAAiB,CAAC;AAG1D,OAAK7C,mBAAmB;;;;;CAMzBqD,gBAAgBC,MAAoB;AACnC,MAAI,CAAC,KAAKxC,iBAAiB,CAC1B,OAAM,IAAIyC,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,KAAKlE,QACT,OAAM,IAAImE,MAAM,wBAAwB;AAEzC,OAAKnE,QAAQ0C,YAAY+B,KAAKC,KAAKC,UAAUP,QAAQ,CAAC;AACtD,OAAKpE,QAAQ0C,YAAY+B,KAAKC,KAAKC,UAAU,EAAEN,MAAM,mBAAmB,CAAC,CAAC;;;;;CAM3E3C,kBAA2B;AAC1B,SAAO,KAAK1B,YAAY,QAAQ,KAAKA,QAAQ0C,YAAYkC,eAAe;;;;;CAMzEC,iBAAqC;AACpC,SAAO,KAAK7E,SAAS6C,eAAe;;;;;CAMrCkC,kBAAsC;AACrC,SAAO,KAAK/E,SAAS+C,gBAAgB;;;;;CAMtCiC,WAAW3E,OAAsB;AAChC,MAAI,KAAKL,SAASiF,aACjB,MAAKjF,QAAQiF,aAAa5E,QAAQA;AAEnC,OAAKA,QAAQA;AACb,OAAKkC,iBAAiB,KAAKjC,WAAW,EAAE4E,SAAS,KAAK7E,OAAO,CAAC;;;;;;CAO/D8E,aAAmB;AAClB,MAAI,KAAKnF,SAASiF,aACjB,MAAKjF,QAAQiF,aAAaG,OAAO;;;;;CAOnCC,cAAoB;AACnB,MAAI,KAAKrF,SAASiF,aACjB,MAAKjF,QAAQiF,aAAaK,MAAM,CAACC,OAAOhC,UAAU;AAEjDrC,WAAQoC,KAAK,mDAAmDC,MAAM;IACrE;;;;;CAOJiC,GAAGC,OAAezD,UAA+B;AAChD,OAAK5B,aAAaoF,GAAGC,OAAOzD,SAAS;;CAGtC0D,IAAID,OAAezD,UAA+B;AACjD,OAAK5B,aAAasF,IAAID,OAAOzD,SAAS;;CAGvC2D,mBAIE;AACD,SAAO;GACNC,OAAO,KAAKtF;GACZuF,UAAU,KAAKvF,cAAc;GAC7B4E,SAAS,KAAK7E;GACd;;;;;CAMF,AAAQoC,iBAAiBC,aAAmC;AAE3DA,cAAYqD,iBAAiB,cAAc;AAC1C,QAAKC,iBAAiBtD,YAAY;AAClC,QAAKrC,QAAQ;AACb,QAAKkC,iBAAiB,YAAY;IACjC;AAGFG,cAAYqD,iBAAiB,YAAYN,UAAgC;AACxE,IAAM,YAAY;AACjB,QAAI;AACH,WAAM,KAAKtF,eAAe+F,cAAcT,MAAMU,MAAMzD,YAAY;aACxDa,OAAO;AACfrC,aAAQqC,MAAM,2BAA2BA,MAAM;;OAE7C;IACH;AAGFb,cAAYqD,iBAAiB,UAAUxC,UAAU;AAChDrC,WAAQqC,MAAM,sBAAsBA,MAAM;AAC1C,QAAKnD,aAAagG,KAAK,SAAS;IAAE/B,MAAM;IAAqBd;IAAO,CAAC;IACpE;AAGFb,cAAYqD,iBAAiB,eAAe;AAC3C,QAAK5F,eAAe4D,OAAO;AAC3B,QAAK3D,aAAagG,KAAK,kBAAkB,EAAE,CAAC;IAC3C;;CAGH,AAAQzD,8BAA8BC,IAA6B;AAElEA,KAAGmD,iBAAiB,+BAA+B;AAClD,OAAInD,GAAG0D,oBAAoB,YAAY1D,GAAG0D,oBAAoB,gBAAgB;AAC7EpF,YAAQqC,MAAM,yCAAyC;AACvD,SAAKpD,eAAe4D,OAAO;AAC3B,SAAK3D,aAAagG,KAAK,SAAS;KAC/B/B,MAAM;KACND,SAAS,cAAcxB,GAAG0D;KAC1B,CAAC;;IAEF;AAGF1D,KAAGmD,iBAAiB,kCAAkC;AACrD,OAAInD,GAAG2D,uBAAuB,YAAY3D,GAAG2D,uBAAuB,eACnErF,SAAQqC,MAAM,wCAAwC;IAEtD;AAGFX,KAAGmD,iBAAiB,8BAA8B,GAAG;;CAGtD,AAAQC,iBAAiBtD,aAAmC;AAC3DxB,UAAQC,IAAI,wEAAwE;AAGpF,OAAKjB,YAAY8D,cAAc;EAG/B,MAAM/C,QAAQ,KAAKf,YAAYsG,sBAAsB;AAErD,OAAKtG,YAAYuG,eAAe;AAEhCvF,UAAQC,IACP,+CACAF,MAAMG,QACN,UACAH,MAAMK,KAAKC,MAAMA,EAAEC,KAAK,CAACC,KAAK,KAC/B,CAAC;EAED,MAAMiF,gBAA+B;GACpCC,YAAY,CAAC,QAAQ,QAAQ;GAC7BC,cAAc,KAAKC,wBAAwB;GAC3CC,OAAO;GACA7F;GACP8F,aAAa;GACbC,gBAAgB;IACf3C,MAAM;IACN4C,WAAW;IACXC,mBAAmB;IACnBC,qBAAqB;IACrB;GACDC,2BAA2B,EAC1BC,OAAO,aACP;GACDC,4BAA4B,EAC3BD,OAAO,aACR;GACA;EAED,MAAME,gBAAgB;GACrBlD,MAAM;GACNrE,SAAS0G;GACT;AAEDxF,UAAQC,IAAI,yEAAyEuF,cAAcK,YAAY;AAC/GrE,cAAY+B,KAAKC,KAAKC,UAAU4C,cAAc,CAAC;AAC/CrG,UAAQC,IAAI,sDAAsD;;CAGnE,AAAQQ,qBAA2B;AAClC,MAAI,CAAC,KAAK3B,SAAS;AAClBkB,WAAQoC,KAAK,iEAAiE;AAC9E;;AAGD,MAAI,KAAKtD,QAAQ0C,YAAYkC,eAAe,QAAQ;AACnD1D,WAAQoC,KACP,+DAA+D,KAAKtD,QAAQ0C,YAAYkC,aACxF;AACD;;EAID,MAAM4C,iBAAiB,KAAKtH,YAAYuH,mBAAmB;AAC3D,MAAI,CAACD,gBAAgB;AACpBtG,WAAQC,IAAI,mFAAmF;AAC/F;;EAID,MAAMF,QAAQ,KAAKf,YAAYsG,sBAAsB;AAErDtF,UAAQC,IACP,0DACA,GAAGqG,eAAeE,MAAK,gBACvBF,eAAeG,MAAMvG,SAAS,IAC3B,IAAIoG,eAAeG,MAAMvG,OAAM,UAAWoG,eAAeG,MAAMtG,MAAM,GAAG,EAAE,CAACI,KAAK,KAAK,GAAG+F,eAAeG,MAAMvG,SAAS,IAAI,QAAQ,GAAE,KACpI,IACHoG,eAAeI,QAAQxG,SAAS,IAAI,IAAIoG,eAAeI,QAAQxG,OAAM,YAAa,GAClF;AAGD,OAAKlB,YAAYuG,eAAe;EAEhC,MAAMc,gBAAgB;GACrBlD,MAAM;GACNrE,SAAS;IACDiB;IACP8F,aAAa;IACd;GACA;AAED,OAAK/G,QAAQ0C,YAAY+B,KAAKC,KAAKC,UAAU4C,cAAc,CAAC;;CAG7D,AAAQV,yBAAiC;AACxC,SAAO;;;;;CAMR,AAAQrD,mBAAmBD,OAAsB;AAChDrC,UAAQqC,MAAM,kBAAkBA,MAAM;AACtC,OAAKhB,iBAAiB,SAAS;GAC9B8B,MAAM;GACNd,OAAOsE,OAAOtE,MAAK;GACnB,CAAC;AACF,OAAKnB,aAAa;;CAGnB,MAAcU,wBAAwBgF,QAAoC;AACzE,MAAI,KAAKvH,cACR,MAAKA,cAAcsD,SAAS;AAG7B,OAAKtD,gBAAgB,IAAIzB,eAAe;AACxC,MAAI;GAEH,MAAMiJ,eAAe,IAAIjD,YAAYgD,OAAOE,gBAAgB,CAAC1G,KAAKC,MAAMA,EAAE0G,OAAO,CAAC,CAAC;AACnF,SAAM,KAAK1H,cAAc2H,WAAWH,aAAa;AACjD,QAAKI,yBAAyB;WACtB5E,OAAO;AACfrC,WAAQqC,MAAM,qEAAqEA,MAAM;AACzF,OAAI,KAAKhD,eAAe;AACvB,SAAKA,cAAcsD,SAAS;AAC5B,SAAKtD,gBAAgB;;;;CAKxB,MAAcyC,yBAAyB8E,QAAoC;AAC1E,MAAI,KAAKtH,eACR,MAAKA,eAAeqD,SAAS;AAG9B,OAAKrD,iBAAiB,IAAI1B,eAAe;AACzC,MAAI;GAEH,MAAMiJ,eAAe,IAAIjD,YAAYgD,OAAOE,gBAAgB,CAAC1G,KAAKC,MAAMA,EAAE0G,OAAO,CAAC,CAAC;AACnF,SAAM,KAAKzH,eAAe0H,WAAWH,aAAa;AAClD,QAAKI,yBAAyB;WACtB5E,OAAO;AACfrC,WAAQqC,MAAM,sEAAsEA,MAAM;AAC1F,OAAI,KAAK/C,gBAAgB;AACxB,SAAKA,eAAeqD,SAAS;AAC7B,SAAKrD,iBAAiB;;;;CAKzB,AAAQ2H,0BAAgC;AACvC,MAAI,CAAC,KAAK5H,iBAAiB,CAAC,KAAKC,gBAAgB;AAChD3B,YAAS,yBAAyB,sDAAsD;AACxF;;AAGD,MAAI,KAAK4B,sBACRmD,eAAc,KAAKnD,sBAAsB;EAG1C,IAAI2H,aAAa;AACjB,OAAK3H,wBAAwBE,kBAAkB;GAC9C,MAAM0H,WAAW,KAAK9H,eAAe+H,eAAe,IAAI;GACxD,MAAMC,eACL,KAAKhI,eAAeiI,iBAAiB7J,qBAAqB,IAAImB,0BAA0B;GACzF,MAAM2I,eAAe,KAAKjI,gBAAgB8H,eAAe,IAAI;GAC7D,MAAMI,mBACL,KAAKlI,gBAAgBgI,iBAAiB7J,qBAAqB,IAAImB,0BAA0B;AAG1FsI;AACA,OAAIA,aAAa,OAAO,EACvBvJ,UAAS,yBAAyB,gBAAgB;IACjD8J,KAAKN,SAASO,QAAQ,EAAE;IACxBC,SAASJ,aAAaG,QAAQ,EAAC;IAC/B,CAAC;AAGH,QAAKxI,aAAagG,KAAK,eAAe;IACrCiC;IACAE;IACAE;IACAC;IACA,CAAC;KACA9J,gCAAgC;;CAGpC,AAAQ2D,iBACPqD,OACAkD,QAAiC,EAAE,EAC5B;AACP,OAAKxI,YAAYsF;EACjB,MAAMoD,UAAU;GACfpD;GACAC,UAAUD,UAAU;GACpBV,SAAS,KAAK7E;GACd,GAAGyI;GACH;AAED,OAAK1I,aAAagG,KAAK,iBAAiB4C,QAAQ;AAEhD,UAAQpD,OAAR;GACC,KAAK;AACJ,SAAKxF,aAAagG,KAAK,sBAAsB4C,QAAQ;AACrD;GACD,KAAK;AACJ,SAAK5I,aAAagG,KAAK,qBAAqB4C,QAAQ;AACpD;GACD,KAAK;AACJ,SAAK5I,aAAagG,KAAK,kBAAkB4C,QAAQ;AACjD;GACD,KAAK;AACJ,SAAK5I,aAAagG,KAAK,SAAS4C,QAAQ;AACxC;GACD,QACC;;;;;;;;;;ACxWJ,SAAgB0F,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,KACM7B,SAAS;;;;;AAM1B,SAAgB8E,6BAA6BjD,MAAmD;AAC/F,KAAI,CAACA,QAAQ,OAAOA,SAAS,SAAU,QAAO;AAE9C,QAAO,OADGA,KACM7B,SAAS;;;;;AAM1B,SAAgB+E,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,EAAEzE,SAAS;;;;;;AAOvE,SAAgBkF,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;;;;;;;;;;;;;;;;;;;;;;;AC3MnC,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;;;;;;AC7XhB,MAAMuK,0BACJ;AAEF,MAAaC,UAA2B,EACtCJ,gBACAC,aACAC,cACI;AACJ,QACE,qBAAC,gBAAgB;EACf,WAAU;EACV,OAAO,GACJ,uBAAiC,SACnC;aAGD,qBAAC;GAAI,WAAU;cAEb,qBAAC;IAAI,WAAU;eACZD,eACC,oBAAC;KACC,SAAQ;KACR,MAAK;KACL,WAAWE;KACX,SAASF;KACT,SAAQ;KACR,MAAK;eAEL,oBAAC,QAAK,WAAU,kBAAe;MAElC,EACAD,kBACC,oBAAC;KACC,SAAQ;KACR,MAAK;KACL,WAAWG;KACX,SAASH;KACT,SAAQ;KACR,MAAK;eAEL,oBAAC,WAAQ,WAAU,kBAAe;MAErC;KACE,EAGJE,WACC,oBAAC;IAAI,WAAU;cACb,oBAAC;KACC,SAAQ;KACR,MAAK;KACL,WAAWC;KACX,SAASD;KACT,SAAQ;KACR,MAAK;eAEL,oBAAC,KAAE,WAAU,kBAAe;MACX;KAEtB;IACE,EAEL,qBAAC,gBAAgB;GAAS,WAAU;;IAClC,oBAAC;KAAY,YAAY,EAAEG,aAAaA,OAAOC;eAC7C,oBAAC,kBAAa;MACH;IAEb,oBAAC,gBAAgB,YACf,YAAY;KACVC;KACAC;KACAC;KACD,GAAC;IAGJ,qBAAC,gBAAgB;KAAe,WAAU;gBACxC,oBAAC,yBAAoB,EACrB,oBAAC,aAAQ;MACqB;;IACR;GACL;;AAI3B,MAAMC,6BAA2B;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAE7BF,OAAA,oBAAA,gBAAA;GAAgC,SAAA;aAC9B,oBAAC;IACS,SAAA;IACA,SAAA;IACE,WAAA;cAEV,oBAAC,iBAAwB,WAAA,cAC3B;KACF;IAAiC;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QARjCE;;AAYJ,MAAMG,sBAAoB;CAAA,MAAAL,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAEtBF,OAAA,qBAAA;GAAe,WAAA;cACb,oBAAA;IAAe,WAAA;cACb,qBAAA;KAAe,WAAA;gBACb,oBAAA;MAAc,WAAA;gBAAkI;OAGhJ,sBAAA;MAAa,WAAA;gBAAsJ;OAGrK;MACF;KACA,sBAAC,sBACH;IAAM;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAZNE;;AAgBJ,MAAMI,0BAAwB;CAAA,MAAAN,IAAAC,EAAA,EAAA;CAC5B,MAAA,EAAAM,SAAAC,eAAgC1B,YAAY;AAE5C,KAAI,CAAC0B,WAAU,QACN;CACR,IAAAN;AAAA,KAAAF,EAAA,OAAAO,SAAA;AAIIL,OAAAK,QAAOE,MAAO,GAAG,EAAE,CAAAC,IAAKC,SA2BvB;AAAAX,IAAA,KAAAO;AAAAP,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAE,IAAA;AA5BJU,OAAA,oBAAA;GAAe,WAAA;aACZV;IA4BG;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;AAAA,QA7BNY;;AAiCJ,MAAMC,iBAAe;CAAA,MAAAb,IAAAC,EAAA,GAAA;CACnB,MAAAa,cAAoB7B,wBAAwB;CAC5C,MAAA8B,gBAAsBD,aAAWE,YAAX;CACtB,MAAAC,oBAA0BH,aAAWI,gBAAX;CAAmC,IAAAhB;CAAA,IAAAU;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAKvDF,OAAA,oBAAC,wBAAsB;AACvBU,OAAA,oBAAC,wBAAsB;AAAAZ,IAAA,KAAAE;AAAAF,IAAA,KAAAY;QAAA;AAAAV,OAAAF,EAAA;AAAAY,OAAAZ,EAAA;;CAER,MAAAmB,KAAAJ,gBAAA,yBAAA;CAGX,MAAAK,KAAAL,iBAAA;CAAsD,IAAAM;AAAA,KAAArB,EAAA,OAAAoB,IAAA;AAF7CC,OAAAnE,GACT,2OACAkE,GACD;AAAApB,IAAA,KAAAoB;AAAApB,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;CAEU,MAAAsB,KAAA,CAACP;CACF,MAAAQ,KAAAR,iBAAAE;CAAkC,IAAAO;AAAA,KAAAxB,EAAA,OAAAmB,MAAAnB,EAAA,OAAAqB,MAAArB,EAAA,OAAAsB,MAAAtB,EAAA,OAAAuB,IAAA;AAR9CC,OAAA,oBAAA,kBAAA;GACe,aAAAL;GACF,WAAAE;GAIL,MAAA;GACK,WAAAC;GACD,UAAAC;GACC,cAAA;IACX;AAAAvB,IAAA,KAAAmB;AAAAnB,IAAA,KAAAqB;AAAArB,IAAA,KAAAsB;AAAAtB,IAAA,KAAAuB;AAAAvB,IAAA,KAAAwB;OAAAA,MAAAxB,EAAA;CAAA,IAAAyB;AAAA,KAAAzB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AACFqB,OAAA,oBAAC,mBAAiB;AAAAzB,IAAA,KAAAyB;OAAAA,MAAAzB,EAAA;CAAA,IAAA0B;AAAA,KAAA1B,EAAA,QAAAwB,IAAA;AAftBE,OAAA,oBAAA,kBAAA;GAAkC,WAAA;aAChC,qBAAA,kBAAA;IAAgD,WAAA;;KAC9CxB;KACAU;KACAY;KAWAC;;KAEJ;IAAyB;AAAAzB,IAAA,MAAAwB;AAAAxB,IAAA,MAAA0B;OAAAA,MAAA1B,EAAA;AAAA,QAjBzB0B;;AAqBJ,MAAMC,kBAAkBC,WAAmC;CACzD,MAAMC,QAAQD,OAAOC,OAAOC,MAAM;AAClC,KAAID,MAAO,QAAOA;CAElB,MAAME,WAAWH,OAAOI,OAAOJ,OAAOK,UAAU;AAChD,KAAI;AACF,SAAO,IAAIC,IAAIH,SAAS,CAACI,YAAYJ;SAC/B;AACN,SAAOA;;;AAIX,MAAMK,gBAAgBR,WAAmC;AACvD,QAAOA,OAAOS;;AAGhB,MAAMC,mBACJC,cACW;AACX,QAAOA,UAAUF;;AAGnB,MAAMG,kBACJD,WACAX,WACwB;CACxB,MAAMa,UAAUF,WAAWG,mBAAmB,EAAE;CAChD,MAAMC,cAAc,IAAIC,IAAIH,QAAQ/B,IAAI4B,gBAAgB,CAAC;CACzD,MAAMO,MAAMT,aAAaR,OAAO;CAChC,MAAMkB,eAAe;EAAET,UAAUT,OAAOS;EAAUU,OAAOnB,OAAOmB;EAAO;AAOvE,QAAO,EAAEL,iBAJPC,YAAYM,IAAIJ,IAAI,GAChBJ,QAAQS,QAAQC,SAASb,gBAAgBa,KAAK,KAAKN,IAAI,GACvD,CAAC,GAAGJ,SAASK,aAAa,EAEA;;AAGlC,MAAMM,4BAA0B;CAAA,MAAApD,IAAAC,EAAA,GAAA;CAC9B,MAAAoD,gBAAsBtE,0BAA0B;CAAC,IAAAmB;AAAA,KAAAF,EAAA,OAAAqD,eAAAC,SAAA;AACjCpD,OAAAmD,eAAaC,WAAb,EAA4B;AAAAtD,IAAA,KAAAqD,eAAAC;AAAAtD,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAA5C,MAAAsD,UAAgBpD;CAA6B,IAAAU;AAAA,KAAAZ,EAAA,OAAAqD,eAAAd,WAAAG,iBAAA;AAErB9B,OAAAyC,eAAad,WAA4BG,mBAAzC,EAA+C;AAAA1C,IAAA,KAAAqD,eAAAd,WAAAG;AAAA1C,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAvE,MAAA0C,kBAAwB9B;CAAgD,IAAAO;AAAA,KAAAnB,EAAA,OAAA0C,iBAAA;AAEhEvB,OAAA,IAAIyB,IAAIF,gBAAehC,IAAK4B,gBAAgB,CAAC;AAAAtC,IAAA,KAAA0C;AAAA1C,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CADrD,MAAAuD,eACQpC;CAGR,MAAAqC,kBAAwBH,eAAaG;CAAkB,IAAApC;AAAA,KAAApB,EAAA,OAAAqD,eAAA;AAGrDjC,QAAAQ,WAAA;AACE,OAAI,CAACyB,cAAa;GAClB,MAAAI,gBAAsBjB,eAAea,cAAad,WAAYX,OAAO;AAChEyB,iBAAaK,aAAcD,cAAc;;AAC/CzD,IAAA,KAAAqD;AAAArD,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CALH,MAAA2D,eAAqBvC;AASrB,KAAI,CAACiC,iBAAiBC,QAAOM,WAAY,EAAC,QACjC;CACR,IAAAvC;AAAA,KAAArB,EAAA,OAAAwD,mBAAAxD,EAAA,OAAA2D,gBAAA3D,EAAA,QAAAuD,gBAAAvD,EAAA,QAAAsD,SAAA;EAAA,IAAAhC;AAAA,MAAAtB,EAAA,QAAAwD,mBAAAxD,EAAA,QAAA2D,gBAAA3D,EAAA,QAAAuD,cAAA;AAIgBjC,WAAAuC,aAAA;IACX,MAAAhB,MAAYT,aAAaR,SAAO;IAChC,MAAAkC,aAAmBP,aAAYN,IAAKJ,IAAI;IACxC,MAAAkB,QAAcpC,eAAeC,SAAO;IACpC,MAAAoC,UAAgBR,oBAAoB5B,SAAMS;AAAU,WAElD,qBAAA;KAEO,MAAA;KACI,eAAMsB,aAAa/B,SAAM;KACvB,WAAA1E,GACT,oHACA4G,aAAA,0DAAA,mFAGF;KACcA,gBAAAA;KACPC,OAAAA;;MAENnC,SAAMqC,UACL,oBAAA;OACO,KAAArC,SAAMqC;OACP,KAAA;OACM,WAAA;OACF,SAAA;QAIX,GADC,oBAAA,UAAgB,WAAA,0DAClB;MACA,oBAAA;OAAgB,WAAA;iBAAgCF;QAC/C;MAAAC,UACC,oBAAA;OAAgB,WAAA;iBAAoC;QAC9C,GAFP;MAGD,oBAAA;OAAgB,WAAA;iBACbpC,SAAMsC;QAEX;;OA7BOrB,IA6BE;;AAEZ7C,KAAA,MAAAwD;AAAAxD,KAAA,MAAA2D;AAAA3D,KAAA,MAAAuD;AAAAvD,KAAA,MAAAsB;QAAAA,QAAAtB,EAAA;AAtCAqB,OAAAiC,QAAO5C,IAAKY,KAsCX;AAAAtB,IAAA,KAAAwD;AAAAxD,IAAA,KAAA2D;AAAA3D,IAAA,MAAAuD;AAAAvD,IAAA,MAAAsD;AAAAtD,IAAA,MAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,QAAAqB,IAAA;AAvCJC,OAAA,oBAAA;GAAe,WAAA;aACZD;IAuCG;AAAArB,IAAA,MAAAqB;AAAArB,IAAA,MAAAsB;OAAAA,MAAAtB,EAAA;AAAA,QAxCNsB;;;;;AA+CJ,MAAM6C,+BAA6B;CAAA,MAAAnE,IAAAC,EAAA,EAAA;CACjC,MAAAmE,eAAqBpF,yBAAyB;AAE9C,KAAI,CAACoF,aAAY,QAAS;CAE1B,MAAA,EAAAC,MAAAC,eAA6BF;CAC7B,MAAAG,YAAkBF,SAAS;CAQrB,MAAAnE,KAAAqE,YAAA,uEAAA;CAE4E,IAAA3D;AAAA,KAAAZ,EAAA,OAAAE,IAAA;AAJnEU,OAAA1D,GACT,kDACAgD,GAGD;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAGC,MAAAmB,KAAAoD,YAAA,2DAAA;CAEmD,IAAAnD;AAAA,KAAApB,EAAA,OAAAuE,WAAA;AAIpDnD,OAAAmD,YACC,oBAAC,UAAiB,WAAA,sBAGnB,GADC,oBAAC,aAAoB,WAAA,sBACtB;AAAAvE,IAAA,KAAAuE;AAAAvE,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,OAAAY,MAAAZ,EAAA,OAAAmB,MAAAnB,EAAA,OAAAoB,MAAApB,EAAA,OAAAsE,YAAA;AArBHjD,OAAA,oBAAC;GACS,SAAA;GACH,MAAA;GACM,WAAAT;GAMF0D,SAAAA;GAEP,SAAAnD;GAIG,MAAA;aAEJC;IAKiB;AAAApB,IAAA,KAAAY;AAAAZ,IAAA,KAAAmB;AAAAnB,IAAA,KAAAoB;AAAApB,IAAA,KAAAsE;AAAAtE,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;AAAA,QAtBpBqB;;;;;AA6BJ,MAAMmD,4BAA0B;CAAA,MAAAxE,IAAAC,EAAA,GAAA;CAC9B,MAAAa,cAAoB7B,wBAAwB;AAE5C,KAAI,CAAC6B,eAAD,CAAiBA,YAAW2D,YAAY,QAAS;CAErD,MAAA,EAAAzD,UAAAE,cAAAwD,OAAAC,SAAgD7D;CAAY,IAAAZ;AAAA,KAAAF,EAAA,OAAAgB,YAAAhB,EAAA,OAAAkB,gBAAAlB,EAAA,OAAA0E,SAAA1E,EAAA,OAAA2E,MAAA;AAE5BzE,aAAA;AAC9B,OAAIc,YAAAE,aACFyD,OAAM;OAEDD,QAAO;;AAEf1E,IAAA,KAAAgB;AAAAhB,IAAA,KAAAkB;AAAAlB,IAAA,KAAA0E;AAAA1E,IAAA,KAAA2E;AAAA3E,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAND,MAAA4E,cAAoB1E;CAcd,MAAAU,KAAAI,WAAA,kEAEIE,eAAA,yCAAA;CAE0E,IAAAC;AAAA,KAAAnB,EAAA,OAAAY,IAAA;AANrEO,OAAAjE,GACT,kDACA0D,GAKD;AAAAZ,IAAA,KAAAY;AAAAZ,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CAGC,MAAAoB,KAAAJ,WAAA,sBAEIE,eAAA,kBAAA;CAEuB,IAAAG;AAAA,KAAArB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAK7BiB,OAAA,oBAAC,OAAc,WAAA,sBAAsB;AAAArB,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,OAAA4E,eAAA5E,EAAA,OAAAkB,gBAAAlB,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,IAAA;AAtBvCE,OAAA,oBAAC;GACS,SAAA;GACH,MAAA;GACM,WAAAH;GAQFyD,SAAAA;GAEP,SAAAxD;GAMG,MAAA;GACKF,UAAAA;aAEVG;IACkB;AAAArB,IAAA,KAAA4E;AAAA5E,IAAA,KAAAkB;AAAAlB,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAAsB;OAAAA,MAAAtB,EAAA;AAAA,QAvBpBsB;;AA2BJ,MAAMuD,uBAAqB;CAAA,MAAA7E,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAIrBF,OAAA,qBAAA;GAAe,WAAA;;IACb,oBAAC,0BACD;wBAAC,wBACD;wBAAC,2BACH;;IAAM;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAIJQ,OAAA,oBAAC;GAAuB,WAAAkE;aACtB,oBAAA,kBAAA;IAAwB,SAAA;cACtB,oBAAC;KACS,SAAA;KACH,MAAA;KACA,MAAA;KACG,SAAA;KACH,MAAA;KACK,WAAA;KACC,cAAA;eAEX,oBAAC,eAAsB,WAAA,qCACzB;MACF;KACF;IAAc;AAAA9E,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAxBlBe,OAAA,qBAAA;GAAe,WAAA;cAEbjB,IAOA,qBAAA;IAAe,WAAA;eACbU,IAgBA,oBAAC;KAAuB,WAAAmE;eACtB,oBAAA,kBAAA;MAA0B,SAAA;gBACxB,oBAAC;OACM,MAAA;OACG,SAAA;OACH,MAAA;OACK,WAAA;OACC,cAAA;iBAEX,oBAAC,cAAqB,WAAA,uDACxB;QACF;OACF;MACF;KACF;IAAM;AAAA/E,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;AAAA,QAxCNmB;;AA4CJ,MAAM6D,qBAAmB;CAAA,MAAAhF,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAErBF,OAAA,oBAAA,iBAAA,mBACE,oBAAA,eAAA;GAA+B,WAAA;aAC7B,oBAAA,eAAA,WAAkC,WAAA,8CACpC;IACF,GAAyB;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAJzBE;;AAQJ,MAAMJ,yBAAuB;CAAA,MAAAE,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAMvBF,OAAA,qBAAA;GAAe,WAAA;cACb,oBAAA,iBAAA,SACc,YAAA;IAAA+E,MACJpI;IAAYC;IAAAC;IAAAmI,OAGX,EAAAC,UAAYtG,6BAAoB;IACzC,GAEF,sBAAC,iBACH;IAAM;AAAAmB,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAdRQ,OAAA,qBAAA,iBAAA;GACY,WAAA;GACA,aAAA;cAEVV,IAYA,qBAAA;IAAe,WAAA;eACb,oBAAC,iBACD,sBAAC,uBACH;KACF;IAAwB;AAAAF,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;AAAA,QApBxBY;;AAwBJ,MAAMwE,2BAAyB;CAAA,MAAApF,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAUrBF,OAAA,oBAAC;GAAuB,WAAAmF;aACtB,oBAAC,aAAoB,WAAA,cACvB;IAAc;AAAArF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAJlBQ,OAAA,oBAAA,mBAAA;GAAyB,SAAA;aACvB,qBAAC;IAA0B,SAAA;eACzBV,IAGA,oBAAC;KAAuB,WAAAoF;eACtB,oBAAC,YAAmB,WAAA,cACtB;MACF;KACF;IAA0B;AAAAtF,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAC1Be,OAAA,oBAAA,mBAAA;GAAmC,SAAA;aACjC,oBAAC;IAA0B,SAAA;cACzB,oBAAC,gBAAuB,WAAA,cAC1B;KACF;IAAoC;AAAAnB,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AApBtCgB,OAAA,qBAAA,mBAAA;GACE,iBAAA;GACS,UAAA;GACK,eAAA;GACJ,WAAA;;IAEVR;IAUAO;IAKA,oBAAA,mBAAA;KAA2B,SAAA;eACzB,oBAAC;MAA0B,SAAA;gBACzB,oBAAC,iBAAwB,WAAA,cAC3B;OACF;MACF;;IAA0B;AAAAnB,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;AAAA,QA1B1BoB;;AA8BJ,MAAMxB,oBAAkB;CAAA,MAAAI,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAMlBF,OAAA,oBAAC,2BAAyB;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAGxBQ,OAAA,oBAAA;GAAe,WAAA;aACb,oBAAA,iBAAA,UACF;IAAM;AAAAZ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AATVe,OAAA,qBAAA,iBAAA;GACY,WAAA;GACA,aAAA;;IAEVjB;IAEA,qBAAA;KAAe,WAAA;gBACbU,IAGA,oBAAA;MAAe,WAAA;gBACb,oBAAC,kBACH;OACF;MAEA;wBAAC,gBAAuB,WAAA,kGAC1B;;IAAwB;AAAAZ,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;AAAA,QAhBxBmB;;AAoBJ,MAAMoE,sBAAoB;CAAA,MAAAvF,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAEtBF,OAAA,oBAAA,mBAAA;GACE,iBAAA;GACS,UAAA;GACC,WAAA;aAEV,oBAAA,mBAAA;IAAyB,SAAA;cACvB,oBAAC;KAA0B,SAAA;KAAiB,WAAA;eAC1C,oBAAC,cAAqB,WAAA,cACxB;MACF;KACF;IAA0B;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAV1BE;;AAcJ,MAAML,qBAAmB;CAAA,MAAAG,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAIjBF,OAAA,oBAAA,kBAAA;GACY,WAAA;GACV,WAAA;IACA;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAEAQ,OAAA,oBAAA,kBAAA;GAA0B,SAAA;aACxB,oBAAC;IAAe,SAAA;IAAa,MAAA;cAAK;KAGpC;IAA2B;AAAAZ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAXjCe,OAAA,oBAAA,iBAAA;GAAiC,WAAA;aAC/B,qBAAA,kBAAA;IAAkC,WAAA;eAChCjB,IAIA,qBAAA;KAAe,WAAA;gBACbU,IAKA,oBAAA,kBAAA;MAAwB,SAAA;gBACtB,oBAAC;OAAY,MAAA;iBAAK;QACpB;OACF;MACF;KACF;IAAwB;AAAAZ,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;AAAA,QAjBxBmB;;AAqBJ,MAAMqE,gBAAqDtF,OAAA;CAAA,MAAAF,IAAAC,EAAA,GAAA;CAAA,IAAA0F;CAAA,IAAAC;AAAA,KAAA5F,EAAA,OAAAE,IAAA;AAAC,GAAA,CAAAyF,cAAAC,QAAA1F;AAG3DF,IAAA,KAAAE;AAAAF,IAAA,KAAA2F;AAAA3F,IAAA,KAAA4F;QAAA;AAAAD,cAAA3F,EAAA;AAAA4F,SAAA5F,EAAA;;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAA2F,WAAA;AAIgB/E,OAAA1D,GACT,8GACAyI,UACD;AAAA3F,IAAA,KAAA2F;AAAA3F,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAGDe,OAAA,oBAAA,sBAAA;GAAgC,SAAA;aAC9B,oBAAC;IAA0B,SAAA;cACzB,oBAAC,mBAA0B,WAAA,cAC7B;KACF;IAAiC;AAAAnB,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAE/BgB,OAAA,oBAAA,sBAAA,WAAgC;AAAApB,IAAA,KAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAAqB;AAAA,KAAArB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AADlCiB,OAAA,qBAAA;GAAgB,WAAA;;IACdD;IAAgC;IAAG,oBAAA,sBAAA,UACrC;;IAAO;AAAApB,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;CAAA,IAAAsB;AAAA,KAAAtB,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AACPkB,OAAA,oBAAA,sBAAA;GAA4B,SAAA;aAC1B,oBAAC;IAA0B,SAAA;cACzB,oBAAC,oBAA2B,WAAA,cAC9B;KACF;IAA6B;AAAAtB,IAAA,KAAAsB;OAAAA,MAAAtB,EAAA;CAAA,IAAAuB;AAAA,KAAAvB,EAAA,OAAA4F,QAAA5F,EAAA,QAAAY,IAAA;AApB/BW,OAAA,qBAAA,sBAAA;GACE,sBAAA;GACW,WAAAX;GAGV,GACGgF;;IAEJzE;IAKAE;IAGAC;;IAK2B;AAAAtB,IAAA,KAAA4F;AAAA5F,IAAA,MAAAY;AAAAZ,IAAA,MAAAuB;OAAAA,MAAAvB,EAAA;AAAA,QArB7BuB;;AAxb0B,SAAAZ,SAAAkF,QAAAC,OAAA;AAAA,QAUtB,oBAAA;EAEY,WAAA;EACH,OAAA,EAAAE,gBAAkB,GAAG,MAAMF,QAAQ,GAAE,KAAK;YAEjD,oBAAA,gBAAA;GACU,QAAAD,OAAMI,eAAgBJ,OAAME;GACpC,MAAA;GACA,SAAA;aAEA,qBAAC;IACS,SAAA;IACE,WAAA;IACE,cAAAF,OAAMI,eAAgBJ,OAAME;eAExC,oBAAA;KAAgB,WAAA;eACbF,OAAME;MAER,EAAAF,OAAMI,eACL,oBAAA;KAAgB,WAAA;eACbJ,OAAMI;MAEX;KAEJ;IACF;IAxBOJ,OAAME,KAwBP;;AAiOa,SAAAjB,SAAA5E,IAAA;CAYM,MAAA,EAAAR,WAAAQ;AAAU,QAAK,CAACR,OAAMwG;;AAZ5B,SAAAnB,SAAA7E,IAAA;CA4BM,MAAA,EAAAR,QAAAyG,aAAAjG;AAAU,QAAKR,SAAMwG;;AAsDvB,SAAAb,SAAAnF,IAAA;CAUI,MAAA,EAAAkG,YAAAlG;AAAW,QAAKkG,QAAOC;;AAV3B,SAAAf,SAAApF,IAAA;CAaI,MAAA,EAAAkG,SAAAE,cAAApG;AAAW,QAAK,CAACkG,UAAOC;;;;;AChgB3D,MAAae,mBAA6C,EAAEF,WAAWC,qBAAqB;CAC3F,MAAME,iBAAiBN,cAAc;EACpC,MAAMO,aAAiB,oBAAC,sBAAmCH,iBAAkB;AAC7EG,OAAKC,cAAc;AACnB,SAAOD;IACL,CAACH,eAAe,CAAC;AAEpB,QACC,qBAAC,oBAAoB;EAAK,WAAWL,GAAG,gCAAgCI,UAAU;;GACjF,oBAAC,kBAAa;GACd,oBAAC;IAAY,YAAY,EAAEM,cAAcA,QAAQC;cAChD,oBAAC,uBAAkB;KACP;GACb,oBAAC;IAAY,YAAY,EAAED,SAAAA,gBAAc,CAACA,UAAQC;cACjD,oBAAC,oBAAoB,SAAM,YAAY,EAAEJ,gBAAgB,GAAC;KAC9C;;GACa;;AAI7B,MAAMK,sBAAoB;CAAA,MAAAC,IAAAnB,EAAA,EAAA;CAAA,IAAAoB;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAExBF,OAAA,oBAAA,oBAAA;GAAyB,SAAA;aACxB,qBAAA;IACM,MAAA;IACM,WAAAd,GACV,uGACA,mEACA,mEACA,iCACD;eAEA,oBAAC,QAAe,WAAA,cAAc;KAGhC;IAA0B;AAAAa,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QAb1BC;;AAiBF,MAAMG,2BAAyB;CAAA,MAAAJ,IAAAnB,EAAA,EAAA;CAAA,IAAAoB;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAE7BF,OAAA,oBAAA;GAAe,WAAA;GAA0C,cAAA;aACvDI,MAAKC,KAAM,EAAAC,QAAU,GAAG,EAAEC,QAM1B;IACI;AAAAR,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QARNC;;AAYF,MAAMQ,sBAA0DR,OAAA;CAAA,MAAAD,IAAAnB,EAAA,EAAA;CAAC,MAAA,EAAAW,mBAAAS;CAAkB,IAAAS;AAAA,KAAAV,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAGrEO,OAAAvB,GACV,8EACA,6EACA,iCACA;AAAAa,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAW;AAAA,KAAAX,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAMAQ,OAAA,oBAAA,wBAAA,SAAwC,UAAA,aAAa;AAAAX,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAR,gBAAA;AAJtDoB,OAAA,oBAAA,wBAAA;GACUpB,SAAAA;GACC,WAAA;aAEVmB;IACiC;AAAAX,IAAA,KAAAR;AAAAQ,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAClCU,OAAA,oBAAA;GAAe,WAAA;aACd,oBAAC,0BACF;IAAM;AAAAb,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;AAAA,KAAAd,EAAA,OAAAY,IAAA;AAfPE,OAAA,qBAAA,wBAAA;GACY,WAAAJ;cAMXE,IAMAC;IAG8B;AAAAb,IAAA,KAAAY;AAAAZ,IAAA,KAAAc;OAAAA,MAAAd,EAAA;AAAA,QAhB/Bc;;AAoBF,MAAMC,8BAA4B;CAAA,MAAAf,IAAAnB,EAAA,EAAA;CAAA,IAAAoB;AAAA,KAAAD,EAAA,OAAAE,OAAAC,IAAA,4BAAA,EAAA;AAEhCF,OAAA,oBAAA,wBAAA;GAAiC,SAAA;aAChC,oBAAA;IACM,MAAA;IACC,OAAA;IACK,cAAA;IACA,WAAAd,GACV,mFACA,qDACA,6FACD;cAEA,oBAAC,WAAkB,WAAA,cACpB;KACD;IAAkC;AAAAa,IAAA,KAAAC;OAAAA,MAAAD,EAAA;AAAA,QAblCC;;AAtC6B,SAAAO,QAAAQ,GAAAC,KAAA;AAAA,QAI3B,oBAAA,SAGW,WAAA,0DADL,mBAAmBA,MAEvB;;;;;;;;ACdN,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,QAA4B;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,QAAAoB,QAAA;AAAA,QAEiCA,OAAMrB;;;;;;;;ACxD9C,SAAO6B,mBAAA;CAAA,MAAAC,IAAAP,EAAA,EAAA;CACN,MAAAQ,WAAiBP,UAAUQ,QAA4B;CAAA,IAAAC;AAAA,KAAAH,EAAA,OAAAC,UAAA;AAAAG,OAAA;AAGtD,OAAI,CAACH,YAAYA,SAAQI,WAAY,GAAC;AAAEF,SAAO;AAAP,UAAAC;;GAExC,MAAAE,uBAA6B,CAAA,GAAIL,SAAS,CAAAM,SAAU,CAAAC,KAAMC,SAA8B;AACxF,OAAI,CAACH,sBAAoB;AAAEH,SAAO;AAAP,UAAAC;;AAG3BD,QADkBG,qBAAoBK,QAAQC,OAAQC,SAAwC,CAC9EC,GAAI,GAAS,EAAAhB,QAAtB;;AAA8BE,IAAA,KAAAC;AAAAD,IAAA,KAAAG;OAAAA,MAAAH,EAAA;AAAA,QAP/BG;;AAHD,SAAAU,SAAArB,KAAA;AAAA,QASuEA,IAACK,SAAU;;AATlF,SAAAY,SAAAM,GAAA;AAAA,QAM4DA,EAACC,SAAU;;AANvE,SAAAd,QAAAe,QAAA;AAAA,QACiCA,OAAMhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC0B9C,MAAM0B,uBAAuBT,cAAgD,KAAK;;;;;;;AAgBlF,MAAaY,yBAAwDC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAJ,UAAAL,OAAAE,aAAAK;CAQzD,MAAAG,KAAAR,YAAAF;CAAiB,IAAAW;AAAA,KAAAH,EAAA,OAAAR,SAAAQ,EAAA,OAAAE,IAAA;AAFrBC,OAAA;GAAAX;GAAAE,UAEIQ;GACV;AAAAF,IAAA,KAAAR;AAAAQ,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAJF,MAAAI,QACQD;CAKP,IAAAE;AAAA,KAAAL,EAAA,OAAAH,YAAAG,EAAA,OAAAI,OAAA;AAEMC,OAAA,oBAAA,qBAAA;GAAsCD;GAAQP;IAAyC;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAAvFK;;;;;AAkBR,SAAOI,2BAAA;AAAA,QACCtB,WAAWQ,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACgFxC,SAAO8E,aAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAEN,MAAAC,iBAAuBlE,UAAUmE,QAA4B;CAC7D,MAAAf,YAAkBpD,UAAUoE,SAA6B;CAGzD,MAAAd,UAAgBpD,YAAY;CAAA,IAAAmE;AAAA,KAAAL,EAAA,OAAAV,SAAA;AAIrBe,OAAAf,QAAOgB,KAAMC,SAAsC,IAAnD;AAAmDP,IAAA,KAAAV;AAAAU,IAAA,KAAAK;OAAAA,MAAAL,EAAA;CAD1D,MAAAT,gBACOc;CAEN,IAAAG;AAAA,KAAAR,EAAA,OAAAV,SAAA;AAEMkB,OAAAlB,QAAOmB,OAAQC,SAAsD,CAAAC,MAAO,GAAG;AAAAX,IAAA,KAAAV;AAAAU,IAAA,KAAAQ;OAAAA,MAAAR,EAAA;CADtF,MAAAR,gBACOgB;CAEN,IAAAI;AAAA,KAAAZ,EAAA,OAAAV,SAAA;AAGOsB,OADWtB,QAAOmB,OAAQK,SAAsD,CACvEC,GAAI,GAAW,IAAxB;AAAwBf,IAAA,KAAAV;AAAAU,IAAA,KAAAY;OAAAA,MAAAZ,EAAA;CAFhC,MAAAP,sBAECmB;CAID,MAAAlB,UAAgBvD,kBAAkB;CAGlC,MAAA6E,cAAoB3E,wBAAwB;CAG5C,MAAA4E,aAAmB7E,qBAAqB;CAGxC,MAAA0D,gBAAsB,CAAC,EACtBkB,aAAWnE,YACXmE,aAAWlE,gBACXkE,aAAWjE;CAIZ,MAAAsC,eAAqBa,gBAAcgB,UAAd,KAA+B;CAAC,IAAAC;AAAAC,MAAA;AAIpD,MAAI,CAACJ,aAAW;AAAEG,QAAO;AAAP,SAAAC;;EAAW,IAAAC;AAAA,MAAArB,EAAA,OAAAgB,YAAA5D,cAAA4C,EAAA,OAAAgB,YAAA9D,SAAA8C,EAAA,OAAAgB,YAAAnE,YAAAmD,EAAA,OAAAgB,YAAAlE,gBAAAkD,EAAA,QAAAgB,YAAAjE,WAAAiD,EAAA,QAAAgB,YAAAhE,WAAAgD,EAAA,QAAAgB,YAAA/D,eAAA+C,EAAA,QAAAgB,YAAAhD,eAAAgC,EAAA,QAAAgB,YAAA7D,aAAA6C,EAAA,QAAAgB,YAAArD,SAAAqC,EAAA,QAAAgB,YAAAnD,QAAAmC,EAAA,QAAAgB,YAAAlD,cAAAkC,EAAA,QAAAgB,YAAAzD,YAAA;AAEtB8D,UAAA;IAAAxE,UACImE,YAAWnE;IAASC,cAChBkE,YAAWlE;IAAaC,SAC7BiE,YAAWjE;IAAQC,SACnBgE,YAAWhE;IAAQC,aACf+D,YAAW/D;IAAYC,OAC7B8D,YAAW9D;IAAMC,WACb6D,YAAW7D;IAAUC,YACpB4D,YAAW5D;IAAWG,YACtByD,YAAWzD;IAAWI,OAC3BqD,YAAWrD;IAAME,MAClBmD,YAAWnD;IAAKC,YACVkD,YAAWlD;IAAWE,aACrBgD,YAAWhD;IACxB;AAAAgC,KAAA,KAAAgB,YAAA5D;AAAA4C,KAAA,KAAAgB,YAAA9D;AAAA8C,KAAA,KAAAgB,YAAAnE;AAAAmD,KAAA,KAAAgB,YAAAlE;AAAAkD,KAAA,MAAAgB,YAAAjE;AAAAiD,KAAA,MAAAgB,YAAAhE;AAAAgD,KAAA,MAAAgB,YAAA/D;AAAA+C,KAAA,MAAAgB,YAAAhD;AAAAgC,KAAA,MAAAgB,YAAA7D;AAAA6C,KAAA,MAAAgB,YAAArD;AAAAqC,KAAA,MAAAgB,YAAAnD;AAAAmC,KAAA,MAAAgB,YAAAlD;AAAAkC,KAAA,MAAAgB,YAAAzD;AAAAyC,KAAA,MAAAqB;QAAAA,QAAArB,EAAA;AAdDmB,OAAOE;;CAHR,MAAA1B,QAAiCwB;CAkBhB,IAAAE;AAAAC,MAAA;AAIhB,MAAI,CAACL,YAAU;AAAEI,QAAO;AAAP,SAAAC;;EAAW,IAAAC;AAAA,MAAAvB,EAAA,QAAAiB,WAAAvC,SAAA;AAKlB6C,UAAAN,WAAUvC,WAAV,EAAwB;AAAAsB,KAAA,MAAAiB,WAAAvC;AAAAsB,KAAA,MAAAuB;QAAAA,QAAAvB,EAAA;EAAA,IAAAwB;AAAA,MAAAxB,EAAA,QAAAiB,WAAAQ,YAAAzB,EAAA,QAAAiB,WAAAtC,aAAAqB,EAAA,QAAAiB,WAAArB,SAAAI,EAAA,QAAAuB,MAAA;AAH3BC,UAAA;IAAAnD,MACA4C,WAAUrB;IAAMtB,MAChB2C,WAAUQ;IAAS/C,SAChB6C;IAAwB5C,WACtBsC,WAAUtC;IACrB;AAAAqB,KAAA,MAAAiB,WAAAQ;AAAAzB,KAAA,MAAAiB,WAAAtC;AAAAqB,KAAA,MAAAiB,WAAArB;AAAAI,KAAA,MAAAuB;AAAAvB,KAAA,MAAAwB;QAAAA,QAAAxB,EAAA;AALDqB,OAAOG;;CAHR,MAAA5B,QAAiCyB;CAYjC,MAAAK,gBAAsBpF,0BAA0B;CAAA,IAAAiF;AAAAI,MAAA;AAI9C,MAAI,CAACD,eAAa;AAAEH,QAAO;AAAP,SAAAI;;EAAW,IAAAH;AAAA,MAAAxB,EAAA,QAAA0B,cAAAxD,SAAA8B,EAAA,QAAA0B,cAAAvD,UAAA;AAExBqD,UAAA;IAAAtD,OACCwD,cAAaxD;IAAMC,UAChBuD,cAAavD;IACvB;AAAA6B,KAAA,MAAA0B,cAAAxD;AAAA8B,KAAA,MAAA0B,cAAAvD;AAAA6B,KAAA,MAAAwB;QAAAA,QAAAxB,EAAA;AAHDuB,OAAOC;;CAHR,MAAAI,WAAmCL;CAOhB,IAAAC;AAAA,KAAAxB,EAAA,QAAAE,gBAAA;AAMPsB,OAAAtB,kBAAA,EAAoB;AAAAF,IAAA,MAAAE;AAAAF,IAAA,MAAAwB;OAAAA,MAAAxB,EAAA;CAArB,MAAA6B,KAACL;CAAgD,IAAAM;AAAA,KAAA9B,EAAA,QAAAV,WAAAU,EAAA,QAAAT,iBAAAS,EAAA,QAAAX,eAAAW,EAAA,QAAAZ,aAAAY,EAAA,QAAAF,iBAAAE,EAAA,QAAAP,uBAAAO,EAAA,QAAAR,iBAAAQ,EAAA,QAAAN,WAAAM,EAAA,QAAA6B,MAAA7B,EAAA,QAAA4B,YAAA5B,EAAA,QAAAJ,SAAAI,EAAA,QAAAL,OAAA;AAFrDmC,OAAA;GAAA3C,UAEI0C;GAAiDzC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC,QAoB3DA;GAAMC;GAIN;AAAAE,IAAA,MAAAV;AAAAU,IAAA,MAAAT;AAAAS,IAAA,MAAAX;AAAAW,IAAA,MAAAZ;AAAAY,IAAA,MAAAF;AAAAE,IAAA,MAAAP;AAAAO,IAAA,MAAAR;AAAAQ,IAAA,MAAAN;AAAAM,IAAA,MAAA6B;AAAA7B,IAAA,MAAA4B;AAAA5B,IAAA,MAAAJ;AAAAI,IAAA,MAAAL;AAAAK,IAAA,MAAA8B;OAAAA,MAAA9B,EAAA;AAAA,QA1BM8B;;AAzFF,SAAAhB,SAAAiB,KAAA;AAAA,QAkBmCC,IAAChD,WAAY,aAAagD,IAAChD,WAAY;;AAlB1E,SAAA0B,SAAAuB,KAAA;AAAA,QAcuBD,IAAChD,WAAY,aAAagD,IAAChD,WAAY;;AAd9D,SAAAuB,SAAAyB,GAAA;AAAA,QAUqBA,EAAChD,WAAY;;AAVlC,SAAAoB,SAAA8B,UAAA;AAAA,QAGkCrC,SAAMT;;AAHxC,SAAAe,QAAAN,QAAA;AAAA,QAEuCA,OAAMV;;;;;;;;;;;;;;;;ACpIpD,SAAOwE,kBAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CACN,MAAAC,MAAY3B,iBAAiB;CAE7B,MAAAY,YAAkBX,kBAAkB2B,QAAmC;CACvE,MAAAf,kBAAwBZ,kBAAkB4B,SAAsC;CAChF,MAAAf,YAAkBb,kBAAkB6B,OAAmC;CACvE,MAAAf,oBAA0Bd,kBAAkB8B,OAA2C;CACvF,MAAAC,cAAoB/B,kBAAkBgC,OAAqC;CAAA,IAAAC;AAAA,KAAAT,EAAA,OAAAO,aAAA;EAG1E,MAAAG,UAAgBH,YAAWI,IAAKC,OAS9B;AACKH,OAAAI,OAAMC,YAAaJ,QAAQ;AAAAV,IAAA,KAAAO;AAAAP,IAAA,KAAAS;OAAAA,MAAAT,EAAA;CAXnC,MAAAT,YAWQkB;CACS,IAAAM;AAAA,KAAAf,EAAA,OAAAE,KAAA;AAGhBa,QAAApB,aAAA;AACCO,OAAGc,SAAU,CAAAtB,eAAgBC,SAAS;;AACtCK,IAAA,KAAAE;AAAAF,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAHF,MAAAN,iBAAuBqB;CAKtB,IAAAE;AAAA,KAAAjB,EAAA,OAAAE,KAAA;AAEqCe,aAAA;AACrCf,OAAGc,SAAU,CAAApB,mBAAoB;;AACjCI,IAAA,KAAAE;AAAAF,IAAA,KAAAiB;OAAAA,MAAAjB,EAAA;CAFD,MAAAJ,oBAA0BqB;CAEjB,IAAAC;AAAA,KAAAlB,EAAA,OAAAE,KAAA;AAGRgB,QAAAC,YAAArC,UAAA;AACCoB,OAAGc,SAAU,CAAAI,KAAM,EAAAvC,IAAMc,YAAU,CAAC,CAAAE,OAAQf,MAAM;;AAClDkB,IAAA,KAAAE;AAAAF,IAAA,KAAAkB;OAAAA,MAAAlB,EAAA;CAHF,MAAAH,SAAeqB;CAKd,IAAAG;AAAA,KAAArB,EAAA,OAAAE,KAAA;AAGAmB,QAAAC,eAAA;AACCpB,OAAGc,SAAU,CAAAI,KAAM,EAAAvC,IAAMc,YAAU,CAAC,CAAAG,SAAU;;AAC9CE,IAAA,KAAAE;AAAAF,IAAA,KAAAqB;OAAAA,MAAArB,EAAA;CAHF,MAAAF,UAAgBuB;CAKf,IAAAE;AAAA,KAAAvB,EAAA,QAAAF,WAAAE,EAAA,QAAAV,qBAAAU,EAAA,QAAAZ,mBAAAY,EAAA,QAAAb,aAAAa,EAAA,QAAAT,aAAAS,EAAA,QAAAH,UAAAG,EAAA,QAAAJ,qBAAAI,EAAA,QAAAN,kBAAAM,EAAA,QAAAX,WAAA;AAGOkC,OAAA;GAAApC;GAAAC;GAAAC;GAAAC;GAAAC;GAAAG;GAAAE;GAAAC;GAAAC;GAUN;AAAAE,IAAA,MAAAF;AAAAE,IAAA,MAAAV;AAAAU,IAAA,MAAAZ;AAAAY,IAAA,MAAAb;AAAAa,IAAA,MAAAT;AAAAS,IAAA,MAAAH;AAAAG,IAAA,MAAAJ;AAAAI,IAAA,MAAAN;AAAAM,IAAA,MAAAX;AAAAW,IAAA,MAAAuB;OAAAA,MAAAvB,EAAA;AAAA,QAVMuB;;AAjDF,SAAAX,OAAAQ,MAAA;CAWJ,MAAAI,aAAwC;EAAA3C,IACnCuC,KAAIvC;EAAGC,OACJsC,KAAItC;EAAMC,QACTqC,KAAIrC;EAA4BC,UAC9BoC,KAAIpC;EAASC,YACXmC,KAAInC;EAChB;AAAA,QACM,CAACmC,KAAIvC,IAAK2C,WAAW;;AAlBxB,SAAAhB,OAAAC,IAAA;CAOiC,MAAA,EAAAO,SAAAU,cAAAjB;AAAW,QAAKO,UAAOT;;AAPxD,SAAAD,OAAAG,IAAA;CAMuC,MAAA,EAAAO,SAAAW,cAAAlB;AAAW,QAAKO,UAAO1B;;AAN9D,SAAAe,OAAAI,IAAA;CAK+B,MAAA,EAAAO,SAAAY,cAAAnB;AAAW,QAAKO,UAAO3B;;AALtD,SAAAe,SAAAK,IAAA;CAIqC,MAAA,EAAAO,SAAAa,cAAApB;AAAW,QAAKO,UAAOc;;AAJ5D,SAAA3B,QAAAM,IAAA;CAG+B,MAAA,EAAAO,YAAAP;AAAW,QAAKO,QAAO7B;;;;;;;;;;;;;;;;AC7B7D,MAAa4C,gBAAgB;;;;;;;;;;AAW7B,MAAaC,uBAAuB;;;;;;;;;;;;;ACXpC,IAAIa,WAAW;;;;;;;AAQf,SAAgBC,eAAwB;AAEvC,KAAID,YAAY,OAAOE,aAAa,YACnC,QAAO;AAIR,KAAIA,SAASC,eAAe,gBAAgB,EAAE;AAC7CH,aAAW;AACX,SAAO;;CAIR,MAAMI,QAAQF,SAASG,cAAc,QAAQ;AAC7CD,OAAME,KAAK;AACXF,OAAMG,cAAcR;AACpBG,UAASM,KAAKC,YAAYL,MAAM;AAEhCJ,YAAW;AACX,QAAO;;;;;;;;;;;;;;ACPR,SAAOsB,YAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAqB,MAAA,EAAAV,OAAAC,kBAAAU,IAAAT,aAAAU,IAAAT,SAAAC,WAAAC,WAAAQ,IAAAP,cAAAE;CAE1B,MAAAP,mBAAAU,OAAAG,SAAA,KAAAH;CACA,MAAAT,cAAAU,OAAAE,SAAA,KAAAF;CAGA,MAAAP,YAAAQ,OAAAC,SAAA,QAAAD;CAGA,MAAA,CAAAE,iBAAAC,sBAA8CrB,MAAKsB,SAAU,MAAM;CAEnE,MAAAC,eAAqBlB,MAAKmB,iBAALlB,mBAAA,GACdA,mBAAmBD,MAAKmB,kBADVL;CAIrB,MAAAM,UAAgBpB,MAAKqB,WACjBrB,MAAKqB,SAASC,WAAY,OAES,GADjCtB,MAAKqB,WADP,GAEKnB,cAAcF,MAAKqB,aAHZP;CAIF,IAAAS;AAAA,KAAAd,EAAA,OAAAH,WAAA;AAICiB,OAAA1B,GACT,oFACAS,UACD;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAc;OAAAA,MAAAd,EAAA;CAAA,IAAAe;AAAA,KAAAf,EAAA,OAAAT,MAAAyB,OAAA;AAUGD,OAAA,oBAAA;GAAc,WAAA;aACXxB,MAAKyB;IACH;AAAAhB,IAAA,KAAAT,MAAAyB;AAAAhB,IAAA,KAAAe;OAAAA,MAAAf,EAAA;CAAA,IAAAiB;AAAA,KAAAjB,EAAA,OAAAT,MAAA2B,SAAA;AACLD,OAAA,oBAAA;GAAa,WAAA;aACV1B,MAAK2B;IACJ;AAAAlB,IAAA,KAAAT,MAAA2B;AAAAlB,IAAA,KAAAiB;OAAAA,MAAAjB,EAAA;CAAA,IAAAmB;AAAA,KAAAnB,EAAA,OAAAe,MAAAf,EAAA,OAAAiB,IAAA;AANNE,OAAA,qBAAA;GAAe,WAAA;cACbJ,IAGAE;IAGI;AAAAjB,IAAA,KAAAe;AAAAf,IAAA,KAAAiB;AAAAjB,IAAA,KAAAmB;OAAAA,MAAAnB,EAAA;CAAA,IAAAoB;AAAA,KAAApB,EAAA,OAAAT,MAAA8B,SAAA;AAGLD,OAAA7B,MAAK8B,WAAYC,OAAMC,KAAMhC,MAAK8B,QAAS,CAAAG,SAAU,KACpD,qBAAA;GAAe,WAAA;;IACZjC,MAAK8B,QAAQI,iBACZ,qBAAA,oBACE,oBAAA;KAAa,WAAA;eAA6D;MAG1E,sBAAA;KAAgB,WAAA;eACblC,MAAK8B,QAAQI;MAElB,IACF;IACClC,MAAK8B,QAAQK,gBACZ,qBAAA,oBACE,oBAAA;KAAa,WAAA;eAA6D;MAG1E,sBAAA;KAAa,WAAA;eAAiCnC,MAAK8B,QAAQK;MAC7D,IACF;IACCnC,MAAK8B,QAAQM,kBAAmBpC,MAAK8B,QAAQO,gBAA7C,4CAEG,qBAAA,oBACE,oBAAA;KAAa,WAAA;eAA6D;MAG1E,sBAAA;KAAgB,WAAA;eACbrC,MAAK8B,QAAQM;MAElB,IACA,uBAAA,oBACE,oBAAA;KAAa,WAAA;eAA6D;MAG1E,sBAAA;KAAgB,WAAA;eACbpC,MAAK8B,QAAQO;MAElB,IAAM,IAEV;;IAEH;AAAA5B,IAAA,KAAAT,MAAA8B;AAAArB,IAAA,MAAAoB;OAAAA,MAAApB,EAAA;CAAA,IAAA6B;AAAA,KAAA7B,EAAA,QAAAT,MAAAuC,cAAA;AAGAD,OAAAtC,MAAKuC,gBAAiBvC,MAAKuC,aAAaC,MAAMP,SAAU,KACvD,qBAAA;GAAe,WAAA;cACb,oBAAA;IAAc,WAAA;cAAiD;KAG/D,sBAAA;IAAc,WAAA;cACXjC,MAAKuC,aAAaC,MAAMC,IAAKC,QAI7B;KAEL;IACD;AAAAjC,IAAA,MAAAT,MAAAuC;AAAA9B,IAAA,MAAA6B;OAAAA,MAAA7B,EAAA;CAAA,IAAAkC;AAAA,KAAAlC,EAAA,QAAAT,MAAAuC,cAAA;AAGAI,QAAA3C,MAAKuC,cAAuBK,YAAI5C,MAAKuC,aAAaK,SAASX,SAAU,KACpE,qBAAA;GAAe,WAAA;cACb,oBAAA;IAAa,WAAA;cAAqD;KAGlE,sBAAA;IAAe,WAAA;cACZjC,MAAKuC,aAAaK,SAASH,IAAKI,OAOhC;KAEL;IACD;AAAApC,IAAA,MAAAT,MAAAuC;AAAA9B,IAAA,MAAAkC;OAAAA,OAAAlC,EAAA;CAAA,IAAAqC;AAAA,KAAArC,EAAA,QAAAT,MAAA+C,aAAAtC,EAAA,QAAAM,mBAAAN,EAAA,QAAAJ,WAAA;AAGAyC,QAAAzC,aAAaL,MAAK+C,aACjB,qBAAA;GACY,WAAA;GACJhC,MAAAA;GACI,WAAAiC,MAAOhC,mBAAmBgC,EAACC,cAAcC,KAAK;cAExD,oBAAA;IAAmB,WAAA;cAA4G;KAG/H,sBAAA;IAAe,WAAA;cACZlD,MAAK+C;KAEV;IACD;AAAAtC,IAAA,MAAAT,MAAA+C;AAAAtC,IAAA,MAAAM;AAAAN,IAAA,MAAAJ;AAAAI,IAAA,MAAAqC;OAAAA,OAAArC,EAAA;CAAA,IAAA0C;AAAA,KAAA1C,EAAA,QAAAkC,OAAAlC,EAAA,QAAAqC,OAAArC,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,MAAApB,EAAA,QAAA6B,IAAA;AAxGDa,QAAA,qBAAA;GAAe,WAAA;;IAEfvB;IAUCC;IA4CAS;IAgBAK;IAmBAG;;IAcG;AAAArC,IAAA,MAAAkC;AAAAlC,IAAA,MAAAqC;AAAArC,IAAA,MAAAmB;AAAAnB,IAAA,MAAAoB;AAAApB,IAAA,MAAA6B;AAAA7B,IAAA,MAAA0C;OAAAA,OAAA1C,EAAA;CAAA,IAAA2C;AAAA,KAAA3C,EAAA,QAAAS,cAAA;AAIDkC,QAAAlC,gBACC,oBAAC;GACC,SAAA;GACU,WAAA;GACL,MAAA;aAEL,oBAAA;IAASA,MAAAA;IAAqB,QAAA;IAAa,KAAA;cAAsB;KAGnE;IACD;AAAAT,IAAA,MAAAS;AAAAT,IAAA,MAAA2C;OAAAA,OAAA3C,EAAA;CAAA,IAAA4C;AAAA,KAAA5C,EAAA,QAAAS,gBAAAT,EAAA,QAAAT,MAAAsD,eAAA7C,EAAA,QAAAN,SAAA;AAEAkD,QAAArD,MAAKsD,eAALnD,WAAA,CAAiCe,gBAChC,oBAAC;GACUf,SAAAA;GACC,WAAA;GACL,MAAA;aACN;IAGF;AAAAM,IAAA,MAAAS;AAAAT,IAAA,MAAAT,MAAAsD;AAAA7C,IAAA,MAAAN;AAAAM,IAAA,MAAA4C;OAAAA,OAAA5C,EAAA;CAAA,IAAA8C;AAAA,KAAA9C,EAAA,QAAAW,SAAA;AAGEmC,QAAAnC,WACC,oBAAC;GACC,SAAA;GACQ,SAAA;GACH,MAAA;GACK,WAAA;aAEV,oBAAA;IAASA,MAAAA;IAAgB,QAAA;IAAa,KAAA;cAAsB;KAG9D;IACD;AAAAX,IAAA,MAAAW;AAAAX,IAAA,MAAA8C;OAAAA,OAAA9C,EAAA;CAAA,IAAA+C;AAAA,KAAA/C,EAAA,QAAAL,WAAA;AACAoD,QAAApD,aACC,oBAAC;GACUA,SAAAA;GACD,SAAA;GACH,MAAA;GACK,WAAA;aACX;IAGF;AAAAK,IAAA,MAAAL;AAAAK,IAAA,MAAA+C;OAAAA,OAAA/C,EAAA;CAAA,IAAAgD;AAAA,KAAAhD,EAAA,QAAAS,gBAAAT,EAAA,QAAAT,MAAAsD,eAAA7C,EAAA,QAAAN,SAAA;AACAsD,QAAAzD,MAAKsD,eAALnD,WAAAe,gBACC,oBAAC;GACUf,SAAAA;GACD,SAAA;GACH,MAAA;GACK,WAAA;aACX;IAGF;AAAAM,IAAA,MAAAS;AAAAT,IAAA,MAAAT,MAAAsD;AAAA7C,IAAA,MAAAN;AAAAM,IAAA,MAAAgD;OAAAA,OAAAhD,EAAA;CAAA,IAAAiD;AAAA,KAAAjD,EAAA,QAAA8C,OAAA9C,EAAA,QAAA+C,OAAA/C,EAAA,QAAAgD,KAAA;AAhCHC,QAAA,qBAAA;GAAe,WAAA;;IACZH;IAYAC;IAUAC;;IAUG;AAAAhD,IAAA,MAAA8C;AAAA9C,IAAA,MAAA+C;AAAA/C,IAAA,MAAAgD;AAAAhD,IAAA,MAAAiD;OAAAA,OAAAjD,EAAA;CAAA,IAAAkD;AAAA,KAAAlD,EAAA,QAAA2C,OAAA3C,EAAA,QAAA4C,OAAA5C,EAAA,QAAAiD,KAAA;AAxDRC,QAAA,qBAAA;GAAe,WAAA;;IACZP;IAYAC;IAUDK;;IAkCI;AAAAjD,IAAA,MAAA2C;AAAA3C,IAAA,MAAA4C;AAAA5C,IAAA,MAAAiD;AAAAjD,IAAA,MAAAkD;OAAAA,OAAAlD,EAAA;CAAA,IAAAmD;AAAA,KAAAnD,EAAA,QAAA0C,OAAA1C,EAAA,QAAAkD,KAAA;AAvKRC,QAAA,qBAAA;GAAe,WAAA;cAEbT,KA4GAQ;IA0DI;AAAAlD,IAAA,MAAA0C;AAAA1C,IAAA,MAAAkD;AAAAlD,IAAA,MAAAmD;OAAAA,OAAAnD,EAAA;CAAA,IAAAoD;AAAA,KAAApD,EAAA,QAAAT,MAAA8D,QAAArD,EAAA,QAAAmD,OAAAnD,EAAA,QAAAc,IAAA;AAjLRsC,QAAA,oBAAA;GACa,WAAAtC;GAIX,qBAAA;GACiB,mBAAAvB,MAAK8D;aAGtBF;IAyKI;AAAAnD,IAAA,MAAAT,MAAA8D;AAAArD,IAAA,MAAAmD;AAAAnD,IAAA,MAAAc;AAAAd,IAAA,MAAAoD;OAAAA,OAAApD,EAAA;AAAA,QAlLNoD;;AAtBG,SAAAhB,OAAAkB,SAAAC,SAAA;AAAA,QAgHS,oBAAA;EAEY,WAAA;YAETD;IAHIE,QAIA;;AArHhB,SAAAvB,QAAAwB,MAAAD,OAAA;AAAA,QAgGS,oBAAA;EAA0B,WAAA;YACvBC;IADMD,MAEJ;;;;;;;;;;;;;;;;AC9FrB,IAAaqB,oBAAb,cAAuCnB,MAAMoB,UAG3C;CACAC,YAAYC,OAA+B;AACzC,QAAMA,MAAM;AACZ,OAAKC,QAAQ;GACXL,UAAU;GACVR,OAAO;GACR;;CAGH,OAAOc,yBAAyBd,OAA+C;AAY7E,SAAO;GACLQ,UAAU;GACVR,OAZ2BiB,YAAYjB,MAAM,GAC3CA,QACA;IACEkB,MAAM;IACNC,OAAO;IACPC,SAAS;IACTC,aAAa;IACbC,WAAWtB,MAAMoB;IAClB;GAKJ;;CAGHG,kBAAkBvB,OAAcI,WAA4B;AAE1DoB,UAAQxB,MAAM,yCAAyCA,OAAOI,UAAU;AAGxE,MAAI,KAAKQ,MAAMV,QACb,KAAI;AACF,QAAKU,MAAMV,QAAQF,OAAOI,UAAU;WAC7BqB,cAAc;AACrBD,WAAQxB,MAAM,qDAAqDyB,aAAa;;;CAKtFC,oBAAoB;AAClB,OAAKC,SAAS;GACZnB,UAAU;GACVR,OAAO;GACR,CAAC;;CAGJ4B,sBAAsB;AAGpBC,SAAOC,KAAK,iDAAiD,SAAS;;CAGxEC,SAAS;AACP,MAAI,KAAKlB,MAAML,YAAY,KAAKK,MAAMb,OAAO;GAC3C,MAAM,EAAEF,UAAUkC,mBAAmBpC,kBAAkBC,aAAaS,cAAc,KAAKM;AAGvF,OAAIoB,kBACF,QAAO,oBAAC;IAAkB,OAAO,KAAKnB,MAAMb;IAAO,OAAO,KAAK0B;KAAe;AAIhF,UACE,oBAAC;IACC,OAAO,KAAKb,MAAMb;IACAJ;IACLC;IACb,SAAS,KAAK6B;IACd,WAAW,KAAKE;IACLtB;KACX;;AAIN,SAAO,KAAKM,MAAMlB;;;;;;AAOtB,SAASuB,YAAYjB,OAAoC;AACvD,QACE,OAAOA,UAAU,YACjBA,UAAU,QACV,UAAUA,SACV,WAAWA,SACX,aAAaA,SACb,iBAAiBA,UAEhBA,iBAAiBG,SAASH,MAAMiC,SAAS,wBAEzC,OAAQjC,MAAckB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1CpC,SAAO2B,oBAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAA6BG,OAAAH,OAAAI,SAAA,EAAwC,GAAxCJ;AAAwCC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAC3E,MAAA,EAAAL,SAAAU,IAAAR,oBADmCK;CAOlC,MAAAI,UAAgB,GANTD,OAAAF,SAAA,0BAAAE,GAMmB;CAAwB,IAAAE;AAAA,KAAAP,EAAA,OAAAH,mBAAAG,EAAA,OAAAM,SAAA;AAO3CC,OAAA,IAAIpB,uBAAuB;GAAAsB,KAAOH;GAAOE,SAJhCX,kBAAA,EAAA,uBACYA,iBAChB,GAFIM;GAI2C,CAAC;AAAAH,IAAA,KAAAH;AAAAG,IAAA,KAAAM;AAAAN,IAAA,KAAAO;OAAAA,MAAAP,EAAA;CAR7D,MAAAU,YAQCH;CAC6B,IAAAI;AAAA,KAAAX,EAAA,OAAAU,WAAA;AAICC,OAAA;GAAAD;GAAAE,uBAIPC;GAGvB;AAAAb,IAAA,KAAAU;AAAAV,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAPD,MAAAP,UAAgBL,eAAeuB,GAO7B;CAAA,IAAAG;AAAA,KAAAd,EAAA,OAAAP,SAAA;AAEKqB,OAAA,EAAArB,SAAW;AAAAO,IAAA,KAAAP;AAAAO,IAAA,KAAAc;OAAAA,MAAAd,EAAA;AAAA,QAAXc;;AA5BD,SAAAD,QAAAE,UAAA;AAAA,QAwBG1B,4CAA4C0B,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACP/D,MAAMqC,iBAAiBpC,cAA0C,KAAK;AAEtE,MAAMqC,mBAA6B;CAAE3B,GAAG;CAAGC,GAAG;CAAG;;;;;;;;;;;AAkCjD,MAAaiC,mBAA6C,EACzDL,UACAlB,MAAMwB,gBACNL,cAAc,OACdC,cAAc,aACdC,cACAC,mBACK;CAEL,MAAMG,eAAeD,mBAAmBE;CAGxC,MAAM,CAACC,cAAcC,mBAAmB5C,SAASmC,YAAY;CAC7D,MAAM3B,SAASiC,eAAeD,iBAAiBG;CAE/C,MAAM,CAAClC,UAAUoC,oBAAoB7C,SAAmBoC,YAAY;CACpE,MAAM,CAAC1B,UAAUoC,oBAAoB9C,SAAmBgC,iBAAiB;CACzE,MAAM,CAACrB,WAAWoC,gBAAgB/C,SAAS,MAAM;CACjD,MAAM,CAACY,eAAeoC,yBAAyBhD,SAAS,MAAM;CAC9D,MAAM,CAACa,cAAcoC,mBAAmBjD,SAAS,MAAM;CAGvD,MAAMkD,kBAAkBnD,OAAOsC,aAAa;CAC5C,MAAMc,kBAAkBpD,OAAOuC,aAAa;AAC5CY,iBAAgBE,UAAUf;AAC1Bc,iBAAgBC,UAAUd;CAG1B,MAAMvB,UAAUnB,aAAaoB,SAAkB;AAE9C4B,kBAAgB5B,KAAK;AAErBkC,kBAAgBE,UAAUpC,KAAK;IAC7B,EAAE,CAAC;CAEN,MAAMC,aAAarB,kBAAkB;EACpC,MAAMyD,OAAO,CAAC7C;AACdoC,kBAAgBS,KAAK;AACrBH,kBAAgBE,UAAUC,KAAK;IAC7B,CAAC7C,OAAO,CAAC;CAEZ,MAAMU,cAActB,aAAauB,SAAmB;AACnD0B,mBAAiB1B,KAAK;AACtBgC,kBAAgBC,UAAUjC,KAAK;IAC7B,EAAE,CAAC;CAEN,MAAMC,cAAcxB,aAAa0D,QAAkB;AAClDR,mBAAiBQ,IAAI;IACnB,EAAE,CAAC;CAEN,MAAMjC,gBAAgBzB,kBAAkB;AACvCkD,mBAAiBd,iBAAiB;IAChC,EAAE,CAAC;CAEN,MAAMV,WAAW1B,kBAAkB;AAClCmD,eAAa,MAAM;IACjB,EAAE,CAAC;CAEN,MAAMxB,aAAa3B,kBAAkB;AACpCmD,eAAa,KAAK;IAChB,EAAE,CAAC;CAEN,MAAMvB,iBAAiB5B,aAAa6B,WAAoB;AACvDuB,wBAAsBvB,OAAO;IAC3B,EAAE,CAAC;CAEN,MAAMC,WAAW9B,kBAAkB;AAClCiD,mBAAiB,YAAY;AAC7BC,mBAAiBd,iBAAiB;AAClCiB,kBAAgB,MAAM;AACtBE,kBAAgBC,UAAU,YAAY;IACpC,EAAE,CAAC;CAEN,MAAMzB,SAAS/B,kBAAkB;AAChCiD,mBAAiB,YAAY;AAC7BM,kBAAgBC,UAAU,YAAY;IACpC,EAAE,CAAC;CAEN,MAAMxB,kBAAkBhC,kBAAkB;AACzCqD,kBAAgB,KAAK;IACnB,EAAE,CAAC;CAEN,MAAMpB,iBAAiBjC,kBAAkB;AACxCqD,kBAAgB,MAAM;IACpB,EAAE,CAAC;CAEN,MAAMnB,mBAAmBlC,kBAAkB;AAC1CqD,mBAAiBM,SAAS,CAACA,KAAK;IAC9B,EAAE,CAAC;CAGN,MAAMC,QAAQ1D,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;EAAgB0B;EAAQtB;GAAmC;;;;;AAkBnF,SAAO0B,qBAAA;AAAA,QACC/D,WAAWkC,eAAe;;;;;AC5SlC,SAAAiC,SAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAH,EAAA,OAAAD,IAAA;AAAkB,GAAA,CAAAG,cAAAC,SAAAJ;AAAoDC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;AAAAF,IAAA,KAAAG;QAAA;AAAAD,cAAAF,EAAA;AAAAG,UAAAH,EAAA;;CAAA,IAAAI;AAAA,KAAAJ,EAAA,OAAAE,WAAA;AAIrDE,OAAAP,GAAG,sCAAsCK,UAAU;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,SAAAH,EAAA,OAAAI,IAAA;AAFhEC,OAAA,oBAAA;GACY,aAAA;GACC,WAAAD;GAAmD,GAC1DD;IACJ;AAAAH,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAJFK;;;;;;;;ACSJ,SAASI,aACPC,aACe;AACf,KAAI,CAACA,YACH,QAAO;AAIT,KACE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAACC,SAASD,YAAY,CAEvB,QAAOA;AAGT,QAAO;;;;;AAMT,SAAgBE,4BACdC,QACW;AACX,KAAIA,OAAOC,QACT,OAAM,IAAIC,MAAM,4CAA4C;AAK9D,QAAO;EACLC,MAHWP,aAAaI,OAAOI,UAAU;EAIzCC,OAAOL,OAAOM,cAAc;EAC5BC,SAASP,OAAOO;EAChBC,cAAcR,OAAOQ;EACrBC,eAAeT,OAAOS;EACtBC,UAAUV,OAAOU;EACjBC,SAASX,OAAOW;EAChBC,aAAaZ,OAAOY,eAAe;EACnCC,WAAWb,OAAOa;EACnB;;;;;AAMH,IAAaC,qBAAb,MAAaA,2BAA2BZ,MAA2B;CACjEC;CACAE;CACAG;CACAC;CACAC;CACAC;CACAC;CACAC;CAEAE,YAAYC,WAAsB;AAChC,QAAMA,UAAUT,QAAQ;AACxB,OAAKU,OAAO;AACZ,OAAKd,OAAOa,UAAUb;AACtB,OAAKE,QAAQW,UAAUX;AACvB,OAAKE,UAAUS,UAAUT;AACzB,OAAKC,eAAeQ,UAAUR;AAC9B,OAAKC,gBAAgBO,UAAUP;AAC/B,OAAKC,WAAWM,UAAUN;AAC1B,OAAKC,UAAUK,UAAUL;AACzB,OAAKC,cAAcI,UAAUJ;AAC7B,OAAKC,YAAYG,UAAUH;AAG3B,MAAIX,MAAMgB,kBACRhB,OAAMgB,kBAAkB,MAAMJ,mBAAmB;;;;;;AAQvD,SAAgBK,eAAenB,QAAkC;AAE/D,OAAM,IAAIc,mBADQf,4BAA4BC,OAAO,CACd;;;;;;;;;;ACzFzC,SAAgB0B,gBAAgBC,OAAwB;AACvD,QAAON,oBAAoBM,SAAS,KAAK;;;;;;;;;AAU1C,SAASC,qBAA6B;AACrC,KAAI,OAAOC,WAAW,YAAa,QAAO;AAK1C,QADeE,KAAKC,MAAMD,KAAKD,QAAQ,GAAG,QAAQ,CACpCG,SAAS,GAAG,CAACC,SAAS,GAAG,IAAI;;;;;;;AAQ5C,MAAMC,wBAAwBP,oBAAoB;;;;;;;AAQlD,SAAgBQ,wBAAgC;AAC/C,QAAOD;;AA2BR,SAAgBkB,0BAA0BC,MAAwC;AACjF,KAAI,OAAOA,SAAS,SAAU,QAAO;AAErC,KAAI;EACH,MAAMC,SAASC,KAAKC,MAAMH,KAAK;AAC/B,MAAI,CAACC,UAAU,OAAOA,WAAW,SAAU,QAAO;EAElD,MAAMG,MAAMH;AACZ,MAAIG,IAAIE,SAAS,OAAQ,QAAO,EAAEA,MAAM,QAAQ;AAChD,MACCF,IAAIE,SAAS,YACb,OAAOF,IAAIG,WAAW,YACtB,OAAOH,IAAII,aAAa,SAExB,QAAO;GACNF,MAAM;GACNC,QAAQH,IAAIG;GACZC,UAAUJ,IAAII;GACdC,MAAML,IAAIK;GACV;AAGF,SAAO;SACA;AACP,SAAO;;;AAIT,SAAgBE,4BAA4BX,MAAgD;AAC3F,KAAI,OAAOA,SAAS,SAAU,QAAO;AAErC,KAAI;EACH,MAAMC,SAASC,KAAKC,MAAMH,KAAK;AAC/B,MAAI,CAACC,UAAU,OAAOA,WAAW,SAAU,QAAO;EAElD,MAAMG,MAAMH;AACZ,MAAIG,IAAIE,SAAS,kBAAkB,CAACM,MAAMC,QAAQT,IAAIN,QAAQ,CAAE,QAAO;AACvE,SAAO;GAAEQ,MAAM;GAAgBR,SAASM,IAAIN;GAAS;SAC9C;AACP,SAAO;;;AAuBT,SAAgBuB,iBAAiBC,QAAgC;AAEhE,QADoBA,OAAOE,QAAQC,MAAMC,QAAMA,IAAEpB,SAAS,OAAO,EAC7CqB,QAAQzB,KAAK0B,UAAUN,OAAOE,QAAQ;;AAG3D,SAAgBK,mBACfE,UACAE,UACM;AACN,KAAIA,aAAa,KAAM,QAAO,EAAE;CAChC,MAAMC,QAAQH,SAASI,WAAWC,MAAMA,EAAEN,OAAOG,SAAS;AAC1D,KAAIC,UAAU,GAAI,QAAOH;AACzB,QAAOA,SAASZ,MAAM,GAAGe,QAAQ,EAAE;;AAGpC,SAASG,oBACRrD,GACAC,GACU;AACV,KAAID,MAAMC,EAAG,QAAO;AACpB,KAAI,CAACD,KAAK,CAACC,EAAG,QAAO;CAErB,MAAMqD,QAAQC,OAAOC,KAAKxD,EAAE;CAC5B,MAAMyD,QAAQF,OAAOC,KAAKvD,EAAE;AAC5B,KAAIqD,MAAMpD,WAAWuD,MAAMvD,OAAQ,QAAO;AAE1C,MAAK,MAAMwD,OAAOJ,OAAO;AACxB,MAAI,CAACC,OAAOI,UAAUC,eAAeC,KAAK5D,GAAGyD,IAAI,CAAE,QAAO;AAC1D,MAAI1D,EAAE0D,SAASzD,EAAEyD,KAAM,QAAO;;AAG/B,QAAO;;AAGR,SAAgBI,uBAAsEzE,OAAa;CAClG,MAAM0E,MAAMjF,OAAOO,MAAM;AACzB,KAAI,CAACgE,oBAAoBU,IAAIC,SAAS3E,MAAM,CAC3C0E,KAAIC,UAAU3E;AAEf,QAAO0E,IAAIC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5HZ,SAAgBU,sBACfC,SAC8B;CAC9B,MAAM,EAAEJ,YAAYI;CACpB,MAAMC,QAAQP,uBAAuB;CAErC,MAAMQ,cAAcZ,kBAAsD;AACzE,MAAI,OAAOa,WAAW,YAAa,QAAOC;EAE1C,MAAMC,iBAAiB;AACtB,OAAI;IAEH,MAAMK,OADOH,SAASC,cAAc,oBAAoB,EACrCG,aAAa,OAAO;AACvC,QAAI,CAACD,KAAM,QAAON;AAClB,WAAO,IAAIQ,IAAIF,MAAMP,OAAOU,SAASH,KAAK,CAACI,UAAU;WAC9C;AACP;;MAEE;AAEJ,SAAO;GACNC,KAAKZ,OAAOU,SAASH;GACrBM,QAAQb,OAAOU,SAASG;GACxBC,OAAOV,SAASU,OAAOC,MAAM,IAAId;GACjCC;GACAJ;GACA;IACC,CAACA,MAAM,CAAC;CAEX,MAAM,CAACH,UAAUqB,eAAe3B,eAC/BI,UAAUM,aAAa,GAAGE,OAC1B;AAEDb,iBAAgB;AACf,MAAI,CAACK,SAAS;AACbuB,eAAYf,OAAU;AACtB;;AAED,MAAI,OAAOD,WAAW,YAAa;EAEnC,MAAMiB,uBAAuB;AAC5BD,eAAYjB,aAAa,CAAC;;AAI3BkB,kBAAgB;AAGhBjB,SAAOkB,iBAAiB,SAASD,eAAe;AAChDb,WAASc,iBAAiB,oBAAoBD,eAAe;EAG7D,MAAME,gBAAgB,IAAIC,iBAAiBH,eAAe;EAC1D,MAAMI,eAAejB,SAASC,cAAc,QAAQ;AACpD,MAAIgB,aACHF,eAAcG,QAAQD,cAAc,EAAEE,WAAW,MAAM,CAAC;EAIzD,MAAMC,eAAe,IAAIJ,iBAAiBH,eAAe;AACzDO,eAAaF,QAAQlB,SAASqB,MAAM;GACnCF,WAAW;GACXG,SAAS;GACTC,YAAY;GACZC,iBAAiB,CAAC,OAAO,OAAM;GAC/B,CAAC;AAEF,eAAa;AACZ5B,UAAO6B,oBAAoB,SAASZ,eAAe;AACnDb,YAASyB,oBAAoB,oBAAoBZ,eAAe;AAChEE,iBAAcW,YAAY;AAC1BN,gBAAaM,YAAY;;IAExB,CAACrC,SAASM,YAAY,CAAC;AAE1B,QAAO,EAAEJ,UAAU;;;;;;;;;;;;;;;;;;;;;ACrFpB,SAAgBkD,0BAA0BC,SAAiD;CAC1F,MAAM,EAAEL,SAASE,OAAOC,aAAaE;CAErC,MAAMC,WAAWd,OAAOU,MAAM;AAC9BI,UAASC,UAAUL;CAGnB,MAAMM,sBAAsBjB,cAAc;AACzC,MAAI,CAACY,UAAUM,MAAO,QAAO;EAE7B,MAAMC,UACLR,MAAMS,KAAKC,OAAO;GACjBC,MAAM,GAAGV,SAASM,MAAK,GAAIG,EAAEC;GAC7BC,aAAaF,EAAEE;GACfC,aAAaH,EAAEG;GACfC,aAAaJ,EAAEI;GACf,EAAE;AAEJN,UAAQO,MAAMC,GAAGC,MAAMD,EAAEL,KAAKO,cAAcD,EAAEN,KAAK,CAAC;AACpD,SAAOf,gBAAgBY,QAAQ;IAC7B,CAACR,OAAOC,UAAUM,MAAM,CAAC;AAG5BnB,iBAAgB;AACf+B,UAAQC,MAAM,gDAAgD;GAC7DC,YAAYvB,QAAQuB;GACpBC,aAAa,CAAC,CAACrB;GACfsB,WAAWnB,SAASC,QAAQmB;GAC5BC,WAAWrB,SAASC,QAAQI,KAAKC,QAAMA,IAAEC,KAAK;GAC9CL,qBAAqBA,oBAAoBoB,MAAM,GAAG,GAAG,GAAG;GACxD,CAAC;AAEF,MAAI5B,QAAQuB,eAAeM,UAAUC,MAAM;AAC1CT,WAAQC,MAAM,4DAA4DtB,QAAQuB,WAAW;AAC7F;;EAGD,MAAMQ,gBAAgB,YAAY;AACjC,OAAI;AACH,QAAI,CAAC5B,UAAU;AACdkB,aAAQW,KAAK,gFAAgF;AAC7F;;IAID,MAAME,cADa5B,SAASC,QACuBI,KAAKC,SAAO;KAC9DC,MAAM,GAAGV,SAASM,MAAK,GAAIG,IAAEC;KAC7BC,aAAaF,IAAEE;KACfC,aAAaH,IAAEG;KACfC,aAAaJ,IAAEI;KACf,EAAE;AAEHK,YAAQC,MAAM,oEAAoE;KACjFG,WAAWS,YAAYR;KACvBC,WAAWO,YAAYvB,KAAKC,QAAMA,IAAEC,KAAI;KACxC,CAAC;AAEF,QAAIqB,YAAYR,SAAS,GAAG;AAC3B,WAAM1B,QAAQmC,KAAK,iBAAiB,CAAC;MAAEjC,OAAOgC;MAAa/B;MAAU,CAAC,CAAC;AACvEkB,aAAQC,MAAM,4DAA4D;;YAEnEc,OAAO;AACff,YAAQe,MAAM,wDAAwDA,MAAM;;;AAI9EL,iBAAe;IACb;EAAC/B;EAASA,QAAQuB;EAAYf;EAAqBL;EAAS,CAAC;;;;;;;;;;;;;AC1FjE,SAAgBqC,UAAUC,OAAkC;AAC3D,KAAI;EAEH,MAAMC,QAAQD,MAAME,MAAM,IAAI;AAC9B,MAAID,MAAME,WAAW,EAAG,QAAO;EAG/B,MAAMC,UAAUH,MAAM;AACtB,MAAI,CAACG,QAAS,QAAO;EAGrB,MAAMC,SAASD,QAAQE,QAAQ,MAAM,IAAI,CAACA,QAAQ,MAAM,IAAI;EAC5D,MAAMC,cAAcC,mBACnBC,KAAKJ,OAAO,CACVH,MAAM,GAAG,CACTQ,KAAKC,QAAM,OAAO,OAAOA,IAAEC,WAAW,EAAE,CAACC,SAAS,GAAG,EAAEC,MAAM,GAAG,CAAC,CACjEC,KAAK,GACR,CAAC;AAED,SAAOC,KAAKC,MAAMV,YAAY;SACvB;AACP,SAAO;;;;;;;;;;AAWT,SAAgBW,uBAAuBlB,OAA8B;AAEpE,QADgBD,UAAUC,MAAM,EAChBH,OAAO;;;;;AC2FxB,SAAS0E,qBAEPG,MAAyB;AAC1B,QAAO,CAAC,GAAGA,KAAK,CAACE,MAAMC,GAAGC,MAAM;EAC/B,MAAMC,QAAQF,EAAEL,iBAAiBK,EAAEJ;AAEnC,UADcK,EAAEN,iBAAiBM,EAAEL,aACpBM;GACd;;AAGH,SAASE,gBAAgBC,QAAwE;AAChG,QAAOA,OAAOC,WAAW;;AAG1B,SAASC,iBACRF,QACmD;AACnD,QAAOA,OAAOC,WAAW;;AAG1B,SAASE,yBACRR,GACAC,GACU;AACV,KAAID,MAAMC,EAAG,QAAO;AACpB,KAAID,EAAES,WAAWR,EAAEQ,OAAQ,QAAO;CAElC,MAAMC,uBAAO,IAAIC,KAAgC;AACjD,MAAK,MAAMN,UAAUL,EAAGU,MAAKE,IAAIP,OAAOQ,IAAIR,OAAO;AAEnD,MAAK,MAAMS,QAAQb,GAAG;EACrB,MAAMc,OAAOL,KAAKM,IAAIF,KAAKD,GAAG;AAC9B,MAAI,CAACE,KAAM,QAAO;AAElB,MAAIA,KAAKT,WAAWQ,KAAKR,OAAQ,QAAO;AACxC,OAAKS,KAAKE,SAAS,SAASH,KAAKG,SAAS,IAAK,QAAO;AACtD,OAAKF,KAAKG,YAAY,SAASJ,KAAKI,YAAY,IAAK,QAAO;AAC5D,OAAKH,KAAKI,cAAc,SAASL,KAAKK,cAAc,IAAK,QAAO;AAChE,MAAIJ,KAAK3B,mBAAmB0B,KAAK1B,eAAgB,QAAO;AACxD,MAAI2B,KAAKK,iBAAiBN,KAAKM,aAAc,QAAO;AACpD,OAAKL,KAAKM,eAAe,QAAQP,KAAKO,eAAe,GAAI,QAAO;AAChE,MAAIN,KAAKpB,kBAAkBmB,KAAKnB,cAAe,QAAO;AACtD,MAAIoB,KAAKnB,cAAckB,KAAKlB,UAAW,QAAO;;AAG/C,QAAO;;;;;;;;;;;AAYR,SAAgB0B,2BACfC,SACmC;CACnC,MAAM,EACLtD,MACAC,WACAC,UACAC,gBACAK,mBAAmB,MACnBC,wBACG6C;CAIJ,MAAMC,SAASzD,uBAAuBG,UAAU;CAChD,MAAMuD,oBAAoB9E,OACzB,QAAQ+E,KAAKC,QAAQ,CAACC,SAAS,GAAG,CAACC,MAAM,GAAG,GAAG,GAC/C;CACD,MAAMC,kBAAkBN,UAAUC,kBAAkBM;CAEpD,MAAM,CAAC/C,eAAegD,oBAAoBpF,SAAS,MAAM;CACzD,MAAM,CAACqF,qBAAqBC,0BAA0BtF,SAAS,MAAM;CACrE,MAAM,CAACuC,WAAWgD,gBAAgBvF,SAAwB,KAAK;CAC/D,MAAM,CAACwC,gBAAgBgD,qBAAqBxF,SAAwB,KAAK;CACzE,MAAM,CAAC4C,WAAW6C,gBAAgBzF,SAA0D,KAAK;CACjG,MAAM,CAAC0F,SAASC,cAAc3F,SAA8B,EAAE,CAAC;CAC/D,MAAM,CAACgC,iBAAiBC,sBAAsBjC,SAA6B4F,OAAU;CACrF,MAAM,CAACC,mBAAmBC,wBAAwB9F,SAAwB,KAAK;CAE/E,MAAM+F,iBAAiBhG,OAA0C,KAAK;CACtE,MAAMiG,gCAAgCjG,OAAO,MAAM;CAEnD,MAAMkG,+BAA+BnG,cAAc;AAClD,MAAI,CAAC+B,iBAAkB,QAAO;AAC9B,MAAIC,oBAAqB,QAAOA;AAChC,MAAI,CAACS,UAAW,QAAO;AACvB,SAAO,+BAA+BA;IACpC;EAACV;EAAkBC;EAAqBS;EAAU,CAAC;CAKtD,MAAME,UAAU9C,SAA6B;EAC5CuG,OAAO;EACPC,MAAMjB;EACN7D;EACA+E,OAAO,EAAEC,YAAY/E,WAAW;EAChCgF,gBAAgBC,OAAOC,WAAW;AACjCb,eAAYxB,SACXP,yBAAyBO,MAAMoC,MAAMb,QAAQ,GAAGvB,OAAOoC,MAAMb,QAC7D;AACD,OAAIc,WAAW,SAAUlB,wBAAuB,KAAK;;EAEtD,CAAC;CAIF,MAAMmB,QAAQ1F,uBAAuB;CAGrC,MAAM,CAAC4B,aAAa+D,kBAAkB1G,SAA2B,EAAE,CAAC;AACpEH,iBAAgB;EACf,MAAM8G,iBAAiBC,UAAwB;GAC9C,MAAME,UAAU7F,4BAA4B2F,MAAMG,KAAK;AACvD,OAAI,CAACD,QAAS;AACdJ,mBAAgBvC,WACfjD,gBAAgBiD,OAAK,KAAKjD,gBAAgB4F,QAAQE,QAAQ,GAAG7C,SAAO2C,QAAQE,QAC5E;;AAEFvE,UAAQwE,iBAAiB,WAAWN,cAAc;AAClD,eAAalE,QAAQyE,oBAAoB,WAAWP,cAAc;IAChE,CAAClE,QAAQ,CAAC;CAGb,MAAM,EAAE0E,aAAatG,sBAAsB,EAC1CuG,SAAS3E,QAAQ4E,eAAeC,UAAUC,QAAQnF,eAClD,CAAC;AAGFtB,2BAA0B;EACzB2B;EACA+E,OAAOjG,YAAY,EAAE;EACrB4F;EACA,CAAC;AAGFtH,iBAAgB;AACf,MAAI,CAAC2B,eAAgB;AACrB,MAAI,CAACiF,MAAO;EAEZ,MAAME,kBAAgB,OAAOC,YAAwB;GACpD,MAAMa,MAAMzG,0BAA0B4F,QAAMG,KAAK;AACjD,OAAI,CAACU,IAAK;AAEV,OAAIA,IAAIC,SAAS,UAAU;AAE1B,QAAI;KACH,MAAMC,SAAS,MAAMnG,eAAeiG,IAAIhG,UAAUgG,IAAI/F,QAAQ,EAAE,CAAC;KACjE,MAAMkG,aAA6B;MAClCF,MAAM;MACNG,QAAQJ,IAAII;MACZF;MACA;AACDlF,aAAQqF,KAAKC,KAAKC,UAAUJ,WAAS,CAAC;aAC9BK,OAAO;KACf,MAAML,WAA6B;MAClCF,MAAM;MACNG,QAAQJ,IAAII;MACZF,QAAQ;OACPO,SAAS,CACR;QACCR,MAAM;QACNS,MAAMF,iBAAiBG,QAAQH,MAAMnB,UAAU;QAC/C,CACD;OACDuB,SAAS;OACV;MACA;AACD5F,aAAQqF,KAAKC,KAAKC,UAAUJ,SAAS,CAAC;;AAEvC;;AAGD,OAAIH,IAAIC,SAAS,OAEhBjF,SAAQqF,KAAKC,KAAKC,UADiB,EAAEN,MAAM,QAAQ,CACd,CAAC;;AAIxCjF,UAAQwE,iBAAiB,WAAWN,gBAAc;AAClD,eAAalE,QAAQyE,oBAAoB,WAAWP,gBAAc;IAChE;EAACnF;EAAgBiF;EAAOhE;EAAQ,CAAC;AAGpC5C,iBAAgB;AACfkG,iBAAeZ,UAAU;AACzBa,gCAA8Bb,UAAU;AACxCC,mBAAiB,MAAM;AACvBE,yBAAuB,MAAM;AAC7BC,eAAa,KAAK;AAClBC,oBAAkB,KAAK;AACvBG,aAAW,EAAE,CAAC;AACd1D,qBAAmB2D,OAAU;AAC7BE,uBAAqB,KAAK;IACxB,CAACxE,UAAU,CAAC;AAIfzB,iBAAgB;AACf,MAAI4C,QAAQ4E,eAAeC,UAAUC,KAAM;AAE3CxB,iBAAeZ,UAAU;AACzBC,mBAAiB,MAAM;AACvBE,yBAAuB,MAAM;IAC3B,CAAC7C,QAAQ4E,WAAW,CAAC;AAGxBxH,iBAAgB;AACf,MAAI,CAACoG,6BAA8B;AACnC,MAAI;AACHH,wBAAqBwC,aAAaC,QAAQtC,6BAA6B,CAAC;UACjE;AACPH,wBAAqB,KAAK;;IAEzB,CAACG,6BAA6B,CAAC;CAElC,MAAMuC,oBAAoB5I,YAAY,YAA2B;AAChE,MAAI6C,QAAQ4E,eAAeC,UAAUC,KACpC,OAAM,IAAIa,MAAM,iCAAiC;AAGlD,MAAI,CAACrC,eAAeZ,SAAS;GAG5B,MAAMsD,SAAS,OAAOC,WAAW,cAAcA,OAAOC,SAASF,SAAS7C;AACxEG,kBAAeZ,UAAU1C,QAAQmG,KAAwB,sBAAsB,CAC9E;IAAEtH;IAAWmH;IAAQ,CACrB,CAAC;;EAGH,MAAMI,aAAa,MAAM9C,eAAeZ;AACxC,MAAI,CAAC0D,WAAWC,QACflI,gBAAeiI,WAAW;AAG3BtD,eAAasD,WAAWtG,UAAU;AAClC,MAAIsG,WAAWrG,eAAgBgD,mBAAkBqD,WAAWrG,eAAe;AAC3E4C,mBAAiB,KAAK;IACpB,CAAC3C,SAASnB,UAAU,CAAC;AAExBzB,iBAAgB;AACf,MAAI4C,QAAQ4E,eAAeC,UAAUC,KAAM;AAC3C,MAAInF,cAAe;AACnB,MAAIQ,UAAW;AAEf4F,qBAAmB,CAACO,OAAOd,YAAU;AACpCe,WAAQf,MAAM,mDAAmDA,QAAM;AAEvE,OAAIA,WAAS,OAAOA,YAAU,YAAY,UAAUA,WAAS,WAAWA,QACvExC,cAAawC,QAAkD;IAE/D;IACA;EAACxF,QAAQ4E;EAAYjF;EAAeQ;EAAW4F;EAAkB,CAAC;CAErE,MAAMS,qBAAqBnJ,cAA+B;AAEzD,SAAO4F,QAAQwD,QAAQC,MAA0BA,EAAEzF,WAAW,UAAU;IACtE,CAACgC,QAAQ,CAAC;CAEb,MAAM0D,gBAAgBtJ,cACfgD,qBAAqBmG,mBAAmBC,OAAO1F,gBAAgB,CAAC,EACtE,CAACyF,mBACF,CAAC;CAED,MAAMI,kBAAkBvJ,cACjBgD,qBAAqBmG,mBAAmBC,OAAOvF,iBAAiB,CAAC,EACvE,CAACsF,mBACF,CAAC;AAEDpJ,iBAAgB;AAKf,MAAImC,gBAAiB;EACrB,MAAMsH,YACLzD,qBAAqBuD,cAAcG,MAAMJ,QAAMA,IAAElF,OAAO4B,kBAAkB,GACvEA,oBACA;EACJ,MAAM2D,WAAWJ,cAAc,IAAInF,MAAM2B;AACzC,MAAI0D,UAAWrH,oBAAmBqH,UAAU;WACnCE,SAAUvH,oBAAmBuH,SAAS;IAC7C;EAACxH;EAAiBoH;EAAevD;EAAkB,CAAC;AAEvDhG,iBAAgB;AAEf,MAAI,CAACmC,gBAAiB;AAEtB,MADeiH,mBAAmBM,MAAMJ,QAAMA,IAAElF,OAAOjC,gBAAgB,CAC3D;AACZC,qBAAmBmH,cAAc,IAAInF,MAAM2B,OAAU;IACnD;EAAC5D;EAAiBiH;EAAoBG;EAAc,CAAC;CAExD,MAAM/G,cAAcI,QAAQ4E,eAAeC,UAAUC;CACrD,MAAMjF,UAAUD,eAAeD,iBAAiBiD;CAChD,MAAMqE,YAAY,CAACpH;AAGnBzC,iBAAgB;AACf,MAAI,CAACyC,QAAS;AACd,MAAI,CAACuD,kBAAmB;AACxB,MAAI,CAACuD,cAAcG,MAAMJ,QAAMA,IAAElF,OAAO4B,kBAAkB,CAAE;AAC5D,MAAIG,8BAA8Bb,QAAS;AAE3Ca,gCAA8Bb,UAAU;AACxC,MAAInD,oBAAoB6D,kBAAmB5D,oBAAmB4D,kBAAkB;IAC9E;EAACvD;EAASuD;EAAmBuD;EAAepH;EAAgB,CAAC;CAEhE,MAAM2H,eAAe/J,YAAY,YAA6B;AAC7D,QAAM4I,mBAAmB;EAEzB,MAAMoB,SAAS,EACd,GAAIpH,iBAAiB,EAAEA,gBAAgB,GAAG,EAAE,EAC5C;EAED,MAAMmF,WAAS,MAAMlF,QAAQmG,KAAyB,gBAAgB,CAACgB,OAAO,CAAC;AAC/E3H,qBAAmB0F,SAAOzF,SAAS;AACnC,SAAOyF,SAAOzF;IACZ;EAACsG;EAAmB/F;EAASD;EAAe,CAAC;CAEhD,MAAML,oBAAoDrC,eAClD;EACNoC,UAAUF;EACV0H;EACAhE,SAAS0D;EACTC;EAEAQ,qBAAqB,YAAY;AAChC,SAAMF,cAAc;;EAGrBG,mBAAmB5H,aAAqB;AACvCD,sBAAmBC,SAAS;;EAG7B6H,UAAU,OAAO7H,YAAkB8H,aAAqB;AACvD,SAAMxB,mBAAmB;AACzB,SAAM/F,QAAQmG,KAAK,gBAAgB,CAClC1G,YACA,EAAEmC,OAAO2F,UAAU,CACnB,CAAC;;EAGHC,WAAW,OAAO/H,eAAqB;AACtC,SAAMsG,mBAAmB;AACzB,SAAM/F,QAAQmG,KAAK,iBAAiB,CAAC1G,WAAS,CAAC;AAC/C,OAAIA,eAAaF,iBAAiB;IACjC,MAAMkI,aAAad,cAAcF,QAAQC,QAAMA,IAAElF,OAAO/B,WAAS,CAAC,IAAI+B;AACtE,QAAIiG,YAAY;AACfjI,wBAAmBiI,WAAW;AAC9B;;AAGD,UAAMP,cAAc;;;EAItBQ,aAAa,OAAOjI,eAAqB;AACxC,SAAMsG,mBAAmB;AACzB,SAAM/F,QAAQmG,KAAK,iBAAiB,CAAC1G,WAAS,CAAC;;EAGhDkI,UAAU,OAAOlI,eAAqB;AACrC,SAAMsG,mBAAmB;AACzB,SAAM/F,QAAQmG,KAAK,gBAAgB,CAAC1G,WAAS,CAAC;AAC9C,OAAIA,eAAaF,gBAChBC,oBAAmBmH,cAAcF,QAAQC,QAAMA,IAAElF,OAAO/B,WAAS,CAAC,IAAI+B,GAAG;;EAG3E,GACD;EACCjC;EACA0H;EACAN;EACAC;EACAM;EACAnB;EACA/F;EAEF,CAAC;AAGD5C,iBAAgB;AACf,MAAI,CAACoG,6BAA8B;AACnC,MAAI,CAAC3D,QAAS;AACd,MAAI,CAACN,gBAAiB;AACtB,MAAI,CAACoH,cAAcG,MAAMJ,QAAMA,IAAElF,OAAOjC,gBAAgB,CAAE;AAE1D,MAAI;AACHsG,gBAAa+B,QAAQpE,8BAA8BjE,gBAAgB;UAC5D;IAGN;EAACiE;EAA8B3D;EAASN;EAAiBoH;EAAc,CAAC;AAE3E,QAAO;EACNpH;EACAC;EACAE;EACAC;EACAC;EACAC;EACAC;EACAC;EACAI;EACAH;EACAE;EACA;;;;;;;;;ACxhBF,SAASyI,uBAAuBC,MAAc;AAC7C,QAAOA,KAAKC,QAAQ,YAAY,GAAG;;AAGpC,SAASC,YAAYC,MAA8B;CAClD,MAAMC,WAAYD,MAAwCC;AAC1D,QAAO,OAAOA,aAAa,YAAYA,SAASC,SAAS,IAAID,WAAW;;;;;;;;;;AAWzE,MAAME,gBACLC,SACAC,aAGI;AACJ,KAAI,CAACD,QAAQI,SAASJ,QAAQI,MAAMN,WAAW,EAC9C,QAAO,EAAE;AAGV,QAAOE,QAAQI,MACbC,QAAQC,MAAMA,EAAEC,SAAS,gBAAgBD,EAAEC,SAAS,OAAO,CAC3DC,KAAKZ,SAAsB;EAC3B,MAAMW,OAAOX,KAAKW;AAGlB,MAAIA,SAAS,OACZ,QAAO;GACNA,MAAM;GACNE,MAAMb,KAAKa;GACX;AAIF,MAAIF,SAAS,YACZ,QAAO;GACNA,MAAM;GACNE,MAAMb,KAAKa;GACX;AAIF,MAAIxB,aAAaW,KAAK,EAAE;GACvB,MAAMc,WAAW1B,YAAYY,KAAK;GAClC,MAAMe,aAAaf,KAAKe;GAGxB,IAAIC,OAAmB,EAAE;GACzB,IAAIC;GACJ,IAAIC;GACJ,IAAIC,UAAU;GAKd,MAAMlB,WAAWF,YAAYC,KAAK;AAElC,OAAIA,KAAKoB,UAAU,qBAAqBpB,KAAKoB,UAAU,kBACtDJ,QAAQhB,KAAKqB,SAAwB,EAAE;YAC7BrB,KAAKoB,UAAU,oBAAoB;AAC7CJ,WAAQhB,KAAKqB,SAAwB,EAAE;AACvCH,aAASlB,KAAKsB;cACJtB,KAAKoB,UAAU,gBAAgB;AACzCJ,WAAQhB,KAAKqB,SAAwB,EAAE;AACvCF,cAAU;AACVD,aAAS,EAAEK,OAAOvB,KAAKwB,WAAW;;AAGnC,OAAIvB,SACHgB,YAAWhB;YACDD,KAAKoB,UAAU,kBAGzBH,YAAW;OAEXA,YAAWQ,KAAKC,UAAU1B,KAAKqB,SAASL,KAAK;AAE9C,OAAIhB,KAAKoB,UAAU,kBAElBH,YAAWrB,uBAAuBqB,SAAS;GAI5C,MAAMU,aAAatB,SAASuB,eAAeb;AAC3C,UAAO;IACNJ,MAAM;IACNG;IACAC;IACAE;IACAD;IACAE;IACAC;IAEA,GAAIQ,YAAYhB,SAAS,eAAe;KACvCkB,WAAWF,WAAWG;KACtBC,QAAQ;MACPpB,MAAM;MACNsB,QAAQ;MACT;KACA;IACD;;AAIF,MAAItB,SAAS,gBAAgB;GAC5B,MAAMG,WAAWd,KAAKc;GACtB,MAAMC,aAAaf,KAAKe;GAExB,IAAIC,OAAmB,EAAE;GACzB,IAAIC;GACJ,IAAIC;GACJ,IAAIC,UAAU;AAEd,OAAInB,KAAKoB,UAAU,qBAAqBpB,KAAKoB,UAAU,kBACtDJ,QAAQhB,KAAKqB,SAAwB,EAAE;YAC7BrB,KAAKoB,UAAU,oBAAoB;AAC7CJ,WAAQhB,KAAKqB,SAAwB,EAAE;AACvCH,aAASlB,KAAKsB;cACJtB,KAAKoB,UAAU,gBAAgB;AACzCJ,WAAQhB,KAAKqB,SAAwB,EAAE;AACvCF,cAAU;AACVD,aAAS,EAAEK,OAAOvB,KAAKwB,WAAW;;GAGnC,MAAMvB,WAAWF,YAAYC,KAAK;AAClC,OAAIC,SACHgB,YAAWhB;YACDD,KAAKoB,UAAU,kBACzBH,YAAW;OAEXA,YAAWQ,KAAKC,UAAU1B,KAAKqB,SAASL,KAAK;AAE9C,OAAIhB,KAAKoB,UAAU,kBAClBH,YAAWrB,uBAAuBqB,SAAS;GAG5C,MAAMU,aAAatB,SAASuB,eAAeb;AAC3C,UAAO;IACNJ,MAAM;IACNG;IACAC;IACAE;IACAD;IACAE;IACAC;IACA,GAAIQ,YAAYhB,SAAS,eAAe;KACvCkB,WAAWF,WAAWG;KACtBC,QAAQ;MACPpB,MAAM;MACNsB,QAAQ;MACT;KACA;IACD;;AAIF,MAAItB,SAAS,aACZ,QAAO;GACNA,MAAM;GACNuB,YAAY;GACZC,IAAInC,KAAKoC;GACTC,KAAKrC,KAAKqC;GACVC,OAAOtC,KAAKsC,SAAS;GACrB;AAIF,MAAI3B,SAAS,mBAAmB;AAC/B4B,WAAQC,KAAK,6BAA6B7B,KAAI,qCAAsC;AACpF,UAAO;;AAIR4B,UAAQC,KAAK,kCAAkC7B,OAAO;AACtD,SAAO;GACN,CACDF,OAAOgC,QAAQ;;;;;;;;;;;;;;;;;;;;;AAwBlB,MAAaC,6BAA6B5D,iCACxCsB,SAAoBC,aAAmD;CACvE,MAAMsC,4BAAY,IAAIC,MAAM;AAE5B,SAAQxC,QAAQyC,MAAhB;EACC,KAAK,QAAQ;GAIZ,MAAMG,eAHY5C,QAAQI,OAAOC,QAC/BC,MAAmDA,EAAEC,SAAS,OAC/D,GAC8BC,KAAKZ,MAAMiD,SAAS;IAClDd,IAAIc,IAAIC,UAAU;IAClBvC,MAAMX,KAAKmD,WAAWC,WAAW,SAAS,GAAI,UAAqB;IACnEC,MAAMrD,KAAKsD,YAAY;IACvBC,SAAS,CACRvD,KAAKmD,WAAWC,WAAW,SAAS,GACjC;KACAzC,MAAM;KACN6C,OAAOxD,KAAKqC;KACZiB,UAAUtD,KAAKsD,YAAY;KAC3B,GACA;KACA3C,MAAM;KACN2C,UAAUtD,KAAKsD,YAAY;KAC3BG,MAAMzD,KAAKqC;KACXqB,UAAU1D,KAAKmD,aAAa;KAC5B,CACH;IACDQ,aAAa3D,KAAKmD,aAAa;IAC/BpB,QAAQ,EAAEpB,MAAM,YAAoB;IACpC,EAAE;AACH,UAAO;IACNkC,MAAM;IACNV,IAAI/B,QAAQ+B;IACZQ;IACAY,SAASpD,aAAaC,SAASC,SAAS;IACxC2C;IACA;;EAGF,KAAK,SACJ,QAAO;GACNH,MAAM;GACNV,IAAI/B,QAAQ+B;GACZQ;GACAY,SAASpD,aAAaC,SAASC,SAAQ;GACvC;EAEF,KAAK,aAAa;GAKjB,MAAMuD,cAAcxD;AAIpB,UAAO;IACNyC,MAAM;IACNV,IAAI/B,QAAQ+B;IACZQ;IACAY,SAASpD,aAAaC,SAASC,SAAS;IACxCA,UAAU;KACTyD,sBAAsBF,YAAYC;KAClCE,eAAexD,MAAMyD,QAAQJ,YAAYH,KAAK,GAC3CG,YAAYH,OACZG,YAAYH,OACX,CAACG,YAAYH,KAAK,GAClBQ;KACJC,QAAQ,EAAC;KACV;IACA;;EAGF;AACC3B,WAAQC,KAAK,6BAA6BpC,QAAQyC,OAAO;AACzD,UAAO,EAAE;;EAGZ;;;;ACnRD,MAAMsD,yBAAyB;;;;;;;;;;;;;;;;AAkI/B,SAAgBsC,mBAAiBC,SAA0D;CAC1F,MAAM,EACL7B,UACAC,MACAC,WACAC,SACAE,UACAC,gBACAI,eAAe,OACfC,+BAA+B,MAC/BC,aACAC,UAAUiB,mBACPD;CAEJ,MAAME,kBAAkBjE,oBAAoB;CAC5C,MAAM,CAACkE,cAAcC,mBAAmBtE,SAA8C,EAAE,CAAC;CAMzF,MAAM,CAAC8B,eAAeyC,yBAAyBvE,SAAqC,KAAK;CACzF,MAAMwE,QAAQhD,uBAAuB;CACrC,MAAMwC,kBAAkBlE,cAAc;AAErC,SADcmD,YAAYyB,MAAMC,WAAWA,OAAOH,UAAUA,MAAM,EACpDI;IACZ,CAAC3B,aAAauB,MAAM,CAAC;CAIxB,MAAMK,cAAc5D,SAA2B;EAC9C6D,OAAO;EACPC,MAAM1C,YAAYV;EAClBW;EACA0C,OAAO,EAAEC,YAAY1C,WAAW;EAChC2C,aAAa7C,YAAY;EACzB8C,gBAAgBC,UAAU;AACzBb,yBAAsBa,OAAOtD,iBAAiB,KAAK;;EAEpD,CAAC;CAUF,MAAM+D,wBAAwBnE,uBARG5B,cAAc;EAC9C,MAAMwF,SAAiF,EAAE;AACzF,MAAIlB,gBAAiBmB,QAAOC,OAAOF,QAAQlB,gBAAgB;AAC3D,MAAID,eAAgBoB,QAAOC,OAAOF,QAAQnB,eAAe;AACzD,SAAOmB,OAAOG;AACd,SAAOF,OAAOG,KAAKJ,OAAO,CAACK,SAAS,IAAIL,SAASM;IAC/C,CAACxB,iBAAiBD,eAAe,CAAC,CAIpC;CAED,MAAM2B,oBAAoB3B,gBAAgBsB;CAC1C,MAAMM,yBAAyBhG,OAAsB,KAAK;CAC1D,MAAMiG,yBAAyBjG,OAAO+F,mBAAmBG,oBAAoB;AAC7ED,wBAAuBE,UAAUJ,mBAAmBG;CAEpD,MAAME,cAAcpG,OAAO2C,SAAS;AACpCyD,aAAYD,UAAUxD;AAEtB7C,iBAAgB;AACf0E,wBAAsB,KAAK;IACzB,CAAClC,SAAS,CAAC;CAEd,MAAM+D,mBAAmBxG,YACxB,OAAOkE,cAA0C;AAChD,MAAI,CAACzB,SAAU;AACf,MAAIwC,YAAYwB,eAAeC,UAAUC,KAAM;AAE/C,MAAI;AAIHhC,yBAHe,MAAMM,YAAY4B,KAAiC,oBAAoB,CACrF3C,UACA,CAAC,IAC8B,KAAK;WAC7B4C,OAAO;AACfC,WAAQD,MAAM,oDAAoDA,MAAM;;IAG1E,CAACrE,UAAUwC,YACZ,CAAC;CASD,MAAM+B,iBAAiB9G,cAAc;EACpC,MAAMoG,UAAUC,YAAYD;AAC5B,SAAO,IAAIW,IAAIX,SAASY,KAAKC,MAAMA,EAAEhC,KAAK,IAAI,EAAE,CAAC;IAC/C,CAACrC,SAAS,CAAC;CAGd,MAAMgB,kBAAkB9D,aACtBgD,aAAmG;EACnG,MAAMoE,OAAOtE,UAAUgC,MAAMqC,QAAMA,IAAEhC,SAASnC,SAAS;AACvD,MAAI,CAACoE,KAAM,QAAO;AAClB,SAAO;GACNrD,aAAaqD,KAAKrD;GAClBC,aAAaoD,KAAKpD;GAClB;IAEF,CAAClB,SACF,CAAC;CAGD,MAAMe,cAAc7D,YACnB,OAAOgD,YAAkBC,SAA2D;AACnF,MAAI,CAACF,eACJ,OAAM,IAAIsE,MAAM,+BAA+B;AAGhD,MAAI,CAACL,eAAeM,IAAItE,WAAS,CAChC,OAAM,IAAIqE,MAAM,SAASrE,WAAQ,oCAAqC;AAGvE,SAAOD,eAAeC,YAAUC,QAAQ,EAAE,CAAC;IAE5C,CAACF,gBAAgBiE,eAClB,CAAC;CAID,MAAM,EAAEO,eAAeC,+BAA+BtH,cAGjD;EACJ,MAAM0G,WAAwB,EAAE;EAChC,MAAMa,uBAAiC,EAAE;AAGzC,OAAK,MAAML,UAAQtE,YAAY,EAAE,EAAE;AAIlC,OAAI,EAHsBK,iBAAiB,UAAU,CAACzB,kBAAkB0F,OAAKpD,YAAY,EAIxFyD,sBAAqBE,KAAKP,OAAKjC,KAAK;AAOrCyB,YAAOQ,OAAKjC,QAAQ;IACnBpB,aAAaqD,OAAKrD,eAAe;IACjC6D,YAAYR,OAAKS,eAAe,EAAE;IAClCC,SAAS,OAAO7E,WAAkB;AAEjC,YAAOtB,iBADY,MAAMkC,YAAYuD,OAAKjC,MAAMlC,OAAgC,CAC7C;;IAEpC;;AAGF,SAAO;GAAEsE,eAAeX;GAAQY,4BAA4BC;GAAsB;IAChF;EAAC3E;EAAUe;EAAaV;EAAa,CAAC;CAQzC,MAAM6E,OAAO7G,aAA0C;EACtD+D,OAAOD;EACPgD,OAAOV;EACPC;EACAU,sCAAsC;EACtCC,6BAA6B;EAC7BC,QAAQ;EACR,CAAC;CAEF,MAAMC,oBAAoB1C,OAAO2C,OAAO7D,aAAa,CAAC8D,MAAMC,MAAMA,GAAGC,SAAS,YAAY;CAC1F,MAAMC,YACLV,KAAKW,WAAW,eAAeX,KAAKW,WAAW,eAAeN;CAE/D,MAAMO,WAAWnH,2BAA2BoH,kBAAkB;EAC7DH;EACAE,UAAUZ,KAAKY;EACfE,UAAU5I,eACF;GACNuE;GACA,GAAIuD,KAAKlB,SAAS,EAAEA,OAAOkB,KAAKlB,MAAMiC,SAAS;GAC/C,GACD,CAACtE,cAAcuD,KAAKlB,MACrB,CAAA;EACA,CAAC;CAEF,MAAM,CAACkC,cAAc5I,gBAAsD,EAAEkG,SAAS,MAAM,EAAE;CAE9F,MAAM2C,WAAWjJ,kBACVgJ,WAAW1C,SAAS4C,OAAOC,iBAAiB,CAAClB,SAAS,EAAE,EAC9D,CAACe,WACF,CAAC;CACD,MAAMI,WAAWpJ,kBAAkB,IAAI,EAAE,CAAC;CAE1C,MAAMqJ,kBAAkBhJ,SAASiJ,mBAAmB;EACnD9D,OAAO;GAAEoD;GAAUF;GAAW;EAC9BO;EACAG;EACA1E;EACA,CAAC;CAEF,MAAM6E,2BAA2BvJ,YAAY,YAAY;AACxD,MAAI,CAACoD,6BAA8B;EAEnC,MAAMoG,iBAAiB7D,OAAO8D,QAAQhF,aAAa,CACjDiF,QAAQ,GAAGf,YAAYA,QAAQF,SAAS,YAAY,CACpDvB,KAAK,CAACyC,gBAAgBA,WAAW;AAEnC,MAAIH,eAAezD,WAAW,GAAG;AAChC,SAAMsD,gBAAgBO,OAAO;AAC7B;;AAGD,OAAK,MAAMD,gBAAcH,eACxB,MAAK,MAAMK,OAAO7B,KAAKY,SACtB,MAAK,MAAMkB,QAAQD,IAAIE,SAAS,EAAE,CACjC,KAAIxI,aAAauI,KAAK,IAAIA,KAAKH,eAAeA,cAAY;AACzD3B,QAAKgC,cAAc;IAClBL,YAAAA;IACAvC,MAAM9F,YAAYwI,KAAK;IACvBG,QAAQ;IACR,CAAC;AACF;;AAMJvF,mBAAiBwF,SAAS;GACzB,MAAMC,OAAO,EAAE,GAAGD,MAAM;AACxB,QAAK,MAAMP,gBAAcH,eACxB,QAAOW,KAAKR;AAEb,UAAOQ;IACN;AAEF,QAAMd,gBAAgBO,OAAO;IAC3B;EAACxG;EAA8BqB;EAAcuD;EAAMqB;EAAgB,CAAC;AAEvEpJ,iBAAgB;EACf,MAAMmK,cAAcjE,uBAAuBG;AAC3C,MAAI,CAAC8D,YAAa;AAClB,MAAI,CAAC3H,SAAU;AACf,MAAIwC,YAAYwB,eAAeC,UAAUC,KAAM;EAE/C,MAAM0D,cAAc,YAAY;AAC/BlE,0BAAuBG,UAAU;AACjC,SAAM0B,KAAKsC,YAAY,EAAEC,MAAMH,aAAa,CAAC;;AAG9CC,eAAa,CAACG,OAAO1D,YAAU;AAC9BC,WAAQD,MAAM,4DAA4DA,QAAM;IAC/E;IACA;EAACrE;EAAUwC,YAAYwB;EAAYuB;EAAM/C;EAAY,CAAC;CAEzD,MAAMwF,QAAQzK,YACb,OAAO+I,YAA2B;AAOjC,MAH4BA,QACeD,UAAU8B,QAAQ7F,WAAW,SAEpD;GAGnB,MAAM8F,eAAe9B,QAAQ+B,QAAQ;AACrC,OAAI,CAACD,gBAAgBA,aAAapC,SAAS,OAAQ;GAGnD,MAAMsC,iBAAiB;IACtBC,IAAI,SAASC,KAAKC,KAAK,CAAA,GAAIC,KAAKC,QAAQ,CAACC,SAAS,GAAG,CAACC,MAAM,GAAG,EAAE;IACjEC,MAAMxC,QAAQwC;IACdC,2BAAW,IAAIP,MAAM;IACrBlB,OAAO,CAAC;KAAEtB,MAAM;KAAiB8B,MAAMM,aAAaN;KAAM,CAAA;IAC1D;AAGDvC,QAAK0D,YAAY,CAAC,GAAG1D,KAAKY,UAAUmC,eAAe,CAAC;AACpD;;AAGD,QAAMxB,0BAA0B;EAEhC,MAAMsB,iBAAe9B,QAAQ+B,QAAQ;AACrC,MAAI,CAACD,kBAAgBA,eAAapC,SAAS,OAAQ;AAGnD,MAAI,CAAChG,UAAU;GACd,MAAM4D,sBAAsBD,uBAAuBE;AACnD,OAAI,CAACD,qBAAqB;AACzBU,YAAQD,MAAM,0EAA0E;AACxF;;AAGDX,0BAAuBG,UAAUuE,eAAaN;AAC9C,SAAMlE,qBAAqB;AAC3B;;AAGD,QAAM2B,KAAKsC,YAAY,EAAEC,MAAMM,eAAaN,MAAM,CAAC;IAEpD;EAAC9H;EAAUuF;EAAMuB;EAClB,CAAC;CAED,MAAMoC,SAAS3L,YACd,OAAO+I,cAA2B;AACjC,MAAI,CAACtG,SAAU;AAEf,QAAM8G,0BAA0B;EAEhC,MAAMqC,cAAc/J,mBAAmBmG,KAAKY,UAAUG,UAAQ8C,YAAY,KAAK;AAC/E7D,OAAK0D,YAAYE,YAAY;EAE7B,MAAMf,iBAAe9B,UAAQ+B,QAAQ;AACrC,MAAI,CAACD,kBAAgBA,eAAapC,SAAS,OAAQ;AAEnD,QAAMT,KAAKsC,YAAY,EAAEC,MAAMM,eAAaN,MAAM,CAAC;IAEpD;EAAC9H;EAAUuF;EAAMuB;EAClB,CAAC;CAED,MAAMuC,WAAW9L,YAChB,OAAO6L,aAA2C;AACjD,MAAI,CAACpJ,SAAU;AAEf,QAAM8G,0BAA0B;EAEhC,MAAMqC,gBAAc/J,mBAAmBmG,KAAKY,UAAUiD,SAAS;AAC/D7D,OAAK0D,YAAYE,cAAY;AAE7B,QAAM5D,KAAK+D,YAAY;IAExB;EAACtJ;EAAUuF;EAAMuB;EAClB,CAAC;CAED,MAAMyC,WAAWhM,YAAY,YAA2B;AACvDgI,OAAKiE,MAAM;AACX,QAAM5C,gBAAgBO,OAAO;IAC3B,CAAC5B,MAAMqB,gBAAgB,CAAC;CAE3B,MAAM6C,kBAAkBlM,aACtBsE,cAAwE;AACxE,MAAI,CAAC7B,SAAU;EAEf,IAAIO,aAAW;AACf,OAAK,MAAM6G,SAAO7B,KAAKY,UAAU;AAChC,QAAK,MAAMkB,UAAQD,MAAIE,SAAS,EAAE,CACjC,KAAIxI,aAAauI,OAAK,IAAIA,OAAKH,eAAerF,UAAQqF,YAAY;AACjE3G,iBAAW1B,YAAYwI,OAAK;AAC5B;;AAGF,OAAI9G,WAAU;;AAGfgF,OAAKgC,cAAc;GAClBL,YAAYrF,UAAQqF;GACpBvC,MAAMpE;GACNiH,QAAQ3F,UAAQ6H,UAAU,UAAU7H,UAAQsC,WAAWtC,UAAQsC;GAC/D,CAAC;IAEH,CAACnE,UAAUuF,KACZ,CAAC;CAED,MAAMoE,mBAAmBpM,aACvBsE,cAAuD;AACvD,MAAI,CAAC7B,SAAU;AACf4G,kBAAgBjB,OAAO9D,UAAQqF,YAAYrF,UAAQ+H,QAAQ;IAE5D,CAAC5J,UAAU4G,gBACZ,CAAC;CAED,MAAMqC,cAAc1L,aAClB4I,eAAuC;AACvC,MAAI,CAACnG,SAAU;AACfuF,OAAK0D,YAAY9C,WAAmC;IAErD,CAACnG,UAAUuF,KACZ,CAAC;CAED,MAAMsE,QAAQpM,eACN;EACN0I;EACAF;EACA+B;EACAkB;EACAG;EACAE;EACAE;EACAE;EACAV;EACApI,UAAU,EAAE,GAAI2C,yBAAyB,EAAE,EAAE;EAC7C,GACD;EACC2C;EACAF;EACA+B;EACAkB;EACAG;EACAE;EACAE;EACAE;EACAV;EACAzF;EAEF,CAAC;AAEDqG,OAAMhJ,SAASuC,aAAaK;CAE5B,MAAMxC,UAAUpD,wBAAwBgM,MAAM;AAE9CtD,YAAW1C,UAAU5C;AAQrB,QAAO;EACNA;EACAC,OARa3D,YAAY,YAAY;AACrC,SAAMqJ,gBAAgBO,OAAO;AAC7BlF,mBAAgB,EAAE,CAAC;AACnBsD,QAAKuE,cAAc;KACjB,CAACvE,MAAMqB,gBAAgB,CAAC;EAK1BzF,eAAe;GACdC;GACAC;GACA;EACD5B,eAAe;GACd+B,SAASZ;GACTa,WAAWhC;GACXiC,cAAcqC;GACdpC;GACD;EACA;;;;;;;;;;;;;;;;;;;;;;AC3dF,MAAMiL,0BAA0B7C,cAAmD,KAAK;;;;AAKxF,SAAO8C,sBAAA;CACN,MAAAC,UAAgB5C,WAAW0C,wBAAwB;AACnD,KAAI,CAACE,QACJ,OAAM,IAAIC,MAAM,4EAA4E;AAC5F,QACMD;;;;;;AAOR,SAAOE,8BAAA;AAAA,QACC9C,WAAW0C,wBAAwB;;;;;;;AAQ3C,SAAAK,wBAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAOGF,OAAA,oBAAA;GAAe,WAAA;aACd,qBAAA;IAAe,WAAA;;KACd,oBAAC,YAAmB,WAAA,sBACpB;yBAAC,YAAmB,WAAA,sBACpB;yBAAC,YAAmB,WAAA,sBACrB;;KACD;IAAM;AAAAF,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAK;AAAA,KAAAL,EAAA,OAAAG,OAAAC,IAAA,4BAAA,EAAA;AAXPC,OAAA,qBAAA;GACW,WAAA;GACC,cAAA;cAGXH,IASA,oBAAA;IAAe,WAAA;cACd,oBAAC,YAAmB,WAAA,mCACrB;KACD;IAAM;AAAAF,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAjBNK;;AAyCF,SAASO,oBAAoB,EAC5B3C,UACAoB,UACAnB,MACAC,WACAoC,SACAnC,UACAC,gBACAK,cACAC,8BACA8B,mBACAC,aACAC,iBAC4B;CAG5B,MAAM,EAAEE,SAASvB,OAAOwB,aAAaC,eAAeC,kBAAkBnD,mBAAiB;EACtFwB;EACAnB;EACAC;EACAoC;EACAnC;EACAC;EACAK;EACAC;EACA+B;EACAO,UAAU,EACTC,YAAYT,mBACb;EACA,CAAC;CAGF,MAAMU,iBAAiBjE,OAAO4D,YAAY;AAC1CK,gBAAeC,UAAUN;CACzB,MAAMO,cAActE,YAAY,YAAY;AAC3C,QAAMoE,eAAeC,SAAS;IAC5B,EAAE,CAAC;CAGN,MAAME,mBAAmBpE,OAAOyD,cAAc;AAC9CW,kBAAiBF,UAAUT;AAC3B1D,eAAc;AACbqE,mBAAiBF,QAAQC,YAAY;IACnC,CAACA,YAAY,CAAC;AAEjB,QACC,oBAAC;EAAsB,OAAOL;YAC7B,oBAAC;GAAsB,OAAOD;aAC7B,oBAAC;IAAkCF;IACjC5C;KACwB;IACJ;GACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkC1B,SAAgBsD,gCAAgC,EAC/CtD,UACAC,MACAC,WACAC,UACAC,gBACAK,eAAe,OACfC,+BAA+B,MAC/BC,kBACAC,eACwC;CAGxC,MAAM,EACLM,iBACAC,oBACAqB,mBACA1B,eACAC,SACAC,WACAC,gBACAM,WACAe,SACAG,gBACG9C,2BAA2B;EAC9BM;EACAC;EACAC;EACAC;EACA,CAAC;CAGF,MAAMmD,WAAWtE,OAA4B,YAAY,GAAG;CAC5D,MAAMuE,oBAAoB1E,aAAa2E,aAAkC;AACxEF,WAASJ,UAAUM;IACjB,EAAE,CAAC;CAEN,MAAMpC,QAAQvC,YAAY,YAAY;AACrC,QAAMyE,SAASJ,SAAS;IACtB,EAAE,CAAC;CAGN,MAAMO,yBAAyBzE,OAAOuD,kBAAkBmB,oBAAoB;AAC5ED,wBAAuBP,UAAUX,kBAAkBmB;CACnD,MAAMrC,WAAWxC,YAAY,YAAY;AACxC,QAAM4E,uBAAuBP,WAAW;IACtC,EAAE,CAAC;CAGN,MAAMS,eAAe5E,eACb;EACN8B;EACAC;EACAC;EACAC;EACAC;EACAC;EACAE;EACAC;EACAC;EACA,GACD;EACCT;EACAC;EACAC;EACAC;EACAC;EACAC;EACAE;EACAC;EACAC;EAEF,CAAC;AAED,QACC,oBAAC,wBAAwB;EAAS,OAAOqC;YACxC,qBAAC;GAAI,WAAU;cACd,oBAAC;IAAS,UAAU,oBAAC,0BAAwB;cAC5C,oBAAC;KACA,UAAU1C;KACJjB;KACKC;KACFoC;KACCnC;KACMC;KACFK;KACgBC;KACX8B;KACNC;KACb,eAAee;KAEdxD;MACmB;KACZ,EACTuB,aACA,oBAAC;IAAI,WAAU;cACd,oBAAC;KACA,OAAOA;KACWZ;KACLC;MAAY;KAG3B;IACG;GAC6B;;;;;;;;;;;;;;;;;;;;;;;;;;ACpWrC,SAAOsD,sBAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CACN,MAAAC,WAAiBR,UAAUS,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;;;;;;;;;;;;;;;;;;;;;;;;;;ACUpC,MAAaqC,oBAAoB;;AASjC,MAAMC,qBAAqB,EAAE;;AAG7B,MAAME,kBAAkB;CACvBC,QAAQf,EAAEgB,KAAK;EAAC;EAAW;EAAU;EAAY;EAAoB;EAAiB;EAAY;EAAe;EAAW;EAAgB,CAAC,CAC3IC,SAAS,wBAAwB;CACnCC,MAAMlB,EAAEgB,KAAK;EAAC;EAAa;EAAW;EAAa;EAAU;EAAW,CAAC,CAACG,UAAU,CAClFF,SAAS,qDAAqD;CAChEG,MAAMpB,EAAEqB,QAAQ,CAACF,UAAU,CACzBF,SAAS,4EAA2E;CACtF;;AAGD,MAAMK,qBAAqB;CAC1BP,QAAQf,EAAEgB,KAAK;EAAC;EAAW;EAAQ;EAAmB;EAAiB;EAAmB;EAAoB;EAAqB,CAAC,CAClIC,SAAS,wBAAwB;CACnCM,YAAYvB,EAAEqB,QAAQ,CAACF,UAAU,CAC/BF,SAAS,wFAAwF;CACnGO,QAAQxB,EAAEqB,QAAQ,CAACF,UAAU,CAC3BF,SAAS,yDAAyD;CACpEC,MAAMlB,EAAEgB,KAAK,CAAC,OAAO,OAAO,CAAC,CAACG,UAAU,CACtCF,SAAS,+FAA2F;CACtGQ,WAAWzB,EAAE0B,MAAM1B,EAAEqB,QAAQ,CAAC,CAACF,UAAU,CACvCF,SAAS,gFAA+E;CAC1F;;AAGD,MAAMU,uBAAuB;CAC5BZ,QAAQf,EAAEgB,KAAK;EAAC;EAAkB;EAAgB;EAAe;EAAc;EAAa;EAAkB,CAAC,CAC7GC,SAAS,wBAAwB;CACnCW,UAAU5B,EAAEqB,QAAQ,CAACF,UAAU,CAC7BF,SAAS,uDAAsD;CACjE;;AAGD,MAAMY,0BAA0B;;AAGhC,MAAMC,uBAAuB;;;;;;;;;;;;;;;;;;AAmB7B,MAAMC,0BAA0B;;;;;;;;;;;;;;;;;AAkBhC,MAAMC,4BAA4B;;;;;;;;;;;;;;;AA0ClC,MAAMY,sBAAsB;;;;;;;;;;AAW5B,SAAgBC,oBAAoBC,SAAsC;CAEzE,MAAMC,UAAU9C,oBAAoB;CACpC,MAAM+C,WAAW9C,qBAAqB;CACtC,MAAM+C,eAAe9C,yBAAyB;CAC9C,MAAM+C,gBAAgB9C,0BAA0B;CAChD,MAAM+C,cAAc9C,wBAAwB;CAC5C,MAAM+C,mBAAmB9C,qBAAqB;CAC9C,MAAM+C,gBAAgBzD,kBAAkB;CACxC,MAAMsC,kBAAkBY,SAASZ;CAGjC,MAAMoB,eAAe7D,iBAAiB;CAGtC,MAAM8D,iBAAiB5D,WAAW6D,MAAMA,EAAEC,SAAS;CACnD,MAAMC,YAAY/D,WAAW6D,QAAMA,IAAEE,UAAU;CAG/C,MAAMC,iBAAiBjE,mBAAmB,EAAEkE,cAAcA,QAAQC,UAAU;CAC5E,MAAMvB,kBAAkB5C,mBAAmB,EAAEkE,SAAAA,gBAAcA,UAAQE,aAAa;CAChF,MAAMC,YAAYrE,mBAAmB,EAAEkE,SAAAA,gBAAcA,UAAQG,UAAU;CAIvE,MAAMC,WAAWjE,OAAO;EACvBgD;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAnB;EACAoB;EACAC;EACAG;EACAC;EACArB;EACAyB;EACA,CAAC;AAEFC,UAASC,UAAU;EAClBlB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAnB;EACAoB;EACAC;EACAG;EACAC;EACArB;EACAyB;EACA;CAKD,MAAMG,mBAAmBpE,YAAY,YAAY;EAChD,MAAMqE,QAAQH,SAASC;EACvB,MAAM9B,mBAAmBgC,MAAMjC,iBAAiBC;EAChD,MAAMM,eAAe0B,MAAMjC,iBAAiBO;EAG5C,MAAM2B,KAAKD,MAAMpB,UACd;GACA7B,MAAMiD,MAAMpB,QAAQsB;GACpBC,cAAcH,MAAMpB,QAAQuB;GAC5BC,WAAWJ,MAAMpB,QAAQwB;GACzBC,UAAUL,MAAMpB,QAAQyB;GACxB,GACA,EAAEC,OAAO,iCAAiC;EAG7C,MAAMhB,YAAYU,MAAMZ,kBAAkB,EAAE,EAAEmB,KAAKC,QAAQ;GAE1D,IAAIC,iBAAiB;AACrB,QAAK,MAAMC,QAAQF,IAAIG,QACtB,KAAID,KAAKE,SAAS,UAAU,UAAUF,QAAQ,OAAOA,KAAKzD,SAAS,UAAU;AAC5EwD,qBAAiBC,KAAKzD,KAAK4D,MAAM,GAAG,IAAI;AACxC;;GAKF,MAAMC,YAAYN,IAAIG,QACpBI,QAAQL,WAASA,OAAKE,SAAS,YAAY,CAC3CL,KAAKS,OAAO;IACZ,MAAMC,eAAeD;AACrB,WAAO;KACNI,MAAMH,aAAaC;KACnBG,QAAQJ,aAAaE,WAAWG,SAAY,cAAc;KAC1D;KACA;AAEH,UAAO;IACNC,IAAIf,IAAIe;IACRC,MAAMhB,IAAIgB;IACVb,SAASF;IACTK;IACA;IACA;EAGF,MAAMW,oBAAoBzB,MAAMjB,eAAe2C,WAAWC,iBAAiBpB,KAAKqB,MAAMA,EAAEC,SAAS,IAAI,EAAE;AAmEvG,SAAO;GAAE5B;GAAI6B,QAjEE;IACdP,IAAIvB,MAAM7B,mBAAmB;IAC7BoB,WAAWS,MAAMT;IACjBwC,SAASzC,SAAS0C,WAAW;IAC7BC,cAAc3C,SAAS0C;IACvB1C;IACA4C,kBAAkBlC,MAAMf,iBAAiBsB,KAAKS,UAAQ;KACrDmB,WAAWnB,KAAGmB;KACd/E,YAAY4D,KAAG5D;KACf8D,UAAUF,KAAGE;KACbkB,MAAMpB,KAAGoB;KACT,EAAE;IACHC,eAAerC,MAAMT,aAAaS,MAAMf,iBAAiB+C,SAAS,IAC/D;KAAEd,UAAUlB,MAAMf,iBAAiB,GAAGiC;KAAUG,QAAQ;KAAW,GACnE;IACH;GAkDoBiB,OA/CPtC,MAAMhB,cACjB;IACAuD,UAAUvC,MAAMhB,YAAYuD;IAC5BC,cAAcxC,MAAMhB,YAAYwD;IAChCC,SAASzC,MAAMhB,YAAYyD;IAC3BC,aAAa1C,MAAMhB,YAAY0D;IAC/BC,YAAY3C,MAAMhB,YAAY2D,cAAc;IAC5CrC,OAAON,MAAMhB,YAAYsB,SAAS;IAClC,GACA,EAAEA,OAAO,+BAA+B;GAsCfsC,OAnCd;IACbC,cAAc7C,MAAMlB,cAAc/B,QAAQ;IAC1C+F,aAAa9C,MAAMnB,UAAU+D,SAAS,EAAE,EAAErC,KAAKlB,SAAO;KACrD+B,MAAM/B,IAAE+B;KACR2B,aAAa1D,IAAE0D,aAAalC,MAAM,GAAG,IAAI,IAAI;KAC7CgB,UAAUxC,IAAE2D,aAAa;KACzB,EAAE;IACHC,YAAYjD,MAAMnB,WACfqE,MAAMC,KAAKnD,MAAMnB,SAASuE,QAAQC,SAAS,CAAC,CAAC9C,KAAK,CAACgB,IAAI+B,aAAa;KACpE/B;KACAvB,OAAOsD,OAAOtD;KACduD,WAAWD,OAAOV,MAAMZ;KACxB1B,OAAOgD,OAAOhD,OAAOkD,WAAW;KAChC,EAAE,GACF,EAAE;IACLC,eAAezD,MAAMjB,gBAClBiB,MAAMjB,cAAcqE,QAAQ7C,KAAKqB,SAAO;KACxCC,UAAUD,IAAEC;KACZ6B,OAAO9B,IAAE8B;KACTC,OAAO/B,IAAE+B,SAAS;KAClBC,KAAKhC,IAAEgC,OAAO;KACdL,WAAW3B,IAAE2B;KACbM,YAAYpC,kBAAkBqC,SAASlC,IAAEC,SAAQ;KACjD,EAAE,GACF,EAAE;IACLkC,iBAAiB/D,MAAMjB,eAAegF,mBAAmB;IACzD;GASkCC,YANhB;IAClBC,mBAAmB3F,cAAcC,cAAc;IAC/C2F,wBAAwB5F,cAAcE,mBAAmB;IACzDR,kBAAkBA,oBAAoB,EAAEsC,OAAO,yCAAwC;IACvF;GAE8C;IAC7C,EAAE,CAAC;AAEN5E,WAAU;EACT0F,MAAM,GAAG5E,kBAAiB;EAC1BuG,aAAarF;EACbyG,aAAa1H;EACb2H,SAASrE;EACT,CAAC;CAKF,MAAMsE,gBAAgB1I,YAAY,OAAOyG,SAA2D;EACnG,MAAM,EAAExF,QAAQG,MAAME,SAASmF;EAC/B,MAAMpC,UAAQH,SAASC;AAEvB,UAAQlD,QAAR;GACC,KAAK;AACJ,QAAI,CAACG,KACJ,QAAO;KAAEuH,SAAS;KAAOhE,OAAO;KAA8C;AAE/E,QAAI,CAACN,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQ2F,YAAYxH,KAAiB;AAC3C,WAAO;KAAEuH,SAAS;KAAMvH;KAAM;GAE/B,KAAK;AACJ,QAAI,CAACiD,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQ4F,QAAQ;AACtB,WAAO;KAAEF,SAAS;KAAMvH,MAAM;KAAa;GAE5C,KAAK;AACJ,QAAI,CAACiD,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQ6F,UAAU;AACxB,WAAO;KAAEH,SAAS;KAAMvH,MAAM;KAAa;GAE5C,KAAK;AACJ,QAAI,CAACiD,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQ8F,kBAAkB;AAChC,WAAO;KAAEJ,SAAS;KAAMnE,cAAc,CAACH,QAAMpB,QAAQuB;KAAc;GAEpE,KAAK;AACJ,QAAI,CAACH,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQ+F,eAAe;AAC7B,WAAO;KAAEL,SAAS;KAAMjE,UAAU;MAAEuE,GAAG;MAAGC,GAAG;MAAE;KAAG;GAEnD,KAAK;AACJ,QAAI,CAAC7E,QAAMpB,QACV,QAAO;KAAE0F,SAAS;KAAOhE,OAAO;KAAiC;AAElEN,YAAMpB,QAAQkG,UAAU;AACxB,WAAO;KAAER,SAAS;KAAMlE,WAAW;KAAO;GAE3C,KAAK;AACJ,QAAI,CAACnD,KACJ,QAAO;KAAEqH,SAAS;KAAOhE,OAAO;KAAkD;AAEnF,QAAI;KACH,MAAMyE,WAAW/E,QAAMb,aAAa4F,UAAU;AAC9CA,cAASC,QAAQ/H,KAAK;AACtB8H,cAASE,MAAM;AACf,YAAO;MAAEX,SAAS;MAAMd,SAASvG;MAAM;aAC/BiI,KAAG;AACX,YAAO;MAAEZ,SAAS;MAAOhE,OAAO4E,eAAaC,QAAQD,IAAE1B,UAAU;MAA0B;;GAG7F,KAAK;AACJ,QAAIvG,SAASqE,OACZ,QAAO;KAAEgD,SAAS;KAAOhE,OAAO;KAA8C;AAE/E,QAAI;AACHN,aAAMb,aAAa4F,UAAU,CAACC,QAAQ/H,KAAK;AAC3C,YAAO;MAAEqH,SAAS;MAAMrH;MAAM;aACtBiI,KAAG;AACX,YAAO;MAAEZ,SAAS;MAAOhE,OAAO4E,eAAaC,QAAQD,IAAE1B,UAAU;MAAsB;;GAGzF,KAAK,gBACJ,KAAI;AACHxD,YAAMb,aAAa4F,UAAU,CAACK,OAAO;AACrC,WAAO,EAAEd,SAAS,MAAM;YAChBY,GAAG;AACX,WAAO;KAAEZ,SAAS;KAAOhE,OAAO4E,aAAaC,QAAQD,EAAE1B,UAAU;KAA4B;;GAG/F,QACC,QAAO;IAAEc,SAAS;IAAOhE,OAAO,mBAAmB1D;IAAU;;IAE7D,EAAE,CAAC;AAENlB,WAAU;EACT0F,MAAM,GAAG5E,kBAAiB;EAC1BuG,aAAapF;EACbwG,aAAaxH;EACbyH,SAASC;EACT,CAAC;CAKF,MAAMgB,mBAAmB1J,YAAY,OAAOyG,WAMtC;EACL,MAAM,EAAExF,QAAAA,UAAQQ,YAAYC,QAAQN,MAAAA,QAAMO,cAAc8E;EACxD,MAAMpC,UAAQH,SAASC;AAEvB,UAAQlD,UAAR;GACC,KAAK,WAAW;AACf,QAAIoD,QAAMf,iBAAiB+C,WAAW,EACrC,QAAO;KAAEsC,SAAS;KAAOhE,OAAO;KAAoC;IAGrE,MAAMgF,WAASlI,aACZ4C,QAAMf,iBAAiBsG,MAAMvE,SAAOA,KAAG5D,eAAeA,WAAW,GACjE4C,QAAMf,iBAAiB;AAE1B,QAAI,CAACqG,SACJ,QAAO;KAAEhB,SAAS;KAAOhE,OAAO,wBAAwBlD;KAAc;AAIvE,QAAI,CAAC4C,QAAMnB,SACV,QAAO;KAAEyF,SAAS;KAAOhE,OAAO;KAAmC;AAGpE,QAAI;KACH,MAAMa,SAAS,MAAMnB,QAAMnB,SAAS2G,SAASF,SAAOpE,UAAUoE,SAAOlD,KAAK;KAC1E,MAAMqD,eAAeC,KAAKC,UAAUxE,OAAOR,WAAWQ,OAAO;AAC7D/E,4BAAuB4D,QAAMd,eAAeoG,SAAOnD,WAAWmD,SAAOlI,YAAYqI,aAAa;AAC9F,YAAO;MAAEnB,SAAS;MAAMpD,UAAUoE,SAAOpE;MAAUC,QAAQsE;MAAc;aACjEP,KAAG;KACX,MAAMU,WAAWV,eAAaC,QAAQD,IAAE1B,UAAU;AAClDpH,4BAAuB4D,QAAMd,eAAeoG,SAAOnD,WAAWmD,SAAOlI,YAAY,UAAUwI,WAAW;AACtG,YAAO;MAAEtB,SAAS;MAAOhE,OAAOsF;MAAU;;;GAI5C,KAAK,QAAQ;AACZ,QAAI5F,QAAMf,iBAAiB+C,WAAW,EACrC,QAAO;KAAEsC,SAAS;KAAOhE,OAAO;KAAiC;IAGlE,MAAMgF,SAASlI,aACZ4C,QAAMf,iBAAiBsG,MAAMvE,SAAOA,KAAG5D,eAAeA,WAAW,GACjE4C,QAAMf,iBAAiB;AAE1B,QAAI,CAACqG,OACJ,QAAO;KAAEhB,SAAS;KAAOhE,OAAO,wBAAwBlD;KAAc;IAGvE,MAAMyI,cAAcxI,SACjB,GAAGoB,oBAAmB,WAAYpB,WAClCoB;AAEHrC,2BAAuB4D,QAAMd,eAAeoG,OAAOnD,WAAWmD,OAAOlI,YAAYyI,YAAY;AAC7F,WAAO;KAAEvB,SAAS;KAAMpD,UAAUoE,OAAOpE;KAAU4E,QAAQ;KAAMzI;KAAQ;;GAG1E,KAAK;AACJ,QAAI,CAACN,OACJ,QAAO;KAAEuH,SAAS;KAAOhE,OAAO;KAAsD;AAEvF,QAAI,CAACN,QAAMlB,aACV,QAAO;KAAEwF,SAAS;KAAOhE,OAAO;KAAsC;AAEvEN,YAAMlB,aAAaiH,QAAQhJ,OAAyB;AACpD,WAAO;KAAEuH,SAAS;KAAMvH,MAAAA;KAAM;GAE/B,KAAK,iBAAiB;AACrB,QAAI,CAACO,aAAaA,UAAU0E,WAAW,EACtC,QAAO;KAAEsC,SAAS;KAAOhE,OAAO;KAAyD;AAE1F,QAAI,CAACN,QAAMjB,cACV,QAAO;KAAEuF,SAAS;KAAOhE,OAAO;KAAuC;IAIxE,MAAMqB,kBAAwCrE,UAC5CiD,KAAKsB,aAAa;KAClB,MAAMyB,WAAStD,QAAMjB,cAAeqE,QAAQmC,MAAM3D,QAAMA,IAAEC,aAAaA,SAAS;AAChF,SAAI,CAACyB,SAAQ,QAAO;AACpB,YAAO;MAAEzB,UAAUyB,SAAOzB;MAAU6B,OAAOJ,SAAOI;MAAO;MACxD,CACD3C,QAAQa,QAA+BA,QAAM,KAAK;AAEpD,UAAM5B,QAAMjB,cAAciH,aAAa,EAAErE,iBAAiB,CAAC;AAC3D,WAAO;KAAE2C,SAAS;KAAM7C,mBAAmBE,gBAAgBpB,KAAKqB,QAAMA,IAAEC,SAAQ;KAAG;;GAGpF,KAAK,mBAAmB;AACvB,QAAI,CAACvE,aAAaA,UAAU0E,WAAW,EACtC,QAAO;KAAEsC,SAAS;KAAOhE,OAAO;KAA2D;AAE5F,QAAI,CAACN,QAAMjB,cACV,QAAO;KAAEuF,SAAS;KAAOhE,OAAO;KAAuC;IAIxE,MAAM4F,eADkBlG,QAAMjB,cAAc2C,WAAWC,mBAAmB,EAAE,EACxCZ,QAAQa,QAAM,CAACtE,UAAUwG,SAASlC,IAAEC,SAAS,CAAC;AAClF,UAAM7B,QAAMjB,cAAciH,aAAa,EAAErE,iBAAiBuE,aAAa,CAAC;AACxE,WAAO;KAAE5B,SAAS;KAAM7C,mBAAmByE,YAAY3F,KAAKqB,QAAMA,IAAEC,SAAQ;KAAG;;GAGhF,KAAK,oBAAoB;AACxB,QAAI,CAAC7B,QAAMjB,cACV,QAAO;KAAEuF,SAAS;KAAOhE,OAAO;KAAuC;IAGxE,MAAM6F,aAAmCnG,QAAMjB,cAAcqE,QAAQ7C,KAAKqB,SAAO;KAChFC,UAAUD,IAAEC;KACZ6B,OAAO9B,IAAE8B;KACT,EAAE;AACH,UAAM1D,QAAMjB,cAAciH,aAAa,EAAErE,iBAAiBwE,YAAY,CAAC;AACvE,WAAO;KAAE7B,SAAS;KAAM7C,mBAAmB0E,WAAW5F,KAAKqB,QAAMA,IAAEC,SAAQ;KAAG;;GAG/E,KAAK;AACJ,QAAI,CAAC7B,QAAMjB,cACV,QAAO;KAAEuF,SAAS;KAAOhE,OAAO;KAAuC;AAGxE,UAAMN,QAAMjB,cAAciH,aAAa,EAAErE,iBAAiB,EAAA,EAAI,CAAC;AAC/D,WAAO;KAAE2C,SAAS;KAAM7C,mBAAmB,EAAA;KAAI;GAGhD,QACC,QAAO;IAAE6C,SAAS;IAAOhE,OAAO,mBAAmB1D;IAAU;;IAE7D,EAAE,CAAC;AAENlB,WAAU;EACT0F,MAAM,GAAG5E,kBAAiB;EAC1BuG,aAAanF;EACbuG,aAAahH;EACbiH,SAASiB;EACT,CAAC;CAKF,MAAMe,qBAAqBzK,YAAY,OAAOyG,WAAgD;EAC7F,MAAM,EAAExF,QAAAA,UAAQa,aAAa2E;EAC7B,MAAMpC,UAAQH,SAASC;AAEvB,UAAQlD,UAAR;GACC,KAAK,iBACJ,KAAI;AACHoD,YAAMb,aAAaM,SAAS,CAAC4G,mBAAmB;AAChD,WAAO;KAAE/B,SAAS;KAAMd,SAAS;KAAsB;YAC/C0B,KAAG;AACX,WAAO;KAAEZ,SAAS;KAAOhE,OAAO4E,eAAaC,QAAQD,IAAE1B,UAAU;KAA8B;;GAGjG,KAAK;AACJ,QAAI,CAAC/F,SACJ,QAAO;KAAE6G,SAAS;KAAOhE,OAAO;KAAuD;AAExF,QAAI;AACHN,aAAMb,aAAaM,SAAS,CAAC6G,eAAe7I,SAAS;AACrD,YAAO;MAAE6G,SAAS;MAAM7G;MAAU;aAC1ByH,KAAG;AACX,YAAO;MAAEZ,SAAS;MAAOhE,OAAO4E,eAAaC,QAAQD,IAAE1B,UAAU;MAA2B;;GAG9F,KAAK,cACJ,QAAO;IACNc,SAAS;IACT5E,WAAWM,QAAMR;IACjBrB,iBAAiB6B,QAAM7B;IACvByB,WAAW,CAAC,GAAGI,QAAMJ,UAAS;IAC9B;GAEF,KAAK;AACJ,QAAI,CAACI,QAAMhB,YACV,QAAO;KAAEsF,SAAS;KAAOhE,OAAO;KAA+B;AAEhE,QAAI,CAACN,QAAMhB,YAAY0D,YACtB,QAAO;KAAE4B,SAAS;KAAOhE,OAAO;KAA4C;AAE7E,QAAI;AACH,WAAMN,QAAMhB,YAAYuH,OAAO;AAC/B,YAAO;MAAEjC,SAAS;MAAMd,SAAS;MAAyB;aAClD0B,KAAG;AACX,YAAO;MAAEZ,SAAS;MAAOhE,OAAO4E,eAAaC,QAAQD,IAAE1B,UAAU;MAAiC;;GAGpG,KAAK;AACJ,QAAI,CAACxD,QAAMhB,YACV,QAAO;KAAEsF,SAAS;KAAOhE,OAAO;KAA+B;AAEhEN,YAAMhB,YAAYwH,MAAM;AACxB,WAAO;KAAElC,SAAS;KAAMd,SAAS;KAAyB;GAE3D,KAAK;AACJ,QAAI,CAACxD,QAAMhB,YACV,QAAO;KAAEsF,SAAS;KAAOhE,OAAO;KAA+B;AAEhEN,YAAMhB,YAAYyH,YAAY;AAC9B,WAAO;KAAEnC,SAAS;KAAM7B,SAAS,CAACzC,QAAMhB,YAAYyD;KAAS;GAE9D,QACC,QAAO;IAAE6B,SAAS;IAAOhE,OAAO,mBAAmB1D;IAAU;;IAE7D,EAAE,CAAC;AAENlB,WAAU;EACT0F,MAAM,GAAG5E,kBAAiB;EAC1BuG,aAAalF;EACbsG,aAAa3G;EACb4G,SAASgC;EACT,CAAC;;;;;;;;;;;;;AChXH,MAAM6E,4BAA0B;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAE/B,MAAAC,mBAAyB9C,6BAA6B;CACtD,MAAA,EAAA+C,iBAAyB1D,aAAa;CAAA,IAAA2D;AAAA,KAAAJ,EAAA,OAAAE,kBAAA;AAGpBE,OAAAF,mBAAA,EAAAA,kBAEI;GAAAG,eACFH,iBAAgBG;GAAcC,SACpCJ,iBAAgBI;GAAQC,iBAChBL,iBAAgBK;GAAgBC,WACtCN,iBAAgBM;GAAUC,gBACrBP,iBAAgBO;GACjC,EAES,GAVKC;AAULV,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,MAAAJ,EAAA;CAAA,IAAAW;AAAA,KAAAX,EAAA,OAAAI,IAAA;AAXOO,OAAA,EAAAC,iBACFR,IAWjB;AAAAJ,IAAA,KAAAI;AAAAJ,IAAA,KAAAW;OAAAA,MAAAX,EAAA;AAZD1C,qBAAoBqD,GAYlB;CAAA,IAAAE;CAAA,IAAAC;AAAA,KAAAd,EAAA,OAAAG,cAAA;AAKQU,aAAA;GACT,MAAAE,QAAcC,iBAAW;AACnBb,kBAAc;MACjB,IAAI;AAAA,gBACMc,aAAaF,MAAM;;AAC9BD,OAAA,CAACX,aAAa;AAAAH,IAAA,KAAAG;AAAAH,IAAA,KAAAa;AAAAb,IAAA,KAAAc;QAAA;AAAAD,OAAAb,EAAA;AAAAc,OAAAd,EAAA;;AALjBlE,WAAU+E,IAKPC,GAAe;AAAA,QAEX;;AAYR,MAAMK,yBAAwDf,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAA7B,eAAAoB,kBAAAZ,cAAAE,gBAAAC,sBAAAyB;CAQ9D,MAAA,EAAAgB,OAAAC,aAA4BlE,qBAAqB;CAAA,IAAAwD;AAAA,KAAAX,EAAA,OAAAsB,OAAAC,IAAA,4BAAA,EAAA;AAU9CZ,OAAA,oBAAC,oBAAkB;AAAAX,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAAA,IAAAa;AAAA,KAAAb,EAAA,OAAAZ,kBAAA;AAClByB,OAAAzB,oBAAoB,oBAAC,wBAAsB;AAAAY,IAAA,KAAAZ;AAAAY,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;AAAA,KAAAd,EAAA,OAAAH,YAAAG,EAAA,OAAAtB,kBAAAsB,EAAA,OAAArB,qBAAAqB,EAAA,OAAAxB,gBAAAwB,EAAA,OAAAa,MAAAb,EAAA,OAAAhC,eAAA;AAP7C8C,OAAA,qBAAC;GACe9C;GACNQ,SAAAA;GACEE,WAAAA;GACGC,cAAAA;;IAEdgC;IACCE;IACAhB;;IACkB;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAtB;AAAAsB,IAAA,KAAArB;AAAAqB,IAAA,KAAAxB;AAAAwB,IAAA,KAAAa;AAAAb,IAAA,KAAAhC;AAAAgC,IAAA,KAAAc;OAAAA,MAAAd,EAAA;CAAA,IAAAwB;AAAA,KAAAxB,EAAA,QAAAoB,SAAApB,EAAA,QAAAqB,YAAArB,EAAA,QAAAc,IAAA;AAVrBU,OAAA,oBAAC;GAA6BJ;GAAiBC;aAC9CP;IAUuB;AAAAd,IAAA,MAAAoB;AAAApB,IAAA,MAAAqB;AAAArB,IAAA,MAAAc;AAAAd,IAAA,MAAAwB;OAAAA,MAAAxB,EAAA;AAAA,QAXxBwB;;;;;;;AAoBF,MAAMC,mBAAiErB,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAArC,SAAAC,WAAAK,MAAAE,eAAAoB,kBAAAC,kBAAAC,aAAAd,cAAAE,gBAAAC,sBAAAyB;CAcvE,MAAA,EAAA7B,OAAAmD,UAAAC,aAAsClF,aAAa;CAGnD,MAAA,EAAAsC,MAAA6C,iBAA+BjF,iBAAiB;CAGhD,MAAAkF,kBAAwBrE,WAAAnB;CAAqC,IAAAsE;AAAA,KAAAX,EAAA,OAAAlC,QAAAkC,EAAA,OAAA6B,iBAAA;AAI5DlB,OAAA7C,eACC;AACA,OAAA;AACqC,WAAxB,IAAIiE,IAAIF,gBAAgB,CAC1B/D;WAAK;AAAA,WAER;;MAEL;AAAAkC,IAAA,KAAAlC;AAAAkC,IAAA,KAAA6B;AAAA7B,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CATL,MAAAgC,eACCrB;CAWD,MAAAsB,wBAA8BjE,iBAAA,GAAoB6D,gBAAe;CAAuB,IAAAhB;AAAA,KAAAb,EAAA,OAAAH,YAAAG,EAAA,OAAAZ,oBAAAY,EAAA,OAAAtB,kBAAAsB,EAAA,OAAArB,qBAAAqB,EAAA,OAAAxB,gBAAAwB,EAAA,OAAAiC,uBAAA;AAYtFpB,OAAA,oBAAC;GACeoB,eAAAA;GACG7C;GACJZ;GACEE;GACGC;GAElBkB;IACsB;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAZ;AAAAY,IAAA,KAAAtB;AAAAsB,IAAA,KAAArB;AAAAqB,IAAA,KAAAxB;AAAAwB,IAAA,KAAAiC;AAAAjC,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;AAAA,KAAAd,EAAA,QAAA4B,gBAAA5B,EAAA,QAAAvC,aAAAuC,EAAA,QAAA2B,YAAA3B,EAAA,QAAAX,oBAAAW,EAAA,QAAAV,eAAAU,EAAA,QAAA0B,YAAA1B,EAAA,QAAAgC,gBAAAhC,EAAA,QAAAa,IAAA;AAjBzBC,OAAA,oBAAC;GACMkB,MAAAA;GACKvE;GACDiE;GACMC,gBAAAA;GACFC;GACIvC;GACLC;aAEbuB;IASiC;AAAAb,IAAA,MAAA4B;AAAA5B,IAAA,MAAAvC;AAAAuC,IAAA,MAAA2B;AAAA3B,IAAA,MAAAX;AAAAW,IAAA,MAAAV;AAAAU,IAAA,MAAA0B;AAAA1B,IAAA,MAAAgC;AAAAhC,IAAA,MAAAa;AAAAb,IAAA,MAAAc;OAAAA,MAAAd,EAAA;AAAA,QAlBlCc;;AAmCF,MAAMqB,0BAA0D/B,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAA7B,eAAAoB,kBAAAZ,cAAAE,gBAAAC,sBAAAyB;CAQhE,MAAAgC,gBAAsBjG,kBAAkB;CAAA,IAAAwE;AAAA,KAAAX,EAAA,OAAAoC,eAAA;AAGdzB,OAAA,YAAA;AACzB0B,WAAOC,IAAK,+DAA+D;AAC3EF,iBAAaG,OAAQrG,0BAAyBsG,UAAW,EAAE,CAAC,CAAC;;AAC7DxC,IAAA,KAAAoC;AAAApC,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAHD,MAAAoB,QAAcT;CAGK,IAAAE;AAAA,KAAAb,EAAA,OAAAsB,OAAAC,IAAA,4BAAA,EAAA;AAUhBV,OAAA,oBAAC,oBAAkB;AAAAb,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;AAAA,KAAAd,EAAA,OAAAZ,kBAAA;AAClB0B,OAAA1B,oBAAoB,oBAAC,wBAAsB;AAAAY,IAAA,KAAAZ;AAAAY,IAAA,KAAAc;OAAAA,MAAAd,EAAA;CAAA,IAAAwB;AAAA,KAAAxB,EAAA,OAAAH,YAAAG,EAAA,OAAAtB,kBAAAsB,EAAA,OAAArB,qBAAAqB,EAAA,OAAAxB,gBAAAwB,EAAA,OAAAc,MAAAd,EAAA,QAAAhC,eAAA;AAP7CwD,OAAA,qBAAC;GACexD;GACNQ,SAAAA;GACEE,WAAAA;GACGC,cAAAA;;IAEdkC;IACCC;IACAjB;;IACkB;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAtB;AAAAsB,IAAA,KAAArB;AAAAqB,IAAA,KAAAxB;AAAAwB,IAAA,KAAAc;AAAAd,IAAA,MAAAhC;AAAAgC,IAAA,MAAAwB;OAAAA,MAAAxB,EAAA;CAAA,IAAAyC;AAAA,KAAAzC,EAAA,QAAAoB,SAAApB,EAAA,QAAAwB,IAAA;AAVrBiB,OAAA,oBAAC;GAA6BrB;aAC7BI;IAUuB;AAAAxB,IAAA,MAAAoB;AAAApB,IAAA,MAAAwB;AAAAxB,IAAA,MAAAyC;OAAAA,MAAAzC,EAAA;AAAA,QAXxByC;;;;;;;AAoBF,MAAMC,oBAAkEtC,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAArC,SAAAE,iBAAAM,eAAAoB,kBAAAZ,cAAAE,gBAAAC,sBAAAyB;CAWxE,MAAAyB,kBAAwBrE,WAAAnB;CAAqC,IAAAsE;AAAA,KAAAX,EAAA,OAAAtC,mBAAAsC,EAAA,OAAA6B,iBAAA;AAGrBlB,OAAA;GAAAnD,SAC9BqE;GAAenE;GAExB;AAAAsC,IAAA,KAAAtC;AAAAsC,IAAA,KAAA6B;AAAA7B,IAAA,KAAAW;OAAAA,MAAAX,EAAA;CAHD,MAAA,EAAA4C,YAAoB7F,oBAAoB4D,GAGtC;CAGF,MAAAsB,wBAA8BjE,iBAAA,GAAoB6D,gBAAe;CAAuB,IAAAhB;AAAA,KAAAb,EAAA,OAAAH,YAAAG,EAAA,OAAAZ,oBAAAY,EAAA,OAAAtB,kBAAAsB,EAAA,OAAArB,qBAAAqB,EAAA,OAAAxB,gBAAAwB,EAAA,OAAAiC,uBAAA;AAItFpB,OAAA,oBAAC;GACeoB,eAAAA;GACG7C;GACJZ;GACEE;GACGC;GAElBkB;IACuB;AAAAG,IAAA,KAAAH;AAAAG,IAAA,KAAAZ;AAAAY,IAAA,KAAAtB;AAAAsB,IAAA,KAAArB;AAAAqB,IAAA,KAAAxB;AAAAwB,IAAA,KAAAiC;AAAAjC,IAAA,KAAAa;OAAAA,MAAAb,EAAA;CAAA,IAAAc;AAAA,KAAAd,EAAA,QAAA4C,WAAA5C,EAAA,QAAAa,IAAA;AAT1BC,OAAA,oBAAC;GAAkC8B;aAClC/B;IAS0B;AAAAb,IAAA,MAAA4C;AAAA5C,IAAA,MAAAa;AAAAb,IAAA,MAAAc;OAAAA,MAAAd,EAAA;AAAA,QAV3Bc;;;;;;;;AAoBF,MAAM+B,gBAAsCzC,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAArC,SAAAC,WAAAC,iBAAAI,MAAAC,OAAAC,eAAAoB,kBAAAC,kBAAAC,aAAAd,cAAAE,gBAAAC,sBAAAyB;AAe5C,KAAI3C,WAAS;EAAA,IAAAkD;AAAA,MAAAX,EAAA,OAAAjC,SAAAiC,EAAA,OAAAxC,WAAAwC,EAAA,OAAAvC,aAAAuC,EAAA,OAAAH,YAAAG,EAAA,OAAAX,oBAAAW,EAAA,OAAAV,eAAAU,EAAA,OAAAZ,oBAAAY,EAAA,OAAAlC,QAAAkC,EAAA,OAAAtB,kBAAAsB,EAAA,OAAArB,qBAAAqB,EAAA,QAAAxB,gBAAAwB,EAAA,QAAAhC,eAAA;AAEX2C,UAAA,oBAAC;IACSnD;IACEC;IACLK;IACCC;IACQC;IACGoB;IACAC;IACLC;IACCd;IACEE;IACGC;IAElBkB;KACgB;AAAAG,KAAA,KAAAjC;AAAAiC,KAAA,KAAAxC;AAAAwC,KAAA,KAAAvC;AAAAuC,KAAA,KAAAH;AAAAG,KAAA,KAAAX;AAAAW,KAAA,KAAAV;AAAAU,KAAA,KAAAZ;AAAAY,KAAA,KAAAlC;AAAAkC,KAAA,KAAAtB;AAAAsB,KAAA,KAAArB;AAAAqB,KAAA,MAAAxB;AAAAwB,KAAA,MAAAhC;AAAAgC,KAAA,MAAAW;QAAAA,QAAAX,EAAA;AAAA,SAdlBW;;CAgBD,IAAAA;AAAA,KAAAX,EAAA,QAAAtC,mBAAAsC,EAAA,QAAAxC,WAAAwC,EAAA,QAAAH,YAAAG,EAAA,QAAAZ,oBAAAY,EAAA,QAAAtB,kBAAAsB,EAAA,QAAArB,qBAAAqB,EAAA,QAAAxB,gBAAAwB,EAAA,QAAAhC,eAAA;AAGA2C,OAAA,oBAAC;GACSnD;GACQE;GACFM;GACGoB;GACJZ;GACEE;GACGC;GAElBkB;IACiB;AAAAG,IAAA,MAAAtC;AAAAsC,IAAA,MAAAxC;AAAAwC,IAAA,MAAAH;AAAAG,IAAA,MAAAZ;AAAAY,IAAA,MAAAtB;AAAAsB,IAAA,MAAArB;AAAAqB,IAAA,MAAAxB;AAAAwB,IAAA,MAAAhC;AAAAgC,IAAA,MAAAW;OAAAA,MAAAX,EAAA;AAAA,QAVnBW;;;;;;;;;;;;;;;;AA4BF,MAAamC,iBAAwC1C,OAAA;CAAA,MAAAJ,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAJ,UAAArC,SAAAC,WAAAC,iBAAAqF,qBAAApF,SAAAG,MAAAC,OAAAC,eAAAC,kBAAA0C,IAAAzC,MAAAC,aAAA0C,IAAAzC,aAAA0C,IAAAzC,qBAAAY,cAAAC,kBAAAC,qBAAAC,kBAAAoC,IAAAnC,kBAAAC,aAAAC,aAAAI,gBAAA8C,IAAAnE,eAAAE,cAAAE,gBAAAC,mBAAAE,cAAAC,cAAAE,yBAAAoB;CASrD,MAAAnC,mBAAA0C,OAAAD,SAAA,OAAAC;CAEA,MAAAxC,cAAA0C,OAAAH,SAAA,QAAAG;CACA,MAAAzC,cAAA0C,OAAAJ,SAAA,cAAAI;CAKA,MAAA1B,mBAAAoC,OAAAd,SAAA,QAAAc;CAIA,MAAA7B,iBAAA8C,OAAA/B,SAAA,QAAA+B;CAUA,MAAA/E,kBAAwBC,SAAOD,mBAAPqF;CAA+C,IAAAC;AAAA,KAAAhD,EAAA,OAAAsB,OAAAC,IAAA,4BAAA,EAAA;AAKpEyB,OAAA,EAAE;AAAAhD,IAAA,KAAAgD;OAAAA,MAAAhD,EAAA;AAFLlE,WAAUmH,SAEPD,GAAG;CAGN,MAAAE,gBAAsBjE,gBAAAC,oBAAAC;CAAuD,IAAAgE;AAAA,KAAAnD,EAAA,OAAAjC,SAAAiC,EAAA,OAAAtC,mBAAAsC,EAAA,OAAAxC,WAAAwC,EAAA,OAAAvC,aAAAuC,EAAA,OAAAH,YAAAG,EAAA,OAAAX,oBAAAW,EAAA,OAAAV,eAAAU,EAAA,OAAAZ,oBAAAY,EAAA,OAAAlC,QAAAkC,EAAA,QAAAtB,kBAAAsB,EAAA,QAAArB,qBAAAqB,EAAA,QAAAxB,gBAAAwB,EAAA,QAAAhC,eAAA;AAO3EmF,OAAA,oBAAC;GACS3F;GACEC;GACMC;GACXI;GACCC;GACQC;GACGoB;GACAC;GACLC;GACCd;GACEE;GACGC;GAElBkB;IACa;AAAAG,IAAA,KAAAjC;AAAAiC,IAAA,KAAAtC;AAAAsC,IAAA,KAAAxC;AAAAwC,IAAA,KAAAvC;AAAAuC,IAAA,KAAAH;AAAAG,IAAA,KAAAX;AAAAW,IAAA,KAAAV;AAAAU,IAAA,KAAAZ;AAAAY,IAAA,KAAAlC;AAAAkC,IAAA,MAAAtB;AAAAsB,IAAA,MAAArB;AAAAqB,IAAA,MAAAxB;AAAAwB,IAAA,MAAAhC;AAAAgC,IAAA,MAAAmD;OAAAA,MAAAnD,EAAA;CAAA,IAAAoD;AAAA,KAAApD,EAAA,QAAA/B,oBAAA+B,EAAA,QAAA1B,iBAAA0B,EAAA,QAAAmD,IAAA;AAhBhBC,OAAA,oBAAC;GAAmCnF;GAAiCK;aACpE6E;IAgBkB;AAAAnD,IAAA,MAAA/B;AAAA+B,IAAA,MAAA1B;AAAA0B,IAAA,MAAAmD;AAAAnD,IAAA,MAAAoD;OAAAA,MAAApD,EAAA;CAlBpB,MAAAqD,UACCD;CAkBA,IAAAE;AAAA,KAAAtD,EAAA,QAAAqD,WAAArD,EAAA,QAAAd,oBAAAc,EAAA,QAAAb,uBAAAa,EAAA,QAAAf,gBAAAe,EAAA,QAAAkD,eAAA;AAiBII,OAAAJ,gBACA,oBAAC;GACSjE,SAAAA;GACKC,cAAAA;GACGC,iBAAAA;aAEhBkE;IAIF,GAVAA;AAUArD,IAAA,MAAAqD;AAAArD,IAAA,MAAAd;AAAAc,IAAA,MAAAb;AAAAa,IAAA,MAAAf;AAAAe,IAAA,MAAAkD;AAAAlD,IAAA,MAAAsD;OAAAA,MAAAtD,EAAA;CAAA,IAAAuD;AAAA,KAAAvD,EAAA,QAAA3B,uBAAA2B,EAAA,QAAAhB,wBAAAgB,EAAA,QAAAsD,IAAA;AAXFC,QAAA,oBAAC;GAAkClF,aAAAA;GAAmCW,cAAAA;aACpEsE;IAWqB;AAAAtD,IAAA,MAAA3B;AAAA2B,IAAA,MAAAhB;AAAAgB,IAAA,MAAAsD;AAAAtD,IAAA,MAAAuD;OAAAA,OAAAvD,EAAA;CAAA,IAAAwD;AAAA,KAAAxD,EAAA,QAAA5B,eAAA4B,EAAA,QAAA7B,eAAA6B,EAAA,QAAAlB,gBAAAkB,EAAA,QAAAnB,gBAAAmB,EAAA,QAAA9B,QAAA8B,EAAA,QAAAuD,KAAA;AAnBxBC,QAAA,oBAAC;GACMtF;GACOC;GACAC;GACCS;GACAC;aAEdyE;IAaiB;AAAAvD,IAAA,MAAA5B;AAAA4B,IAAA,MAAA7B;AAAA6B,IAAA,MAAAlB;AAAAkB,IAAA,MAAAnB;AAAAmB,IAAA,MAAA9B;AAAA8B,IAAA,MAAAuD;AAAAvD,IAAA,MAAAwD;OAAAA,OAAAxD,EAAA;CAAA,IAAAyD;AAAA,KAAAzD,EAAA,QAAAX,oBAAAW,EAAA,QAAAV,eAAAU,EAAA,QAAAT,eAAAS,EAAA,QAAAL,kBAAAK,EAAA,QAAAwD,KAAA;AA1BnBC,QAAA,oBAAC;GACkBpE;GACLC;GACJC,SAAAA;GACEI,WAAAA;aAEX6D;IAqBmB;AAAAxD,IAAA,MAAAX;AAAAW,IAAA,MAAAV;AAAAU,IAAA,MAAAT;AAAAS,IAAA,MAAAL;AAAAK,IAAA,MAAAwD;AAAAxD,IAAA,MAAAyD;OAAAA,OAAAzD,EAAA;AAAA,QA3BpByD;;AAlEmD,SAAAR,UAAA;AAmCnD7G,eAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChjBhB,MAAa4I,eAAoCC,OAAA;CAAA,MAAAC,IAAAvB,EAAA,GAAA;CAAA,IAAAmB;CAAA,IAAAC;CAAA,IAAAI;AAAA,KAAAD,EAAA,OAAAD,IAAA;AAAC,GAAA,CAAAH,WAAAC,YAAAI,kBAAAF;AAAyCC,IAAA,KAAAD;AAAAC,IAAA,KAAAJ;AAAAI,IAAA,KAAAH;AAAAG,IAAA,KAAAC;QAAA;AAAAL,cAAAI,EAAA;AAAAH,YAAAG,EAAA;AAAAC,mBAAAD,EAAA;;CAAA,IAAAE;AAAA,KAAAF,EAAA,OAAAJ,aAAAI,EAAA,OAAAH,SAAA;AAGxFK,OAAA,oBAAC;GAA4BN;GAAoBC;IAAW;AAAAG,IAAA,KAAAJ;AAAAI,IAAA,KAAAH;AAAAG,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAAA,IAAAG;AAAA,KAAAH,EAAA,OAAAC,kBAAAD,EAAA,OAAAE,IAAA;AAD7DC,OAAA,oBAAC;GAAa,GAAKF;aAClBC;IACe;AAAAF,IAAA,KAAAC;AAAAD,IAAA,KAAAE;AAAAF,IAAA,KAAAG;OAAAA,MAAAH,EAAA;AAAA,QAFhBG;;;;;;AAeF,MAAME,oBAA8CN,OAAA;CAAA,MAAAC,IAAAvB,EAAA,GAAA;CAAC,MAAA,EAAAmB,WAAAC,YAAAE;CACpD,MAAA,EAAAO,WAAAC,WAAAC,sBAAoDlB,iBAAiB;CACrE,MAAAmB,QAAcpB,YAAU;CAGxB,MAAA,CAAAqB,QAAAC,aAA4B9B,SAAiB,cAAc;CAAA,IAAAqB;AAAA,KAAAF,EAAA,OAAAY,OAAAC,IAAA,4BAAA,EAAA;AAGxBX,aAAA;AAClCS,aAAU,cAAc;;AACxBX,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAFD,MAAAc,iBAAuBZ;CAEjB,IAAAC;AAAA,KAAAH,EAAA,OAAAY,OAAAC,IAAA,4BAAA,EAAA;AAG6BV,aAAA;AAClCQ,aAAU,cAAc;;AACxBX,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CAFD,MAAAe,iBAAuBZ;CAEjB,IAAAa;AAAA,KAAAhB,EAAA,OAAAS,MAAAQ,QAAA;AAG6BD,aAAA;AAClCL,aAAU,cAAc;AACnBF,SAAKQ,QAAiBC,UAAS,EAAAC,MAACC,MAEnC;;AACFpB,IAAA,KAAAS,MAAAQ;AAAAjB,IAAA,KAAAgB;OAAAA,MAAAhB,EAAA;CALD,MAAAqB,iBAAuBL;CAKL,IAAAM;AAAA,KAAAtB,EAAA,OAAAY,OAAAC,IAAA,4BAAA,EAAA;AAGqBS,aAAA;AACtCX,aAAU,cAAc;;AACxBX,IAAA,KAAAsB;OAAAA,MAAAtB,EAAA;CAFD,MAAAuB,qBAA2BD;CAK3B,MAAAE,yBAA+B5C,OAAO,MAAM;CAAA,IAAA6C;CAAA,IAAAC;AAAA,KAAA1B,EAAA,OAAAM,aAAAN,EAAA,OAAAQ,qBAAAR,EAAA,OAAAO,UAAAoB,QAAA;AAClCF,aAAA;AACT,OAAID,uBAAsBI,QAAQ;AAClC,OAAItB,UAAS;AACb,OAAIC,UAASoB,SAAU,EAAC;AAExBH,0BAAsBI,UAAW;AACjC,OAAA;AACCpB,uBAAmB;YAAAqB,MAAA;IACXC,MAAAA,UAAAA;AACRC,YAAOD,MAAO,uDAAuDA,QAAM;;;AAE1EJ,OAAA;GAACpB;GAAWC,UAASoB;GAASnB;GAAkB;AAAAR,IAAA,KAAAM;AAAAN,IAAA,KAAAQ;AAAAR,IAAA,KAAAO,UAAAoB;AAAA3B,IAAA,KAAAyB;AAAAzB,IAAA,KAAA0B;QAAA;AAAAD,OAAAzB,EAAA;AAAA0B,OAAA1B,EAAA;;AAXnDrB,WAAU8C,IAWPC,GAAiD;CAAA,IAAAG;AAAA,KAAA7B,EAAA,QAAAJ,WAAA;AAQvCiC,OAAApC,GACV,kEACA,uCACAG,UACA;AAAAI,IAAA,MAAAJ;AAAAI,IAAA,MAAA6B;OAAAA,MAAA7B,EAAA;CAAA,IAAAgC;AAAA,KAAAhC,EAAA,QAAAH,WAAAG,EAAA,QAAAU,UAAAV,EAAA,QAAAqB,gBAAA;AAEAW,OAAAtB,WAAW,gBACX,qBAAA;GAAe,WAAA;cAEd,qBAAA;IAAe,WAAA;eAEd,qBAAA;KAAe,WAAA;gBACd,oBAAC;MACQ,SAAA;MACH,MAAA;MACMuB,WAnBjB;MAoBelB,SAAAA;MACD,SAAA;MACH,MAAA;gBAEL,oBAAC,aAAoB,WAAA,kBACtB;OACA,sBAAC;MACQ,SAAA;MACH,MAAA;MACMkB,WA7BjB;MA8BeZ,SAAAA;MACD,SAAA;MACH,MAAA;gBAEL,oBAAC,QAAe,WAAA,kBACjB;OACD;MAGC,EAAAxB,WACA,oBAAA;KAAe,WAAA;eACd,oBAAC;MACQ,SAAA;MACH,MAAA;MACMoC,WA5ClB;MA6CgBpC,SAAAA;MACD,SAAA;MACH,MAAA;gBAEL,oBAAC,KAAY,WAAA,kBACd;OACD;MACD;KAGD,sBAAA;IAAe,WAAA;cACd,oBAAC;KAA0B,WAAA;KAA4B0B,gBAAAA;MACxD;KACD;IAOA,GALA,oBAAC;GACgBT,gBAAAA;GACHO,aAAAA;GACJxB;IAEV;AAAAG,IAAA,MAAAH;AAAAG,IAAA,MAAAU;AAAAV,IAAA,MAAAqB;AAAArB,IAAA,MAAAgC;OAAAA,MAAAhC,EAAA;CAAA,IAAAkC;AAAA,KAAAlC,EAAA,QAAA6B,MAAA7B,EAAA,QAAAgC,IAAA;AA9DFE,OAAA,oBAAA;GACY,WAAAL;aAMVG;IAwDI;AAAAhC,IAAA,MAAA6B;AAAA7B,IAAA,MAAAgC;AAAAhC,IAAA,MAAAkC;OAAAA,MAAAlC,EAAA;AAAA,QA/DNkC;;AAlDkD,SAAAd,MAAAU,OAAA;AAqBjDC,SAAOD,MAAO,6CAA6CA,MAAM;;;;;;;;;ACjGpE,MAAMa,qBAAqB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;;;;AAMD,SAASE,oBAAoBC,aAA8B;CAC1D,MAAME,aAAaC,iBAAiBH,YAAY;CAChD,MAAMI,oBAAoBP,mBAAmBQ,KAAIC,SAAQ;EACxD,MAAMC,QAAQL,WAAWM,iBAAiBF,KAAK,CAACG,MAAM;AACtD,SAAOF,QAAQ,GAAGD,KAAI,IAAKC,MAAK,gBAAiB;GAChD,CACAG,OAAOC,QAAQ,CACfC,KAAK,SAAa;AAEpB,KAAI,CAACR,kBAAmB,QAAO;AAE/B,QAAO;;;;MAIFA,kBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCvB,MAAac,cAAkCC,OAAA;CAAA,MAAAC,IAAA9B,EAAA,GAAA;CAAC,MAAA,EAAAwB,UAAAC,QAAAC,WAAAC,MAAAI,OAAAF;CAI/C,MAAAF,OAAAI,OAAAC,SAAA,SAAAD;CAEA,MAAAE,UAAgB/B,OAAuB,KAAK;CAC5C,MAAA,CAAAgC,iBAAAC,sBAA8ChC,SAAyB,KAAK;CAAA,IAAAiC;CAAA,IAAAC;AAAA,KAAAP,EAAA,OAAAQ,OAAAC,IAAA,4BAAA,EAAA;AAGlEH,aAAA;GACT,MAAAI,OAAaP,QAAOQ;AACpB,OAAI,CAACD,KAAI;GAET,MAAAE,kBAAkB;IACjB,MAAAC,OAAaC,SAAQC;IACrB,MAAAC,SACCH,KAAII,UAAUC,SAAU,OACwE,IAA/F,CAACL,KAAII,UAAUC,SAAU,QAAqE,IAAzDC,OAAMC,WAAY,+BAA+B,CAAAC;AACxFX,SAAIO,UAAUK,OAAQ,QAAQN,OAAO;;AAItCJ,cAAW;GAGX,MAAAW,WAAiB,IAAIC,iBAAiBZ,UAAU;AAChDW,YAAQE,QAASX,SAAQC,iBAAkB;IAAAW,YAAc;IAAIC,iBAAmB,CAAC,QAAO;IAAG,CAAC;GAG5F,MAAAC,aAAmBT,OAAMC,WAAY,+BAA+B;AACpEQ,cAAUC,iBAAkB,UAAUjB,UAAU;AAAA,gBAEzC;AACNW,aAAQO,YAAa;AACrBF,eAAUG,oBAAqB,UAAUnB,UAAU;;;AAElDL,OAAA,EAAE;AAAAP,IAAA,KAAAM;AAAAN,IAAA,KAAAO;QAAA;AAAAD,OAAAN,EAAA;AAAAO,OAAAP,EAAA;;AA3BL7B,WAAUmC,IA2BPC,GAAG;CAAA,IAAAyB;CAAA,IAAAC;AAAA,KAAAjC,EAAA,OAAAH,QAAAG,EAAA,OAAAL,QAAA;AAEIqC,aAAA;GACT,MAAAE,SAAa/B,QAAOQ;AACpB,OAAI,CAACD,OAAI;GAGT,IAAAyB,SAAazB,OAAI0B;AACjB,OAAI,CAACD,OACJA,UAASzB,OAAI2B,aAAc,EAAAxC,MAAQ,CAAC;GAKrC,MAAAyC,mBAAyB5B,OAAI6B;GAC7B,MAAAC,eAAqBF,mBAAmB3D,oBAAoB2D,iBAAsB,GAA7D;GAoBrB,IAAAG,eAAmBN,OAAMO,cAAe,4BAA4B;AACpE,OAAI,CAACD,cAAY;AAChBA,mBAAe3B,SAAQ6B,cAAe,QAAQ;AAC9CF,iBAAYG,aAAc,sBAAsB,GAAG;AACnDT,WAAMU,aAAcJ,cAAcN,OAAMW,WAAY;;AAIrDL,gBAAYM,cAzBS,4VAyBqBpD,SAAS6C;GAGnD,IAAAQ,YAAgBb,OAAMO,cAAe,0BAA0B;AAC/D,OAAI,CAACM,WAAS;AACbA,gBAAYlC,SAAQ6B,cAAe,MAAM;AACzCK,cAASJ,aAAc,yBAAyB,GAAG;AACnDT,WAAMc,YAAaD,UAAU;;AAG9B3C,sBAAmB2C,UAAU;;AAC3Bf,OAAA,CAACpC,MAAMF,OAAO;AAAAK,IAAA,KAAAH;AAAAG,IAAA,KAAAL;AAAAK,IAAA,KAAAgC;AAAAhC,IAAA,KAAAiC;QAAA;AAAAD,OAAAhC,EAAA;AAAAiC,OAAAjC,EAAA;;AApDjB7B,WAAU6D,IAoDPC,GAAe;CAAA,IAAAiB;AAAA,KAAAlD,EAAA,OAAAN,YAAAM,EAAA,OAAAI,iBAAA;AAIf8C,OAAA9C,mBAAmB9B,aAAaoB,UAAUU,gBAAgB;AAAAJ,IAAA,KAAAN;AAAAM,IAAA,KAAAI;AAAAJ,IAAA,KAAAkD;OAAAA,MAAAlD,EAAA;CAAA,IAAAmD;AAAA,KAAAnD,EAAA,OAAAJ,aAAAI,EAAA,QAAAkD,IAAA;AAD5DC,OAAA,oBAAA;GAAUhD,KAAAA;GAAoBP;aAC5BsD;IACI;AAAAlD,IAAA,KAAAJ;AAAAI,IAAA,MAAAkD;AAAAlD,IAAA,MAAAmD;OAAAA,MAAAnD,EAAA;AAAA,QAFNmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpJF,MAAMO,qBAAqBC,gBAAkC;AAC5D,KAAIA,eAAe,OAAOC,WAAW,YACpC,QAAOA,OAAOC,SAASC;AAExB,QAAON;;;;;;;;;;;;;;AAuGR,MAAMiB,iBAAwCC,OAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAC,MAAA,EAAAT,WAAAC,MAAAG,SAAAC,kBAAAK,IAAAR,WAAAC,YAAAI;CAI9C,MAAAF,mBAAAK,OAAAC,SAAA,QAAAD;CAAwB,IAAAE;AAAA,KAAAJ,EAAA,OAAAR,aAAAQ,EAAA,OAAAJ,SAAA;AAKxBQ,YAAgBrB,kBAAkBa,SAAOZ,YAAc;EAGvD,MAAAqB,WAAiBb,YAAA,cAAA;AAGjB,MAAI,OAAOP,WAAW,YACrBqB,SAAOC,MAAO,wBAAwB;GAAAC,cACvB,CAAC,CAAChB;GAASa;GAAAI,MAEnBb,UAAA,gBAAA;GAAsCQ;GAE5C,CAAC;AACFJ,IAAA,KAAAR;AAAAQ,IAAA,KAAAJ;AAAAI,IAAA,KAAAI;OAAAA,WAAAJ,EAAA;CAGD,MAAAU,eAAqB,CAACd,WAAD,CAAa,CAACA,QAAON;CAG1C,MAAAD,kBAAwBO,SAAOP;CAQb,MAAAsB,KAAAD,eAAA,GAAkBN,QAAO,yBAAzBD;CAIJ,MAAAS,KAAAlB,aAAA;CAAkC,IAAAmB;AAAA,KAAAb,EAAA,OAAAX,mBAAAW,EAAA,OAAAI,WAAAJ,EAAA,OAAAR,aAAAQ,EAAA,OAAAH,oBAAAG,EAAA,OAAAL,WAAAK,EAAA,OAAAP,QAAAO,EAAA,OAAAW,MAAAX,EAAA,QAAAY,IAAA;AAT/CC,OAAA,oBAAC;GAAmBjC,QAAAA;aACnB,oBAAC;IACSwB;IACEZ;IACMH;IACF,eAAAsB;IACG,kBAAA;IACZlB;IACYI;IACP,WAAAe;IACFjB;KAEX;IAAa;AAAAK,IAAA,KAAAX;AAAAW,IAAA,KAAAI;AAAAJ,IAAA,KAAAR;AAAAQ,IAAA,KAAAH;AAAAG,IAAA,KAAAL;AAAAK,IAAA,KAAAP;AAAAO,IAAA,KAAAW;AAAAX,IAAA,MAAAY;AAAAZ,IAAA,MAAAa;OAAAA,MAAAb,EAAA;AAAA,QAZba;;;;;;;;AAsBF,MAAMC,qBAAqBrC,KAAKqB,eAAwD,EACvFkB,OAAO;CAGNxB,WAAW;CAGXC,MAAM;CAGNG,SAAS;CAGTC,kBAAkB;CACnB,EACA,CAAC;;;;;;;AAQF,SAAgBoB,oBAAoBC,UAAU,gBAAsB;AACnE,KAAI,OAAOjC,WAAW,YAAa;AAEnC,KAAI,CAACkC,eAAeC,IAAIF,QAAQ,CAC/BC,gBAAeE,OAAOH,SAASJ,mBAAmB;;AAKpDG,qBAAqB"}