@vanira/sdk 0.0.1 â 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/WebRTCClient.d.ts +5 -1
- package/dist/ui/styles/index.d.ts +1 -0
- package/dist/ui/styles/keyframes.d.ts +1 -1
- package/dist/ui/styles/widget.css.d.ts +1 -1
- package/dist/vanira-sdk.es.js +23 -10
- package/dist/vanira-sdk.js +23 -10
- package/dist/vanira-sdk.js.map +1 -1
- package/package.json +1 -1
package/dist/vanira-sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vanira-sdk.js","sources":["../src/api/services/ConfigService.ts","../src/api/services/ChatService.ts","../src/ui/abstraction/AbstractWidgetProvider.ts","../src/core/WebRTCClient.ts","../src/core/VaniraAI.ts","../src/core/SessionManager.ts","../src/ui/icons_data.ts","../src/ui/styles/theme.ts","../src/ui/styles/widget.css.ts","../src/ui/styles/index.ts","../src/ui/components/FloatingButton.ts","../src/ui/components/Panel.ts","../src/ui/components/VoiceOverlay.ts","../src/ui/components/ChatWindow.ts","../src/ui/components/AvatarView.ts","../src/ui/components/VoiceOrb.ts","../src/ui/components/FloatingWelcomeChips.ts","../src/ui/views/AbstractVoiceView.ts","../src/ui/views/VoiceOnlyView.ts","../src/ui/views/ChatOnlyView.ts","../src/ui/views/AbstractChatView.ts","../src/ui/views/ChatVoiceView.ts","../src/ui/views/AvatarOnlyView.ts","../src/ui/views/ChatAvatarView.ts","../src/ui/adapters/VaniraChatAdapter.ts","../src/ui/providers/VaniraInternalProvider.ts","../src/ui/factory/WidgetFactory.ts","../src/ui/VaniraWidget.ts","../src/cdn.ts"],"sourcesContent":["import { WidgetConfig } from '../../types';\n\nconst HASURA_URL = 'https://coredb.travelr.club/v1/graphql';\n\nexport class ConfigService {\n static async fetchWidgetConfig(widgetId: string): Promise<WidgetConfig> {\n const query = `\n query GetWidgetConfig($id: uuid!) {\n app_widget_by_pk(id: $id) {\n agent_id\n client_id\n mode\n icon\n gradient\n agent {\n tts_voice {\n provider {\n root_name\n provider_country\n }\n }\n }\n }\n }\n `;\n\n try {\n const response = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ query, variables: { id: widgetId } }),\n });\n\n const data = await response.json();\n const widget = data.data?.app_widget_by_pk;\n\n if (!widget) {\n throw new Error(`Widget configuration not found for ID: ${widgetId}`);\n }\n\n // Fetch Client Details using client_id\n if (widget.client_id) {\n const clientQuery = `\n query GetClientDetails($id: uuid!) {\n client_by_pk(id: $id) {\n base_prospect_group_id\n }\n }\n `;\n\n const clientResponse = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: clientQuery,\n variables: { id: widget.client_id },\n }),\n });\n\n const clientData = await clientResponse.json();\n if (clientData.data?.client_by_pk) {\n widget.client = clientData.data.client_by_pk;\n }\n }\n\n return widget as WidgetConfig;\n } catch (error) {\n console.error('[VaniraAI] Failed to fetch widget config:', error);\n throw error;\n }\n }\n}\n","export interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n widget?: {\n type: 'carousel' | 'button_list';\n data: any;\n };\n}\n\nconst HASURA_URL = 'https://coredb.travelr.club/v1/graphql';\nlet CHAT_URL = 'https://inboxapi.travelr.club';\n\nexport class ChatService {\n static setChatUrl(url: string) {\n CHAT_URL = url;\n }\n\n static async createChatProspect(prospectGroupId: string): Promise<string> {\n const mutation = `\n mutation CreateChatProspect($prospectGroupId: uuid!, $name: String!) {\n insert_prospects_one(object: {prospect_group_id: $prospectGroupId, name: $name, source: \"widget\"}) {\n id\n }\n }\n `;\n\n try {\n const response = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: mutation,\n variables: {\n prospectGroupId,\n name: `Widget Guest ${new Date().toLocaleString()}`\n }\n }),\n });\n\n const data = await response.json();\n\n if (data.errors) {\n console.warn('[VaniraAI] Prospect creation failed, using anonymous ID', data.errors);\n // Fallback Logic\n return `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n return data.data?.insert_prospects_one?.id || `anon_${Date.now()}`;\n } catch (error) {\n console.error('[VaniraAI] Failed to create prospect:', error);\n return `anon_${Date.now()}`;\n }\n }\n\n // Calls the new Go bridge /widget/chat endpoint with an empty message to initialize the session and get the Welcome config + inbox_id\n static async fetchWelcomeMessage(agentId: string, prospectId: string, widgetId?: string): Promise<ChatMessage & { chatId?: string }> {\n try {\n const response = await fetch(`${CHAT_URL}/widget/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentId,\n ...(widgetId ? { widget_id: widgetId } : {}),\n message: '',\n prospect_id: prospectId,\n stream: false\n }),\n });\n\n if (!response.ok) throw new Error('Failed to fetch welcome message');\n\n const data = await response.json();\n let content = data.response || 'Hello! How can I help you today?';\n let widget = undefined;\n const chatId = data.chat_id || data.inbox_id; // Go bridge returns chat_id which is the inbox_id\n\n if (data.widget) {\n widget = data.widget;\n const uiPayload: any = { text: content };\n if (widget.type === 'carousel' && widget.data?.cards) {\n uiPayload.cards = widget.data.cards;\n } else if (widget.type === 'button_list' && widget.data?.buttons) {\n uiPayload.buttons = widget.data.buttons;\n }\n content = JSON.stringify(uiPayload);\n }\n\n return { role: 'assistant', content, widget, chatId };\n } catch (error) {\n console.error('[VaniraAI] Failed to fetch welcome message:', error);\n // Graceful Degradation\n return { role: 'assistant', content: 'Hello! How can I help you today?' };\n }\n }\n\n static async sendChatMessage(\n agentId: string,\n prospectId: string,\n message: string,\n chatId: string | null,\n onChunk: (text: string) => void,\n onWidget: (widget: any) => void,\n onDone: (newChatId: string | null) => void,\n widgetId?: string\n ): Promise<void> {\n try {\n const payload: any = {\n agent_id: agentId,\n message: message,\n prospect_id: prospectId,\n stream: true\n };\n\n if (chatId) payload.inbox_id = chatId;\n if (widgetId) payload.widget_id = widgetId;\n\n const response = await fetch(`${CHAT_URL}/widget/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) throw new Error('Chat request failed');\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n if (!reader) throw new Error('No reader');\n\n let assistantContent = '';\n let buffer = '';\n let newChatId: string | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine) continue;\n\n if (trimmedLine.startsWith('data: ')) {\n const data = trimmedLine.slice(6);\n if (data === '[DONE]') {\n onDone(newChatId);\n return;\n }\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === 'metadata' && parsed.chat_id) {\n newChatId = parsed.chat_id;\n continue;\n }\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n assistantContent += content;\n onChunk(assistantContent);\n }\n if (parsed.widget) {\n onWidget(parsed.widget);\n }\n if (parsed.chat_id && !newChatId) {\n newChatId = parsed.chat_id;\n }\n } catch (e) { }\n }\n }\n }\n\n onDone(newChatId);\n } catch (error) {\n console.error('[VaniraAI] Chat error:', error);\n onChunk('Sorry, I encountered an error. Please try again.');\n onDone(null);\n }\n }\n static listenForAdminReplies(inboxId: string, sender: string, onMessage: (content: string) => void): { close: () => void } {\n const url = `${CHAT_URL}/inbox/stream?inbox_id=${inboxId}&sender=${encodeURIComponent(sender)}`;\n let es: EventSource | null = null;\n let reconnectAttempts = 0;\n let isClosed = false;\n\n const connect = () => {\n if (isClosed) return;\n\n es = new EventSource(url);\n console.log(`[VaniraAI] Subscribed to SSE EventSource at ${es.url}`);\n\n es.onopen = () => {\n console.log(\"[VaniraAI] SSE connection opened successfully.\");\n reconnectAttempts = 0; // Reset backoff on success\n };\n\n es.onmessage = (event) => {\n console.log(\"[VaniraAI] đĄ Raw SSE Event triggered:\", event.data);\n try {\n const data = JSON.parse(event.data);\n console.log(\"[VaniraAI] SSE stream JSON parsed:\", data);\n\n const isOutgoing = data.direction === 'outgoing';\n const hasContent = !!data.content;\n const isNotAI = data.source !== 'ai';\n\n if (isOutgoing && hasContent && isNotAI) {\n console.log(\"[VaniraAI] đ¯ Displaying admin message in chat UI:\", data.content);\n onMessage(data.content);\n }\n } catch (e) {\n console.error('[VaniraAI] SSE parse error', e);\n }\n };\n\n es.onerror = (err) => {\n console.error('[VaniraAI] SSE connection error or disconnect', err);\n if (es) {\n es.close();\n es = null;\n }\n\n if (isClosed) return;\n\n // Exponential backoff: 2s, 4s, 8s, 16s... max 30s\n const delay = Math.min(2000 * Math.pow(2, reconnectAttempts), 30000);\n console.log(`[VaniraAI] Reconnecting SSE in ${delay}ms (Attempt ${reconnectAttempts + 1})...`);\n reconnectAttempts++;\n\n setTimeout(connect, delay);\n };\n };\n\n connect(); // Start initial connection\n\n return {\n close: () => {\n isClosed = true;\n if (es) {\n es.close();\n es = null;\n console.log(\"[VaniraAI] SSE connection manually closed.\");\n }\n }\n };\n }\n\n static async createCall(agentId: string, clientId: string | null, prospectId: string | null, widgetMode: string): Promise<{ callId: string, workerUrl: string }> {\n try {\n const response = await fetch('https://wfapi.travelr.club/webhook/create-web-call', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentId,\n client_id: clientId,\n prospect_id: prospectId,\n is_avatar_call: widgetMode.includes('avatar')\n }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`[VaniraAI] Call creation failed HTTP ${response.status}`);\n }\n\n if (!data.worker_url) {\n throw new Error('[VaniraAI] Worker URL missing from response. Call cannot proceed.');\n }\n\n let baseWorkerUrl: string;\n try {\n baseWorkerUrl = new URL(data.worker_url).origin;\n } catch (e) {\n baseWorkerUrl = data.worker_url;\n }\n\n return {\n callId: data.call_id || data.id || `web_${Date.now()}`,\n workerUrl: baseWorkerUrl\n };\n } catch (error) {\n console.error('[VaniraAI] Failed to create call:', error);\n throw error; // Re-throw to ensure caller knows it failed\n }\n }\n}\n","import { IWidgetProvider } from './interfaces';\n\nexport abstract class AbstractWidgetProvider implements IWidgetProvider {\n protected config: any;\n protected root: ShadowRoot | null = null;\n\n constructor(config: any) {\n this.config = config;\n }\n\n abstract create_call(): Promise<void>;\n abstract end_call(): void;\n abstract ui_renderer(root: ShadowRoot): void;\n\n async initialize(config: any): Promise<void> {\n this.config = config;\n }\n}\n","import { WebRTCClientConfig, ControlEvent } from '../types';\n\n\nexport class WebRTCClient {\n private serverUrl: string;\n private agentId: string;\n private callId: string;\n private onConnected: () => void;\n private onDisconnected: () => void;\n private onError: (error: any) => void;\n private onTranscription: (text: string, isFinal: boolean) => void;\n // @ts-ignore\n private onRemoteTrack: (track: MediaStreamTrack, stream: MediaStream) => void;\n private onClientToolCall: (toolCall: any) => void;\n\n private pc: RTCPeerConnection | null = null;\n private dataChannel: RTCDataChannel | null = null;\n private audioElement: HTMLAudioElement | null = null;\n public connected: boolean = false;\n private iceServers?: RTCIceServer[];\n private token?: string;\n\n constructor(config: WebRTCClientConfig) {\n if (!config.serverUrl) throw new Error(\"serverUrl is required\");\n if (!config.agentId) throw new Error(\"agentId is required\");\n\n this.serverUrl = config.serverUrl.replace(/\\/$/, '');\n this.agentId = config.agentId;\n this.callId = config.callId || this.generateCallId();\n this.iceServers = config.iceServers;\n this.token = config.token;\n\n // Callbacks\n this.onConnected = config.onConnected || (() => { });\n this.onDisconnected = config.onDisconnected || (() => { });\n this.onError = config.onError || ((e) => console.error('[WebRTC]', e));\n this.onTranscription = config.onTranscription || (() => { });\n // @ts-ignore\n this.onRemoteTrack = config.onRemoteTrack || (() => { });\n this.onClientToolCall = config.onClientToolCall || (() => { });\n }\n\n /**\n * Connect via HTTP signaling (no WebSocket)\n */\n async connect(): Promise<void> {\n console.log('đĩ [WebRTC] Starting connection...');\n\n try {\n // Fetch ICE servers if not provided\n if (!this.iceServers && this.token) {\n try {\n this.iceServers = await WebRTCClient.fetchIceServers(this.token);\n } catch (e) {\n console.warn('â ī¸ [WebRTC] Failed to fetch ICE servers:', e);\n }\n }\n\n // 1. Create RTCPeerConnection\n this.pc = new RTCPeerConnection({\n iceServers: this.iceServers || [\n {\n urls: 'stun:global.relay.metered.ca:80'\n },\n {\n urls: [\n 'turns:global.relay.metered.ca:443?transport=tcp',\n 'turn:global.relay.metered.ca:80?transport=tcp',\n 'turn:global.relay.metered.ca:443?transport=tcp'\n ],\n username: 'fa97658be3343d21da3b65e6',\n credential: 'HXHDoqeHbvZrmCuf'\n }\n ]\n });\n\n // Add video transceiver to ensure we offer video handling capability\n this.pc.addTransceiver('video', { direction: 'recvonly' });\n\n // 2. Get microphone with AEC/NS/AGC\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n sampleRate: { ideal: 16000 },\n channelCount: 1\n }\n });\n console.log('đ¤ [WebRTC] Microphone access granted');\n\n // Check if connection was closed during getUserMedia (e.g., StrictMode unmount)\n if (!this.pc) {\n console.log('[WebRTC] Connection aborted: peer connection closed during setup');\n stream.getTracks().forEach(track => track.stop()); // Clean up media tracks\n return;\n }\n\n // 3. Add audio track\n stream.getTracks().forEach(track => {\n this.pc?.addTrack(track, stream);\n });\n\n // 4. Create DataChannel for control events\n if (!this.pc) {\n throw new Error('RTCPeerConnection was closed unexpectedly');\n }\n this.dataChannel = this.pc.createDataChannel('control');\n this.dataChannel.onopen = () => console.log('đĄ [WebRTC] DataChannel opened');\n this.dataChannel.onmessage = (e) => {\n // Handle both string and ArrayBuffer data\n if (typeof e.data === 'string') {\n try {\n this.handleControlEvent(JSON.parse(e.data));\n } catch (err) {\n console.warn('[WebRTC] Failed to parse message:', e.data);\n }\n } else if (e.data instanceof ArrayBuffer) {\n // Binary data: decode and log for inspection only\n // DO NOT re-feed into handleControlEvent (binary frames may falsely decode as clearAudio etc.)\n try {\n const text = new TextDecoder().decode(e.data);\n try {\n const parsed = JSON.parse(text);\n // Only explicitly forward client_tool_call to prevent clearAudio bugs\n if (parsed && typeof parsed === 'object' && parsed.event === 'client_tool_call') {\n console.log('[VaniraAI] Safely decoding binary tool_call to JSON:', parsed);\n this.handleControlEvent(parsed);\n } else {\n console.log('[VaniraAI] Decoded JSON from binary (inspect only):', parsed);\n }\n } catch (_) {\n console.log('[VaniraAI] Decoded String from binary:', text);\n }\n } catch (_) {\n console.log('[VaniraAI] Received binary data:', e.data.byteLength, 'bytes (not decodable)');\n }\n } else if (e.data instanceof Blob) {\n // Blob data - convert to text if needed\n e.data.text().then(text => {\n try {\n this.handleControlEvent(JSON.parse(text));\n } catch (err) {\n console.warn('[WebRTC] Failed to parse blob data:', text);\n }\n });\n }\n };\n this.dataChannel.onerror = (e) => console.error('â [WebRTC] DataChannel error:', e);\n\n // 5. Handle incoming tracks from server\n this.pc.ontrack = (event) => {\n const track = event.track;\n const stream = event.streams[0];\n console.log(`đĨ [WebRTC] Received ${track.kind} track`);\n\n if (track.kind === 'audio') {\n console.log('đ [WebRTC] Received audio track from server');\n this.audioElement = new Audio();\n this.audioElement.srcObject = stream;\n this.audioElement.play().catch(e => console.warn('Audio autoplay blocked:', e));\n\n // Notify server when playback finishes\n this.audioElement.onended = () => {\n this.sendEvent('playedStream');\n console.log('â
[WebRTC] TTS playback complete');\n };\n } else if (track.kind === 'video') {\n console.log('đš [WebRTC] Video track received');\n this.onRemoteTrack(track, stream);\n }\n };\n\n // 6. Connection state monitoring\n const checkConnectionState = () => {\n console.log('đ [WebRTC] State:', this.pc?.connectionState, '| ICE:', this.pc?.iceConnectionState);\n const isConnected =\n this.pc?.connectionState === 'connected' ||\n this.pc?.iceConnectionState === 'connected' ||\n this.pc?.iceConnectionState === 'completed';\n\n const isFailed =\n this.pc?.connectionState === 'failed' ||\n this.pc?.iceConnectionState === 'failed' ||\n this.pc?.connectionState === 'closed' ||\n this.pc?.iceConnectionState === 'closed' ||\n this.pc?.connectionState === 'disconnected' ||\n this.pc?.iceConnectionState === 'disconnected';\n\n if (isConnected && !this.connected) {\n this.connected = true;\n this.onConnected();\n } else if (isFailed && this.connected) {\n this.connected = false;\n this.onDisconnected();\n }\n };\n\n this.pc.onconnectionstatechange = checkConnectionState;\n this.pc.oniceconnectionstatechange = checkConnectionState;\n\n // 7. Create offer\n const offer = await this.pc.createOffer();\n await this.pc.setLocalDescription(offer);\n console.log('đ [WebRTC] Created offer, waiting for ICE gathering...');\n\n // 8. Wait for ICE gathering to complete (non-trickle)\n await this.waitForIceGathering();\n console.log('đ§ [WebRTC] ICE gathering complete');\n\n // 9. Send offer via HTTP POST\n console.log('đ¤ [WebRTC] Sending offer via HTTP...');\n const response = await fetch(`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n offer: this.pc.localDescription,\n agentId: this.agentId,\n callId: this.callId\n })\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n const { answer } = await response.json();\n console.log('đĨ [WebRTC] Received answer from server');\n\n // 10. Set remote description\n await this.pc.setRemoteDescription(answer);\n console.log('â
[WebRTC] Connection established!');\n\n } catch (error: any) {\n console.error('â [WebRTC] Connection failed:', error);\n this.disconnect(); // Ensure cleanup (pc, streams, etc.)\n this.onError(error.message || error);\n throw error;\n }\n }\n\n /**\n * Wait for ICE gathering to complete\n */\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) return resolve();\n if (this.pc.iceGatheringState === 'complete') {\n resolve();\n } else {\n const checkState = () => {\n if (this.pc?.iceGatheringState === 'complete') {\n this.pc?.removeEventListener('icegatheringstatechange', checkState);\n resolve();\n }\n };\n this.pc.addEventListener('icegatheringstatechange', checkState);\n\n // Timeout fallback (5 seconds)\n setTimeout(() => {\n this.pc?.removeEventListener('icegatheringstatechange', checkState);\n console.warn('â ī¸ [WebRTC] ICE gathering timeout, proceeding anyway');\n resolve();\n }, 5000);\n }\n });\n }\n\n /**\n * Send control event via DataChannel\n */\n sendEvent(event: string, data = {}): void {\n if (this.dataChannel?.readyState === 'open') {\n this.dataChannel.send(JSON.stringify({ event, ...data }));\n }\n }\n\n /**\n * Handle control events from server\n */\n private handleControlEvent(msg: ControlEvent): void {\n switch (msg.event) {\n case 'clearAudio':\n console.log('đ [WebRTC] Interrupt: clearAudio received (levanirag stream unpaused)');\n // DONT pause the audio element! The server simply stops sending packets.\n // Pausing a WebRTC stream's audio element permanently mutes all future backend packets.\n // if (this.audioElement) {\n // this.audioElement.pause();\n // this.audioElement.currentTime = 0;\n // }\n break;\n\n case 'transcription':\n console.log('đ [WebRTC] Transcription:', msg.text);\n // @ts-ignore\n this.onTranscription(msg.text, msg.isFinal);\n break;\n\n case 'mark':\n // @ts-ignore\n console.log('đˇī¸ [WebRTC] Mark:', msg.name);\n break;\n\n case 'client_tool_call':\n console.log('đ ī¸ [VaniraAI] Client Tool Call:', msg);\n this.onClientToolCall(msg.tool_call || msg.data || msg);\n break;\n\n default:\n console.log('âšī¸ [WebRTC] Unknown event:', msg.event);\n }\n }\n\n /**\n * Disconnect and cleanup\n */\n disconnect(): void {\n console.log('đ´ [WebRTC] Disconnecting...');\n\n if (this.audioElement) {\n this.audioElement.pause();\n this.audioElement.srcObject = null;\n }\n\n if (this.dataChannel) {\n this.dataChannel.close();\n this.dataChannel = null;\n }\n\n if (this.pc) {\n // Stop all local tracks (Microphone) to release the device\n this.pc.getSenders().forEach(sender => {\n if (sender.track) {\n sender.track.stop();\n }\n });\n this.pc.close();\n this.pc = null;\n }\n\n this.connected = false;\n this.onDisconnected();\n }\n\n /**\n * Generate unique call ID\n */\n generateCallId(): string {\n return 'web_' + Date.now() + '_' + Math.random().toString(36).substr(2, 8);\n }\n\n /**\n * Send client-side tool execution result back to the AI server.\n * Use this to unblock a 'blocking' execution mode tool.\n */\n sendToolResult(callId: string, result: any): void {\n this.sendEvent('client_tool_result', {\n call_id: callId,\n result: result\n });\n }\n\n /**\n * Silently update the AI's context with what the user is currently viewing.\n * Does NOT interrupt the AI's current speech.\n */\n sendSilentContext(context: string): void {\n this.sendEvent('silent_context', { context });\n }\n\n /**\n * Trigger a client-side interrupt â cuts AI audio and forces it to react to a UI event.\n */\n triggerActionInterrupt(): void {\n // DONT pause the audio element! The server simply stops sending packets.\n // Pausing a WebRTC stream's audio element permanently mutes all future backend packets.\n // if (this.audioElement) {\n // this.audioElement.pause();\n // this.audioElement.currentTime = 0;\n // }\n this.sendEvent('action_interrupt');\n console.log('đ [VaniraAI] Triggered client-side action interrupt');\n }\n\n /**\n * Static helper to fetch ICE servers from Hasura\n */\n public static async fetchIceServers(token: string, graphqlEndpoint: string = 'https://coredb.travelr.club/v1/graphql'): Promise<RTCIceServer[]> {\n try {\n const query = `\n query GetIceServers {\n ice_servers(where: {enabled: {_eq: true}}) {\n urls\n username\n credential\n }\n }`;\n\n const response = await fetch(graphqlEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': token,\n },\n body: JSON.stringify({ query }),\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch ICE servers');\n }\n\n const data = await response.json();\n return data.data?.ice_servers || [];\n } catch (error) {\n console.error('[WebRTC] Failed to fetch ICE servers:', error);\n throw error;\n }\n }\n}\n","/**\n * VaniraAI SDK\n * ============\n * A simple, developer-friendly Voice AI client.\n * Hides all WebRTC complexity behind a clean event-emitter API.\n *\n * @example\n * ```ts\n * const client = new VaniraAI({ agentId: 'your-agent-id', token: 'Bearer your-token' });\n * client.on('tool_call', ({ name, arguments: args, tool_call_id, execution_mode }) => {\n * // render your UI component here\n * if (execution_mode === 'blocking') {\n * client.sendToolResult(tool_call_id, { success: true });\n * }\n * });\n * await client.start();\n * ```\n */\n\nimport { WebRTCClient } from './WebRTCClient';\n\n// âââ Types âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\nexport type VaniraAIStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';\n\nexport interface VaniraAIConfig {\n /** Your Vanira agent ID from the dashboard */\n agentId: string;\n /** Bearer token for authentication. Required for ICE server fetching. */\n token?: string;\n /** Override the WebRTC server URL. Auto-detected if omitted. */\n serverUrl?: string;\n /** Override the GraphQL endpoint for config fetching. */\n graphqlEndpoint?: string;\n /** Optional: pre-supply your own ICE servers (skips auto-fetch). */\n iceServers?: RTCIceServer[];\n /** Optional call ID override. Auto-generated if omitted. */\n callId?: string;\n}\n\nexport interface ClientToolCall {\n /** The ref_code of the triggered action */\n name: string;\n /** The mapped payload from client_action_fields */\n arguments: Record<string, any>;\n /** Unique ID for this execution. Required when sending a result back for blocking tools. */\n tool_call_id: string;\n /** Whether the AI is paused waiting for result ('blocking') or keeps talking ('fire_and_forget') */\n execution_mode: 'blocking' | 'fire_and_forget';\n}\n\nexport interface TranscriptionEvent {\n text: string;\n isFinal: boolean;\n}\n\ntype EventMap = {\n /** Fired when WebRTC connection is fully established */\n connected: void;\n /** Fired when the connection is lost or explicitly disconnected */\n disconnected: void;\n /** Fired on connection or protocol error. Payload is an error message string. */\n error: string;\n /** Fired whenever the AI transcribes speech (both interim and final) */\n transcription: TranscriptionEvent;\n /** Fired when the AI triggers a client-side tool (action) */\n tool_call: ClientToolCall;\n /** Fired when a remote media track (like video) is received */\n track: { track: MediaStreamTrack; stream: MediaStream };\n};\n\ntype EventCallback<T> = T extends void ? () => void : (payload: T) => void;\n\n// âââ VaniraAI Class ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\nexport class VaniraAI {\n private config: VaniraAIConfig;\n private _status: VaniraAIStatus = 'idle';\n private client: WebRTCClient | null = null;\n private listeners: Map<string, Set<Function>> = new Map();\n\n constructor(config: VaniraAIConfig) {\n if (!config.agentId) throw new Error('[VaniraAI] agentId is required');\n this.config = config;\n }\n\n // âââ Status ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /** Current connection status */\n get status(): VaniraAIStatus {\n return this._status;\n }\n\n /** Shorthand: true when status is 'connected' */\n get isConnected(): boolean {\n return this._status === 'connected';\n }\n\n // âââ Event Emitter âââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Register an event listener.\n * @param event - Event name\n * @param callback - Handler function\n * @returns `this` for chaining\n */\n on<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n return this;\n }\n\n /**\n * Remove a previously registered event listener.\n * @param event - Event name\n * @param callback - The exact same function reference that was registered\n */\n off<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): this {\n this.listeners.get(event)?.delete(callback);\n return this;\n }\n\n private emit<K extends keyof EventMap>(event: K, payload?: EventMap[K]): void {\n this.listeners.get(event)?.forEach(cb => cb(payload));\n }\n\n // âââ Lifecycle âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Connect to the Voice AI agent and start the call.\n * Requests microphone permission, establishes WebRTC, and opens the data channel.\n */\n async start(): Promise<void> {\n if (this._status === 'connecting' || this._status === 'connected') {\n console.warn('[VaniraAI] Already connecting or connected. Call stop() first.');\n return;\n }\n\n this._setStatus('connecting');\n\n const serverUrl = this.config.serverUrl || this._inferServerUrl();\n\n try {\n this.client = new WebRTCClient({\n serverUrl,\n agentId: this.config.agentId,\n callId: this.config.callId,\n token: this.config.token,\n iceServers: this.config.iceServers,\n onConnected: () => {\n this._setStatus('connected');\n this.emit('connected');\n },\n onDisconnected: () => {\n this._setStatus('disconnected');\n this.emit('disconnected');\n },\n onError: (err: any) => {\n this._setStatus('error');\n this.emit('error', typeof err === 'string' ? err : (err?.message || 'Connection failed'));\n },\n onTranscription: (text: string, isFinal: boolean) => {\n this.emit('transcription', { text, isFinal });\n },\n // @ts-ignore - onClientToolCall is on the dashboard's WebRTCClient; proxy it here\n onClientToolCall: (rawCall: any) => {\n // Normalize the payload (server may send nested or flat)\n const data = rawCall?.data || rawCall;\n const toolCall: ClientToolCall = {\n name: data.name || data.tool_name || '',\n arguments: data.arguments || data.args || {},\n tool_call_id: data.tool_call_id || data.call_id || '',\n execution_mode: data.execution_mode || 'fire_and_forget',\n };\n this.emit('tool_call', toolCall);\n },\n // @ts-ignore - onRemoteTrack is on the dashboard's WebRTCClient; proxy it here\n onRemoteTrack: (track: MediaStreamTrack, stream: MediaStream) => {\n this.emit('track', { track, stream });\n }\n });\n\n await this.client.connect();\n } catch (err: any) {\n this._setStatus('error');\n this.emit('error', err?.message || 'Failed to start call');\n throw err;\n }\n }\n\n /**\n * Disconnect the call and release all resources (microphone, WebRTC connection).\n */\n stop(): void {\n if (this.client) {\n this.client.disconnect();\n this.client = null;\n }\n this._setStatus('disconnected');\n }\n\n // âââ Client â Server Actions âââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Send the result of a **blocking** client-side tool back to the AI.\n * The AI is paused and will resume once it receives this.\n *\n * @param toolCallId - The `tool_call_id` from the `tool_call` event\n * @param result - Arbitrary JSON payload the AI needs to continue\n *\n * @example\n * client.sendToolResult(tool_call_id, { selected_store: 'Store #5' });\n */\n sendToolResult(toolCallId: string, result: Record<string, any>): void {\n this._assertConnected('sendToolResult');\n this.client!.sendToolResult(toolCallId, result);\n }\n\n /**\n * Send an error result for a **blocking** client-side tool.\n * Use when the user cancelled or the UI crashed.\n *\n * @param toolCallId - The `tool_call_id` from the `tool_call` event\n * @param errorMessage - Human-readable error description\n */\n sendToolError(toolCallId: string, errorMessage: string): void {\n this._assertConnected('sendToolError');\n // Fallback: use the generic sendEvent until SDK's WebRTCClient is fully updated\n this.client!.sendEvent('client_tool_result', {\n call_id: toolCallId,\n result: { status: 'error', error: errorMessage }\n });\n }\n\n /**\n * Silently update the AI's context with what the user is currently doing on screen.\n * Does NOT interrupt the AI's current speech.\n *\n * @example\n * client.updateContext({ active_page: 'Checkout', item: 'Nike Shoes', price: 149.99 });\n */\n updateContext(context: Record<string, any>): void {\n this._assertConnected('updateContext');\n this.client!.sendEvent('client_context_update', {\n data: {\n context\n }\n });\n }\n\n /**\n * Force the AI to stop speaking and immediately react to a UI event.\n * Use when the user performs a significant action (e.g., clicks a button, opens a page).\n *\n * @param actionName - A descriptive name for the action (e.g., 'user_clicked_cart')\n * @param data - Optional context about the action\n *\n * @example\n * client.triggerInterrupt('user_opened_checkout', { cart_value: 299 });\n */\n triggerInterrupt(actionName: string, data: Record<string, any> = {}): void {\n this._assertConnected('triggerInterrupt');\n this.client!.triggerActionInterrupt();\n // Send the action context using the exact `client_action_trigger` envelope the backend Go server expects\n this.client!.sendEvent('client_action_trigger', {\n data: {\n action_name: actionName,\n data\n }\n });\n }\n\n // âââ Private helpers âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private _setStatus(status: VaniraAIStatus): void {\n this._status = status;\n }\n\n private _inferServerUrl(): string {\n // Default production server URL â overridable via config.serverUrl\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const env = (typeof import.meta !== 'undefined' && (import.meta as any).env) || {};\n return env.VITE_WEBRTC_SERVER_URL || 'https://in-godspeed.travelr.club';\n }\n\n private _assertConnected(method: string): void {\n if (!this.client || !this.isConnected) {\n throw new Error(`[VaniraAI] Cannot call ${method}() when not connected. Call start() first.`);\n }\n }\n}\n","/**\n * SessionManager\n * ==============\n * Manages per-tab widget sessions using:\n * - sessionStorage â tab_id (unique per browser tab, survives refresh, gone on tab close)\n * - localStorage â session data (prospect_id, chat_id, messages â persists across refreshes)\n * - BroadcastChannel â real-time cross-tab communication\n * - Heartbeat â detect dead tabs (no heartbeat for 15s â tab considered gone)\n *\n * Key behaviours:\n * 1. Each tab gets a unique tab_id.\n * 2. Only one tab is \"active\" at a time (owns the session).\n * 3. When a second tab loads the widget, it detects the conflict and fires onTabConflict().\n * 4. Chat messages, prospect_id and chat_id are persisted so a page refresh restores the session.\n * 5. Tab closure is detected via heartbeat expiry â the next tab to init auto-claims.\n */\n\nexport interface StoredMessage {\n role: 'user' | 'assistant';\n content: string;\n timestamp: number;\n}\n\nexport interface SessionData {\n tabId: string;\n prospectId: string;\n chatId: string | null;\n messages: StoredMessage[];\n lastActive: number; // unix ms â heartbeat timestamp\n}\n\nexport type SessionEvent =\n | 'tab_conflict' // another tab already owns the session\n | 'session_claimed' // this tab successfully claimed the session\n | 'session_restored' // existing session loaded (prospect/chatId/messages recovered)\n | 'tab_took_over' // a different tab stole the session from this one\n | 'session_cleared'; // session was explicitly cleared\n\nexport class SessionManager {\n private tabId: string;\n private sessionKey: string;\n private channelName: string;\n\n private channel: BroadcastChannel | null = null;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private listeners: Map<SessionEvent, Set<Function>> = new Map();\n\n /** How often (ms) the active tab broadcasts its heartbeat */\n private static readonly HEARTBEAT_INTERVAL_MS = 5_000;\n /** How old (ms) a heartbeat must be before we consider the tab dead */\n private static readonly HEARTBEAT_TIMEOUT_MS = 15_000;\n\n constructor(widgetId: string) {\n const safeId = widgetId.replace(/[^a-z0-9_-]/gi, '_');\n this.sessionKey = `vaniraai_session_${safeId}`;\n this.channelName = `vaniraai_channel_${safeId}`;\n this.tabId = this._getOrCreateTabId();\n\n this._setupChannel();\n }\n\n // âââ Public API ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /** Returns this tab's unique ID (stable across same-tab page refreshes). */\n getTabId(): string {\n return this.tabId;\n }\n\n /**\n * Try to claim the session for this tab.\n * Returns true â session claimed (or restored after stale prior tab).\n * Returns false â another live tab already owns the session.\n */\n claimSession(): boolean {\n const existing = this._loadSession();\n\n if (existing) {\n const age = Date.now() - existing.lastActive;\n const isOwnTab = existing.tabId === this.tabId;\n const isStaletab = age > SessionManager.HEARTBEAT_TIMEOUT_MS;\n\n if (isOwnTab) {\n // This tab already owned the session (e.g. page refresh)\n this._startHeartbeat();\n this._emit('session_restored');\n return true;\n }\n\n if (!isStaletab) {\n // A live different tab owns the session â conflict\n this._emit('tab_conflict');\n return false;\n }\n // Stale tab â safe to take over\n }\n\n // No session or stale session â claim it\n const draft: SessionData = existing\n ? { ...existing, tabId: this.tabId, lastActive: Date.now() }\n : { tabId: this.tabId, prospectId: '', chatId: null, messages: [], lastActive: Date.now() };\n\n this._saveSession(draft);\n this._startHeartbeat();\n\n // Notify other tabs (if any) that this tab took over\n this._broadcast({ type: 'took_over', tabId: this.tabId });\n\n const hadPrior = !!(existing?.prospectId);\n this._emit(hadPrior ? 'session_restored' : 'session_claimed');\n return true;\n }\n\n /**\n * Force-claim the session even if another tab owns it.\n * Call this when the user explicitly clicks \"Use here\" in the conflict UI.\n */\n forceClaimSession(): void {\n const existing = this._loadSession();\n const draft: SessionData = existing\n ? { ...existing, tabId: this.tabId, lastActive: Date.now() }\n : { tabId: this.tabId, prospectId: '', chatId: null, messages: [], lastActive: Date.now() };\n\n this._saveSession(draft);\n this._startHeartbeat();\n this._broadcast({ type: 'took_over', tabId: this.tabId });\n this._emit('session_claimed');\n }\n\n /** Save / update the prospect and chat IDs for this session. */\n saveIds(prospectId: string, chatId: string | null): void {\n const session = this._loadSession() ?? this._blankSession();\n this._saveSession({ ...session, prospectId, chatId, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Append a message to the persisted history. */\n pushMessage(role: 'user' | 'assistant', content: string): void {\n const session = this._loadSession() ?? this._blankSession();\n session.messages.push({ role, content, timestamp: Date.now() });\n\n // Keep last 100 messages to avoid bloating localStorage\n if (session.messages.length > 100) {\n session.messages = session.messages.slice(-100);\n }\n\n this._saveSession({ ...session, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Update the content of the last assistant message (streaming). */\n updateLastAssistantMessage(content: string): void {\n const session = this._loadSession() ?? this._blankSession();\n const msgs = session.messages;\n\n // Find the last assistant message that is a placeholder (empty) or the last one\n let found = false;\n for (let i = msgs.length - 1; i >= 0; i--) {\n if (msgs[i].role === 'assistant' && msgs[i].content === '') {\n // Update the placeholder we pushed before streaming started\n msgs[i].content = content;\n found = true;\n break;\n }\n }\n\n if (!found) {\n // Fallback: update the very last assistant message (older approach)\n for (let i = msgs.length - 1; i >= 0; i--) {\n if (msgs[i].role === 'assistant') {\n msgs[i].content = content;\n found = true;\n break;\n }\n }\n }\n\n if (!found) {\n // No assistant message at all â just append\n msgs.push({ role: 'assistant', content, timestamp: Date.now() });\n }\n\n this._saveSession({ ...session, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Returns the currently persisted session data (null if none). */\n getSession(): SessionData | null {\n return this._loadSession();\n }\n\n /** Clears ALL session data (prospect_id, chat_id, messages). */\n clearSession(): void {\n localStorage.removeItem(this.sessionKey);\n this._broadcast({ type: 'session_cleared', tabId: this.tabId });\n this._emit('session_cleared');\n }\n\n /** Stop the heartbeat and release resources. Call on widget destroy. */\n destroy(): void {\n this._stopHeartbeat();\n if (this.channel) {\n this.channel.close();\n this.channel = null;\n }\n }\n\n // âââ Event Emitter âââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n on(event: SessionEvent, cb: Function): this {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(cb);\n return this;\n }\n\n off(event: SessionEvent, cb: Function): this {\n this.listeners.get(event)?.delete(cb);\n return this;\n }\n\n // âââ Private âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private _getOrCreateTabId(): string {\n let id = sessionStorage.getItem('vaniraai_tab_id');\n if (!id) {\n id = `tab_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n sessionStorage.setItem('vaniraai_tab_id', id);\n }\n return id;\n }\n\n private _setupChannel(): void {\n if (typeof BroadcastChannel === 'undefined') return; // SSR / old browsers\n\n this.channel = new BroadcastChannel(this.channelName);\n this.channel.onmessage = (ev) => {\n const msg = ev.data as { type: string; tabId: string };\n\n if (msg.tabId === this.tabId) return; // Ignore own messages\n\n if (msg.type === 'took_over') {\n // Another tab stole the session from us\n this._stopHeartbeat();\n this._emit('tab_took_over');\n }\n\n if (msg.type === 'heartbeat') {\n // Another tab is alive â if that tab isn't us, we're in conflict\n // (handled at claimSession time, not runtime)\n }\n\n if (msg.type === 'session_cleared') {\n this._emit('session_cleared');\n }\n };\n }\n\n private _broadcast(data: object): void {\n this.channel?.postMessage(data);\n }\n\n private _startHeartbeat(): void {\n this._stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n const session = this._loadSession();\n if (session && session.tabId === this.tabId) {\n this._saveSession({ ...session, lastActive: Date.now() });\n this._broadcast({ type: 'heartbeat', tabId: this.tabId });\n }\n }, SessionManager.HEARTBEAT_INTERVAL_MS);\n }\n\n private _stopHeartbeat(): void {\n if (this.heartbeatTimer !== null) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n private _loadSession(): SessionData | null {\n try {\n const raw = localStorage.getItem(this.sessionKey);\n return raw ? (JSON.parse(raw) as SessionData) : null;\n } catch {\n return null;\n }\n }\n\n private _saveSession(data: SessionData): void {\n try {\n localStorage.setItem(this.sessionKey, JSON.stringify(data));\n } catch (e) {\n console.warn('[VaniraAI] SessionManager: failed to save session', e);\n }\n }\n\n private _blankSession(): SessionData {\n return {\n tabId: this.tabId,\n prospectId: '',\n chatId: null,\n messages: [],\n lastActive: Date.now(),\n };\n }\n\n private _emit(event: SessionEvent): void {\n this.listeners.get(event)?.forEach(cb => cb());\n }\n}\n","export const MALE_ICON_BASE64 = \"data:image/png;base64,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\";\nexport const FEMALE_ICON_BASE64 = \"data:image/png;base64,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\";\n","export const theme = {\n colors: {\n primary: 'var(--primary, #6366f1)',\n primaryHover: 'var(--primary-hover, #4f46e5)',\n secondary: 'var(--secondary, #4f46e5)',\n bg: 'var(--bg, #ffffff)',\n text: 'var(--text, #1f2937)',\n textMuted: 'var(--text-muted, #6b7280)',\n border: 'var(--border, #e5e7eb)',\n danger: '#ef4444',\n success: '#10b981',\n white: '#ffffff',\n },\n shadows: {\n base: 'var(--shadow, 0 10px 40px rgba(0, 0, 0, 0.1))',\n lg: 'var(--shadow-lg, 0 20px 60px rgba(0, 0, 0, 0.15))',\n },\n transitions: {\n base: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n smooth: 'all 0.5s ease',\n },\n fonts: {\n base: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n }\n};\n\nexport const generateThemeVars = (primary: string, secondary: string | null) => {\n return `\n --primary: ${primary};\n --primary-hover: ${secondary || primary};\n --secondary: ${secondary || primary};\n `;\n};\n","\nimport { keyframes } from './keyframes';\n\nexport const widgetStyles = `\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n box-sizing: border-box;\n \n /* Default Theme Variables */\n --primary: #6366f1;\n --primary-hover: #4f46e5;\n --bg: #ffffff;\n --text: #1f2937;\n --text-muted: #6b7280;\n --border: #e5e7eb;\n --shadow: 0 10px 40px rgba(0, 0, 0, 0.1);\n --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.15);\n }\n\n :host * {\n box-sizing: border-box;\n }\n\n ${keyframes}\n\n .widget-fab {\n position: fixed;\n z-index: 9999;\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--shadow);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: fadeInScale 0.4s ease-out;\n }\n\n .widget-fab:hover {\n transform: scale(1.1);\n box-shadow: var(--shadow-lg);\n }\n\n .widget-fab:active {\n transform: scale(0.95);\n }\n\n .widget-fab svg {\n width: 28px;\n height: 28px;\n color: white;\n }\n\n .widget-panel {\n position: fixed;\n z-index: 10000; /* Higher than FAB */\n background: rgba(255, 255, 255, 0.98);\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n border: 1px solid #d1d5db; /* Solid light gray border for better differentiation */\n border-radius: 28px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n \n /* Default Dimensions */\n width: 400px;\n height: 600px;\n max-height: 90vh;\n max-width: 95vw;\n }\n\n .widget-panel.maximized {\n width: 90vw !important;\n height: 90vh !important;\n top: 5vh !important;\n left: 5vw !important;\n right: 5vw !important;\n bottom: 5vh !important;\n margin: auto;\n }\n\n .widget-panel.maximized {\n width: 800px;\n max-width: calc(100vw - 40px);\n height: 80vh;\n }\n\n .widget-body {\n padding: 0;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n }\n\n .widget-panel.hidden {\n opacity: 0;\n pointer-events: none;\n transform: translateY(20px) scale(0.95);\n }\n/* ... rest of the content is redundant if I use replace or overwrite, but I will overwrite to include everything properly */\n .widget-header {\n background: #1f2937;\n color: white;\n padding: 14px 20px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .widget-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0;\n letter-spacing: 0.3px;\n }\n\n .close-btn {\n background: rgba(255, 255, 255, 0.15);\n border: none;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s;\n backdrop-filter: blur(10px);\n }\n\n .close-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n transform: scale(1.1);\n }\n\n .close-btn.maximize-btn {\n display: flex;\n }\n\n .close-btn svg {\n width: 18px;\n height: 18px;\n color: white;\n flex-shrink: 0;\n }\n\n .widget-body {\n padding: 0;\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n\n .status-indicator {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: #f9fafb;\n border-radius: 12px;\n margin-bottom: 20px;\n }\n\n .status-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #10b981;\n animation: pulse 2s infinite;\n }\n\n .status-text {\n font-size: 14px;\n color: var(--text-muted);\n margin: 0;\n }\n\n .controls {\n display: flex;\n gap: 12px;\n justify-content: center;\n }\n\n .control-btn {\n flex: 1;\n padding: 14px 20px;\n border: none;\n border-radius: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .control-btn svg {\n width: 18px;\n height: 18px;\n }\n\n .control-btn.primary {\n background: #1f2937;\n color: white;\n }\n\n .control-btn.primary:hover {\n background: #374151;\n }\n\n .control-btn.danger {\n background: #ef4444;\n color: white;\n }\n\n .control-btn.danger:hover {\n background: #dc2626;\n }\n\n .voice-mode-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding-bottom: 0;\n }\n\n .central-orb-container {\n position: relative;\n width: 120px;\n height: 120px;\n margin-bottom: 32px;\n cursor: pointer;\n }\n\n .central-orb {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n position: relative;\n z-index: 10;\n box-shadow: 0 10px 30px rgba(99, 102, 241, 0.3);\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .central-orb.active {\n animation: pulse 2s infinite;\n }\n \n .central-orb.idle {\n animation: floatOrb 4s ease-in-out infinite;\n cursor: pointer;\n }\n\n .central-orb.idle:hover {\n transform: scale(1.05);\n }\n\n .central-orb-glow {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 140%;\n height: 140%;\n background: radial-gradient(circle, rgba(99, 102, 241, 0.2) 0%, transparent 70%);\n animation: pulseGlowIdle 4s ease-in-out infinite;\n z-index: -1;\n pointer-events: none;\n }\n\n .central-orb svg {\n width: 24px;\n height: 24px;\n }\n\n .voice-status-text {\n font-size: 20px;\n font-weight: 600;\n color: var(--text);\n margin-bottom: 8px;\n text-align: center;\n }\n\n .voice-status-subtext {\n font-size: 14px;\n color: var(--text-muted);\n text-align: center;\n }\n\n /* Chat Mode Styles */\n .chat-messages {\n flex: 1;\n min-height: 0; /* Crucial for scrolling in flex column */\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: #f9fafb; \n \n /* Scrollbar Styling */\n scrollbar-width: thin;\n scrollbar-color: rgba(156, 163, 175, 0.5) transparent;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background-color: rgba(156, 163, 175, 0.5);\n border-radius: 3px;\n }\n\n .chat-messages::-webkit-scrollbar-thumb:hover {\n background-color: rgba(107, 114, 128, 0.8);\n }\n\n .chat-message {\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user {\n align-self: flex-end;\n background: #000000;\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.assistant {\n align-self: flex-start;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n color: var(--text);\n border-bottom-left-radius: 4px;\n box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n }\n\n .chat-input-area {\n padding: 20px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n display: flex;\n gap: 10px;\n align-items: center;\n background: white;\n z-index: 30;\n position: relative;\n border-bottom-left-radius: 28px;\n border-bottom-right-radius: 28px;\n }\n\n .chat-input {\n flex: 1;\n padding: 14px 20px;\n border: 1px solid #e5e7eb;\n border-radius: 28px;\n font-size: 15px;\n outline: none;\n transition: all 0.3s;\n background: #f3f4f6;\n color: #1f2937;\n }\n\n .chat-input:focus {\n border-color: var(--primary);\n background: white;\n box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);\n }\n\n .chat-send-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--primary);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n flex-shrink: 0;\n }\n\n .chat-send-btn:hover {\n transform: scale(1.05) rotate(-10deg);\n background: var(--primary-hover);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n }\n\n .chat-send-btn:active {\n transform: scale(0.95);\n }\n\n .chat-send-btn svg {\n width: 22px;\n height: 22px;\n color: white;\n margin-left: 2px;\n }\n\n /* Avatar Container */\n .avatar-container {\n background: transparent;\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n }\n \n /* Avatar Video */\n .avatar-video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n /* Voice Button (Simple) in Chat */\n .voice-btn-simple {\n position: relative;\n width: 44px; /* Matching send-btn size for symmetry */\n height: 44px;\n border-radius: 50%;\n border: 1.5px solid #e5e7eb;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.3s;\n overflow: visible;\n background: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .voice-btn-simple:hover {\n transform: scale(1.05);\n background: #f9fafb;\n border-color: #9ca3af;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);\n }\n\n .voice-btn-simple:active {\n animation: clickBounce 0.4s ease-out;\n }\n\n .voice-btn-icon {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #4b5563;\n }\n\n .voice-btn-icon svg {\n width: 20px;\n height: 20px;\n stroke-width: 2px;\n }\n\n /* Utility Classes */\n .absolute { position: absolute; }\n .relative { position: relative; }\n .rounded-full { border-radius: 9999px; }\n .flex { display: flex; }\n .items-center { align-items: center; }\n .justify-center { justify-content: center; }\n .w-full { width: 100%; }\n .h-full { height: 100%; }\n .z-50 { z-index: 50; }\n\n .branding-footer {\n display: flex;\n justify-content: center;\n padding: 4px 0 8px 0;\n background-color: #f9fafb;\n font-size: 10px;\n color: #9ca3af;\n font-weight: 500;\n letter-spacing: 0.025em;\n }\n\n .branding-footer b {\n color: #3b82f6;\n font-weight: 700;\n margin-left: 4px;\n }\n\n @media (max-width: 640px) {\n .widget-panel {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n border-radius: 0 !important;\n margin: 0 !important;\n }\n\n .widget-fab {\n width: 56px;\n height: 56px;\n bottom: 16px !important;\n right: 16px !important;\n }\n\n :host(.vanira-panel-open) .widget-fab {\n display: none !important;\n }\n\n .close-btn.maximize-btn {\n display: none !important;\n }\n\n .widget-header {\n padding: 12px 16px;\n }\n\n .widget-title {\n font-size: 16px;\n }\n\n .chat-input-area {\n padding: 12px;\n padding-bottom: env(safe-area-inset-bottom, 12px);\n }\n }\n`;\n","import { MALE_ICON_BASE64, FEMALE_ICON_BASE64 } from '../icons_data';\n\nexport const icons = {\n phone: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"/>\n </svg>\n `,\n close: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n `,\n mic: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n `,\n micOff: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"/>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\"/>\n <path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\n </svg>\n `,\n waves: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n <path d=\"M2 12c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n <path d=\"M2 18c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n </svg>\n `,\n send: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n `,\n chat: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n `,\n video: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"23 7 16 12 23 17 23 7\"/>\n <rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"/>\n </svg>\n `,\n talkToAgent: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" opacity=\"0.3\"/>\n <path d=\"M12 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"2\"/>\n </svg>\n `,\n sparkles: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2l2.5 6.5L21 11l-6.5 2.5L12 20l-2.5-6.5L3 11l6.5-2.5L12 2z\"/>\n <path d=\"M18 2l1.5 3.5L23 7l-3.5 1.5L18 12l-1.5-3.5L13 7l3.5-1.5L18 2z\" opacity=\"0.6\"/>\n <path d=\"M6 12l1.5 3.5L11 17l-3.5 1.5L6 22l-1.5-3.5L1 17l3.5-1.5L6 12z\" opacity=\"0.6\"/>\n </svg>\n `,\n audioLines: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 10v3\"/>\n <path d=\"M6 6v11\"/>\n <path d=\"M10 3v18\"/>\n <path d=\"M14 8v7\"/>\n <path d=\"M18 5v13\"/>\n <path d=\"M22 10v3\"/>\n </svg>\n `,\n maximize2: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"15 3 21 3 21 9\"/>\n <polyline points=\"9 21 3 21 3 15\"/>\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/>\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>\n </svg>\n `,\n minimize2: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"4 14 10 14 10 20\"/>\n <polyline points=\"20 10 14 10 14 4\"/>\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\"/>\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>\n </svg>\n `,\n user: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/>\n <circle cx=\"12\" cy=\"7\" r=\"4\"/>\n </svg>\n `,\n keyboard: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" ry=\"2\"/>\n <line x1=\"6\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n <line x1=\"10\" y1=\"8\" x2=\"10\" y2=\"8\"/>\n <line x1=\"14\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"18\" y1=\"8\" x2=\"18\" y2=\"8\"/>\n <line x1=\"6\" y1=\"12\" x2=\"6\" y2=\"12\"/>\n <line x1=\"10\" y1=\"12\" x2=\"10\" y2=\"12\"/>\n <line x1=\"14\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n <line x1=\"18\" y1=\"12\" x2=\"18\" y2=\"12\"/>\n <line x1=\"7\" y1=\"16\" x2=\"17\" y2=\"16\"/>\n </svg>\n `\n};\n\nexport const industryIcons: Record<string, string> = {\n automotive: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"/>\n <circle cx=\"7\" cy=\"17\" r=\"2\"/>\n <path d=\"M9 17h6\"/>\n <circle cx=\"17\" cy=\"17\" r=\"2\"/>\n </svg>\n `,\n education: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 10v6M2 10l10-5 10 5-10 5z\"/>\n <path d=\"M6 12v5c3 3 9 3 12 0v-5\"/>\n </svg>\n `,\n finance: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\"/>\n <line x1=\"6\" y1=\"21\" x2=\"6\" y2=\"12\"/>\n <line x1=\"18\" y1=\"21\" x2=\"18\" y2=\"12\"/>\n <line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/>\n <path d=\"M5 6 L12 2 L19 6\"/>\n <line x1=\"6\" y1=\"6\" x2=\"6\" y2=\"12\"/>\n <line x1=\"18\" y1=\"6\" x2=\"18\" y2=\"12\"/>\n <line x1=\"10\" y1=\"21\" x2=\"10\" y2=\"12\"/>\n <line x1=\"14\" y1=\"21\" x2=\"14\" y2=\"12\"/>\n </svg>\n `,\n fitness: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m6.5 6.5 11 11\"/>\n <path d=\"m21 21-1-1\"/>\n <path d=\"m3 3 1 1\"/>\n <path d=\"m18 22 4-4\"/>\n <path d=\"m2 6 4-4\"/>\n <path d=\"m3 10 7-7\"/>\n <path d=\"m14 21 7-7\"/>\n </svg>\n `,\n food: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2\"/>\n <path d=\"M7 2v20\"/>\n <path d=\"M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7\"/>\n </svg>\n `,\n government: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"/>\n <path d=\"M9 22v-4h6v4\"/>\n <path d=\"M8 6h.01\"/>\n <path d=\"M16 6h.01\"/>\n <path d=\"M12 6h.01\"/>\n <path d=\"M12 10h.01\"/>\n <path d=\"M12 14h.01\"/>\n <path d=\"M16 10h.01\"/>\n <path d=\"M16 14h.01\"/>\n <path d=\"M8 10h.01\"/>\n <path d=\"M8 14h.01\"/>\n </svg>\n `,\n healthcare: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 12h-4l-3 9L9 3l-3 9H2\"/>\n </svg>\n `,\n travel: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 2a5 5 0 0 1 5 5c0 4.5-9 13-9 13S3 11.5 3 7a5 5 0 0 1 10 0Z\"/>\n <circle cx=\"12\" cy=\"7\" r=\"2\"/>\n </svg>\n `,\n legal: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1z\"/>\n <path d=\"m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1z\"/>\n <path d=\"M7 21h10\"/>\n <path d=\"M12 3v18\"/>\n <path d=\"M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2\"/>\n </svg>\n `,\n manufacturing: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7 5V8l-7 5V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\"/>\n <path d=\"M17 18h1\"/>\n <path d=\"M12 18h1\"/>\n <path d=\"M7 18h1\"/>\n </svg>\n `,\n media: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"20\" height=\"20\" x=\"2\" y=\"2\" rx=\"2.18\" ry=\"2.18\"/>\n <line x1=\"7\" x2=\"7\" y1=\"2\" y2=\"22\"/>\n <line x1=\"17\" x2=\"17\" y1=\"2\" y2=\"22\"/>\n <line x1=\"2\" x2=\"22\" y1=\"12\" y2=\"12\"/>\n <line x1=\"2\" x2=\"7\" y1=\"7\" y2=\"7\"/>\n <line x1=\"2\" x2=\"7\" y1=\"17\" y2=\"17\"/>\n <line x1=\"17\" x2=\"22\" y1=\"17\" y2=\"17\"/>\n <line x1=\"17\" x2=\"22\" y1=\"7\" y2=\"7\"/>\n </svg>\n `,\n nonprofit: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\"/>\n </svg>\n `,\n professional: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"7\" rx=\"2\" ry=\"2\"/>\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\"/>\n </svg>\n `,\n realestate: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\n </svg>\n `,\n retail: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/>\n <path d=\"M3 6h18\"/>\n <path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n `,\n technology: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"18\" height=\"12\" x=\"3\" y=\"4\" rx=\"2\" ry=\"2\"/>\n <line x1=\"2\" x2=\"22\" y1=\"20\" y2=\"20\"/>\n </svg>\n `\n};\n\nexport const widgetIcons: Record<string, string> = {\n ...industryIcons,\n default_chat: icons.chat,\n default_voice: icons.mic,\n male: `<img src=\"${MALE_ICON_BASE64}\" style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;\" />`,\n female: `<img src=\"${FEMALE_ICON_BASE64}\" style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;\" />`,\n};\n\nObject.entries(industryIcons).forEach(([name, svg]) => {\n widgetIcons[`male_${name} `] = `\n < div style = \"position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: white; border-radius: 50%;\" >\n <div style=\"width: 60%; height: 60%; color: #6366f1;\" >\n ${svg}\n</div>\n < div style = \"\nposition: absolute;\nbottom: -2px;\nright: -2px;\nwidth: 28px;\nheight: 28px;\nbackground: white;\nborder - radius: 50 %;\nborder: 2px solid white;\nbox - shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\noverflow: hidden;\n\">\n < img src = \"${MALE_ICON_BASE64}\" style = \"width: 100%; height: 100%; object-fit: cover;\" />\n </div>\n </div>\n `;\n\n widgetIcons[`female_${name} `] = `\n < div style = \"position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: white; border-radius: 50%;\" >\n <div style=\"width: 60%; height: 60%; color: #6366f1;\" >\n ${svg}\n</div>\n < div style = \"\nposition: absolute;\nbottom: -2px;\nright: -2px;\nwidth: 28px;\nheight: 28px;\nbackground: white;\nborder - radius: 50 %;\nborder: 2px solid white;\nbox - shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\noverflow: hidden;\n\">\n < img src = \"${FEMALE_ICON_BASE64}\" style = \"width: 100%; height: 100%; object-fit: cover;\" />\n </div>\n </div>\n `;\n});\n\nexport * from './theme';\nexport * from './widget.css';\nexport * from './keyframes';\n","\nimport { icons } from '../styles';\n\nexport class FloatingButton {\n private element: HTMLButtonElement;\n private iconContainer: HTMLElement;\n\n private isDragging = false;\n private startX = 0;\n private startY = 0;\n private currentX = 0;\n private currentY = 0;\n private hasMoved = false;\n\n constructor(\n private onClick: () => void,\n initialIcon: string = icons.chat\n ) {\n this.element = document.createElement('button');\n this.element.className = 'widget-fab';\n \n // Use pointer events for better cross-device support\n this.element.onpointerdown = this.dragStart.bind(this);\n \n this.iconContainer = document.createElement('div');\n this.iconContainer.style.display = 'flex';\n this.iconContainer.style.alignItems = 'center';\n this.iconContainer.style.justifyContent = 'center';\n this.iconContainer.style.width = '100%';\n this.iconContainer.style.height = '100%';\n this.iconContainer.innerHTML = initialIcon;\n\n this.element.appendChild(this.iconContainer);\n }\n\n private dragStart(e: PointerEvent) {\n const rect = this.element.getBoundingClientRect();\n this.isDragging = true;\n this.hasMoved = false;\n this.startX = e.clientX - rect.left;\n this.startY = e.clientY - rect.top;\n \n this.element.setPointerCapture(e.pointerId);\n this.element.style.transition = 'none';\n this.element.style.cursor = 'grabbing';\n\n const onPointerMove = (moveEvent: PointerEvent) => {\n if (!this.isDragging) return;\n \n this.hasMoved = true;\n this.currentX = moveEvent.clientX - this.startX;\n this.currentY = moveEvent.clientY - this.startY;\n\n // Boundary checks\n const maxX = window.innerWidth - this.element.offsetWidth;\n const maxY = window.innerHeight - this.element.offsetHeight;\n \n this.currentX = Math.max(0, Math.min(this.currentX, maxX));\n this.currentY = Math.max(0, Math.min(this.currentY, maxY));\n\n this.element.style.left = `${this.currentX}px`;\n this.element.style.top = `${this.currentY}px`;\n this.element.style.right = 'auto';\n this.element.style.bottom = 'auto';\n };\n\n const onPointerUp = (upEvent: PointerEvent) => {\n this.isDragging = false;\n if (this.element.hasPointerCapture(upEvent.pointerId)) {\n this.element.releasePointerCapture(upEvent.pointerId);\n }\n this.element.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)';\n this.element.style.cursor = 'pointer';\n\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n\n // If it was just a click (no movement), trigger the onClick\n if (!this.hasMoved) {\n this.onClick();\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n }\n\n public getElement(): HTMLButtonElement {\n return this.element;\n }\n\n public setIcon(iconHtml: string) {\n this.iconContainer.innerHTML = iconHtml;\n }\n\n public setPosition(positionStyle: string) {\n // Parse initial position\n const styles = positionStyle.split(';').filter(s => s.trim());\n styles.forEach(s => {\n const [prop, val] = s.split(':').map(str => str.trim());\n if (prop && val) {\n (this.element.style as any)[prop] = val;\n \n // If initializing with right/bottom, convert to left/top for drag consistency later\n // but for now just set them.\n }\n });\n this.element.style.position = 'fixed';\n }\n\n public static get styles() {\n return `\n .widget-fab {\n position: fixed;\n z-index: 9999;\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--shadow);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: fadeInScale 0.4s ease-out;\n touch-action: none;\n padding: 0;\n margin: 0;\n }\n\n .widget-fab:hover {\n transform: scale(1.05);\n box-shadow: var(--shadow-lg);\n }\n\n .widget-fab:active {\n transform: scale(0.95);\n }\n\n .widget-fab svg {\n width: 26px;\n height: 26px;\n color: white;\n }\n `;\n }\n}\n","\nimport { icons } from '../styles';\n\nexport class Panel {\n private element: HTMLDivElement;\n private header: HTMLDivElement;\n private titleElement: HTMLHeadingElement;\n private contentArea: HTMLDivElement;\n private maximizeBtn: HTMLButtonElement;\n private closeBtn: HTMLButtonElement;\n\n private isMaximized = false;\n\n constructor(\n private onClose: () => void,\n private title: string = 'Assistant'\n ) {\n this.element = document.createElement('div');\n this.element.className = 'widget-panel hidden';\n\n // Header\n this.header = document.createElement('div');\n this.header.className = 'widget-header';\n\n this.titleElement = document.createElement('h3');\n this.titleElement.className = 'widget-title';\n this.titleElement.textContent = this.title;\n\n const controls = document.createElement('div');\n controls.style.display = 'flex';\n controls.style.alignItems = 'center';\n controls.style.gap = '8px';\n controls.style.marginLeft = 'auto';\n\n this.maximizeBtn = document.createElement('button');\n this.maximizeBtn.className = 'close-btn maximize-btn';\n this.maximizeBtn.innerHTML = icons.maximize2;\n this.maximizeBtn.onclick = () => this.toggleMaximize();\n\n this.closeBtn = document.createElement('button');\n this.closeBtn.className = 'close-btn';\n this.closeBtn.innerHTML = icons.close;\n this.closeBtn.onclick = this.onClose;\n\n controls.appendChild(this.maximizeBtn);\n controls.appendChild(this.closeBtn);\n\n this.header.appendChild(controls);\n\n // Content Area\n this.contentArea = document.createElement('div');\n this.contentArea.className = 'widget-body';\n this.contentArea.style.flex = '1';\n this.contentArea.style.display = 'flex';\n this.contentArea.style.flexDirection = 'column';\n this.contentArea.style.overflow = 'hidden';\n this.contentArea.style.padding = '0'; // Let children handle padding if needed\n\n this.element.appendChild(this.header);\n this.element.appendChild(this.contentArea);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setContent(content: HTMLElement) {\n this.contentArea.innerHTML = '';\n this.contentArea.appendChild(content);\n }\n\n public addToContent(element: HTMLElement) {\n this.contentArea.appendChild(element);\n }\n\n public setTitle(title: string) {\n this.titleElement.textContent = title;\n }\n\n public open(position: { bottom?: string, right?: string, top?: string, left?: string }) {\n this.element.classList.remove('hidden');\n // Apply positioning logic here or via CSS classes\n // For now, we assume fixed positioning managed by parent styled classes, \n // or we set style directlly.\n Object.assign(this.element.style, position);\n }\n\n public close() {\n this.element.classList.add('hidden');\n }\n\n public toggleMaximize() {\n this.isMaximized = !this.isMaximized;\n if (this.isMaximized) {\n this.element.classList.add('maximized');\n this.maximizeBtn.innerHTML = icons.minimize2;\n } else {\n this.element.classList.remove('maximized');\n this.maximizeBtn.innerHTML = icons.maximize2;\n }\n }\n\n public static get styles() {\n return `\n /* Panel Styles handled in widget.css.ts mostly, specific overrides here */\n `;\n }\n}\n","\nimport { icons } from '../styles';\n\nexport class VoiceOverlay {\n private element: HTMLDivElement;\n\n // Layout\n private contentContainer: HTMLDivElement;\n\n // Orb / visual\n private orbWrapper: HTMLDivElement; // w-52 h-52 centered circle area\n private connectingRing: HTMLDivElement; // spinning conic-gradient ring (connecting)\n private errorRing: HTMLDivElement; // red ring (error)\n private waveLayers: HTMLDivElement[] = []; // active wave layers\n private outerGlow: HTMLDivElement;\n private wave1: HTMLDivElement;\n private wave2: HTMLDivElement;\n private wave3: HTMLDivElement;\n private centerIcon: HTMLDivElement; // dark circle with phone/spinner\n\n // Status area\n private statusArea: HTMLDivElement;\n private connectingLabel: HTMLDivElement;\n private connectedBadge: HTMLDivElement;\n private errorLabel: HTMLDivElement;\n private retryBtn: HTMLButtonElement;\n private timerEl: HTMLDivElement;\n\n // Transcription\n private transcriptionEl: HTMLDivElement;\n\n // Footer\n private hangupBtn: HTMLButtonElement;\n\n // Avatar\n private videoContainer: HTMLDivElement;\n private videoElement: HTMLVideoElement;\n private prepareBadge: HTMLDivElement;\n private statusBadge: HTMLDivElement;\n\n private startTime: number | null = null;\n private timerInterval: any = null;\n private isAvatarMode: boolean = false;\n private callStartedAt: number | null = null; // wall-clock ms when call started\n\n constructor(\n private onHangup: () => void,\n private primaryColor: string = '#6366f1',\n private secondaryColor: string = '#a855f7',\n private onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n // ââ ROOT ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.element = document.createElement('div');\n this.element.id = 'voice-active-overlay';\n this.element.style.cssText = `\n position: absolute; top: 0; left: 0; width: 100%; height: 100%;\n background: #f9fafb;\n pointer-events: auto;\n z-index: 60;\n display: none;\n flex-direction: column;\n align-items: center;\n `;\n\n // ââ CONTENT AREA ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.contentContainer = document.createElement('div');\n this.contentContainer.style.cssText = `\n flex: 1; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n width: 100%; padding: 24px 20px 12px;\n `;\n\n // ââ AVATAR VIDEO âââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.videoContainer = document.createElement('div');\n this.videoContainer.style.cssText = `\n display: none; position: relative; width: 100%; max-width: 260px;\n aspect-ratio: 1/1; margin-bottom: 16px; overflow: hidden;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25), 0 0 0 1px rgba(17,24,39,0.05);\n `;\n this.videoElement = document.createElement('video');\n this.videoElement.style.cssText = 'width:100%; height:100%; object-fit:cover; background:black;';\n this.videoElement.autoplay = true;\n this.videoElement.playsInline = true;\n this.videoElement.muted = true;\n this.videoContainer.appendChild(this.videoElement);\n this.contentContainer.appendChild(this.videoContainer);\n\n // ââ ORB WRAPPER ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.orbWrapper = document.createElement('div');\n this.orbWrapper.style.cssText = `\n position: relative; width: 208px; height: 208px;\n display: flex; align-items: center; justify-content: center;\n margin: 8px 0;\n `;\n\n // Connecting: spinning conic-gradient ring\n this.connectingRing = document.createElement('div');\n this.connectingRing.style.cssText = `\n position: absolute; width: 180px; height: 180px;\n border-radius: 50%;\n background: conic-gradient(from 0deg, #94a3b8, #cbd5e1, #e2e8f0, #94a3b8);\n animation: spin 3s linear infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.connectingRing);\n\n // Error: red conic ring\n this.errorRing = document.createElement('div');\n this.errorRing.style.cssText = `\n position: absolute; width: 180px; height: 180px;\n border-radius: 50%;\n background: conic-gradient(from 0deg, #ef4444, #f87171, #fca5a5, #ef4444);\n animation: pulse 1.5s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.errorRing);\n\n // Wave layers (connected state)\n this.outerGlow = document.createElement('div');\n this.outerGlow.style.cssText = `\n position: absolute; inset: 0; border-radius: 50%;\n background: radial-gradient(circle, ${this.primaryColor}20 0%, transparent 70%);\n animation: pulse 2s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.outerGlow);\n\n this.wave1 = document.createElement('div');\n this.wave1.style.cssText = `\n position: absolute; width: 200px; height: 200px; border-radius: 50%;\n background: conic-gradient(from 0deg, ${this.primaryColor}, ${this.secondaryColor}, #fcd34d, ${this.primaryColor});\n animation: wave-rotate-1 8s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave1);\n\n this.wave2 = document.createElement('div');\n this.wave2.style.cssText = `\n position: absolute; width: 180px; height: 180px; border-radius: 50%;\n background: conic-gradient(from 60deg, ${this.secondaryColor}, #fcd34d, ${this.primaryColor}, ${this.secondaryColor});\n opacity: 0.8;\n animation: wave-rotate-2 6s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave2);\n\n this.wave3 = document.createElement('div');\n this.wave3.style.cssText = `\n position: absolute; width: 160px; height: 160px; border-radius: 50%;\n background: conic-gradient(from 120deg, #fcd34d, ${this.primaryColor}, ${this.secondaryColor}, #fcd34d);\n opacity: 0.9;\n animation: wave-rotate-3 4s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave3);\n\n // Inner shine (connected only)\n const shine = document.createElement('div');\n shine.style.cssText = `\n position: absolute; width: 140px; height: 140px; border-radius: 50%;\n background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4) 0%, transparent 60%);\n display: none; pointer-events: none;\n `;\n shine.id = 'voice-shine';\n this.orbWrapper.appendChild(shine);\n\n this.waveLayers = [this.outerGlow, this.wave1, this.wave2, this.wave3, shine];\n\n // Center dark circle with phone/spinner icon\n this.centerIcon = document.createElement('div');\n this.centerIcon.style.cssText = `\n position: relative; z-index: 10;\n width: 56px; height: 56px; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n background: #374151;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.15), 0 8px 10px -6px rgba(0,0,0,0.1);\n color: white;\n `;\n this.centerIcon.innerHTML = icons.phone;\n const phoneSvg = this.centerIcon.querySelector('svg');\n if (phoneSvg) { phoneSvg.style.width = '20px'; phoneSvg.style.height = '20px'; }\n this.orbWrapper.appendChild(this.centerIcon);\n\n this.contentContainer.appendChild(this.orbWrapper);\n\n // ââ STATUS AREA ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.statusArea = document.createElement('div');\n this.statusArea.style.cssText = 'display:flex; flex-direction:column; align-items:center; gap:8px; margin-top:8px;';\n\n // Connecting label\n this.connectingLabel = document.createElement('p');\n this.connectingLabel.textContent = 'Connecting...';\n this.connectingLabel.style.cssText = 'font-size:11px; font-weight:600; color:#9ca3af; text-transform:uppercase; letter-spacing:0.1em; margin:0; display:none;';\n this.statusArea.appendChild(this.connectingLabel);\n\n // Connected badge\n this.connectedBadge = document.createElement('div');\n this.connectedBadge.style.cssText = `\n display: none; align-items: center; gap: 8px;\n padding: 5px 16px; background: #f0fdf4;\n border-radius: 9999px; border: 1px solid #dcfce7;\n `;\n const greenDot = document.createElement('div');\n greenDot.style.cssText = 'width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite; box-shadow:0 0 8px rgba(34,197,94,0.6);';\n const connectedText = document.createElement('span');\n connectedText.textContent = 'Connected';\n connectedText.style.cssText = 'font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;';\n this.connectedBadge.appendChild(greenDot);\n this.connectedBadge.appendChild(connectedText);\n this.statusArea.appendChild(this.connectedBadge);\n\n // Timer\n this.timerEl = document.createElement('div');\n this.timerEl.textContent = '00:00';\n this.timerEl.style.cssText = 'font-size:13px; color:#6b7280; font-variant-numeric:tabular-nums; display:none;';\n this.statusArea.appendChild(this.timerEl);\n\n // Error label + retry\n this.errorLabel = document.createElement('p');\n this.errorLabel.textContent = 'Connection failed';\n this.errorLabel.style.cssText = 'font-size:12px; color:#ef4444; font-weight:500; margin:0; display:none;';\n this.statusArea.appendChild(this.errorLabel);\n\n this.retryBtn = document.createElement('button');\n this.retryBtn.textContent = 'âģ Retry Connection';\n this.retryBtn.style.cssText = `\n display:none; padding:6px 14px; background:#f3f4f6; border:none;\n border-radius:9999px; font-size:12px; font-weight:500; color:#374151;\n cursor:pointer; transition:background 0.2s; pointer-events:auto;\n `;\n this.retryBtn.onmouseover = () => this.retryBtn.style.background = '#e5e7eb';\n this.retryBtn.onmouseout = () => this.retryBtn.style.background = '#f3f4f6';\n this.statusArea.appendChild(this.retryBtn);\n\n // Avatar preparing / connected badges\n this.prepareBadge = document.createElement('p');\n this.prepareBadge.style.cssText = 'display:none; font-size:11px; font-weight:600; color:#a855f7; text-transform:uppercase; letter-spacing:0.1em; margin:0; animation:pulse 1.5s infinite;';\n this.statusArea.appendChild(this.prepareBadge);\n\n this.statusBadge = document.createElement('div');\n this.statusBadge.style.cssText = 'display:none; align-items:center; gap:8px; padding:5px 16px; background:#f0fdf4; border-radius:9999px; border:1px solid #dcfce7;';\n const sDot = document.createElement('div');\n sDot.style.cssText = 'width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite;';\n const sTxt = document.createElement('span');\n sTxt.textContent = 'Connected';\n sTxt.style.cssText = 'font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;';\n this.statusBadge.appendChild(sDot);\n this.statusBadge.appendChild(sTxt);\n this.statusArea.appendChild(this.statusBadge);\n\n this.contentContainer.appendChild(this.statusArea);\n\n // ââ TRANSCRIPTION ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.transcriptionEl = document.createElement('div');\n this.transcriptionEl.style.cssText = `\n margin-top: 14px; padding: 0 20px; text-align: center;\n min-height: 36px; max-height: 72px; overflow-y: auto;\n font-size: 13px; color: #9ca3af; font-style: italic;\n `;\n this.contentContainer.appendChild(this.transcriptionEl);\n\n this.element.appendChild(this.contentContainer);\n\n // ââ FOOTER: always-on End Call âââââââââââââââââââââââââââââââââââââââââââ\n const footer = document.createElement('div');\n footer.style.cssText = 'width:100%; display:flex; justify-content:center; padding:0 20px 20px; pointer-events:auto;';\n\n this.hangupBtn = document.createElement('button');\n this.hangupBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"transform:rotate(135deg);flex-shrink:0;\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.18h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.77a16 16 0 0 0 6.29 6.29l.87-.87a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z\"/></svg> End Call`;\n this.hangupBtn.style.cssText = `\n display: flex; align-items: center; gap: 8px;\n padding: 10px 28px; background: #ef4444; color: white;\n border: none; border-radius: 9999px; font-size: 14px; font-weight: 500;\n cursor: pointer; pointer-events: auto;\n transition: background-color 0.2s;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);\n `;\n this.hangupBtn.onmouseover = () => this.hangupBtn.style.backgroundColor = '#dc2626';\n this.hangupBtn.onmouseout = () => this.hangupBtn.style.backgroundColor = '#ef4444';\n this.hangupBtn.onclick = () => {\n const duration = this.callStartedAt ? Date.now() - this.callStartedAt : 0;\n const startedAt = this.callStartedAt ?? Date.now();\n if (this.onCallEnded && duration > 0) {\n this.onCallEnded(duration, startedAt);\n }\n this.onHangup();\n };\n\n footer.appendChild(this.hangupBtn);\n this.element.appendChild(footer);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setMode(mode: 'voice' | 'avatar') {\n this.isAvatarMode = (mode === 'avatar');\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.isAvatarMode = true;\n if (track.kind === 'video' && this.videoElement) {\n const stream = new MediaStream([track]);\n this.videoElement.srcObject = stream;\n this.videoContainer.style.display = 'block';\n this.orbWrapper.style.display = 'none';\n this.connectingLabel.style.display = 'none';\n this.timerEl.style.display = 'none';\n\n this.videoElement.onplaying = () => {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n };\n this.videoElement.play().catch(e => console.warn('Video play error', e));\n }\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n if (status === 'connecting') {\n // CENTER ICON: spinner while connecting\n this.centerIcon.style.background = '#4b5563';\n this.centerIcon.innerHTML = `<div style=\"width:18px;height:18px;border:2px solid #ffffff;border-top-color:transparent;border-radius:50%;animation:spin 1s linear infinite;\"></div>`;\n\n if (this.isAvatarMode) {\n this.videoContainer.style.display = 'block';\n this.orbWrapper.style.display = 'none';\n this.prepareBadge.textContent = 'CONNECTING...';\n this.prepareBadge.style.display = 'block';\n this.statusBadge.style.display = 'none';\n this.connectingLabel.style.display = 'none';\n } else {\n this.orbWrapper.style.display = 'flex';\n this.videoContainer.style.display = 'none';\n this.connectingRing.style.display = 'block';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'block';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n }\n this.stopTimer();\n\n } else if (status === 'connected') {\n // CENTER ICON: phone\n this.centerIcon.style.background = '#1f2937';\n this.centerIcon.innerHTML = icons.phone;\n const svg = this.centerIcon.querySelector('svg');\n if (svg) { svg.style.cssText = 'width:20px;height:20px;'; }\n\n if (this.isAvatarMode) {\n const isPlaying = this.videoElement && !this.videoElement.paused && this.videoElement.readyState > 2;\n if (isPlaying) {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n } else {\n this.prepareBadge.textContent = 'AGENT IS ON THE WAY...';\n this.prepareBadge.style.display = 'block';\n setTimeout(() => {\n if (this.prepareBadge.style.display !== 'none') {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n }\n }, 5000);\n }\n } else {\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'flex');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'flex';\n this.timerEl.style.display = 'block';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n this.startTimer();\n }\n\n } else if (status === 'error') {\n this.centerIcon.style.background = '#dc2626';\n this.centerIcon.innerHTML = icons.phone;\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'block';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'block';\n this.retryBtn.style.display = 'block';\n this.stopTimer();\n }\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.transcriptionEl.textContent = `\"${text}\"`;\n this.transcriptionEl.style.color = isFinal ? '#1f2937' : '#9ca3af';\n this.transcriptionEl.style.fontStyle = isFinal ? 'normal' : 'italic';\n }\n\n public show() {\n this.callStartedAt = Date.now();\n this.element.style.display = 'flex';\n this.setStatus('connecting');\n }\n\n public hide() {\n this.element.style.display = 'none';\n this.reset();\n }\n\n public reset() {\n if (this.videoElement) this.videoElement.srcObject = null;\n this.isAvatarMode = false;\n this.callStartedAt = null;\n this.stopTimer();\n this.transcriptionEl.textContent = '';\n\n // Reset to defaults\n this.videoContainer.style.display = 'none';\n this.orbWrapper.style.display = 'flex';\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'none';\n this.centerIcon.style.background = '#374151';\n this.centerIcon.innerHTML = icons.phone;\n const svg = this.centerIcon.querySelector('svg');\n if (svg) { svg.style.cssText = 'width:20px;height:20px;'; }\n }\n\n private startTimer() {\n if (this.timerInterval) clearInterval(this.timerInterval);\n this.startTime = Date.now();\n this.timerEl.textContent = '00:00';\n this.timerInterval = setInterval(() => {\n if (!this.startTime) return;\n const diff = Math.floor((Date.now() - this.startTime) / 1000);\n const mins = Math.floor(diff / 60).toString().padStart(2, '0');\n const secs = (diff % 60).toString().padStart(2, '0');\n this.timerEl.textContent = `${mins}:${secs}`;\n }, 1000);\n }\n\n private stopTimer() {\n if (this.timerInterval) { clearInterval(this.timerInterval); this.timerInterval = null; }\n this.timerEl.textContent = '';\n }\n\n public setFullScreen(enable: boolean) {\n if (enable) {\n this.videoContainer.style.position = 'absolute';\n this.videoContainer.style.top = '0';\n this.videoContainer.style.left = '0';\n this.videoContainer.style.width = '100%';\n this.videoContainer.style.height = '100%';\n this.videoContainer.style.maxWidth = 'none';\n this.videoContainer.style.borderRadius = '0';\n this.videoContainer.style.margin = '0';\n this.videoContainer.style.zIndex = '0';\n } else {\n this.videoContainer.style.position = 'relative';\n this.videoContainer.style.width = '100%';\n this.videoContainer.style.maxWidth = '260px';\n this.videoContainer.style.height = 'auto';\n this.videoContainer.style.aspectRatio = '1/1';\n this.videoContainer.style.borderRadius = '16px';\n this.videoContainer.style.marginBottom = '16px';\n }\n }\n}\n","\nimport { icons } from '../styles';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport class ChatWindow {\n private element: HTMLDivElement;\n private messageContainer: HTMLDivElement;\n private inputArea: HTMLDivElement;\n private input: HTMLInputElement;\n private sendBtn: HTMLButtonElement;\n private typingIndicator: HTMLDivElement | null = null;\n\n constructor(\n private onSend: (message: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n this.element.style.flex = '1';\n this.element.style.overflow = 'hidden';\n this.element.style.minHeight = '0'; // Crucial for nested flex scrolling\n\n // Messages Area\n this.messageContainer = document.createElement('div');\n this.messageContainer.className = 'chat-messages';\n\n // Input Area\n this.inputArea = document.createElement('div');\n this.inputArea.className = 'chat-input-area';\n\n this.input = document.createElement('input');\n this.input.className = 'chat-input';\n this.input.placeholder = 'Type a message...';\n this.input.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') this.handleSend();\n });\n\n this.sendBtn = document.createElement('button');\n this.sendBtn.className = 'chat-send-btn';\n this.sendBtn.innerHTML = icons.send;\n this.sendBtn.onclick = () => this.handleSend();\n\n this.inputArea.appendChild(this.input);\n this.inputArea.appendChild(this.sendBtn);\n\n // Branding Area\n const brandingArea = document.createElement('div');\n brandingArea.className = 'branding-footer';\n brandingArea.innerHTML = `Technology Powered by <b>Vanira AI</b>`;\n\n this.element.appendChild(this.messageContainer);\n this.element.appendChild(this.inputArea);\n this.element.appendChild(brandingArea);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n private formatTime(date: Date = new Date()): string {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n\n public addMessage(role: 'user' | 'assistant', content: string, timestamp?: number) {\n const wrapper = document.createElement('div');\n wrapper.style.cssText = `\n display: flex;\n flex-direction: column;\n align-items: ${role === 'user' ? 'flex-end' : 'flex-start'};\n margin-bottom: 2px;\n `;\n\n const msgDiv = document.createElement('div');\n msgDiv.className = `chat-message ${role}`;\n msgDiv.textContent = content;\n wrapper.appendChild(msgDiv);\n\n const ts = document.createElement('span');\n ts.style.cssText = `\n font-size: 10px;\n color: #9ca3af;\n margin: 2px 4px 6px;\n display: block;\n `;\n ts.textContent = this.formatTime(timestamp ? new Date(timestamp) : undefined);\n wrapper.appendChild(ts);\n\n this.messageContainer.appendChild(wrapper);\n this.scrollToBottom();\n }\n\n public updateLastAssistantMessage(content: string) {\n // The last child is the wrapper div; the message is its first child\n const lastWrapper = this.messageContainer.lastElementChild as HTMLElement;\n if (lastWrapper) {\n const lastMsg = lastWrapper.querySelector('.chat-message.assistant') as HTMLElement;\n if (lastMsg) {\n lastMsg.textContent = content;\n this.scrollToBottom();\n return;\n }\n }\n this.addMessage('assistant', content);\n }\n\n public addButtons(buttons: Array<{ title: string; payload: string }>) {\n const buttonsContainer = document.createElement('div');\n buttonsContainer.className = 'chat-buttons-container';\n buttonsContainer.style.display = 'flex';\n buttonsContainer.style.flexWrap = 'wrap';\n buttonsContainer.style.gap = '8px';\n buttonsContainer.style.marginTop = '8px';\n buttonsContainer.style.marginBottom = '12px';\n buttonsContainer.style.justifyContent = 'flex-start';\n\n buttons.forEach(btn => {\n const buttonEl = document.createElement('button');\n buttonEl.className = 'chat-suggestion-chip';\n buttonEl.textContent = btn.title;\n // Basic styles if CSS class not defined\n buttonEl.style.padding = '6px 12px';\n buttonEl.style.borderRadius = '16px';\n buttonEl.style.border = '1px solid #e5e7eb';\n buttonEl.style.backgroundColor = 'white';\n buttonEl.style.fontSize = '12px';\n buttonEl.style.color = '#4b5563';\n buttonEl.style.cursor = 'pointer';\n buttonEl.style.transition = 'all 0.2s';\n\n buttonEl.onmouseenter = () => {\n buttonEl.style.backgroundColor = '#f3f4f6';\n buttonEl.style.borderColor = '#d1d5db';\n };\n buttonEl.onmouseleave = () => {\n buttonEl.style.backgroundColor = 'white';\n buttonEl.style.borderColor = '#e5e7eb';\n };\n\n buttonEl.onclick = () => {\n this.handleSend(btn.payload);\n };\n\n buttonsContainer.appendChild(buttonEl);\n });\n\n // Append to the last message if probable? Or just append.\n // Usually buttons belong to the last assistant message.\n // For simplicity, append to container.\n this.messageContainer.appendChild(buttonsContainer);\n this.scrollToBottom();\n }\n\n private handleSend(overrideText?: string) {\n const text = overrideText || this.input.value.trim();\n if (!text) return;\n\n this.onSend(text);\n if (!overrideText) {\n this.input.value = '';\n }\n }\n\n public setTyping(isTyping: boolean) {\n if (this.typingIndicator) {\n this.typingIndicator.remove();\n this.typingIndicator = null;\n }\n\n if (isTyping) {\n this.typingIndicator = document.createElement('div');\n this.typingIndicator.className = 'typing-indicator';\n\n // 3 dots\n for (let i = 0; i < 3; i++) {\n const dot = document.createElement('div');\n dot.className = 'typing-dot';\n this.typingIndicator.appendChild(dot);\n }\n\n this.messageContainer.appendChild(this.typingIndicator);\n this.scrollToBottom();\n }\n }\n\n /**\n * Inject a \"Voice call ended\" card into the message list.\n * @param durationMs call duration in milliseconds\n * @param timestamp unix ms when the call started (for ordering across restore)\n */\n public addCallRecord(durationMs: number, timestamp: number = Date.now()) {\n const mins = Math.floor(durationMs / 60000);\n const secs = Math.floor((durationMs % 60000) / 1000);\n const label = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n\n const card = document.createElement('div');\n card.dataset.callTimestamp = String(timestamp);\n card.style.cssText = `\n display: flex; justify-content: center;\n margin: 10px 16px;\n `;\n\n card.innerHTML = `\n <div style=\"\n display: flex; align-items: center; gap: 8px;\n background: #f3f4f6; border: 1px solid #e5e7eb;\n border-radius: 12px; padding: 8px 14px;\n font-size: 12px; color: #6b7280;\n max-width: 210px; width: fit-content;\n \">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#9ca3af\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"9\" width=\"4\" height=\"12\" rx=\"2\"/>\n <rect x=\"9\" y=\"5\" width=\"4\" height=\"16\" rx=\"2\"/>\n <rect x=\"16\" y=\"2\" width=\"4\" height=\"20\" rx=\"2\"/>\n </svg>\n <span>\n <span style=\"font-weight:500; color:#374151;\">Voice call ended</span>\n <span style=\"margin-left:6px; color:#9ca3af;\">¡</span>\n <span style=\"margin-left:6px;\">${label}</span>\n </span>\n </div>\n `;\n\n this.messageContainer.appendChild(card);\n this.scrollToBottom();\n }\n\n public clearMessages() {\n this.messageContainer.innerHTML = '';\n }\n\n\n private scrollToBottom() {\n this.messageContainer.scrollTop = this.messageContainer.scrollHeight;\n }\n}\n","\nexport class AvatarView {\n private element: HTMLDivElement;\n private videoElement: HTMLVideoElement;\n private placeholderContainer: HTMLDivElement;\n\n constructor(avatarUrl?: string | null) {\n this.element = document.createElement('div');\n this.element.className = 'avatar-container';\n this.element.style.position = 'relative';\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n this.element.style.background = '#ffffff'; // White card background\n this.element.style.borderRadius = '16px';\n this.element.style.overflow = 'hidden';\n\n // 1. Placeholder Container (Centered Circle)\n this.placeholderContainer = document.createElement('div');\n this.placeholderContainer.style.width = '100%';\n this.placeholderContainer.style.height = '100%';\n this.placeholderContainer.style.display = 'flex';\n this.placeholderContainer.style.alignItems = 'center';\n this.placeholderContainer.style.justifyContent = 'center';\n\n // Determine Avatar Source\n // Use provided URL or fallback to default video\n const sourceUrl = avatarUrl || \"https://www.simli.com/jenna.mp4\";\n const isVideo = sourceUrl.endsWith('.mp4') || sourceUrl.endsWith('.webm');\n\n let mediaElement: HTMLElement;\n\n if (isVideo) {\n const vid = document.createElement('video');\n vid.src = sourceUrl;\n vid.muted = true;\n vid.loop = true;\n vid.autoplay = true;\n vid.playsInline = true;\n mediaElement = vid;\n } else {\n const img = document.createElement('img');\n img.src = sourceUrl;\n mediaElement = img;\n }\n\n // Apply Circle Styles\n mediaElement.style.width = '140px';\n mediaElement.style.height = '140px';\n mediaElement.style.borderRadius = '50%';\n mediaElement.style.objectFit = 'cover';\n mediaElement.style.backgroundColor = '#f3f4f6';\n\n this.placeholderContainer.appendChild(mediaElement);\n this.element.appendChild(this.placeholderContainer);\n\n // 2. Video Element\n this.videoElement = document.createElement('video');\n this.videoElement.className = 'avatar-video';\n this.videoElement.autoplay = true;\n this.videoElement.playsInline = true;\n this.videoElement.muted = true; // Often required for autoplay\n this.videoElement.style.display = 'none';\n\n this.element.appendChild(this.videoElement);\n\n // Initial State - NO DEFAULT ICON per user request\n // this.setPlaceholder(this.currentGender as any);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setStream(stream: MediaStream) {\n this.videoElement.srcObject = stream;\n this.videoElement.style.display = 'block';\n this.placeholderContainer.style.display = 'none';\n }\n\n\n}\n","import { icons } from '../styles';\n\nexport class VoiceOrb {\n private element: HTMLDivElement;\n\n constructor(private onClick: () => void) {\n this.element = document.createElement('div');\n this.element.className = 'voice-mode-container';\n\n this.element.innerHTML = `\n <div class=\"central-orb-container\">\n <div class=\"central-orb idle\">\n ${icons.audioLines}\n </div>\n <div class=\"central-orb-glow\"></div>\n </div>\n <div class=\"voice-status-text\">Tap to speak</div>\n <div class=\"voice-status-subtext\">Start a conversation</div>\n `;\n\n const orbContainer = this.element.querySelector('.central-orb-container') as HTMLElement;\n if (orbContainer) {\n orbContainer.onclick = this.onClick;\n }\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n}\n","\nexport interface WelcomeChip {\n title: string;\n payload?: string;\n}\n\nexport class FloatingWelcomeChips {\n private element: HTMLElement;\n private chips: WelcomeChip[] = [];\n\n constructor(\n private onChipClick: (text: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.className = 'welcome-chips-container';\n }\n\n public setChips(chips: WelcomeChip[]) {\n this.chips = chips;\n this.render();\n }\n\n public getElement(): HTMLElement {\n return this.element;\n }\n\n public setPosition(positionStyle: string) {\n // Parse positionStyle (e.g., \"bottom: 24px; right: 24px;\")\n // We want to be slightly ABOVE the launcher.\n // Launcher is usually 64px + 24px = ~88px from bottom.\n // If bottom-right, we want right: 24px, bottom: 100px.\n\n // Simple parsing/replacement for now.\n // Assuming positionStyle is exactly what VaniraInternalProvider returns.\n\n // Remove standard bottom/top/left/right and adjust.\n // Actually, easier to just pass the raw style and let the provider adjust, \n // OR adjust here.\n\n // Let's set the base style, but we need to offset it.\n // If \"bottom: 24px\", make it \"bottom: 100px\".\n\n let style = positionStyle;\n if (style.includes('bottom:')) {\n style = style.replace(/bottom:\\s*[\\d]+px/, 'bottom: 100px');\n } else if (style.includes('top:')) {\n style = style.replace(/top:\\s*[\\d]+px/, 'top: 100px');\n }\n\n this.element.setAttribute('style', style);\n }\n\n private render() {\n this.element.innerHTML = '';\n\n this.chips.forEach((chip, index) => {\n const btn = document.createElement('button');\n btn.className = 'welcome-chip-btn';\n btn.textContent = chip.title;\n btn.onclick = (e) => {\n e.stopPropagation();\n this.onChipClick(chip.title); // Send title as text\n };\n // Add staggered delay\n btn.style.animationDelay = `${index * 0.1}s`;\n this.element.appendChild(btn);\n });\n }\n\n public static get styles() {\n return `\n .welcome-chips-container {\n position: fixed;\n z-index: 9998;\n display: flex;\n flex-direction: column; /* Stack vertically */\n align-items: flex-end; /* Align to right (usually) */\n gap: 12px;\n pointer-events: none; /* Container passes clicks */\n /* Max width to prevent huge buttons */\n max-width: 300px;\n }\n\n /* Adjust alignment based on position */\n /* We might need to know if it's left or right to align flex-start or flex-end \n For now, defaulting to flex-end (right) which matches most widgets.\n TODO: Pass alignment if needed.\n */\n\n .welcome-chip-btn {\n background: white;\n color: #4f46e5; /* Secondary/Primary color - hardcoded or use var */\n color: var(--primary);\n border: 1px solid transparent;\n padding: 10px 18px;\n border-radius: 20px;\n font-family: inherit;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);\n pointer-events: auto;\n opacity: 0;\n margin-bottom: 4px; /* Tiny spacing */\n \n /* Animation */\n animation: slideUpFade 0.4s ease-out forwards;\n }\n\n .welcome-chip-btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);\n background: #f8fafc;\n }\n\n @keyframes slideUpFade {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n `;\n }\n}\n","import { VoiceOverlay } from '../components';\n\nexport abstract class AbstractVoiceView {\n protected element: HTMLDivElement;\n protected overlay!: VoiceOverlay;\n protected onStartCall: () => void;\n protected onHangup: () => void;\n protected primaryColor: string;\n protected secondaryColor: string;\n protected onCallEnded?: (durationMs: number, startedAt: number) => void;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n this.onStartCall = onStartCall;\n this.onHangup = onHangup;\n this.primaryColor = primaryColor;\n this.secondaryColor = secondaryColor;\n this.onCallEnded = onCallEnded;\n this.element = document.createElement('div');\n this.element.style.height = '100%';\n this.element.style.position = 'relative';\n\n // Child classes implement specific init\n // BUT calling initOverlay here is common\n }\n\n protected initOverlay() {\n this.overlay = new VoiceOverlay(() => this.onHangup(), this.primaryColor, this.secondaryColor, this.onCallEnded);\n this.element.appendChild(this.overlay.getElement());\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setCallActive(active: boolean) {\n if (active) this.overlay.show();\n else this.overlay.hide();\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n this.overlay.setStatus(status);\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.overlay.setTranscription(text, isFinal);\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.overlay.setVideoTrack(track);\n }\n}\n","import { VoiceOrb } from '../components';\nimport { AbstractVoiceView } from './AbstractVoiceView';\n\nexport class VoiceOnlyView extends AbstractVoiceView {\n private voiceOrb: VoiceOrb;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n\n this.element.style.background = '#f9fafb';\n\n this.voiceOrb = new VoiceOrb(() => this.onStartCall());\n this.element.appendChild(this.voiceOrb.getElement());\n\n this.initOverlay();\n }\n}\n","import { ChatWindow } from '../components';\n\nexport class ChatOnlyView {\n private element: HTMLDivElement;\n private chatWindow: ChatWindow;\n\n constructor(\n private onSendMessage: (msg: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.flex = '1';\n this.element.style.width = '100%';\n this.element.style.minHeight = '0'; // Crucial for flex scrolling\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n\n this.chatWindow = new ChatWindow((msg) => this.onSendMessage(msg));\n this.element.appendChild(this.chatWindow.getElement());\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public getChatWindow(): ChatWindow {\n return this.chatWindow;\n }\n}\n","import { ChatWindow, VoiceOverlay } from '../components';\nimport { icons } from '../styles';\n\nexport abstract class AbstractChatView {\n protected element: HTMLDivElement;\n protected chatWindow!: ChatWindow;\n protected overlay!: VoiceOverlay;\n protected voiceTrigger!: HTMLButtonElement;\n\n constructor(\n protected onSendMessage: (msg: string) => void,\n protected onStartCall: () => void,\n protected onHangup: () => void,\n protected primaryColor: string = '#6366f1',\n protected secondaryColor: string = '#a855f7',\n protected onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.flex = '1'; // Fill parent (widget-body)\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n this.element.style.minHeight = '0'; // Crucial for flex scrolling\n this.element.style.position = 'relative'; // Added from VoiceView\n\n // Child classes will append specific elements (Avatar, etc)\n // Then call setupChat()\n }\n\n protected setupChat() {\n this.chatWindow = new ChatWindow((msg) => this.onSendMessage(msg));\n const chatEl = this.chatWindow.getElement();\n chatEl.style.flex = '1';\n this.element.appendChild(chatEl);\n\n this.injectVoiceTrigger();\n\n this.overlay = new VoiceOverlay(() => this.onHangup(), this.primaryColor, this.secondaryColor, this.onCallEnded);\n this.element.appendChild(this.overlay.getElement());\n }\n\n protected injectVoiceTrigger() {\n const triggerBtn = document.createElement('button');\n this.voiceTrigger = triggerBtn;\n triggerBtn.className = 'voice-btn-simple';\n triggerBtn.innerHTML = `<div class=\"voice-btn-icon\">${icons.audioLines}</div>`;\n triggerBtn.onclick = () => this.onStartCall();\n\n // Synchronous injection since ChatWindow is already constructed\n const inputArea = this.chatWindow.getElement().querySelector('.chat-input-area');\n\n if (inputArea) {\n inputArea.insertBefore(this.voiceTrigger, inputArea.firstChild);\n } else {\n console.warn('VaniraSDK: Failed to inject voice trigger', { inputArea });\n }\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public getChatWindow(): ChatWindow {\n return this.chatWindow;\n }\n\n public setCallActive(active: boolean) {\n if (active) {\n this.overlay.show();\n // User Request: Hide Chat Welcome & Chat Box during interaction\n if (this.chatWindow) {\n this.chatWindow.getElement().style.display = 'none';\n }\n } else {\n this.overlay.hide();\n // Restore functionality on hangup\n if (this.chatWindow) {\n this.chatWindow.getElement().style.display = 'flex';\n }\n }\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n this.overlay.setStatus(status);\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.overlay.setTranscription(text, isFinal);\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.overlay.setVideoTrack(track);\n }\n}\n","import { AbstractChatView } from './AbstractChatView';\n\nexport class ChatVoiceView extends AbstractChatView {\n constructor(\n onSendMessage: (msg: string) => void,\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onSendMessage, onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n this.setupChat();\n }\n}\n","import { AvatarView } from '../components';\nimport { icons } from '../styles';\nimport { AbstractVoiceView } from './AbstractVoiceView';\n\nexport class AvatarOnlyView extends AbstractVoiceView {\n private avatarView: AvatarView;\n private startCallBtn: HTMLButtonElement;\n private controlsContainer: HTMLDivElement;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n\n // Ensure flex layout\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n\n // 1. Avatar View (Idle State matching Overlay Card)\n this.avatarView = new AvatarView();\n const avatarEl = this.avatarView.getElement();\n // Match VoiceOverlay VideoContainer styles\n avatarEl.style.width = '100%';\n avatarEl.style.maxWidth = '300px';\n avatarEl.style.aspectRatio = '1/1';\n avatarEl.style.borderRadius = '16px';\n avatarEl.style.overflow = 'hidden';\n avatarEl.style.margin = 'auto'; // Center vertically and horizontally\n avatarEl.style.position = 'relative'; // Ensure proper stacking\n\n this.element.appendChild(avatarEl);\n\n // 2. Start Call Controls\n this.controlsContainer = document.createElement('div');\n this.controlsContainer.className = 'widget-body';\n this.controlsContainer.style.position = 'absolute';\n this.controlsContainer.style.bottom = '20px';\n this.controlsContainer.style.width = '100%';\n this.controlsContainer.style.zIndex = '10';\n\n const controls = document.createElement('div');\n controls.className = 'controls';\n\n this.startCallBtn = document.createElement('button');\n this.startCallBtn.className = 'control-btn primary';\n this.startCallBtn.innerHTML = `${icons.phone} <span>Start Call</span>`;\n this.startCallBtn.onclick = () => this.onStartCall();\n\n controls.appendChild(this.startCallBtn);\n this.controlsContainer.appendChild(controls);\n this.element.appendChild(this.controlsContainer);\n\n // 3. Overlay\n this.initOverlay();\n this.overlay.setMode('avatar');\n // REVERTED Full Screen: this.overlay.setFullScreen(true);\n }\n\n public getAvatarView(): AvatarView {\n return this.avatarView;\n }\n\n public override setCallActive(active: boolean) {\n if (active) {\n this.overlay.setMode('avatar');\n }\n super.setCallActive(active);\n if (active) {\n this.controlsContainer.style.display = 'none';\n } else {\n this.controlsContainer.style.display = 'block';\n }\n }\n}\n","import { AbstractChatView } from './AbstractChatView';\nimport { icons } from '../styles';\n\nexport class ChatAvatarView extends AbstractChatView {\n\n constructor(\n onSendMessage: (msg: string) => void,\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onSendMessage, onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n // No top AvatarView anymore! Just standard chat setup.\n this.setupChat();\n this.overlay.setMode('avatar');\n }\n\n // Override to inject the unique Circular Video Button\n protected override injectVoiceTrigger() {\n const triggerBtn = document.createElement('button');\n this.voiceTrigger = triggerBtn;\n triggerBtn.className = 'voice-btn-simple';\n // Custom styling for Avatar Mode\n triggerBtn.style.overflow = 'hidden'; // Clip video\n triggerBtn.style.padding = '0';\n triggerBtn.style.border = '1.5px solid #e5e7eb'; // Clean border\n\n // Video Loop (Simli Jenna or equiv)\n triggerBtn.innerHTML = `\n <video \n src=\"https://www.simli.com/jenna.mp4\" \n autoplay loop muted pip=\"false\" playsinline \n style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%;\">\n </video>\n <div style=\"position: absolute; bottom: -2px; right: -2px; background: white; border-radius: 50%; padding: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.1);\">\n ${icons.audioLines.replace('width=\"24\"', 'width=\"12\"').replace('height=\"24\"', 'height=\"12\"')}\n </div>\n `;\n\n // Ensure small icon style if replacement didn't work (regex safely)\n const iconDiv = triggerBtn.querySelector('div');\n if (iconDiv) {\n const svg = iconDiv.querySelector('svg');\n if (svg) {\n svg.style.width = '12px';\n svg.style.height = '12px';\n }\n }\n\n triggerBtn.onclick = () => this.onStartCall();\n\n // Synchronous injection\n const inputArea = this.chatWindow.getElement().querySelector('.chat-input-area');\n const sendBtn = inputArea?.querySelector('.chat-send-btn');\n\n if (inputArea && sendBtn) {\n inputArea.insertBefore(this.voiceTrigger, sendBtn);\n } else {\n console.warn('VaniraSDK: Failed to inject voice trigger', { inputArea, sendBtn });\n }\n }\n\n // No getAvatarView method anymore. VaniraInternalProvider should check for capability or cast.\n}\n","import { IChatAdapter } from '../abstraction/interfaces';\nimport { ChatService } from '../../api/services/ChatService';\n\nexport class VaniraChatAdapter implements IChatAdapter {\n async sendMessage(\n text: string,\n agentId: string,\n prospectId: string,\n chatId: string | null,\n onResponse: (response: any) => void,\n onStream?: (text: string) => void,\n onChatIdUpdate?: (newId: string) => void,\n widgetId?: string\n ): Promise<void> {\n return ChatService.sendChatMessage(\n agentId,\n prospectId,\n text,\n chatId,\n (stream) => {\n if (onStream) onStream(stream);\n },\n onResponse,\n (newId) => {\n if (onChatIdUpdate && newId) onChatIdUpdate(newId);\n },\n widgetId\n );\n }\n\n async sendFile(file: File): Promise<void> {\n console.warn(\"sendFile not implemented for VaniraChatAdapter yet - Incompatible function adapted\", file);\n throw new Error(\"Method not implemented.\");\n }\n\n async likeDislike(messageId: string, action: 'like' | 'dislike'): Promise<void> {\n console.warn(\"likeDislike not implemented for VaniraChatAdapter yet - Incompatible function adapted\", messageId, action);\n // Implement API call here when available\n }\n}\n","import { ChatService } from '../../api/services/ChatService';\nimport { AbstractWidgetProvider } from '../abstraction/AbstractWidgetProvider';\nimport { VaniraAI } from '../../core/VaniraAI';\nimport { SessionManager } from '../../core/SessionManager';\nimport { WidgetMode } from '../../types';\nimport { generateThemeVars, widgetIcons, icons } from '../styles';\nimport { widgetStyles as baseCss } from '../styles/widget.css';\nimport { FloatingButton, Panel, FloatingWelcomeChips, WelcomeChip } from '../components';\nimport { VoiceOnlyView, ChatOnlyView, ChatVoiceView, AvatarOnlyView, ChatAvatarView } from '../views';\nimport { VaniraChatAdapter } from '../adapters/VaniraChatAdapter';\n\nexport class VaniraInternalProvider extends AbstractWidgetProvider {\n private vaniraClient: VaniraAI | null = null;\n private currentView: any = null;\n private isPanelOpen: boolean = false;\n private callActive: boolean = false;\n private eventSource: { close: () => void } | null = null;\n\n // Components\n private floatingButton: FloatingButton | null = null;\n private floatingWelcomeChips: FloatingWelcomeChips | null = null;\n private panel: Panel | null = null;\n private welcomeChipsData: WelcomeChip[] = [];\n\n // Chat Adapter\n private chatAdapter: VaniraChatAdapter;\n\n // âââ Session Manager âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n private sessionManager: SessionManager | null = null;\n /** Whether this tab currently owns the widget session. */\n private sessionActive: boolean = false;\n\n // Config derived state\n private widgetMode: WidgetMode = 'voice_only';\n private agentId: string = '';\n private prospectGroupId: string = '';\n private chatServerUrl: string = '';\n\n private prospectId: string = '';\n private chatId: string | null = null;\n private widgetId: string = '';\n\n // Appearance (Defaults)\n private primaryColor: string = '#6366f1';\n private secondaryColor: string = '#4f46e5';\n private gradient: string | null = null;\n private position: string = 'bottom-right';\n private widgetIcon: string | null = null;\n\n constructor(config: any) {\n super(config);\n this.chatAdapter = new VaniraChatAdapter();\n this.processConfig(config);\n }\n\n // âââ Session Initialisation âââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Boot the SessionManager.\n * Called once we have a stable widgetId to key the session on.\n * Returns true if this tab owns the session, false if another tab owns it.\n */\n private initSessionManager(): boolean {\n const key = this.widgetId || this.agentId || 'default';\n this.sessionManager = new SessionManager(key);\n\n // Wire cross-tab events\n this.sessionManager.on('tab_took_over', () => {\n // Another tab stole the session â show \"taken over\" banner in this tab\n console.warn('[VaniraAI] Session taken over by another tab.');\n this.sessionActive = false;\n this.showTabConflictBanner('taken_over');\n });\n\n this.sessionManager.on('session_cleared', () => {\n console.log('[VaniraAI] Session cleared externally.');\n });\n\n const claimed = this.sessionManager.claimSession();\n this.sessionActive = claimed;\n return claimed;\n }\n\n /**\n * Restore persisted chat messages into the chat window.\n * Called after the view is rendered.\n */\n private restoreSessionMessages(): void {\n const session = this.sessionManager?.getSession();\n if (!session) return;\n\n const cw = this.currentView?.getChatWindow?.();\n if (!cw) return;\n\n // Filter out empty placeholder messages\n const visibleMessages = session.messages.filter(msg => msg.content.trim() !== '');\n\n // Load persisted call records\n const callKey = `vanira_calls_${this.widgetId || this.agentId}`;\n const callRecords: Array<{ durationMs: number; startedAt: number }> =\n JSON.parse(localStorage.getItem(callKey) || '[]');\n\n if (visibleMessages.length === 0 && callRecords.length === 0) return;\n\n cw.clearMessages();\n\n // Merge messages and call records by timestamp, then render in order\n type Entry =\n | { type: 'msg'; role: 'user' | 'assistant'; content: string; ts: number }\n | { type: 'call'; durationMs: number; startedAt: number; ts: number };\n\n const entries: Entry[] = [\n ...visibleMessages.map((m, i) => ({\n type: 'msg' as const,\n role: m.role,\n content: m.content,\n // If session messages have no timestamp, use index as tiebreaker\n ts: (m as any).timestamp ?? i,\n })),\n ...callRecords.map(r => ({\n type: 'call' as const,\n durationMs: r.durationMs,\n startedAt: r.startedAt,\n ts: r.startedAt,\n })),\n ];\n\n entries.sort((a, b) => a.ts - b.ts);\n\n entries.forEach(entry => {\n if (entry.type === 'msg') {\n cw.addMessage(entry.role, entry.content, entry.ts);\n } else {\n cw.addCallRecord(entry.durationMs, entry.startedAt);\n }\n });\n\n console.log(`[VaniraAI] Restored ${visibleMessages.length} messages + ${callRecords.length} call records from session.`);\n }\n\n // âââ Tab Conflict UI âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Renders a friendly overlay when:\n * - 'conflict' â this tab tried to open but another tab owns the session\n * - 'taken_over' â another tab stole the session while this tab was active\n */\n private showTabConflictBanner(reason: 'conflict' | 'taken_over'): void {\n if (!this.root) return;\n\n // Remove any existing banner\n this.root.querySelector('.vanira-tab-conflict-banner')?.remove();\n\n if (reason === 'conflict') {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n if (this.widgetMode.includes('chat')) {\n this.initializeChatSession(false);\n }\n }\n // If 'taken_over', do nothing. The tab silently becomes dormant.\n }\n\n private static audioContext: AudioContext | null = null;\n private playMessageSound(type: 'send' | 'receive') {\n try {\n if (!VaniraInternalProvider.audioContext) {\n const AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;\n if (!AudioContextClass) return;\n VaniraInternalProvider.audioContext = new AudioContextClass();\n }\n const ctx = VaniraInternalProvider.audioContext;\n \n // Required by modern browsers to play sound after interaction\n if (ctx.state === 'suspended') {\n ctx.resume().catch(() => {});\n }\n \n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.connect(gain);\n gain.connect(ctx.destination);\n\n const now = ctx.currentTime;\n if (type === 'send') {\n // A subtle rising pop for sending\n osc.type = 'sine';\n osc.frequency.setValueAtTime(300, now);\n osc.frequency.exponentialRampToValueAtTime(500, now + 0.05);\n gain.gain.setValueAtTime(0, now);\n gain.gain.linearRampToValueAtTime(0.1, now + 0.01);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.1);\n osc.start(now);\n osc.stop(now + 0.1);\n } else {\n // A friendly bright pop for receiving\n osc.type = 'sine';\n osc.frequency.setValueAtTime(500, now);\n osc.frequency.exponentialRampToValueAtTime(800, now + 0.1);\n gain.gain.setValueAtTime(0, now);\n gain.gain.linearRampToValueAtTime(0.15, now + 0.02);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.2);\n osc.start(now);\n osc.stop(now + 0.2);\n }\n } catch (e) {\n console.warn('[VaniraAI] Audio feedback failed', e);\n }\n }\n\n // âââ Chat Logic âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private async initializeChatSession(forceNew: boolean = false): Promise<void> {\n if (!this.sessionActive) return;\n\n try {\n ChatService.setChatUrl(this.chatServerUrl);\n\n const session = this.sessionManager?.getSession();\n\n // ââ Restore existing session ââââââââââââââââââââââââââââââââââââââ\n if (!forceNew && session?.prospectId) {\n this.prospectId = session.prospectId;\n this.chatId = session.chatId;\n\n console.log(`[VaniraAI] Session restored â tab: ${this.sessionManager?.getTabId()}, prospect: ${this.prospectId}`);\n\n // Restore messages into UI\n this.restoreSessionMessages();\n\n // Re-attach the SSE admin-reply stream\n if (this.chatId && !this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (text) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', text);\n this.sessionManager?.pushMessage('assistant', text);\n this.playMessageSound('receive');\n }\n );\n }\n\n return; // Don't fetch a new welcome message\n }\n\n // ââ Fresh session âââââââââââââââââââââââââââââââââââââââââââââââââ\n if (this.prospectGroupId) {\n this.prospectId = await ChatService.createChatProspect(this.prospectGroupId);\n } else {\n this.prospectId = `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n const welcome = await ChatService.fetchWelcomeMessage(this.agentId, this.prospectId, this.widgetId || undefined);\n\n if (welcome?.chatId && !this.chatId) {\n this.chatId = welcome.chatId;\n if (!this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (text) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', text);\n this.sessionManager?.pushMessage('assistant', text);\n this.playMessageSound('receive');\n }\n );\n }\n }\n\n // Persist IDs so a refresh restores the session\n this.sessionManager?.saveIds(this.prospectId, this.chatId);\n\n if (welcome && this.currentView?.getChatWindow) {\n const cw = this.currentView.getChatWindow();\n cw.clearMessages();\n\n if (welcome.widget) {\n try {\n const payload = JSON.parse(welcome.content);\n const welcomeText = payload.text || '';\n cw.addMessage(welcome.role, welcomeText);\n this.sessionManager?.pushMessage(welcome.role, welcomeText);\n\n if (payload.buttons && Array.isArray(payload.buttons)) {\n cw.addButtons(payload.buttons);\n this.welcomeChipsData = payload.buttons;\n }\n this.updateWelcomeChipsVisibility();\n } catch (e) {\n console.error('Failed to parse welcome widget content', e);\n cw.addMessage(welcome.role, welcome.content);\n this.sessionManager?.pushMessage(welcome.role, welcome.content);\n }\n } else {\n cw.addMessage(welcome.role, welcome.content);\n this.sessionManager?.pushMessage(welcome.role, welcome.content);\n }\n }\n } catch (error) {\n console.error('[VaniraAI] Chat init failed', error);\n const fallback = 'Hello! How can I help you today?';\n this.currentView?.getChatWindow?.().addMessage('assistant', fallback);\n this.sessionManager?.pushMessage('assistant', fallback);\n }\n }\n\n async initialize(config: any): Promise<void> {\n await super.initialize(config);\n this.processConfig(config);\n if (this.root) {\n this.ui_renderer(this.root);\n }\n }\n\n private processConfig(config: any) {\n this.widgetId = config.widgetId || config.widget_id || '';\n this.agentId = config.agentId || config.agent_id || '';\n this.prospectGroupId = config.prospectGroupId || config.client?.base_prospect_group_id || '';\n this.widgetMode = config.widgetMode || config.mode || 'voice_only';\n this.widgetId = config.widgetId || config.widget_id || \"\";\n\n this.primaryColor = config.primaryColor || '#6366f1';\n this.secondaryColor = config.secondaryColor || config.primaryColor || '#4f46e5';\n this.gradient = config.gradient || null;\n this.position = config.position || 'bottom-right';\n this.widgetIcon = config.widgetIcon || config.icon || null;\n\n // Configurable server URLs â fall back to Vanira production endpoints\n this.chatServerUrl = config.serverUrl || config.chatServerUrl || 'https://inboxapi.travelr.club';\n\n\n }\n\n async create_call(): Promise<void> {\n if (this.callActive || !this.agentId) return;\n if (!this.sessionActive) {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n }\n try {\n this.callActive = true;\n this.updateViewCallState(true);\n this.updateViewStatus('connecting');\n\n // Generate call ID from server\n const callContext = await ChatService.createCall(\n this.agentId,\n null,\n this.prospectId || null,\n this.widgetMode\n );\n\n // Use VaniraAI SDK â abstracts all WebRTC internals\n const client = new VaniraAI({\n agentId: this.agentId,\n callId: callContext.callId,\n serverUrl: callContext.workerUrl,\n });\n\n // Status events\n client\n .on('connected', () => this.updateViewStatus('connected'))\n .on('disconnected', () => this.end_call())\n .on('error', (msg) => {\n console.error('[VaniraAI Widget] Call error:', msg);\n this.updateViewStatus('error');\n })\n .on('transcription', ({ text, isFinal }) => {\n this.currentView?.setTranscription?.(text, isFinal);\n })\n .on('track', ({ track }) => {\n if (this.widgetMode.includes('avatar') && track.kind === 'video' && this.currentView?.setVideoTrack) {\n this.currentView.setVideoTrack(track);\n }\n })\n .on('tool_call', (toolCall) => {\n // Dispatch tool_call event to the host page via a custom DOM event\n const event = new CustomEvent('vaniraai:tool_call', {\n detail: toolCall,\n bubbles: true,\n composed: true, // crosses Shadow DOM boundary\n });\n this.root?.host?.dispatchEvent(event);\n\n console.log('[VaniraAI Widget] Tool call dispatched:', toolCall.name, toolCall.arguments);\n\n if (toolCall.execution_mode === 'fire_and_forget') {\n // Auto-resolved â nothing extra needed\n }\n // Blocking tools: host page must call window.VaniraAI.sendToolResult(...)\n });\n\n this.vaniraClient = client;\n await client.start();\n\n } catch (err) {\n console.error('[VaniraAI Widget] Call failed', err);\n this.updateViewStatus('error');\n }\n }\n\n end_call(): void {\n this.callActive = false;\n const client = this.vaniraClient;\n this.vaniraClient = null;\n if (client) {\n client.stop();\n }\n this.updateViewCallState(false);\n }\n\n private updateViewCallState(active: boolean) {\n if (this.currentView?.setCallActive) {\n this.currentView.setCallActive(active);\n }\n }\n\n private updateViewStatus(status: string) {\n if (this.currentView?.setStatus) {\n this.currentView.setStatus(status);\n }\n }\n\n ui_renderer(root: ShadowRoot): void {\n this.root = root;\n this.root.innerHTML = ''; // Start fresh\n\n // ââ Session Management ââââââââââââââââââââââââââââââââââââââââââââââ\n // Inject keyframe animation for the conflict banner\n const animStyle = document.createElement('style');\n animStyle.textContent = `@keyframes vanira-slide-up {\n from { opacity:0; transform:translateY(16px); }\n to { opacity:1; transform:translateY(0); }\n }`;\n this.root.appendChild(animStyle);\n\n // Establish the design tokens\n const style = document.createElement('style');\n style.textContent = `\n ${baseCss}\n :host { ${generateThemeVars(this.primaryColor, this.secondaryColor)} }\n ${FloatingButton.styles}\n ${FloatingWelcomeChips.styles}\n ${Panel.styles}\n ${this.gradient ? `.widget-fab { background: ${this.gradient} !important; }` : ''}\n `;\n this.root.appendChild(style);\n\n // FloatingButton\n this.floatingButton = new FloatingButton(() => this.togglePanel());\n this.floatingButton.setIcon(this.getFabIcon());\n this.floatingButton.setPosition(this.getPosStyle());\n\n // Floating Welcome Chips\n this.floatingWelcomeChips = new FloatingWelcomeChips((text) => this.handleFloatingChipClick(text));\n this.floatingWelcomeChips.setPosition(this.getPosStyle());\n\n // Panel\n this.panel = new Panel(() => this.closePanel(), this.getPanelTitle());\n\n // Append components\n this.root.appendChild(this.floatingWelcomeChips.getElement());\n this.root.appendChild(this.floatingButton.getElement());\n this.root.appendChild(this.panel.getElement());\n\n // Setup content view\n this.setupPanelContent();\n\n // ââ Init Session ââââââââââââââââââââââââââââââââââââââââââââââââââââ\n const owned = this.initSessionManager();\n\n if (!owned) {\n // Another live tab owns the session â show a conflict banner\n this.showTabConflictBanner('conflict');\n } else if (this.widgetMode.includes('chat')) {\n // Session is ours â initialise chat (will restore if session exists)\n this.initializeChatSession();\n }\n }\n\n private getFabIcon(): string {\n if (this.widgetIcon && widgetIcons[this.widgetIcon]) {\n return widgetIcons[this.widgetIcon];\n }\n if (this.widgetMode.includes('chat')) {\n return icons.chat;\n }\n return icons.audioLines;\n }\n\n private getPanelTitle(): string {\n return 'Assistant';\n }\n\n private getPosStyle() {\n const posStyles: Record<string, string> = {\n 'bottom-right': 'bottom: 24px; right: 24px;',\n 'bottom-left': 'bottom: 24px; left: 24px;',\n 'top-right': 'top: 24px; right: 24px;',\n 'top-left': 'top: 24px; left: 24px;',\n };\n return posStyles[this.position] || posStyles['bottom-right'];\n }\n\n private setupPanelContent() {\n // ââ Voice Call History callback ââââââââââââââââââââââââââââââââââââââââââ\n const onCallEnded = (durationMs: number, startedAt: number) => {\n // 1. Inject card into active chat window (chat_voice / chat_avatar modes)\n const cw = this.currentView?.getChatWindow?.();\n if (cw) cw.addCallRecord(durationMs, startedAt);\n\n // 2. Persist to localStorage for cross-session restore\n const key = `vanira_calls_${this.widgetId || this.agentId}`;\n const existing: Array<{ durationMs: number; startedAt: number }> = JSON.parse(localStorage.getItem(key) || '[]');\n existing.push({ durationMs, startedAt });\n // Keep last 50 records max\n if (existing.length > 50) existing.splice(0, existing.length - 50);\n localStorage.setItem(key, JSON.stringify(existing));\n };\n\n switch (this.widgetMode) {\n case 'chat_only':\n this.currentView = new ChatOnlyView((msg: string) => this.handleChatSend(msg));\n break;\n case 'chat_voice':\n this.currentView = new ChatVoiceView(\n (msg: string) => this.handleChatSend(msg),\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'avatar_only':\n this.currentView = new AvatarOnlyView(\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'chat_avatar':\n this.currentView = new ChatAvatarView(\n (msg: string) => this.handleChatSend(msg),\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'voice_only':\n default:\n this.currentView = new VoiceOnlyView(\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n }\n\n if (this.currentView && this.panel) {\n this.panel.setContent(this.currentView.getElement());\n }\n }\n\n private async handleChatSend(text: string) {\n if (!text) return;\n if (!this.sessionActive) {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n if (this.widgetMode.includes('chat')) {\n await this.initializeChatSession(false);\n }\n }\n\n const cw = this.currentView?.getChatWindow?.();\n if (!cw) return;\n\n // Ensure SSE stream is running\n if (this.chatId && !this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (replyText) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', replyText);\n this.sessionManager?.pushMessage('assistant', replyText);\n this.playMessageSound('receive');\n }\n );\n }\n\n cw.addMessage('user', text);\n this.sessionManager?.pushMessage('user', text);\n cw.setTyping(true);\n\n // Push an empty assistant placeholder BEFORE streaming starts.\n // This ensures updateLastAssistantMessage always targets this new slot,\n // not the previous welcome message.\n this.sessionManager?.pushMessage('assistant', '');\n\n try {\n let hasPlayedReceive = false;\n \n await this.chatAdapter.sendMessage(\n text,\n this.agentId,\n this.prospectId,\n this.chatId,\n (response) => {\n if (!hasPlayedReceive) {\n this.playMessageSound('receive');\n hasPlayedReceive = true;\n }\n // onWidget\n cw.setTyping(false);\n if (response?.type === 'button_list' && response.data?.buttons) {\n cw.addButtons(response.data.buttons);\n this.welcomeChipsData = response.data.buttons;\n this.updateWelcomeChipsVisibility();\n }\n },\n (streamText) => {\n if (!hasPlayedReceive) {\n this.playMessageSound('receive');\n hasPlayedReceive = true;\n }\n // onStream â update last assistant message\n cw.setTyping(false);\n cw.updateLastAssistantMessage(streamText);\n this.sessionManager?.updateLastAssistantMessage(streamText);\n },\n (newId) => {\n if (newId) {\n this.chatId = newId;\n this.sessionManager?.saveIds(this.prospectId, newId);\n }\n }\n );\n } catch (err) {\n cw.setTyping(false);\n console.error('[VaniraAI] Send message failed', err);\n cw.addMessage('assistant', 'Error sending message.');\n }\n }\n\n // âââ Panel Management âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private togglePanel() {\n this.isPanelOpen ? this.closePanel() : this.openPanel();\n }\n\n private openPanel() {\n this.isPanelOpen = true;\n this.updateWelcomeChipsVisibility();\n this.panel?.open({\n bottom: this.position.includes('bottom') ? '100px' : undefined,\n top: this.position.includes('top') ? '100px' : undefined,\n right: this.position.includes('right') ? '24px' : undefined,\n left: this.position.includes('left') ? '24px' : undefined,\n });\n if (this.root?.host) {\n this.root.host.classList.add('vanira-panel-open');\n }\n }\n\n private closePanel() {\n this.isPanelOpen = false;\n this.updateWelcomeChipsVisibility();\n this.panel?.close();\n if (this.root?.host) {\n this.root.host.classList.remove('vanira-panel-open');\n }\n }\n\n private updateWelcomeChipsVisibility() {\n if (!this.floatingWelcomeChips) return;\n\n if (!this.isPanelOpen && this.welcomeChipsData.length > 0) {\n this.floatingWelcomeChips.setChips(this.welcomeChipsData);\n this.floatingWelcomeChips.getElement().style.display = 'flex';\n } else {\n this.floatingWelcomeChips.getElement().style.display = 'none';\n }\n }\n\n private handleFloatingChipClick(text: string) {\n this.openPanel();\n this.handleChatSend(text);\n }\n}\n","import { IWidgetProvider } from '../abstraction/interfaces';\nimport { VaniraInternalProvider } from '../providers/VaniraInternalProvider';\n\nexport class WidgetProviderFactory {\n /**\n * Factory Method to create the appropriate Widget Provider.\n * Implements the Factory Pattern to decouple creation logic.\n * Trade-off: Currently hardcoded to VaniraInternalProvider, but extensible for other providers.\n */\n static getProvider(config: any): IWidgetProvider {\n // Here we could check config.providerType to return different implementations\n // e.g. if (config.provider === 'external_sip') return new ExternalSIPProvider(config);\n\n return new VaniraInternalProvider(config);\n }\n}\n","import { ConfigService } from '../api/services/ConfigService';\nimport { WidgetProviderFactory } from './factory/WidgetFactory';\nimport { IWidgetProvider } from './abstraction/interfaces';\n\nexport class VaniraWidget extends HTMLElement {\n private shadow: ShadowRoot;\n private provider: IWidgetProvider | null = null;\n\n // Config attributes\n private widgetId: string = \"\";\n private agentId: string = \"\";\n private serverUrl: string = \"https://inboxapi.travelr.club\";\n private position: string = \"bottom-right\";\n private primaryColor: string = \"#6366f1\";\n private secondaryColor: string = \"#4f46e5\";\n private gradient: string | null = null;\n\n static get observedAttributes() {\n return ['widget-id', 'agent-id', 'position', 'primary-color', 'secondary-color', 'server-url', 'gradient'];\n }\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n console.log(\"[VaniraAI Widget] Initializing...\");\n this.readAttributes();\n\n // Initial Config based on attributes\n const initialConfig = {\n widgetId: this.widgetId,\n agentId: this.agentId,\n serverUrl: this.serverUrl,\n position: this.position,\n primaryColor: this.primaryColor,\n secondaryColor: this.secondaryColor,\n gradient: this.gradient\n };\n\n // Factory Pattern: Create specific provider\n this.provider = WidgetProviderFactory.getProvider(initialConfig);\n\n // UI Renderer: Delegate to provider (SRP)\n if (this.provider) {\n this.provider.ui_renderer(this.shadow);\n }\n\n // Fetch expanded config if widgetId is present\n if (this.widgetId && !this.agentId) {\n this.initializeExpandedConfig();\n }\n }\n\n private readAttributes() {\n this.widgetId = this.getAttribute('widget-id') || \"\";\n this.agentId = this.getAttribute('agent-id') || \"\";\n this.serverUrl = this.getAttribute('server-url') || \"https://inboxapi.travelr.club\";\n this.position = this.getAttribute('position') || \"bottom-right\";\n this.primaryColor = this.getAttribute('primary-color') || \"#6366f1\";\n this.secondaryColor = this.getAttribute('secondary-color') || this.primaryColor;\n this.gradient = this.getAttribute('gradient');\n }\n\n async initializeExpandedConfig() {\n try {\n const config = await ConfigService.fetchWidgetConfig(this.widgetId);\n\n // Pass API config to provider to update state/UI\n if (this.provider) {\n // This will trigger internal re-render in provider\n await this.provider.initialize(config);\n }\n } catch (error) {\n console.error(\"[VaniraAI Widget] Config failed:\", error);\n // specific error handling or Fallback_principle logic can be added here\n // Provider already has default state (Graceful degradation)\n }\n }\n}\n","import { VaniraWidget } from './ui/VaniraWidget';\nimport { VaniraAI } from './core/VaniraAI';\n\n// âââ Register Custom Element âââââââââââââââââââââââââââââââââââââââââââââââââ\nif (!customElements.get('vanira-convai')) {\n customElements.define('vanira-convai', VaniraWidget);\n}\n\n// âââ Global window exports âââââââââââââââââââââââââââââââââââââââââââââââââââ\nif (typeof window !== 'undefined') {\n // Legacy widget registration\n (window as any).VaniraConvAI = VaniraWidget;\n // New SDK class â integrators can do: const client = new window.VaniraAI({ agentId: '...' })\n (window as any).VaniraAI = VaniraAI;\n}\n\n// âââ Auto-inject Widget via script attributes ââââââââââââââââââââââââââââââââ\nconst currentScript = document.currentScript;\nif (currentScript) {\n const widgetId = currentScript.getAttribute('data-widget-id') || currentScript.getAttribute('widget-id');\n const agentId = currentScript.getAttribute('data-agent-id') || currentScript.getAttribute('agent-id');\n\n if (widgetId || agentId) {\n const position = currentScript.getAttribute('data-position') || 'bottom-right';\n const primaryColor = currentScript.getAttribute('data-primary-color') || currentScript.getAttribute('primary-color') || '#6366f1';\n const secondaryColor = currentScript.getAttribute('data-secondary-color') || currentScript.getAttribute('secondary-color');\n const gradient = currentScript.getAttribute('data-gradient') || currentScript.getAttribute('gradient');\n const serverUrl = currentScript.getAttribute('data-server-url') || currentScript.getAttribute('server-url');\n\n const widget = document.createElement('vanira-convai');\n if (widgetId) widget.setAttribute('widget-id', widgetId);\n if (agentId) widget.setAttribute('agent-id', agentId);\n widget.setAttribute('position', position);\n widget.setAttribute('primary-color', primaryColor);\n if (secondaryColor) widget.setAttribute('secondary-color', secondaryColor);\n if (gradient) widget.setAttribute('gradient', gradient);\n if (serverUrl) widget.setAttribute('server-url', serverUrl);\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => document.body.appendChild(widget));\n } else {\n document.body.appendChild(widget);\n }\n\n // âââ Listen for vaniraai:tool_call events from the widget ââââââââââââââ\n // Integrators can attach their own handlers:\n // document.querySelector('vanira-convai').addEventListener('vaniraai:tool_call', (e) => { ... })\n // But also expose a default global handler slot for convenience.\n widget.addEventListener('vaniraai:tool_call', (e: Event) => {\n const toolCall = (e as CustomEvent).detail;\n console.log('[VaniraAI Widget] Tool call received by host page:', toolCall.name, toolCall.arguments);\n // If integrator registered a global handler, call it\n if (typeof (window as any).__vaniraai_tool_handler === 'function') {\n (window as any).__vaniraai_tool_handler(toolCall, {\n sendResult: (result: any) => {\n // Future: wire back to widget vaniraClient\n console.log('[VaniraAI] sendResult called:', result);\n }\n });\n }\n });\n }\n}\n"],"names":["HASURA_URL","ConfigService","widgetId","query","widget","_a","clientData","_b","error","CHAT_URL","ChatService","url","prospectGroupId","mutation","data","agentId","prospectId","response","content","chatId","uiPayload","message","onChunk","onWidget","onDone","payload","reader","decoder","assistantContent","buffer","newChatId","done","value","lines","line","trimmedLine","parsed","_d","_c","inboxId","sender","onMessage","es","reconnectAttempts","isClosed","connect","event","isOutgoing","hasContent","isNotAI","e","err","delay","clientId","widgetMode","baseWorkerUrl","AbstractWidgetProvider","config","__publicField","WebRTCClient","stream","track","text","checkConnectionState","isConnected","_e","isFailed","_f","_g","_h","_i","_j","_k","offer","answer","resolve","checkState","msg","callId","result","context","token","graphqlEndpoint","VaniraAI","callback","cb","serverUrl","isFinal","rawCall","toolCall","toolCallId","errorMessage","actionName","status","_documentCurrentScript","__vite_import_meta_env__","method","_SessionManager","safeId","existing","age","isOwnTab","isStaletab","draft","hadPrior","session","role","msgs","found","i","id","ev","raw","SessionManager","MALE_ICON_BASE64","FEMALE_ICON_BASE64","generateThemeVars","primary","secondary","widgetStyles","icons","industryIcons","widgetIcons","name","svg","FloatingButton","onClick","initialIcon","rect","onPointerMove","moveEvent","maxX","maxY","onPointerUp","upEvent","iconHtml","positionStyle","s","prop","val","str","Panel","onClose","title","controls","element","position","VoiceOverlay","onHangup","primaryColor","secondaryColor","onCallEnded","shine","phoneSvg","greenDot","connectedText","sDot","sTxt","footer","duration","startedAt","mode","l","diff","mins","secs","enable","ChatWindow","onSend","brandingArea","date","timestamp","wrapper","msgDiv","ts","lastWrapper","lastMsg","buttons","buttonsContainer","btn","buttonEl","overrideText","isTyping","dot","durationMs","label","card","AvatarView","avatarUrl","sourceUrl","isVideo","mediaElement","vid","img","VoiceOrb","orbContainer","FloatingWelcomeChips","onChipClick","chips","style","chip","index","AbstractVoiceView","onStartCall","active","VoiceOnlyView","ChatOnlyView","onSendMessage","AbstractChatView","chatEl","triggerBtn","inputArea","ChatVoiceView","AvatarOnlyView","avatarEl","ChatAvatarView","iconDiv","sendBtn","VaniraChatAdapter","onResponse","onStream","onChatIdUpdate","newId","file","messageId","action","_VaniraInternalProvider","key","claimed","cw","visibleMessages","callKey","callRecords","entries","m","r","a","b","entry","reason","type","AudioContextClass","ctx","osc","gain","now","forceNew","welcome","welcomeText","fallback","callContext","client","root","animStyle","baseCss","posStyles","replyText","hasPlayedReceive","streamText","VaniraInternalProvider","WidgetProviderFactory","VaniraWidget","initialConfig","currentScript","gradient"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
|
|
1
|
+
{"version":3,"file":"vanira-sdk.js","sources":["../src/api/services/ConfigService.ts","../src/api/services/ChatService.ts","../src/ui/abstraction/AbstractWidgetProvider.ts","../src/core/WebRTCClient.ts","../src/core/VaniraAI.ts","../src/core/SessionManager.ts","../src/ui/icons_data.ts","../src/ui/styles/theme.ts","../src/ui/styles/widget.css.ts","../src/ui/styles/index.ts","../src/ui/components/FloatingButton.ts","../src/ui/components/Panel.ts","../src/ui/components/VoiceOverlay.ts","../src/ui/components/ChatWindow.ts","../src/ui/components/AvatarView.ts","../src/ui/components/VoiceOrb.ts","../src/ui/components/FloatingWelcomeChips.ts","../src/ui/views/AbstractVoiceView.ts","../src/ui/views/VoiceOnlyView.ts","../src/ui/views/ChatOnlyView.ts","../src/ui/views/AbstractChatView.ts","../src/ui/views/ChatVoiceView.ts","../src/ui/views/AvatarOnlyView.ts","../src/ui/views/ChatAvatarView.ts","../src/ui/adapters/VaniraChatAdapter.ts","../src/ui/providers/VaniraInternalProvider.ts","../src/ui/factory/WidgetFactory.ts","../src/ui/VaniraWidget.ts","../src/cdn.ts"],"sourcesContent":["import { WidgetConfig } from '../../types';\n\nconst HASURA_URL = 'https://coredb.travelr.club/v1/graphql';\n\nexport class ConfigService {\n static async fetchWidgetConfig(widgetId: string): Promise<WidgetConfig> {\n const query = `\n query GetWidgetConfig($id: uuid!) {\n app_widget_by_pk(id: $id) {\n agent_id\n client_id\n mode\n icon\n gradient\n agent {\n tts_voice {\n provider {\n root_name\n provider_country\n }\n }\n }\n }\n }\n `;\n\n try {\n const response = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ query, variables: { id: widgetId } }),\n });\n\n const data = await response.json();\n const widget = data.data?.app_widget_by_pk;\n\n if (!widget) {\n throw new Error(`Widget configuration not found for ID: ${widgetId}`);\n }\n\n // Fetch Client Details using client_id\n if (widget.client_id) {\n const clientQuery = `\n query GetClientDetails($id: uuid!) {\n client_by_pk(id: $id) {\n base_prospect_group_id\n }\n }\n `;\n\n const clientResponse = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: clientQuery,\n variables: { id: widget.client_id },\n }),\n });\n\n const clientData = await clientResponse.json();\n if (clientData.data?.client_by_pk) {\n widget.client = clientData.data.client_by_pk;\n }\n }\n\n return widget as WidgetConfig;\n } catch (error) {\n console.error('[VaniraAI] Failed to fetch widget config:', error);\n throw error;\n }\n }\n}\n","export interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n widget?: {\n type: 'carousel' | 'button_list';\n data: any;\n };\n}\n\nconst HASURA_URL = 'https://coredb.travelr.club/v1/graphql';\nlet CHAT_URL = 'https://inboxapi.travelr.club';\n\nexport class ChatService {\n static setChatUrl(url: string) {\n CHAT_URL = url;\n }\n\n static async createChatProspect(prospectGroupId: string): Promise<string> {\n const mutation = `\n mutation CreateChatProspect($prospectGroupId: uuid!, $name: String!) {\n insert_prospects_one(object: {prospect_group_id: $prospectGroupId, name: $name, source: \"widget\"}) {\n id\n }\n }\n `;\n\n try {\n const response = await fetch(HASURA_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: mutation,\n variables: {\n prospectGroupId,\n name: `Widget Guest ${new Date().toLocaleString()}`\n }\n }),\n });\n\n const data = await response.json();\n\n if (data.errors) {\n console.warn('[VaniraAI] Prospect creation failed, using anonymous ID', data.errors);\n // Fallback Logic\n return `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n return data.data?.insert_prospects_one?.id || `anon_${Date.now()}`;\n } catch (error) {\n console.error('[VaniraAI] Failed to create prospect:', error);\n return `anon_${Date.now()}`;\n }\n }\n\n // Calls the new Go bridge /widget/chat endpoint with an empty message to initialize the session and get the Welcome config + inbox_id\n static async fetchWelcomeMessage(agentId: string, prospectId: string, widgetId?: string): Promise<ChatMessage & { chatId?: string }> {\n try {\n const response = await fetch(`${CHAT_URL}/widget/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentId,\n ...(widgetId ? { widget_id: widgetId } : {}),\n message: '',\n prospect_id: prospectId,\n stream: false\n }),\n });\n\n if (!response.ok) throw new Error('Failed to fetch welcome message');\n\n const data = await response.json();\n let content = data.response || 'Hello! How can I help you today?';\n let widget = undefined;\n const chatId = data.chat_id || data.inbox_id; // Go bridge returns chat_id which is the inbox_id\n\n if (data.widget) {\n widget = data.widget;\n const uiPayload: any = { text: content };\n if (widget.type === 'carousel' && widget.data?.cards) {\n uiPayload.cards = widget.data.cards;\n } else if (widget.type === 'button_list' && widget.data?.buttons) {\n uiPayload.buttons = widget.data.buttons;\n }\n content = JSON.stringify(uiPayload);\n }\n\n return { role: 'assistant', content, widget, chatId };\n } catch (error) {\n console.error('[VaniraAI] Failed to fetch welcome message:', error);\n // Graceful Degradation\n return { role: 'assistant', content: 'Hello! How can I help you today?' };\n }\n }\n\n static async sendChatMessage(\n agentId: string,\n prospectId: string,\n message: string,\n chatId: string | null,\n onChunk: (text: string) => void,\n onWidget: (widget: any) => void,\n onDone: (newChatId: string | null) => void,\n widgetId?: string\n ): Promise<void> {\n try {\n const payload: any = {\n agent_id: agentId,\n message: message,\n prospect_id: prospectId,\n stream: true\n };\n\n if (chatId) payload.inbox_id = chatId;\n if (widgetId) payload.widget_id = widgetId;\n\n const response = await fetch(`${CHAT_URL}/widget/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) throw new Error('Chat request failed');\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n if (!reader) throw new Error('No reader');\n\n let assistantContent = '';\n let buffer = '';\n let newChatId: string | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine) continue;\n\n if (trimmedLine.startsWith('data: ')) {\n const data = trimmedLine.slice(6);\n if (data === '[DONE]') {\n onDone(newChatId);\n return;\n }\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === 'metadata' && parsed.chat_id) {\n newChatId = parsed.chat_id;\n continue;\n }\n const content = parsed.choices?.[0]?.delta?.content;\n if (content) {\n assistantContent += content;\n onChunk(assistantContent);\n }\n if (parsed.widget) {\n onWidget(parsed.widget);\n }\n if (parsed.chat_id && !newChatId) {\n newChatId = parsed.chat_id;\n }\n } catch (e) { }\n }\n }\n }\n\n onDone(newChatId);\n } catch (error) {\n console.error('[VaniraAI] Chat error:', error);\n onChunk('Sorry, I encountered an error. Please try again.');\n onDone(null);\n }\n }\n static listenForAdminReplies(inboxId: string, sender: string, onMessage: (content: string) => void): { close: () => void } {\n const url = `${CHAT_URL}/inbox/stream?inbox_id=${inboxId}&sender=${encodeURIComponent(sender)}`;\n let es: EventSource | null = null;\n let reconnectAttempts = 0;\n let isClosed = false;\n\n const connect = () => {\n if (isClosed) return;\n\n es = new EventSource(url);\n console.log(`[VaniraAI] Subscribed to SSE EventSource at ${es.url}`);\n\n es.onopen = () => {\n console.log(\"[VaniraAI] SSE connection opened successfully.\");\n reconnectAttempts = 0; // Reset backoff on success\n };\n\n es.onmessage = (event) => {\n console.log(\"[VaniraAI] đĄ Raw SSE Event triggered:\", event.data);\n try {\n const data = JSON.parse(event.data);\n console.log(\"[VaniraAI] SSE stream JSON parsed:\", data);\n\n const isOutgoing = data.direction === 'outgoing';\n const hasContent = !!data.content;\n const isNotAI = data.source !== 'ai';\n\n if (isOutgoing && hasContent && isNotAI) {\n console.log(\"[VaniraAI] đ¯ Displaying admin message in chat UI:\", data.content);\n onMessage(data.content);\n }\n } catch (e) {\n console.error('[VaniraAI] SSE parse error', e);\n }\n };\n\n es.onerror = (err) => {\n console.error('[VaniraAI] SSE connection error or disconnect', err);\n if (es) {\n es.close();\n es = null;\n }\n\n if (isClosed) return;\n\n // Exponential backoff: 2s, 4s, 8s, 16s... max 30s\n const delay = Math.min(2000 * Math.pow(2, reconnectAttempts), 30000);\n console.log(`[VaniraAI] Reconnecting SSE in ${delay}ms (Attempt ${reconnectAttempts + 1})...`);\n reconnectAttempts++;\n\n setTimeout(connect, delay);\n };\n };\n\n connect(); // Start initial connection\n\n return {\n close: () => {\n isClosed = true;\n if (es) {\n es.close();\n es = null;\n console.log(\"[VaniraAI] SSE connection manually closed.\");\n }\n }\n };\n }\n\n static async createCall(agentId: string, clientId: string | null, prospectId: string | null, widgetMode: string): Promise<{ callId: string, workerUrl: string }> {\n try {\n const response = await fetch('https://wfapi.travelr.club/webhook/create-web-call', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentId,\n client_id: clientId,\n prospect_id: prospectId,\n is_avatar_call: widgetMode.includes('avatar')\n }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`[VaniraAI] Call creation failed HTTP ${response.status}`);\n }\n\n if (!data.worker_url) {\n throw new Error('[VaniraAI] Worker URL missing from response. Call cannot proceed.');\n }\n\n let baseWorkerUrl: string;\n try {\n baseWorkerUrl = new URL(data.worker_url).origin;\n } catch (e) {\n baseWorkerUrl = data.worker_url;\n }\n\n return {\n callId: data.call_id || data.id || `web_${Date.now()}`,\n workerUrl: baseWorkerUrl\n };\n } catch (error) {\n console.error('[VaniraAI] Failed to create call:', error);\n throw error; // Re-throw to ensure caller knows it failed\n }\n }\n}\n","import { IWidgetProvider } from './interfaces';\n\nexport abstract class AbstractWidgetProvider implements IWidgetProvider {\n protected config: any;\n protected root: ShadowRoot | null = null;\n\n constructor(config: any) {\n this.config = config;\n }\n\n abstract create_call(): Promise<void>;\n abstract end_call(): void;\n abstract ui_renderer(root: ShadowRoot): void;\n\n async initialize(config: any): Promise<void> {\n this.config = config;\n }\n}\n","import { WebRTCClientConfig, ControlEvent } from '../types';\n\n\nexport class WebRTCClient {\n private serverUrl: string;\n private agentId: string;\n private callId: string;\n private onConnected: () => void;\n private onDisconnected: () => void;\n private onError: (error: any) => void;\n private onTranscription: (text: string, isFinal: boolean) => void;\n // @ts-ignore\n private onRemoteTrack: (track: MediaStreamTrack, stream: MediaStream) => void;\n private onClientToolCall: (toolCall: any) => void;\n\n private pc: RTCPeerConnection | null = null;\n private dataChannel: RTCDataChannel | null = null;\n private audioElement: HTMLAudioElement | null = null;\n public connected: boolean = false;\n private iceServers?: RTCIceServer[];\n private token?: string;\n\n constructor(config: WebRTCClientConfig) {\n if (!config.serverUrl) throw new Error(\"serverUrl is required\");\n if (!config.agentId) throw new Error(\"agentId is required\");\n\n this.serverUrl = config.serverUrl.replace(/\\/$/, '');\n this.agentId = config.agentId;\n this.callId = config.callId || this.generateCallId();\n this.iceServers = config.iceServers;\n this.token = config.token;\n\n // Callbacks\n this.onConnected = config.onConnected || (() => { });\n this.onDisconnected = config.onDisconnected || (() => { });\n this.onError = config.onError || ((e) => console.error('[WebRTC]', e));\n this.onTranscription = config.onTranscription || (() => { });\n // @ts-ignore\n this.onRemoteTrack = config.onRemoteTrack || (() => { });\n this.onClientToolCall = config.onClientToolCall || (() => { });\n }\n\n /**\n * Connect via HTTP signaling (no WebSocket)\n */\n async connect(): Promise<void> {\n console.log('đĩ [WebRTC] Starting connection...');\n\n try {\n // Fetch ICE servers if not provided\n if (!this.iceServers && this.token) {\n try {\n this.iceServers = await WebRTCClient.fetchIceServers(this.token);\n } catch (e) {\n console.warn('â ī¸ [WebRTC] Failed to fetch ICE servers:', e);\n }\n }\n\n // 1. Create RTCPeerConnection\n this.pc = new RTCPeerConnection({\n iceServers: this.iceServers || [\n {\n urls: 'stun:global.relay.metered.ca:80'\n },\n {\n urls: [\n 'turns:global.relay.metered.ca:443?transport=tcp',\n 'turn:global.relay.metered.ca:80?transport=tcp',\n 'turn:global.relay.metered.ca:443?transport=tcp'\n ],\n username: 'fa97658be3343d21da3b65e6',\n credential: 'HXHDoqeHbvZrmCuf'\n }\n ]\n });\n\n // Add video transceiver to ensure we offer video handling capability\n this.pc.addTransceiver('video', { direction: 'recvonly' });\n\n // 2. Get microphone with AEC/NS/AGC\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n sampleRate: { ideal: 16000 },\n channelCount: 1\n }\n });\n console.log('đ¤ [WebRTC] Microphone access granted');\n\n // Check if connection was closed during getUserMedia (e.g., StrictMode unmount)\n if (!this.pc) {\n console.log('[WebRTC] Connection aborted: peer connection closed during setup');\n stream.getTracks().forEach(track => track.stop()); // Clean up media tracks\n return;\n }\n\n // 3. Add audio track\n stream.getTracks().forEach(track => {\n this.pc?.addTrack(track, stream);\n });\n\n // 4. Create DataChannel for control events\n if (!this.pc) {\n throw new Error('RTCPeerConnection was closed unexpectedly');\n }\n this.dataChannel = this.pc.createDataChannel('control');\n this.dataChannel.onopen = () => console.log('đĄ [WebRTC] DataChannel opened');\n this.dataChannel.onmessage = (e) => {\n // Handle both string and ArrayBuffer data\n if (typeof e.data === 'string') {\n try {\n this.handleControlEvent(JSON.parse(e.data));\n } catch (err) {\n console.warn('[WebRTC] Failed to parse message:', e.data);\n }\n } else if (e.data instanceof ArrayBuffer) {\n // Binary data: decode and log for inspection only\n // DO NOT re-feed into handleControlEvent (binary frames may falsely decode as clearAudio etc.)\n try {\n const text = new TextDecoder().decode(e.data);\n try {\n const parsed = JSON.parse(text);\n // Only explicitly forward client_tool_call to prevent clearAudio bugs\n if (parsed && typeof parsed === 'object' && parsed.event === 'client_tool_call') {\n console.log('[VaniraAI] Safely decoding binary tool_call to JSON:', parsed);\n this.handleControlEvent(parsed);\n } else {\n console.log('[VaniraAI] Decoded JSON from binary (inspect only):', parsed);\n }\n } catch (_) {\n console.log('[VaniraAI] Decoded String from binary:', text);\n }\n } catch (_) {\n console.log('[VaniraAI] Received binary data:', e.data.byteLength, 'bytes (not decodable)');\n }\n } else if (e.data instanceof Blob) {\n // Blob data - convert to text if needed\n e.data.text().then(text => {\n try {\n this.handleControlEvent(JSON.parse(text));\n } catch (err) {\n console.warn('[WebRTC] Failed to parse blob data:', text);\n }\n });\n }\n };\n this.dataChannel.onerror = (e) => console.error('â [WebRTC] DataChannel error:', e);\n\n // 5. Handle incoming tracks from server\n this.pc.ontrack = (event) => {\n const track = event.track;\n const stream = event.streams[0];\n console.log(`đĨ [WebRTC] Received ${track.kind} track`);\n\n if (track.kind === 'audio') {\n console.log('đ [WebRTC] Received audio track from server');\n this.audioElement = new Audio();\n this.audioElement.srcObject = stream;\n this.audioElement.play().catch(e => console.warn('Audio autoplay blocked:', e));\n\n // Notify server when playback finishes\n this.audioElement.onended = () => {\n this.sendEvent('playedStream');\n console.log('â
[WebRTC] TTS playback complete');\n };\n } else if (track.kind === 'video') {\n console.log('đš [WebRTC] Video track received');\n this.onRemoteTrack(track, stream);\n }\n };\n\n // 6. Connection state monitoring\n const checkConnectionState = () => {\n console.log('đ [WebRTC] State:', this.pc?.connectionState, '| ICE:', this.pc?.iceConnectionState);\n const isConnected =\n this.pc?.connectionState === 'connected' ||\n this.pc?.iceConnectionState === 'connected' ||\n this.pc?.iceConnectionState === 'completed';\n\n const isFailed =\n this.pc?.connectionState === 'failed' ||\n this.pc?.iceConnectionState === 'failed' ||\n this.pc?.connectionState === 'closed' ||\n this.pc?.iceConnectionState === 'closed' ||\n this.pc?.connectionState === 'disconnected' ||\n this.pc?.iceConnectionState === 'disconnected';\n\n if (isConnected && !this.connected) {\n this.connected = true;\n this.onConnected();\n } else if (isFailed && this.connected) {\n this.connected = false;\n this.onDisconnected();\n }\n };\n\n this.pc.onconnectionstatechange = checkConnectionState;\n this.pc.oniceconnectionstatechange = checkConnectionState;\n\n // 7. Create offer\n const offer = await this.pc.createOffer();\n await this.pc.setLocalDescription(offer);\n console.log('đ [WebRTC] Created offer, waiting for ICE gathering...');\n\n // 8. Wait for ICE gathering to complete (non-trickle)\n await this.waitForIceGathering();\n console.log('đ§ [WebRTC] ICE gathering complete');\n\n // 9. Send offer via HTTP POST\n console.log('đ¤ [WebRTC] Sending offer via HTTP...');\n const response = await fetch(`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n offer: this.pc.localDescription,\n agentId: this.agentId,\n callId: this.callId\n })\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n const { answer } = await response.json();\n console.log('đĨ [WebRTC] Received answer from server');\n\n // 10. Set remote description\n await this.pc.setRemoteDescription(answer);\n console.log('â
[WebRTC] Connection established!');\n\n } catch (error: any) {\n console.error('â [WebRTC] Connection failed:', error);\n this.disconnect(); // Ensure cleanup (pc, streams, etc.)\n this.onError(error.message || error);\n throw error;\n }\n }\n\n /**\n * Wait for ICE gathering to complete\n */\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) return resolve();\n if (this.pc.iceGatheringState === 'complete') {\n resolve();\n } else {\n const checkState = () => {\n if (this.pc?.iceGatheringState === 'complete') {\n this.pc?.removeEventListener('icegatheringstatechange', checkState);\n resolve();\n }\n };\n this.pc.addEventListener('icegatheringstatechange', checkState);\n\n // Timeout fallback (5 seconds)\n setTimeout(() => {\n this.pc?.removeEventListener('icegatheringstatechange', checkState);\n console.warn('â ī¸ [WebRTC] ICE gathering timeout, proceeding anyway');\n resolve();\n }, 5000);\n }\n });\n }\n\n /**\n * Send control event via DataChannel\n */\n sendEvent(event: string, data = {}): void {\n if (this.dataChannel?.readyState === 'open') {\n this.dataChannel.send(JSON.stringify({ event, ...data }));\n }\n }\n\n /**\n * Handle control events from server\n */\n private handleControlEvent(msg: ControlEvent): void {\n switch (msg.event) {\n case 'clearAudio':\n console.log('đ [WebRTC] Interrupt: clearAudio received (leaving stream unpaused)');\n // DONT pause the audio element! The server simply stops sending packets.\n // Pausing a WebRTC stream's audio element permanently mutes all future backend packets.\n // if (this.audioElement) {\n // this.audioElement.pause();\n // this.audioElement.currentTime = 0;\n // }\n break;\n\n case 'transcription':\n console.log('đ [WebRTC] Transcription:', msg.text);\n // @ts-ignore\n this.onTranscription(msg.text, msg.isFinal);\n break;\n\n case 'mark':\n // @ts-ignore\n console.log('đˇī¸ [WebRTC] Mark:', msg.name);\n break;\n\n case 'client_tool_call':\n console.log('đ ī¸ [VaniraAI] Client Tool Call:', msg);\n this.onClientToolCall(msg.tool_call || msg.data || msg);\n break;\n\n default:\n console.log('âšī¸ [WebRTC] Unknown event:', msg.event);\n }\n }\n\n /**\n * Disconnect and cleanup\n */\n disconnect(): void {\n console.log('đ´ [WebRTC] Disconnecting...');\n\n if (this.audioElement) {\n this.audioElement.pause();\n this.audioElement.srcObject = null;\n }\n\n if (this.dataChannel) {\n this.dataChannel.close();\n this.dataChannel = null;\n }\n\n if (this.pc) {\n // Stop all local tracks (Microphone) to release the device\n this.pc.getSenders().forEach(sender => {\n if (sender.track) {\n sender.track.stop();\n }\n });\n this.pc.close();\n this.pc = null;\n }\n\n this.connected = false;\n this.onDisconnected();\n }\n\n /**\n * Generate unique call ID\n */\n generateCallId(): string {\n return 'web_' + Date.now() + '_' + Math.random().toString(36).substr(2, 8);\n }\n\n /**\n * Send client-side tool execution result back to the AI server.\n * Use this to unblock a 'blocking' execution mode tool.\n */\n sendToolResult(callId: string, result: any): void {\n this.sendEvent('client_tool_result', {\n call_id: callId,\n result: result\n });\n }\n\n /**\n * Silently update the AI's context with what the user is currently viewing.\n * Does NOT interrupt the AI's current speech.\n */\n sendContextUpdate(context: Record<string, any>): void {\n this.sendEvent('client_context_update', { data: { context } });\n }\n\n /**\n * Trigger a client-side action â forces the AI to react to a UI event.\n */\n sendActionTrigger(actionName: string, data: Record<string, any> = {}): void {\n this.sendEvent('client_action_trigger', {\n data: {\n action_name: actionName,\n data\n }\n });\n }\n\n /**\n * Trigger a client-side interrupt â cuts AI audio and forces it to react to a UI event.\n */\n triggerActionInterrupt(): void {\n // DONT pause the audio element! The server simply stops sending packets.\n // Pausing a WebRTC stream's audio element permanently mutes all future backend packets.\n // if (this.audioElement) {\n // this.audioElement.pause();\n // this.audioElement.currentTime = 0;\n // }\n this.sendEvent('action_interrupt');\n console.log('đ [VaniraAI] Triggered client-side action interrupt');\n }\n\n /**\n * Static helper to fetch ICE servers from Hasura\n */\n public static async fetchIceServers(token: string, graphqlEndpoint: string = 'https://coredb.travelr.club/v1/graphql'): Promise<RTCIceServer[]> {\n try {\n const query = `\n query GetIceServers {\n ice_servers(where: {enabled: {_eq: true}}) {\n urls\n username\n credential\n }\n }`;\n\n const response = await fetch(graphqlEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': token,\n },\n body: JSON.stringify({ query }),\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch ICE servers');\n }\n\n const data = await response.json();\n return data.data?.ice_servers || [];\n } catch (error) {\n console.error('[WebRTC] Failed to fetch ICE servers:', error);\n throw error;\n }\n }\n}\n","/**\n * VaniraAI SDK\n * ============\n * A simple, developer-friendly Voice AI client.\n * Hides all WebRTC complexity behind a clean event-emitter API.\n *\n * @example\n * ```ts\n * const client = new VaniraAI({ agentId: 'your-agent-id', token: 'Bearer your-token' });\n * client.on('tool_call', ({ name, arguments: args, tool_call_id, execution_mode }) => {\n * // render your UI component here\n * if (execution_mode === 'blocking') {\n * client.sendToolResult(tool_call_id, { success: true });\n * }\n * });\n * await client.start();\n * ```\n */\n\nimport { WebRTCClient } from './WebRTCClient';\n\n// âââ Types âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\nexport type VaniraAIStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';\n\nexport interface VaniraAIConfig {\n /** Your Vanira agent ID from the dashboard */\n agentId: string;\n /** Bearer token for authentication. Required for ICE server fetching. */\n token?: string;\n /** Override the WebRTC server URL. Auto-detected if omitted. */\n serverUrl?: string;\n /** Override the GraphQL endpoint for config fetching. */\n graphqlEndpoint?: string;\n /** Optional: pre-supply your own ICE servers (skips auto-fetch). */\n iceServers?: RTCIceServer[];\n /** Optional call ID override. Auto-generated if omitted. */\n callId?: string;\n}\n\nexport interface ClientToolCall {\n /** The ref_code of the triggered action */\n name: string;\n /** The mapped payload from client_action_fields */\n arguments: Record<string, any>;\n /** Unique ID for this execution. Required when sending a result back for blocking tools. */\n tool_call_id: string;\n /** Whether the AI is paused waiting for result ('blocking') or keeps talking ('fire_and_forget') */\n execution_mode: 'blocking' | 'fire_and_forget';\n}\n\nexport interface TranscriptionEvent {\n text: string;\n isFinal: boolean;\n}\n\ntype EventMap = {\n /** Fired when WebRTC connection is fully established */\n connected: void;\n /** Fired when the connection is lost or explicitly disconnected */\n disconnected: void;\n /** Fired on connection or protocol error. Payload is an error message string. */\n error: string;\n /** Fired whenever the AI transcribes speech (both interim and final) */\n transcription: TranscriptionEvent;\n /** Fired when the AI triggers a client-side tool (action) */\n tool_call: ClientToolCall;\n /** Fired when a remote media track (like video) is received */\n track: { track: MediaStreamTrack; stream: MediaStream };\n};\n\ntype EventCallback<T> = T extends void ? () => void : (payload: T) => void;\n\n// âââ VaniraAI Class ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\nexport class VaniraAI {\n private config: VaniraAIConfig;\n private _status: VaniraAIStatus = 'idle';\n private client: WebRTCClient | null = null;\n private listeners: Map<string, Set<Function>> = new Map();\n\n constructor(config: VaniraAIConfig) {\n if (!config.agentId) throw new Error('[VaniraAI] agentId is required');\n this.config = config;\n }\n\n // âââ Status ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /** Current connection status */\n get status(): VaniraAIStatus {\n return this._status;\n }\n\n /** Shorthand: true when status is 'connected' */\n get isConnected(): boolean {\n return this._status === 'connected';\n }\n\n // âââ Event Emitter âââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Register an event listener.\n * @param event - Event name\n * @param callback - Handler function\n * @returns `this` for chaining\n */\n on<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n return this;\n }\n\n /**\n * Remove a previously registered event listener.\n * @param event - Event name\n * @param callback - The exact same function reference that was registered\n */\n off<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): this {\n this.listeners.get(event)?.delete(callback);\n return this;\n }\n\n private emit<K extends keyof EventMap>(event: K, payload?: EventMap[K]): void {\n this.listeners.get(event)?.forEach(cb => cb(payload));\n }\n\n // âââ Lifecycle âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Connect to the Voice AI agent and start the call.\n * Requests microphone permission, establishes WebRTC, and opens the data channel.\n */\n async start(): Promise<void> {\n if (this._status === 'connecting' || this._status === 'connected') {\n console.warn('[VaniraAI] Already connecting or connected. Call stop() first.');\n return;\n }\n\n this._setStatus('connecting');\n\n const serverUrl = this.config.serverUrl || this._inferServerUrl();\n\n try {\n this.client = new WebRTCClient({\n serverUrl,\n agentId: this.config.agentId,\n callId: this.config.callId,\n token: this.config.token,\n iceServers: this.config.iceServers,\n onConnected: () => {\n this._setStatus('connected');\n this.emit('connected');\n },\n onDisconnected: () => {\n this._setStatus('disconnected');\n this.emit('disconnected');\n },\n onError: (err: any) => {\n this._setStatus('error');\n this.emit('error', typeof err === 'string' ? err : (err?.message || 'Connection failed'));\n },\n onTranscription: (text: string, isFinal: boolean) => {\n this.emit('transcription', { text, isFinal });\n },\n // @ts-ignore - onClientToolCall is on the dashboard's WebRTCClient; proxy it here\n onClientToolCall: (rawCall: any) => {\n // Normalize the payload (server may send nested or flat)\n const data = rawCall?.data || rawCall;\n const toolCall: ClientToolCall = {\n name: data.name || data.tool_name || '',\n arguments: data.arguments || data.args || {},\n tool_call_id: data.tool_call_id || data.call_id || '',\n execution_mode: data.execution_mode || 'fire_and_forget',\n };\n this.emit('tool_call', toolCall);\n },\n // @ts-ignore - onRemoteTrack is on the dashboard's WebRTCClient; proxy it here\n onRemoteTrack: (track: MediaStreamTrack, stream: MediaStream) => {\n this.emit('track', { track, stream });\n }\n });\n\n await this.client.connect();\n } catch (err: any) {\n this._setStatus('error');\n this.emit('error', err?.message || 'Failed to start call');\n throw err;\n }\n }\n\n /**\n * Disconnect the call and release all resources (microphone, WebRTC connection).\n */\n stop(): void {\n if (this.client) {\n this.client.disconnect();\n this.client = null;\n }\n this._setStatus('disconnected');\n }\n\n // âââ Client â Server Actions âââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Send the result of a **blocking** client-side tool back to the AI.\n * The AI is paused and will resume once it receives this.\n *\n * @param toolCallId - The `tool_call_id` from the `tool_call` event\n * @param result - Arbitrary JSON payload the AI needs to continue\n *\n * @example\n * client.sendToolResult(tool_call_id, { selected_store: 'Store #5' });\n */\n sendToolResult(toolCallId: string, result: Record<string, any>): void {\n this._assertConnected('sendToolResult');\n this.client!.sendToolResult(toolCallId, result);\n }\n\n /**\n * Send an error result for a **blocking** client-side tool.\n * Use when the user cancelled or the UI crashed.\n *\n * @param toolCallId - The `tool_call_id` from the `tool_call` event\n * @param errorMessage - Human-readable error description\n */\n sendToolError(toolCallId: string, errorMessage: string): void {\n this._assertConnected('sendToolError');\n // Fallback: use the generic sendEvent until SDK's WebRTCClient is fully updated\n this.client!.sendEvent('client_tool_result', {\n call_id: toolCallId,\n result: { status: 'error', error: errorMessage }\n });\n }\n\n /**\n * Silently update the AI's context with what the user is currently doing on screen.\n * Does NOT interrupt the AI's current speech.\n *\n * @example\n * client.updateContext({ active_page: 'Checkout', item: 'Nike Shoes', price: 149.99 });\n */\n updateContext(context: Record<string, any>): void {\n this._assertConnected('updateContext');\n this.client!.sendContextUpdate(context);\n }\n\n /**\n * Force the AI to stop speaking and immediately react to a UI event.\n * Use when the user performs a significant action (e.g., clicks a button, opens a page).\n *\n * @param actionName - A descriptive name for the action (e.g., 'user_clicked_cart')\n * @param data - Optional context about the action\n *\n * @example\n * client.triggerInterrupt('user_opened_checkout', { cart_value: 299 });\n */\n triggerInterrupt(actionName: string, data: Record<string, any> = {}): void {\n this._assertConnected('triggerInterrupt');\n this.client!.triggerActionInterrupt();\n this.client!.sendActionTrigger(actionName, data);\n }\n\n // âââ Private helpers âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private _setStatus(status: VaniraAIStatus): void {\n this._status = status;\n }\n\n private _inferServerUrl(): string {\n // Default production server URL â overridable via config.serverUrl\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const env = (typeof import.meta !== 'undefined' && (import.meta as any).env) || {};\n return env.VITE_WEBRTC_SERVER_URL || 'https://in-godspeed.travelr.club';\n }\n\n private _assertConnected(method: string): void {\n if (!this.client || !this.isConnected) {\n throw new Error(`[VaniraAI] Cannot call ${method}() when not connected. Call start() first.`);\n }\n }\n}\n","/**\n * SessionManager\n * ==============\n * Manages per-tab widget sessions using:\n * - sessionStorage â tab_id (unique per browser tab, survives refresh, gone on tab close)\n * - localStorage â session data (prospect_id, chat_id, messages â persists across refreshes)\n * - BroadcastChannel â real-time cross-tab communication\n * - Heartbeat â detect dead tabs (no heartbeat for 15s â tab considered gone)\n *\n * Key behaviours:\n * 1. Each tab gets a unique tab_id.\n * 2. Only one tab is \"active\" at a time (owns the session).\n * 3. When a second tab loads the widget, it detects the conflict and fires onTabConflict().\n * 4. Chat messages, prospect_id and chat_id are persisted so a page refresh restores the session.\n * 5. Tab closure is detected via heartbeat expiry â the next tab to init auto-claims.\n */\n\nexport interface StoredMessage {\n role: 'user' | 'assistant';\n content: string;\n timestamp: number;\n}\n\nexport interface SessionData {\n tabId: string;\n prospectId: string;\n chatId: string | null;\n messages: StoredMessage[];\n lastActive: number; // unix ms â heartbeat timestamp\n}\n\nexport type SessionEvent =\n | 'tab_conflict' // another tab already owns the session\n | 'session_claimed' // this tab successfully claimed the session\n | 'session_restored' // existing session loaded (prospect/chatId/messages recovered)\n | 'tab_took_over' // a different tab stole the session from this one\n | 'session_cleared'; // session was explicitly cleared\n\nexport class SessionManager {\n private tabId: string;\n private sessionKey: string;\n private channelName: string;\n\n private channel: BroadcastChannel | null = null;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private listeners: Map<SessionEvent, Set<Function>> = new Map();\n\n /** How often (ms) the active tab broadcasts its heartbeat */\n private static readonly HEARTBEAT_INTERVAL_MS = 5_000;\n /** How old (ms) a heartbeat must be before we consider the tab dead */\n private static readonly HEARTBEAT_TIMEOUT_MS = 15_000;\n\n constructor(widgetId: string) {\n const safeId = widgetId.replace(/[^a-z0-9_-]/gi, '_');\n this.sessionKey = `vaniraai_session_${safeId}`;\n this.channelName = `vaniraai_channel_${safeId}`;\n this.tabId = this._getOrCreateTabId();\n\n this._setupChannel();\n }\n\n // âââ Public API ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /** Returns this tab's unique ID (stable across same-tab page refreshes). */\n getTabId(): string {\n return this.tabId;\n }\n\n /**\n * Try to claim the session for this tab.\n * Returns true â session claimed (or restored after stale prior tab).\n * Returns false â another live tab already owns the session.\n */\n claimSession(): boolean {\n const existing = this._loadSession();\n\n if (existing) {\n const age = Date.now() - existing.lastActive;\n const isOwnTab = existing.tabId === this.tabId;\n const isStaletab = age > SessionManager.HEARTBEAT_TIMEOUT_MS;\n\n if (isOwnTab) {\n // This tab already owned the session (e.g. page refresh)\n this._startHeartbeat();\n this._emit('session_restored');\n return true;\n }\n\n if (!isStaletab) {\n // A live different tab owns the session â conflict\n this._emit('tab_conflict');\n return false;\n }\n // Stale tab â safe to take over\n }\n\n // No session or stale session â claim it\n const draft: SessionData = existing\n ? { ...existing, tabId: this.tabId, lastActive: Date.now() }\n : { tabId: this.tabId, prospectId: '', chatId: null, messages: [], lastActive: Date.now() };\n\n this._saveSession(draft);\n this._startHeartbeat();\n\n // Notify other tabs (if any) that this tab took over\n this._broadcast({ type: 'took_over', tabId: this.tabId });\n\n const hadPrior = !!(existing?.prospectId);\n this._emit(hadPrior ? 'session_restored' : 'session_claimed');\n return true;\n }\n\n /**\n * Force-claim the session even if another tab owns it.\n * Call this when the user explicitly clicks \"Use here\" in the conflict UI.\n */\n forceClaimSession(): void {\n const existing = this._loadSession();\n const draft: SessionData = existing\n ? { ...existing, tabId: this.tabId, lastActive: Date.now() }\n : { tabId: this.tabId, prospectId: '', chatId: null, messages: [], lastActive: Date.now() };\n\n this._saveSession(draft);\n this._startHeartbeat();\n this._broadcast({ type: 'took_over', tabId: this.tabId });\n this._emit('session_claimed');\n }\n\n /** Save / update the prospect and chat IDs for this session. */\n saveIds(prospectId: string, chatId: string | null): void {\n const session = this._loadSession() ?? this._blankSession();\n this._saveSession({ ...session, prospectId, chatId, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Append a message to the persisted history. */\n pushMessage(role: 'user' | 'assistant', content: string): void {\n const session = this._loadSession() ?? this._blankSession();\n session.messages.push({ role, content, timestamp: Date.now() });\n\n // Keep last 100 messages to avoid bloating localStorage\n if (session.messages.length > 100) {\n session.messages = session.messages.slice(-100);\n }\n\n this._saveSession({ ...session, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Update the content of the last assistant message (streaming). */\n updateLastAssistantMessage(content: string): void {\n const session = this._loadSession() ?? this._blankSession();\n const msgs = session.messages;\n\n // Find the last assistant message that is a placeholder (empty) or the last one\n let found = false;\n for (let i = msgs.length - 1; i >= 0; i--) {\n if (msgs[i].role === 'assistant' && msgs[i].content === '') {\n // Update the placeholder we pushed before streaming started\n msgs[i].content = content;\n found = true;\n break;\n }\n }\n\n if (!found) {\n // Fallback: update the very last assistant message (older approach)\n for (let i = msgs.length - 1; i >= 0; i--) {\n if (msgs[i].role === 'assistant') {\n msgs[i].content = content;\n found = true;\n break;\n }\n }\n }\n\n if (!found) {\n // No assistant message at all â just append\n msgs.push({ role: 'assistant', content, timestamp: Date.now() });\n }\n\n this._saveSession({ ...session, tabId: this.tabId, lastActive: Date.now() });\n }\n\n /** Returns the currently persisted session data (null if none). */\n getSession(): SessionData | null {\n return this._loadSession();\n }\n\n /** Clears ALL session data (prospect_id, chat_id, messages). */\n clearSession(): void {\n localStorage.removeItem(this.sessionKey);\n this._broadcast({ type: 'session_cleared', tabId: this.tabId });\n this._emit('session_cleared');\n }\n\n /** Stop the heartbeat and release resources. Call on widget destroy. */\n destroy(): void {\n this._stopHeartbeat();\n if (this.channel) {\n this.channel.close();\n this.channel = null;\n }\n }\n\n // âââ Event Emitter âââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n on(event: SessionEvent, cb: Function): this {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(cb);\n return this;\n }\n\n off(event: SessionEvent, cb: Function): this {\n this.listeners.get(event)?.delete(cb);\n return this;\n }\n\n // âââ Private âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private _getOrCreateTabId(): string {\n let id = sessionStorage.getItem('vaniraai_tab_id');\n if (!id) {\n id = `tab_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n sessionStorage.setItem('vaniraai_tab_id', id);\n }\n return id;\n }\n\n private _setupChannel(): void {\n if (typeof BroadcastChannel === 'undefined') return; // SSR / old browsers\n\n this.channel = new BroadcastChannel(this.channelName);\n this.channel.onmessage = (ev) => {\n const msg = ev.data as { type: string; tabId: string };\n\n if (msg.tabId === this.tabId) return; // Ignore own messages\n\n if (msg.type === 'took_over') {\n // Another tab stole the session from us\n this._stopHeartbeat();\n this._emit('tab_took_over');\n }\n\n if (msg.type === 'heartbeat') {\n // Another tab is alive â if that tab isn't us, we're in conflict\n // (handled at claimSession time, not runtime)\n }\n\n if (msg.type === 'session_cleared') {\n this._emit('session_cleared');\n }\n };\n }\n\n private _broadcast(data: object): void {\n this.channel?.postMessage(data);\n }\n\n private _startHeartbeat(): void {\n this._stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n const session = this._loadSession();\n if (session && session.tabId === this.tabId) {\n this._saveSession({ ...session, lastActive: Date.now() });\n this._broadcast({ type: 'heartbeat', tabId: this.tabId });\n }\n }, SessionManager.HEARTBEAT_INTERVAL_MS);\n }\n\n private _stopHeartbeat(): void {\n if (this.heartbeatTimer !== null) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n private _loadSession(): SessionData | null {\n try {\n const raw = localStorage.getItem(this.sessionKey);\n return raw ? (JSON.parse(raw) as SessionData) : null;\n } catch {\n return null;\n }\n }\n\n private _saveSession(data: SessionData): void {\n try {\n localStorage.setItem(this.sessionKey, JSON.stringify(data));\n } catch (e) {\n console.warn('[VaniraAI] SessionManager: failed to save session', e);\n }\n }\n\n private _blankSession(): SessionData {\n return {\n tabId: this.tabId,\n prospectId: '',\n chatId: null,\n messages: [],\n lastActive: Date.now(),\n };\n }\n\n private _emit(event: SessionEvent): void {\n this.listeners.get(event)?.forEach(cb => cb());\n }\n}\n","export const MALE_ICON_BASE64 = \"data:image/png;base64,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\";\nexport const FEMALE_ICON_BASE64 = \"data:image/png;base64,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\";\n","export const theme = {\n colors: {\n primary: 'var(--primary, #6366f1)',\n primaryHover: 'var(--primary-hover, #4f46e5)',\n secondary: 'var(--secondary, #4f46e5)',\n bg: 'var(--bg, #ffffff)',\n text: 'var(--text, #1f2937)',\n textMuted: 'var(--text-muted, #6b7280)',\n border: 'var(--border, #e5e7eb)',\n danger: '#ef4444',\n success: '#10b981',\n white: '#ffffff',\n },\n shadows: {\n base: 'var(--shadow, 0 10px 40px rgba(0, 0, 0, 0.1))',\n lg: 'var(--shadow-lg, 0 20px 60px rgba(0, 0, 0, 0.15))',\n },\n transitions: {\n base: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n smooth: 'all 0.5s ease',\n },\n fonts: {\n base: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n }\n};\n\nexport const generateThemeVars = (primary: string, secondary: string | null) => {\n return `\n --primary: ${primary};\n --primary-hover: ${secondary || primary};\n --secondary: ${secondary || primary};\n `;\n};\n","\nimport { keyframes } from './keyframes';\n\nexport const widgetStyles = `\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n box-sizing: border-box;\n \n /* Default Theme Variables */\n --primary: #6366f1;\n --primary-hover: #4f46e5;\n --bg: #ffffff;\n --text: #1f2937;\n --text-muted: #6b7280;\n --border: #e5e7eb;\n --shadow: 0 10px 40px rgba(0, 0, 0, 0.1);\n --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.15);\n }\n\n :host * {\n box-sizing: border-box;\n }\n\n ${keyframes}\n\n .widget-fab {\n position: fixed;\n z-index: 9999;\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--shadow);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: fadeInScale 0.4s ease-out;\n }\n\n .widget-fab:hover {\n transform: scale(1.1);\n box-shadow: var(--shadow-lg);\n }\n\n .widget-fab:active {\n transform: scale(0.95);\n }\n\n .widget-fab svg {\n width: 28px;\n height: 28px;\n color: white;\n }\n\n .widget-panel {\n position: fixed;\n z-index: 10000; /* Higher than FAB */\n background: rgba(255, 255, 255, 0.98);\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n border: 1px solid #d1d5db; /* Solid light gray border for better differentiation */\n border-radius: 28px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n \n /* Default Dimensions */\n width: 400px;\n height: 600px;\n max-height: 90vh;\n max-width: 95vw;\n }\n\n .widget-panel.maximized {\n width: 90vw !important;\n height: 90vh !important;\n top: 5vh !important;\n left: 5vw !important;\n right: 5vw !important;\n bottom: 5vh !important;\n margin: auto;\n }\n\n .widget-panel.maximized {\n width: 800px;\n max-width: calc(100vw - 40px);\n height: 80vh;\n }\n\n .widget-body {\n padding: 0;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n }\n\n .widget-panel.hidden {\n opacity: 0;\n pointer-events: none;\n transform: translateY(20px) scale(0.95);\n }\n/* ... rest of the content is redundant if I use replace or overwrite, but I will overwrite to include everything properly */\n .widget-header {\n background: #1f2937;\n color: white;\n padding: 14px 20px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .widget-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0;\n letter-spacing: 0.3px;\n }\n\n .close-btn {\n background: rgba(255, 255, 255, 0.15);\n border: none;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s;\n backdrop-filter: blur(10px);\n }\n\n .close-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n transform: scale(1.1);\n }\n\n .close-btn.maximize-btn {\n display: flex;\n }\n\n .close-btn svg {\n width: 18px;\n height: 18px;\n color: white;\n flex-shrink: 0;\n }\n\n .widget-body {\n padding: 0;\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n\n .status-indicator {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: #f9fafb;\n border-radius: 12px;\n margin-bottom: 20px;\n }\n\n .status-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #10b981;\n animation: pulse 2s infinite;\n }\n\n .status-text {\n font-size: 14px;\n color: var(--text-muted);\n margin: 0;\n }\n\n .controls {\n display: flex;\n gap: 12px;\n justify-content: center;\n }\n\n .control-btn {\n flex: 1;\n padding: 14px 20px;\n border: none;\n border-radius: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .control-btn svg {\n width: 18px;\n height: 18px;\n }\n\n .control-btn.primary {\n background: #1f2937;\n color: white;\n }\n\n .control-btn.primary:hover {\n background: #374151;\n }\n\n .control-btn.danger {\n background: #ef4444;\n color: white;\n }\n\n .control-btn.danger:hover {\n background: #dc2626;\n }\n\n .voice-mode-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding-bottom: 0;\n }\n\n .central-orb-container {\n position: relative;\n width: 120px;\n height: 120px;\n margin-bottom: 32px;\n cursor: pointer;\n }\n\n .central-orb {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n position: relative;\n z-index: 10;\n box-shadow: 0 10px 30px rgba(99, 102, 241, 0.3);\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .central-orb.active {\n animation: pulse 2s infinite;\n }\n \n .central-orb.idle {\n animation: floatOrb 4s ease-in-out infinite;\n cursor: pointer;\n }\n\n .central-orb.idle:hover {\n transform: scale(1.05);\n }\n\n .central-orb-glow {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 140%;\n height: 140%;\n background: radial-gradient(circle, rgba(99, 102, 241, 0.2) 0%, transparent 70%);\n animation: pulseGlowIdle 4s ease-in-out infinite;\n z-index: -1;\n pointer-events: none;\n }\n\n .central-orb svg {\n width: 24px;\n height: 24px;\n }\n\n .voice-status-text {\n font-size: 20px;\n font-weight: 600;\n color: var(--text);\n margin-bottom: 8px;\n text-align: center;\n }\n\n .voice-status-subtext {\n font-size: 14px;\n color: var(--text-muted);\n text-align: center;\n }\n\n /* Chat Mode Styles */\n .chat-messages {\n flex: 1;\n min-height: 0; /* Crucial for scrolling in flex column */\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: #f9fafb; \n \n /* Scrollbar Styling */\n scrollbar-width: thin;\n scrollbar-color: rgba(156, 163, 175, 0.5) transparent;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background-color: rgba(156, 163, 175, 0.5);\n border-radius: 3px;\n }\n\n .chat-messages::-webkit-scrollbar-thumb:hover {\n background-color: rgba(107, 114, 128, 0.8);\n }\n\n .chat-message {\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user {\n align-self: flex-end;\n background: #000000;\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.assistant {\n align-self: flex-start;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n color: var(--text);\n border-bottom-left-radius: 4px;\n box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n }\n\n .chat-input-area {\n padding: 20px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n display: flex;\n gap: 10px;\n align-items: center;\n background: white;\n z-index: 30;\n position: relative;\n border-bottom-left-radius: 28px;\n border-bottom-right-radius: 28px;\n }\n\n .chat-input {\n flex: 1;\n padding: 14px 20px;\n border: 1px solid #e5e7eb;\n border-radius: 28px;\n font-size: 15px;\n outline: none;\n transition: all 0.3s;\n background: #f3f4f6;\n color: #1f2937;\n }\n\n .chat-input:focus {\n border-color: var(--primary);\n background: white;\n box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);\n }\n\n .chat-send-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--primary);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n flex-shrink: 0;\n }\n\n .chat-send-btn:hover {\n transform: scale(1.05) rotate(-10deg);\n background: var(--primary-hover);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n }\n\n .chat-send-btn:active {\n transform: scale(0.95);\n }\n\n .chat-send-btn svg {\n width: 22px;\n height: 22px;\n color: white;\n margin-left: 2px;\n }\n\n /* Avatar Container */\n .avatar-container {\n background: transparent;\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n }\n \n /* Avatar Video */\n .avatar-video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n /* Voice Button (Simple) in Chat */\n .voice-btn-simple {\n position: relative;\n width: 44px; /* Matching send-btn size for symmetry */\n height: 44px;\n border-radius: 50%;\n border: 1.5px solid #e5e7eb;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.3s;\n overflow: visible;\n background: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .voice-btn-simple:hover {\n transform: scale(1.05);\n background: #f9fafb;\n border-color: #9ca3af;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);\n }\n\n .voice-btn-simple:active {\n animation: clickBounce 0.4s ease-out;\n }\n\n .voice-btn-icon {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #4b5563;\n }\n\n .voice-btn-icon svg {\n width: 20px;\n height: 20px;\n stroke-width: 2px;\n }\n\n /* Utility Classes */\n .absolute { position: absolute; }\n .relative { position: relative; }\n .rounded-full { border-radius: 9999px; }\n .flex { display: flex; }\n .items-center { align-items: center; }\n .justify-center { justify-content: center; }\n .w-full { width: 100%; }\n .h-full { height: 100%; }\n .z-50 { z-index: 50; }\n\n .branding-footer {\n display: flex;\n justify-content: center;\n padding: 4px 0 8px 0;\n background-color: #f9fafb;\n font-size: 10px;\n color: #9ca3af;\n font-weight: 500;\n letter-spacing: 0.025em;\n }\n\n .branding-footer b {\n color: #3b82f6;\n font-weight: 700;\n margin-left: 4px;\n }\n\n @media (max-width: 640px) {\n .widget-panel {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n border-radius: 0 !important;\n margin: 0 !important;\n }\n\n .widget-fab {\n width: 56px;\n height: 56px;\n bottom: 16px !important;\n right: 16px !important;\n }\n\n :host(.vanira-panel-open) .widget-fab {\n display: none !important;\n }\n\n .close-btn.maximize-btn {\n display: none !important;\n }\n\n .widget-header {\n padding: 12px 16px;\n }\n\n .widget-title {\n font-size: 16px;\n }\n\n .chat-input-area {\n padding: 12px;\n padding-bottom: env(safe-area-inset-bottom, 12px);\n }\n }\n`;\n","import { MALE_ICON_BASE64, FEMALE_ICON_BASE64 } from '../icons_data';\n\nexport const icons = {\n phone: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"/>\n </svg>\n `,\n close: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n `,\n mic: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n `,\n micOff: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"/>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\"/>\n <path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\n </svg>\n `,\n waves: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n <path d=\"M2 12c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n <path d=\"M2 18c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\"/>\n </svg>\n `,\n send: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>\n </svg>\n `,\n chat: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n `,\n video: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"23 7 16 12 23 17 23 7\"/>\n <rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"/>\n </svg>\n `,\n talkToAgent: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" opacity=\"0.3\"/>\n <path d=\"M12 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"2\"/>\n </svg>\n `,\n sparkles: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2l2.5 6.5L21 11l-6.5 2.5L12 20l-2.5-6.5L3 11l6.5-2.5L12 2z\"/>\n <path d=\"M18 2l1.5 3.5L23 7l-3.5 1.5L18 12l-1.5-3.5L13 7l3.5-1.5L18 2z\" opacity=\"0.6\"/>\n <path d=\"M6 12l1.5 3.5L11 17l-3.5 1.5L6 22l-1.5-3.5L1 17l3.5-1.5L6 12z\" opacity=\"0.6\"/>\n </svg>\n `,\n audioLines: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 10v3\"/>\n <path d=\"M6 6v11\"/>\n <path d=\"M10 3v18\"/>\n <path d=\"M14 8v7\"/>\n <path d=\"M18 5v13\"/>\n <path d=\"M22 10v3\"/>\n </svg>\n `,\n maximize2: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"15 3 21 3 21 9\"/>\n <polyline points=\"9 21 3 21 3 15\"/>\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/>\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>\n </svg>\n `,\n minimize2: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"4 14 10 14 10 20\"/>\n <polyline points=\"20 10 14 10 14 4\"/>\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\"/>\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>\n </svg>\n `,\n user: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/>\n <circle cx=\"12\" cy=\"7\" r=\"4\"/>\n </svg>\n `,\n keyboard: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" ry=\"2\"/>\n <line x1=\"6\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n <line x1=\"10\" y1=\"8\" x2=\"10\" y2=\"8\"/>\n <line x1=\"14\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"18\" y1=\"8\" x2=\"18\" y2=\"8\"/>\n <line x1=\"6\" y1=\"12\" x2=\"6\" y2=\"12\"/>\n <line x1=\"10\" y1=\"12\" x2=\"10\" y2=\"12\"/>\n <line x1=\"14\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n <line x1=\"18\" y1=\"12\" x2=\"18\" y2=\"12\"/>\n <line x1=\"7\" y1=\"16\" x2=\"17\" y2=\"16\"/>\n </svg>\n `,\n voice_orb: `\n <div style=\"display: flex; align-items: center; justify-content: center; gap: 3px; height: 100%; width: 100%;\">\n <div style=\"width: 3px; height: 10px; background: white; border-radius: 10px; animation: voice-bars-orb 1.2s infinite ease-in-out; animation-delay: 0s;\"></div>\n <div style=\"width: 3px; height: 18px; background: white; border-radius: 10px; animation: voice-bars-orb 1.2s infinite ease-in-out; animation-delay: 0.2s;\"></div>\n <div style=\"width: 3px; height: 14px; background: white; border-radius: 10px; animation: voice-bars-orb 1.2s infinite ease-in-out; animation-delay: 0.4s;\"></div>\n <div style=\"width: 3px; height: 22px; background: white; border-radius: 10px; animation: voice-bars-orb 1.2s infinite ease-in-out; animation-delay: 0.1s;\"></div>\n <div style=\"width: 3px; height: 12px; background: white; border-radius: 10px; animation: voice-bars-orb 1.2s infinite ease-in-out; animation-delay: 0.3s;\"></div>\n </div>\n `\n};\n\nexport const industryIcons: Record<string, string> = {\n automotive: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"/>\n <circle cx=\"7\" cy=\"17\" r=\"2\"/>\n <path d=\"M9 17h6\"/>\n <circle cx=\"17\" cy=\"17\" r=\"2\"/>\n </svg>\n `,\n education: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 10v6M2 10l10-5 10 5-10 5z\"/>\n <path d=\"M6 12v5c3 3 9 3 12 0v-5\"/>\n </svg>\n `,\n finance: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\"/>\n <line x1=\"6\" y1=\"21\" x2=\"6\" y2=\"12\"/>\n <line x1=\"18\" y1=\"21\" x2=\"18\" y2=\"12\"/>\n <line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/>\n <path d=\"M5 6 L12 2 L19 6\"/>\n <line x1=\"6\" y1=\"6\" x2=\"6\" y2=\"12\"/>\n <line x1=\"18\" y1=\"6\" x2=\"18\" y2=\"12\"/>\n <line x1=\"10\" y1=\"21\" x2=\"10\" y2=\"12\"/>\n <line x1=\"14\" y1=\"21\" x2=\"14\" y2=\"12\"/>\n </svg>\n `,\n fitness: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m6.5 6.5 11 11\"/>\n <path d=\"m21 21-1-1\"/>\n <path d=\"m3 3 1 1\"/>\n <path d=\"m18 22 4-4\"/>\n <path d=\"m2 6 4-4\"/>\n <path d=\"m3 10 7-7\"/>\n <path d=\"m14 21 7-7\"/>\n </svg>\n `,\n food: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2\"/>\n <path d=\"M7 2v20\"/>\n <path d=\"M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7\"/>\n </svg>\n `,\n government: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"/>\n <path d=\"M9 22v-4h6v4\"/>\n <path d=\"M8 6h.01\"/>\n <path d=\"M16 6h.01\"/>\n <path d=\"M12 6h.01\"/>\n <path d=\"M12 10h.01\"/>\n <path d=\"M12 14h.01\"/>\n <path d=\"M16 10h.01\"/>\n <path d=\"M16 14h.01\"/>\n <path d=\"M8 10h.01\"/>\n <path d=\"M8 14h.01\"/>\n </svg>\n `,\n healthcare: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 12h-4l-3 9L9 3l-3 9H2\"/>\n </svg>\n `,\n travel: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 2a5 5 0 0 1 5 5c0 4.5-9 13-9 13S3 11.5 3 7a5 5 0 0 1 10 0Z\"/>\n <circle cx=\"12\" cy=\"7\" r=\"2\"/>\n </svg>\n `,\n legal: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1z\"/>\n <path d=\"m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1z\"/>\n <path d=\"M7 21h10\"/>\n <path d=\"M12 3v18\"/>\n <path d=\"M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2\"/>\n </svg>\n `,\n manufacturing: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7 5V8l-7 5V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\"/>\n <path d=\"M17 18h1\"/>\n <path d=\"M12 18h1\"/>\n <path d=\"M7 18h1\"/>\n </svg>\n `,\n media: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"20\" height=\"20\" x=\"2\" y=\"2\" rx=\"2.18\" ry=\"2.18\"/>\n <line x1=\"7\" x2=\"7\" y1=\"2\" y2=\"22\"/>\n <line x1=\"17\" x2=\"17\" y1=\"2\" y2=\"22\"/>\n <line x1=\"2\" x2=\"22\" y1=\"12\" y2=\"12\"/>\n <line x1=\"2\" x2=\"7\" y1=\"7\" y2=\"7\"/>\n <line x1=\"2\" x2=\"7\" y1=\"17\" y2=\"17\"/>\n <line x1=\"17\" x2=\"22\" y1=\"17\" y2=\"17\"/>\n <line x1=\"17\" x2=\"22\" y1=\"7\" y2=\"7\"/>\n </svg>\n `,\n nonprofit: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\"/>\n </svg>\n `,\n professional: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"7\" rx=\"2\" ry=\"2\"/>\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\"/>\n </svg>\n `,\n realestate: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\n </svg>\n `,\n retail: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/>\n <path d=\"M3 6h18\"/>\n <path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n `,\n technology: `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"18\" height=\"12\" x=\"3\" y=\"4\" rx=\"2\" ry=\"2\"/>\n <line x1=\"2\" x2=\"22\" y1=\"20\" y2=\"20\"/>\n </svg>\n `\n};\n\nexport const widgetIcons: Record<string, string> = {\n ...industryIcons,\n default_chat: icons.chat,\n default_voice: icons.mic,\n voice_orb: icons.voice_orb,\n male: `<img src=\"${MALE_ICON_BASE64}\" style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;\" />`,\n female: `<img src=\"${FEMALE_ICON_BASE64}\" style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;\" />`,\n};\n\nObject.entries(industryIcons).forEach(([name, svg]) => {\n widgetIcons[`male_${name} `] = `\n < div style = \"position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: white; border-radius: 50%;\" >\n <div style=\"width: 60%; height: 60%; color: #6366f1;\" >\n ${svg}\n</div>\n < div style = \"\nposition: absolute;\nbottom: -2px;\nright: -2px;\nwidth: 28px;\nheight: 28px;\nbackground: white;\nborder - radius: 50 %;\nborder: 2px solid white;\nbox - shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\noverflow: hidden;\n\">\n < img src = \"${MALE_ICON_BASE64}\" style = \"width: 100%; height: 100%; object-fit: cover;\" />\n </div>\n </div>\n `;\n\n widgetIcons[`female_${name} `] = `\n < div style = \"position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: white; border-radius: 50%;\" >\n <div style=\"width: 60%; height: 60%; color: #6366f1;\" >\n ${svg}\n</div>\n < div style = \"\nposition: absolute;\nbottom: -2px;\nright: -2px;\nwidth: 28px;\nheight: 28px;\nbackground: white;\nborder - radius: 50 %;\nborder: 2px solid white;\nbox - shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\noverflow: hidden;\n\">\n < img src = \"${FEMALE_ICON_BASE64}\" style = \"width: 100%; height: 100%; object-fit: cover;\" />\n </div>\n </div>\n `;\n});\n\nexport * from './theme';\nexport * from './widget.css';\nexport * from './keyframes';\n","\nimport { icons } from '../styles';\n\nexport class FloatingButton {\n private element: HTMLButtonElement;\n private iconContainer: HTMLElement;\n\n private isDragging = false;\n private startX = 0;\n private startY = 0;\n private currentX = 0;\n private currentY = 0;\n private hasMoved = false;\n\n constructor(\n private onClick: () => void,\n initialIcon: string = icons.chat\n ) {\n this.element = document.createElement('button');\n this.element.className = 'widget-fab';\n \n // Use pointer events for better cross-device support\n this.element.onpointerdown = this.dragStart.bind(this);\n \n this.iconContainer = document.createElement('div');\n this.iconContainer.style.display = 'flex';\n this.iconContainer.style.alignItems = 'center';\n this.iconContainer.style.justifyContent = 'center';\n this.iconContainer.style.width = '100%';\n this.iconContainer.style.height = '100%';\n this.iconContainer.innerHTML = initialIcon;\n\n this.element.appendChild(this.iconContainer);\n }\n\n private dragStart(e: PointerEvent) {\n const rect = this.element.getBoundingClientRect();\n this.isDragging = true;\n this.hasMoved = false;\n this.startX = e.clientX - rect.left;\n this.startY = e.clientY - rect.top;\n \n this.element.setPointerCapture(e.pointerId);\n this.element.style.transition = 'none';\n this.element.style.cursor = 'grabbing';\n\n const onPointerMove = (moveEvent: PointerEvent) => {\n if (!this.isDragging) return;\n \n this.hasMoved = true;\n this.currentX = moveEvent.clientX - this.startX;\n this.currentY = moveEvent.clientY - this.startY;\n\n // Boundary checks\n const maxX = window.innerWidth - this.element.offsetWidth;\n const maxY = window.innerHeight - this.element.offsetHeight;\n \n this.currentX = Math.max(0, Math.min(this.currentX, maxX));\n this.currentY = Math.max(0, Math.min(this.currentY, maxY));\n\n this.element.style.left = `${this.currentX}px`;\n this.element.style.top = `${this.currentY}px`;\n this.element.style.right = 'auto';\n this.element.style.bottom = 'auto';\n };\n\n const onPointerUp = (upEvent: PointerEvent) => {\n this.isDragging = false;\n if (this.element.hasPointerCapture(upEvent.pointerId)) {\n this.element.releasePointerCapture(upEvent.pointerId);\n }\n this.element.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)';\n this.element.style.cursor = 'pointer';\n\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n\n // If it was just a click (no movement), trigger the onClick\n if (!this.hasMoved) {\n this.onClick();\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n }\n\n public getElement(): HTMLButtonElement {\n return this.element;\n }\n\n public setIcon(iconHtml: string) {\n this.iconContainer.innerHTML = iconHtml;\n }\n\n public setPosition(positionStyle: string) {\n // Parse initial position\n const styles = positionStyle.split(';').filter(s => s.trim());\n styles.forEach(s => {\n const [prop, val] = s.split(':').map(str => str.trim());\n if (prop && val) {\n (this.element.style as any)[prop] = val;\n \n // If initializing with right/bottom, convert to left/top for drag consistency later\n // but for now just set them.\n }\n });\n this.element.style.position = 'fixed';\n }\n\n public static get styles() {\n return `\n .widget-fab {\n position: fixed;\n z-index: 9999;\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--shadow);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: fadeInScale 0.4s ease-out;\n touch-action: none;\n padding: 0;\n margin: 0;\n }\n\n .widget-fab:hover {\n transform: scale(1.05);\n box-shadow: var(--shadow-lg);\n }\n\n .widget-fab:active {\n transform: scale(0.95);\n }\n\n .widget-fab svg {\n width: 26px;\n height: 26px;\n color: white;\n }\n `;\n }\n}\n","\nimport { icons } from '../styles';\n\nexport class Panel {\n private element: HTMLDivElement;\n private header: HTMLDivElement;\n private titleElement: HTMLHeadingElement;\n private contentArea: HTMLDivElement;\n private maximizeBtn: HTMLButtonElement;\n private closeBtn: HTMLButtonElement;\n\n private isMaximized = false;\n\n constructor(\n private onClose: () => void,\n private title: string = 'Assistant'\n ) {\n this.element = document.createElement('div');\n this.element.className = 'widget-panel hidden';\n\n // Header\n this.header = document.createElement('div');\n this.header.className = 'widget-header';\n\n this.titleElement = document.createElement('h3');\n this.titleElement.className = 'widget-title';\n this.titleElement.textContent = this.title;\n\n const controls = document.createElement('div');\n controls.style.display = 'flex';\n controls.style.alignItems = 'center';\n controls.style.gap = '8px';\n controls.style.marginLeft = 'auto';\n\n this.maximizeBtn = document.createElement('button');\n this.maximizeBtn.className = 'close-btn maximize-btn';\n this.maximizeBtn.innerHTML = icons.maximize2;\n this.maximizeBtn.onclick = () => this.toggleMaximize();\n\n this.closeBtn = document.createElement('button');\n this.closeBtn.className = 'close-btn';\n this.closeBtn.innerHTML = icons.close;\n this.closeBtn.onclick = this.onClose;\n\n controls.appendChild(this.maximizeBtn);\n controls.appendChild(this.closeBtn);\n\n this.header.appendChild(controls);\n\n // Content Area\n this.contentArea = document.createElement('div');\n this.contentArea.className = 'widget-body';\n this.contentArea.style.flex = '1';\n this.contentArea.style.display = 'flex';\n this.contentArea.style.flexDirection = 'column';\n this.contentArea.style.overflow = 'hidden';\n this.contentArea.style.padding = '0'; // Let children handle padding if needed\n\n this.element.appendChild(this.header);\n this.element.appendChild(this.contentArea);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setContent(content: HTMLElement) {\n this.contentArea.innerHTML = '';\n this.contentArea.appendChild(content);\n }\n\n public addToContent(element: HTMLElement) {\n this.contentArea.appendChild(element);\n }\n\n public setTitle(title: string) {\n this.titleElement.textContent = title;\n }\n\n public open(position: { bottom?: string, right?: string, top?: string, left?: string }) {\n this.element.classList.remove('hidden');\n // Apply positioning logic here or via CSS classes\n // For now, we assume fixed positioning managed by parent styled classes, \n // or we set style directlly.\n Object.assign(this.element.style, position);\n }\n\n public close() {\n this.element.classList.add('hidden');\n }\n\n public toggleMaximize() {\n this.isMaximized = !this.isMaximized;\n if (this.isMaximized) {\n this.element.classList.add('maximized');\n this.maximizeBtn.innerHTML = icons.minimize2;\n } else {\n this.element.classList.remove('maximized');\n this.maximizeBtn.innerHTML = icons.maximize2;\n }\n }\n\n public static get styles() {\n return `\n /* Panel Styles handled in widget.css.ts mostly, specific overrides here */\n `;\n }\n}\n","\nimport { icons } from '../styles';\n\nexport class VoiceOverlay {\n private element: HTMLDivElement;\n\n // Layout\n private contentContainer: HTMLDivElement;\n\n // Orb / visual\n private orbWrapper: HTMLDivElement; // w-52 h-52 centered circle area\n private connectingRing: HTMLDivElement; // spinning conic-gradient ring (connecting)\n private errorRing: HTMLDivElement; // red ring (error)\n private waveLayers: HTMLDivElement[] = []; // active wave layers\n private outerGlow: HTMLDivElement;\n private wave1: HTMLDivElement;\n private wave2: HTMLDivElement;\n private wave3: HTMLDivElement;\n private centerIcon: HTMLDivElement; // dark circle with phone/spinner\n\n // Status area\n private statusArea: HTMLDivElement;\n private connectingLabel: HTMLDivElement;\n private connectedBadge: HTMLDivElement;\n private errorLabel: HTMLDivElement;\n private retryBtn: HTMLButtonElement;\n private timerEl: HTMLDivElement;\n\n // Transcription\n private transcriptionEl: HTMLDivElement;\n\n // Footer\n private hangupBtn: HTMLButtonElement;\n\n // Avatar\n private videoContainer: HTMLDivElement;\n private videoElement: HTMLVideoElement;\n private prepareBadge: HTMLDivElement;\n private statusBadge: HTMLDivElement;\n\n private startTime: number | null = null;\n private timerInterval: any = null;\n private isAvatarMode: boolean = false;\n private callStartedAt: number | null = null; // wall-clock ms when call started\n\n constructor(\n private onHangup: () => void,\n private primaryColor: string = '#6366f1',\n private secondaryColor: string = '#a855f7',\n private onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n // ââ ROOT ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.element = document.createElement('div');\n this.element.id = 'voice-active-overlay';\n this.element.style.cssText = `\n position: absolute; top: 0; left: 0; width: 100%; height: 100%;\n background: #f9fafb;\n pointer-events: auto;\n z-index: 60;\n display: none;\n flex-direction: column;\n align-items: center;\n `;\n\n // ââ CONTENT AREA ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.contentContainer = document.createElement('div');\n this.contentContainer.style.cssText = `\n flex: 1; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n width: 100%; padding: 24px 20px 12px;\n `;\n\n // ââ AVATAR VIDEO âââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.videoContainer = document.createElement('div');\n this.videoContainer.style.cssText = `\n display: none; position: relative; width: 100%; max-width: 260px;\n aspect-ratio: 1/1; margin-bottom: 16px; overflow: hidden;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25), 0 0 0 1px rgba(17,24,39,0.05);\n `;\n this.videoElement = document.createElement('video');\n this.videoElement.style.cssText = 'width:100%; height:100%; object-fit:cover; background:black;';\n this.videoElement.autoplay = true;\n this.videoElement.playsInline = true;\n this.videoElement.muted = true;\n this.videoContainer.appendChild(this.videoElement);\n this.contentContainer.appendChild(this.videoContainer);\n\n // ââ ORB WRAPPER ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.orbWrapper = document.createElement('div');\n this.orbWrapper.style.cssText = `\n position: relative; width: 208px; height: 208px;\n display: flex; align-items: center; justify-content: center;\n margin: 8px 0;\n `;\n\n // Connecting: spinning conic-gradient ring\n this.connectingRing = document.createElement('div');\n this.connectingRing.style.cssText = `\n position: absolute; width: 180px; height: 180px;\n border-radius: 50%;\n background: conic-gradient(from 0deg, #94a3b8, #cbd5e1, #e2e8f0, #94a3b8);\n animation: spin 3s linear infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.connectingRing);\n\n // Error: red conic ring\n this.errorRing = document.createElement('div');\n this.errorRing.style.cssText = `\n position: absolute; width: 180px; height: 180px;\n border-radius: 50%;\n background: conic-gradient(from 0deg, #ef4444, #f87171, #fca5a5, #ef4444);\n animation: pulse 1.5s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.errorRing);\n\n // Wave layers (connected state)\n this.outerGlow = document.createElement('div');\n this.outerGlow.style.cssText = `\n position: absolute; inset: 0; border-radius: 50%;\n background: radial-gradient(circle, ${this.primaryColor}20 0%, transparent 70%);\n animation: pulse 2s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.outerGlow);\n\n this.wave1 = document.createElement('div');\n this.wave1.style.cssText = `\n position: absolute; width: 200px; height: 200px; border-radius: 50%;\n background: conic-gradient(from 0deg, ${this.primaryColor}, ${this.secondaryColor}, #fcd34d, ${this.primaryColor});\n animation: wave-rotate-1 8s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave1);\n\n this.wave2 = document.createElement('div');\n this.wave2.style.cssText = `\n position: absolute; width: 180px; height: 180px; border-radius: 50%;\n background: conic-gradient(from 60deg, ${this.secondaryColor}, #fcd34d, ${this.primaryColor}, ${this.secondaryColor});\n opacity: 0.8;\n animation: wave-rotate-2 6s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave2);\n\n this.wave3 = document.createElement('div');\n this.wave3.style.cssText = `\n position: absolute; width: 160px; height: 160px; border-radius: 50%;\n background: conic-gradient(from 120deg, #fcd34d, ${this.primaryColor}, ${this.secondaryColor}, #fcd34d);\n opacity: 0.9;\n animation: wave-rotate-3 4s ease-in-out infinite;\n display: none;\n `;\n this.orbWrapper.appendChild(this.wave3);\n\n // Inner shine (connected only)\n const shine = document.createElement('div');\n shine.style.cssText = `\n position: absolute; width: 140px; height: 140px; border-radius: 50%;\n background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4) 0%, transparent 60%);\n display: none; pointer-events: none;\n `;\n shine.id = 'voice-shine';\n this.orbWrapper.appendChild(shine);\n\n this.waveLayers = [this.outerGlow, this.wave1, this.wave2, this.wave3, shine];\n\n // Center dark circle with phone/spinner icon\n this.centerIcon = document.createElement('div');\n this.centerIcon.style.cssText = `\n position: relative; z-index: 10;\n width: 56px; height: 56px; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n background: #374151;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.15), 0 8px 10px -6px rgba(0,0,0,0.1);\n color: white;\n `;\n this.centerIcon.innerHTML = icons.phone;\n const phoneSvg = this.centerIcon.querySelector('svg');\n if (phoneSvg) { phoneSvg.style.width = '20px'; phoneSvg.style.height = '20px'; }\n this.orbWrapper.appendChild(this.centerIcon);\n\n this.contentContainer.appendChild(this.orbWrapper);\n\n // ââ STATUS AREA ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.statusArea = document.createElement('div');\n this.statusArea.style.cssText = 'display:flex; flex-direction:column; align-items:center; gap:8px; margin-top:8px;';\n\n // Connecting label\n this.connectingLabel = document.createElement('p');\n this.connectingLabel.textContent = 'Connecting...';\n this.connectingLabel.style.cssText = 'font-size:11px; font-weight:600; color:#9ca3af; text-transform:uppercase; letter-spacing:0.1em; margin:0; display:none;';\n this.statusArea.appendChild(this.connectingLabel);\n\n // Connected badge\n this.connectedBadge = document.createElement('div');\n this.connectedBadge.style.cssText = `\n display: none; align-items: center; gap: 8px;\n padding: 5px 16px; background: #f0fdf4;\n border-radius: 9999px; border: 1px solid #dcfce7;\n `;\n const greenDot = document.createElement('div');\n greenDot.style.cssText = 'width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite; box-shadow:0 0 8px rgba(34,197,94,0.6);';\n const connectedText = document.createElement('span');\n connectedText.textContent = 'Connected';\n connectedText.style.cssText = 'font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;';\n this.connectedBadge.appendChild(greenDot);\n this.connectedBadge.appendChild(connectedText);\n this.statusArea.appendChild(this.connectedBadge);\n\n // Timer\n this.timerEl = document.createElement('div');\n this.timerEl.textContent = '00:00';\n this.timerEl.style.cssText = 'font-size:13px; color:#6b7280; font-variant-numeric:tabular-nums; display:none;';\n this.statusArea.appendChild(this.timerEl);\n\n // Error label + retry\n this.errorLabel = document.createElement('p');\n this.errorLabel.textContent = 'Connection failed';\n this.errorLabel.style.cssText = 'font-size:12px; color:#ef4444; font-weight:500; margin:0; display:none;';\n this.statusArea.appendChild(this.errorLabel);\n\n this.retryBtn = document.createElement('button');\n this.retryBtn.textContent = 'âģ Retry Connection';\n this.retryBtn.style.cssText = `\n display:none; padding:6px 14px; background:#f3f4f6; border:none;\n border-radius:9999px; font-size:12px; font-weight:500; color:#374151;\n cursor:pointer; transition:background 0.2s; pointer-events:auto;\n `;\n this.retryBtn.onmouseover = () => this.retryBtn.style.background = '#e5e7eb';\n this.retryBtn.onmouseout = () => this.retryBtn.style.background = '#f3f4f6';\n this.statusArea.appendChild(this.retryBtn);\n\n // Avatar preparing / connected badges\n this.prepareBadge = document.createElement('p');\n this.prepareBadge.style.cssText = 'display:none; font-size:11px; font-weight:600; color:#a855f7; text-transform:uppercase; letter-spacing:0.1em; margin:0; animation:pulse 1.5s infinite;';\n this.statusArea.appendChild(this.prepareBadge);\n\n this.statusBadge = document.createElement('div');\n this.statusBadge.style.cssText = 'display:none; align-items:center; gap:8px; padding:5px 16px; background:#f0fdf4; border-radius:9999px; border:1px solid #dcfce7;';\n const sDot = document.createElement('div');\n sDot.style.cssText = 'width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite;';\n const sTxt = document.createElement('span');\n sTxt.textContent = 'Connected';\n sTxt.style.cssText = 'font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;';\n this.statusBadge.appendChild(sDot);\n this.statusBadge.appendChild(sTxt);\n this.statusArea.appendChild(this.statusBadge);\n\n this.contentContainer.appendChild(this.statusArea);\n\n // ââ TRANSCRIPTION ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n this.transcriptionEl = document.createElement('div');\n this.transcriptionEl.style.cssText = `\n margin-top: 14px; padding: 0 20px; text-align: center;\n min-height: 36px; max-height: 72px; overflow-y: auto;\n font-size: 13px; color: #9ca3af; font-style: italic;\n `;\n this.contentContainer.appendChild(this.transcriptionEl);\n\n this.element.appendChild(this.contentContainer);\n\n // ââ FOOTER: always-on End Call âââââââââââââââââââââââââââââââââââââââââââ\n const footer = document.createElement('div');\n footer.style.cssText = 'width:100%; display:flex; justify-content:center; padding:0 20px 20px; pointer-events:auto;';\n\n this.hangupBtn = document.createElement('button');\n this.hangupBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"transform:rotate(135deg);flex-shrink:0;\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.18h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.77a16 16 0 0 0 6.29 6.29l.87-.87a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z\"/></svg> End Call`;\n this.hangupBtn.style.cssText = `\n display: flex; align-items: center; gap: 8px;\n padding: 10px 28px; background: #ef4444; color: white;\n border: none; border-radius: 9999px; font-size: 14px; font-weight: 500;\n cursor: pointer; pointer-events: auto;\n transition: background-color 0.2s;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);\n `;\n this.hangupBtn.onmouseover = () => this.hangupBtn.style.backgroundColor = '#dc2626';\n this.hangupBtn.onmouseout = () => this.hangupBtn.style.backgroundColor = '#ef4444';\n this.hangupBtn.onclick = () => {\n const duration = this.callStartedAt ? Date.now() - this.callStartedAt : 0;\n const startedAt = this.callStartedAt ?? Date.now();\n if (this.onCallEnded && duration > 0) {\n this.onCallEnded(duration, startedAt);\n }\n this.onHangup();\n };\n\n footer.appendChild(this.hangupBtn);\n this.element.appendChild(footer);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setMode(mode: 'voice' | 'avatar') {\n this.isAvatarMode = (mode === 'avatar');\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.isAvatarMode = true;\n if (track.kind === 'video' && this.videoElement) {\n const stream = new MediaStream([track]);\n this.videoElement.srcObject = stream;\n this.videoContainer.style.display = 'block';\n this.orbWrapper.style.display = 'none';\n this.connectingLabel.style.display = 'none';\n this.timerEl.style.display = 'none';\n\n this.videoElement.onplaying = () => {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n };\n this.videoElement.play().catch(e => console.warn('Video play error', e));\n }\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n if (status === 'connecting') {\n // CENTER ICON: spinner while connecting\n this.centerIcon.style.background = '#4b5563';\n this.centerIcon.innerHTML = `<div style=\"width:18px;height:18px;border:2px solid #ffffff;border-top-color:transparent;border-radius:50%;animation:spin 1s linear infinite;\"></div>`;\n\n if (this.isAvatarMode) {\n this.videoContainer.style.display = 'block';\n this.orbWrapper.style.display = 'none';\n this.prepareBadge.textContent = 'CONNECTING...';\n this.prepareBadge.style.display = 'block';\n this.statusBadge.style.display = 'none';\n this.connectingLabel.style.display = 'none';\n } else {\n this.orbWrapper.style.display = 'flex';\n this.videoContainer.style.display = 'none';\n this.connectingRing.style.display = 'block';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'block';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n }\n this.stopTimer();\n\n } else if (status === 'connected') {\n // CENTER ICON: phone\n this.centerIcon.style.background = '#1f2937';\n this.centerIcon.innerHTML = icons.phone;\n const svg = this.centerIcon.querySelector('svg');\n if (svg) { svg.style.cssText = 'width:20px;height:20px;'; }\n\n if (this.isAvatarMode) {\n const isPlaying = this.videoElement && !this.videoElement.paused && this.videoElement.readyState > 2;\n if (isPlaying) {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n } else {\n this.prepareBadge.textContent = 'AGENT IS ON THE WAY...';\n this.prepareBadge.style.display = 'block';\n setTimeout(() => {\n if (this.prepareBadge.style.display !== 'none') {\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'flex';\n }\n }, 5000);\n }\n } else {\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'flex');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'flex';\n this.timerEl.style.display = 'block';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n this.startTimer();\n }\n\n } else if (status === 'error') {\n this.centerIcon.style.background = '#dc2626';\n this.centerIcon.innerHTML = icons.phone;\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'block';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'block';\n this.retryBtn.style.display = 'block';\n this.stopTimer();\n }\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.transcriptionEl.textContent = `\"${text}\"`;\n this.transcriptionEl.style.color = isFinal ? '#1f2937' : '#9ca3af';\n this.transcriptionEl.style.fontStyle = isFinal ? 'normal' : 'italic';\n }\n\n public show() {\n this.callStartedAt = Date.now();\n this.element.style.display = 'flex';\n this.setStatus('connecting');\n }\n\n public hide() {\n this.element.style.display = 'none';\n this.reset();\n }\n\n public reset() {\n if (this.videoElement) this.videoElement.srcObject = null;\n this.isAvatarMode = false;\n this.callStartedAt = null;\n this.stopTimer();\n this.transcriptionEl.textContent = '';\n\n // Reset to defaults\n this.videoContainer.style.display = 'none';\n this.orbWrapper.style.display = 'flex';\n this.connectingRing.style.display = 'none';\n this.errorRing.style.display = 'none';\n this.waveLayers.forEach(l => l.style.display = 'none');\n this.connectingLabel.style.display = 'none';\n this.connectedBadge.style.display = 'none';\n this.timerEl.style.display = 'none';\n this.errorLabel.style.display = 'none';\n this.retryBtn.style.display = 'none';\n this.prepareBadge.style.display = 'none';\n this.statusBadge.style.display = 'none';\n this.centerIcon.style.background = '#374151';\n this.centerIcon.innerHTML = icons.phone;\n const svg = this.centerIcon.querySelector('svg');\n if (svg) { svg.style.cssText = 'width:20px;height:20px;'; }\n }\n\n private startTimer() {\n if (this.timerInterval) clearInterval(this.timerInterval);\n this.startTime = Date.now();\n this.timerEl.textContent = '00:00';\n this.timerInterval = setInterval(() => {\n if (!this.startTime) return;\n const diff = Math.floor((Date.now() - this.startTime) / 1000);\n const mins = Math.floor(diff / 60).toString().padStart(2, '0');\n const secs = (diff % 60).toString().padStart(2, '0');\n this.timerEl.textContent = `${mins}:${secs}`;\n }, 1000);\n }\n\n private stopTimer() {\n if (this.timerInterval) { clearInterval(this.timerInterval); this.timerInterval = null; }\n this.timerEl.textContent = '';\n }\n\n public setFullScreen(enable: boolean) {\n if (enable) {\n this.videoContainer.style.position = 'absolute';\n this.videoContainer.style.top = '0';\n this.videoContainer.style.left = '0';\n this.videoContainer.style.width = '100%';\n this.videoContainer.style.height = '100%';\n this.videoContainer.style.maxWidth = 'none';\n this.videoContainer.style.borderRadius = '0';\n this.videoContainer.style.margin = '0';\n this.videoContainer.style.zIndex = '0';\n } else {\n this.videoContainer.style.position = 'relative';\n this.videoContainer.style.width = '100%';\n this.videoContainer.style.maxWidth = '260px';\n this.videoContainer.style.height = 'auto';\n this.videoContainer.style.aspectRatio = '1/1';\n this.videoContainer.style.borderRadius = '16px';\n this.videoContainer.style.marginBottom = '16px';\n }\n }\n}\n","\nimport { icons } from '../styles';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport class ChatWindow {\n private element: HTMLDivElement;\n private messageContainer: HTMLDivElement;\n private inputArea: HTMLDivElement;\n private input: HTMLInputElement;\n private sendBtn: HTMLButtonElement;\n private typingIndicator: HTMLDivElement | null = null;\n\n constructor(\n private onSend: (message: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n this.element.style.flex = '1';\n this.element.style.overflow = 'hidden';\n this.element.style.minHeight = '0'; // Crucial for nested flex scrolling\n\n // Messages Area\n this.messageContainer = document.createElement('div');\n this.messageContainer.className = 'chat-messages';\n\n // Input Area\n this.inputArea = document.createElement('div');\n this.inputArea.className = 'chat-input-area';\n\n this.input = document.createElement('input');\n this.input.className = 'chat-input';\n this.input.placeholder = 'Type a message...';\n this.input.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') this.handleSend();\n });\n\n this.sendBtn = document.createElement('button');\n this.sendBtn.className = 'chat-send-btn';\n this.sendBtn.innerHTML = icons.send;\n this.sendBtn.onclick = () => this.handleSend();\n\n this.inputArea.appendChild(this.input);\n this.inputArea.appendChild(this.sendBtn);\n\n // Branding Area\n const brandingArea = document.createElement('div');\n brandingArea.className = 'branding-footer';\n brandingArea.innerHTML = `Technology Powered by <b>Vanira AI</b>`;\n\n this.element.appendChild(this.messageContainer);\n this.element.appendChild(this.inputArea);\n this.element.appendChild(brandingArea);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n private formatTime(date: Date = new Date()): string {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n\n public addMessage(role: 'user' | 'assistant', content: string, timestamp?: number) {\n const wrapper = document.createElement('div');\n wrapper.style.cssText = `\n display: flex;\n flex-direction: column;\n align-items: ${role === 'user' ? 'flex-end' : 'flex-start'};\n margin-bottom: 2px;\n `;\n\n const msgDiv = document.createElement('div');\n msgDiv.className = `chat-message ${role}`;\n msgDiv.textContent = content;\n wrapper.appendChild(msgDiv);\n\n const ts = document.createElement('span');\n ts.style.cssText = `\n font-size: 10px;\n color: #9ca3af;\n margin: 2px 4px 6px;\n display: block;\n `;\n ts.textContent = this.formatTime(timestamp ? new Date(timestamp) : undefined);\n wrapper.appendChild(ts);\n\n this.messageContainer.appendChild(wrapper);\n this.scrollToBottom();\n }\n\n public updateLastAssistantMessage(content: string) {\n // The last child is the wrapper div; the message is its first child\n const lastWrapper = this.messageContainer.lastElementChild as HTMLElement;\n if (lastWrapper) {\n const lastMsg = lastWrapper.querySelector('.chat-message.assistant') as HTMLElement;\n if (lastMsg) {\n lastMsg.textContent = content;\n this.scrollToBottom();\n return;\n }\n }\n this.addMessage('assistant', content);\n }\n\n public addButtons(buttons: Array<{ title: string; payload: string }>) {\n const buttonsContainer = document.createElement('div');\n buttonsContainer.className = 'chat-buttons-container';\n buttonsContainer.style.display = 'flex';\n buttonsContainer.style.flexWrap = 'wrap';\n buttonsContainer.style.gap = '8px';\n buttonsContainer.style.marginTop = '8px';\n buttonsContainer.style.marginBottom = '12px';\n buttonsContainer.style.justifyContent = 'flex-start';\n\n buttons.forEach(btn => {\n const buttonEl = document.createElement('button');\n buttonEl.className = 'chat-suggestion-chip';\n buttonEl.textContent = btn.title;\n // Basic styles if CSS class not defined\n buttonEl.style.padding = '6px 12px';\n buttonEl.style.borderRadius = '16px';\n buttonEl.style.border = '1px solid #e5e7eb';\n buttonEl.style.backgroundColor = 'white';\n buttonEl.style.fontSize = '12px';\n buttonEl.style.color = '#4b5563';\n buttonEl.style.cursor = 'pointer';\n buttonEl.style.transition = 'all 0.2s';\n\n buttonEl.onmouseenter = () => {\n buttonEl.style.backgroundColor = '#f3f4f6';\n buttonEl.style.borderColor = '#d1d5db';\n };\n buttonEl.onmouseleave = () => {\n buttonEl.style.backgroundColor = 'white';\n buttonEl.style.borderColor = '#e5e7eb';\n };\n\n buttonEl.onclick = () => {\n this.handleSend(btn.payload);\n };\n\n buttonsContainer.appendChild(buttonEl);\n });\n\n // Append to the last message if probable? Or just append.\n // Usually buttons belong to the last assistant message.\n // For simplicity, append to container.\n this.messageContainer.appendChild(buttonsContainer);\n this.scrollToBottom();\n }\n\n private handleSend(overrideText?: string) {\n const text = overrideText || this.input.value.trim();\n if (!text) return;\n\n this.onSend(text);\n if (!overrideText) {\n this.input.value = '';\n }\n }\n\n public setTyping(isTyping: boolean) {\n if (this.typingIndicator) {\n this.typingIndicator.remove();\n this.typingIndicator = null;\n }\n\n if (isTyping) {\n this.typingIndicator = document.createElement('div');\n this.typingIndicator.className = 'typing-indicator';\n\n // 3 dots\n for (let i = 0; i < 3; i++) {\n const dot = document.createElement('div');\n dot.className = 'typing-dot';\n this.typingIndicator.appendChild(dot);\n }\n\n this.messageContainer.appendChild(this.typingIndicator);\n this.scrollToBottom();\n }\n }\n\n /**\n * Inject a \"Voice call ended\" card into the message list.\n * @param durationMs call duration in milliseconds\n * @param timestamp unix ms when the call started (for ordering across restore)\n */\n public addCallRecord(durationMs: number, timestamp: number = Date.now()) {\n const mins = Math.floor(durationMs / 60000);\n const secs = Math.floor((durationMs % 60000) / 1000);\n const label = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n\n const card = document.createElement('div');\n card.dataset.callTimestamp = String(timestamp);\n card.style.cssText = `\n display: flex; justify-content: center;\n margin: 10px 16px;\n `;\n\n card.innerHTML = `\n <div style=\"\n display: flex; align-items: center; gap: 8px;\n background: #f3f4f6; border: 1px solid #e5e7eb;\n border-radius: 12px; padding: 8px 14px;\n font-size: 12px; color: #6b7280;\n max-width: 210px; width: fit-content;\n \">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#9ca3af\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"9\" width=\"4\" height=\"12\" rx=\"2\"/>\n <rect x=\"9\" y=\"5\" width=\"4\" height=\"16\" rx=\"2\"/>\n <rect x=\"16\" y=\"2\" width=\"4\" height=\"20\" rx=\"2\"/>\n </svg>\n <span>\n <span style=\"font-weight:500; color:#374151;\">Voice call ended</span>\n <span style=\"margin-left:6px; color:#9ca3af;\">¡</span>\n <span style=\"margin-left:6px;\">${label}</span>\n </span>\n </div>\n `;\n\n this.messageContainer.appendChild(card);\n this.scrollToBottom();\n }\n\n public clearMessages() {\n this.messageContainer.innerHTML = '';\n }\n\n\n private scrollToBottom() {\n this.messageContainer.scrollTop = this.messageContainer.scrollHeight;\n }\n}\n","\nexport class AvatarView {\n private element: HTMLDivElement;\n private videoElement: HTMLVideoElement;\n private placeholderContainer: HTMLDivElement;\n\n constructor(avatarUrl?: string | null) {\n this.element = document.createElement('div');\n this.element.className = 'avatar-container';\n this.element.style.position = 'relative';\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n this.element.style.background = '#ffffff'; // White card background\n this.element.style.borderRadius = '16px';\n this.element.style.overflow = 'hidden';\n\n // 1. Placeholder Container (Centered Circle)\n this.placeholderContainer = document.createElement('div');\n this.placeholderContainer.style.width = '100%';\n this.placeholderContainer.style.height = '100%';\n this.placeholderContainer.style.display = 'flex';\n this.placeholderContainer.style.alignItems = 'center';\n this.placeholderContainer.style.justifyContent = 'center';\n\n // Determine Avatar Source\n // Use provided URL or fallback to default video\n const sourceUrl = avatarUrl || \"https://www.simli.com/jenna.mp4\";\n const isVideo = sourceUrl.endsWith('.mp4') || sourceUrl.endsWith('.webm');\n\n let mediaElement: HTMLElement;\n\n if (isVideo) {\n const vid = document.createElement('video');\n vid.src = sourceUrl;\n vid.muted = true;\n vid.loop = true;\n vid.autoplay = true;\n vid.playsInline = true;\n mediaElement = vid;\n } else {\n const img = document.createElement('img');\n img.src = sourceUrl;\n mediaElement = img;\n }\n\n // Apply Circle Styles\n mediaElement.style.width = '140px';\n mediaElement.style.height = '140px';\n mediaElement.style.borderRadius = '50%';\n mediaElement.style.objectFit = 'cover';\n mediaElement.style.backgroundColor = '#f3f4f6';\n\n this.placeholderContainer.appendChild(mediaElement);\n this.element.appendChild(this.placeholderContainer);\n\n // 2. Video Element\n this.videoElement = document.createElement('video');\n this.videoElement.className = 'avatar-video';\n this.videoElement.autoplay = true;\n this.videoElement.playsInline = true;\n this.videoElement.muted = true; // Often required for autoplay\n this.videoElement.style.display = 'none';\n\n this.element.appendChild(this.videoElement);\n\n // Initial State - NO DEFAULT ICON per user request\n // this.setPlaceholder(this.currentGender as any);\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setStream(stream: MediaStream) {\n this.videoElement.srcObject = stream;\n this.videoElement.style.display = 'block';\n this.placeholderContainer.style.display = 'none';\n }\n\n\n}\n","import { icons } from '../styles';\n\nexport class VoiceOrb {\n private element: HTMLDivElement;\n\n constructor(private onClick: () => void) {\n this.element = document.createElement('div');\n this.element.className = 'voice-mode-container';\n\n this.element.innerHTML = `\n <div class=\"central-orb-container\">\n <div class=\"central-orb idle\">\n ${icons.audioLines}\n </div>\n <div class=\"central-orb-glow\"></div>\n </div>\n <div class=\"voice-status-text\">Tap to speak</div>\n <div class=\"voice-status-subtext\">Start a conversation</div>\n `;\n\n const orbContainer = this.element.querySelector('.central-orb-container') as HTMLElement;\n if (orbContainer) {\n orbContainer.onclick = this.onClick;\n }\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n}\n","\nexport interface WelcomeChip {\n title: string;\n payload?: string;\n}\n\nexport class FloatingWelcomeChips {\n private element: HTMLElement;\n private chips: WelcomeChip[] = [];\n\n constructor(\n private onChipClick: (text: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.className = 'welcome-chips-container';\n }\n\n public setChips(chips: WelcomeChip[]) {\n this.chips = chips;\n this.render();\n }\n\n public getElement(): HTMLElement {\n return this.element;\n }\n\n public setPosition(positionStyle: string) {\n // Parse positionStyle (e.g., \"bottom: 24px; right: 24px;\")\n // We want to be slightly ABOVE the launcher.\n // Launcher is usually 64px + 24px = ~88px from bottom.\n // If bottom-right, we want right: 24px, bottom: 100px.\n\n // Simple parsing/replacement for now.\n // Assuming positionStyle is exactly what VaniraInternalProvider returns.\n\n // Remove standard bottom/top/left/right and adjust.\n // Actually, easier to just pass the raw style and let the provider adjust, \n // OR adjust here.\n\n // Let's set the base style, but we need to offset it.\n // If \"bottom: 24px\", make it \"bottom: 100px\".\n\n let style = positionStyle;\n if (style.includes('bottom:')) {\n style = style.replace(/bottom:\\s*[\\d]+px/, 'bottom: 100px');\n } else if (style.includes('top:')) {\n style = style.replace(/top:\\s*[\\d]+px/, 'top: 100px');\n }\n\n this.element.setAttribute('style', style);\n }\n\n private render() {\n this.element.innerHTML = '';\n\n this.chips.forEach((chip, index) => {\n const btn = document.createElement('button');\n btn.className = 'welcome-chip-btn';\n btn.textContent = chip.title;\n btn.onclick = (e) => {\n e.stopPropagation();\n this.onChipClick(chip.title); // Send title as text\n };\n // Add staggered delay\n btn.style.animationDelay = `${index * 0.1}s`;\n this.element.appendChild(btn);\n });\n }\n\n public static get styles() {\n return `\n .welcome-chips-container {\n position: fixed;\n z-index: 9998;\n display: flex;\n flex-direction: column; /* Stack vertically */\n align-items: flex-end; /* Align to right (usually) */\n gap: 12px;\n pointer-events: none; /* Container passes clicks */\n /* Max width to prevent huge buttons */\n max-width: 300px;\n }\n\n /* Adjust alignment based on position */\n /* We might need to know if it's left or right to align flex-start or flex-end \n For now, defaulting to flex-end (right) which matches most widgets.\n TODO: Pass alignment if needed.\n */\n\n .welcome-chip-btn {\n background: white;\n color: #4f46e5; /* Secondary/Primary color - hardcoded or use var */\n color: var(--primary);\n border: 1px solid transparent;\n padding: 10px 18px;\n border-radius: 20px;\n font-family: inherit;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);\n pointer-events: auto;\n opacity: 0;\n margin-bottom: 4px; /* Tiny spacing */\n \n /* Animation */\n animation: slideUpFade 0.4s ease-out forwards;\n }\n\n .welcome-chip-btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);\n background: #f8fafc;\n }\n\n @keyframes slideUpFade {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n `;\n }\n}\n","import { VoiceOverlay } from '../components';\n\nexport abstract class AbstractVoiceView {\n protected element: HTMLDivElement;\n protected overlay!: VoiceOverlay;\n protected onStartCall: () => void;\n protected onHangup: () => void;\n protected primaryColor: string;\n protected secondaryColor: string;\n protected onCallEnded?: (durationMs: number, startedAt: number) => void;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n this.onStartCall = onStartCall;\n this.onHangup = onHangup;\n this.primaryColor = primaryColor;\n this.secondaryColor = secondaryColor;\n this.onCallEnded = onCallEnded;\n this.element = document.createElement('div');\n this.element.style.height = '100%';\n this.element.style.position = 'relative';\n\n // Child classes implement specific init\n // BUT calling initOverlay here is common\n }\n\n protected initOverlay() {\n this.overlay = new VoiceOverlay(() => this.onHangup(), this.primaryColor, this.secondaryColor, this.onCallEnded);\n this.element.appendChild(this.overlay.getElement());\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public setCallActive(active: boolean) {\n if (active) this.overlay.show();\n else this.overlay.hide();\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n this.overlay.setStatus(status);\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.overlay.setTranscription(text, isFinal);\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.overlay.setVideoTrack(track);\n }\n}\n","import { VoiceOrb } from '../components';\nimport { AbstractVoiceView } from './AbstractVoiceView';\n\nexport class VoiceOnlyView extends AbstractVoiceView {\n private voiceOrb: VoiceOrb;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n\n this.element.style.background = '#f9fafb';\n\n this.voiceOrb = new VoiceOrb(() => this.onStartCall());\n this.element.appendChild(this.voiceOrb.getElement());\n\n this.initOverlay();\n }\n}\n","import { ChatWindow } from '../components';\n\nexport class ChatOnlyView {\n private element: HTMLDivElement;\n private chatWindow: ChatWindow;\n\n constructor(\n private onSendMessage: (msg: string) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.flex = '1';\n this.element.style.width = '100%';\n this.element.style.minHeight = '0'; // Crucial for flex scrolling\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n\n this.chatWindow = new ChatWindow((msg) => this.onSendMessage(msg));\n this.element.appendChild(this.chatWindow.getElement());\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public getChatWindow(): ChatWindow {\n return this.chatWindow;\n }\n}\n","import { ChatWindow, VoiceOverlay } from '../components';\nimport { icons } from '../styles';\n\nexport abstract class AbstractChatView {\n protected element: HTMLDivElement;\n protected chatWindow!: ChatWindow;\n protected overlay!: VoiceOverlay;\n protected voiceTrigger!: HTMLButtonElement;\n\n constructor(\n protected onSendMessage: (msg: string) => void,\n protected onStartCall: () => void,\n protected onHangup: () => void,\n protected primaryColor: string = '#6366f1',\n protected secondaryColor: string = '#a855f7',\n protected onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n this.element = document.createElement('div');\n this.element.style.flex = '1'; // Fill parent (widget-body)\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n this.element.style.minHeight = '0'; // Crucial for flex scrolling\n this.element.style.position = 'relative'; // Added from VoiceView\n\n // Child classes will append specific elements (Avatar, etc)\n // Then call setupChat()\n }\n\n protected setupChat() {\n this.chatWindow = new ChatWindow((msg) => this.onSendMessage(msg));\n const chatEl = this.chatWindow.getElement();\n chatEl.style.flex = '1';\n this.element.appendChild(chatEl);\n\n this.injectVoiceTrigger();\n\n this.overlay = new VoiceOverlay(() => this.onHangup(), this.primaryColor, this.secondaryColor, this.onCallEnded);\n this.element.appendChild(this.overlay.getElement());\n }\n\n protected injectVoiceTrigger() {\n const triggerBtn = document.createElement('button');\n this.voiceTrigger = triggerBtn;\n triggerBtn.className = 'voice-btn-simple';\n triggerBtn.innerHTML = `<div class=\"voice-btn-icon\">${icons.audioLines}</div>`;\n triggerBtn.onclick = () => this.onStartCall();\n\n // Synchronous injection since ChatWindow is already constructed\n const inputArea = this.chatWindow.getElement().querySelector('.chat-input-area');\n\n if (inputArea) {\n inputArea.insertBefore(this.voiceTrigger, inputArea.firstChild);\n } else {\n console.warn('VaniraSDK: Failed to inject voice trigger', { inputArea });\n }\n }\n\n public getElement(): HTMLDivElement {\n return this.element;\n }\n\n public getChatWindow(): ChatWindow {\n return this.chatWindow;\n }\n\n public setCallActive(active: boolean) {\n if (active) {\n this.overlay.show();\n // User Request: Hide Chat Welcome & Chat Box during interaction\n if (this.chatWindow) {\n this.chatWindow.getElement().style.display = 'none';\n }\n } else {\n this.overlay.hide();\n // Restore functionality on hangup\n if (this.chatWindow) {\n this.chatWindow.getElement().style.display = 'flex';\n }\n }\n }\n\n public setStatus(status: 'connecting' | 'connected' | 'disconnected' | 'error') {\n this.overlay.setStatus(status);\n }\n\n public setTranscription(text: string, isFinal: boolean) {\n this.overlay.setTranscription(text, isFinal);\n }\n\n public setVideoTrack(track: MediaStreamTrack) {\n this.overlay.setVideoTrack(track);\n }\n}\n","import { AbstractChatView } from './AbstractChatView';\n\nexport class ChatVoiceView extends AbstractChatView {\n constructor(\n onSendMessage: (msg: string) => void,\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onSendMessage, onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n this.setupChat();\n }\n}\n","import { AvatarView } from '../components';\nimport { icons } from '../styles';\nimport { AbstractVoiceView } from './AbstractVoiceView';\n\nexport class AvatarOnlyView extends AbstractVoiceView {\n private avatarView: AvatarView;\n private startCallBtn: HTMLButtonElement;\n private controlsContainer: HTMLDivElement;\n\n constructor(\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n\n // Ensure flex layout\n this.element.style.display = 'flex';\n this.element.style.flexDirection = 'column';\n\n // 1. Avatar View (Idle State matching Overlay Card)\n this.avatarView = new AvatarView();\n const avatarEl = this.avatarView.getElement();\n // Match VoiceOverlay VideoContainer styles\n avatarEl.style.width = '100%';\n avatarEl.style.maxWidth = '300px';\n avatarEl.style.aspectRatio = '1/1';\n avatarEl.style.borderRadius = '16px';\n avatarEl.style.overflow = 'hidden';\n avatarEl.style.margin = 'auto'; // Center vertically and horizontally\n avatarEl.style.position = 'relative'; // Ensure proper stacking\n\n this.element.appendChild(avatarEl);\n\n // 2. Start Call Controls\n this.controlsContainer = document.createElement('div');\n this.controlsContainer.className = 'widget-body';\n this.controlsContainer.style.position = 'absolute';\n this.controlsContainer.style.bottom = '20px';\n this.controlsContainer.style.width = '100%';\n this.controlsContainer.style.zIndex = '10';\n\n const controls = document.createElement('div');\n controls.className = 'controls';\n\n this.startCallBtn = document.createElement('button');\n this.startCallBtn.className = 'control-btn primary';\n this.startCallBtn.innerHTML = `${icons.phone} <span>Start Call</span>`;\n this.startCallBtn.onclick = () => this.onStartCall();\n\n controls.appendChild(this.startCallBtn);\n this.controlsContainer.appendChild(controls);\n this.element.appendChild(this.controlsContainer);\n\n // 3. Overlay\n this.initOverlay();\n this.overlay.setMode('avatar');\n // REVERTED Full Screen: this.overlay.setFullScreen(true);\n }\n\n public getAvatarView(): AvatarView {\n return this.avatarView;\n }\n\n public override setCallActive(active: boolean) {\n if (active) {\n this.overlay.setMode('avatar');\n }\n super.setCallActive(active);\n if (active) {\n this.controlsContainer.style.display = 'none';\n } else {\n this.controlsContainer.style.display = 'block';\n }\n }\n}\n","import { AbstractChatView } from './AbstractChatView';\nimport { icons } from '../styles';\n\nexport class ChatAvatarView extends AbstractChatView {\n\n constructor(\n onSendMessage: (msg: string) => void,\n onStartCall: () => void,\n onHangup: () => void,\n primaryColor: string = '#6366f1',\n secondaryColor: string = '#a855f7',\n onCallEnded?: (durationMs: number, startedAt: number) => void\n ) {\n super(onSendMessage, onStartCall, onHangup, primaryColor, secondaryColor, onCallEnded);\n // No top AvatarView anymore! Just standard chat setup.\n this.setupChat();\n this.overlay.setMode('avatar');\n }\n\n // Override to inject the unique Circular Video Button\n protected override injectVoiceTrigger() {\n const triggerBtn = document.createElement('button');\n this.voiceTrigger = triggerBtn;\n triggerBtn.className = 'voice-btn-simple';\n // Custom styling for Avatar Mode\n triggerBtn.style.overflow = 'hidden'; // Clip video\n triggerBtn.style.padding = '0';\n triggerBtn.style.border = '1.5px solid #e5e7eb'; // Clean border\n\n // Video Loop (Simli Jenna or equiv)\n triggerBtn.innerHTML = `\n <video \n src=\"https://www.simli.com/jenna.mp4\" \n autoplay loop muted pip=\"false\" playsinline \n style=\"width: 100%; height: 100%; object-fit: cover; border-radius: 50%;\">\n </video>\n <div style=\"position: absolute; bottom: -2px; right: -2px; background: white; border-radius: 50%; padding: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.1);\">\n ${icons.audioLines.replace('width=\"24\"', 'width=\"12\"').replace('height=\"24\"', 'height=\"12\"')}\n </div>\n `;\n\n // Ensure small icon style if replacement didn't work (regex safely)\n const iconDiv = triggerBtn.querySelector('div');\n if (iconDiv) {\n const svg = iconDiv.querySelector('svg');\n if (svg) {\n svg.style.width = '12px';\n svg.style.height = '12px';\n }\n }\n\n triggerBtn.onclick = () => this.onStartCall();\n\n // Synchronous injection\n const inputArea = this.chatWindow.getElement().querySelector('.chat-input-area');\n const sendBtn = inputArea?.querySelector('.chat-send-btn');\n\n if (inputArea && sendBtn) {\n inputArea.insertBefore(this.voiceTrigger, sendBtn);\n } else {\n console.warn('VaniraSDK: Failed to inject voice trigger', { inputArea, sendBtn });\n }\n }\n\n // No getAvatarView method anymore. VaniraInternalProvider should check for capability or cast.\n}\n","import { IChatAdapter } from '../abstraction/interfaces';\nimport { ChatService } from '../../api/services/ChatService';\n\nexport class VaniraChatAdapter implements IChatAdapter {\n async sendMessage(\n text: string,\n agentId: string,\n prospectId: string,\n chatId: string | null,\n onResponse: (response: any) => void,\n onStream?: (text: string) => void,\n onChatIdUpdate?: (newId: string) => void,\n widgetId?: string\n ): Promise<void> {\n return ChatService.sendChatMessage(\n agentId,\n prospectId,\n text,\n chatId,\n (stream) => {\n if (onStream) onStream(stream);\n },\n onResponse,\n (newId) => {\n if (onChatIdUpdate && newId) onChatIdUpdate(newId);\n },\n widgetId\n );\n }\n\n async sendFile(file: File): Promise<void> {\n console.warn(\"sendFile not implemented for VaniraChatAdapter yet - Incompatible function adapted\", file);\n throw new Error(\"Method not implemented.\");\n }\n\n async likeDislike(messageId: string, action: 'like' | 'dislike'): Promise<void> {\n console.warn(\"likeDislike not implemented for VaniraChatAdapter yet - Incompatible function adapted\", messageId, action);\n // Implement API call here when available\n }\n}\n","import { ChatService } from '../../api/services/ChatService';\nimport { AbstractWidgetProvider } from '../abstraction/AbstractWidgetProvider';\nimport { VaniraAI } from '../../core/VaniraAI';\nimport { SessionManager } from '../../core/SessionManager';\nimport { WidgetMode } from '../../types';\nimport { generateThemeVars, widgetIcons, icons } from '../styles';\nimport { widgetStyles as baseCss } from '../styles/widget.css';\nimport { FloatingButton, Panel, FloatingWelcomeChips, WelcomeChip } from '../components';\nimport { VoiceOnlyView, ChatOnlyView, ChatVoiceView, AvatarOnlyView, ChatAvatarView } from '../views';\nimport { VaniraChatAdapter } from '../adapters/VaniraChatAdapter';\n\nexport class VaniraInternalProvider extends AbstractWidgetProvider {\n private vaniraClient: VaniraAI | null = null;\n private currentView: any = null;\n private isPanelOpen: boolean = false;\n private callActive: boolean = false;\n private eventSource: { close: () => void } | null = null;\n\n // Components\n private floatingButton: FloatingButton | null = null;\n private floatingWelcomeChips: FloatingWelcomeChips | null = null;\n private panel: Panel | null = null;\n private welcomeChipsData: WelcomeChip[] = [];\n\n // Chat Adapter\n private chatAdapter: VaniraChatAdapter;\n\n // âââ Session Manager âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n private sessionManager: SessionManager | null = null;\n /** Whether this tab currently owns the widget session. */\n private sessionActive: boolean = false;\n\n // Config derived state\n private widgetMode: WidgetMode = 'voice_only';\n private agentId: string = '';\n private prospectGroupId: string = '';\n private chatServerUrl: string = '';\n\n private prospectId: string = '';\n private chatId: string | null = null;\n private widgetId: string = '';\n\n // Appearance (Defaults)\n private primaryColor: string = '#6366f1';\n private secondaryColor: string = '#4f46e5';\n private gradient: string | null = null;\n private position: string = 'bottom-right';\n private widgetIcon: string | null = null;\n\n constructor(config: any) {\n super(config);\n this.chatAdapter = new VaniraChatAdapter();\n this.processConfig(config);\n }\n\n // âââ Session Initialisation âââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Boot the SessionManager.\n * Called once we have a stable widgetId to key the session on.\n * Returns true if this tab owns the session, false if another tab owns it.\n */\n private initSessionManager(): boolean {\n const key = this.widgetId || this.agentId || 'default';\n this.sessionManager = new SessionManager(key);\n\n // Wire cross-tab events\n this.sessionManager.on('tab_took_over', () => {\n // Another tab stole the session â show \"taken over\" banner in this tab\n console.warn('[VaniraAI] Session taken over by another tab.');\n this.sessionActive = false;\n this.showTabConflictBanner('taken_over');\n });\n\n this.sessionManager.on('session_cleared', () => {\n console.log('[VaniraAI] Session cleared externally.');\n });\n\n const claimed = this.sessionManager.claimSession();\n this.sessionActive = claimed;\n return claimed;\n }\n\n /**\n * Restore persisted chat messages into the chat window.\n * Called after the view is rendered.\n */\n private restoreSessionMessages(): void {\n const session = this.sessionManager?.getSession();\n if (!session) return;\n\n const cw = this.currentView?.getChatWindow?.();\n if (!cw) return;\n\n // Filter out empty placeholder messages\n const visibleMessages = session.messages.filter(msg => msg.content.trim() !== '');\n\n // Load persisted call records\n const callKey = `vanira_calls_${this.widgetId || this.agentId}`;\n const callRecords: Array<{ durationMs: number; startedAt: number }> =\n JSON.parse(localStorage.getItem(callKey) || '[]');\n\n if (visibleMessages.length === 0 && callRecords.length === 0) return;\n\n cw.clearMessages();\n\n // Merge messages and call records by timestamp, then render in order\n type Entry =\n | { type: 'msg'; role: 'user' | 'assistant'; content: string; ts: number }\n | { type: 'call'; durationMs: number; startedAt: number; ts: number };\n\n const entries: Entry[] = [\n ...visibleMessages.map((m, i) => ({\n type: 'msg' as const,\n role: m.role,\n content: m.content,\n // If session messages have no timestamp, use index as tiebreaker\n ts: (m as any).timestamp ?? i,\n })),\n ...callRecords.map(r => ({\n type: 'call' as const,\n durationMs: r.durationMs,\n startedAt: r.startedAt,\n ts: r.startedAt,\n })),\n ];\n\n entries.sort((a, b) => a.ts - b.ts);\n\n entries.forEach(entry => {\n if (entry.type === 'msg') {\n cw.addMessage(entry.role, entry.content, entry.ts);\n } else {\n cw.addCallRecord(entry.durationMs, entry.startedAt);\n }\n });\n\n console.log(`[VaniraAI] Restored ${visibleMessages.length} messages + ${callRecords.length} call records from session.`);\n }\n\n // âââ Tab Conflict UI âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n /**\n * Renders a friendly overlay when:\n * - 'conflict' â this tab tried to open but another tab owns the session\n * - 'taken_over' â another tab stole the session while this tab was active\n */\n private showTabConflictBanner(reason: 'conflict' | 'taken_over'): void {\n if (!this.root) return;\n\n // Remove any existing banner\n this.root.querySelector('.vanira-tab-conflict-banner')?.remove();\n\n if (reason === 'conflict') {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n if (this.widgetMode.includes('chat')) {\n this.initializeChatSession(false);\n }\n }\n // If 'taken_over', do nothing. The tab silently becomes dormant.\n }\n\n private static audioContext: AudioContext | null = null;\n private playMessageSound(type: 'send' | 'receive') {\n try {\n if (!VaniraInternalProvider.audioContext) {\n const AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;\n if (!AudioContextClass) return;\n VaniraInternalProvider.audioContext = new AudioContextClass();\n }\n const ctx = VaniraInternalProvider.audioContext;\n \n // Required by modern browsers to play sound after interaction\n if (ctx.state === 'suspended') {\n ctx.resume().catch(() => {});\n }\n \n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.connect(gain);\n gain.connect(ctx.destination);\n\n const now = ctx.currentTime;\n if (type === 'send') {\n // A subtle rising pop for sending\n osc.type = 'sine';\n osc.frequency.setValueAtTime(300, now);\n osc.frequency.exponentialRampToValueAtTime(500, now + 0.05);\n gain.gain.setValueAtTime(0, now);\n gain.gain.linearRampToValueAtTime(0.1, now + 0.01);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.1);\n osc.start(now);\n osc.stop(now + 0.1);\n } else {\n // A friendly bright pop for receiving\n osc.type = 'sine';\n osc.frequency.setValueAtTime(500, now);\n osc.frequency.exponentialRampToValueAtTime(800, now + 0.1);\n gain.gain.setValueAtTime(0, now);\n gain.gain.linearRampToValueAtTime(0.15, now + 0.02);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.2);\n osc.start(now);\n osc.stop(now + 0.2);\n }\n } catch (e) {\n console.warn('[VaniraAI] Audio feedback failed', e);\n }\n }\n\n // âââ Chat Logic âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private async initializeChatSession(forceNew: boolean = false): Promise<void> {\n if (!this.sessionActive) return;\n\n try {\n ChatService.setChatUrl(this.chatServerUrl);\n\n const session = this.sessionManager?.getSession();\n\n // ââ Restore existing session ââââââââââââââââââââââââââââââââââââââ\n if (!forceNew && session?.prospectId) {\n this.prospectId = session.prospectId;\n this.chatId = session.chatId;\n\n console.log(`[VaniraAI] Session restored â tab: ${this.sessionManager?.getTabId()}, prospect: ${this.prospectId}`);\n\n // Restore messages into UI\n this.restoreSessionMessages();\n\n // Re-attach the SSE admin-reply stream\n if (this.chatId && !this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (text) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', text);\n this.sessionManager?.pushMessage('assistant', text);\n this.playMessageSound('receive');\n }\n );\n }\n\n return; // Don't fetch a new welcome message\n }\n\n // ââ Fresh session âââââââââââââââââââââââââââââââââââââââââââââââââ\n if (this.prospectGroupId) {\n this.prospectId = await ChatService.createChatProspect(this.prospectGroupId);\n } else {\n this.prospectId = `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n const welcome = await ChatService.fetchWelcomeMessage(this.agentId, this.prospectId, this.widgetId || undefined);\n\n if (welcome?.chatId && !this.chatId) {\n this.chatId = welcome.chatId;\n if (!this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (text) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', text);\n this.sessionManager?.pushMessage('assistant', text);\n this.playMessageSound('receive');\n }\n );\n }\n }\n\n // Persist IDs so a refresh restores the session\n this.sessionManager?.saveIds(this.prospectId, this.chatId);\n\n if (welcome && this.currentView?.getChatWindow) {\n const cw = this.currentView.getChatWindow();\n cw.clearMessages();\n\n if (welcome.widget) {\n try {\n const payload = JSON.parse(welcome.content);\n const welcomeText = payload.text || '';\n cw.addMessage(welcome.role, welcomeText);\n this.sessionManager?.pushMessage(welcome.role, welcomeText);\n\n if (payload.buttons && Array.isArray(payload.buttons)) {\n cw.addButtons(payload.buttons);\n this.welcomeChipsData = payload.buttons;\n }\n this.updateWelcomeChipsVisibility();\n } catch (e) {\n console.error('Failed to parse welcome widget content', e);\n cw.addMessage(welcome.role, welcome.content);\n this.sessionManager?.pushMessage(welcome.role, welcome.content);\n }\n } else {\n cw.addMessage(welcome.role, welcome.content);\n this.sessionManager?.pushMessage(welcome.role, welcome.content);\n }\n }\n } catch (error) {\n console.error('[VaniraAI] Chat init failed', error);\n const fallback = 'Hello! How can I help you today?';\n this.currentView?.getChatWindow?.().addMessage('assistant', fallback);\n this.sessionManager?.pushMessage('assistant', fallback);\n }\n }\n\n async initialize(config: any): Promise<void> {\n await super.initialize(config);\n this.processConfig(config);\n if (this.root) {\n this.ui_renderer(this.root);\n }\n }\n\n private processConfig(config: any) {\n this.widgetId = config.widgetId || config.widget_id || '';\n this.agentId = config.agentId || config.agent_id || '';\n this.prospectGroupId = config.prospectGroupId || config.client?.base_prospect_group_id || '';\n this.widgetMode = config.widgetMode || config.mode || 'voice_only';\n this.widgetId = config.widgetId || config.widget_id || \"\";\n\n this.primaryColor = config.primaryColor || '#6366f1';\n this.secondaryColor = config.secondaryColor || config.primaryColor || '#4f46e5';\n this.gradient = config.gradient || null;\n this.position = config.position || 'bottom-right';\n this.widgetIcon = config.widgetIcon || config.icon || null;\n\n // Configurable server URLs â fall back to Vanira production endpoints\n this.chatServerUrl = config.serverUrl || config.chatServerUrl || 'https://inboxapi.travelr.club';\n\n\n }\n\n async create_call(): Promise<void> {\n if (this.callActive || !this.agentId) return;\n if (!this.sessionActive) {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n }\n try {\n this.callActive = true;\n this.updateViewCallState(true);\n this.updateViewStatus('connecting');\n\n // Generate call ID from server\n const callContext = await ChatService.createCall(\n this.agentId,\n null,\n this.prospectId || null,\n this.widgetMode\n );\n\n // Use VaniraAI SDK â abstracts all WebRTC internals\n const client = new VaniraAI({\n agentId: this.agentId,\n callId: callContext.callId,\n serverUrl: callContext.workerUrl,\n });\n\n // Status events\n client\n .on('connected', () => this.updateViewStatus('connected'))\n .on('disconnected', () => this.end_call())\n .on('error', (msg) => {\n console.error('[VaniraAI Widget] Call error:', msg);\n this.updateViewStatus('error');\n })\n .on('transcription', ({ text, isFinal }) => {\n this.currentView?.setTranscription?.(text, isFinal);\n })\n .on('track', ({ track }) => {\n if (this.widgetMode.includes('avatar') && track.kind === 'video' && this.currentView?.setVideoTrack) {\n this.currentView.setVideoTrack(track);\n }\n })\n .on('tool_call', (toolCall) => {\n // Dispatch tool_call event to the host page via a custom DOM event\n const event = new CustomEvent('vaniraai:tool_call', {\n detail: toolCall,\n bubbles: true,\n composed: true, // crosses Shadow DOM boundary\n });\n this.root?.host?.dispatchEvent(event);\n\n console.log('[VaniraAI Widget] Tool call dispatched:', toolCall.name, toolCall.arguments);\n\n if (toolCall.execution_mode === 'fire_and_forget') {\n // Auto-resolved â nothing extra needed\n }\n // Blocking tools: host page must call window.VaniraAI.sendToolResult(...)\n });\n\n this.vaniraClient = client;\n await client.start();\n\n } catch (err) {\n console.error('[VaniraAI Widget] Call failed', err);\n this.updateViewStatus('error');\n }\n }\n\n end_call(): void {\n this.callActive = false;\n const client = this.vaniraClient;\n this.vaniraClient = null;\n if (client) {\n client.stop();\n }\n this.updateViewCallState(false);\n }\n\n private updateViewCallState(active: boolean) {\n if (this.currentView?.setCallActive) {\n this.currentView.setCallActive(active);\n }\n }\n\n private updateViewStatus(status: string) {\n if (this.currentView?.setStatus) {\n this.currentView.setStatus(status);\n }\n }\n\n ui_renderer(root: ShadowRoot): void {\n this.root = root;\n this.root.innerHTML = ''; // Start fresh\n\n // ââ Session Management ââââââââââââââââââââââââââââââââââââââââââââââ\n // Inject keyframe animation for the conflict banner\n const animStyle = document.createElement('style');\n animStyle.textContent = `@keyframes vanira-slide-up {\n from { opacity:0; transform:translateY(16px); }\n to { opacity:1; transform:translateY(0); }\n }`;\n this.root.appendChild(animStyle);\n\n // Establish the design tokens\n const style = document.createElement('style');\n style.textContent = `\n ${baseCss}\n :host { ${generateThemeVars(this.primaryColor, this.secondaryColor)} }\n ${FloatingButton.styles}\n ${FloatingWelcomeChips.styles}\n ${Panel.styles}\n ${this.gradient ? `.widget-fab { background: ${this.gradient} !important; }` : ''}\n `;\n this.root.appendChild(style);\n\n // FloatingButton\n this.floatingButton = new FloatingButton(() => this.togglePanel());\n this.floatingButton.setIcon(this.getFabIcon());\n this.floatingButton.setPosition(this.getPosStyle());\n\n // Floating Welcome Chips\n this.floatingWelcomeChips = new FloatingWelcomeChips((text) => this.handleFloatingChipClick(text));\n this.floatingWelcomeChips.setPosition(this.getPosStyle());\n\n // Panel\n this.panel = new Panel(() => this.closePanel(), this.getPanelTitle());\n\n // Append components\n this.root.appendChild(this.floatingWelcomeChips.getElement());\n this.root.appendChild(this.floatingButton.getElement());\n this.root.appendChild(this.panel.getElement());\n\n // Setup content view\n this.setupPanelContent();\n\n // ââ Init Session ââââââââââââââââââââââââââââââââââââââââââââââââââââ\n const owned = this.initSessionManager();\n\n if (!owned) {\n // Another live tab owns the session â show a conflict banner\n this.showTabConflictBanner('conflict');\n } else if (this.widgetMode.includes('chat')) {\n // Session is ours â initialise chat (will restore if session exists)\n this.initializeChatSession();\n }\n }\n\n private getFabIcon(): string {\n if (this.widgetIcon && widgetIcons[this.widgetIcon]) {\n return widgetIcons[this.widgetIcon];\n }\n if (this.widgetMode.includes('chat')) {\n return icons.chat;\n }\n return icons.voice_orb;\n }\n\n private getPanelTitle(): string {\n return 'Assistant';\n }\n\n private getPosStyle() {\n const posStyles: Record<string, string> = {\n 'bottom-right': 'bottom: 24px; right: 24px;',\n 'bottom-left': 'bottom: 24px; left: 24px;',\n 'top-right': 'top: 24px; right: 24px;',\n 'top-left': 'top: 24px; left: 24px;',\n };\n return posStyles[this.position] || posStyles['bottom-right'];\n }\n\n private setupPanelContent() {\n // ââ Voice Call History callback ââââââââââââââââââââââââââââââââââââââââââ\n const onCallEnded = (durationMs: number, startedAt: number) => {\n // 1. Inject card into active chat window (chat_voice / chat_avatar modes)\n const cw = this.currentView?.getChatWindow?.();\n if (cw) cw.addCallRecord(durationMs, startedAt);\n\n // 2. Persist to localStorage for cross-session restore\n const key = `vanira_calls_${this.widgetId || this.agentId}`;\n const existing: Array<{ durationMs: number; startedAt: number }> = JSON.parse(localStorage.getItem(key) || '[]');\n existing.push({ durationMs, startedAt });\n // Keep last 50 records max\n if (existing.length > 50) existing.splice(0, existing.length - 50);\n localStorage.setItem(key, JSON.stringify(existing));\n };\n\n switch (this.widgetMode) {\n case 'chat_only':\n this.currentView = new ChatOnlyView((msg: string) => this.handleChatSend(msg));\n break;\n case 'chat_voice':\n this.currentView = new ChatVoiceView(\n (msg: string) => this.handleChatSend(msg),\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'avatar_only':\n this.currentView = new AvatarOnlyView(\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'chat_avatar':\n this.currentView = new ChatAvatarView(\n (msg: string) => this.handleChatSend(msg),\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n case 'voice_only':\n default:\n this.currentView = new VoiceOnlyView(\n () => this.create_call(),\n () => this.end_call(),\n this.primaryColor, this.secondaryColor,\n onCallEnded\n );\n break;\n }\n\n if (this.currentView && this.panel) {\n this.panel.setContent(this.currentView.getElement());\n }\n }\n\n private async handleChatSend(text: string) {\n if (!text) return;\n if (!this.sessionActive) {\n this.sessionManager?.forceClaimSession();\n this.sessionActive = true;\n if (this.widgetMode.includes('chat')) {\n await this.initializeChatSession(false);\n }\n }\n\n const cw = this.currentView?.getChatWindow?.();\n if (!cw) return;\n\n // Ensure SSE stream is running\n if (this.chatId && !this.eventSource) {\n this.eventSource = ChatService.listenForAdminReplies(\n this.chatId,\n this.prospectId,\n (replyText) => {\n this.currentView?.getChatWindow?.().addMessage('assistant', replyText);\n this.sessionManager?.pushMessage('assistant', replyText);\n this.playMessageSound('receive');\n }\n );\n }\n\n cw.addMessage('user', text);\n this.sessionManager?.pushMessage('user', text);\n cw.setTyping(true);\n\n // Push an empty assistant placeholder BEFORE streaming starts.\n // This ensures updateLastAssistantMessage always targets this new slot,\n // not the previous welcome message.\n this.sessionManager?.pushMessage('assistant', '');\n\n try {\n let hasPlayedReceive = false;\n \n await this.chatAdapter.sendMessage(\n text,\n this.agentId,\n this.prospectId,\n this.chatId,\n (response) => {\n if (!hasPlayedReceive) {\n this.playMessageSound('receive');\n hasPlayedReceive = true;\n }\n // onWidget\n cw.setTyping(false);\n if (response?.type === 'button_list' && response.data?.buttons) {\n cw.addButtons(response.data.buttons);\n this.welcomeChipsData = response.data.buttons;\n this.updateWelcomeChipsVisibility();\n }\n },\n (streamText) => {\n if (!hasPlayedReceive) {\n this.playMessageSound('receive');\n hasPlayedReceive = true;\n }\n // onStream â update last assistant message\n cw.setTyping(false);\n cw.updateLastAssistantMessage(streamText);\n this.sessionManager?.updateLastAssistantMessage(streamText);\n },\n (newId) => {\n if (newId) {\n this.chatId = newId;\n this.sessionManager?.saveIds(this.prospectId, newId);\n }\n }\n );\n } catch (err) {\n cw.setTyping(false);\n console.error('[VaniraAI] Send message failed', err);\n cw.addMessage('assistant', 'Error sending message.');\n }\n }\n\n // âââ Panel Management âââââââââââââââââââââââââââââââââââââââââââââââââââââ\n\n private togglePanel() {\n this.isPanelOpen ? this.closePanel() : this.openPanel();\n }\n\n private openPanel() {\n this.isPanelOpen = true;\n this.updateWelcomeChipsVisibility();\n this.panel?.open({\n bottom: this.position.includes('bottom') ? '100px' : undefined,\n top: this.position.includes('top') ? '100px' : undefined,\n right: this.position.includes('right') ? '24px' : undefined,\n left: this.position.includes('left') ? '24px' : undefined,\n });\n if (this.root?.host) {\n this.root.host.classList.add('vanira-panel-open');\n }\n }\n\n private closePanel() {\n this.isPanelOpen = false;\n this.updateWelcomeChipsVisibility();\n this.panel?.close();\n if (this.root?.host) {\n this.root.host.classList.remove('vanira-panel-open');\n }\n }\n\n private updateWelcomeChipsVisibility() {\n if (!this.floatingWelcomeChips) return;\n\n if (!this.isPanelOpen && this.welcomeChipsData.length > 0) {\n this.floatingWelcomeChips.setChips(this.welcomeChipsData);\n this.floatingWelcomeChips.getElement().style.display = 'flex';\n } else {\n this.floatingWelcomeChips.getElement().style.display = 'none';\n }\n }\n\n private handleFloatingChipClick(text: string) {\n this.openPanel();\n this.handleChatSend(text);\n }\n}\n","import { IWidgetProvider } from '../abstraction/interfaces';\nimport { VaniraInternalProvider } from '../providers/VaniraInternalProvider';\n\nexport class WidgetProviderFactory {\n /**\n * Factory Method to create the appropriate Widget Provider.\n * Implements the Factory Pattern to decouple creation logic.\n * Trade-off: Currently hardcoded to VaniraInternalProvider, but extensible for other providers.\n */\n static getProvider(config: any): IWidgetProvider {\n // Here we could check config.providerType to return different implementations\n // e.g. if (config.provider === 'external_sip') return new ExternalSIPProvider(config);\n\n return new VaniraInternalProvider(config);\n }\n}\n","import { ConfigService } from '../api/services/ConfigService';\nimport { WidgetProviderFactory } from './factory/WidgetFactory';\nimport { IWidgetProvider } from './abstraction/interfaces';\n\nexport class VaniraWidget extends HTMLElement {\n private shadow: ShadowRoot;\n private provider: IWidgetProvider | null = null;\n\n // Config attributes\n private widgetId: string = \"\";\n private agentId: string = \"\";\n private serverUrl: string = \"https://inboxapi.travelr.club\";\n private position: string = \"bottom-right\";\n private primaryColor: string = \"#6366f1\";\n private secondaryColor: string = \"#4f46e5\";\n private gradient: string | null = null;\n\n static get observedAttributes() {\n return ['widget-id', 'agent-id', 'position', 'primary-color', 'secondary-color', 'server-url', 'gradient'];\n }\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n console.log(\"[VaniraAI Widget] Initializing...\");\n this.readAttributes();\n\n // Initial Config based on attributes\n const initialConfig = {\n widgetId: this.widgetId,\n agentId: this.agentId,\n serverUrl: this.serverUrl,\n position: this.position,\n primaryColor: this.primaryColor,\n secondaryColor: this.secondaryColor,\n gradient: this.gradient\n };\n\n // Factory Pattern: Create specific provider\n this.provider = WidgetProviderFactory.getProvider(initialConfig);\n\n // UI Renderer: Delegate to provider (SRP)\n if (this.provider) {\n this.provider.ui_renderer(this.shadow);\n }\n\n // Fetch expanded config if widgetId is present\n if (this.widgetId && !this.agentId) {\n this.initializeExpandedConfig();\n }\n }\n\n private readAttributes() {\n this.widgetId = this.getAttribute('widget-id') || \"\";\n this.agentId = this.getAttribute('agent-id') || \"\";\n this.serverUrl = this.getAttribute('server-url') || \"https://inboxapi.travelr.club\";\n this.position = this.getAttribute('position') || \"bottom-right\";\n this.primaryColor = this.getAttribute('primary-color') || \"#6366f1\";\n this.secondaryColor = this.getAttribute('secondary-color') || this.primaryColor;\n this.gradient = this.getAttribute('gradient');\n }\n\n async initializeExpandedConfig() {\n try {\n const config = await ConfigService.fetchWidgetConfig(this.widgetId);\n\n // Pass API config to provider to update state/UI\n if (this.provider) {\n // This will trigger internal re-render in provider\n await this.provider.initialize(config);\n }\n } catch (error) {\n console.error(\"[VaniraAI Widget] Config failed:\", error);\n // specific error handling or Fallback_principle logic can be added here\n // Provider already has default state (Graceful degradation)\n }\n }\n}\n","import { VaniraWidget } from './ui/VaniraWidget';\nimport { VaniraAI } from './core/VaniraAI';\n\n// âââ Register Custom Element âââââââââââââââââââââââââââââââââââââââââââââââââ\nif (!customElements.get('vanira-convai')) {\n customElements.define('vanira-convai', VaniraWidget);\n}\n\n// âââ Global window exports âââââââââââââââââââââââââââââââââââââââââââââââââââ\nif (typeof window !== 'undefined') {\n // Legacy widget registration\n (window as any).VaniraConvAI = VaniraWidget;\n // New SDK class â integrators can do: const client = new window.VaniraAI({ agentId: '...' })\n (window as any).VaniraAI = VaniraAI;\n}\n\n// âââ Auto-inject Widget via script attributes ââââââââââââââââââââââââââââââââ\nconst currentScript = document.currentScript;\nif (currentScript) {\n const widgetId = currentScript.getAttribute('data-widget-id') || currentScript.getAttribute('widget-id');\n const agentId = currentScript.getAttribute('data-agent-id') || currentScript.getAttribute('agent-id');\n\n if (widgetId || agentId) {\n const position = currentScript.getAttribute('data-position') || 'bottom-right';\n const primaryColor = currentScript.getAttribute('data-primary-color') || currentScript.getAttribute('primary-color') || '#6366f1';\n const secondaryColor = currentScript.getAttribute('data-secondary-color') || currentScript.getAttribute('secondary-color');\n const gradient = currentScript.getAttribute('data-gradient') || currentScript.getAttribute('gradient');\n const serverUrl = currentScript.getAttribute('data-server-url') || currentScript.getAttribute('server-url');\n\n const widget = document.createElement('vanira-convai');\n if (widgetId) widget.setAttribute('widget-id', widgetId);\n if (agentId) widget.setAttribute('agent-id', agentId);\n widget.setAttribute('position', position);\n widget.setAttribute('primary-color', primaryColor);\n if (secondaryColor) widget.setAttribute('secondary-color', secondaryColor);\n if (gradient) widget.setAttribute('gradient', gradient);\n if (serverUrl) widget.setAttribute('server-url', serverUrl);\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => document.body.appendChild(widget));\n } else {\n document.body.appendChild(widget);\n }\n\n // âââ Listen for vaniraai:tool_call events from the widget ââââââââââââââ\n // Integrators can attach their own handlers:\n // document.querySelector('vanira-convai').addEventListener('vaniraai:tool_call', (e) => { ... })\n // But also expose a default global handler slot for convenience.\n widget.addEventListener('vaniraai:tool_call', (e: Event) => {\n const toolCall = (e as CustomEvent).detail;\n console.log('[VaniraAI Widget] Tool call received by host page:', toolCall.name, toolCall.arguments);\n // If integrator registered a global handler, call it\n if (typeof (window as any).__vaniraai_tool_handler === 'function') {\n (window as any).__vaniraai_tool_handler(toolCall, {\n sendResult: (result: any) => {\n // Future: wire back to widget vaniraClient\n console.log('[VaniraAI] sendResult called:', result);\n }\n });\n }\n });\n }\n}\n"],"names":["HASURA_URL","ConfigService","widgetId","query","widget","_a","clientData","_b","error","CHAT_URL","ChatService","url","prospectGroupId","mutation","data","agentId","prospectId","response","content","chatId","uiPayload","message","onChunk","onWidget","onDone","payload","reader","decoder","assistantContent","buffer","newChatId","done","value","lines","line","trimmedLine","parsed","_d","_c","inboxId","sender","onMessage","es","reconnectAttempts","isClosed","connect","event","isOutgoing","hasContent","isNotAI","e","err","delay","clientId","widgetMode","baseWorkerUrl","AbstractWidgetProvider","config","__publicField","WebRTCClient","stream","track","text","checkConnectionState","isConnected","_e","isFailed","_f","_g","_h","_i","_j","_k","offer","answer","resolve","checkState","msg","callId","result","context","actionName","token","graphqlEndpoint","VaniraAI","callback","cb","serverUrl","isFinal","rawCall","toolCall","toolCallId","errorMessage","status","_documentCurrentScript","__vite_import_meta_env__","method","_SessionManager","safeId","existing","age","isOwnTab","isStaletab","draft","hadPrior","session","role","msgs","found","i","id","ev","raw","SessionManager","MALE_ICON_BASE64","FEMALE_ICON_BASE64","generateThemeVars","primary","secondary","widgetStyles","icons","industryIcons","widgetIcons","name","svg","FloatingButton","onClick","initialIcon","rect","onPointerMove","moveEvent","maxX","maxY","onPointerUp","upEvent","iconHtml","positionStyle","s","prop","val","str","Panel","onClose","title","controls","element","position","VoiceOverlay","onHangup","primaryColor","secondaryColor","onCallEnded","shine","phoneSvg","greenDot","connectedText","sDot","sTxt","footer","duration","startedAt","mode","l","diff","mins","secs","enable","ChatWindow","onSend","brandingArea","date","timestamp","wrapper","msgDiv","ts","lastWrapper","lastMsg","buttons","buttonsContainer","btn","buttonEl","overrideText","isTyping","dot","durationMs","label","card","AvatarView","avatarUrl","sourceUrl","isVideo","mediaElement","vid","img","VoiceOrb","orbContainer","FloatingWelcomeChips","onChipClick","chips","style","chip","index","AbstractVoiceView","onStartCall","active","VoiceOnlyView","ChatOnlyView","onSendMessage","AbstractChatView","chatEl","triggerBtn","inputArea","ChatVoiceView","AvatarOnlyView","avatarEl","ChatAvatarView","iconDiv","sendBtn","VaniraChatAdapter","onResponse","onStream","onChatIdUpdate","newId","file","messageId","action","_VaniraInternalProvider","key","claimed","cw","visibleMessages","callKey","callRecords","entries","m","r","a","b","entry","reason","type","AudioContextClass","ctx","osc","gain","now","forceNew","welcome","welcomeText","fallback","callContext","client","root","animStyle","baseCss","posStyles","replyText","hasPlayedReceive","streamText","VaniraInternalProvider","WidgetProviderFactory","VaniraWidget","initialConfig","currentScript","gradient"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
|