@1interface/voice-core 0.1.0 → 0.2.0-pipecat.0

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/index.d.ts CHANGED
@@ -11,21 +11,10 @@ import { Reducer } from '@reduxjs/toolkit';
11
11
  import { Storage as Storage_2 } from '@1interface/shared-core';
12
12
  import { ThunkAction } from '@reduxjs/toolkit';
13
13
  import { ThunkDispatch } from '@reduxjs/toolkit';
14
+ import { Transport } from '@pipecat-ai/client-js';
14
15
  import { UnknownAction } from '@reduxjs/toolkit';
15
16
 
16
- export declare interface AudioCapture {
17
- open(opts: AudioCaptureOpenOptions): void;
18
- setMuted(muted: boolean): void;
19
- close(): void;
20
- }
21
-
22
- export declare interface AudioCaptureOpenOptions {
23
- micDeviceId: string | null;
24
- initialMuted: boolean;
25
- onChunk: (buffer: ArrayBuffer) => void;
26
- onLoadingChange?: (loading: boolean) => void;
27
- onError?: (error: unknown) => void;
28
- }
17
+ export declare const attachBrowserBotAudioTrack: BotAudioTrackAttacher;
29
18
 
30
19
  export declare interface AudioDeviceInfo {
31
20
  deviceId: string;
@@ -42,46 +31,26 @@ export declare interface AudioDevicesSnapshot {
42
31
  speakers: AudioDeviceInfo[];
43
32
  }
44
33
 
45
- declare interface AudioEntry {
46
- pcmInt16: Int16Array;
47
- sampleRate: number;
48
- }
49
-
50
34
  export declare interface AudioPlatform {
51
- createCapture(): AudioCapture;
52
- createPlayer(): AudioPlayer;
53
- createThinkingSound(): ThinkingSound;
35
+ attachBotAudioTrack: BotAudioTrackAttacher;
54
36
  readonly devices: AudioDevices;
55
37
  requestMicPermission(): Promise<MicPermissionResult>;
56
- requiresSoftwareAecMute?: boolean;
57
38
  }
58
39
 
59
40
  export declare const AudioPlatformContext: Context<AudioPlatform>;
60
41
 
61
- export declare interface AudioPlayer {
62
- play(pcmBytes: ArrayBuffer, speakerId?: string): void;
63
- setPrerollProvider(provider: (() => number) | null): void;
64
- readonly remainingSeconds: number;
65
- onDrained(callback: () => void): void;
66
- resetForNewSegment(): void;
67
- stop(): void;
68
- destroy(): void;
42
+ export declare type BotAudioTrackAttacher = (track: MediaStreamTrack) => () => void;
43
+
44
+ export declare interface BotTurnSegment {
45
+ id: number;
46
+ text: string;
47
+ spokenChars: number;
69
48
  }
70
49
 
71
- export declare class BrowserAudioCapture implements AudioCapture {
72
- private ctx;
73
- private stream;
74
- private source;
75
- private gain;
76
- private worklet;
77
- private worker;
78
- private visibilityHandler;
79
- private opening;
80
- private cancelled;
81
- private opts;
82
- open(opts: AudioCaptureOpenOptions): void;
83
- setMuted(muted: boolean): void;
84
- close(): void;
50
+ export declare interface BotTurnState {
51
+ active: boolean;
52
+ chatMsgId: string | null;
53
+ segments: BotTurnSegment[];
85
54
  }
86
55
 
87
56
  export declare class BrowserAudioDevices implements AudioDevices {
@@ -91,55 +60,19 @@ export declare class BrowserAudioDevices implements AudioDevices {
91
60
 
92
61
  export declare const browserAudioPlatform: AudioPlatform;
93
62
 
94
- export declare class BrowserAudioPlayer implements AudioPlayer {
95
- private ctx;
96
- private masterGain;
97
- private currentSpeakerId;
98
- private nextPlayTime;
99
- private doneTimer;
100
- private isFirstChunk;
101
- private prerollProvider;
102
- private activeSources;
103
- setPrerollProvider(provider: (() => number) | null): void;
104
- play(pcmBytes: ArrayBuffer, speakerId?: string): void;
105
- get remainingSeconds(): number;
106
- onDrained(callback: () => void): void;
107
- resetForNewSegment(): void;
108
- stop(): void;
109
- destroy(): void;
110
- }
111
-
112
- export declare class BrowserThinkingSound implements ThinkingSound {
113
- private audio;
114
- private timer;
115
- private pendingPlay;
116
- private pendingAction;
117
- unlock(): void;
118
- start(remainingAudioSeconds: number): void;
119
- pause(): void;
120
- resume(remainingAudioSeconds?: number): void;
121
- stop(): void;
122
- destroy(): void;
123
- private _doPlay;
124
- }
125
-
126
- export declare function clearAudioBuffer(): void;
127
-
128
- export declare function computeAdaptivePreroll(arrivals: number[]): number;
129
-
130
- export declare function createAccumulator(sampleRate: number): string;
131
-
132
- export declare function finalizeAudio(id: string): void;
133
-
134
- export declare function getAudio(id: string): AudioEntry | undefined;
63
+ export declare const clearBotTurn: ActionCreatorWithoutPayload<"voice/clearBotTurn">;
135
64
 
136
65
  export declare const hydrateVoice: (storage: Storage_2) => ThunkAction<Promise<void>, unknown, unknown, UnknownAction>;
137
66
 
138
- declare interface MicPermissionResult {
67
+ export declare interface MicPermissionResult {
139
68
  granted: boolean;
140
69
  error?: unknown;
141
70
  }
142
71
 
72
+ export declare const openBotTurn: ActionCreatorWithOptionalPayload< {
73
+ chatMsgId: string;
74
+ }, "voice/openBotTurn">;
75
+
143
76
  export declare const ORB_STATE_CONFIG: Record<string, OrbStateConfig>;
144
77
 
145
78
  declare interface OrbStateConfig {
@@ -148,15 +81,13 @@ declare interface OrbStateConfig {
148
81
  scale: number;
149
82
  }
150
83
 
151
- export declare function pushChunk(id: string, chunk: ArrayBuffer): void;
152
-
153
84
  export declare const resetIndicatorState: ActionCreatorWithoutPayload<"voice/resetIndicatorState">;
154
85
 
155
86
  export declare const setConnectionStatus: ActionCreatorWithOptionalPayload<VoiceConnectionStatus, "voice/setConnectionStatus">;
156
87
 
157
88
  export declare const setError: ActionCreatorWithOptionalPayload<string, "voice/setError">;
158
89
 
159
- export declare const setFirstAssistantMessageComplete: ActionCreatorWithOptionalPayload<boolean, "voice/setFirstAssistantMessageComplete">;
90
+ export declare const setInterimTranscript: ActionCreatorWithOptionalPayload<string, "voice/setInterimTranscript">;
160
91
 
161
92
  export declare const setIsAgentWorking: ActionCreatorWithOptionalPayload<boolean, "voice/setIsAgentWorking">;
162
93
 
@@ -172,16 +103,15 @@ export declare const setSelectedMicId: ActionCreatorWithOptionalPayload<string,
172
103
 
173
104
  export declare const setSelectedSpeakerId: ActionCreatorWithOptionalPayload<string, "voice/setSelectedSpeakerId">;
174
105
 
106
+ export declare const setServerMuted: ActionCreatorWithOptionalPayload<boolean, "voice/setServerMuted">;
107
+
175
108
  export declare const setStatusText: ActionCreatorWithOptionalPayload<string, "voice/setStatusText">;
176
109
 
177
- export declare interface ThinkingSound {
178
- unlock(): void;
179
- start(remainingAudioSeconds: number): void;
180
- pause(): void;
181
- resume(remainingAudioSeconds?: number): void;
182
- stop(): void;
183
- destroy(): void;
184
- }
110
+ export declare const upsertBotSegment: ActionCreatorWithOptionalPayload< {
111
+ id: number;
112
+ text: string;
113
+ spokenChars: number;
114
+ }, "voice/upsertBotSegment">;
185
115
 
186
116
  export declare const useAudioPlatform: () => AudioPlatform;
187
117
 
@@ -193,41 +123,13 @@ export declare function useMediaDevices(): {
193
123
 
194
124
  export declare const useVoice: () => VoiceContextValue;
195
125
 
196
- export declare function useVoiceAudioPlayback(audioId?: string): {
197
- playing: boolean;
198
- toggle: () => void;
199
- hasAudio: boolean;
200
- };
201
-
202
126
  export declare function useVoiceDisplayState(loading: boolean, errored: boolean, effectiveMuted?: boolean): VoiceDisplayState;
203
127
 
204
- export declare function useVoiceMicCapture({ micOpen, muted, onChunk }: UseVoiceMicCaptureOptions): {
205
- loading: boolean;
206
- errored: boolean;
207
- };
208
-
209
- declare interface UseVoiceMicCaptureOptions {
210
- micOpen: boolean;
211
- muted: boolean;
212
- onChunk: (buf: ArrayBuffer) => void;
213
- }
214
-
215
- export declare const useVoiceProviderValue: ({ conversationId, voiceBridge, assistantStartsConversation, }: VoiceProviderParams) => VoiceContextValue;
128
+ export declare const useVoiceProviderValue: ({ conversationId, voiceBridge, transportFactory, }: VoiceProviderParams) => VoiceContextValue;
216
129
 
217
130
  export declare const useVoiceUI: () => VoiceUIContextValue;
218
131
 
219
- export declare function useVoiceWebSocket(conversationId: string | null, bridge: VoiceChatBridge): {
220
- connect: () => void;
221
- disconnect: (reason?: VoiceDisconnectReason) => void;
222
- sendAudioChunk: (buf: ArrayBuffer) => void;
223
- sendText: (text: string) => void;
224
- };
225
-
226
- export declare const VOICE_AUTH_ERROR_PATTERNS: readonly RegExp[];
227
-
228
- export declare const VOICE_BARGE_IN_DELAY_MS = 400;
229
-
230
- export declare const VOICE_CHUNK_SAMPLES = 2048;
132
+ export declare const VOICE_CONNECT_TIMEOUT_MS = 15000;
231
133
 
232
134
  export declare const VOICE_CONNECTION_STATUSES: {
233
135
  readonly DISCONNECTED: "disconnected";
@@ -235,13 +137,6 @@ export declare const VOICE_CONNECTION_STATUSES: {
235
137
  readonly CONNECTED: "connected";
236
138
  };
237
139
 
238
- declare const VOICE_DISCONNECT_REASONS: {
239
- readonly USER: "user";
240
- readonly CONV_CHANGE: "conv-change";
241
- readonly LOGOUT: "logout";
242
- readonly WATCHDOG: "watchdog";
243
- };
244
-
245
140
  export declare const VOICE_DISPLAY_STATES: {
246
141
  readonly OFFLINE: "offline";
247
142
  readonly CONNECTING: "connecting";
@@ -254,11 +149,10 @@ export declare const VOICE_DISPLAY_STATES: {
254
149
  readonly SPEAKING: "speaking";
255
150
  };
256
151
 
257
- export declare const VOICE_FATAL_ERROR_PATTERNS: readonly RegExp[];
258
-
259
- export declare const VOICE_KEEPALIVE_INTERVAL_MS = 20000;
260
-
261
- export declare const VOICE_PCM_INT16_MAX = 32768;
152
+ export declare const VOICE_PIPELINE_MODES: {
153
+ readonly CASCADE: "cascade";
154
+ readonly REALTIME: "realtime";
155
+ };
262
156
 
263
157
  export declare const VOICE_PIPELINE_STATUSES: {
264
158
  readonly IDLE: "idle";
@@ -267,62 +161,19 @@ export declare const VOICE_PIPELINE_STATUSES: {
267
161
  readonly SPEAKING: "speaking";
268
162
  };
269
163
 
270
- export declare const VOICE_PREROLL_DEFAULT_SECONDS = 0.2;
271
-
272
- export declare const VOICE_PREROLL_JITTER_WINDOW = 30;
273
-
274
- export declare const VOICE_PREROLL_MAX_SECONDS = 0.5;
275
-
276
- export declare const VOICE_PREROLL_MIN_SAMPLES = 5;
277
-
278
- export declare const VOICE_PREROLL_MIN_SECONDS = 0.1;
279
-
280
- export declare const VOICE_SAMPLE_RATE = 24000;
281
-
282
164
  export declare const VOICE_STORAGE_KEYS: {
283
165
  readonly SELECTED_MIC_ID: "voice_selectedMicId";
284
166
  readonly SELECTED_SPEAKER_ID: "voice_selectedSpeakerId";
285
167
  };
286
168
 
287
- export declare const VOICE_TERMINAL_ERROR_PATTERNS: readonly RegExp[];
288
-
289
- export declare const VOICE_THINKING_SOUND_DELAY_MS = 300;
290
-
291
- export declare const VOICE_THINKING_SOUND_PATH = "/sounds/thinking-sound.mp3";
292
-
293
- export declare const VOICE_THINKING_SOUND_VOLUME = 0.5;
294
-
295
- export declare const VOICE_WS_CLIENT: {
296
- readonly START_CONVERSATION: "start_conversation";
297
- readonly TEXT_MESSAGE: "text_message";
298
- readonly STOP_PLAYBACK: "stop_playback";
299
- readonly PING: "ping";
300
- };
301
-
302
- export declare const VOICE_WS_SERVER: {
303
- readonly SPEECH_STARTED: "speech_started";
304
- readonly SPEECH_STOPPED: "speech_stopped";
305
- readonly STT_RESULT: "stt_result";
306
- readonly TEXT_DELTA: "text_delta";
307
- readonly STATUS_UPDATE: "status_update";
308
- readonly STATUS_CLEAR: "clear_status";
309
- readonly TTS_START: "tts_start";
310
- readonly TTS_END: "tts_end";
311
- readonly WIDGET: "widget";
312
- readonly PAYMENT: "payment";
313
- readonly CONVERSATION_TITLE: "conversation_title";
314
- readonly ERROR: "error";
315
- readonly PONG: "pong";
316
- };
317
-
318
169
  export declare type VoiceAppDispatch = Dispatch<UnknownAction>;
319
170
 
320
171
  export declare interface VoiceChatBridge {
321
172
  setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
322
173
  updateStreamingMessage: (chatMsgId: string, content: string) => void;
174
+ addStreamingWidget: (chatMsgId: string, widget: unknown) => void;
323
175
  commitStreamingMessages: () => void;
324
176
  discardStreamingMessages: () => void;
325
- shouldGreetOnConnect: () => boolean;
326
177
  setVoiceSendText: (fn: ((text: string) => void) | null) => void;
327
178
  onPaymentInit?: (init: PaymentInitPayload) => void;
328
179
  onConversationTitle?: (title: string) => void;
@@ -341,22 +192,27 @@ export declare interface VoiceContextValue {
341
192
  toggleMute: () => void;
342
193
  sendText: (text: string) => void;
343
194
  muted: boolean;
344
- micLoading: boolean;
345
- micErrored: boolean;
195
+ serverMuted: boolean;
346
196
  }
347
197
 
348
- declare type VoiceDisconnectReason = (typeof VOICE_DISCONNECT_REASONS)[keyof typeof VOICE_DISCONNECT_REASONS];
349
-
350
198
  export declare type VoiceDisplayState = (typeof VOICE_DISPLAY_STATES)[keyof typeof VOICE_DISPLAY_STATES];
351
199
 
200
+ export declare interface VoiceIceServer {
201
+ urls: string | string[];
202
+ username?: string;
203
+ credential?: string;
204
+ }
205
+
352
206
  export declare const voiceListenerMiddleware: ListenerMiddlewareInstance<unknown, ThunkDispatch<unknown, unknown, UnknownAction>, unknown>;
353
207
 
208
+ export declare type VoicePipelineMode = (typeof VOICE_PIPELINE_MODES)[keyof typeof VOICE_PIPELINE_MODES];
209
+
354
210
  export declare type VoicePipelineStatus = (typeof VOICE_PIPELINE_STATUSES)[keyof typeof VOICE_PIPELINE_STATUSES];
355
211
 
356
212
  export declare interface VoiceProviderParams {
357
213
  conversationId: string | null;
358
214
  voiceBridge: VoiceChatBridge;
359
- assistantStartsConversation: boolean;
215
+ transportFactory: VoiceTransportFactory;
360
216
  }
361
217
 
362
218
  export declare const voiceReducer: Reducer<VoiceState>;
@@ -368,32 +224,24 @@ export declare interface VoiceRootState {
368
224
  };
369
225
  }
370
226
 
371
- export declare interface VoiceServerMessage {
372
- type: string;
373
- text?: string;
374
- message?: string;
375
- token?: string;
376
- message_id?: number;
377
- cancelled?: boolean;
378
- data?: Record<string, unknown>;
379
- [key: string]: unknown;
380
- }
381
-
382
227
  export declare interface VoiceState {
383
228
  connectionStatus: VoiceConnectionStatus;
384
229
  pipelineStatus: VoicePipelineStatus;
385
230
  listeningEnabled: boolean;
386
231
  muted: boolean;
387
- firstAssistantMessageComplete: boolean;
232
+ serverMuted: boolean;
388
233
  statusText: string | null;
389
234
  isAgentWorking: boolean;
390
235
  responseStartTime: number | null;
391
236
  error: string | null;
392
237
  interimTranscript: string | null;
238
+ botTurn: BotTurnState;
393
239
  selectedMicId: string;
394
240
  selectedSpeakerId: string;
395
241
  }
396
242
 
243
+ export declare type VoiceTransportFactory = () => Transport;
244
+
397
245
  export declare const VoiceUIContext: Context<VoiceUIContextValue>;
398
246
 
399
247
  export declare interface VoiceUIContextValue {
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=require("react-redux"),r=require("@reduxjs/toolkit"),n=require("@1interface/shared-core"),s={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected"},c={IDLE:"idle",LISTENING:"listening",PROCESSING:"processing",SPEAKING:"speaking"},i={OFFLINE:"offline",CONNECTING:"connecting",READY:"ready",LOADING:"loading",IDLE:"idle",LISTENING:"listening",MUTED:"muted",PROCESSING:"processing",SPEAKING:"speaking"},o=24e3,a=32768,u="/sounds/thinking-sound.mp3",l=new Set([1006,1011,1012,1013,1014]),d=.2,p="reset",g={START_CONVERSATION:"start_conversation",TEXT_MESSAGE:"text_message",STOP_PLAYBACK:"stop_playback",PING:"ping"},S=[/rejected/i,/unauthori[sz]ed/i,/forbidden/i,/\b40[13]\b/],m=[/\b402\b/,/\b429\b/,/rate[\s-]?limit/i],h=[...S,...m],E={SPEECH_STARTED:"speech_started",SPEECH_STOPPED:"speech_stopped",STT_RESULT:"stt_result",TEXT_DELTA:"text_delta",STATUS_UPDATE:"status_update",STATUS_CLEAR:"clear_status",TTS_START:"tts_start",TTS_END:"tts_end",WIDGET:"widget",PAYMENT:"payment",CONVERSATION_TITLE:"conversation_title",ERROR:"error",PONG:"pong"},f={SELECTED_MIC_ID:"voice_selectedMicId",SELECTED_SPEAKER_ID:"voice_selectedSpeakerId"};function T(){return{connectionStatus:s.DISCONNECTED,pipelineStatus:c.IDLE,listeningEnabled:!1,muted:!1,firstAssistantMessageComplete:!1,statusText:null,isAgentWorking:!1,responseStartTime:null,error:null,interimTranscript:null,selectedMicId:"",selectedSpeakerId:""}}const I=T(),_=r.createSlice({name:"voice",initialState:I,reducers:{setConnectionStatus(e,t){e.connectionStatus=t.payload},setPipelineStatus(e,t){e.pipelineStatus=t.payload},setListeningEnabled(e,t){e.listeningEnabled=t.payload},setStatusText(e,t){e.statusText=t.payload},setIsAgentWorking(e,t){e.isAgentWorking=t.payload},setResponseStartTime(e,t){e.responseStartTime=t.payload},setError(e,t){e.error=t.payload},setInterimTranscript(e,t){e.interimTranscript=t.payload},setMuted(e,t){e.muted=t.payload},setFirstAssistantMessageComplete(e,t){e.firstAssistantMessageComplete=t.payload},setSelectedMicId(e,t){e.selectedMicId=t.payload},setSelectedSpeakerId(e,t){e.selectedSpeakerId=t.payload},resetVoiceState:()=>T(),resetIndicatorState(e){e.statusText=null,e.isAgentWorking=!1,e.responseStartTime=null}}}),{setConnectionStatus:C,setPipelineStatus:v,setListeningEnabled:A,setMuted:R,setFirstAssistantMessageComplete:y,setStatusText:k,setIsAgentWorking:N,setResponseStartTime:w,setError:x,setInterimTranscript:O,setSelectedMicId:P,setSelectedSpeakerId:b,resetVoiceState:D,resetIndicatorState:M}=_.actions,L=_.reducer,V=new Map,G=new Map;let W=0;function U(e){const t="voice_audio_"+ ++W;return G.set(t,{chunks:[],sampleRate:e}),t}function K(e,t){const r=G.get(e);r&&r.chunks.push(t)}function F(e){const t=G.get(e);if(!t||0===t.chunks.length)return void G.delete(e);const r=t.chunks.reduce((e,t)=>e+t.byteLength,0),n=new Int16Array(r/2);let s=0;for(const e of t.chunks)n.set(new Int16Array(e),s),s+=e.byteLength/2;V.set(e,{pcmInt16:n,sampleRate:t.sampleRate}),G.delete(e)}function B(e){return V.get(e)}function H(){V.clear(),G.clear()}function q(e){if(e.length<5)return d;let t=0,r=0;for(let n=1;n<e.length;n++){const s=e[n]-e[n-1];t+=s,s>r&&(r=s)}return Math.min(.5,Math.max(.1,(r-t/(e.length-1))/1e3))}class Y{ctx=null;masterGain=null;currentSpeakerId=void 0;nextPlayTime=0;doneTimer=null;isFirstChunk=!0;prerollProvider=null;activeSources=new Set;setPrerollProvider(e){this.prerollProvider=e}play(e,t){this.ctx&&t!==this.currentSpeakerId&&(this.ctx.close(),this.ctx=null,this.masterGain=null),this.ctx||(this.ctx=new AudioContext({sampleRate:o,...t?{sinkId:t}:{}}),this.masterGain=this.ctx.createGain(),this.masterGain.connect(this.ctx.destination),this.currentSpeakerId=t);const r=this.ctx,n=new Int16Array(e),s=new Float32Array(n.length);for(let e=0;e<n.length;e++)s[e]=n[e]/a;const c=r.createBuffer(1,s.length,o);c.getChannelData(0).set(s);const i=r.createBufferSource();i.buffer=c,i.connect(this.masterGain),this.activeSources.add(i),i.onended=()=>this.activeSources.delete(i);const u=r.currentTime;let l=Math.max(u,this.nextPlayTime);if(this.isFirstChunk){this.isFirstChunk=!1;const e=this.prerollProvider?this.prerollProvider():d;l=Math.max(l,u+e)}i.start(l),this.nextPlayTime=l+c.duration}get remainingSeconds(){return this.ctx?Math.max(0,this.nextPlayTime-this.ctx.currentTime):0}onDrained(e){this.doneTimer&&clearTimeout(this.doneTimer);const t=this.remainingSeconds;t<=0?e():this.doneTimer=setTimeout(()=>{this.doneTimer=null,e()},1e3*t)}resetForNewSegment(){this.isFirstChunk=!0}stop(){this.doneTimer&&(clearTimeout(this.doneTimer),this.doneTimer=null);for(const e of this.activeSources)try{e.stop()}catch(e){}this.activeSources.clear(),this.nextPlayTime=0,this.isFirstChunk=!0}destroy(){this.stop(),this.ctx&&(this.ctx.close(),this.ctx=null,this.masterGain=null)}}const $=e.createContext(null),J=()=>{const t=e.useContext($);if(!t)throw new Error("useAudioPlatform must be used inside <AudioPlatformProvider>. <VoiceProvider> mounts one by default; if you replaced VoiceProvider, you must wire your own.");return t};function j(e,t){try{e()}catch(e){n.logger.error({message:"Voice WS bridge call threw",api_name:"voice-ws",context:t,error_message:e instanceof Error?e.message:String(e)})}}function X(r,i){const a=t.useDispatch(),u=e.useRef(c.IDLE),p=e.useRef(""),h=e.useRef(null),f=t.useSelector(e=>e.voice.pipelineStatus),T=t.useSelector(e=>e.voice.selectedSpeakerId),I=t.useSelector(e=>e.voice.statusText),_=t.useSelector(e=>e.auth.accessToken);u.current=f,p.current=T,h.current=I;const R=e.useRef(null),P=e.useRef(0),b=J(),D=e.useRef(null);D.current||(D.current=b.createPlayer());const M=e.useRef(null);M.current||(M.current=b.createThinkingSound());const L=e.useRef([]),V=e.useRef(null),G=e.useRef(!1),W=e.useRef(!1),B=e.useRef(null),H=e.useRef(null),Y=e.useRef(null),$=e.useRef(null),X=e.useRef(null),z=e.useRef(!1),Z=e.useRef(null),Q=e.useRef(0),ee=e.useRef(!1),te=e.useRef(0),re=e.useRef(0),ne=e.useRef(0),se=e.useRef(0),ce=e.useRef(0),ie=e.useRef(0),oe=e.useRef(null),ae=e.useRef(null),ue=e.useRef(new Map),le=e.useRef(new Map),de=e.useRef([]),pe=e.useRef(new Set),ge=e.useRef(null),Se=e.useRef(!1),me=e.useRef(null),he=e.useRef(!1),Ee=e.useRef(!1),fe=e.useRef(""),Te=e.useCallback(()=>{const e=de.current;0!==e.length&&(de.current=[],j(()=>ve.current.setMessages(t=>[...t,...e]),"widget-flush"))},[]),Ie=e.useCallback(()=>{if(null!=ae.current)return;const e=Date.now();ae.current=e,a(w(e)),a(n.clearLastResponseTime())},[a]),_e=e.useCallback(()=>{const e=ae.current;ae.current=null,a(w(null)),null!=e&&a(n.setLastResponseTime(Date.now()-e))},[a]),Ce=e.useCallback(()=>{ae.current=null,a(w(null))},[a]),ve=e.useRef(i);ve.current=i;const Ae=e.useCallback(()=>{B.current&&(F(B.current),B.current=null)},[a]),Re=e.useCallback(()=>{M.current.stop(),Ae(),D.current.stop()},[Ae]),ye=e.useCallback((e=n.INDICATOR_TIMER_ACTIONS.KEEP)=>{a(k(null)),a(N(!1)),e===n.INDICATOR_TIMER_ACTIONS.FINALIZE?_e():e===n.INDICATOR_TIMER_ACTIONS.CANCEL&&Ce()},[a,_e,Ce]),ke=e.useRef({setStatusText:e=>a(k(e||null)),setIsAgentWorking:e=>a(N(e)),appendStreamText:(e,t)=>{if(null==t)return;const r=ue.current.get(t);if(!r)return;const n=(le.current.get(r)??"")+e;le.current.set(r,n),W.current||ve.current.updateStreamingMessage(r,n)},pushWidget:e=>{const t=`voice-widget-${n.generateUniqueId()}`,r={id:t,msg_id:t,sender:"agent",message:"",timestamp:(new Date).toISOString(),widget:[e],message_type:["widget"]};de.current.push(r)},onPayment:e=>ve.current.onPaymentInit?.(e),onConversationTitle:e=>ve.current.onConversationTitle?.(e),onError:e=>{n.logger.error({message:"Voice WS server error",api_name:"voice-ws",error_message:e}),a(x(e))},onStatusActive:e=>{Ee.current=!0,fe.current=e,Ie(),M.current?.start(D.current?.remainingSeconds??0)}}),Ne=e.useCallback(()=>{if(R.current&&R.current.readyState<=WebSocket.OPEN)return void n.logger.debug({message:"Voice WS connect() skipped — already connecting/open",api_name:"voice-ws",ready_state:R.current.readyState});if(!r)return void n.logger.debug({message:"Voice WS connect() skipped — no conversationId",api_name:"voice-ws"});if(n.isTokenAboutToExpire(n.readTokenExpiresAt())&&re.current<1){re.current+=1;const e=ne.current;return n.logger.debug({message:"Voice WS refreshing token before connect (about to expire)",api_name:"voice-ws"}),void Promise.resolve(n.getTokenRefreshHandler()?.()).then(()=>{e===ne.current&&we.current()})}n.logger.debug({message:"Voice WS connecting",api_name:"voice-ws",generation:P.current+1}),M.current.unlock();const e=++P.current,t=ne.current,i=Date.now();ce.current=i,ie.current=i,oe.current="connecting";const f=n.readAccessToken()??"",T=function(e,t){const r="undefined"!=typeof window?window.location?.origin:void 0,s=new URL(n.API_ENDPOINTS.CONVERSATION_STREAM(e),r);s.protocol="https:"===s.protocol?"wss:":"ws:",t&&s.searchParams.append("access_token",t);const c=function(){const e=n.getCustomHeaders();for(const[t,r]of Object.entries(e))if("x-client-id"===t.toLowerCase()&&r)return r;return null}();return c&&s.searchParams.append("client_id",c),s.toString()}(r,f);let I=!1;const _=new WebSocket(T);R.current=_,a(C(s.CONNECTING)),_.binaryType="arraybuffer",_.onopen=()=>{I=!0,n.logger.debug({message:"Voice WS open",api_name:"voice-ws",generation:e}),a(C(s.CONNECTED)),a(A(!0)),ve.current.shouldGreetOnConnect()&&(_.send(JSON.stringify({type:g.START_CONVERSATION})),a(N(!0)),Ie()),a(v(c.IDLE)),ue.current.clear(),pe.current.clear(),ge.current=null,Se.current=!1,me.current=null,W.current=!1,he.current=!1,Ee.current=!1,fe.current="",de.current=[],L.current=[],V.current=null,G.current=!1,a(y(!1)),D.current.setPrerollProvider(()=>V.current??d),$.current&&(clearTimeout($.current),$.current=null);const t=Date.now();ce.current=t,ie.current=t,oe.current="open",X.current&&clearInterval(X.current),X.current=setInterval(()=>{const t=Date.now(),r=t-ce.current;if(r>3e4)return n.logger.warn({message:"Voice WS PONG watchdog tripped — closing presumed-dead socket",api_name:"voice-ws",generation:e,ms_since_last_pong:r,ms_since_last_event:t-ie.current,last_event_type:oe.current,pipeline_status:u.current}),z.current=!0,X.current&&(clearInterval(X.current),X.current=null),_.readyState<=WebSocket.OPEN&&_.close(),void b(1006,"watchdog forced",!1);n.logger.debug({message:"Voice WS keepalive tick",api_name:"voice-ws",generation:e,current_generation:P.current,ready_state:_.readyState,will_send:_.readyState===WebSocket.OPEN}),_.readyState===WebSocket.OPEN&&_.send(JSON.stringify({type:g.PING}))},2e4)};let w=0;_.onmessage=t=>{if(e!==P.current)return;if(t.data instanceof ArrayBuffer){ie.current=Date.now(),oe.current="binary",w++,1===w&&(H.current&&clearInterval(H.current),H.current=setInterval(()=>{w>0&&n.logger.debug({message:"Voice WS audio chunks",api_name:"voice-ws",chunks:w})},2e3)),B.current&&K(B.current,t.data);const e=L.current;if(e.push(performance.now()),e.length>30&&e.shift(),1===w&&W.current){W.current=!1;for(const[e,t]of le.current)t&&ve.current.updateStreamingMessage(e,t)}return void D.current.play(t.data,p.current||void 0)}let r;try{r=JSON.parse(t.data)}catch{return}const s=r.type,i=r.data??r;switch(ie.current=Date.now(),oe.current=s,s){case E.SPEECH_STARTED:if((se.current>0?performance.now()-se.current:1/0)<500)break;if(_.send(JSON.stringify({type:g.STOP_PLAYBACK})),he.current=!0,Se.current=!1,a(O(null)),M.current.stop(),Y.current&&clearTimeout(Y.current),Y.current=setTimeout(()=>{D.current.stop(),Y.current=null},400),a(v(c.LISTENING)),ye(n.INDICATOR_TIMER_ACTIONS.KEEP),Ee.current);else{(u.current===c.SPEAKING||u.current===c.PROCESSING)&&null!=ge.current&&(pe.current.add(ge.current),ge.current=null);for(const e of ue.current.keys())pe.current.add(e);if(W.current){W.current=!1;for(const[e,t]of le.current)t&&ve.current.updateStreamingMessage(e,t)}j(()=>ve.current.commitStreamingMessages(),"barge-in"),Te(),le.current.clear(),Ce()}break;case E.SPEECH_STOPPED:he.current=!1,Se.current=!0,me.current=ge.current,Y.current&&(clearTimeout(Y.current),Y.current=null),a(v(c.PROCESSING)),Ee.current||(a(N(!0)),a(k(null)),Ie());break;case E.STT_RESULT:{const e=i.message_id,t=null!=e&&e===me.current;if(null!=e&&pe.current.has(e)&&!t)break;null==e||t||(ge.current=e);const r=i.text;if(!Se.current&&!t){r&&a(O(r));break}if(Se.current=!1,me.current=null,a(O(null)),r&&r.trim()){const t=e,s={id:`voice-user-${n.generateUniqueId()}`,sender:"user",message:r,timestamp:(new Date).toISOString()};ve.current.setMessages(e=>{if(null!=t){const r=ue.current.get(t);if(r){const t=e.findIndex(e=>e.id===r);if(-1!==t){const r=[...e];return r.splice(t,0,s),r}}}return[...e,s]})}break}case E.TEXT_DELTA:{const e=i.token,t=i.message_id;if(!e||null==t)break;if(pe.current.has(t))break;n.handleSharedEvent({kind:"text",text:e,messageId:t},ke.current);break}case E.STATUS_UPDATE:if(he.current)break;n.handleSharedEvent({kind:"status_update",statusText:i.text},ke.current);break;case E.WIDGET:if(!r.data)break;ye(n.INDICATOR_TIMER_ACTIONS.KEEP),n.handleSharedEvent({kind:"widget",widget:r.data},ke.current);break;case E.PAYMENT:if(!r.data)break;n.handleSharedEvent({kind:"payment",payment:r.data},ke.current);break;case E.CONVERSATION_TITLE:{const e="string"==typeof i.text?i.text.trim():"";e&&n.handleSharedEvent({kind:"conversation_title",title:e},ke.current);break}case E.STATUS_CLEAR:Ee.current=!1,fe.current="",M.current.stop(),ye(n.INDICATOR_TIMER_ACTIONS.KEEP);break;case E.TTS_START:{const e=i.message_id;if(null!=e&&pe.current.has(e)){D.current.stop(),Ae();break}if(ge.current=null,se.current=performance.now(),M.current.pause(),w=0,L.current=[],D.current.stop(),Ae(),B.current=U(o),null!=e&&!ue.current.has(e)){const t=`voice-agent-${n.generateUniqueId()}`;ue.current.set(e,t),le.current.set(t,"")}W.current=!0,ye(Ee.current?n.INDICATOR_TIMER_ACTIONS.KEEP:n.INDICATOR_TIMER_ACTIONS.FINALIZE),a(v(c.SPEAKING));break}case E.TTS_END:if(se.current=0,H.current&&(clearInterval(H.current),H.current=null),w=0,Ae(),i.cancelled&&D.current.stop(),L.current.length>0&&(V.current=q(L.current)),W.current){W.current=!1;for(const[e,t]of le.current)t&&ve.current.updateStreamingMessage(e,t)}j(()=>ve.current.commitStreamingMessages(),"tts-end"),Te();let e=!1;const t=()=>{e||(e=!0,$.current&&(clearTimeout($.current),$.current=null),a(v(c.IDLE)),G.current||(G.current=!0,a(y(!0))),null!=h.current&&M.current.resume(),j(()=>ve.current.commitStreamingMessages(),"drain"),Te(),Ee.current&&(a(N(!0)),a(k(fe.current)),M.current.start(D.current.remainingSeconds)))};D.current.onDrained(t),$.current&&clearTimeout($.current),$.current=setTimeout(t,1e3*(D.current.remainingSeconds+5));break;case E.ERROR:{const e=i.message||"Voice error";n.handleSharedEvent({kind:"error",error:e},ke.current),a(v(c.IDLE)),ye(n.INDICATOR_TIMER_ACTIONS.CANCEL);{const t=S.some(t=>t.test(e)),r=m.some(t=>t.test(e));(t||r)&&(t&&(ee.current=!0),n.logger.warn({message:"Voice WS fatal error — tearing down connection",api_name:"voice-ws",error_message:e,auth_recoverable:t}),_.close())}break}case E.PONG:ce.current=Date.now(),Q.current=0,te.current=0,re.current=0;break;default:n.logger.warn({message:"Voice WS unhandled event",api_name:"voice-ws",event_type:s})}};let x=!1;const b=(i,o,d)=>{if(x)return;if(x=!0,e!==P.current)return void n.logger.debug({message:"Voice WS closed (superseded)",api_name:"voice-ws",code:i,reason:o});const p=Date.now(),g={api_name:"voice-ws",code:i,reason:o||null,was_clean:d,generation:e,ms_since_last_event:p-ie.current,ms_since_last_pong:p-ce.current,last_event_type:oe.current,pipeline_status:u.current};!0===d||1e3===i||1005===i?n.logger.info({message:"Voice WS closed (clean)",...g}):n.logger.warn({message:"Voice WS closed (abnormal)",...g}),X.current&&(clearInterval(X.current),X.current=null),H.current&&(clearInterval(H.current),H.current=null),$.current&&(clearTimeout($.current),$.current=null),a(A(!1)),a(v(c.IDLE)),a(C(s.DISCONNECTED)),ye(n.INDICATOR_TIMER_ACTIONS.CANCEL),j(()=>ve.current.commitStreamingMessages(),"onclose"),Te(),le.current.clear(),Ee.current=!1,Se.current=!1,a(O(null)),fe.current="",me.current=null;const S=!I||ee.current;if(ee.current=!1,S)return void(t===ne.current&&te.current<1&&null!=r&&(te.current+=1,n.logger.info({message:"Voice WS auth-attributed close — refreshing session",api_name:"voice-ws",generation:e,attempt:te.current,last_close_code:i}),(async()=>{const r=await(n.getTokenRefreshHandler()?.());t===ne.current&&(r?we.current():n.logger.warn({message:"Voice WS auth refresh failed — leaving disconnected (no reconnect)",api_name:"voice-ws",generation:e}))})()));const m=z.current||l.has(i);z.current=!1;const h=Q.current>=3,E=m&&!h&&null!=r;m&&h&&n.logger.warn({message:"Voice WS auto-reconnect cap exhausted — giving up",api_name:"voice-ws",generation:e,attempts:Q.current,last_close_code:i}),E&&(Q.current+=1,n.logger.info({message:"Voice WS auto-reconnecting after abnormal close",api_name:"voice-ws",generation:e,attempt:Q.current,delay_ms:1e3,last_close_code:i}),Z.current&&clearTimeout(Z.current),Z.current=setTimeout(()=>{Z.current=null,we.current()},1e3))};_.onclose=e=>b(e.code,e.reason,e.wasClean),_.onerror=()=>{if(e!==P.current)return;const t=Date.now();n.logger.warn({message:"Voice WS error event",api_name:"voice-ws",generation:e,ready_state:_.readyState,ms_since_last_event:t-ie.current,ms_since_last_pong:t-ce.current,last_event_type:oe.current,pipeline_status:u.current}),a(C(s.DISCONNECTED))}},[r,a,Ae,Ie,_e,Ce,ye]),we=e.useRef(Ne);e.useEffect(()=>{we.current=Ne},[Ne]);const xe=e.useCallback(e=>{const t=R.current;t&&t.readyState===WebSocket.OPEN&&t.send(e)},[]),Oe=e.useCallback(e=>{const t=R.current;if(!t||t.readyState!==WebSocket.OPEN)return;t.send(JSON.stringify({type:g.STOP_PLAYBACK})),Re(),t.send(JSON.stringify({type:g.TEXT_MESSAGE,text:e}));const r=`voice-user-${n.generateUniqueId()}`;ve.current.setMessages(t=>[...t,{id:r,sender:"user",message:e,timestamp:(new Date).toISOString()}]),a(N(!0)),a(k(null)),Ie(),a(v(c.PROCESSING))},[a,Re,Ie]),Pe=e.useCallback((e="user")=>{const t=R.current;n.logger.info({message:"Voice WS disconnect() called",api_name:"voice-ws",reason:e,had_ws:null!==t,ready_state:t?.readyState,generation:P.current}),z.current=!1,Z.current&&(clearTimeout(Z.current),Z.current=null),Q.current=0,te.current=0,re.current=0,ne.current+=1,t&&t.readyState<=WebSocket.OPEN&&t.close(),R.current=null,X.current&&(clearInterval(X.current),X.current=null),H.current&&(clearInterval(H.current),H.current=null),Y.current&&(clearTimeout(Y.current),Y.current=null),$.current&&(clearTimeout($.current),$.current=null),pe.current.clear(),ge.current=null,Se.current=!1,me.current=null,he.current=!1,Ee.current=!1,fe.current="",de.current=[],W.current=!1,a(O(null)),Re(),a(A(!1)),a(v(c.IDLE)),a(C(s.DISCONNECTED)),ye(n.INDICATOR_TIMER_ACTIONS.CANCEL)},[a,Re,ye]),be=e.useRef(r),De=e.useRef(!1);e.useEffect(()=>{const e=be.current;if(be.current=r,e===r)return;const t=null!==R.current&&R.current.readyState<=WebSocket.OPEN;t&&(De.current=!0),t&&(ve.current.discardStreamingMessages(),le.current.clear(),de.current=[],Pe("conv-change")),De.current&&null!=r&&(De.current=!1,Ne())},[r,Pe,Ne]);const Me=e.useRef(_);return e.useEffect(()=>{const e=Me.current;if(Me.current=_,e&&!_){const e=R.current;e&&e.readyState<=WebSocket.OPEN&&Pe("logout")}},[_,Pe]),e.useEffect(()=>()=>{X.current&&clearInterval(X.current),H.current&&clearInterval(H.current),Y.current&&clearTimeout(Y.current),$.current&&clearTimeout($.current),Z.current&&clearTimeout(Z.current),W.current=!1,M.current.destroy(),D.current.destroy()},[]),{connect:Ne,disconnect:Pe,sendAudioChunk:xe,sendText:Oe}}function z({micOpen:r,muted:n,onChunk:s}){const c=J(),[i,o]=e.useState(!1),[a,u]=e.useState(!1),l=t.useSelector(e=>e.voice.selectedMicId),d=e.useRef(s);d.current=s;const p=e.useRef(null);return e.useEffect(()=>{if(!r)return;o(!0),u(!1);const e=c.createCapture();return p.current=e,e.open({micDeviceId:l||null,initialMuted:n,onChunk:e=>d.current(e),onLoadingChange:o,onError:()=>u(!0)}),()=>{e.close(),p.current===e&&(p.current=null)}},[r,l]),e.useEffect(()=>{p.current?.setMuted(n)},[n]),{loading:i,errored:a}}function Z(e,r,n){const o=t.useSelector(e=>e.voice.connectionStatus),a=t.useSelector(e=>e.voice.pipelineStatus),u=t.useSelector(e=>e.voice.listeningEnabled),l=t.useSelector(e=>e.voice.muted);return o===s.CONNECTING?i.CONNECTING:o===s.CONNECTED?u?e?i.LOADING:r?i.OFFLINE:n??l?i.MUTED:a===c.PROCESSING?i.PROCESSING:a===c.SPEAKING?i.SPEAKING:a===c.LISTENING?i.LISTENING:i.IDLE:i.READY:i.OFFLINE}const Q=e.createContext(null),ee=e.createContext({strategyActive:!1,voiceSlot:null,onEnterVoice:null,onFloatingOrbClick:null,voiceInputHidden:!1,headerCenterSlot:null,floatOrbPositionRef:null}),te={stop:null},re=r.createListenerMiddleware();re.startListening({actionCreator:P,effect:async e=>{const t=n.getStorageRef();t&&await t.setItem(f.SELECTED_MIC_ID,e.payload)}}),re.startListening({actionCreator:b,effect:async e=>{const t=n.getStorageRef();t&&await t.setItem(f.SELECTED_SPEAKER_ID,e.payload)}}),re.startListening({actionCreator:D,effect:()=>{H()}}),re.startListening({matcher:r.isAnyOf(n.clearSession,n.sessionExpired),effect:async(e,t)=>{const r=n.getStorageRef();r&&await Promise.all([r.removeItem(f.SELECTED_MIC_ID),r.removeItem(f.SELECTED_SPEAKER_ID)]),t.dispatch(D())}});class ne{ctx=null;stream=null;source=null;gain=null;worklet=null;worker=null;visibilityHandler=null;opening=!1;cancelled=!1;opts=null;open(e){this.opening||this.ctx||(this.cancelled=!1,this.opening=!0,this.opts=e,e.onLoadingChange?.(!0),(async()=>{let t=null,r=null,s=null,c=null,i=null,a=null;try{try{t=new AudioContext({sampleRate:o})}catch{t=new AudioContext}if(this.cancelled)return void await t.close().catch(()=>{});if(await t.audioWorklet.addModule(`${n.getBaseUrl()}/audio-recorder.worklet.js`),this.cancelled)return void await t.close().catch(()=>{});if(r=await navigator.mediaDevices.getUserMedia({audio:{...e.micDeviceId?{deviceId:{exact:e.micDeviceId}}:{},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1,sampleRate:o,echoCancellationType:{ideal:"system"}}}),this.cancelled)return r.getTracks().forEach(e=>e.stop()),void await t.close().catch(()=>{});s=t.createMediaStreamSource(r),c=t.createGain(),c.gain.setValueAtTime(e.initialMuted?0:1,t.currentTime),i=new AudioWorkletNode(t,"audio-recorder"),a=new Worker(`${n.getBaseUrl()}/audio-processor.worker.js`);const u=a;if(i.port.onmessage=e=>{if(this.cancelled)return;const t=e.data;t&&0!==t.length&&u.postMessage({type:"frame",frame:t},[t.buffer])},a.onmessage=e=>{const t=e.data;t&&"chunk"===t.type&&t.buffer instanceof ArrayBuffer&&this.opts?.onChunk(t.buffer)},s.connect(c).connect(i).connect(t.destination),"suspended"===t.state&&await t.resume().catch(()=>{}),this.cancelled)return a.terminate(),i.disconnect(),c.disconnect(),s.disconnect(),r.getTracks().forEach(e=>e.stop()),void await t.close().catch(()=>{});this.ctx=t,this.stream=r,this.source=s,this.gain=c,this.worklet=i,this.worker=a;const l=()=>{"visible"===document.visibilityState&&"suspended"===t.state&&t.resume().catch(()=>{})};document.addEventListener("visibilitychange",l),this.visibilityHandler=l,this.opts?.onLoadingChange?.(!1)}catch(e){n.logger.error({message:"Mic capture failed",api_name:"voice-mic",error_message:e instanceof Error?e.message:String(e)}),t?.close().catch(()=>{}),r?.getTracks().forEach(e=>e.stop()),a?.terminate(),i?.disconnect(),c?.disconnect(),s?.disconnect(),this.cancelled||(this.opts?.onError?.(e),this.opts?.onLoadingChange?.(!1))}finally{this.opening=!1}})())}setMuted(e){const t=this.ctx,r=this.gain;t&&r&&(r.gain.setValueAtTime(e?0:1,t.currentTime),e&&this.worker?.postMessage({type:p}))}close(){this.cancelled=!0;const e=this.worker,t=this.worklet,r=this.gain,n=this.source,s=this.stream,c=this.ctx;e&&(e.postMessage({type:p}),e.terminate()),t?.disconnect(),r?.disconnect(),n?.disconnect(),s?.getTracks().forEach(e=>e.stop()),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),c?.close().catch(()=>{}),this.ctx=null,this.stream=null,this.source=null,this.gain=null,this.worklet=null,this.worker=null,this.opts=null}}class se{async enumerate(){const e={microphones:[],speakers:[]};if(!navigator.mediaDevices?.enumerateDevices)return e;try{const e=await navigator.mediaDevices.enumerateDevices();let t=0,r=0;return{microphones:e.filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Microphone "+ ++t})),speakers:e.filter(e=>"audiooutput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Speaker "+ ++r}))}}catch{return e}}onChange(e){const t=navigator.mediaDevices;return t?.addEventListener?(t.addEventListener("devicechange",e),()=>t.removeEventListener("devicechange",e)):()=>{}}}class ce{audio=null;timer=null;pendingPlay=null;pendingAction=null;unlock(){this.audio||(this.audio=new Audio(`${n.getBaseUrl()}${u}`),this.audio.loop=!0,this.audio.volume=.5,this.audio.preload="auto",this.audio.load());const e=this.audio.volume;this.audio.volume=0;const t=this.audio.play();t&&"function"==typeof t.then?t.then(()=>{this.pendingPlay?this.audio&&(this.audio.volume=e):(this.audio?.pause(),this.audio&&(this.audio.currentTime=0,this.audio.volume=e))}).catch(()=>{this.audio&&(this.audio.volume=e)}):(this.pendingPlay||(this.audio.pause(),this.audio.currentTime=0),this.audio.volume=e)}start(e){if(this.timer||this.audio&&!this.audio.paused)return;this.stop(),this.audio||(this.audio=new Audio(`${n.getBaseUrl()}${u}`),this.audio.loop=!0,this.audio.volume=.5);const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this._doPlay()},t)}pause(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingPlay?this.pendingAction="pause":this.audio&&!this.audio.paused&&this.audio.pause()}resume(e=0){if(!this.audio)return;const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this._doPlay()},t)}stop(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingPlay?this.pendingAction="stop":this.audio&&(this.audio.pause(),this.audio.currentTime=0)}destroy(){this.stop(),this.pendingAction=null,this.audio&&(this.audio.removeAttribute("src"),this.audio=null)}_doPlay(){this.pendingAction=null;const e=this.audio?.play();e instanceof Promise?(this.pendingPlay=e,e.then(()=>{this.pendingPlay=null;const e=this.pendingAction;this.pendingAction=null,"pause"===e?this.audio?.pause():"stop"===e&&this.audio&&(this.audio.pause(),this.audio.currentTime=0)}).catch(()=>{this.pendingPlay=null,this.pendingAction=null})):this.pendingPlay=null}}const ie={createCapture:()=>new ne,createPlayer:()=>new Y,createThinkingSound:()=>new ce,devices:new se,requestMicPermission:async function(){try{return(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(e=>e.stop()),{granted:!0}}catch(e){return{granted:!1,error:e}}},requiresSoftwareAecMute:!1};exports.AudioPlatformContext=$,exports.BrowserAudioCapture=ne,exports.BrowserAudioDevices=se,exports.BrowserAudioPlayer=Y,exports.BrowserThinkingSound=ce,exports.ORB_STATE_CONFIG={offline:{opacity:.15,playbackRate:.3,scale:1},connecting:{opacity:.4,playbackRate:.5,scale:1},ready:{opacity:.4,playbackRate:.4,scale:1},loading:{opacity:.6,playbackRate:.6,scale:1},idle:{opacity:.6,playbackRate:.6,scale:1},listening:{opacity:.7,playbackRate:.7,scale:1},muted:{opacity:.7,playbackRate:.5,scale:1},processing:{opacity:1,playbackRate:1,scale:1},speaking:{opacity:1,playbackRate:1,scale:1.3}},exports.VOICE_AUTH_ERROR_PATTERNS=S,exports.VOICE_BARGE_IN_DELAY_MS=400,exports.VOICE_CHUNK_SAMPLES=2048,exports.VOICE_CONNECTION_STATUSES=s,exports.VOICE_DISPLAY_STATES=i,exports.VOICE_FATAL_ERROR_PATTERNS=h,exports.VOICE_KEEPALIVE_INTERVAL_MS=2e4,exports.VOICE_PCM_INT16_MAX=a,exports.VOICE_PIPELINE_STATUSES=c,exports.VOICE_PREROLL_DEFAULT_SECONDS=d,exports.VOICE_PREROLL_JITTER_WINDOW=30,exports.VOICE_PREROLL_MAX_SECONDS=.5,exports.VOICE_PREROLL_MIN_SAMPLES=5,exports.VOICE_PREROLL_MIN_SECONDS=.1,exports.VOICE_SAMPLE_RATE=o,exports.VOICE_STORAGE_KEYS=f,exports.VOICE_TERMINAL_ERROR_PATTERNS=m,exports.VOICE_THINKING_SOUND_DELAY_MS=300,exports.VOICE_THINKING_SOUND_PATH=u,exports.VOICE_THINKING_SOUND_VOLUME=.5,exports.VOICE_WS_CLIENT=g,exports.VOICE_WS_SERVER=E,exports.VoiceContext=Q,exports.VoiceUIContext=ee,exports.browserAudioPlatform=ie,exports.clearAudioBuffer=H,exports.computeAdaptivePreroll=q,exports.createAccumulator=U,exports.finalizeAudio=F,exports.getAudio=B,exports.hydrateVoice=e=>async t=>{const[r,n]=await Promise.all([e.getItem(f.SELECTED_MIC_ID),e.getItem(f.SELECTED_SPEAKER_ID)]);r&&t(_.actions.setSelectedMicId(r)),n&&t(_.actions.setSelectedSpeakerId(n))},exports.pushChunk=K,exports.resetIndicatorState=M,exports.setConnectionStatus=C,exports.setError=x,exports.setFirstAssistantMessageComplete=y,exports.setIsAgentWorking=N,exports.setListeningEnabled=A,exports.setMuted=R,exports.setPipelineStatus=v,exports.setResponseStartTime=w,exports.setSelectedMicId=P,exports.setSelectedSpeakerId=b,exports.setStatusText=k,exports.useAudioPlatform=J,exports.useMediaDevices=function(){const r=J(),[n,s]=e.useState([]),[c,i]=e.useState([]),o=t.useSelector(e=>e.voice.listeningEnabled),a=e.useCallback(async()=>{const e=await r.devices.enumerate();s(e.microphones),i(e.speakers)},[r]);return e.useEffect(()=>(a(),r.devices.onChange(a)),[r,a]),e.useEffect(()=>{o&&a()},[o,a]),{microphones:n,speakers:c,refresh:a}},exports.useVoice=()=>{const t=e.useContext(Q);if(!t)throw new Error("useVoice must be used within VoiceProvider");return t},exports.useVoiceAudioPlayback=function(r){const[n,s]=e.useState(!1),c=e.useRef(null),i=e.useRef(null),u=e.useRef(!1),l=t.useSelector(e=>e.voice.selectedSpeakerId),d=e.useRef(l);d.current=l;const p=!!r&&!!B(r),g=e.useCallback(()=>{i.current?.stop(),i.current?.disconnect(),i.current=null,c.current?.close(),c.current=null,u.current=!1,s(!1)},[]),S=e.useCallback(()=>{if(n)return g(),void(te.stop=null);if(!r)return;const e=B(r);if(!e)return;te.stop&&te.stop();const t=d.current,l=new AudioContext({sampleRate:e.sampleRate??o,...t?{sinkId:t}:{}});c.current=l;const p=new Float32Array(e.pcmInt16.length);for(let t=0;t<e.pcmInt16.length;t++)p[t]=e.pcmInt16[t]/a;const S=l.createBuffer(1,p.length,e.sampleRate??o);S.getChannelData(0).set(p);const m=l.createBufferSource();m.buffer=S,m.connect(l.destination),i.current=m,m.onended=()=>{g(),te.stop=null},te.stop=g,u.current=!0,s(!0),m.start()},[n,r,g]);return e.useEffect(()=>()=>{u.current&&(g(),te.stop===g&&(te.stop=null))},[g]),{playing:n,toggle:S,hasAudio:p}},exports.useVoiceDisplayState=Z,exports.useVoiceMicCapture=z,exports.useVoiceProviderValue=({conversationId:r,voiceBridge:i,assistantStartsConversation:o})=>{const a=t.useDispatch(),u=J(),l=t.useSelector(e=>e.voice.muted),d=t.useSelector(e=>e.voice.connectionStatus),p=t.useSelector(e=>e.voice.pipelineStatus),g=t.useSelector(e=>e.voice.isAgentWorking),S=t.useSelector(e=>e.voice.listeningEnabled),m=t.useSelector(e=>e.voice.firstAssistantMessageComplete),[h,E]=e.useState(!1),{connect:f,disconnect:T,sendAudioChunk:I,sendText:_}=X(r,i),{orbMuted:C,effectiveMuted:v}=function(e){const t=e.userMuted||e.assistantStartsConversation&&!e.firstAssistantMessageComplete&&!e.welcomeMuteDismissed;return{orbMuted:t,effectiveMuted:t||!0===e.requiresSoftwareAecMute&&e.pipelineStatus===c.SPEAKING}}({userMuted:l,assistantStartsConversation:o,firstAssistantMessageComplete:m,welcomeMuteDismissed:h,pipelineStatus:p,requiresSoftwareAecMute:u.requiresSoftwareAecMute}),A=o&&!m;e.useEffect(()=>{A&&d===s.CONNECTED||E(!1)},[d,A]);const{loading:y,errored:k}=z({micOpen:S,muted:v,onChunk:I}),N=Z(y,k,C);e.useEffect(()=>(i.setVoiceSendText(_),()=>i.setVoiceSendText(null)),[i,_]);const w=e.useRef(!1);return{displayState:N,pipelineStatus:p,isAgentWorking:g,enterVoiceMode:e.useCallback(async()=>{if(w.current)return n.showErrorToast("Microphone permission changed — please reload the page to apply the new setting."),!1;const e=await u.requestMicPermission();return e.granted?(f(),!0):(n.logger.error({message:"Mic permission denied",api_name:"voice-mic",error_message:e.error?e.error instanceof Error?e.error.message:String(e.error):void 0}),w.current=!0,n.showErrorToast("Microphone access is required for voice mode. Please allow it in your browser's site settings and reload the page."),!1)},[u,f]),exitVoiceMode:e.useCallback(()=>{T()},[T]),toggleMute:e.useCallback(()=>{if(C)return E(!0),void a(R(!1));a(R(!0))},[a,C]),sendText:_,muted:C,micLoading:y,micErrored:k}},exports.useVoiceUI=()=>e.useContext(ee),exports.useVoiceWebSocket=X,exports.voiceListenerMiddleware=re,exports.voiceReducer=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=require("react-redux"),r=require("@reduxjs/toolkit"),n=require("@1interface/shared-core"),s={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected"},a={IDLE:"idle",LISTENING:"listening",PROCESSING:"processing",SPEAKING:"speaking"},o={CASCADE:"cascade",REALTIME:"realtime"},c={OFFLINE:"offline",CONNECTING:"connecting",READY:"ready",LOADING:"loading",IDLE:"idle",LISTENING:"listening",MUTED:"muted",PROCESSING:"processing",SPEAKING:"speaking"},i={SELECTED_MIC_ID:"voice_selectedMicId",SELECTED_SPEAKER_ID:"voice_selectedSpeakerId"};function u(){return{connectionStatus:s.DISCONNECTED,pipelineStatus:a.IDLE,listeningEnabled:!1,muted:!1,serverMuted:!1,statusText:null,isAgentWorking:!1,responseStartTime:null,error:null,interimTranscript:null,botTurn:{active:!1,chatMsgId:null,segments:[]},selectedMicId:"",selectedSpeakerId:""}}const l=u(),d=r.createSlice({name:"voice",initialState:l,reducers:{setConnectionStatus(e,t){e.connectionStatus=t.payload},setPipelineStatus(e,t){e.pipelineStatus=t.payload},setListeningEnabled(e,t){e.listeningEnabled=t.payload},setStatusText(e,t){e.statusText=t.payload},setIsAgentWorking(e,t){e.isAgentWorking=t.payload},setResponseStartTime(e,t){e.responseStartTime=t.payload},setError(e,t){e.error=t.payload},setInterimTranscript(e,t){e.interimTranscript=t.payload},openBotTurn(e,t){e.botTurn={active:!0,chatMsgId:t.payload?.chatMsgId??null,segments:[]}},upsertBotSegment(e,t){const{id:r,text:n,spokenChars:s}=t.payload;e.botTurn.active=!0;const a=e.botTurn.segments.find(e=>e.id===r);a?(a.text=n,a.spokenChars=Math.max(a.spokenChars,s)):(e.botTurn.segments.push({id:r,text:n,spokenChars:s}),e.botTurn.segments.sort((e,t)=>e.id-t.id))},clearBotTurn(e){e.botTurn={active:!1,chatMsgId:null,segments:[]}},setMuted(e,t){e.muted=t.payload},setServerMuted(e,t){e.serverMuted=t.payload},setSelectedMicId(e,t){e.selectedMicId=t.payload},setSelectedSpeakerId(e,t){e.selectedSpeakerId=t.payload},resetVoiceState:()=>u(),resetIndicatorState(e){e.statusText=null,e.isAgentWorking=!1,e.responseStartTime=null,e.interimTranscript=null,e.serverMuted=!1,e.botTurn={active:!1,chatMsgId:null,segments:[]}}}}),{setConnectionStatus:p,setPipelineStatus:g,setListeningEnabled:E,setMuted:S,setServerMuted:I,setStatusText:m,setIsAgentWorking:T,setResponseStartTime:C,setError:f,setInterimTranscript:v,openBotTurn:k,upsertBotSegment:x,clearBotTurn:N,setSelectedMicId:h,setSelectedSpeakerId:R,resetVoiceState:y,resetIndicatorState:_}=d.actions,b=d.reducer,M=e.createContext(null),A=()=>{const t=e.useContext(M);if(!t)throw new Error("useAudioPlatform must be used inside <AudioPlatformProvider>. <VoiceProvider> mounts one by default; if you replaced VoiceProvider, you must wire your own.");return t};function D(){const e={};for(const[t,r]of Object.entries(n.getCustomHeaders()))r&&(e[t]=r);const t=n.readAccessToken();return t&&(e["X-Access-Token"]=t),e}async function O(e){try{const t=await fetch(n.API_ENDPOINTS.WEBRTC_ICE(e),{headers:D()});return t.ok?(await t.json()).iceServers??[]:(n.logger.warn({message:"Voice ICE fetch failed — continuing without TURN",api_name:"voice-webrtc-ice",status:t.status}),[])}catch(e){return n.logger.warn({message:"Voice ICE fetch error — continuing without TURN",api_name:"voice-webrtc-ice",error_message:e instanceof Error?e.message:String(e)}),[]}}const w="voice-user-",P=(e,t=`${w}${n.generateUniqueId()}`)=>({id:t,sender:"user",message:e,timestamp:(new Date).toISOString()});function L(e,r,n){const o=t.useSelector(e=>e.voice.connectionStatus),i=t.useSelector(e=>e.voice.pipelineStatus),u=t.useSelector(e=>e.voice.listeningEnabled),l=t.useSelector(e=>e.voice.muted);return o===s.CONNECTING?c.CONNECTING:o===s.CONNECTED?u?e?c.LOADING:r?c.OFFLINE:n??l?c.MUTED:i===a.PROCESSING?c.PROCESSING:i===a.SPEAKING?c.SPEAKING:i===a.LISTENING?c.LISTENING:c.IDLE:c.READY:c.OFFLINE}const V=e.createContext(null),G=e.createContext({strategyActive:!1,voiceSlot:null,onEnterVoice:null,onFloatingOrbClick:null,voiceInputHidden:!1,headerCenterSlot:null,floatOrbPositionRef:null}),B=r.createListenerMiddleware();B.startListening({actionCreator:h,effect:async e=>{const t=n.getStorageRef();t&&await t.setItem(i.SELECTED_MIC_ID,e.payload)}}),B.startListening({actionCreator:R,effect:async e=>{const t=n.getStorageRef();t&&await t.setItem(i.SELECTED_SPEAKER_ID,e.payload)}}),B.startListening({matcher:r.isAnyOf(n.clearSession,n.sessionExpired),effect:async(e,t)=>{const r=n.getStorageRef();r&&await Promise.all([r.removeItem(i.SELECTED_MIC_ID),r.removeItem(i.SELECTED_SPEAKER_ID)]),t.dispatch(y())}});class U{async enumerate(){const e={microphones:[],speakers:[]};if(!navigator.mediaDevices?.enumerateDevices)return e;try{const e=await navigator.mediaDevices.enumerateDevices();let t=0,r=0;return{microphones:e.filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Microphone "+ ++t})),speakers:e.filter(e=>"audiooutput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Speaker "+ ++r}))}}catch{return e}}onChange(e){const t=navigator.mediaDevices;return t?.addEventListener?(t.addEventListener("devicechange",e),()=>t.removeEventListener("devicechange",e)):()=>{}}}const F=e=>{const t=document.createElement("audio");return t.autoplay=!0,t.style.display="none",t.srcObject=new MediaStream([e]),document.body.appendChild(t),()=>{try{t.pause(),t.srcObject=null,t.remove()}catch{}}},q={attachBotAudioTrack:F,devices:new U,requestMicPermission:async function(){try{return(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(e=>e.stop()),{granted:!0}}catch(e){return{granted:!1,error:e}}}};exports.AudioPlatformContext=M,exports.BrowserAudioDevices=U,exports.ORB_STATE_CONFIG={offline:{opacity:.15,playbackRate:.3,scale:1},connecting:{opacity:.4,playbackRate:.5,scale:1},ready:{opacity:.4,playbackRate:.4,scale:1},loading:{opacity:.6,playbackRate:.6,scale:1},idle:{opacity:.6,playbackRate:.6,scale:1},listening:{opacity:.7,playbackRate:.7,scale:1},muted:{opacity:.7,playbackRate:.5,scale:1},processing:{opacity:1,playbackRate:1,scale:1},speaking:{opacity:1,playbackRate:1,scale:1.3}},exports.VOICE_CONNECTION_STATUSES=s,exports.VOICE_CONNECT_TIMEOUT_MS=15e3,exports.VOICE_DISPLAY_STATES=c,exports.VOICE_PIPELINE_MODES=o,exports.VOICE_PIPELINE_STATUSES=a,exports.VOICE_STORAGE_KEYS=i,exports.VoiceContext=V,exports.VoiceUIContext=G,exports.attachBrowserBotAudioTrack=F,exports.browserAudioPlatform=q,exports.clearBotTurn=N,exports.hydrateVoice=e=>async t=>{const[r,n]=await Promise.all([e.getItem(i.SELECTED_MIC_ID),e.getItem(i.SELECTED_SPEAKER_ID)]);r&&t(d.actions.setSelectedMicId(r)),n&&t(d.actions.setSelectedSpeakerId(n))},exports.openBotTurn=k,exports.resetIndicatorState=_,exports.setConnectionStatus=p,exports.setError=f,exports.setInterimTranscript=v,exports.setIsAgentWorking=T,exports.setListeningEnabled=E,exports.setMuted=S,exports.setPipelineStatus=g,exports.setResponseStartTime=C,exports.setSelectedMicId=h,exports.setSelectedSpeakerId=R,exports.setServerMuted=I,exports.setStatusText=m,exports.upsertBotSegment=x,exports.useAudioPlatform=A,exports.useMediaDevices=function(){const r=A(),[n,s]=e.useState([]),[a,o]=e.useState([]),c=t.useSelector(e=>e.voice.listeningEnabled),i=e.useCallback(async()=>{const e=await r.devices.enumerate();s(e.microphones),o(e.speakers)},[r]);return e.useEffect(()=>(i(),r.devices.onChange(i)),[r,i]),e.useEffect(()=>{c&&i()},[c,i]),{microphones:n,speakers:a,refresh:i}},exports.useVoice=()=>{const t=e.useContext(V);if(!t)throw new Error("useVoice must be used within VoiceProvider");return t},exports.useVoiceDisplayState=L,exports.useVoiceProviderValue=({conversationId:r,voiceBridge:c,transportFactory:i})=>{const u=t.useDispatch(),l=A(),d=t.useSelector(e=>e.voice.muted),h=t.useSelector(e=>e.voice.serverMuted),R=t.useSelector(e=>e.voice.pipelineStatus),y=t.useSelector(e=>e.voice.isAgentWorking),{connect:_,disconnect:b,sendText:M,setMicEnabled:V}=function(r,c,i){const u=t.useDispatch(),l=A(),d=t.useSelector(e=>e.auth.accessToken),S=e.useRef(c);e.useEffect(()=>{S.current=c});const h=e.useRef(null),R=e.useRef(new Map),y=e.useRef(""),_=e.useRef(!1),b=e.useRef([]),M=e.useRef(null),L=e.useRef(""),V=e.useRef(null),G=e.useRef(null),B=e.useRef(null),U=e.useRef(0),F=e.useRef(0),q=e.useRef(!1),W=e.useRef(0),K=e.useRef(null),j=e.useCallback(()=>{if(null!=K.current)return;const e=Date.now();K.current=e,u(C(e)),u(n.clearLastResponseTime())},[u]),$=e.useCallback(()=>{const e=K.current;K.current=null,u(C(null)),null!=e&&u(n.setLastResponseTime(Date.now()-e))},[u]),H=e.useCallback(()=>{K.current=null,u(C(null))},[u]),Y=e.useCallback((e=n.INDICATOR_TIMER_ACTIONS.KEEP)=>{u(m(null)),u(T(!1)),e===n.INDICATOR_TIMER_ACTIONS.FINALIZE?$():e===n.INDICATOR_TIMER_ACTIONS.CANCEL&&H()},[u,$,H]),Z=e.useRef({setStatusText:e=>u(m(e||null)),setIsAgentWorking:e=>u(T(e)),appendStreamText:()=>{},pushWidget:e=>{b.current.push(e)},onPayment:e=>S.current.onPaymentInit?.(e),onConversationTitle:e=>S.current.onConversationTitle?.(e),onError:e=>{n.logger.error({message:"Voice RTVI server error",api_name:"voice-rtvi",error_message:e}),u(f(e))},onStatusActive:()=>{j()}}),X=e.useCallback(()=>{B.current&&(clearTimeout(B.current),B.current=null)},[]),z=e.useCallback(()=>[...R.current.entries()].sort((e,t)=>e[0]-t[0]).map(([,e])=>e).join(" ").trim(),[]),J=e.useCallback(()=>{const e=h.current;if(e){const t=z();t&&S.current.updateStreamingMessage(e,t),S.current.commitStreamingMessages()}h.current=null,R.current=new Map,y.current="",u(N())},[u,z]),Q=e.useCallback(()=>{const e=b.current;if(!e.length)return;b.current=[];const t=`voice-widget-${n.generateUniqueId()}`;S.current.setMessages(r=>[...r,{id:t,msg_id:t,sender:"agent",message:"",timestamp:(new Date).toISOString(),widget:e,message_type:["widget"]}])},[]),ee=e.useCallback(e=>{X(),G.current?.(),G.current=null,V.current=null,q.current=!1,u(E(!1)),u(g(a.IDLE)),u(p(s.DISCONNECTED)),u(v(null)),u(I(!1)),M.current=null,L.current="",_.current=!1,e?(J(),Q()):(S.current.discardStreamingMessages(),h.current=null,R.current=new Map,y.current="",b.current=[],u(N())),Y(n.INDICATOR_TIMER_ACTIONS.CANCEL)},[u,Y,X,J,Q]),te=e.useCallback(()=>{if(h.current)return;const e=`voice-agent-${n.generateUniqueId()}`;if(h.current=e,R.current=new Map,y.current="",u(k({chatMsgId:e})),b.current.length){const t=b.current;b.current=[];for(const r of t)S.current.addStreamingWidget(e,r)}},[u]),re=e.useCallback(e=>{const t=e.spoken_progress?.accumulated_text??"",r=e.spoken_progress?t+(e.spoken_progress?.remaining_text??""):e.text??"";if(!r)return;if(te(),_.current){const e=(R.current.get(0)??"")+r;R.current.set(0,e),u(x({id:0,text:e,spokenChars:e.length}))}else{const n=e.segment_id??0;R.current.set(n,r),u(x({id:n,text:r,spokenChars:e.spoken_progress?t.length:r.length}))}const n=z();n&&h.current&&n!==y.current&&(y.current=n,S.current.updateStreamingMessage(h.current,n))},[u,te,z]),ne=e.useCallback(e=>{const t=e,r=t?.type,s=t?.data;switch(r){case"status_update":n.handleSharedEvent({kind:"status_update",statusText:s?.text??""},Z.current);break;case"clear_status":Y(n.INDICATOR_TIMER_ACTIONS.KEEP);break;case"widget":s&&n.handleSharedEvent({kind:"widget",widget:s},Z.current);break;case"payment":s&&n.handleSharedEvent({kind:"payment",payment:s},Z.current);break;case"conversation_title":{const e="string"==typeof s?.text?s.text.trim():"";e&&n.handleSharedEvent({kind:"conversation_title",title:e},Z.current);break}default:n.logger.debug({message:"Voice RTVI unhandled server-message",api_name:"voice-rtvi",event_type:r??"unknown"})}},[Y]),se=e.useRef(()=>{}),ae=e.useCallback(e=>{const t=()=>e===U.current;return{onConnected:()=>{t()&&(u(p(s.CONNECTED)),u(E(!0)),u(g(a.IDLE)))},onBotReady:e=>{if(!t())return;const r=e?.about;_.current=r?.pipeline_mode===o.REALTIME,X()},onDisconnected:()=>{t()&&ee(!0)},onError:e=>{if(!t())return;const r=e?.data;n.handleSharedEvent({kind:"error",error:r?.error??r?.message??"Voice error"},Z.current),u(g(a.IDLE)),Y(n.INDICATOR_TIMER_ACTIONS.CANCEL),r?.fatal&&se.current()},onTrackStarted:(e,r)=>{t()&&(r?.local||"audio"!==e.kind||(G.current?.(),G.current=l.attachBotAudioTrack(e)))},onUserMuteStarted:()=>{t()&&u(I(!0))},onUserMuteStopped:()=>{t()&&u(I(!1))},onUserStartedSpeaking:()=>{t()&&(Q(),M.current=null,L.current="",u(v(null)),u(g(a.LISTENING)))},onUserStoppedSpeaking:()=>{if(!t())return;u(g(a.PROCESSING)),u(T(!0)),u(m(null)),j();const e=L.current.trim();if(e){const t=`${w}${n.generateUniqueId()}`;M.current=t,u(v(null)),S.current.setMessages(r=>[...r,P(e,t)])}},onUserTranscript:e=>{if(!t())return;if(!e.final)return void(e.text&&(L.current=e.text,_.current||u(v(e.text))));u(v(null));const r=e.text&&e.text.trim()?e.text:"",n=M.current;M.current=null,n?r&&S.current.setMessages(e=>e.map(e=>e.id===n?{...e,message:r}:e)):r&&S.current.setMessages(e=>[...e,P(r)])},onBotStartedSpeaking:()=>{t()&&(te(),u(g(a.SPEAKING)),Y(n.INDICATOR_TIMER_ACTIONS.FINALIZE))},onBotOutput:e=>{t()&&re(e)},onBotStoppedSpeaking:()=>{t()&&(J(),u(g(a.IDLE)),Y(n.INDICATOR_TIMER_ACTIONS.FINALIZE))},onServerMessage:e=>{t()&&ne(e)}}},[u,l,X,ee,Y,j,re,te,J,Q,ne]),oe=e.useCallback(async()=>{if(V.current||q.current)return;if(!r)return;if(q.current=!0,n.isTokenAboutToExpire(n.readTokenExpiresAt())&&W.current<1){W.current+=1;const e=F.current;try{await Promise.resolve(n.getTokenRefreshHandler()?.())}catch{}if(e!==F.current)return}const e=++U.current,t=F.current;u(p(s.CONNECTING));const a=()=>t!==F.current||e!==U.current;try{const[{PipecatClient:t},s]=await Promise.all([Promise.resolve().then(()=>require("./index.module-DCaqEXL5.cjs")),O(r)]);if(a())return;const o=new t({transport:i(),enableMic:!0,enableCam:!1,callbacks:ae(e)});if(a())return void o.disconnect();V.current=o,X(),B.current=setTimeout(()=>{n.logger.warn({message:"Voice RTVI connect timed out (no bot-ready)",api_name:"voice-rtvi"}),n.showErrorToast("Voice connection timed out. Please try again."),se.current()},15e3),await o.connect({webrtcRequestParams:{endpoint:n.API_ENDPOINTS.WEBRTC_OFFER(r),headers:new Headers(D())},iceConfig:{iceServers:s}})}catch(t){n.logger.error({message:"Voice RTVI connect failed",api_name:"voice-rtvi",error_message:t instanceof Error?t.message:String(t)}),e===U.current&&(n.showErrorToast("Could not connect voice. Please try again."),ee(!1))}},[r,u,i,ae,X,ee]),ce=e.useCallback((e=!0)=>{F.current+=1,U.current+=1,W.current=0;const t=V.current;if(t)try{t.disconnect()}catch(e){n.logger.warn({message:"Voice RTVI disconnect threw",api_name:"voice-rtvi",error_message:e instanceof Error?e.message:String(e)})}ee(e)},[ee]),ie=e.useCallback(e=>{V.current?.enableMic(e)},[]),ue=e.useCallback(e=>{const t=V.current;if(t){try{t.sendText(e,{run_immediately:!0,audio_response:!0})}catch(e){return void n.logger.error({message:"Voice RTVI send-text failed",api_name:"voice-rtvi",error_message:e instanceof Error?e.message:String(e)})}S.current.setMessages(t=>[...t,P(e)]),u(T(!0)),u(m(null)),j(),u(g(a.PROCESSING))}},[u,j]);e.useEffect(()=>{se.current=ce},[ce]);const le=e.useRef(r),de=e.useRef(!1);e.useEffect(()=>{const e=le.current;if(le.current=r,e===r)return;const t=q.current;t&&(de.current=!0),t&&ce(!1),de.current&&null!=r&&(de.current=!1,oe())},[r,ce,oe]);const pe=e.useRef(d);return e.useEffect(()=>{const e=pe.current;pe.current=d,e&&!d&&q.current&&ce(!1)},[d,ce]),e.useEffect(()=>()=>{se.current()},[]),{connect:oe,disconnect:ce,sendText:ue,setMicEnabled:ie}}(r,c,i);e.useEffect(()=>{V(!d&&!h)},[d,h,V]);const G=L(!1,!1,d);e.useEffect(()=>(c.setVoiceSendText(M),()=>c.setVoiceSendText(null)),[c,M]);const B=e.useRef(!1);return{displayState:G,pipelineStatus:R,isAgentWorking:y,enterVoiceMode:e.useCallback(async()=>{if(B.current)return n.showErrorToast("Microphone permission changed — please reload the page to apply the new setting."),!1;const e=await l.requestMicPermission();if(!e.granted){const t=e.error;return n.logger.error({message:"Mic permission denied",api_name:"voice-mic",error_message:t instanceof Error?t.message:t?String(t):void 0}),B.current=!0,n.showErrorToast("Microphone access is required for voice mode. Please allow it in your browser's site settings and reload the page."),!1}return _(),!0},[l,_]),exitVoiceMode:e.useCallback(()=>{b()},[b]),toggleMute:e.useCallback(()=>{u(S(!d))},[u,d]),sendText:M,muted:d,serverMuted:h}},exports.useVoiceUI=()=>e.useContext(G),exports.voiceListenerMiddleware=B,exports.voiceReducer=b;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{createContext as e,useContext as t,useRef as r,useCallback as n,useEffect as s,useState as c}from"react";import{useDispatch as i,useSelector as a}from"react-redux";import{createSlice as o,createListenerMiddleware as u,isAnyOf as l}from"@reduxjs/toolkit";import{clearLastResponseTime as d,setLastResponseTime as p,INDICATOR_TIMER_ACTIONS as m,logger as h,generateUniqueId as g,isTokenAboutToExpire as S,readTokenExpiresAt as f,getTokenRefreshHandler as E,readAccessToken as v,handleSharedEvent as T,API_ENDPOINTS as y,getCustomHeaders as I,showErrorToast as _,getStorageRef as w,clearSession as k,sessionExpired as C,getBaseUrl as b}from"@1interface/shared-core";const A={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected"},N={IDLE:"idle",LISTENING:"listening",PROCESSING:"processing",SPEAKING:"speaking"},P={OFFLINE:"offline",CONNECTING:"connecting",READY:"ready",LOADING:"loading",IDLE:"idle",LISTENING:"listening",MUTED:"muted",PROCESSING:"processing",SPEAKING:"speaking"},D=24e3,M=32768,O=2048,x=.5,L="/sounds/thinking-sound.mp3",R=300,G=400,W=2e4,V=new Set([1006,1011,1012,1013,1014]),F=.2,K=.1,U=.5,B=30,H=5,$="reset",q={START_CONVERSATION:"start_conversation",TEXT_MESSAGE:"text_message",STOP_PLAYBACK:"stop_playback",PING:"ping"},Y=[/rejected/i,/unauthori[sz]ed/i,/forbidden/i,/\b40[13]\b/],J=[/\b402\b/,/\b429\b/,/rate[\s-]?limit/i],j=[...Y,...J],X={SPEECH_STARTED:"speech_started",SPEECH_STOPPED:"speech_stopped",STT_RESULT:"stt_result",TEXT_DELTA:"text_delta",STATUS_UPDATE:"status_update",STATUS_CLEAR:"clear_status",TTS_START:"tts_start",TTS_END:"tts_end",WIDGET:"widget",PAYMENT:"payment",CONVERSATION_TITLE:"conversation_title",ERROR:"error",PONG:"pong"},Z={SELECTED_MIC_ID:"voice_selectedMicId",SELECTED_SPEAKER_ID:"voice_selectedSpeakerId"},z={offline:{opacity:.15,playbackRate:.3,scale:1},connecting:{opacity:.4,playbackRate:.5,scale:1},ready:{opacity:.4,playbackRate:.4,scale:1},loading:{opacity:.6,playbackRate:.6,scale:1},idle:{opacity:.6,playbackRate:.6,scale:1},listening:{opacity:.7,playbackRate:.7,scale:1},muted:{opacity:.7,playbackRate:.5,scale:1},processing:{opacity:1,playbackRate:1,scale:1},speaking:{opacity:1,playbackRate:1,scale:1.3}};function Q(){return{connectionStatus:A.DISCONNECTED,pipelineStatus:N.IDLE,listeningEnabled:!1,muted:!1,firstAssistantMessageComplete:!1,statusText:null,isAgentWorking:!1,responseStartTime:null,error:null,interimTranscript:null,selectedMicId:"",selectedSpeakerId:""}}const ee=e=>async t=>{const[r,n]=await Promise.all([e.getItem(Z.SELECTED_MIC_ID),e.getItem(Z.SELECTED_SPEAKER_ID)]);r&&t(te.actions.setSelectedMicId(r)),n&&t(te.actions.setSelectedSpeakerId(n))},te=o({name:"voice",initialState:Q(),reducers:{setConnectionStatus(e,t){e.connectionStatus=t.payload},setPipelineStatus(e,t){e.pipelineStatus=t.payload},setListeningEnabled(e,t){e.listeningEnabled=t.payload},setStatusText(e,t){e.statusText=t.payload},setIsAgentWorking(e,t){e.isAgentWorking=t.payload},setResponseStartTime(e,t){e.responseStartTime=t.payload},setError(e,t){e.error=t.payload},setInterimTranscript(e,t){e.interimTranscript=t.payload},setMuted(e,t){e.muted=t.payload},setFirstAssistantMessageComplete(e,t){e.firstAssistantMessageComplete=t.payload},setSelectedMicId(e,t){e.selectedMicId=t.payload},setSelectedSpeakerId(e,t){e.selectedSpeakerId=t.payload},resetVoiceState:()=>Q(),resetIndicatorState(e){e.statusText=null,e.isAgentWorking=!1,e.responseStartTime=null}}}),{setConnectionStatus:re,setPipelineStatus:ne,setListeningEnabled:se,setMuted:ce,setFirstAssistantMessageComplete:ie,setStatusText:ae,setIsAgentWorking:oe,setResponseStartTime:ue,setError:le,setInterimTranscript:de,setSelectedMicId:pe,setSelectedSpeakerId:me,resetVoiceState:he,resetIndicatorState:ge}=te.actions,Se=te.reducer,fe=new Map,Ee=new Map;let ve=0;function Te(e){const t="voice_audio_"+ ++ve;return Ee.set(t,{chunks:[],sampleRate:e}),t}function ye(e,t){const r=Ee.get(e);r&&r.chunks.push(t)}function Ie(e){const t=Ee.get(e);if(!t||0===t.chunks.length)return void Ee.delete(e);const r=t.chunks.reduce((e,t)=>e+t.byteLength,0),n=new Int16Array(r/2);let s=0;for(const e of t.chunks)n.set(new Int16Array(e),s),s+=e.byteLength/2;fe.set(e,{pcmInt16:n,sampleRate:t.sampleRate}),Ee.delete(e)}function _e(e){return fe.get(e)}function we(){fe.clear(),Ee.clear()}function ke(e){if(e.length<5)return F;let t=0,r=0;for(let n=1;n<e.length;n++){const s=e[n]-e[n-1];t+=s,s>r&&(r=s)}return Math.min(.5,Math.max(.1,(r-t/(e.length-1))/1e3))}class Ce{ctx=null;masterGain=null;currentSpeakerId=void 0;nextPlayTime=0;doneTimer=null;isFirstChunk=!0;prerollProvider=null;activeSources=new Set;setPrerollProvider(e){this.prerollProvider=e}play(e,t){this.ctx&&t!==this.currentSpeakerId&&(this.ctx.close(),this.ctx=null,this.masterGain=null),this.ctx||(this.ctx=new AudioContext({sampleRate:D,...t?{sinkId:t}:{}}),this.masterGain=this.ctx.createGain(),this.masterGain.connect(this.ctx.destination),this.currentSpeakerId=t);const r=this.ctx,n=new Int16Array(e),s=new Float32Array(n.length);for(let e=0;e<n.length;e++)s[e]=n[e]/M;const c=r.createBuffer(1,s.length,D);c.getChannelData(0).set(s);const i=r.createBufferSource();i.buffer=c,i.connect(this.masterGain),this.activeSources.add(i),i.onended=()=>this.activeSources.delete(i);const a=r.currentTime;let o=Math.max(a,this.nextPlayTime);if(this.isFirstChunk){this.isFirstChunk=!1;const e=this.prerollProvider?this.prerollProvider():F;o=Math.max(o,a+e)}i.start(o),this.nextPlayTime=o+c.duration}get remainingSeconds(){return this.ctx?Math.max(0,this.nextPlayTime-this.ctx.currentTime):0}onDrained(e){this.doneTimer&&clearTimeout(this.doneTimer);const t=this.remainingSeconds;t<=0?e():this.doneTimer=setTimeout(()=>{this.doneTimer=null,e()},1e3*t)}resetForNewSegment(){this.isFirstChunk=!0}stop(){this.doneTimer&&(clearTimeout(this.doneTimer),this.doneTimer=null);for(const e of this.activeSources)try{e.stop()}catch(e){}this.activeSources.clear(),this.nextPlayTime=0,this.isFirstChunk=!0}destroy(){this.stop(),this.ctx&&(this.ctx.close(),this.ctx=null,this.masterGain=null)}}const be=e(null),Ae=()=>{const e=t(be);if(!e)throw new Error("useAudioPlatform must be used inside <AudioPlatformProvider>. <VoiceProvider> mounts one by default; if you replaced VoiceProvider, you must wire your own.");return e};function Ne(e,t){try{e()}catch(e){h.error({message:"Voice WS bridge call threw",api_name:"voice-ws",context:t,error_message:e instanceof Error?e.message:String(e)})}}function Pe(e,t){const c=i(),o=r(N.IDLE),u=r(""),l=r(null),_=a(e=>e.voice.pipelineStatus),w=a(e=>e.voice.selectedSpeakerId),k=a(e=>e.voice.statusText),C=a(e=>e.auth.accessToken);o.current=_,u.current=w,l.current=k;const b=r(null),P=r(0),M=Ae(),O=r(null);O.current||(O.current=M.createPlayer());const x=r(null);x.current||(x.current=M.createThinkingSound());const L=r([]),R=r(null),G=r(!1),W=r(!1),K=r(null),U=r(null),B=r(null),H=r(null),$=r(null),j=r(!1),Z=r(null),z=r(0),Q=r(!1),ee=r(0),te=r(0),ce=r(0),pe=r(0),me=r(0),he=r(0),ge=r(null),Se=r(null),fe=r(new Map),Ee=r(new Map),ve=r([]),_e=r(new Set),we=r(null),Ce=r(!1),be=r(null),Pe=r(!1),De=r(!1),Me=r(""),Oe=n(()=>{const e=ve.current;0!==e.length&&(ve.current=[],Ne(()=>Ge.current.setMessages(t=>[...t,...e]),"widget-flush"))},[]),xe=n(()=>{if(null!=Se.current)return;const e=Date.now();Se.current=e,c(ue(e)),c(d())},[c]),Le=n(()=>{const e=Se.current;Se.current=null,c(ue(null)),null!=e&&c(p(Date.now()-e))},[c]),Re=n(()=>{Se.current=null,c(ue(null))},[c]),Ge=r(t);Ge.current=t;const We=n(()=>{K.current&&(Ie(K.current),K.current=null)},[c]),Ve=n(()=>{x.current.stop(),We(),O.current.stop()},[We]),Fe=n((e=m.KEEP)=>{c(ae(null)),c(oe(!1)),e===m.FINALIZE?Le():e===m.CANCEL&&Re()},[c,Le,Re]),Ke=r({setStatusText:e=>c(ae(e||null)),setIsAgentWorking:e=>c(oe(e)),appendStreamText:(e,t)=>{if(null==t)return;const r=fe.current.get(t);if(!r)return;const n=(Ee.current.get(r)??"")+e;Ee.current.set(r,n),W.current||Ge.current.updateStreamingMessage(r,n)},pushWidget:e=>{const t=`voice-widget-${g()}`,r={id:t,msg_id:t,sender:"agent",message:"",timestamp:(new Date).toISOString(),widget:[e],message_type:["widget"]};ve.current.push(r)},onPayment:e=>Ge.current.onPaymentInit?.(e),onConversationTitle:e=>Ge.current.onConversationTitle?.(e),onError:e=>{h.error({message:"Voice WS server error",api_name:"voice-ws",error_message:e}),c(le(e))},onStatusActive:e=>{De.current=!0,Me.current=e,xe(),x.current?.start(O.current?.remainingSeconds??0)}}),Ue=n(()=>{if(b.current&&b.current.readyState<=WebSocket.OPEN)return void h.debug({message:"Voice WS connect() skipped — already connecting/open",api_name:"voice-ws",ready_state:b.current.readyState});if(!e)return void h.debug({message:"Voice WS connect() skipped — no conversationId",api_name:"voice-ws"});if(S(f())&&te.current<1){te.current+=1;const e=ce.current;return h.debug({message:"Voice WS refreshing token before connect (about to expire)",api_name:"voice-ws"}),void Promise.resolve(E()?.()).then(()=>{e===ce.current&&Be.current()})}h.debug({message:"Voice WS connecting",api_name:"voice-ws",generation:P.current+1}),x.current.unlock();const t=++P.current,r=ce.current,n=Date.now();me.current=n,he.current=n,ge.current="connecting";const s=v()??"",i=function(e,t){const r="undefined"!=typeof window?window.location?.origin:void 0,n=new URL(y.CONVERSATION_STREAM(e),r);n.protocol="https:"===n.protocol?"wss:":"ws:",t&&n.searchParams.append("access_token",t);const s=function(){const e=I();for(const[t,r]of Object.entries(e))if("x-client-id"===t.toLowerCase()&&r)return r;return null}();return s&&n.searchParams.append("client_id",s),n.toString()}(e,s);let a=!1;const d=new WebSocket(i);b.current=d,c(re(A.CONNECTING)),d.binaryType="arraybuffer",d.onopen=()=>{a=!0,h.debug({message:"Voice WS open",api_name:"voice-ws",generation:t}),c(re(A.CONNECTED)),c(se(!0)),Ge.current.shouldGreetOnConnect()&&(d.send(JSON.stringify({type:q.START_CONVERSATION})),c(oe(!0)),xe()),c(ne(N.IDLE)),fe.current.clear(),_e.current.clear(),we.current=null,Ce.current=!1,be.current=null,W.current=!1,Pe.current=!1,De.current=!1,Me.current="",ve.current=[],L.current=[],R.current=null,G.current=!1,c(ie(!1)),O.current.setPrerollProvider(()=>R.current??F),H.current&&(clearTimeout(H.current),H.current=null);const e=Date.now();me.current=e,he.current=e,ge.current="open",$.current&&clearInterval($.current),$.current=setInterval(()=>{const e=Date.now(),r=e-me.current;if(r>3e4)return h.warn({message:"Voice WS PONG watchdog tripped — closing presumed-dead socket",api_name:"voice-ws",generation:t,ms_since_last_pong:r,ms_since_last_event:e-he.current,last_event_type:ge.current,pipeline_status:o.current}),j.current=!0,$.current&&(clearInterval($.current),$.current=null),d.readyState<=WebSocket.OPEN&&d.close(),void w(1006,"watchdog forced",!1);h.debug({message:"Voice WS keepalive tick",api_name:"voice-ws",generation:t,current_generation:P.current,ready_state:d.readyState,will_send:d.readyState===WebSocket.OPEN}),d.readyState===WebSocket.OPEN&&d.send(JSON.stringify({type:q.PING}))},2e4)};let p=0;d.onmessage=e=>{if(t!==P.current)return;if(e.data instanceof ArrayBuffer){he.current=Date.now(),ge.current="binary",p++,1===p&&(U.current&&clearInterval(U.current),U.current=setInterval(()=>{p>0&&h.debug({message:"Voice WS audio chunks",api_name:"voice-ws",chunks:p})},2e3)),K.current&&ye(K.current,e.data);const t=L.current;if(t.push(performance.now()),t.length>30&&t.shift(),1===p&&W.current){W.current=!1;for(const[e,t]of Ee.current)t&&Ge.current.updateStreamingMessage(e,t)}return void O.current.play(e.data,u.current||void 0)}let r;try{r=JSON.parse(e.data)}catch{return}const n=r.type,s=r.data??r;switch(he.current=Date.now(),ge.current=n,n){case X.SPEECH_STARTED:if((pe.current>0?performance.now()-pe.current:1/0)<500)break;if(d.send(JSON.stringify({type:q.STOP_PLAYBACK})),Pe.current=!0,Ce.current=!1,c(de(null)),x.current.stop(),B.current&&clearTimeout(B.current),B.current=setTimeout(()=>{O.current.stop(),B.current=null},400),c(ne(N.LISTENING)),Fe(m.KEEP),De.current);else{(o.current===N.SPEAKING||o.current===N.PROCESSING)&&null!=we.current&&(_e.current.add(we.current),we.current=null);for(const e of fe.current.keys())_e.current.add(e);if(W.current){W.current=!1;for(const[e,t]of Ee.current)t&&Ge.current.updateStreamingMessage(e,t)}Ne(()=>Ge.current.commitStreamingMessages(),"barge-in"),Oe(),Ee.current.clear(),Re()}break;case X.SPEECH_STOPPED:Pe.current=!1,Ce.current=!0,be.current=we.current,B.current&&(clearTimeout(B.current),B.current=null),c(ne(N.PROCESSING)),De.current||(c(oe(!0)),c(ae(null)),xe());break;case X.STT_RESULT:{const e=s.message_id,t=null!=e&&e===be.current;if(null!=e&&_e.current.has(e)&&!t)break;null==e||t||(we.current=e);const r=s.text;if(!Ce.current&&!t){r&&c(de(r));break}if(Ce.current=!1,be.current=null,c(de(null)),r&&r.trim()){const t=e,n={id:`voice-user-${g()}`,sender:"user",message:r,timestamp:(new Date).toISOString()};Ge.current.setMessages(e=>{if(null!=t){const r=fe.current.get(t);if(r){const t=e.findIndex(e=>e.id===r);if(-1!==t){const r=[...e];return r.splice(t,0,n),r}}}return[...e,n]})}break}case X.TEXT_DELTA:{const e=s.token,t=s.message_id;if(!e||null==t)break;if(_e.current.has(t))break;T({kind:"text",text:e,messageId:t},Ke.current);break}case X.STATUS_UPDATE:if(Pe.current)break;T({kind:"status_update",statusText:s.text},Ke.current);break;case X.WIDGET:if(!r.data)break;Fe(m.KEEP),T({kind:"widget",widget:r.data},Ke.current);break;case X.PAYMENT:if(!r.data)break;T({kind:"payment",payment:r.data},Ke.current);break;case X.CONVERSATION_TITLE:{const e="string"==typeof s.text?s.text.trim():"";e&&T({kind:"conversation_title",title:e},Ke.current);break}case X.STATUS_CLEAR:De.current=!1,Me.current="",x.current.stop(),Fe(m.KEEP);break;case X.TTS_START:{const e=s.message_id;if(null!=e&&_e.current.has(e)){O.current.stop(),We();break}if(we.current=null,pe.current=performance.now(),x.current.pause(),p=0,L.current=[],O.current.stop(),We(),K.current=Te(D),null!=e&&!fe.current.has(e)){const t=`voice-agent-${g()}`;fe.current.set(e,t),Ee.current.set(t,"")}W.current=!0,Fe(De.current?m.KEEP:m.FINALIZE),c(ne(N.SPEAKING));break}case X.TTS_END:if(pe.current=0,U.current&&(clearInterval(U.current),U.current=null),p=0,We(),s.cancelled&&O.current.stop(),L.current.length>0&&(R.current=ke(L.current)),W.current){W.current=!1;for(const[e,t]of Ee.current)t&&Ge.current.updateStreamingMessage(e,t)}Ne(()=>Ge.current.commitStreamingMessages(),"tts-end"),Oe();let e=!1;const t=()=>{e||(e=!0,H.current&&(clearTimeout(H.current),H.current=null),c(ne(N.IDLE)),G.current||(G.current=!0,c(ie(!0))),null!=l.current&&x.current.resume(),Ne(()=>Ge.current.commitStreamingMessages(),"drain"),Oe(),De.current&&(c(oe(!0)),c(ae(Me.current)),x.current.start(O.current.remainingSeconds)))};O.current.onDrained(t),H.current&&clearTimeout(H.current),H.current=setTimeout(t,1e3*(O.current.remainingSeconds+5));break;case X.ERROR:{const e=s.message||"Voice error";T({kind:"error",error:e},Ke.current),c(ne(N.IDLE)),Fe(m.CANCEL);{const t=Y.some(t=>t.test(e)),r=J.some(t=>t.test(e));(t||r)&&(t&&(Q.current=!0),h.warn({message:"Voice WS fatal error — tearing down connection",api_name:"voice-ws",error_message:e,auth_recoverable:t}),d.close())}break}case X.PONG:me.current=Date.now(),z.current=0,ee.current=0,te.current=0;break;default:h.warn({message:"Voice WS unhandled event",api_name:"voice-ws",event_type:n})}};let _=!1;const w=(n,s,i)=>{if(_)return;if(_=!0,t!==P.current)return void h.debug({message:"Voice WS closed (superseded)",api_name:"voice-ws",code:n,reason:s});const u=Date.now(),l={api_name:"voice-ws",code:n,reason:s||null,was_clean:i,generation:t,ms_since_last_event:u-he.current,ms_since_last_pong:u-me.current,last_event_type:ge.current,pipeline_status:o.current};!0===i||1e3===n||1005===n?h.info({message:"Voice WS closed (clean)",...l}):h.warn({message:"Voice WS closed (abnormal)",...l}),$.current&&(clearInterval($.current),$.current=null),U.current&&(clearInterval(U.current),U.current=null),H.current&&(clearTimeout(H.current),H.current=null),c(se(!1)),c(ne(N.IDLE)),c(re(A.DISCONNECTED)),Fe(m.CANCEL),Ne(()=>Ge.current.commitStreamingMessages(),"onclose"),Oe(),Ee.current.clear(),De.current=!1,Ce.current=!1,c(de(null)),Me.current="",be.current=null;const d=!a||Q.current;if(Q.current=!1,d)return void(r===ce.current&&ee.current<1&&null!=e&&(ee.current+=1,h.info({message:"Voice WS auth-attributed close — refreshing session",api_name:"voice-ws",generation:t,attempt:ee.current,last_close_code:n}),(async()=>{const e=await(E()?.());r===ce.current&&(e?Be.current():h.warn({message:"Voice WS auth refresh failed — leaving disconnected (no reconnect)",api_name:"voice-ws",generation:t}))})()));const p=j.current||V.has(n);j.current=!1;const g=z.current>=3,S=p&&!g&&null!=e;p&&g&&h.warn({message:"Voice WS auto-reconnect cap exhausted — giving up",api_name:"voice-ws",generation:t,attempts:z.current,last_close_code:n}),S&&(z.current+=1,h.info({message:"Voice WS auto-reconnecting after abnormal close",api_name:"voice-ws",generation:t,attempt:z.current,delay_ms:1e3,last_close_code:n}),Z.current&&clearTimeout(Z.current),Z.current=setTimeout(()=>{Z.current=null,Be.current()},1e3))};d.onclose=e=>w(e.code,e.reason,e.wasClean),d.onerror=()=>{if(t!==P.current)return;const e=Date.now();h.warn({message:"Voice WS error event",api_name:"voice-ws",generation:t,ready_state:d.readyState,ms_since_last_event:e-he.current,ms_since_last_pong:e-me.current,last_event_type:ge.current,pipeline_status:o.current}),c(re(A.DISCONNECTED))}},[e,c,We,xe,Le,Re,Fe]),Be=r(Ue);s(()=>{Be.current=Ue},[Ue]);const He=n(e=>{const t=b.current;t&&t.readyState===WebSocket.OPEN&&t.send(e)},[]),$e=n(e=>{const t=b.current;if(!t||t.readyState!==WebSocket.OPEN)return;t.send(JSON.stringify({type:q.STOP_PLAYBACK})),Ve(),t.send(JSON.stringify({type:q.TEXT_MESSAGE,text:e}));const r=`voice-user-${g()}`;Ge.current.setMessages(t=>[...t,{id:r,sender:"user",message:e,timestamp:(new Date).toISOString()}]),c(oe(!0)),c(ae(null)),xe(),c(ne(N.PROCESSING))},[c,Ve,xe]),qe=n((e="user")=>{const t=b.current;h.info({message:"Voice WS disconnect() called",api_name:"voice-ws",reason:e,had_ws:null!==t,ready_state:t?.readyState,generation:P.current}),j.current=!1,Z.current&&(clearTimeout(Z.current),Z.current=null),z.current=0,ee.current=0,te.current=0,ce.current+=1,t&&t.readyState<=WebSocket.OPEN&&t.close(),b.current=null,$.current&&(clearInterval($.current),$.current=null),U.current&&(clearInterval(U.current),U.current=null),B.current&&(clearTimeout(B.current),B.current=null),H.current&&(clearTimeout(H.current),H.current=null),_e.current.clear(),we.current=null,Ce.current=!1,be.current=null,Pe.current=!1,De.current=!1,Me.current="",ve.current=[],W.current=!1,c(de(null)),Ve(),c(se(!1)),c(ne(N.IDLE)),c(re(A.DISCONNECTED)),Fe(m.CANCEL)},[c,Ve,Fe]),Ye=r(e),Je=r(!1);s(()=>{const t=Ye.current;if(Ye.current=e,t===e)return;const r=null!==b.current&&b.current.readyState<=WebSocket.OPEN;r&&(Je.current=!0),r&&(Ge.current.discardStreamingMessages(),Ee.current.clear(),ve.current=[],qe("conv-change")),Je.current&&null!=e&&(Je.current=!1,Ue())},[e,qe,Ue]);const je=r(C);return s(()=>{const e=je.current;if(je.current=C,e&&!C){const e=b.current;e&&e.readyState<=WebSocket.OPEN&&qe("logout")}},[C,qe]),s(()=>()=>{$.current&&clearInterval($.current),U.current&&clearInterval(U.current),B.current&&clearTimeout(B.current),H.current&&clearTimeout(H.current),Z.current&&clearTimeout(Z.current),W.current=!1,x.current.destroy(),O.current.destroy()},[]),{connect:Ue,disconnect:qe,sendAudioChunk:He,sendText:$e}}function De({micOpen:e,muted:t,onChunk:n}){const i=Ae(),[o,u]=c(!1),[l,d]=c(!1),p=a(e=>e.voice.selectedMicId),m=r(n);m.current=n;const h=r(null);return s(()=>{if(!e)return;u(!0),d(!1);const r=i.createCapture();return h.current=r,r.open({micDeviceId:p||null,initialMuted:t,onChunk:e=>m.current(e),onLoadingChange:u,onError:()=>d(!0)}),()=>{r.close(),h.current===r&&(h.current=null)}},[e,p]),s(()=>{h.current?.setMuted(t)},[t]),{loading:o,errored:l}}function Me(e,t,r){const n=a(e=>e.voice.connectionStatus),s=a(e=>e.voice.pipelineStatus),c=a(e=>e.voice.listeningEnabled),i=a(e=>e.voice.muted);return n===A.CONNECTING?P.CONNECTING:n===A.CONNECTED?c?e?P.LOADING:t?P.OFFLINE:r??i?P.MUTED:s===N.PROCESSING?P.PROCESSING:s===N.SPEAKING?P.SPEAKING:s===N.LISTENING?P.LISTENING:P.IDLE:P.READY:P.OFFLINE}const Oe=e(null),xe=({conversationId:e,voiceBridge:t,assistantStartsConversation:o})=>{const u=i(),l=Ae(),d=a(e=>e.voice.muted),p=a(e=>e.voice.connectionStatus),m=a(e=>e.voice.pipelineStatus),g=a(e=>e.voice.isAgentWorking),S=a(e=>e.voice.listeningEnabled),f=a(e=>e.voice.firstAssistantMessageComplete),[E,v]=c(!1),{connect:T,disconnect:y,sendAudioChunk:I,sendText:w}=Pe(e,t),{orbMuted:k,effectiveMuted:C}=function(e){const t=e.userMuted||e.assistantStartsConversation&&!e.firstAssistantMessageComplete&&!e.welcomeMuteDismissed;return{orbMuted:t,effectiveMuted:t||!0===e.requiresSoftwareAecMute&&e.pipelineStatus===N.SPEAKING}}({userMuted:d,assistantStartsConversation:o,firstAssistantMessageComplete:f,welcomeMuteDismissed:E,pipelineStatus:m,requiresSoftwareAecMute:l.requiresSoftwareAecMute}),b=o&&!f;s(()=>{b&&p===A.CONNECTED||v(!1)},[p,b]);const{loading:P,errored:D}=De({micOpen:S,muted:C,onChunk:I}),M=Me(P,D,k);s(()=>(t.setVoiceSendText(w),()=>t.setVoiceSendText(null)),[t,w]);const O=r(!1);return{displayState:M,pipelineStatus:m,isAgentWorking:g,enterVoiceMode:n(async()=>{if(O.current)return _("Microphone permission changed — please reload the page to apply the new setting."),!1;const e=await l.requestMicPermission();return e.granted?(T(),!0):(h.error({message:"Mic permission denied",api_name:"voice-mic",error_message:e.error?e.error instanceof Error?e.error.message:String(e.error):void 0}),O.current=!0,_("Microphone access is required for voice mode. Please allow it in your browser's site settings and reload the page."),!1)},[l,T]),exitVoiceMode:n(()=>{y()},[y]),toggleMute:n(()=>{if(k)return v(!0),void u(ce(!1));u(ce(!0))},[u,k]),sendText:w,muted:k,micLoading:P,micErrored:D}},Le=()=>{const e=t(Oe);if(!e)throw new Error("useVoice must be used within VoiceProvider");return e},Re=e({strategyActive:!1,voiceSlot:null,onEnterVoice:null,onFloatingOrbClick:null,voiceInputHidden:!1,headerCenterSlot:null,floatOrbPositionRef:null}),Ge=()=>t(Re),We={stop:null};function Ve(e){const[t,i]=c(!1),o=r(null),u=r(null),l=r(!1),d=a(e=>e.voice.selectedSpeakerId),p=r(d);p.current=d;const m=!!e&&!!_e(e),h=n(()=>{u.current?.stop(),u.current?.disconnect(),u.current=null,o.current?.close(),o.current=null,l.current=!1,i(!1)},[]),g=n(()=>{if(t)return h(),void(We.stop=null);if(!e)return;const r=_e(e);if(!r)return;We.stop&&We.stop();const n=p.current,s=new AudioContext({sampleRate:r.sampleRate??D,...n?{sinkId:n}:{}});o.current=s;const c=new Float32Array(r.pcmInt16.length);for(let e=0;e<r.pcmInt16.length;e++)c[e]=r.pcmInt16[e]/M;const a=s.createBuffer(1,c.length,r.sampleRate??D);a.getChannelData(0).set(c);const d=s.createBufferSource();d.buffer=a,d.connect(s.destination),u.current=d,d.onended=()=>{h(),We.stop=null},We.stop=h,l.current=!0,i(!0),d.start()},[t,e,h]);return s(()=>()=>{l.current&&(h(),We.stop===h&&(We.stop=null))},[h]),{playing:t,toggle:g,hasAudio:m}}function Fe(){const e=Ae(),[t,r]=c([]),[i,o]=c([]),u=a(e=>e.voice.listeningEnabled),l=n(async()=>{const t=await e.devices.enumerate();r(t.microphones),o(t.speakers)},[e]);return s(()=>(l(),e.devices.onChange(l)),[e,l]),s(()=>{u&&l()},[u,l]),{microphones:t,speakers:i,refresh:l}}const Ke=u();Ke.startListening({actionCreator:pe,effect:async e=>{const t=w();t&&await t.setItem(Z.SELECTED_MIC_ID,e.payload)}}),Ke.startListening({actionCreator:me,effect:async e=>{const t=w();t&&await t.setItem(Z.SELECTED_SPEAKER_ID,e.payload)}}),Ke.startListening({actionCreator:he,effect:()=>{we()}}),Ke.startListening({matcher:l(k,C),effect:async(e,t)=>{const r=w();r&&await Promise.all([r.removeItem(Z.SELECTED_MIC_ID),r.removeItem(Z.SELECTED_SPEAKER_ID)]),t.dispatch(he())}});class Ue{ctx=null;stream=null;source=null;gain=null;worklet=null;worker=null;visibilityHandler=null;opening=!1;cancelled=!1;opts=null;open(e){this.opening||this.ctx||(this.cancelled=!1,this.opening=!0,this.opts=e,e.onLoadingChange?.(!0),(async()=>{let t=null,r=null,n=null,s=null,c=null,i=null;try{try{t=new AudioContext({sampleRate:D})}catch{t=new AudioContext}if(this.cancelled)return void await t.close().catch(()=>{});if(await t.audioWorklet.addModule(`${b()}/audio-recorder.worklet.js`),this.cancelled)return void await t.close().catch(()=>{});if(r=await navigator.mediaDevices.getUserMedia({audio:{...e.micDeviceId?{deviceId:{exact:e.micDeviceId}}:{},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1,sampleRate:D,echoCancellationType:{ideal:"system"}}}),this.cancelled)return r.getTracks().forEach(e=>e.stop()),void await t.close().catch(()=>{});n=t.createMediaStreamSource(r),s=t.createGain(),s.gain.setValueAtTime(e.initialMuted?0:1,t.currentTime),c=new AudioWorkletNode(t,"audio-recorder"),i=new Worker(`${b()}/audio-processor.worker.js`);const a=i;if(c.port.onmessage=e=>{if(this.cancelled)return;const t=e.data;t&&0!==t.length&&a.postMessage({type:"frame",frame:t},[t.buffer])},i.onmessage=e=>{const t=e.data;t&&"chunk"===t.type&&t.buffer instanceof ArrayBuffer&&this.opts?.onChunk(t.buffer)},n.connect(s).connect(c).connect(t.destination),"suspended"===t.state&&await t.resume().catch(()=>{}),this.cancelled)return i.terminate(),c.disconnect(),s.disconnect(),n.disconnect(),r.getTracks().forEach(e=>e.stop()),void await t.close().catch(()=>{});this.ctx=t,this.stream=r,this.source=n,this.gain=s,this.worklet=c,this.worker=i;const o=()=>{"visible"===document.visibilityState&&"suspended"===t.state&&t.resume().catch(()=>{})};document.addEventListener("visibilitychange",o),this.visibilityHandler=o,this.opts?.onLoadingChange?.(!1)}catch(e){h.error({message:"Mic capture failed",api_name:"voice-mic",error_message:e instanceof Error?e.message:String(e)}),t?.close().catch(()=>{}),r?.getTracks().forEach(e=>e.stop()),i?.terminate(),c?.disconnect(),s?.disconnect(),n?.disconnect(),this.cancelled||(this.opts?.onError?.(e),this.opts?.onLoadingChange?.(!1))}finally{this.opening=!1}})())}setMuted(e){const t=this.ctx,r=this.gain;t&&r&&(r.gain.setValueAtTime(e?0:1,t.currentTime),e&&this.worker?.postMessage({type:$}))}close(){this.cancelled=!0;const e=this.worker,t=this.worklet,r=this.gain,n=this.source,s=this.stream,c=this.ctx;e&&(e.postMessage({type:$}),e.terminate()),t?.disconnect(),r?.disconnect(),n?.disconnect(),s?.getTracks().forEach(e=>e.stop()),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),c?.close().catch(()=>{}),this.ctx=null,this.stream=null,this.source=null,this.gain=null,this.worklet=null,this.worker=null,this.opts=null}}class Be{async enumerate(){const e={microphones:[],speakers:[]};if(!navigator.mediaDevices?.enumerateDevices)return e;try{const e=await navigator.mediaDevices.enumerateDevices();let t=0,r=0;return{microphones:e.filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Microphone "+ ++t})),speakers:e.filter(e=>"audiooutput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Speaker "+ ++r}))}}catch{return e}}onChange(e){const t=navigator.mediaDevices;return t?.addEventListener?(t.addEventListener("devicechange",e),()=>t.removeEventListener("devicechange",e)):()=>{}}}class He{audio=null;timer=null;pendingPlay=null;pendingAction=null;unlock(){this.audio||(this.audio=new Audio(`${b()}${L}`),this.audio.loop=!0,this.audio.volume=.5,this.audio.preload="auto",this.audio.load());const e=this.audio.volume;this.audio.volume=0;const t=this.audio.play();t&&"function"==typeof t.then?t.then(()=>{this.pendingPlay?this.audio&&(this.audio.volume=e):(this.audio?.pause(),this.audio&&(this.audio.currentTime=0,this.audio.volume=e))}).catch(()=>{this.audio&&(this.audio.volume=e)}):(this.pendingPlay||(this.audio.pause(),this.audio.currentTime=0),this.audio.volume=e)}start(e){if(this.timer||this.audio&&!this.audio.paused)return;this.stop(),this.audio||(this.audio=new Audio(`${b()}${L}`),this.audio.loop=!0,this.audio.volume=.5);const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this._doPlay()},t)}pause(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingPlay?this.pendingAction="pause":this.audio&&!this.audio.paused&&this.audio.pause()}resume(e=0){if(!this.audio)return;const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this._doPlay()},t)}stop(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingPlay?this.pendingAction="stop":this.audio&&(this.audio.pause(),this.audio.currentTime=0)}destroy(){this.stop(),this.pendingAction=null,this.audio&&(this.audio.removeAttribute("src"),this.audio=null)}_doPlay(){this.pendingAction=null;const e=this.audio?.play();e instanceof Promise?(this.pendingPlay=e,e.then(()=>{this.pendingPlay=null;const e=this.pendingAction;this.pendingAction=null,"pause"===e?this.audio?.pause():"stop"===e&&this.audio&&(this.audio.pause(),this.audio.currentTime=0)}).catch(()=>{this.pendingPlay=null,this.pendingAction=null})):this.pendingPlay=null}}const $e={createCapture:()=>new Ue,createPlayer:()=>new Ce,createThinkingSound:()=>new He,devices:new Be,requestMicPermission:async function(){try{return(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(e=>e.stop()),{granted:!0}}catch(e){return{granted:!1,error:e}}},requiresSoftwareAecMute:!1};export{be as AudioPlatformContext,Ue as BrowserAudioCapture,Be as BrowserAudioDevices,Ce as BrowserAudioPlayer,He as BrowserThinkingSound,z as ORB_STATE_CONFIG,Y as VOICE_AUTH_ERROR_PATTERNS,G as VOICE_BARGE_IN_DELAY_MS,O as VOICE_CHUNK_SAMPLES,A as VOICE_CONNECTION_STATUSES,P as VOICE_DISPLAY_STATES,j as VOICE_FATAL_ERROR_PATTERNS,W as VOICE_KEEPALIVE_INTERVAL_MS,M as VOICE_PCM_INT16_MAX,N as VOICE_PIPELINE_STATUSES,F as VOICE_PREROLL_DEFAULT_SECONDS,B as VOICE_PREROLL_JITTER_WINDOW,U as VOICE_PREROLL_MAX_SECONDS,H as VOICE_PREROLL_MIN_SAMPLES,K as VOICE_PREROLL_MIN_SECONDS,D as VOICE_SAMPLE_RATE,Z as VOICE_STORAGE_KEYS,J as VOICE_TERMINAL_ERROR_PATTERNS,R as VOICE_THINKING_SOUND_DELAY_MS,L as VOICE_THINKING_SOUND_PATH,x as VOICE_THINKING_SOUND_VOLUME,q as VOICE_WS_CLIENT,X as VOICE_WS_SERVER,Oe as VoiceContext,Re as VoiceUIContext,$e as browserAudioPlatform,we as clearAudioBuffer,ke as computeAdaptivePreroll,Te as createAccumulator,Ie as finalizeAudio,_e as getAudio,ee as hydrateVoice,ye as pushChunk,ge as resetIndicatorState,re as setConnectionStatus,le as setError,ie as setFirstAssistantMessageComplete,oe as setIsAgentWorking,se as setListeningEnabled,ce as setMuted,ne as setPipelineStatus,ue as setResponseStartTime,pe as setSelectedMicId,me as setSelectedSpeakerId,ae as setStatusText,Ae as useAudioPlatform,Fe as useMediaDevices,Le as useVoice,Ve as useVoiceAudioPlayback,Me as useVoiceDisplayState,De as useVoiceMicCapture,xe as useVoiceProviderValue,Ge as useVoiceUI,Pe as useVoiceWebSocket,Ke as voiceListenerMiddleware,Se as voiceReducer};
1
+ import{createContext as e,useContext as t,useRef as r,useEffect as n,useCallback as s,useState as c}from"react";import{useDispatch as a,useSelector as i}from"react-redux";import{createSlice as o,createListenerMiddleware as u,isAnyOf as l}from"@reduxjs/toolkit";import{API_ENDPOINTS as d,logger as p,getCustomHeaders as g,readAccessToken as m,clearLastResponseTime as E,setLastResponseTime as S,INDICATOR_TIMER_ACTIONS as I,generateUniqueId as v,handleSharedEvent as T,isTokenAboutToExpire as f,readTokenExpiresAt as y,getTokenRefreshHandler as C,showErrorToast as k,getStorageRef as h,clearSession as M,sessionExpired as N}from"@1interface/shared-core";const b={DISCONNECTED:"disconnected",CONNECTING:"connecting",CONNECTED:"connected"},w={IDLE:"idle",LISTENING:"listening",PROCESSING:"processing",SPEAKING:"speaking"},_={CASCADE:"cascade",REALTIME:"realtime"},D={OFFLINE:"offline",CONNECTING:"connecting",READY:"ready",LOADING:"loading",IDLE:"idle",LISTENING:"listening",MUTED:"muted",PROCESSING:"processing",SPEAKING:"speaking"},L=15e3,R={SELECTED_MIC_ID:"voice_selectedMicId",SELECTED_SPEAKER_ID:"voice_selectedSpeakerId"},P={offline:{opacity:.15,playbackRate:.3,scale:1},connecting:{opacity:.4,playbackRate:.5,scale:1},ready:{opacity:.4,playbackRate:.4,scale:1},loading:{opacity:.6,playbackRate:.6,scale:1},idle:{opacity:.6,playbackRate:.6,scale:1},listening:{opacity:.7,playbackRate:.7,scale:1},muted:{opacity:.7,playbackRate:.5,scale:1},processing:{opacity:1,playbackRate:1,scale:1},speaking:{opacity:1,playbackRate:1,scale:1.3}};function x(){return{connectionStatus:b.DISCONNECTED,pipelineStatus:w.IDLE,listeningEnabled:!1,muted:!1,serverMuted:!1,statusText:null,isAgentWorking:!1,responseStartTime:null,error:null,interimTranscript:null,botTurn:{active:!1,chatMsgId:null,segments:[]},selectedMicId:"",selectedSpeakerId:""}}const A=e=>async t=>{const[r,n]=await Promise.all([e.getItem(R.SELECTED_MIC_ID),e.getItem(R.SELECTED_SPEAKER_ID)]);r&&t(O.actions.setSelectedMicId(r)),n&&t(O.actions.setSelectedSpeakerId(n))},O=o({name:"voice",initialState:x(),reducers:{setConnectionStatus(e,t){e.connectionStatus=t.payload},setPipelineStatus(e,t){e.pipelineStatus=t.payload},setListeningEnabled(e,t){e.listeningEnabled=t.payload},setStatusText(e,t){e.statusText=t.payload},setIsAgentWorking(e,t){e.isAgentWorking=t.payload},setResponseStartTime(e,t){e.responseStartTime=t.payload},setError(e,t){e.error=t.payload},setInterimTranscript(e,t){e.interimTranscript=t.payload},openBotTurn(e,t){e.botTurn={active:!0,chatMsgId:t.payload?.chatMsgId??null,segments:[]}},upsertBotSegment(e,t){const{id:r,text:n,spokenChars:s}=t.payload;e.botTurn.active=!0;const c=e.botTurn.segments.find(e=>e.id===r);c?(c.text=n,c.spokenChars=Math.max(c.spokenChars,s)):(e.botTurn.segments.push({id:r,text:n,spokenChars:s}),e.botTurn.segments.sort((e,t)=>e.id-t.id))},clearBotTurn(e){e.botTurn={active:!1,chatMsgId:null,segments:[]}},setMuted(e,t){e.muted=t.payload},setServerMuted(e,t){e.serverMuted=t.payload},setSelectedMicId(e,t){e.selectedMicId=t.payload},setSelectedSpeakerId(e,t){e.selectedSpeakerId=t.payload},resetVoiceState:()=>x(),resetIndicatorState(e){e.statusText=null,e.isAgentWorking=!1,e.responseStartTime=null,e.interimTranscript=null,e.serverMuted=!1,e.botTurn={active:!1,chatMsgId:null,segments:[]}}}}),{setConnectionStatus:V,setPipelineStatus:G,setListeningEnabled:B,setMuted:F,setServerMuted:W,setStatusText:K,setIsAgentWorking:U,setResponseStartTime:j,setError:$,setInterimTranscript:q,openBotTurn:Z,upsertBotSegment:H,clearBotTurn:Y,setSelectedMicId:X,setSelectedSpeakerId:z,resetVoiceState:J,resetIndicatorState:Q}=O.actions,ee=O.reducer,te=e(null),re=()=>{const e=t(te);if(!e)throw new Error("useAudioPlatform must be used inside <AudioPlatformProvider>. <VoiceProvider> mounts one by default; if you replaced VoiceProvider, you must wire your own.");return e};function ne(){const e={};for(const[t,r]of Object.entries(g()))r&&(e[t]=r);const t=m();return t&&(e["X-Access-Token"]=t),e}async function se(e){try{const t=await fetch(d.WEBRTC_ICE(e),{headers:ne()});return t.ok?(await t.json()).iceServers??[]:(p.warn({message:"Voice ICE fetch failed — continuing without TURN",api_name:"voice-webrtc-ice",status:t.status}),[])}catch(e){return p.warn({message:"Voice ICE fetch error — continuing without TURN",api_name:"voice-webrtc-ice",error_message:e instanceof Error?e.message:String(e)}),[]}}const ce="voice-user-",ae=(e,t=`${ce}${v()}`)=>({id:t,sender:"user",message:e,timestamp:(new Date).toISOString()});function ie(e,t,r){const n=i(e=>e.voice.connectionStatus),s=i(e=>e.voice.pipelineStatus),c=i(e=>e.voice.listeningEnabled),a=i(e=>e.voice.muted);return n===b.CONNECTING?D.CONNECTING:n===b.CONNECTED?c?e?D.LOADING:t?D.OFFLINE:r??a?D.MUTED:s===w.PROCESSING?D.PROCESSING:s===w.SPEAKING?D.SPEAKING:s===w.LISTENING?D.LISTENING:D.IDLE:D.READY:D.OFFLINE}const oe=e(null),ue=({conversationId:e,voiceBridge:t,transportFactory:c})=>{const o=a(),u=re(),l=i(e=>e.voice.muted),g=i(e=>e.voice.serverMuted),m=i(e=>e.voice.pipelineStatus),h=i(e=>e.voice.isAgentWorking),{connect:M,disconnect:N,sendText:D,setMicEnabled:L}=function(e,t,c){const o=a(),u=re(),l=i(e=>e.auth.accessToken),g=r(t);n(()=>{g.current=t});const m=r(null),h=r(new Map),M=r(""),N=r(!1),D=r([]),L=r(null),R=r(""),P=r(null),x=r(null),A=r(null),O=r(0),F=r(0),X=r(!1),z=r(0),J=r(null),Q=s(()=>{if(null!=J.current)return;const e=Date.now();J.current=e,o(j(e)),o(E())},[o]),ee=s(()=>{const e=J.current;J.current=null,o(j(null)),null!=e&&o(S(Date.now()-e))},[o]),te=s(()=>{J.current=null,o(j(null))},[o]),ie=s((e=I.KEEP)=>{o(K(null)),o(U(!1)),e===I.FINALIZE?ee():e===I.CANCEL&&te()},[o,ee,te]),oe=r({setStatusText:e=>o(K(e||null)),setIsAgentWorking:e=>o(U(e)),appendStreamText:()=>{},pushWidget:e=>{D.current.push(e)},onPayment:e=>g.current.onPaymentInit?.(e),onConversationTitle:e=>g.current.onConversationTitle?.(e),onError:e=>{p.error({message:"Voice RTVI server error",api_name:"voice-rtvi",error_message:e}),o($(e))},onStatusActive:()=>{Q()}}),ue=s(()=>{A.current&&(clearTimeout(A.current),A.current=null)},[]),le=s(()=>[...h.current.entries()].sort((e,t)=>e[0]-t[0]).map(([,e])=>e).join(" ").trim(),[]),de=s(()=>{const e=m.current;if(e){const t=le();t&&g.current.updateStreamingMessage(e,t),g.current.commitStreamingMessages()}m.current=null,h.current=new Map,M.current="",o(Y())},[o,le]),pe=s(()=>{const e=D.current;if(!e.length)return;D.current=[];const t=`voice-widget-${v()}`;g.current.setMessages(r=>[...r,{id:t,msg_id:t,sender:"agent",message:"",timestamp:(new Date).toISOString(),widget:e,message_type:["widget"]}])},[]),ge=s(e=>{ue(),x.current?.(),x.current=null,P.current=null,X.current=!1,o(B(!1)),o(G(w.IDLE)),o(V(b.DISCONNECTED)),o(q(null)),o(W(!1)),L.current=null,R.current="",N.current=!1,e?(de(),pe()):(g.current.discardStreamingMessages(),m.current=null,h.current=new Map,M.current="",D.current=[],o(Y())),ie(I.CANCEL)},[o,ie,ue,de,pe]),me=s(()=>{if(m.current)return;const e=`voice-agent-${v()}`;if(m.current=e,h.current=new Map,M.current="",o(Z({chatMsgId:e})),D.current.length){const t=D.current;D.current=[];for(const r of t)g.current.addStreamingWidget(e,r)}},[o]),Ee=s(e=>{const t=e.spoken_progress?.accumulated_text??"",r=e.spoken_progress?t+(e.spoken_progress?.remaining_text??""):e.text??"";if(!r)return;if(me(),N.current){const e=(h.current.get(0)??"")+r;h.current.set(0,e),o(H({id:0,text:e,spokenChars:e.length}))}else{const n=e.segment_id??0;h.current.set(n,r),o(H({id:n,text:r,spokenChars:e.spoken_progress?t.length:r.length}))}const n=le();n&&m.current&&n!==M.current&&(M.current=n,g.current.updateStreamingMessage(m.current,n))},[o,me,le]),Se=s(e=>{const t=e,r=t?.type,n=t?.data;switch(r){case"status_update":T({kind:"status_update",statusText:n?.text??""},oe.current);break;case"clear_status":ie(I.KEEP);break;case"widget":n&&T({kind:"widget",widget:n},oe.current);break;case"payment":n&&T({kind:"payment",payment:n},oe.current);break;case"conversation_title":{const e="string"==typeof n?.text?n.text.trim():"";e&&T({kind:"conversation_title",title:e},oe.current);break}default:p.debug({message:"Voice RTVI unhandled server-message",api_name:"voice-rtvi",event_type:r??"unknown"})}},[ie]),Ie=r(()=>{}),ve=s(e=>{const t=()=>e===O.current;return{onConnected:()=>{t()&&(o(V(b.CONNECTED)),o(B(!0)),o(G(w.IDLE)))},onBotReady:e=>{if(!t())return;const r=e?.about;N.current=r?.pipeline_mode===_.REALTIME,ue()},onDisconnected:()=>{t()&&ge(!0)},onError:e=>{if(!t())return;const r=e?.data;T({kind:"error",error:r?.error??r?.message??"Voice error"},oe.current),o(G(w.IDLE)),ie(I.CANCEL),r?.fatal&&Ie.current()},onTrackStarted:(e,r)=>{t()&&(r?.local||"audio"!==e.kind||(x.current?.(),x.current=u.attachBotAudioTrack(e)))},onUserMuteStarted:()=>{t()&&o(W(!0))},onUserMuteStopped:()=>{t()&&o(W(!1))},onUserStartedSpeaking:()=>{t()&&(pe(),L.current=null,R.current="",o(q(null)),o(G(w.LISTENING)))},onUserStoppedSpeaking:()=>{if(!t())return;o(G(w.PROCESSING)),o(U(!0)),o(K(null)),Q();const e=R.current.trim();if(e){const t=`${ce}${v()}`;L.current=t,o(q(null)),g.current.setMessages(r=>[...r,ae(e,t)])}},onUserTranscript:e=>{if(!t())return;if(!e.final)return void(e.text&&(R.current=e.text,N.current||o(q(e.text))));o(q(null));const r=e.text&&e.text.trim()?e.text:"",n=L.current;L.current=null,n?r&&g.current.setMessages(e=>e.map(e=>e.id===n?{...e,message:r}:e)):r&&g.current.setMessages(e=>[...e,ae(r)])},onBotStartedSpeaking:()=>{t()&&(me(),o(G(w.SPEAKING)),ie(I.FINALIZE))},onBotOutput:e=>{t()&&Ee(e)},onBotStoppedSpeaking:()=>{t()&&(de(),o(G(w.IDLE)),ie(I.FINALIZE))},onServerMessage:e=>{t()&&Se(e)}}},[o,u,ue,ge,ie,Q,Ee,me,de,pe,Se]),Te=s(async()=>{if(P.current||X.current)return;if(!e)return;if(X.current=!0,f(y())&&z.current<1){z.current+=1;const e=F.current;try{await Promise.resolve(C()?.())}catch{}if(e!==F.current)return}const t=++O.current,r=F.current;o(V(b.CONNECTING));const n=()=>r!==F.current||t!==O.current;try{const[{PipecatClient:r},s]=await Promise.all([import("./index.module-S2alA3-r.js"),se(e)]);if(n())return;const a=new r({transport:c(),enableMic:!0,enableCam:!1,callbacks:ve(t)});if(n())return void a.disconnect();P.current=a,ue(),A.current=setTimeout(()=>{p.warn({message:"Voice RTVI connect timed out (no bot-ready)",api_name:"voice-rtvi"}),k("Voice connection timed out. Please try again."),Ie.current()},15e3),await a.connect({webrtcRequestParams:{endpoint:d.WEBRTC_OFFER(e),headers:new Headers(ne())},iceConfig:{iceServers:s}})}catch(e){p.error({message:"Voice RTVI connect failed",api_name:"voice-rtvi",error_message:e instanceof Error?e.message:String(e)}),t===O.current&&(k("Could not connect voice. Please try again."),ge(!1))}},[e,o,c,ve,ue,ge]),fe=s((e=!0)=>{F.current+=1,O.current+=1,z.current=0;const t=P.current;if(t)try{t.disconnect()}catch(e){p.warn({message:"Voice RTVI disconnect threw",api_name:"voice-rtvi",error_message:e instanceof Error?e.message:String(e)})}ge(e)},[ge]),ye=s(e=>{P.current?.enableMic(e)},[]),Ce=s(e=>{const t=P.current;if(t){try{t.sendText(e,{run_immediately:!0,audio_response:!0})}catch(e){return void p.error({message:"Voice RTVI send-text failed",api_name:"voice-rtvi",error_message:e instanceof Error?e.message:String(e)})}g.current.setMessages(t=>[...t,ae(e)]),o(U(!0)),o(K(null)),Q(),o(G(w.PROCESSING))}},[o,Q]);n(()=>{Ie.current=fe},[fe]);const ke=r(e),he=r(!1);n(()=>{const t=ke.current;if(ke.current=e,t===e)return;const r=X.current;r&&(he.current=!0),r&&fe(!1),he.current&&null!=e&&(he.current=!1,Te())},[e,fe,Te]);const Me=r(l);return n(()=>{const e=Me.current;Me.current=l,e&&!l&&X.current&&fe(!1)},[l,fe]),n(()=>()=>{Ie.current()},[]),{connect:Te,disconnect:fe,sendText:Ce,setMicEnabled:ye}}(e,t,c);n(()=>{L(!l&&!g)},[l,g,L]);const R=ie(!1,!1,l);n(()=>(t.setVoiceSendText(D),()=>t.setVoiceSendText(null)),[t,D]);const P=r(!1);return{displayState:R,pipelineStatus:m,isAgentWorking:h,enterVoiceMode:s(async()=>{if(P.current)return k("Microphone permission changed — please reload the page to apply the new setting."),!1;const e=await u.requestMicPermission();if(!e.granted){const t=e.error;return p.error({message:"Mic permission denied",api_name:"voice-mic",error_message:t instanceof Error?t.message:t?String(t):void 0}),P.current=!0,k("Microphone access is required for voice mode. Please allow it in your browser's site settings and reload the page."),!1}return M(),!0},[u,M]),exitVoiceMode:s(()=>{N()},[N]),toggleMute:s(()=>{o(F(!l))},[o,l]),sendText:D,muted:l,serverMuted:g}},le=()=>{const e=t(oe);if(!e)throw new Error("useVoice must be used within VoiceProvider");return e},de=e({strategyActive:!1,voiceSlot:null,onEnterVoice:null,onFloatingOrbClick:null,voiceInputHidden:!1,headerCenterSlot:null,floatOrbPositionRef:null}),pe=()=>t(de);function ge(){const e=re(),[t,r]=c([]),[a,o]=c([]),u=i(e=>e.voice.listeningEnabled),l=s(async()=>{const t=await e.devices.enumerate();r(t.microphones),o(t.speakers)},[e]);return n(()=>(l(),e.devices.onChange(l)),[e,l]),n(()=>{u&&l()},[u,l]),{microphones:t,speakers:a,refresh:l}}const me=u();me.startListening({actionCreator:X,effect:async e=>{const t=h();t&&await t.setItem(R.SELECTED_MIC_ID,e.payload)}}),me.startListening({actionCreator:z,effect:async e=>{const t=h();t&&await t.setItem(R.SELECTED_SPEAKER_ID,e.payload)}}),me.startListening({matcher:l(M,N),effect:async(e,t)=>{const r=h();r&&await Promise.all([r.removeItem(R.SELECTED_MIC_ID),r.removeItem(R.SELECTED_SPEAKER_ID)]),t.dispatch(J())}});class Ee{async enumerate(){const e={microphones:[],speakers:[]};if(!navigator.mediaDevices?.enumerateDevices)return e;try{const e=await navigator.mediaDevices.enumerateDevices();let t=0,r=0;return{microphones:e.filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Microphone "+ ++t})),speakers:e.filter(e=>"audiooutput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label||"Speaker "+ ++r}))}}catch{return e}}onChange(e){const t=navigator.mediaDevices;return t?.addEventListener?(t.addEventListener("devicechange",e),()=>t.removeEventListener("devicechange",e)):()=>{}}}const Se=e=>{const t=document.createElement("audio");return t.autoplay=!0,t.style.display="none",t.srcObject=new MediaStream([e]),document.body.appendChild(t),()=>{try{t.pause(),t.srcObject=null,t.remove()}catch{}}},Ie={attachBotAudioTrack:Se,devices:new Ee,requestMicPermission:async function(){try{return(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(e=>e.stop()),{granted:!0}}catch(e){return{granted:!1,error:e}}}};export{te as AudioPlatformContext,Ee as BrowserAudioDevices,P as ORB_STATE_CONFIG,b as VOICE_CONNECTION_STATUSES,L as VOICE_CONNECT_TIMEOUT_MS,D as VOICE_DISPLAY_STATES,_ as VOICE_PIPELINE_MODES,w as VOICE_PIPELINE_STATUSES,R as VOICE_STORAGE_KEYS,oe as VoiceContext,de as VoiceUIContext,Se as attachBrowserBotAudioTrack,Ie as browserAudioPlatform,Y as clearBotTurn,A as hydrateVoice,Z as openBotTurn,Q as resetIndicatorState,V as setConnectionStatus,$ as setError,q as setInterimTranscript,U as setIsAgentWorking,B as setListeningEnabled,F as setMuted,G as setPipelineStatus,j as setResponseStartTime,X as setSelectedMicId,z as setSelectedSpeakerId,W as setServerMuted,K as setStatusText,H as upsertBotSegment,re as useAudioPlatform,ge as useMediaDevices,le as useVoice,ie as useVoiceDisplayState,ue as useVoiceProviderValue,pe as useVoiceUI,me as voiceListenerMiddleware,ee as voiceReducer};
@@ -0,0 +1 @@
1
+ "use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var t,r={exports:{}};const s=e(function(){if(t)return r.exports;t=1;var e,s="object"==typeof Reflect?Reflect:null,n=s&&"function"==typeof s.apply?s.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};e=s&&"function"==typeof s.ownKeys?s.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var i=Number.isNaN||function(e){return e!=e};function o(){o.init.call(this)}r.exports=o,r.exports.once=function(e,t){return new Promise(function(r,s){function n(r){e.removeListener(t,i),s(r)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",n),r([].slice.call(arguments))}b(e,t,i,{once:!0}),"error"!==t&&function(e,t){"function"==typeof e.on&&b(e,"error",t,{once:!0})}(e,n)})},o.EventEmitter=o,o.prototype._events=void 0,o.prototype._eventsCount=0,o.prototype._maxListeners=void 0;var a=10;function c(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function d(e){return void 0===e._maxListeners?o.defaultMaxListeners:e._maxListeners}function l(e,t,r,s){var n,i,o;if(c(r),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),i=e._events),o=i[t]),void 0===o)o=i[t]=r,++e._eventsCount;else if("function"==typeof o?o=i[t]=s?[r,o]:[o,r]:s?o.unshift(r):o.push(r),(n=d(e))>0&&o.length>n&&!o.warned){o.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=o.length,console&&console.warn&&console.warn(a)}return e}function p(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function u(e,t,r){var s={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},n=p.bind(s);return n.listener=r,s.wrapFn=n,n}function h(e,t,r){var s=e._events;if(void 0===s)return[];var n=s[t];return void 0===n?[]:"function"==typeof n?r?[n.listener||n]:[n]:r?function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(n):g(n,n.length)}function m(e){var t=this._events;if(void 0!==t){var r=t[e];if("function"==typeof r)return 1;if(void 0!==r)return r.length}return 0}function g(e,t){for(var r=new Array(t),s=0;s<t;++s)r[s]=e[s];return r}function b(e,t,r,s){if("function"==typeof e.on)s.once?e.once(t,r):e.on(t,r);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,function n(i){s.once&&e.removeEventListener(t,n),r(i)})}}return Object.defineProperty(o,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||i(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");a=e}}),o.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},o.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||i(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},o.prototype.getMaxListeners=function(){return d(this)},o.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t.push(arguments[r]);var s="error"===e,i=this._events;if(void 0!==i)s=s&&void 0===i.error;else if(!s)return!1;if(s){var o;if(t.length>0&&(o=t[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)n(c,this,t);else{var d=c.length,l=g(c,d);for(r=0;r<d;++r)n(l[r],this,t)}return!0},o.prototype.on=o.prototype.addListener=function(e,t){return l(this,e,t,!1)},o.prototype.prependListener=function(e,t){return l(this,e,t,!0)},o.prototype.once=function(e,t){return c(t),this.on(e,u(this,e,t)),this},o.prototype.prependOnceListener=function(e,t){return c(t),this.prependListener(e,u(this,e,t)),this},o.prototype.off=o.prototype.removeListener=function(e,t){var r,s,n,i,o;if(c(t),void 0===(s=this._events))return this;if(void 0===(r=s[e]))return this;if(r===t||r.listener===t)0===--this._eventsCount?this._events=Object.create(null):(delete s[e],s.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(n=-1,i=r.length-1;i>=0;i--)if(r[i]===t||r[i].listener===t){o=r[i].listener,n=i;break}if(n<0)return this;0===n?r.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(r,n),1===r.length&&(s[e]=r[0]),void 0!==s.removeListener&&this.emit("removeListener",e,o||t)}return this},o.prototype.removeAllListeners=function(e){var t,r,s;if(void 0===(r=this._events))return this;if(void 0===r.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==r[e]&&(0===--this._eventsCount?this._events=Object.create(null):delete r[e]),this;if(0===arguments.length){var n,i=Object.keys(r);for(s=0;s<i.length;++s)"removeListener"!==(n=i[s])&&this.removeAllListeners(n);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(void 0!==t)for(s=t.length-1;s>=0;s--)this.removeListener(e,t[s]);return this},o.prototype.listeners=function(e){return h(this,e,!0)},o.prototype.rawListeners=function(e){return h(this,e,!1)},o.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},o.prototype.listenerCount=m,o.prototype.eventNames=function(){return this._eventsCount>0?e(this._events):[]},r.exports}()),n=[];for(let e=0;e<256;++e)n.push((e+256).toString(16).slice(1));let i;const o=new Uint8Array(16),a={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)},c={AmazonBot:"amazonbot","Amazon Silk":"amazon_silk","Android Browser":"android",BaiduSpider:"baiduspider",Bada:"bada",BingCrawler:"bingcrawler",Brave:"brave",BlackBerry:"blackberry","ChatGPT-User":"chatgpt_user",Chrome:"chrome",ClaudeBot:"claudebot",Chromium:"chromium",Diffbot:"diffbot",DuckDuckBot:"duckduckbot",DuckDuckGo:"duckduckgo",Electron:"electron",Epiphany:"epiphany",FacebookExternalHit:"facebookexternalhit",Firefox:"firefox",Focus:"focus",Generic:"generic","Google Search":"google_search",Googlebot:"googlebot",GPTBot:"gptbot","Internet Explorer":"ie",InternetArchiveCrawler:"internetarchivecrawler","K-Meleon":"k_meleon",LibreWolf:"librewolf",Linespider:"linespider",Maxthon:"maxthon","Meta-ExternalAds":"meta_externalads","Meta-ExternalAgent":"meta_externalagent","Meta-ExternalFetcher":"meta_externalfetcher","Meta-WebIndexer":"meta_webindexer","Microsoft Edge":"edge","MZ Browser":"mz","NAVER Whale Browser":"naver","OAI-SearchBot":"oai_searchbot",Omgilibot:"omgilibot",Opera:"opera","Opera Coast":"opera_coast","Pale Moon":"pale_moon",PerplexityBot:"perplexitybot","Perplexity-User":"perplexity_user",PhantomJS:"phantomjs",PingdomBot:"pingdombot",Puffin:"puffin",QQ:"qq",QQLite:"qqlite",QupZilla:"qupzilla",Roku:"roku",Safari:"safari",Sailfish:"sailfish","Samsung Internet for Android":"samsung_internet",SlackBot:"slackbot",SeaMonkey:"seamonkey",Sleipnir:"sleipnir","Sogou Browser":"sogou",Swing:"swing",Tizen:"tizen","UC Browser":"uc",Vivaldi:"vivaldi","WebOS Browser":"webos",WeChat:"wechat",YahooSlurp:"yahooslurp","Yandex Browser":"yandex",YandexBot:"yandexbot",YouBot:"youbot"},d={amazonbot:"AmazonBot",amazon_silk:"Amazon Silk",android:"Android Browser",baiduspider:"BaiduSpider",bada:"Bada",bingcrawler:"BingCrawler",blackberry:"BlackBerry",brave:"Brave",chatgpt_user:"ChatGPT-User",chrome:"Chrome",claudebot:"ClaudeBot",chromium:"Chromium",diffbot:"Diffbot",duckduckbot:"DuckDuckBot",duckduckgo:"DuckDuckGo",edge:"Microsoft Edge",electron:"Electron",epiphany:"Epiphany",facebookexternalhit:"FacebookExternalHit",firefox:"Firefox",focus:"Focus",generic:"Generic",google_search:"Google Search",googlebot:"Googlebot",gptbot:"GPTBot",ie:"Internet Explorer",internetarchivecrawler:"InternetArchiveCrawler",k_meleon:"K-Meleon",librewolf:"LibreWolf",linespider:"Linespider",maxthon:"Maxthon",meta_externalads:"Meta-ExternalAds",meta_externalagent:"Meta-ExternalAgent",meta_externalfetcher:"Meta-ExternalFetcher",meta_webindexer:"Meta-WebIndexer",mz:"MZ Browser",naver:"NAVER Whale Browser",oai_searchbot:"OAI-SearchBot",omgilibot:"Omgilibot",opera:"Opera",opera_coast:"Opera Coast",pale_moon:"Pale Moon",perplexitybot:"PerplexityBot",perplexity_user:"Perplexity-User",phantomjs:"PhantomJS",pingdombot:"PingdomBot",puffin:"Puffin",qq:"QQ Browser",qqlite:"QQ Browser Lite",qupzilla:"QupZilla",roku:"Roku",safari:"Safari",sailfish:"Sailfish",samsung_internet:"Samsung Internet for Android",seamonkey:"SeaMonkey",slackbot:"SlackBot",sleipnir:"Sleipnir",sogou:"Sogou Browser",swing:"Swing",tizen:"Tizen",uc:"UC Browser",vivaldi:"Vivaldi",webos:"WebOS Browser",wechat:"WeChat",yahooslurp:"YahooSlurp",yandex:"Yandex Browser",yandexbot:"YandexBot",youbot:"YouBot"},l={bot:"bot",desktop:"desktop",mobile:"mobile",tablet:"tablet",tv:"tv"},p={Android:"Android",Bada:"Bada",BlackBerry:"BlackBerry",ChromeOS:"Chrome OS",HarmonyOS:"HarmonyOS",iOS:"iOS",Linux:"Linux",MacOS:"macOS",PlayStation4:"PlayStation 4",Roku:"Roku",Tizen:"Tizen",WebOS:"WebOS",Windows:"Windows",WindowsPhone:"Windows Phone"},u={Blink:"Blink",EdgeHTML:"EdgeHTML",Gecko:"Gecko",Presto:"Presto",Trident:"Trident",WebKit:"WebKit"};class h{static getFirstMatch(e,t){const r=t.match(e);return r&&r.length>0&&r[1]||""}static getSecondMatch(e,t){const r=t.match(e);return r&&r.length>1&&r[2]||""}static matchAndReturnConst(e,t,r){if(e.test(t))return r}static getWindowsVersionName(e){switch(e){case"NT":return"NT";case"XP":case"NT 5.1":return"XP";case"NT 5.0":return"2000";case"NT 5.2":return"2003";case"NT 6.0":return"Vista";case"NT 6.1":return"7";case"NT 6.2":return"8";case"NT 6.3":return"8.1";case"NT 10.0":return"10";default:return}}static getMacOSVersionName(e){const t=e.split(".").splice(0,2).map(e=>parseInt(e,10)||0);t.push(0);const r=t[0];if(10===r)switch(t[1]){case 5:return"Leopard";case 6:return"Snow Leopard";case 7:return"Lion";case 8:return"Mountain Lion";case 9:return"Mavericks";case 10:return"Yosemite";case 11:return"El Capitan";case 12:return"Sierra";case 13:return"High Sierra";case 14:return"Mojave";case 15:return"Catalina";default:return}switch(r){case 11:return"Big Sur";case 12:return"Monterey";case 13:return"Ventura";case 14:return"Sonoma";case 15:return"Sequoia";default:return}}static getAndroidVersionName(e){const t=e.split(".").splice(0,2).map(e=>parseInt(e,10)||0);if(t.push(0),!(1===t[0]&&t[1]<5))return 1===t[0]&&t[1]<6?"Cupcake":1===t[0]&&t[1]>=6?"Donut":2===t[0]&&t[1]<2?"Eclair":2===t[0]&&2===t[1]?"Froyo":2===t[0]&&t[1]>2?"Gingerbread":3===t[0]?"Honeycomb":4===t[0]&&t[1]<1?"Ice Cream Sandwich":4===t[0]&&t[1]<4?"Jelly Bean":4===t[0]&&t[1]>=4?"KitKat":5===t[0]?"Lollipop":6===t[0]?"Marshmallow":7===t[0]?"Nougat":8===t[0]?"Oreo":9===t[0]?"Pie":void 0}static getVersionPrecision(e){return e.split(".").length}static compareVersions(e,t,r=!1){const s=h.getVersionPrecision(e),n=h.getVersionPrecision(t);let i=Math.max(s,n),o=0;const a=h.map([e,t],e=>{const t=i-h.getVersionPrecision(e),r=e+new Array(t+1).join(".0");return h.map(r.split("."),e=>new Array(20-e.length).join("0")+e).reverse()});for(r&&(o=i-Math.min(s,n)),i-=1;i>=o;){if(a[0][i]>a[1][i])return 1;if(a[0][i]===a[1][i]){if(i===o)return 0;i-=1}else if(a[0][i]<a[1][i])return-1}}static map(e,t){const r=[];let s;if(Array.prototype.map)return Array.prototype.map.call(e,t);for(s=0;s<e.length;s+=1)r.push(t(e[s]));return r}static find(e,t){let r,s;if(Array.prototype.find)return Array.prototype.find.call(e,t);for(r=0,s=e.length;r<s;r+=1){const s=e[r];if(t(s,r))return s}}static assign(e,...t){const r=e;let s,n;if(Object.assign)return Object.assign(e,...t);for(s=0,n=t.length;s<n;s+=1){const e=t[s];"object"==typeof e&&null!==e&&Object.keys(e).forEach(t=>{r[t]=e[t]})}return e}static getBrowserAlias(e){return c[e]}static getBrowserTypeByAlias(e){return d[e]||""}}const m=/version\/(\d+(\.?_?\d+)+)/i,g=[{test:[/gptbot/i],describe(e){const t={name:"GPTBot"},r=h.getFirstMatch(/gptbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/chatgpt-user/i],describe(e){const t={name:"ChatGPT-User"},r=h.getFirstMatch(/chatgpt-user\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/oai-searchbot/i],describe(e){const t={name:"OAI-SearchBot"},r=h.getFirstMatch(/oai-searchbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/claudebot/i,/claude-web/i,/claude-user/i,/claude-searchbot/i],describe(e){const t={name:"ClaudeBot"},r=h.getFirstMatch(/(?:claudebot|claude-web|claude-user|claude-searchbot)\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/omgilibot/i,/webzio-extended/i],describe(e){const t={name:"Omgilibot"},r=h.getFirstMatch(/(?:omgilibot|webzio-extended)\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/diffbot/i],describe(e){const t={name:"Diffbot"},r=h.getFirstMatch(/diffbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/perplexitybot/i],describe(e){const t={name:"PerplexityBot"},r=h.getFirstMatch(/perplexitybot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/perplexity-user/i],describe(e){const t={name:"Perplexity-User"},r=h.getFirstMatch(/perplexity-user\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/youbot/i],describe(e){const t={name:"YouBot"},r=h.getFirstMatch(/youbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-webindexer/i],describe(e){const t={name:"Meta-WebIndexer"},r=h.getFirstMatch(/meta-webindexer\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalads/i],describe(e){const t={name:"Meta-ExternalAds"},r=h.getFirstMatch(/meta-externalads\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalagent/i],describe(e){const t={name:"Meta-ExternalAgent"},r=h.getFirstMatch(/meta-externalagent\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalfetcher/i],describe(e){const t={name:"Meta-ExternalFetcher"},r=h.getFirstMatch(/meta-externalfetcher\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/googlebot/i],describe(e){const t={name:"Googlebot"},r=h.getFirstMatch(/googlebot\/(\d+(\.\d+))/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/linespider/i],describe(e){const t={name:"Linespider"},r=h.getFirstMatch(/(?:linespider)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/amazonbot/i],describe(e){const t={name:"AmazonBot"},r=h.getFirstMatch(/amazonbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/bingbot/i],describe(e){const t={name:"BingCrawler"},r=h.getFirstMatch(/bingbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/baiduspider/i],describe(e){const t={name:"BaiduSpider"},r=h.getFirstMatch(/baiduspider\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/duckduckbot/i],describe(e){const t={name:"DuckDuckBot"},r=h.getFirstMatch(/duckduckbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/ia_archiver/i],describe(e){const t={name:"InternetArchiveCrawler"},r=h.getFirstMatch(/ia_archiver\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/facebookexternalhit/i,/facebookcatalog/i],describe:()=>({name:"FacebookExternalHit"})},{test:[/slackbot/i,/slack-imgProxy/i],describe(e){const t={name:"SlackBot"},r=h.getFirstMatch(/(?:slackbot|slack-imgproxy)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/yahoo!?[\s/]*slurp/i],describe:()=>({name:"YahooSlurp"})},{test:[/yandexbot/i,/yandexmobilebot/i],describe:()=>({name:"YandexBot"})},{test:[/pingdom/i],describe:()=>({name:"PingdomBot"})},{test:[/opera/i],describe(e){const t={name:"Opera"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/opr\/|opios/i],describe(e){const t={name:"Opera"},r=h.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/SamsungBrowser/i],describe(e){const t={name:"Samsung Internet for Android"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Whale/i],describe(e){const t={name:"NAVER Whale Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/PaleMoon/i],describe(e){const t={name:"Pale Moon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:PaleMoon)[\s/](\d+(?:\.\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/MZBrowser/i],describe(e){const t={name:"MZ Browser"},r=h.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/focus/i],describe(e){const t={name:"Focus"},r=h.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/swing/i],describe(e){const t={name:"Swing"},r=h.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/coast/i],describe(e){const t={name:"Opera Coast"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/opt\/\d+(?:.?_?\d+)+/i],describe(e){const t={name:"Opera Touch"},r=h.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/yabrowser/i],describe(e){const t={name:"Yandex Browser"},r=h.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/ucbrowser/i],describe(e){const t={name:"UC Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Maxthon|mxios/i],describe(e){const t={name:"Maxthon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/epiphany/i],describe(e){const t={name:"Epiphany"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/puffin/i],describe(e){const t={name:"Puffin"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sleipnir/i],describe(e){const t={name:"Sleipnir"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/k-meleon/i],describe(e){const t={name:"K-Meleon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/micromessenger/i],describe(e){const t={name:"WeChat"},r=h.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/qqbrowser/i],describe(e){const t={name:/qqbrowserlite/i.test(e)?"QQ Browser Lite":"QQ Browser"},r=h.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/msie|trident/i],describe(e){const t={name:"Internet Explorer"},r=h.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/\sedg\//i],describe(e){const t={name:"Microsoft Edge"},r=h.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/edg([ea]|ios)/i],describe(e){const t={name:"Microsoft Edge"},r=h.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/vivaldi/i],describe(e){const t={name:"Vivaldi"},r=h.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/seamonkey/i],describe(e){const t={name:"SeaMonkey"},r=h.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sailfish/i],describe(e){const t={name:"Sailfish"},r=h.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i,e);return r&&(t.version=r),t}},{test:[/silk/i],describe(e){const t={name:"Amazon Silk"},r=h.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/phantom/i],describe(e){const t={name:"PhantomJS"},r=h.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/slimerjs/i],describe(e){const t={name:"SlimerJS"},r=h.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe(e){const t={name:"BlackBerry"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(web|hpw)[o0]s/i],describe(e){const t={name:"WebOS Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/bada/i],describe(e){const t={name:"Bada"},r=h.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/tizen/i],describe(e){const t={name:"Tizen"},r=h.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/qupzilla/i],describe(e){const t={name:"QupZilla"},r=h.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/librewolf/i],describe(e){const t={name:"LibreWolf"},r=h.getFirstMatch(/(?:librewolf)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/firefox|iceweasel|fxios/i],describe(e){const t={name:"Firefox"},r=h.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/electron/i],describe(e){const t={name:"Electron"},r=h.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sogoumobilebrowser/i,/metasr/i,/se 2\.[x]/i],describe(e){const t={name:"Sogou Browser"},r=h.getFirstMatch(/(?:sogoumobilebrowser)[\s/](\d+(\.?_?\d+)+)/i,e),s=h.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i,e),n=h.getFirstMatch(/se ([\d.]+)x/i,e),i=r||s||n;return i&&(t.version=i),t}},{test:[/MiuiBrowser/i],describe(e){const t={name:"Miui"},r=h.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:e=>!!e.hasBrand("DuckDuckGo")||e.test(/\sDdg\/[\d.]+$/i),describe(e,t){const r={name:"DuckDuckGo"};if(t){const e=t.getBrandVersion("DuckDuckGo");if(e)return r.version=e,r}const s=h.getFirstMatch(/\sDdg\/([\d.]+)$/i,e);return s&&(r.version=s),r}},{test:e=>e.hasBrand("Brave"),describe(e,t){const r={name:"Brave"};if(t){const e=t.getBrandVersion("Brave");if(e)return r.version=e,r}return r}},{test:[/chromium/i],describe(e){const t={name:"Chromium"},r=h.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/chrome|crios|crmo/i],describe(e){const t={name:"Chrome"},r=h.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/GSA/i],describe(e){const t={name:"Google Search"},r=h.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test(e){const t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe(e){const t={name:"Android Browser"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/playstation 4/i],describe(e){const t={name:"PlayStation 4"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/safari|applewebkit/i],describe(e){const t={name:"Safari"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/.*/i],describe(e){const t=-1!==e.search("\\(")?/^(.*)\/(.*)[ \t]\((.*)/:/^(.*)\/(.*) /;return{name:h.getFirstMatch(t,e),version:h.getSecondMatch(t,e)}}}],b=[{test:[/Roku\/DVP/],describe(e){const t=h.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i,e);return{name:p.Roku,version:t}}},{test:[/windows phone/i],describe(e){const t=h.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i,e);return{name:p.WindowsPhone,version:t}}},{test:[/windows /i],describe(e){const t=h.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i,e),r=h.getWindowsVersionName(t);return{name:p.Windows,version:t,versionName:r}}},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe(e){const t={name:p.iOS},r=h.getSecondMatch(/(Version\/)(\d[\d.]+)/,e);return r&&(t.version=r),t}},{test:[/macintosh/i],describe(e){const t=h.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i,e).replace(/[_\s]/g,"."),r=h.getMacOSVersionName(t),s={name:p.MacOS,version:t};return r&&(s.versionName=r),s}},{test:[/(ipod|iphone|ipad)/i],describe(e){const t=h.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i,e).replace(/[_\s]/g,".");return{name:p.iOS,version:t}}},{test:[/OpenHarmony/i],describe(e){const t=h.getFirstMatch(/OpenHarmony\s+(\d+(\.\d+)*)/i,e);return{name:p.HarmonyOS,version:t}}},{test(e){const t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe(e){const t=h.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i,e),r=h.getAndroidVersionName(t),s={name:p.Android,version:t};return r&&(s.versionName=r),s}},{test:[/(web|hpw)[o0]s/i],describe(e){const t=h.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i,e),r={name:p.WebOS};return t&&t.length&&(r.version=t),r}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe(e){const t=h.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i,e)||h.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i,e)||h.getFirstMatch(/\bbb(\d+)/i,e);return{name:p.BlackBerry,version:t}}},{test:[/bada/i],describe(e){const t=h.getFirstMatch(/bada\/(\d+(\.\d+)*)/i,e);return{name:p.Bada,version:t}}},{test:[/tizen/i],describe(e){const t=h.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i,e);return{name:p.Tizen,version:t}}},{test:[/linux/i],describe:()=>({name:p.Linux})},{test:[/CrOS/],describe:()=>({name:p.ChromeOS})},{test:[/PlayStation 4/],describe(e){const t=h.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i,e);return{name:p.PlayStation4,version:t}}}],f=[{test:[/googlebot/i],describe:()=>({type:l.bot,vendor:"Google"})},{test:[/linespider/i],describe:()=>({type:l.bot,vendor:"Line"})},{test:[/amazonbot/i],describe:()=>({type:l.bot,vendor:"Amazon"})},{test:[/gptbot/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/chatgpt-user/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/oai-searchbot/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/baiduspider/i],describe:()=>({type:l.bot,vendor:"Baidu"})},{test:[/bingbot/i],describe:()=>({type:l.bot,vendor:"Bing"})},{test:[/duckduckbot/i],describe:()=>({type:l.bot,vendor:"DuckDuckGo"})},{test:[/claudebot/i,/claude-web/i,/claude-user/i,/claude-searchbot/i],describe:()=>({type:l.bot,vendor:"Anthropic"})},{test:[/omgilibot/i,/webzio-extended/i],describe:()=>({type:l.bot,vendor:"Webz.io"})},{test:[/diffbot/i],describe:()=>({type:l.bot,vendor:"Diffbot"})},{test:[/perplexitybot/i],describe:()=>({type:l.bot,vendor:"Perplexity AI"})},{test:[/perplexity-user/i],describe:()=>({type:l.bot,vendor:"Perplexity AI"})},{test:[/youbot/i],describe:()=>({type:l.bot,vendor:"You.com"})},{test:[/ia_archiver/i],describe:()=>({type:l.bot,vendor:"Internet Archive"})},{test:[/meta-webindexer/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalads/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalagent/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalfetcher/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/facebookexternalhit/i,/facebookcatalog/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/slackbot/i,/slack-imgProxy/i],describe:()=>({type:l.bot,vendor:"Slack"})},{test:[/yahoo/i],describe:()=>({type:l.bot,vendor:"Yahoo"})},{test:[/yandexbot/i,/yandexmobilebot/i],describe:()=>({type:l.bot,vendor:"Yandex"})},{test:[/pingdom/i],describe:()=>({type:l.bot,vendor:"Pingdom"})},{test:[/huawei/i],describe(e){const t=h.getFirstMatch(/(can-l01)/i,e)&&"Nova",r={type:l.mobile,vendor:"Huawei"};return t&&(r.model=t),r}},{test:[/nexus\s*(?:7|8|9|10).*/i],describe:()=>({type:l.tablet,vendor:"Nexus"})},{test:[/ipad/i],describe:()=>({type:l.tablet,vendor:"Apple",model:"iPad"})},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe:()=>({type:l.tablet,vendor:"Apple",model:"iPad"})},{test:[/kftt build/i],describe:()=>({type:l.tablet,vendor:"Amazon",model:"Kindle Fire HD 7"})},{test:[/silk/i],describe:()=>({type:l.tablet,vendor:"Amazon"})},{test:[/tablet(?! pc)/i],describe:()=>({type:l.tablet})},{test(e){const t=e.test(/ipod|iphone/i),r=e.test(/like (ipod|iphone)/i);return t&&!r},describe(e){const t=h.getFirstMatch(/(ipod|iphone)/i,e);return{type:l.mobile,vendor:"Apple",model:t}}},{test:[/nexus\s*[0-6].*/i,/galaxy nexus/i],describe:()=>({type:l.mobile,vendor:"Nexus"})},{test:[/Nokia/i],describe(e){const t=h.getFirstMatch(/Nokia\s+([0-9]+(\.[0-9]+)?)/i,e),r={type:l.mobile,vendor:"Nokia"};return t&&(r.model=t),r}},{test:[/[^-]mobi/i],describe:()=>({type:l.mobile})},{test:e=>"blackberry"===e.getBrowserName(!0),describe:()=>({type:l.mobile,vendor:"BlackBerry"})},{test:e=>"bada"===e.getBrowserName(!0),describe:()=>({type:l.mobile})},{test:e=>"windows phone"===e.getBrowserName(),describe:()=>({type:l.mobile,vendor:"Microsoft"})},{test(e){const t=Number(String(e.getOSVersion()).split(".")[0]);return"android"===e.getOSName(!0)&&t>=3},describe:()=>({type:l.tablet})},{test:e=>"android"===e.getOSName(!0),describe:()=>({type:l.mobile})},{test:[/smart-?tv|smarttv/i],describe:()=>({type:l.tv})},{test:[/netcast/i],describe:()=>({type:l.tv})},{test:e=>"macos"===e.getOSName(!0),describe:()=>({type:l.desktop,vendor:"Apple"})},{test:e=>"windows"===e.getOSName(!0),describe:()=>({type:l.desktop})},{test:e=>"linux"===e.getOSName(!0),describe:()=>({type:l.desktop})},{test:e=>"playstation 4"===e.getOSName(!0),describe:()=>({type:l.tv})},{test:e=>"roku"===e.getOSName(!0),describe:()=>({type:l.tv})}],v=[{test:e=>"microsoft edge"===e.getBrowserName(!0),describe(e){if(/\sedg\//i.test(e))return{name:u.Blink};const t=h.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i,e);return{name:u.EdgeHTML,version:t}}},{test:[/trident/i],describe(e){const t={name:u.Trident},r=h.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:e=>e.test(/presto/i),describe(e){const t={name:u.Presto},r=h.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test(e){const t=e.test(/gecko/i),r=e.test(/like gecko/i);return t&&!r},describe(e){const t={name:u.Gecko},r=h.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(apple)?webkit\/537\.36/i],describe:()=>({name:u.Blink})},{test:[/(apple)?webkit/i],describe(e){const t={name:u.WebKit},r=h.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}}];class S{constructor(e,t=!1,r=null){if(null==e||""===e)throw new Error("UserAgent parameter can't be empty");this._ua=e;let s=!1;"boolean"==typeof t?(s=t,this._hints=r):this._hints=null!=t&&"object"==typeof t?t:null,this.parsedResult={},!0!==s&&this.parse()}getHints(){return this._hints}hasBrand(e){if(!this._hints||!Array.isArray(this._hints.brands))return!1;const t=e.toLowerCase();return this._hints.brands.some(e=>e.brand&&e.brand.toLowerCase()===t)}getBrandVersion(e){if(!this._hints||!Array.isArray(this._hints.brands))return;const t=e.toLowerCase(),r=this._hints.brands.find(e=>e.brand&&e.brand.toLowerCase()===t);return r?r.version:void 0}getUA(){return this._ua}test(e){return e.test(this._ua)}parseBrowser(){this.parsedResult.browser={};const e=h.find(g,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.browser=e.describe(this.getUA(),this)),this.parsedResult.browser}getBrowser(){return this.parsedResult.browser?this.parsedResult.browser:this.parseBrowser()}getBrowserName(e){return e?String(this.getBrowser().name).toLowerCase()||"":this.getBrowser().name||""}getBrowserVersion(){return this.getBrowser().version}getOS(){return this.parsedResult.os?this.parsedResult.os:this.parseOS()}parseOS(){this.parsedResult.os={};const e=h.find(b,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.os=e.describe(this.getUA())),this.parsedResult.os}getOSName(e){const{name:t}=this.getOS();return e?String(t).toLowerCase()||"":t||""}getOSVersion(){return this.getOS().version}getPlatform(){return this.parsedResult.platform?this.parsedResult.platform:this.parsePlatform()}getPlatformType(e=!1){const{type:t}=this.getPlatform();return e?String(t).toLowerCase()||"":t||""}parsePlatform(){this.parsedResult.platform={};const e=h.find(f,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.platform=e.describe(this.getUA())),this.parsedResult.platform}getEngine(){return this.parsedResult.engine?this.parsedResult.engine:this.parseEngine()}getEngineName(e){return e?String(this.getEngine().name).toLowerCase()||"":this.getEngine().name||""}parseEngine(){this.parsedResult.engine={};const e=h.find(v,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.engine=e.describe(this.getUA())),this.parsedResult.engine}parse(){return this.parseBrowser(),this.parseOS(),this.parsePlatform(),this.parseEngine(),this}getResult(){return h.assign({},this.parsedResult)}satisfies(e){const t={};let r=0;const s={};let n=0;if(Object.keys(e).forEach(i=>{const o=e[i];"string"==typeof o?(s[i]=o,n+=1):"object"==typeof o&&(t[i]=o,r+=1)}),r>0){const e=Object.keys(t),r=h.find(e,e=>this.isOS(e));if(r){const e=this.satisfies(t[r]);if(void 0!==e)return e}const s=h.find(e,e=>this.isPlatform(e));if(s){const e=this.satisfies(t[s]);if(void 0!==e)return e}}if(n>0){const e=Object.keys(s),t=h.find(e,e=>this.isBrowser(e,!0));if(void 0!==t)return this.compareVersion(s[t])}}isBrowser(e,t=!1){const r=this.getBrowserName().toLowerCase();let s=e.toLowerCase();const n=h.getBrowserTypeByAlias(s);return t&&n&&(s=n.toLowerCase()),s===r}compareVersion(e){let t=[0],r=e,s=!1;const n=this.getBrowserVersion();if("string"==typeof n)return">"===e[0]||"<"===e[0]?(r=e.substr(1),"="===e[1]?(s=!0,r=e.substr(2)):t=[],t.push(">"===e[0]?1:-1)):"="===e[0]?r=e.substr(1):"~"===e[0]&&(s=!0,r=e.substr(1)),t.indexOf(h.compareVersions(n,r,s))>-1}isOS(e){return this.getOSName(!0)===String(e).toLowerCase()}isPlatform(e){return this.getPlatformType(!0)===String(e).toLowerCase()}isEngine(e){return this.getEngineName(!0)===String(e).toLowerCase()}is(e,t=!1){return this.isBrowser(e,t)||this.isOS(e)||this.isPlatform(e)}some(e=[]){return e.some(e=>this.is(e))}}class y{static getParser(e,t=!1,r=null){if("string"!=typeof e)throw new Error("UserAgent should be a string");return new S(e,t,r)}static parse(e,t=null){return new S(e,t).getResult()}static get BROWSER_MAP(){return d}static get ENGINE_MAP(){return u}static get OS_MAP(){return p}static get PLATFORMS_MAP(){return l}}function T(e,t){return Object.keys(t).forEach(function(r){"default"===r||"__esModule"===r||Object.prototype.hasOwnProperty.call(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[r]}})}),e}function _(e,t,r,s){Object.defineProperty(e,t,{get:r,set:s,enumerable:!0,configurable:!0})}function M(e){return e&&e.__esModule?e.default:e}var E={},x={};_(x,"A11ySnapshotStreamer",()=>q);const w=200,k=new WeakMap,R="undefined"==typeof WeakRef?void 0:WeakRef,L=new Map;let I=0;function C(e){const t=k.get(e);if(t)return t;const r="e"+ ++I;return k.set(e,r),L.set(r,R?new R(e):e),r}function B(e){const t=L.get(e);if(!t)return null;const r="deref"in t?t.deref():t;return r&&r.isConnected?r:(L.delete(e),null)}function A(e){return k.get(e)??null}const O=new Set(["script","style","link","meta","noscript","template"]),F=new Set([...new Set(["button","link","checkbox","radio","textbox","combobox","switch","menuitem","tab"]),"heading","img"]);function P(e){return e.replace(/\s+/g," ").trim()}function N(e,t=100){const r=P(e);return r.length<=t?r:r.slice(0,t-1)+"…"}function U(e){const t=[];for(let r=0;r<e.childNodes.length;r++){const s=e.childNodes[r];if(3===s.nodeType){const e=(s.textContent??"").trim();e&&t.push(e)}else if(1===s.nodeType){const e=s;if(O.has(e.tagName.toLowerCase()))continue;if("true"===e.getAttribute("aria-hidden"))continue;const r=U(e);r&&t.push(r)}}return t.join(" ").replace(/\s+/g," ").trim()}function V(e,t){const r=e.getAttribute(t);if(!r)return;const s=parseInt(r,10);return Number.isNaN(s)||s<0?void 0:s}function D(e,t,r,s,n=!1){if(function(e){if(O.has(e.tagName.toLowerCase()))return!0;if("true"===e.getAttribute("aria-hidden"))return!0;if(e.hasAttribute("data-a11y-exclude"))return!0;if(e.hidden)return!0;if(e instanceof HTMLElement&&null===e.offsetParent&&"BODY"!==e.tagName){const t=window.getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility)return!0}return!1}(e))return[];if(r.count>=w)return[];if(t>10)return r.count++,[{ref:C(e),role:"ellipsis",name:"<truncated: max depth>"}];const i=function(e){const t=e.getAttribute("role");if(t)return t;const r=e.tagName.toLowerCase();switch(r){case"main":case"nav":case"header":case"aside":case"footer":return r;case"article":case"section":return function(e){return!!e.hasAttribute("aria-label")||!!e.hasAttribute("aria-labelledby")||(e.textContent??"").trim().length>0}(e)?"region":null;case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return"heading";case"a":return e.hasAttribute("href")?"link":null;case"button":return"button";case"input":{const t=e.type;return"checkbox"===t?"checkbox":"radio"===t?"radio":"submit"===t||"button"===t||"reset"===t?"button":"hidden"===t?null:"textbox"}case"select":return"combobox";case"textarea":return"textbox";case"label":return null;case"img":return null!==e.getAttribute("alt")?"img":null;case"p":return"paragraph";case"ul":case"ol":return"list";case"li":return"listitem";case"table":return"table";case"tr":return"row";case"th":return"columnheader";case"td":return"cell";default:return e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||e.hasAttribute("tabindex")?"generic":null}}(e);if(null===i)return j(e,t,r,s,{skipTextNodes:n});r.count++;const o={ref:C(e),role:i},a=function(e,t){const r=e.getAttribute("aria-label");if(r)return N(r);const s=function(e){const t=e.getAttribute("aria-labelledby");if(!t)return;const r=[];for(const s of t.split(/\s+/)){if(!s)continue;const t=e.ownerDocument.getElementById(s);t&&r.push(U(t))}return r.filter(Boolean).join(" ")||void 0}(e);if(s)return N(s);const n=e.tagName.toLowerCase();if("input"===n||"textarea"===n||"select"===n){const t=e.getAttribute("id");if(t){const r=e.ownerDocument.getElementsByTagName("label");for(let e=0;e<r.length;e++)if(r[e].htmlFor===t&&r[e].textContent)return N(r[e].textContent??"")}const r=e.closest("label");if(r?.textContent)return N(r.textContent);const s=e.getAttribute("placeholder");return s?N(s):void 0}if("img"===n){const t=e.getAttribute("alt");return t?N(t):void 0}if(F.has(t)||"paragraph"===t){const t=U(e);return t?N(t):void 0}}(e,i);a&&(o.name=a);const c=function(e){if(e instanceof HTMLInputElement){if("password"===e.type)return;if("checkbox"===e.type||"radio"===e.type||"hidden"===e.type)return;return e.value||void 0}if(e instanceof HTMLTextAreaElement)return e.value||void 0;if(e instanceof HTMLSelectElement){const t=e.selectedOptions[0],r=t?.text?.trim();return r||e.value||void 0}}(e);void 0!==c&&(o.value=c);const d=function(e){const t=[];return e.ownerDocument.activeElement===e&&t.push("focused"),"true"===e.getAttribute("aria-expanded")&&t.push("expanded"),"true"===e.getAttribute("aria-selected")&&t.push("selected"),(e.hasAttribute("disabled")||"true"===e.getAttribute("aria-disabled"))&&t.push("disabled"),"true"===e.getAttribute("aria-checked")&&t.push("checked"),e instanceof HTMLInputElement&&("checkbox"!==e.type&&"radio"!==e.type||!e.checked||t.includes("checked")||t.push("checked")),t}(e);s.trackViewport&&function(e){const t=e.getBoundingClientRect();if(0===t.width&&0===t.height)return!0;const r=window.innerWidth||document.documentElement.clientWidth,s=window.innerHeight||document.documentElement.clientHeight;return t.bottom<=0||t.top>=s||t.right<=0||t.left>=r}(e)&&d.push("offscreen"),d.length&&(o.state=d);const l=function(e,t){if("heading"!==t)return;const r=e.tagName.toLowerCase().match(/^h([1-6])$/);if(r)return parseInt(r[1],10);const s=e.getAttribute("aria-level");if(s){const e=parseInt(s,10);if(!Number.isNaN(e))return e}}(e,i);void 0!==l&&(o.level=l);const p=V(e,"aria-colcount");void 0!==p&&(o.colcount=p);const u=V(e,"aria-rowcount");if(void 0!==u&&(o.rowcount=u),F.has(i)){if(e instanceof HTMLSelectElement){const t=function(e,t,r){const s=[],n=e.options;let i=0;for(let e=0;e<n.length&&!(t.count>=w);e++){const o=n[e];if(o.hidden)continue;if("true"===o.getAttribute("aria-hidden"))continue;if(i>=20){t.count++,s.push({ref:`${r}.more`,role:"ellipsis",name:n.length-i+" more"});break}t.count++,i++;const a=(o.text||o.value||"").trim(),c={ref:C(o),role:"option",name:N(a)},d=[];o.selected&&d.push("selected"),o.disabled&&d.push("disabled"),d.length&&(c.state=d),s.push(c)}return s}(e,r,o.ref);t.length>0&&(o.children=t)}}else{const n=j(e,t+1,r,s,{skipTextNodes:"paragraph"===i});if(n.length>0)if(n.length>50){const e=n.slice(0,50);e.push({ref:`${o.ref}.more`,role:"ellipsis",name:n.length-50+" more"}),o.children=e}else o.children=n}return[o]}function j(e,t,r,s,n={}){const i=[];for(let o=0;o<e.childNodes.length;o++){const a=e.childNodes[o];if(3===a.nodeType){if(n.skipTextNodes)continue;const e=P(a.textContent??"");if(e){if(r.count>=w)break;r.count++,i.push({ref:"",role:"text",name:N(e)})}}else if(1===a.nodeType){const e=D(a,t,r,s,n.skipTextNodes);for(const t of e)i.push(t);if(r.count>=w)break}}return i}function z(e){return e.length<=2e3?e:e.slice(0,1999)+"…"}function H(){if("undefined"==typeof document)return null;const e=document.activeElement;if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=e.selectionStart,r=e.selectionEnd;if(null!==t&&null!==r&&t!==r){const s=k.get(e);if(!s)return null;const n=e.value.slice(t,r);return n?{ref:s,text:z(n),start_offset:t,end_offset:r}:null}}const t=document.getSelection();if(!t||0===t.rangeCount||t.isCollapsed)return null;const r=t.toString();if(!r)return null;let s=t.getRangeAt(0).commonAncestorContainer;for(;s&&1!==s.nodeType;)s=s.parentNode;const n=function(e){let t=e;for(;t;){if("true"===t.getAttribute("aria-hidden")||t.hasAttribute("data-a11y-exclude"))return null;if(k.has(t))return t;t=t.parentElement}return null}(s);if(!n)return null;const i=k.get(n);return i?{ref:i,text:z(r)}:null}function G(e,t={}){const r=e??("undefined"!=typeof document?document.body:null);if(!r)return{root:{ref:"e0",role:"generic"},captured_at:Date.now()};const s=j(r,0,{count:0},{trackViewport:t.trackViewport??!0}),n=H();return{root:{ref:C(r),role:"generic",...s.length>0?{children:s}:{}},captured_at:Date.now(),...n?{selection:n}:{}}}class q{constructor(e,t={}){this.running=!1,this.emitSnapshot=e,this.debounceMs=t.debounceMs??300,this.trackViewport=t.trackViewport??!0,this.logSnapshots=t.logSnapshots??!1}start(){this.running||"undefined"!=typeof document&&(this.running=!0,this.schedule(),this.observer=new MutationObserver(()=>this.schedule()),this.observer.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["role","aria-label","aria-labelledby","aria-expanded","aria-selected","aria-checked","aria-disabled","aria-level","aria-hidden","aria-colcount","aria-rowcount","data-a11y-exclude","disabled","hidden","tabindex","href"]}),this.focusHandler=()=>this.schedule(),document.addEventListener("focusin",this.focusHandler),document.addEventListener("focusout",this.focusHandler),this.scrollEndHandler=()=>this.schedule(),window.addEventListener("scrollend",this.scrollEndHandler,{capture:!0}),this.resizeHandler=()=>this.schedule(),window.addEventListener("resize",this.resizeHandler),this.visibilityHandler=()=>{"visible"===document.visibilityState&&this.schedule()},document.addEventListener("visibilitychange",this.visibilityHandler),this.selectionHandler=()=>this.schedule(),document.addEventListener("selectionchange",this.selectionHandler),this.formHandler=()=>this.schedule(),document.addEventListener("input",this.formHandler,{capture:!0}),document.addEventListener("change",this.formHandler,{capture:!0}))}stop(){this.running&&(this.running=!1,void 0!==this.timer&&(clearTimeout(this.timer),this.timer=void 0),this.observer&&(this.observer.disconnect(),this.observer=void 0),"undefined"!=typeof document&&(this.focusHandler&&(document.removeEventListener("focusin",this.focusHandler),document.removeEventListener("focusout",this.focusHandler)),this.visibilityHandler&&document.removeEventListener("visibilitychange",this.visibilityHandler),this.selectionHandler&&document.removeEventListener("selectionchange",this.selectionHandler),this.formHandler&&(document.removeEventListener("input",this.formHandler,{capture:!0}),document.removeEventListener("change",this.formHandler,{capture:!0}))),"undefined"!=typeof window&&(this.scrollEndHandler&&window.removeEventListener("scrollend",this.scrollEndHandler,{capture:!0}),this.resizeHandler&&window.removeEventListener("resize",this.resizeHandler)),this.focusHandler=void 0,this.scrollEndHandler=void 0,this.resizeHandler=void 0,this.visibilityHandler=void 0,this.selectionHandler=void 0,this.formHandler=void 0)}schedule(){this.running&&(void 0!==this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>this.emit(),this.debounceMs))}emit(){if(this.timer=void 0,this.running)try{const e=G(void 0,{trackViewport:this.trackViewport});if(this.emitSnapshot(e),this.logSnapshots){const t=W(e.root),r=Math.round(JSON.stringify(e).length/4);console.groupCollapsed(`[A11ySnapshotStreamer] emit: ${t} nodes, ~${r} tokens`),console.groupEnd()}}catch{}}}function W(e){let t=1;const r=e.children;if(r)for(const e of r)t+=W(e);return t}var $,Y={};_(Y,"PipecatClient",()=>Ve),$=JSON.parse('{"name":"@pipecat-ai/client-js","version":"1.12.0","license":"BSD-2-Clause","main":"dist/index.js","module":"dist/index.module.js","types":"dist/index.d.ts","source":"index.ts","repository":{"type":"git","url":"git+https://github.com/pipecat-ai/pipecat-client-web.git"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.module.js","require":"./dist/index.js"}},"files":["dist","package.json","README.md"],"scripts":{"build":"jest --silent --passWithNoTests && parcel build --no-cache","dev":"parcel watch","lint":"eslint . --report-unused-disable-directives --max-warnings 0","test":"jest"},"jest":{"preset":"ts-jest","testEnvironment":"jsdom","setupFilesAfterEnv":["<rootDir>/tests/jest.setup.ts"]},"devDependencies":{"@jest/globals":"^29.7.0","@types/clone-deep":"^4.0.4","@types/jest":"^29.5.12","eslint":"^9.11.1","eslint-config-prettier":"^9.1.0","eslint-plugin-simple-import-sort":"^12.1.1","jest":"^29.7.0","jest-environment-jsdom":"^30.0.2","ts-jest":"^29.2.5","whatwg-fetch":"^3.6.20"},"dependencies":{"@types/events":"^3.0.3","bowser":"^2.11.0","clone-deep":"^4.0.1","events":"^3.3.0","typed-emitter":"^2.1.0","uuid":"^11.1.1"}}');var J={};_(J,"findElementByRef",()=>B),_(J,"findRefForElement",()=>A),_(J,"serializeSelection",()=>H),_(J,"snapshotDocument",()=>G);var K,Q={};_(Q,"TransportStateEnum",()=>exports.TransportStateEnum),exports.TransportStateEnum=void 0,(K=exports.TransportStateEnum||(exports.TransportStateEnum={})).DISCONNECTED="disconnected",K.INITIALIZING="initializing",K.INITIALIZED="initialized",K.AUTHENTICATING="authenticating",K.AUTHENTICATED="authenticated",K.CONNECTING="connecting",K.CONNECTED="connected",K.READY="ready",K.DISCONNECTING="disconnecting",K.ERROR="error";var X={};_(X,"RTVIError",()=>Z),_(X,"ConnectionTimeoutError",()=>ee),_(X,"StartBotError",()=>te),_(X,"TransportStartError",()=>re),_(X,"InvalidTransportParamsError",()=>se),_(X,"BotNotReadyError",()=>ne),_(X,"BotAlreadyStartedError",()=>ie),_(X,"UnsupportedFeatureError",()=>oe),_(X,"MessageTooLargeError",()=>ae),_(X,"DeviceError",()=>ce);class Z extends Error{constructor(e,t){super(e),this.status=t}}class ee extends Z{constructor(e){super(e??"Bot did not enter ready state within the specified timeout period.")}}class te extends Z{constructor(e,t){super(e??"Failed to connect / invalid auth bundle from base url",t??500),this.error="invalid-request-error"}}class re extends Z{constructor(e){super(e??"Unable to connect to transport")}}class se extends Z{constructor(e){super(e??"Invalid transport connection parameters")}}class ne extends Z{constructor(e){super(e??"Attempt to call action on transport when not in 'ready' state.")}}class ie extends Z{constructor(e){super(e??"Pipecat client has already been started. Please call disconnect() before starting again.")}}class oe extends Z{constructor(e,t,r){let s=`${e} not supported${r?`: ${r}`:""}`;t&&(s=`${t} does not support ${e}${r?`: ${r}`:""}`),super(s),this.feature=e}}class ae extends Z{constructor(e){super(e??"Message size exceeds the maximum allowed limit for transport.")}}class ce extends Z{constructor(e,t,r,s){super(r??`Device error for ${e.join(", ")}: ${t}`),this.devices=e,this.type=t,this.details=s}}var de,le={};_(le,"RTVIEvent",()=>exports.RTVIEvent),exports.RTVIEvent=void 0,(de=exports.RTVIEvent||(exports.RTVIEvent={})).Connected="connected",de.Disconnected="disconnected",de.TransportStateChanged="transportStateChanged",de.BotStarted="botStarted",de.BotConnected="botConnected",de.BotReady="botReady",de.BotDisconnected="botDisconnected",de.Error="error",de.ServerMessage="serverMessage",de.ServerResponse="serverResponse",de.MessageError="messageError",de.UICommand="uiCommand",de.UIJobGroup="uiJobGroup",de.Metrics="metrics",de.BotStartedSpeaking="botStartedSpeaking",de.BotStoppedSpeaking="botStoppedSpeaking",de.UserStartedSpeaking="userStartedSpeaking",de.UserStoppedSpeaking="userStoppedSpeaking",de.UserMuteStarted="userMuteStarted",de.UserMuteStopped="userMuteStopped",de.UserTranscript="userTranscript",de.BotOutput="botOutput",de.BotTranscript="botTranscript",de.UserLlmText="userLlmText",de.BotLlmText="botLlmText",de.BotLlmStarted="botLlmStarted",de.BotLlmStopped="botLlmStopped",de.LLMFunctionCall="llmFunctionCall",de.LLMFunctionCallStarted="llmFunctionCallStarted",de.LLMFunctionCallInProgress="llmFunctionCallInProgress",de.LLMFunctionCallStopped="llmFunctionCallStopped",de.BotLlmSearchResponse="botLlmSearchResponse",de.BotTtsText="botTtsText",de.BotTtsStarted="botTtsStarted",de.BotTtsStopped="botTtsStopped",de.ParticipantConnected="participantConnected",de.ParticipantLeft="participantLeft",de.TrackStarted="trackStarted",de.TrackStopped="trackStopped",de.ScreenTrackStarted="screenTrackStarted",de.ScreenTrackStopped="screenTrackStopped",de.ScreenShareError="screenShareError",de.LocalAudioLevel="localAudioLevel",de.RemoteAudioLevel="remoteAudioLevel",de.AvailableCamsUpdated="availableCamsUpdated",de.AvailableMicsUpdated="availableMicsUpdated",de.AvailableSpeakersUpdated="availableSpeakersUpdated",de.CamUpdated="camUpdated",de.MicUpdated="micUpdated",de.SpeakerUpdated="speakerUpdated",de.DeviceError="deviceError",de.MediaStateUpdated="mediaStateUpdated",de.UnsupportedFeature="unsupportedFeature";var pe={};_(pe,"RTVI_PROTOCOL_VERSION",()=>ue),_(pe,"RTVI_MESSAGE_LABEL",()=>he),_(pe,"RTVIMessageType",()=>exports.RTVIMessageType),_(pe,"AggregationType",()=>exports.AggregationType),_(pe,"setAboutClient",()=>fe),_(pe,"RTVIMessage",()=>ve);const ue="2.0.0",he="rtvi-ai";var me,ge;let be;function fe(e){be=be?{...be,...e}:e}exports.RTVIMessageType=void 0,(me=exports.RTVIMessageType||(exports.RTVIMessageType={})).CLIENT_READY="client-ready",me.DISCONNECT_BOT="disconnect-bot",me.CLIENT_MESSAGE="client-message",me.SEND_TEXT="send-text",me.UI_EVENT="ui-event",me.UI_SNAPSHOT="ui-snapshot",me.UI_CANCEL_JOB_GROUP="ui-cancel-job-group",me.APPEND_TO_CONTEXT="append-to-context",me.BOT_READY="bot-ready",me.ERROR="error",me.METRICS="metrics",me.SERVER_MESSAGE="server-message",me.SERVER_RESPONSE="server-response",me.ERROR_RESPONSE="error-response",me.APPEND_TO_CONTEXT_RESULT="append-to-context-result",me.UI_COMMAND="ui-command",me.UI_JOB_GROUP="ui-job-group",me.USER_STARTED_SPEAKING="user-started-speaking",me.USER_STOPPED_SPEAKING="user-stopped-speaking",me.BOT_STARTED_SPEAKING="bot-started-speaking",me.BOT_STOPPED_SPEAKING="bot-stopped-speaking",me.USER_MUTE_STARTED="user-mute-started",me.USER_MUTE_STOPPED="user-mute-stopped",me.USER_TRANSCRIPTION="user-transcription",me.BOT_OUTPUT="bot-output",me.BOT_TRANSCRIPTION="bot-transcription",me.USER_LLM_TEXT="user-llm-text",me.BOT_LLM_TEXT="bot-llm-text",me.BOT_LLM_STARTED="bot-llm-started",me.BOT_LLM_STOPPED="bot-llm-stopped",me.LLM_FUNCTION_CALL="llm-function-call",me.LLM_FUNCTION_CALL_STARTED="llm-function-call-started",me.LLM_FUNCTION_CALL_IN_PROGRESS="llm-function-call-in-progress",me.LLM_FUNCTION_CALL_STOPPED="llm-function-call-stopped",me.LLM_FUNCTION_CALL_RESULT="llm-function-call-result",me.BOT_LLM_SEARCH_RESPONSE="bot-llm-search-response",me.BOT_TTS_TEXT="bot-tts-text",me.BOT_TTS_STARTED="bot-tts-started",me.BOT_TTS_STOPPED="bot-tts-stopped",exports.AggregationType=void 0,(ge=exports.AggregationType||(exports.AggregationType={})).WORD="word",ge.SENTENCE="sentence";class ve{constructor(e,t,r){this.label=he,this.type=e,this.data=t,this.id=r||function(e){if(a.randomUUID&&!e)return a.randomUUID();const t=(e=e||{}).random??e.rng?.()??function(){if(!i){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");i=crypto.getRandomValues.bind(crypto)}return i(o)}();if(t.length<16)throw new Error("Random bytes length must be >= 16");return t[6]=15&t[6]|64,t[8]=63&t[8]|128,function(e,t=0){return(n[e[t+0]]+n[e[t+1]]+n[e[t+2]]+n[e[t+3]]+"-"+n[e[t+4]]+n[e[t+5]]+"-"+n[e[t+6]]+n[e[t+7]]+"-"+n[e[t+8]]+n[e[t+9]]+"-"+n[e[t+10]]+n[e[t+11]]+n[e[t+12]]+n[e[t+13]]+n[e[t+14]]+n[e[t+15]]).toLowerCase()}(t)}().slice(0,8)}static clientReady(){return new ve(exports.RTVIMessageType.CLIENT_READY,{version:ue,about:be||{library:$.name,library_version:$.version}})}static disconnectBot(){return new ve(exports.RTVIMessageType.DISCONNECT_BOT,{})}static error(e,t=!1){return new ve(exports.RTVIMessageType.ERROR,{message:e,fatal:t})}}function Se(e,t,r){const s=r.value;return r.value=function(...e){if("ready"===this.state)return s.apply(this,e);throw new ne(`Attempt to call ${t.toString()} when transport not in ready state. Await connect() first.`)},r}function ye(e,t,r){const s=r.value,n=["authenticating","connecting","connected","ready"];return r.value=function(...e){if(n.includes(this.state))throw new ie(`Attempt to call ${t.toString()} when client already started. Please call disconnect() before starting again.`);return s.apply(this,e)},r}T(J,Q),T(J,X),T(J,le),T(J,pe),T(J,{});var Te={};_(Te,"MessageDispatcher",()=>we);var _e,Me={};_(Me,"LogLevel",()=>exports.LogLevel),_(Me,"logger",()=>xe),exports.LogLevel=void 0,(_e=exports.LogLevel||(exports.LogLevel={}))[_e.NONE=0]="NONE",_e[_e.ERROR=1]="ERROR",_e[_e.WARN=2]="WARN",_e[_e.INFO=3]="INFO",_e[_e.DEBUG=4]="DEBUG";class Ee{constructor(){this.level=exports.LogLevel.DEBUG}static getInstance(){return Ee.instance||(Ee.instance=new Ee),Ee.instance}setLevel(e){this.level=e}debug(...e){exports}info(...e){exports}warn(...e){this.level>=exports.LogLevel.WARN&&console.warn(...e)}error(...e){this.level>=exports.LogLevel.ERROR&&console.error(...e)}}const xe=Ee.getInstance();class we{constructor(e){this._queue=new Array,this._gcInterval=void 0,this._queue=[],this._sendMethod=e}disconnect(){this.clearQueue(),clearInterval(this._gcInterval),this._gcInterval=void 0}dispatch(e,t=exports.RTVIMessageType.CLIENT_MESSAGE,r=1e4){this._gcInterval||(this._gcInterval=setInterval(()=>{this._gc()},2e3));const s=new ve(t,e),n=new Promise((e,t)=>{this._queue.push({message:s,timestamp:Date.now(),timeout:r,resolve:e,reject:t})});xe.debug("[MessageDispatcher] dispatch",s);try{this._sendMethod(s)}catch(e){return xe.error("[MessageDispatcher] Error sending message",e),Promise.reject(e)}return this._gc(),n}clearQueue(){this._queue=[]}_resolveReject(e,t=!0){const r=this._queue.find(t=>t.message.id===e.id);return r&&(t?(xe.debug("[MessageDispatcher] Resolve",e),r.resolve(e)):(xe.debug("[MessageDispatcher] Reject",e),r.reject(e)),this._queue=this._queue.filter(t=>t.message.id!==e.id),xe.debug("[MessageDispatcher] Queue",this._queue)),e}resolve(e){return this._resolveReject(e,!0)}reject(e){return this._resolveReject(e,!1)}_gc(){const e=[];this._queue=this._queue.filter(t=>{const r=Date.now()-t.timestamp<t.timeout;return r||e.push(t),r}),e.forEach(e=>{e.message.type===exports.RTVIMessageType.CLIENT_MESSAGE&&e.reject(new ve(exports.RTVIMessageType.ERROR_RESPONSE,{error:"Timed out waiting for response",msgType:e.message.data.t,data:e.message.data.d,fatal:!1}))}),xe.debug("[MessageDispatcher] GC",this._queue)}}var ke={};function Re(e){if("object"==typeof e&&null!==e&&Object.keys(e).includes("endpoint")){const t=e.endpoint;return"string"==typeof t||t instanceof URL||"undefined"!=typeof Request&&t instanceof Request}return!1}async function Le(e,t){let r;return t||(t=new AbortController),new Promise((s,n)=>{(async()=>{let i;e.timeout&&(r=setTimeout(async()=>{t.abort(),n(new Error("Timed out"))},e.timeout)),"undefined"!=typeof Request&&e.endpoint instanceof Request?(i=new Request(e.endpoint,{signal:t.signal}),e.requestData&&xe.warn("[Pipecat Client] requestData in APIRequest is ignored when endpoint is a Request object"),e.headers&&xe.warn("[Pipecat Client] headers in APIRequest is ignored when endpoint is a Request object")):i=new Request(e.endpoint,{method:"POST",mode:"cors",headers:new Headers({"Content-Type":"application/json",...Object.fromEntries((e.headers??new Headers).entries())}),body:JSON.stringify(e.requestData),signal:t.signal}),xe.debug(`[Pipecat Client] Fetching from ${i.url}`),fetch(i).then(e=>{if(xe.debug(`[Pipecat Client] Received response from ${i.url}`,e),e.ok)return e.json();n(e)}).then(e=>{s(e)}).catch(e=>{xe.error(`[Pipecat Client] Error fetching: ${e}`),n(e)}).finally(()=>{r&&clearTimeout(r)})})()})}_(ke,"isAPIRequest",()=>Re),_(ke,"makeRequest",()=>Le);var Ie={};_(Ie,"Transport",()=>Ce),_(Ie,"TransportWrapper",()=>Be);class Ce{constructor(){this._state="disconnected",this._maxMessageSize=65536}connect(e){this._abortController=new AbortController;let t=e;try{t=this._validateConnectionParams(e)}catch(e){throw new Z(`Invalid connection params: ${e.message}. Please check your connection params and try again.`)}return this._connect(t)}get startBotParams(){return this._startBotParams}set startBotParams(e){this._startBotParams="undefined"!=typeof Request&&e.endpoint instanceof Request?{...e,endpoint:e.endpoint.clone()}:e}disconnect(){return this._abortController&&this._abortController.abort(),this._disconnect()}get maxMessageSize(){return this._maxMessageSize}}class Be{constructor(e){this._transport=e,this._proxy=new Proxy(this._transport,{get:(e,t,r)=>{if("function"==typeof e[t]){let r;switch(String(t)){case"initialize":r="Direct calls to initialize() are disabled and used internally by the PipecatClient.";break;case"initDevices":r="Direct calls to initDevices() are disabled. Please use the PipecatClient.initDevices() wrapper or let PipecatClient.connect() call it for you.";break;case"sendReadyMessage":r="Direct calls to sendReadyMessage() are disabled and used internally by the PipecatClient.";break;case"connect":r="Direct calls to connect() are disabled. Please use the PipecatClient.connect() wrapper.";break;case"disconnect":r="Direct calls to disconnect() are disabled. Please use the PipecatClient.disconnect() wrapper."}return r?()=>{throw new Error(r)}:(...r)=>e[t](...r)}return Reflect.get(e,t,r)}})}get proxy(){return this._proxy}}var Ae={};function Oe(){let e={library:$.name,library_version:$.version,platform_details:{}},t=null;if(window?.navigator?.userAgent)try{t=y.parse(window.navigator.userAgent)}catch(e){}return t?.browser?.name&&(e.platform_details.browser=t.browser.name),"Safari"!==t?.browser?.name||t.browser.version?t?.browser?.version&&(e.platform_details.browser_version=t.browser.version):e.platform_details.browser_version="Web View",t?.platform?.type&&(e.platform_details.platform_type=t.platform.type),t?.engine?.name&&(e.platform_details.engine=t.engine.name),t?.os&&(e.platform=t.os.name,e.platform_version=t.os.version),e}function Fe(e,t){return(e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length})(e)<=t}_(Ae,"learnAboutClient",()=>Oe),_(Ae,"messageSizeWithinLimit",()=>Fe);var Pe=function(e,t,r,s){var n,i=arguments.length,o=i<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,r):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,r,s);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(o=(i<3?n(o):i>3?n(t,r,o):n(t,r))||o);return i>3&&o&&Object.defineProperty(t,r,o),o};function Ne(e){switch(e){case"in-use":return"already-in-use";case"permissions":return"blocked";case"not-found":return"not-found";case"undefined-mediadevices":return"not-supported";case"constraints":return"invalid-constraints";default:return"unknown"}}class Ue extends s{}class Ve extends Ue{constructor(e){super(),this._functionCallCallbacks={},this._botTranscriptionWarned=!1,this._llmFunctionCallWarned=!1,this._mediaState={mic:{state:"uninitialized"},cam:{state:"uninitialized"}},fe(Oe()),this._transport=e.transport,this._transportWrapper=new Be(this._transport),this._disconnectOnBotDisconnect=e.disconnectOnBotDisconnect??!0;const t={...e.callbacks,onMessageError:t=>{e?.callbacks?.onMessageError?.(t),this.emit(exports.RTVIEvent.MessageError,t)},onError:t=>{e?.callbacks?.onError?.(t);try{this.emit(exports.RTVIEvent.Error,t)}catch(r){r instanceof Error&&r.message.includes("Unhandled error")?e?.callbacks?.onError||xe.debug("No onError callback registered to handle error",t):xe.debug("Could not emit error",t,r)}const r=t.data;r?.fatal&&(xe.error("Fatal error reported. Disconnecting..."),this.disconnect())},onConnected:()=>{e?.callbacks?.onConnected?.(),this.emit(exports.RTVIEvent.Connected)},onDisconnected:()=>{e?.callbacks?.onDisconnected?.(),this.emit(exports.RTVIEvent.Disconnected)},onTransportStateChanged:t=>{e?.callbacks?.onTransportStateChanged?.(t),this.emit(exports.RTVIEvent.TransportStateChanged,t),"ready"===t&&this._flushPendingUISnapshot()},onParticipantJoined:t=>{e?.callbacks?.onParticipantJoined?.(t),this.emit(exports.RTVIEvent.ParticipantConnected,t)},onParticipantLeft:t=>{e?.callbacks?.onParticipantLeft?.(t),this.emit(exports.RTVIEvent.ParticipantLeft,t)},onTrackStarted:(t,r)=>{e?.callbacks?.onTrackStarted?.(t,r),this.emit(exports.RTVIEvent.TrackStarted,t,r)},onTrackStopped:(t,r)=>{e?.callbacks?.onTrackStopped?.(t,r),this.emit(exports.RTVIEvent.TrackStopped,t,r)},onScreenTrackStarted:(t,r)=>{e?.callbacks?.onScreenTrackStarted?.(t,r),this.emit(exports.RTVIEvent.ScreenTrackStarted,t,r)},onScreenTrackStopped:(t,r)=>{e?.callbacks?.onScreenTrackStopped?.(t,r),this.emit(exports.RTVIEvent.ScreenTrackStopped,t,r)},onScreenShareError:t=>{e?.callbacks?.onScreenShareError?.(t),this.emit(exports.RTVIEvent.ScreenShareError,t)},onUnsupportedFeature:t=>{e?.callbacks?.onUnsupportedFeature?.(t),this.emit(exports.RTVIEvent.UnsupportedFeature,t)},onAvailableCamsUpdated:t=>{e?.callbacks?.onAvailableCamsUpdated?.(t),this.emit(exports.RTVIEvent.AvailableCamsUpdated,t)},onAvailableMicsUpdated:t=>{e?.callbacks?.onAvailableMicsUpdated?.(t),this.emit(exports.RTVIEvent.AvailableMicsUpdated,t)},onAvailableSpeakersUpdated:t=>{e?.callbacks?.onAvailableSpeakersUpdated?.(t),this.emit(exports.RTVIEvent.AvailableSpeakersUpdated,t)},onCamUpdated:t=>{t?.deviceId&&this._markDeviceGranted("cam"),e?.callbacks?.onCamUpdated?.(t),this.emit(exports.RTVIEvent.CamUpdated,t)},onMicUpdated:t=>{t?.deviceId&&this._markDeviceGranted("mic"),e?.callbacks?.onMicUpdated?.(t),this.emit(exports.RTVIEvent.MicUpdated,t)},onSpeakerUpdated:t=>{e?.callbacks?.onSpeakerUpdated?.(t),this.emit(exports.RTVIEvent.SpeakerUpdated,t)},onDeviceError:t=>{this._classifyAndApplyDeviceError(t),e?.callbacks?.onDeviceError?.(t),this.emit(exports.RTVIEvent.DeviceError,t)},onBotStarted:t=>{e?.callbacks?.onBotStarted?.(t),this.emit(exports.RTVIEvent.BotStarted,t)},onBotConnected:t=>{e?.callbacks?.onBotConnected?.(t),this.emit(exports.RTVIEvent.BotConnected,t)},onBotReady:t=>{e?.callbacks?.onBotReady?.(t),this.emit(exports.RTVIEvent.BotReady,t)},onBotDisconnected:t=>{e?.callbacks?.onBotDisconnected?.(t),this.emit(exports.RTVIEvent.BotDisconnected,t),this._disconnectOnBotDisconnect&&(xe.info("Bot disconnected. Disconnecting client..."),this.disconnect())},onUserStartedSpeaking:()=>{e?.callbacks?.onUserStartedSpeaking?.(),this.emit(exports.RTVIEvent.UserStartedSpeaking)},onUserStoppedSpeaking:()=>{e?.callbacks?.onUserStoppedSpeaking?.(),this.emit(exports.RTVIEvent.UserStoppedSpeaking)},onBotStartedSpeaking:()=>{e?.callbacks?.onBotStartedSpeaking?.(),this.emit(exports.RTVIEvent.BotStartedSpeaking)},onBotStoppedSpeaking:()=>{e?.callbacks?.onBotStoppedSpeaking?.(),this.emit(exports.RTVIEvent.BotStoppedSpeaking)},onRemoteAudioLevel:(t,r)=>{e?.callbacks?.onRemoteAudioLevel?.(t,r),this.emit(exports.RTVIEvent.RemoteAudioLevel,t,r)},onLocalAudioLevel:t=>{e?.callbacks?.onLocalAudioLevel?.(t),this.emit(exports.RTVIEvent.LocalAudioLevel,t)},onUserMuteStarted:()=>{e?.callbacks?.onUserMuteStarted?.(),this.emit(exports.RTVIEvent.UserMuteStarted)},onUserMuteStopped:()=>{e?.callbacks?.onUserMuteStopped?.(),this.emit(exports.RTVIEvent.UserMuteStopped)},onUserTranscript:t=>{e?.callbacks?.onUserTranscript?.(t),this.emit(exports.RTVIEvent.UserTranscript,t)},onBotOutput:t=>{e?.callbacks?.onBotOutput?.(t),this.emit(exports.RTVIEvent.BotOutput,t)},onBotTranscript:t=>{(!!e?.callbacks?.onBotTranscript||this.listenerCount(exports.RTVIEvent.BotTranscript)>0)&&!this._botTranscriptionWarned&&(xe.warn("[Pipecat Client] Bot transcription is deprecated. Please use the onBotOutput instead."),this._botTranscriptionWarned=!0),e?.callbacks?.onBotTranscript?.(t),this.emit(exports.RTVIEvent.BotTranscript,t)},onBotLlmText:t=>{e?.callbacks?.onBotLlmText?.(t),this.emit(exports.RTVIEvent.BotLlmText,t)},onBotLlmStarted:()=>{e?.callbacks?.onBotLlmStarted?.(),this.emit(exports.RTVIEvent.BotLlmStarted)},onBotLlmStopped:()=>{e?.callbacks?.onBotLlmStopped?.(),this.emit(exports.RTVIEvent.BotLlmStopped)},onBotTtsText:t=>{e?.callbacks?.onBotTtsText?.(t),this.emit(exports.RTVIEvent.BotTtsText,t)},onBotTtsStarted:()=>{e?.callbacks?.onBotTtsStarted?.(),this.emit(exports.RTVIEvent.BotTtsStarted)},onBotTtsStopped:()=>{e?.callbacks?.onBotTtsStopped?.(),this.emit(exports.RTVIEvent.BotTtsStopped)}};this._options={...e,callbacks:t,enableMic:e.enableMic??!0,enableCam:e.enableCam??!1,enableScreenShare:e.enableScreenShare??!1},this._initialize(),xe.debug("[Pipecat Client] Initialized",this.version)}setLogLevel(e){xe.setLevel(e)}async initDevices(){xe.debug("[Pipecat Client] Initializing devices..."),this._setMediaState({mic:{state:"initializing"},cam:{state:"initializing"}});try{await this._transport.initDevices(),this._resolveLingeringInitializing({state:"uninitialized"})}catch(e){throw this._resolveLingeringInitializing({state:"error",reason:"unknown"}),e}finally{await this._enrichFromPermissionsAPI()}}_resolveLingeringInitializing(e){const t={};for(const r of["mic","cam"])"initializing"===this._mediaState[r].state&&(t[r]=e);Object.keys(t).length>0&&this._setMediaState(t)}_markDeviceGranted(e){"granted"!==this._mediaState[e].state&&this._setMediaState({[e]:{state:"granted"}})}async startBot(e){let t;this.needsInit()&&await this.initDevices(),this._transport.state="authenticating",this._transport.startBotParams=e,this._abortController=new AbortController;try{t=await Le(e,this._abortController)}catch(e){let t,r="An unknown error occurred while starting the bot.";if(e instanceof Response){const s=await e.json();r=s.info??s.detail??e.statusText,t=e.status}else e instanceof Error&&(r=e.message);throw this._options.callbacks?.onError?.(new ve(exports.RTVIMessageType.ERROR_RESPONSE,{message:r,fatal:!0})),new te(r,t)}return this._transport.state="authenticated",this._options.callbacks?.onBotStarted?.(t),t}async connect(e){return e&&Re(e)?(xe.warn("Calling connect with an API endpoint is deprecated. Use startBotAndConnect() instead."),this.startBotAndConnect(e)):new Promise((t,r)=>{(async()=>{this._connectResolve=t,this.needsInit()&&await this.initDevices();try{await this._transport.connect(e),await this._transport.sendReadyMessage()}catch(e){return this.disconnect(),void r(e)}})()})}async startBotAndConnect(e){const t=await this.startBot(e);return this.connect(t)}async disconnect(){this.stopUISnapshotStream(),await this._transport.disconnect(),this._messageDispatcher.disconnect()}_initialize(){this._transport.initialize(this._options,this.handleMessage.bind(this)),this._messageDispatcher=new we(this._sendMessage.bind(this))}_setMediaState(e){const t={...this._mediaState,...e};this._statusEquals(t.mic,this._mediaState.mic)&&this._statusEquals(t.cam,this._mediaState.cam)||(this._mediaState=t,this._options.callbacks?.onMediaStateChanged?.(this.mediaState),this.emit(exports.RTVIEvent.MediaStateUpdated,this.mediaState))}_statusEquals(e,t){return e.state===t.state&&("error"!==e.state||"error"!==t.state||e.reason===t.reason&&e.details===t.details)}_classifyAndApplyDeviceError(e){const t={state:"error",reason:Ne(e.type),details:e.details},r={};e.devices.includes("mic")&&(r.mic=t),e.devices.includes("cam")&&(r.cam=t),0!==Object.keys(r).length&&this._setMediaState(r)}async _enrichFromPermissionsAPI(){const e=globalThis.navigator?.permissions;if(!e?.query)return;const t=e.query.bind(e),r={};await Promise.all(["mic","cam"].map(async e=>{try{"denied"===(await t({name:"mic"===e?"microphone":"camera"})).state&&(r[e]={state:"error",reason:"blocked"})}catch{}})),Object.keys(r).length>0&&this._setMediaState(r)}_sendMessage(e){if(!Fe(e,this._transport.maxMessageSize)){const e=`Message data too large. Max size is ${this._transport.maxMessageSize}`;throw this._options.callbacks?.onError?.(ve.error(e,!1)),new ae(e)}try{this._transport.sendMessage(e)}catch(e){throw e instanceof Error?this._options.callbacks?.onError?.(ve.error(e.message,!1)):this._options.callbacks?.onError?.(ve.error("Unknown error sending message",!1)),e}}get connected(){return["connected","ready"].includes(this._transport.state)}get transport(){return this._transportWrapper.proxy}get state(){return this._transport.state}get mediaState(){return{mic:{...this._mediaState.mic},cam:{...this._mediaState.cam}}}needsInit(){return!1!==this._options.enableMic&&"uninitialized"===this._mediaState.mic.state||!1!==this._options.enableCam&&"uninitialized"===this._mediaState.cam.state}get version(){return M($).version}async getAllMics(){return await this._transport.getAllMics()}async getAllCams(){return await this._transport.getAllCams()}async getAllSpeakers(){return await this._transport.getAllSpeakers()}get selectedMic(){return this._transport.selectedMic}get selectedCam(){try{return this._transport.selectedCam}catch(e){if(e instanceof oe)return this._options.callbacks?.onUnsupportedFeature?.(e),{};throw e}}get selectedSpeaker(){return this._transport.selectedSpeaker}updateMic(e){this._transport.updateMic(e)}updateCam(e){this._transport.updateCam(e)}updateSpeaker(e){this._transport.updateSpeaker(e)}enableMic(e){this._transport.enableMic(e)}get isMicEnabled(){return this._transport.isMicEnabled}enableCam(e){try{this._transport.enableCam(e)}catch(e){if(!(e instanceof oe))throw e;this._options.callbacks?.onUnsupportedFeature?.(e)}}get isCamEnabled(){return this._transport.isCamEnabled}tracks(){return this._transport.tracks()}enableScreenShare(e){try{return this._transport.enableScreenShare(e)}catch(e){if(!(e instanceof oe))throw e;this._options.callbacks?.onUnsupportedFeature?.(e)}}get isSharingScreen(){return this._transport.isSharingScreen}sendClientMessage(e,t){this._sendMessage(new ve(exports.RTVIMessageType.CLIENT_MESSAGE,{t:e,d:t}))}sendUIEvent(e,t){this._sendMessage(new ve(exports.RTVIMessageType.UI_EVENT,{event:e,payload:t}))}startUISnapshotStream(e={}){this.stopUISnapshotStream(),this._uiSnapshotStreamer=new q(e=>{"ready"===this.state?this._sendUISnapshot(e):this._pendingUISnapshot=e},e),this._uiSnapshotStreamer.start()}stopUISnapshotStream(){this._uiSnapshotStreamer?.stop(),this._uiSnapshotStreamer=void 0,this._pendingUISnapshot=void 0}_sendUISnapshot(e){this._sendMessage(new ve(exports.RTVIMessageType.UI_SNAPSHOT,{tree:e}))}_flushPendingUISnapshot(){if(!this._pendingUISnapshot||"ready"!==this.state)return;const e=this._pendingUISnapshot;this._pendingUISnapshot=void 0,this._sendUISnapshot(e)}cancelUIJobGroup(e,t){const r={job_id:e};void 0!==t&&(r.reason=t),this._sendMessage(new ve(exports.RTVIMessageType.UI_CANCEL_JOB_GROUP,r))}async sendClientRequest(e,t,r){const s={t:e,d:t};return(await this._messageDispatcher.dispatch(s,exports.RTVIMessageType.CLIENT_MESSAGE,r)).data.d}registerFunctionCallHandler(e,t){this._functionCallCallbacks[e]=t}unregisterFunctionCallHandler(e){delete this._functionCallCallbacks[e]}unregisterAllFunctionCallHandlers(){this._functionCallCallbacks={}}async appendToContext(e){return xe.warn("appendToContext() is deprecated. Use sendText() instead."),await this._sendMessage(new ve(exports.RTVIMessageType.APPEND_TO_CONTEXT,{role:e.role,content:e.content,run_immediately:e.run_immediately})),!0}async sendText(e,t={}){await this._sendMessage(new ve(exports.RTVIMessageType.SEND_TEXT,{content:e,options:t}))}disconnectBot(){this._sendMessage(new ve(exports.RTVIMessageType.DISCONNECT_BOT,{}))}handleMessage(e){switch(xe.debug("[RTVI Message]",e),e.type){case exports.RTVIMessageType.BOT_READY:{const t=e.data,r=t.version?t.version.split(".").map(Number):[0,0,0];xe.debug(`[Pipecat Client] Bot is ready. Version: ${t.version}`),r[0]<2&&xe.warn(`[Pipecat Client] Bot protocol version ${t.version} is older than this client (${ue}). Compatibility issues may occur.`),this._connectResolve?.(e.data),this._options.callbacks?.onBotReady?.(e.data);break}case exports.RTVIMessageType.ERROR:this._options.callbacks?.onError?.(e);break;case exports.RTVIMessageType.SERVER_RESPONSE:this._messageDispatcher.resolve(e);break;case exports.RTVIMessageType.ERROR_RESPONSE:{const t=this._messageDispatcher.reject(e);this._options.callbacks?.onMessageError?.(t);break}case exports.RTVIMessageType.USER_STARTED_SPEAKING:this._options.callbacks?.onUserStartedSpeaking?.();break;case exports.RTVIMessageType.USER_STOPPED_SPEAKING:this._options.callbacks?.onUserStoppedSpeaking?.();break;case exports.RTVIMessageType.BOT_STARTED_SPEAKING:this._options.callbacks?.onBotStartedSpeaking?.();break;case exports.RTVIMessageType.BOT_STOPPED_SPEAKING:this._options.callbacks?.onBotStoppedSpeaking?.();break;case exports.RTVIMessageType.USER_MUTE_STARTED:this._options.callbacks?.onUserMuteStarted?.();break;case exports.RTVIMessageType.USER_MUTE_STOPPED:this._options.callbacks?.onUserMuteStopped?.();break;case exports.RTVIMessageType.USER_TRANSCRIPTION:{const t=e.data;this._options.callbacks?.onUserTranscript?.(t);break}case exports.RTVIMessageType.USER_LLM_TEXT:{const t=e.data;this._options.callbacks?.onUserLlmText?.(t),this.emit(exports.RTVIEvent.UserLlmText,t);break}case exports.RTVIMessageType.BOT_OUTPUT:this._options.callbacks?.onBotOutput?.(e.data);break;case exports.RTVIMessageType.BOT_TRANSCRIPTION:this._options.callbacks?.onBotTranscript?.(e.data);break;case exports.RTVIMessageType.BOT_LLM_TEXT:this._options.callbacks?.onBotLlmText?.(e.data);break;case exports.RTVIMessageType.BOT_LLM_STARTED:this._options.callbacks?.onBotLlmStarted?.();break;case exports.RTVIMessageType.BOT_LLM_STOPPED:this._options.callbacks?.onBotLlmStopped?.();break;case exports.RTVIMessageType.BOT_TTS_TEXT:this._options.callbacks?.onBotTtsText?.(e.data);break;case exports.RTVIMessageType.BOT_TTS_STARTED:this._options.callbacks?.onBotTtsStarted?.();break;case exports.RTVIMessageType.BOT_TTS_STOPPED:this._options.callbacks?.onBotTtsStopped?.();break;case exports.RTVIMessageType.METRICS:this._options.callbacks?.onMetrics?.(e.data),this.emit(exports.RTVIEvent.Metrics,e.data);break;case exports.RTVIMessageType.SERVER_MESSAGE:this._options.callbacks?.onServerMessage?.(e.data),this.emit(exports.RTVIEvent.ServerMessage,e.data);break;case exports.RTVIMessageType.UI_COMMAND:{const t=e.data;this._options.callbacks?.onUICommand?.(t),this.emit(exports.RTVIEvent.UICommand,t);break}case exports.RTVIMessageType.UI_JOB_GROUP:{const t=e.data;this._options.callbacks?.onUIJobGroup?.(t),this.emit(exports.RTVIEvent.UIJobGroup,t);break}case exports.RTVIMessageType.LLM_FUNCTION_CALL_STARTED:{const t=e.data;this._options.callbacks?.onLLMFunctionCallStarted?.(t),this.emit(exports.RTVIEvent.LLMFunctionCallStarted,t);break}case exports.RTVIMessageType.LLM_FUNCTION_CALL_IN_PROGRESS:{const t=e.data;this._maybeTriggerFunctionCallCallback(t),this._options.callbacks?.onLLMFunctionCallInProgress?.(t),this.emit(exports.RTVIEvent.LLMFunctionCallInProgress,t);break}case exports.RTVIMessageType.LLM_FUNCTION_CALL_STOPPED:{const t=e.data;this._options.callbacks?.onLLMFunctionCallStopped?.(t),this.emit(exports.RTVIEvent.LLMFunctionCallStopped,t);break}case exports.RTVIMessageType.LLM_FUNCTION_CALL:{const t=e.data;this._maybeTriggerFunctionCallCallback({function_name:t.function_name,tool_call_id:t.tool_call_id,arguments:t.args}),this._options.callbacks?.onLLMFunctionCall&&(this._llmFunctionCallWarned||(xe.warn("[Pipecat Client] onLLMFunctionCall is deprecated. Please use onLLMFunctionCallInProgress instead."),this._llmFunctionCallWarned=!0)),this._options.callbacks?.onLLMFunctionCall?.(t),this.emit(exports.RTVIEvent.LLMFunctionCall,t);break}case exports.RTVIMessageType.BOT_LLM_SEARCH_RESPONSE:{const t=e.data;this._options.callbacks?.onBotLlmSearchResponse?.(t),this.emit(exports.RTVIEvent.BotLlmSearchResponse,t);break}default:xe.debug("[Pipecat Client] Unrecognized message type",e.type)}}_maybeTriggerFunctionCallCallback(e){if(!e.function_name)return;const t=this._functionCallCallbacks[e.function_name];t&&t({functionName:e.function_name??"",arguments:e.arguments??{}}).then(t=>{null!=t&&this._sendMessage(new ve(exports.RTVIMessageType.LLM_FUNCTION_CALL_RESULT,{function_name:e.function_name,tool_call_id:e.tool_call_id,arguments:e.arguments??{},result:t}))}).catch(e=>{xe.error("Error in function call callback",e)})}}Pe([ye],Ve.prototype,"startBot",null),Pe([ye],Ve.prototype,"connect",null),Pe([ye],Ve.prototype,"startBotAndConnect",null),Pe([Se],Ve.prototype,"sendClientMessage",null),Pe([Se],Ve.prototype,"sendUIEvent",null),Pe([Se],Ve.prototype,"cancelUIJobGroup",null),Pe([Se],Ve.prototype,"sendClientRequest",null),Pe([Se],Ve.prototype,"appendToContext",null),Pe([Se],Ve.prototype,"sendText",null),Pe([Se],Ve.prototype,"disconnectBot",null),T(E,x),T(E,Y),T(E,Te),T(E,Me),T(E,ke),T(E,Ie),T(E,Ae),exports.A11ySnapshotStreamer=q,exports.BotAlreadyStartedError=ie,exports.BotNotReadyError=ne,exports.ConnectionTimeoutError=ee,exports.DeviceError=ce,exports.InvalidTransportParamsError=se,exports.MessageDispatcher=we,exports.MessageTooLargeError=ae,exports.PipecatClient=Ve,exports.RTVIError=Z,exports.RTVIMessage=ve,exports.RTVI_MESSAGE_LABEL=he,exports.RTVI_PROTOCOL_VERSION=ue,exports.StartBotError=te,exports.Transport=Ce,exports.TransportStartError=re,exports.TransportWrapper=Be,exports.UnsupportedFeatureError=oe,exports.findElementByRef=B,exports.findRefForElement=A,exports.isAPIRequest=Re,exports.learnAboutClient=Oe,exports.logger=xe,exports.makeRequest=Le,exports.messageSizeWithinLimit=Fe,exports.serializeSelection=H,exports.setAboutClient=fe,exports.snapshotDocument=G;
@@ -0,0 +1 @@
1
+ function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t,r={exports:{}};const s=e(function(){if(t)return r.exports;t=1;var e,s="object"==typeof Reflect?Reflect:null,n=s&&"function"==typeof s.apply?s.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};e=s&&"function"==typeof s.ownKeys?s.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var i=Number.isNaN||function(e){return e!=e};function o(){o.init.call(this)}r.exports=o,r.exports.once=function(e,t){return new Promise(function(r,s){function n(r){e.removeListener(t,i),s(r)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",n),r([].slice.call(arguments))}g(e,t,i,{once:!0}),"error"!==t&&function(e,t){"function"==typeof e.on&&g(e,"error",t,{once:!0})}(e,n)})},o.EventEmitter=o,o.prototype._events=void 0,o.prototype._eventsCount=0,o.prototype._maxListeners=void 0;var a=10;function c(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function d(e){return void 0===e._maxListeners?o.defaultMaxListeners:e._maxListeners}function l(e,t,r,s){var n,i,o;if(c(r),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),i=e._events),o=i[t]),void 0===o)o=i[t]=r,++e._eventsCount;else if("function"==typeof o?o=i[t]=s?[r,o]:[o,r]:s?o.unshift(r):o.push(r),(n=d(e))>0&&o.length>n&&!o.warned){o.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=o.length,console&&console.warn&&console.warn(a)}return e}function u(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,r){var s={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},n=u.bind(s);return n.listener=r,s.wrapFn=n,n}function h(e,t,r){var s=e._events;if(void 0===s)return[];var n=s[t];return void 0===n?[]:"function"==typeof n?r?[n.listener||n]:[n]:r?function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(n):b(n,n.length)}function m(e){var t=this._events;if(void 0!==t){var r=t[e];if("function"==typeof r)return 1;if(void 0!==r)return r.length}return 0}function b(e,t){for(var r=new Array(t),s=0;s<t;++s)r[s]=e[s];return r}function g(e,t,r,s){if("function"==typeof e.on)s.once?e.once(t,r):e.on(t,r);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,function n(i){s.once&&e.removeEventListener(t,n),r(i)})}}return Object.defineProperty(o,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||i(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");a=e}}),o.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},o.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||i(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},o.prototype.getMaxListeners=function(){return d(this)},o.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t.push(arguments[r]);var s="error"===e,i=this._events;if(void 0!==i)s=s&&void 0===i.error;else if(!s)return!1;if(s){var o;if(t.length>0&&(o=t[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)n(c,this,t);else{var d=c.length,l=b(c,d);for(r=0;r<d;++r)n(l[r],this,t)}return!0},o.prototype.on=o.prototype.addListener=function(e,t){return l(this,e,t,!1)},o.prototype.prependListener=function(e,t){return l(this,e,t,!0)},o.prototype.once=function(e,t){return c(t),this.on(e,p(this,e,t)),this},o.prototype.prependOnceListener=function(e,t){return c(t),this.prependListener(e,p(this,e,t)),this},o.prototype.off=o.prototype.removeListener=function(e,t){var r,s,n,i,o;if(c(t),void 0===(s=this._events))return this;if(void 0===(r=s[e]))return this;if(r===t||r.listener===t)0===--this._eventsCount?this._events=Object.create(null):(delete s[e],s.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(n=-1,i=r.length-1;i>=0;i--)if(r[i]===t||r[i].listener===t){o=r[i].listener,n=i;break}if(n<0)return this;0===n?r.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(r,n),1===r.length&&(s[e]=r[0]),void 0!==s.removeListener&&this.emit("removeListener",e,o||t)}return this},o.prototype.removeAllListeners=function(e){var t,r,s;if(void 0===(r=this._events))return this;if(void 0===r.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==r[e]&&(0===--this._eventsCount?this._events=Object.create(null):delete r[e]),this;if(0===arguments.length){var n,i=Object.keys(r);for(s=0;s<i.length;++s)"removeListener"!==(n=i[s])&&this.removeAllListeners(n);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(void 0!==t)for(s=t.length-1;s>=0;s--)this.removeListener(e,t[s]);return this},o.prototype.listeners=function(e){return h(this,e,!0)},o.prototype.rawListeners=function(e){return h(this,e,!1)},o.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},o.prototype.listenerCount=m,o.prototype.eventNames=function(){return this._eventsCount>0?e(this._events):[]},r.exports}()),n=[];for(let e=0;e<256;++e)n.push((e+256).toString(16).slice(1));let i;const o=new Uint8Array(16),a={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)},c={AmazonBot:"amazonbot","Amazon Silk":"amazon_silk","Android Browser":"android",BaiduSpider:"baiduspider",Bada:"bada",BingCrawler:"bingcrawler",Brave:"brave",BlackBerry:"blackberry","ChatGPT-User":"chatgpt_user",Chrome:"chrome",ClaudeBot:"claudebot",Chromium:"chromium",Diffbot:"diffbot",DuckDuckBot:"duckduckbot",DuckDuckGo:"duckduckgo",Electron:"electron",Epiphany:"epiphany",FacebookExternalHit:"facebookexternalhit",Firefox:"firefox",Focus:"focus",Generic:"generic","Google Search":"google_search",Googlebot:"googlebot",GPTBot:"gptbot","Internet Explorer":"ie",InternetArchiveCrawler:"internetarchivecrawler","K-Meleon":"k_meleon",LibreWolf:"librewolf",Linespider:"linespider",Maxthon:"maxthon","Meta-ExternalAds":"meta_externalads","Meta-ExternalAgent":"meta_externalagent","Meta-ExternalFetcher":"meta_externalfetcher","Meta-WebIndexer":"meta_webindexer","Microsoft Edge":"edge","MZ Browser":"mz","NAVER Whale Browser":"naver","OAI-SearchBot":"oai_searchbot",Omgilibot:"omgilibot",Opera:"opera","Opera Coast":"opera_coast","Pale Moon":"pale_moon",PerplexityBot:"perplexitybot","Perplexity-User":"perplexity_user",PhantomJS:"phantomjs",PingdomBot:"pingdombot",Puffin:"puffin",QQ:"qq",QQLite:"qqlite",QupZilla:"qupzilla",Roku:"roku",Safari:"safari",Sailfish:"sailfish","Samsung Internet for Android":"samsung_internet",SlackBot:"slackbot",SeaMonkey:"seamonkey",Sleipnir:"sleipnir","Sogou Browser":"sogou",Swing:"swing",Tizen:"tizen","UC Browser":"uc",Vivaldi:"vivaldi","WebOS Browser":"webos",WeChat:"wechat",YahooSlurp:"yahooslurp","Yandex Browser":"yandex",YandexBot:"yandexbot",YouBot:"youbot"},d={amazonbot:"AmazonBot",amazon_silk:"Amazon Silk",android:"Android Browser",baiduspider:"BaiduSpider",bada:"Bada",bingcrawler:"BingCrawler",blackberry:"BlackBerry",brave:"Brave",chatgpt_user:"ChatGPT-User",chrome:"Chrome",claudebot:"ClaudeBot",chromium:"Chromium",diffbot:"Diffbot",duckduckbot:"DuckDuckBot",duckduckgo:"DuckDuckGo",edge:"Microsoft Edge",electron:"Electron",epiphany:"Epiphany",facebookexternalhit:"FacebookExternalHit",firefox:"Firefox",focus:"Focus",generic:"Generic",google_search:"Google Search",googlebot:"Googlebot",gptbot:"GPTBot",ie:"Internet Explorer",internetarchivecrawler:"InternetArchiveCrawler",k_meleon:"K-Meleon",librewolf:"LibreWolf",linespider:"Linespider",maxthon:"Maxthon",meta_externalads:"Meta-ExternalAds",meta_externalagent:"Meta-ExternalAgent",meta_externalfetcher:"Meta-ExternalFetcher",meta_webindexer:"Meta-WebIndexer",mz:"MZ Browser",naver:"NAVER Whale Browser",oai_searchbot:"OAI-SearchBot",omgilibot:"Omgilibot",opera:"Opera",opera_coast:"Opera Coast",pale_moon:"Pale Moon",perplexitybot:"PerplexityBot",perplexity_user:"Perplexity-User",phantomjs:"PhantomJS",pingdombot:"PingdomBot",puffin:"Puffin",qq:"QQ Browser",qqlite:"QQ Browser Lite",qupzilla:"QupZilla",roku:"Roku",safari:"Safari",sailfish:"Sailfish",samsung_internet:"Samsung Internet for Android",seamonkey:"SeaMonkey",slackbot:"SlackBot",sleipnir:"Sleipnir",sogou:"Sogou Browser",swing:"Swing",tizen:"Tizen",uc:"UC Browser",vivaldi:"Vivaldi",webos:"WebOS Browser",wechat:"WeChat",yahooslurp:"YahooSlurp",yandex:"Yandex Browser",yandexbot:"YandexBot",youbot:"YouBot"},l={bot:"bot",desktop:"desktop",mobile:"mobile",tablet:"tablet",tv:"tv"},u={Android:"Android",Bada:"Bada",BlackBerry:"BlackBerry",ChromeOS:"Chrome OS",HarmonyOS:"HarmonyOS",iOS:"iOS",Linux:"Linux",MacOS:"macOS",PlayStation4:"PlayStation 4",Roku:"Roku",Tizen:"Tizen",WebOS:"WebOS",Windows:"Windows",WindowsPhone:"Windows Phone"},p={Blink:"Blink",EdgeHTML:"EdgeHTML",Gecko:"Gecko",Presto:"Presto",Trident:"Trident",WebKit:"WebKit"};class h{static getFirstMatch(e,t){const r=t.match(e);return r&&r.length>0&&r[1]||""}static getSecondMatch(e,t){const r=t.match(e);return r&&r.length>1&&r[2]||""}static matchAndReturnConst(e,t,r){if(e.test(t))return r}static getWindowsVersionName(e){switch(e){case"NT":return"NT";case"XP":case"NT 5.1":return"XP";case"NT 5.0":return"2000";case"NT 5.2":return"2003";case"NT 6.0":return"Vista";case"NT 6.1":return"7";case"NT 6.2":return"8";case"NT 6.3":return"8.1";case"NT 10.0":return"10";default:return}}static getMacOSVersionName(e){const t=e.split(".").splice(0,2).map(e=>parseInt(e,10)||0);t.push(0);const r=t[0];if(10===r)switch(t[1]){case 5:return"Leopard";case 6:return"Snow Leopard";case 7:return"Lion";case 8:return"Mountain Lion";case 9:return"Mavericks";case 10:return"Yosemite";case 11:return"El Capitan";case 12:return"Sierra";case 13:return"High Sierra";case 14:return"Mojave";case 15:return"Catalina";default:return}switch(r){case 11:return"Big Sur";case 12:return"Monterey";case 13:return"Ventura";case 14:return"Sonoma";case 15:return"Sequoia";default:return}}static getAndroidVersionName(e){const t=e.split(".").splice(0,2).map(e=>parseInt(e,10)||0);if(t.push(0),!(1===t[0]&&t[1]<5))return 1===t[0]&&t[1]<6?"Cupcake":1===t[0]&&t[1]>=6?"Donut":2===t[0]&&t[1]<2?"Eclair":2===t[0]&&2===t[1]?"Froyo":2===t[0]&&t[1]>2?"Gingerbread":3===t[0]?"Honeycomb":4===t[0]&&t[1]<1?"Ice Cream Sandwich":4===t[0]&&t[1]<4?"Jelly Bean":4===t[0]&&t[1]>=4?"KitKat":5===t[0]?"Lollipop":6===t[0]?"Marshmallow":7===t[0]?"Nougat":8===t[0]?"Oreo":9===t[0]?"Pie":void 0}static getVersionPrecision(e){return e.split(".").length}static compareVersions(e,t,r=!1){const s=h.getVersionPrecision(e),n=h.getVersionPrecision(t);let i=Math.max(s,n),o=0;const a=h.map([e,t],e=>{const t=i-h.getVersionPrecision(e),r=e+new Array(t+1).join(".0");return h.map(r.split("."),e=>new Array(20-e.length).join("0")+e).reverse()});for(r&&(o=i-Math.min(s,n)),i-=1;i>=o;){if(a[0][i]>a[1][i])return 1;if(a[0][i]===a[1][i]){if(i===o)return 0;i-=1}else if(a[0][i]<a[1][i])return-1}}static map(e,t){const r=[];let s;if(Array.prototype.map)return Array.prototype.map.call(e,t);for(s=0;s<e.length;s+=1)r.push(t(e[s]));return r}static find(e,t){let r,s;if(Array.prototype.find)return Array.prototype.find.call(e,t);for(r=0,s=e.length;r<s;r+=1){const s=e[r];if(t(s,r))return s}}static assign(e,...t){const r=e;let s,n;if(Object.assign)return Object.assign(e,...t);for(s=0,n=t.length;s<n;s+=1){const e=t[s];"object"==typeof e&&null!==e&&Object.keys(e).forEach(t=>{r[t]=e[t]})}return e}static getBrowserAlias(e){return c[e]}static getBrowserTypeByAlias(e){return d[e]||""}}const m=/version\/(\d+(\.?_?\d+)+)/i,b=[{test:[/gptbot/i],describe(e){const t={name:"GPTBot"},r=h.getFirstMatch(/gptbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/chatgpt-user/i],describe(e){const t={name:"ChatGPT-User"},r=h.getFirstMatch(/chatgpt-user\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/oai-searchbot/i],describe(e){const t={name:"OAI-SearchBot"},r=h.getFirstMatch(/oai-searchbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/claudebot/i,/claude-web/i,/claude-user/i,/claude-searchbot/i],describe(e){const t={name:"ClaudeBot"},r=h.getFirstMatch(/(?:claudebot|claude-web|claude-user|claude-searchbot)\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/omgilibot/i,/webzio-extended/i],describe(e){const t={name:"Omgilibot"},r=h.getFirstMatch(/(?:omgilibot|webzio-extended)\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/diffbot/i],describe(e){const t={name:"Diffbot"},r=h.getFirstMatch(/diffbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/perplexitybot/i],describe(e){const t={name:"PerplexityBot"},r=h.getFirstMatch(/perplexitybot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/perplexity-user/i],describe(e){const t={name:"Perplexity-User"},r=h.getFirstMatch(/perplexity-user\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/youbot/i],describe(e){const t={name:"YouBot"},r=h.getFirstMatch(/youbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-webindexer/i],describe(e){const t={name:"Meta-WebIndexer"},r=h.getFirstMatch(/meta-webindexer\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalads/i],describe(e){const t={name:"Meta-ExternalAds"},r=h.getFirstMatch(/meta-externalads\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalagent/i],describe(e){const t={name:"Meta-ExternalAgent"},r=h.getFirstMatch(/meta-externalagent\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/meta-externalfetcher/i],describe(e){const t={name:"Meta-ExternalFetcher"},r=h.getFirstMatch(/meta-externalfetcher\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/googlebot/i],describe(e){const t={name:"Googlebot"},r=h.getFirstMatch(/googlebot\/(\d+(\.\d+))/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/linespider/i],describe(e){const t={name:"Linespider"},r=h.getFirstMatch(/(?:linespider)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/amazonbot/i],describe(e){const t={name:"AmazonBot"},r=h.getFirstMatch(/amazonbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/bingbot/i],describe(e){const t={name:"BingCrawler"},r=h.getFirstMatch(/bingbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/baiduspider/i],describe(e){const t={name:"BaiduSpider"},r=h.getFirstMatch(/baiduspider\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/duckduckbot/i],describe(e){const t={name:"DuckDuckBot"},r=h.getFirstMatch(/duckduckbot\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/ia_archiver/i],describe(e){const t={name:"InternetArchiveCrawler"},r=h.getFirstMatch(/ia_archiver\/(\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/facebookexternalhit/i,/facebookcatalog/i],describe:()=>({name:"FacebookExternalHit"})},{test:[/slackbot/i,/slack-imgProxy/i],describe(e){const t={name:"SlackBot"},r=h.getFirstMatch(/(?:slackbot|slack-imgproxy)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/yahoo!?[\s/]*slurp/i],describe:()=>({name:"YahooSlurp"})},{test:[/yandexbot/i,/yandexmobilebot/i],describe:()=>({name:"YandexBot"})},{test:[/pingdom/i],describe:()=>({name:"PingdomBot"})},{test:[/opera/i],describe(e){const t={name:"Opera"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/opr\/|opios/i],describe(e){const t={name:"Opera"},r=h.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/SamsungBrowser/i],describe(e){const t={name:"Samsung Internet for Android"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Whale/i],describe(e){const t={name:"NAVER Whale Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/PaleMoon/i],describe(e){const t={name:"Pale Moon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:PaleMoon)[\s/](\d+(?:\.\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/MZBrowser/i],describe(e){const t={name:"MZ Browser"},r=h.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/focus/i],describe(e){const t={name:"Focus"},r=h.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/swing/i],describe(e){const t={name:"Swing"},r=h.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/coast/i],describe(e){const t={name:"Opera Coast"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/opt\/\d+(?:.?_?\d+)+/i],describe(e){const t={name:"Opera Touch"},r=h.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/yabrowser/i],describe(e){const t={name:"Yandex Browser"},r=h.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/ucbrowser/i],describe(e){const t={name:"UC Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Maxthon|mxios/i],describe(e){const t={name:"Maxthon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/epiphany/i],describe(e){const t={name:"Epiphany"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/puffin/i],describe(e){const t={name:"Puffin"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sleipnir/i],describe(e){const t={name:"Sleipnir"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/k-meleon/i],describe(e){const t={name:"K-Meleon"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/micromessenger/i],describe(e){const t={name:"WeChat"},r=h.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/qqbrowser/i],describe(e){const t={name:/qqbrowserlite/i.test(e)?"QQ Browser Lite":"QQ Browser"},r=h.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/msie|trident/i],describe(e){const t={name:"Internet Explorer"},r=h.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/\sedg\//i],describe(e){const t={name:"Microsoft Edge"},r=h.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/edg([ea]|ios)/i],describe(e){const t={name:"Microsoft Edge"},r=h.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/vivaldi/i],describe(e){const t={name:"Vivaldi"},r=h.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/seamonkey/i],describe(e){const t={name:"SeaMonkey"},r=h.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sailfish/i],describe(e){const t={name:"Sailfish"},r=h.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i,e);return r&&(t.version=r),t}},{test:[/silk/i],describe(e){const t={name:"Amazon Silk"},r=h.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/phantom/i],describe(e){const t={name:"PhantomJS"},r=h.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/slimerjs/i],describe(e){const t={name:"SlimerJS"},r=h.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe(e){const t={name:"BlackBerry"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(web|hpw)[o0]s/i],describe(e){const t={name:"WebOS Browser"},r=h.getFirstMatch(m,e)||h.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/bada/i],describe(e){const t={name:"Bada"},r=h.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/tizen/i],describe(e){const t={name:"Tizen"},r=h.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/qupzilla/i],describe(e){const t={name:"QupZilla"},r=h.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/librewolf/i],describe(e){const t={name:"LibreWolf"},r=h.getFirstMatch(/(?:librewolf)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/firefox|iceweasel|fxios/i],describe(e){const t={name:"Firefox"},r=h.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/electron/i],describe(e){const t={name:"Electron"},r=h.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sogoumobilebrowser/i,/metasr/i,/se 2\.[x]/i],describe(e){const t={name:"Sogou Browser"},r=h.getFirstMatch(/(?:sogoumobilebrowser)[\s/](\d+(\.?_?\d+)+)/i,e),s=h.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i,e),n=h.getFirstMatch(/se ([\d.]+)x/i,e),i=r||s||n;return i&&(t.version=i),t}},{test:[/MiuiBrowser/i],describe(e){const t={name:"Miui"},r=h.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:e=>!!e.hasBrand("DuckDuckGo")||e.test(/\sDdg\/[\d.]+$/i),describe(e,t){const r={name:"DuckDuckGo"};if(t){const e=t.getBrandVersion("DuckDuckGo");if(e)return r.version=e,r}const s=h.getFirstMatch(/\sDdg\/([\d.]+)$/i,e);return s&&(r.version=s),r}},{test:e=>e.hasBrand("Brave"),describe(e,t){const r={name:"Brave"};if(t){const e=t.getBrandVersion("Brave");if(e)return r.version=e,r}return r}},{test:[/chromium/i],describe(e){const t={name:"Chromium"},r=h.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i,e)||h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/chrome|crios|crmo/i],describe(e){const t={name:"Chrome"},r=h.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/GSA/i],describe(e){const t={name:"Google Search"},r=h.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test(e){const t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe(e){const t={name:"Android Browser"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/playstation 4/i],describe(e){const t={name:"PlayStation 4"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/safari|applewebkit/i],describe(e){const t={name:"Safari"},r=h.getFirstMatch(m,e);return r&&(t.version=r),t}},{test:[/.*/i],describe(e){const t=-1!==e.search("\\(")?/^(.*)\/(.*)[ \t]\((.*)/:/^(.*)\/(.*) /;return{name:h.getFirstMatch(t,e),version:h.getSecondMatch(t,e)}}}],g=[{test:[/Roku\/DVP/],describe(e){const t=h.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i,e);return{name:u.Roku,version:t}}},{test:[/windows phone/i],describe(e){const t=h.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i,e);return{name:u.WindowsPhone,version:t}}},{test:[/windows /i],describe(e){const t=h.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i,e),r=h.getWindowsVersionName(t);return{name:u.Windows,version:t,versionName:r}}},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe(e){const t={name:u.iOS},r=h.getSecondMatch(/(Version\/)(\d[\d.]+)/,e);return r&&(t.version=r),t}},{test:[/macintosh/i],describe(e){const t=h.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i,e).replace(/[_\s]/g,"."),r=h.getMacOSVersionName(t),s={name:u.MacOS,version:t};return r&&(s.versionName=r),s}},{test:[/(ipod|iphone|ipad)/i],describe(e){const t=h.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i,e).replace(/[_\s]/g,".");return{name:u.iOS,version:t}}},{test:[/OpenHarmony/i],describe(e){const t=h.getFirstMatch(/OpenHarmony\s+(\d+(\.\d+)*)/i,e);return{name:u.HarmonyOS,version:t}}},{test(e){const t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe(e){const t=h.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i,e),r=h.getAndroidVersionName(t),s={name:u.Android,version:t};return r&&(s.versionName=r),s}},{test:[/(web|hpw)[o0]s/i],describe(e){const t=h.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i,e),r={name:u.WebOS};return t&&t.length&&(r.version=t),r}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe(e){const t=h.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i,e)||h.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i,e)||h.getFirstMatch(/\bbb(\d+)/i,e);return{name:u.BlackBerry,version:t}}},{test:[/bada/i],describe(e){const t=h.getFirstMatch(/bada\/(\d+(\.\d+)*)/i,e);return{name:u.Bada,version:t}}},{test:[/tizen/i],describe(e){const t=h.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i,e);return{name:u.Tizen,version:t}}},{test:[/linux/i],describe:()=>({name:u.Linux})},{test:[/CrOS/],describe:()=>({name:u.ChromeOS})},{test:[/PlayStation 4/],describe(e){const t=h.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i,e);return{name:u.PlayStation4,version:t}}}],f=[{test:[/googlebot/i],describe:()=>({type:l.bot,vendor:"Google"})},{test:[/linespider/i],describe:()=>({type:l.bot,vendor:"Line"})},{test:[/amazonbot/i],describe:()=>({type:l.bot,vendor:"Amazon"})},{test:[/gptbot/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/chatgpt-user/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/oai-searchbot/i],describe:()=>({type:l.bot,vendor:"OpenAI"})},{test:[/baiduspider/i],describe:()=>({type:l.bot,vendor:"Baidu"})},{test:[/bingbot/i],describe:()=>({type:l.bot,vendor:"Bing"})},{test:[/duckduckbot/i],describe:()=>({type:l.bot,vendor:"DuckDuckGo"})},{test:[/claudebot/i,/claude-web/i,/claude-user/i,/claude-searchbot/i],describe:()=>({type:l.bot,vendor:"Anthropic"})},{test:[/omgilibot/i,/webzio-extended/i],describe:()=>({type:l.bot,vendor:"Webz.io"})},{test:[/diffbot/i],describe:()=>({type:l.bot,vendor:"Diffbot"})},{test:[/perplexitybot/i],describe:()=>({type:l.bot,vendor:"Perplexity AI"})},{test:[/perplexity-user/i],describe:()=>({type:l.bot,vendor:"Perplexity AI"})},{test:[/youbot/i],describe:()=>({type:l.bot,vendor:"You.com"})},{test:[/ia_archiver/i],describe:()=>({type:l.bot,vendor:"Internet Archive"})},{test:[/meta-webindexer/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalads/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalagent/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/meta-externalfetcher/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/facebookexternalhit/i,/facebookcatalog/i],describe:()=>({type:l.bot,vendor:"Meta"})},{test:[/slackbot/i,/slack-imgProxy/i],describe:()=>({type:l.bot,vendor:"Slack"})},{test:[/yahoo/i],describe:()=>({type:l.bot,vendor:"Yahoo"})},{test:[/yandexbot/i,/yandexmobilebot/i],describe:()=>({type:l.bot,vendor:"Yandex"})},{test:[/pingdom/i],describe:()=>({type:l.bot,vendor:"Pingdom"})},{test:[/huawei/i],describe(e){const t=h.getFirstMatch(/(can-l01)/i,e)&&"Nova",r={type:l.mobile,vendor:"Huawei"};return t&&(r.model=t),r}},{test:[/nexus\s*(?:7|8|9|10).*/i],describe:()=>({type:l.tablet,vendor:"Nexus"})},{test:[/ipad/i],describe:()=>({type:l.tablet,vendor:"Apple",model:"iPad"})},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe:()=>({type:l.tablet,vendor:"Apple",model:"iPad"})},{test:[/kftt build/i],describe:()=>({type:l.tablet,vendor:"Amazon",model:"Kindle Fire HD 7"})},{test:[/silk/i],describe:()=>({type:l.tablet,vendor:"Amazon"})},{test:[/tablet(?! pc)/i],describe:()=>({type:l.tablet})},{test(e){const t=e.test(/ipod|iphone/i),r=e.test(/like (ipod|iphone)/i);return t&&!r},describe(e){const t=h.getFirstMatch(/(ipod|iphone)/i,e);return{type:l.mobile,vendor:"Apple",model:t}}},{test:[/nexus\s*[0-6].*/i,/galaxy nexus/i],describe:()=>({type:l.mobile,vendor:"Nexus"})},{test:[/Nokia/i],describe(e){const t=h.getFirstMatch(/Nokia\s+([0-9]+(\.[0-9]+)?)/i,e),r={type:l.mobile,vendor:"Nokia"};return t&&(r.model=t),r}},{test:[/[^-]mobi/i],describe:()=>({type:l.mobile})},{test:e=>"blackberry"===e.getBrowserName(!0),describe:()=>({type:l.mobile,vendor:"BlackBerry"})},{test:e=>"bada"===e.getBrowserName(!0),describe:()=>({type:l.mobile})},{test:e=>"windows phone"===e.getBrowserName(),describe:()=>({type:l.mobile,vendor:"Microsoft"})},{test(e){const t=Number(String(e.getOSVersion()).split(".")[0]);return"android"===e.getOSName(!0)&&t>=3},describe:()=>({type:l.tablet})},{test:e=>"android"===e.getOSName(!0),describe:()=>({type:l.mobile})},{test:[/smart-?tv|smarttv/i],describe:()=>({type:l.tv})},{test:[/netcast/i],describe:()=>({type:l.tv})},{test:e=>"macos"===e.getOSName(!0),describe:()=>({type:l.desktop,vendor:"Apple"})},{test:e=>"windows"===e.getOSName(!0),describe:()=>({type:l.desktop})},{test:e=>"linux"===e.getOSName(!0),describe:()=>({type:l.desktop})},{test:e=>"playstation 4"===e.getOSName(!0),describe:()=>({type:l.tv})},{test:e=>"roku"===e.getOSName(!0),describe:()=>({type:l.tv})}],v=[{test:e=>"microsoft edge"===e.getBrowserName(!0),describe(e){if(/\sedg\//i.test(e))return{name:p.Blink};const t=h.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i,e);return{name:p.EdgeHTML,version:t}}},{test:[/trident/i],describe(e){const t={name:p.Trident},r=h.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:e=>e.test(/presto/i),describe(e){const t={name:p.Presto},r=h.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test(e){const t=e.test(/gecko/i),r=e.test(/like gecko/i);return t&&!r},describe(e){const t={name:p.Gecko},r=h.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(apple)?webkit\/537\.36/i],describe:()=>({name:p.Blink})},{test:[/(apple)?webkit/i],describe(e){const t={name:p.WebKit},r=h.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i,e);return r&&(t.version=r),t}}];class S{constructor(e,t=!1,r=null){if(null==e||""===e)throw new Error("UserAgent parameter can't be empty");this._ua=e;let s=!1;"boolean"==typeof t?(s=t,this._hints=r):this._hints=null!=t&&"object"==typeof t?t:null,this.parsedResult={},!0!==s&&this.parse()}getHints(){return this._hints}hasBrand(e){if(!this._hints||!Array.isArray(this._hints.brands))return!1;const t=e.toLowerCase();return this._hints.brands.some(e=>e.brand&&e.brand.toLowerCase()===t)}getBrandVersion(e){if(!this._hints||!Array.isArray(this._hints.brands))return;const t=e.toLowerCase(),r=this._hints.brands.find(e=>e.brand&&e.brand.toLowerCase()===t);return r?r.version:void 0}getUA(){return this._ua}test(e){return e.test(this._ua)}parseBrowser(){this.parsedResult.browser={};const e=h.find(b,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.browser=e.describe(this.getUA(),this)),this.parsedResult.browser}getBrowser(){return this.parsedResult.browser?this.parsedResult.browser:this.parseBrowser()}getBrowserName(e){return e?String(this.getBrowser().name).toLowerCase()||"":this.getBrowser().name||""}getBrowserVersion(){return this.getBrowser().version}getOS(){return this.parsedResult.os?this.parsedResult.os:this.parseOS()}parseOS(){this.parsedResult.os={};const e=h.find(g,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.os=e.describe(this.getUA())),this.parsedResult.os}getOSName(e){const{name:t}=this.getOS();return e?String(t).toLowerCase()||"":t||""}getOSVersion(){return this.getOS().version}getPlatform(){return this.parsedResult.platform?this.parsedResult.platform:this.parsePlatform()}getPlatformType(e=!1){const{type:t}=this.getPlatform();return e?String(t).toLowerCase()||"":t||""}parsePlatform(){this.parsedResult.platform={};const e=h.find(f,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.platform=e.describe(this.getUA())),this.parsedResult.platform}getEngine(){return this.parsedResult.engine?this.parsedResult.engine:this.parseEngine()}getEngineName(e){return e?String(this.getEngine().name).toLowerCase()||"":this.getEngine().name||""}parseEngine(){this.parsedResult.engine={};const e=h.find(v,e=>{if("function"==typeof e.test)return e.test(this);if(Array.isArray(e.test))return e.test.some(e=>this.test(e));throw new Error("Browser's test function is not valid")});return e&&(this.parsedResult.engine=e.describe(this.getUA())),this.parsedResult.engine}parse(){return this.parseBrowser(),this.parseOS(),this.parsePlatform(),this.parseEngine(),this}getResult(){return h.assign({},this.parsedResult)}satisfies(e){const t={};let r=0;const s={};let n=0;if(Object.keys(e).forEach(i=>{const o=e[i];"string"==typeof o?(s[i]=o,n+=1):"object"==typeof o&&(t[i]=o,r+=1)}),r>0){const e=Object.keys(t),r=h.find(e,e=>this.isOS(e));if(r){const e=this.satisfies(t[r]);if(void 0!==e)return e}const s=h.find(e,e=>this.isPlatform(e));if(s){const e=this.satisfies(t[s]);if(void 0!==e)return e}}if(n>0){const e=Object.keys(s),t=h.find(e,e=>this.isBrowser(e,!0));if(void 0!==t)return this.compareVersion(s[t])}}isBrowser(e,t=!1){const r=this.getBrowserName().toLowerCase();let s=e.toLowerCase();const n=h.getBrowserTypeByAlias(s);return t&&n&&(s=n.toLowerCase()),s===r}compareVersion(e){let t=[0],r=e,s=!1;const n=this.getBrowserVersion();if("string"==typeof n)return">"===e[0]||"<"===e[0]?(r=e.substr(1),"="===e[1]?(s=!0,r=e.substr(2)):t=[],t.push(">"===e[0]?1:-1)):"="===e[0]?r=e.substr(1):"~"===e[0]&&(s=!0,r=e.substr(1)),t.indexOf(h.compareVersions(n,r,s))>-1}isOS(e){return this.getOSName(!0)===String(e).toLowerCase()}isPlatform(e){return this.getPlatformType(!0)===String(e).toLowerCase()}isEngine(e){return this.getEngineName(!0)===String(e).toLowerCase()}is(e,t=!1){return this.isBrowser(e,t)||this.isOS(e)||this.isPlatform(e)}some(e=[]){return e.some(e=>this.is(e))}}class _{static getParser(e,t=!1,r=null){if("string"!=typeof e)throw new Error("UserAgent should be a string");return new S(e,t,r)}static parse(e,t=null){return new S(e,t).getResult()}static get BROWSER_MAP(){return d}static get ENGINE_MAP(){return p}static get OS_MAP(){return u}static get PLATFORMS_MAP(){return l}}function y(e,t){return Object.keys(t).forEach(function(r){"default"===r||"__esModule"===r||Object.prototype.hasOwnProperty.call(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[r]}})}),e}function w(e,t,r,s){Object.defineProperty(e,t,{get:r,set:s,enumerable:!0,configurable:!0})}function M(e){return e&&e.__esModule?e.default:e}var k={},E={};w(E,"A11ySnapshotStreamer",()=>q);const T=200,C=new WeakMap,B="undefined"==typeof WeakRef?void 0:WeakRef,L=new Map;let A=0;function x(e){const t=C.get(e);if(t)return t;const r="e"+ ++A;return C.set(e,r),L.set(r,B?new B(e):e),r}function O(e){const t=L.get(e);if(!t)return null;const r="deref"in t?t.deref():t;return r&&r.isConnected?r:(L.delete(e),null)}function R(e){return C.get(e)??null}const F=new Set(["script","style","link","meta","noscript","template"]),P=new Set([...new Set(["button","link","checkbox","radio","textbox","combobox","switch","menuitem","tab"]),"heading","img"]);function N(e){return e.replace(/\s+/g," ").trim()}function U(e,t=100){const r=N(e);return r.length<=t?r:r.slice(0,t-1)+"…"}function I(e){const t=[];for(let r=0;r<e.childNodes.length;r++){const s=e.childNodes[r];if(3===s.nodeType){const e=(s.textContent??"").trim();e&&t.push(e)}else if(1===s.nodeType){const e=s;if(F.has(e.tagName.toLowerCase()))continue;if("true"===e.getAttribute("aria-hidden"))continue;const r=I(e);r&&t.push(r)}}return t.join(" ").replace(/\s+/g," ").trim()}function D(e,t){const r=e.getAttribute(t);if(!r)return;const s=parseInt(r,10);return Number.isNaN(s)||s<0?void 0:s}function j(e,t,r,s,n=!1){if(function(e){if(F.has(e.tagName.toLowerCase()))return!0;if("true"===e.getAttribute("aria-hidden"))return!0;if(e.hasAttribute("data-a11y-exclude"))return!0;if(e.hidden)return!0;if(e instanceof HTMLElement&&null===e.offsetParent&&"BODY"!==e.tagName){const t=window.getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility)return!0}return!1}(e))return[];if(r.count>=T)return[];if(t>10)return r.count++,[{ref:x(e),role:"ellipsis",name:"<truncated: max depth>"}];const i=function(e){const t=e.getAttribute("role");if(t)return t;const r=e.tagName.toLowerCase();switch(r){case"main":case"nav":case"header":case"aside":case"footer":return r;case"article":case"section":return function(e){return!!e.hasAttribute("aria-label")||!!e.hasAttribute("aria-labelledby")||(e.textContent??"").trim().length>0}(e)?"region":null;case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return"heading";case"a":return e.hasAttribute("href")?"link":null;case"button":return"button";case"input":{const t=e.type;return"checkbox"===t?"checkbox":"radio"===t?"radio":"submit"===t||"button"===t||"reset"===t?"button":"hidden"===t?null:"textbox"}case"select":return"combobox";case"textarea":return"textbox";case"label":return null;case"img":return null!==e.getAttribute("alt")?"img":null;case"p":return"paragraph";case"ul":case"ol":return"list";case"li":return"listitem";case"table":return"table";case"tr":return"row";case"th":return"columnheader";case"td":return"cell";default:return e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||e.hasAttribute("tabindex")?"generic":null}}(e);if(null===i)return z(e,t,r,s,{skipTextNodes:n});r.count++;const o={ref:x(e),role:i},a=function(e,t){const r=e.getAttribute("aria-label");if(r)return U(r);const s=function(e){const t=e.getAttribute("aria-labelledby");if(!t)return;const r=[];for(const s of t.split(/\s+/)){if(!s)continue;const t=e.ownerDocument.getElementById(s);t&&r.push(I(t))}return r.filter(Boolean).join(" ")||void 0}(e);if(s)return U(s);const n=e.tagName.toLowerCase();if("input"===n||"textarea"===n||"select"===n){const t=e.getAttribute("id");if(t){const r=e.ownerDocument.getElementsByTagName("label");for(let e=0;e<r.length;e++)if(r[e].htmlFor===t&&r[e].textContent)return U(r[e].textContent??"")}const r=e.closest("label");if(r?.textContent)return U(r.textContent);const s=e.getAttribute("placeholder");return s?U(s):void 0}if("img"===n){const t=e.getAttribute("alt");return t?U(t):void 0}if(P.has(t)||"paragraph"===t){const t=I(e);return t?U(t):void 0}}(e,i);a&&(o.name=a);const c=function(e){if(e instanceof HTMLInputElement){if("password"===e.type)return;if("checkbox"===e.type||"radio"===e.type||"hidden"===e.type)return;return e.value||void 0}if(e instanceof HTMLTextAreaElement)return e.value||void 0;if(e instanceof HTMLSelectElement){const t=e.selectedOptions[0],r=t?.text?.trim();return r||e.value||void 0}}(e);void 0!==c&&(o.value=c);const d=function(e){const t=[];return e.ownerDocument.activeElement===e&&t.push("focused"),"true"===e.getAttribute("aria-expanded")&&t.push("expanded"),"true"===e.getAttribute("aria-selected")&&t.push("selected"),(e.hasAttribute("disabled")||"true"===e.getAttribute("aria-disabled"))&&t.push("disabled"),"true"===e.getAttribute("aria-checked")&&t.push("checked"),e instanceof HTMLInputElement&&("checkbox"!==e.type&&"radio"!==e.type||!e.checked||t.includes("checked")||t.push("checked")),t}(e);s.trackViewport&&function(e){const t=e.getBoundingClientRect();if(0===t.width&&0===t.height)return!0;const r=window.innerWidth||document.documentElement.clientWidth,s=window.innerHeight||document.documentElement.clientHeight;return t.bottom<=0||t.top>=s||t.right<=0||t.left>=r}(e)&&d.push("offscreen"),d.length&&(o.state=d);const l=function(e,t){if("heading"!==t)return;const r=e.tagName.toLowerCase().match(/^h([1-6])$/);if(r)return parseInt(r[1],10);const s=e.getAttribute("aria-level");if(s){const e=parseInt(s,10);if(!Number.isNaN(e))return e}}(e,i);void 0!==l&&(o.level=l);const u=D(e,"aria-colcount");void 0!==u&&(o.colcount=u);const p=D(e,"aria-rowcount");if(void 0!==p&&(o.rowcount=p),P.has(i)){if(e instanceof HTMLSelectElement){const t=function(e,t,r){const s=[],n=e.options;let i=0;for(let e=0;e<n.length&&!(t.count>=T);e++){const o=n[e];if(o.hidden)continue;if("true"===o.getAttribute("aria-hidden"))continue;if(i>=20){t.count++,s.push({ref:`${r}.more`,role:"ellipsis",name:n.length-i+" more"});break}t.count++,i++;const a=(o.text||o.value||"").trim(),c={ref:x(o),role:"option",name:U(a)},d=[];o.selected&&d.push("selected"),o.disabled&&d.push("disabled"),d.length&&(c.state=d),s.push(c)}return s}(e,r,o.ref);t.length>0&&(o.children=t)}}else{const n=z(e,t+1,r,s,{skipTextNodes:"paragraph"===i});if(n.length>0)if(n.length>50){const e=n.slice(0,50);e.push({ref:`${o.ref}.more`,role:"ellipsis",name:n.length-50+" more"}),o.children=e}else o.children=n}return[o]}function z(e,t,r,s,n={}){const i=[];for(let o=0;o<e.childNodes.length;o++){const a=e.childNodes[o];if(3===a.nodeType){if(n.skipTextNodes)continue;const e=N(a.textContent??"");if(e){if(r.count>=T)break;r.count++,i.push({ref:"",role:"text",name:U(e)})}}else if(1===a.nodeType){const e=j(a,t,r,s,n.skipTextNodes);for(const t of e)i.push(t);if(r.count>=T)break}}return i}function H(e){return e.length<=2e3?e:e.slice(0,1999)+"…"}function G(){if("undefined"==typeof document)return null;const e=document.activeElement;if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=e.selectionStart,r=e.selectionEnd;if(null!==t&&null!==r&&t!==r){const s=C.get(e);if(!s)return null;const n=e.value.slice(t,r);return n?{ref:s,text:H(n),start_offset:t,end_offset:r}:null}}const t=document.getSelection();if(!t||0===t.rangeCount||t.isCollapsed)return null;const r=t.toString();if(!r)return null;let s=t.getRangeAt(0).commonAncestorContainer;for(;s&&1!==s.nodeType;)s=s.parentNode;const n=function(e){let t=e;for(;t;){if("true"===t.getAttribute("aria-hidden")||t.hasAttribute("data-a11y-exclude"))return null;if(C.has(t))return t;t=t.parentElement}return null}(s);if(!n)return null;const i=C.get(n);return i?{ref:i,text:H(r)}:null}function V(e,t={}){const r=e??("undefined"!=typeof document?document.body:null);if(!r)return{root:{ref:"e0",role:"generic"},captured_at:Date.now()};const s=z(r,0,{count:0},{trackViewport:t.trackViewport??!0}),n=G();return{root:{ref:x(r),role:"generic",...s.length>0?{children:s}:{}},captured_at:Date.now(),...n?{selection:n}:{}}}class q{constructor(e,t={}){this.running=!1,this.emitSnapshot=e,this.debounceMs=t.debounceMs??300,this.trackViewport=t.trackViewport??!0,this.logSnapshots=t.logSnapshots??!1}start(){this.running||"undefined"!=typeof document&&(this.running=!0,this.schedule(),this.observer=new MutationObserver(()=>this.schedule()),this.observer.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["role","aria-label","aria-labelledby","aria-expanded","aria-selected","aria-checked","aria-disabled","aria-level","aria-hidden","aria-colcount","aria-rowcount","data-a11y-exclude","disabled","hidden","tabindex","href"]}),this.focusHandler=()=>this.schedule(),document.addEventListener("focusin",this.focusHandler),document.addEventListener("focusout",this.focusHandler),this.scrollEndHandler=()=>this.schedule(),window.addEventListener("scrollend",this.scrollEndHandler,{capture:!0}),this.resizeHandler=()=>this.schedule(),window.addEventListener("resize",this.resizeHandler),this.visibilityHandler=()=>{"visible"===document.visibilityState&&this.schedule()},document.addEventListener("visibilitychange",this.visibilityHandler),this.selectionHandler=()=>this.schedule(),document.addEventListener("selectionchange",this.selectionHandler),this.formHandler=()=>this.schedule(),document.addEventListener("input",this.formHandler,{capture:!0}),document.addEventListener("change",this.formHandler,{capture:!0}))}stop(){this.running&&(this.running=!1,void 0!==this.timer&&(clearTimeout(this.timer),this.timer=void 0),this.observer&&(this.observer.disconnect(),this.observer=void 0),"undefined"!=typeof document&&(this.focusHandler&&(document.removeEventListener("focusin",this.focusHandler),document.removeEventListener("focusout",this.focusHandler)),this.visibilityHandler&&document.removeEventListener("visibilitychange",this.visibilityHandler),this.selectionHandler&&document.removeEventListener("selectionchange",this.selectionHandler),this.formHandler&&(document.removeEventListener("input",this.formHandler,{capture:!0}),document.removeEventListener("change",this.formHandler,{capture:!0}))),"undefined"!=typeof window&&(this.scrollEndHandler&&window.removeEventListener("scrollend",this.scrollEndHandler,{capture:!0}),this.resizeHandler&&window.removeEventListener("resize",this.resizeHandler)),this.focusHandler=void 0,this.scrollEndHandler=void 0,this.resizeHandler=void 0,this.visibilityHandler=void 0,this.selectionHandler=void 0,this.formHandler=void 0)}schedule(){this.running&&(void 0!==this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>this.emit(),this.debounceMs))}emit(){if(this.timer=void 0,this.running)try{const e=V(void 0,{trackViewport:this.trackViewport});if(this.emitSnapshot(e),this.logSnapshots){const t=W(e.root),r=Math.round(JSON.stringify(e).length/4);console.groupCollapsed(`[A11ySnapshotStreamer] emit: ${t} nodes, ~${r} tokens`),console.groupEnd()}}catch{}}}function W(e){let t=1;const r=e.children;if(r)for(const e of r)t+=W(e);return t}var $,Y={};w(Y,"PipecatClient",()=>Ve),$=JSON.parse('{"name":"@pipecat-ai/client-js","version":"1.12.0","license":"BSD-2-Clause","main":"dist/index.js","module":"dist/index.module.js","types":"dist/index.d.ts","source":"index.ts","repository":{"type":"git","url":"git+https://github.com/pipecat-ai/pipecat-client-web.git"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.module.js","require":"./dist/index.js"}},"files":["dist","package.json","README.md"],"scripts":{"build":"jest --silent --passWithNoTests && parcel build --no-cache","dev":"parcel watch","lint":"eslint . --report-unused-disable-directives --max-warnings 0","test":"jest"},"jest":{"preset":"ts-jest","testEnvironment":"jsdom","setupFilesAfterEnv":["<rootDir>/tests/jest.setup.ts"]},"devDependencies":{"@jest/globals":"^29.7.0","@types/clone-deep":"^4.0.4","@types/jest":"^29.5.12","eslint":"^9.11.1","eslint-config-prettier":"^9.1.0","eslint-plugin-simple-import-sort":"^12.1.1","jest":"^29.7.0","jest-environment-jsdom":"^30.0.2","ts-jest":"^29.2.5","whatwg-fetch":"^3.6.20"},"dependencies":{"@types/events":"^3.0.3","bowser":"^2.11.0","clone-deep":"^4.0.1","events":"^3.3.0","typed-emitter":"^2.1.0","uuid":"^11.1.1"}}');var J={};w(J,"findElementByRef",()=>O),w(J,"findRefForElement",()=>R),w(J,"serializeSelection",()=>G),w(J,"snapshotDocument",()=>V);var K,Q,X={};w(X,"TransportStateEnum",()=>K),(Q=K||(K={})).DISCONNECTED="disconnected",Q.INITIALIZING="initializing",Q.INITIALIZED="initialized",Q.AUTHENTICATING="authenticating",Q.AUTHENTICATED="authenticated",Q.CONNECTING="connecting",Q.CONNECTED="connected",Q.READY="ready",Q.DISCONNECTING="disconnecting",Q.ERROR="error";var Z={};w(Z,"RTVIError",()=>ee),w(Z,"ConnectionTimeoutError",()=>te),w(Z,"StartBotError",()=>re),w(Z,"TransportStartError",()=>se),w(Z,"InvalidTransportParamsError",()=>ne),w(Z,"BotNotReadyError",()=>ie),w(Z,"BotAlreadyStartedError",()=>oe),w(Z,"UnsupportedFeatureError",()=>ae),w(Z,"MessageTooLargeError",()=>ce),w(Z,"DeviceError",()=>de);class ee extends Error{constructor(e,t){super(e),this.status=t}}class te extends ee{constructor(e){super(e??"Bot did not enter ready state within the specified timeout period.")}}class re extends ee{constructor(e,t){super(e??"Failed to connect / invalid auth bundle from base url",t??500),this.error="invalid-request-error"}}class se extends ee{constructor(e){super(e??"Unable to connect to transport")}}class ne extends ee{constructor(e){super(e??"Invalid transport connection parameters")}}class ie extends ee{constructor(e){super(e??"Attempt to call action on transport when not in 'ready' state.")}}class oe extends ee{constructor(e){super(e??"Pipecat client has already been started. Please call disconnect() before starting again.")}}class ae extends ee{constructor(e,t,r){let s=`${e} not supported${r?`: ${r}`:""}`;t&&(s=`${t} does not support ${e}${r?`: ${r}`:""}`),super(s),this.feature=e}}class ce extends ee{constructor(e){super(e??"Message size exceeds the maximum allowed limit for transport.")}}class de extends ee{constructor(e,t,r,s){super(r??`Device error for ${e.join(", ")}: ${t}`),this.devices=e,this.type=t,this.details=s}}var le,ue,pe={};w(pe,"RTVIEvent",()=>le),(ue=le||(le={})).Connected="connected",ue.Disconnected="disconnected",ue.TransportStateChanged="transportStateChanged",ue.BotStarted="botStarted",ue.BotConnected="botConnected",ue.BotReady="botReady",ue.BotDisconnected="botDisconnected",ue.Error="error",ue.ServerMessage="serverMessage",ue.ServerResponse="serverResponse",ue.MessageError="messageError",ue.UICommand="uiCommand",ue.UIJobGroup="uiJobGroup",ue.Metrics="metrics",ue.BotStartedSpeaking="botStartedSpeaking",ue.BotStoppedSpeaking="botStoppedSpeaking",ue.UserStartedSpeaking="userStartedSpeaking",ue.UserStoppedSpeaking="userStoppedSpeaking",ue.UserMuteStarted="userMuteStarted",ue.UserMuteStopped="userMuteStopped",ue.UserTranscript="userTranscript",ue.BotOutput="botOutput",ue.BotTranscript="botTranscript",ue.UserLlmText="userLlmText",ue.BotLlmText="botLlmText",ue.BotLlmStarted="botLlmStarted",ue.BotLlmStopped="botLlmStopped",ue.LLMFunctionCall="llmFunctionCall",ue.LLMFunctionCallStarted="llmFunctionCallStarted",ue.LLMFunctionCallInProgress="llmFunctionCallInProgress",ue.LLMFunctionCallStopped="llmFunctionCallStopped",ue.BotLlmSearchResponse="botLlmSearchResponse",ue.BotTtsText="botTtsText",ue.BotTtsStarted="botTtsStarted",ue.BotTtsStopped="botTtsStopped",ue.ParticipantConnected="participantConnected",ue.ParticipantLeft="participantLeft",ue.TrackStarted="trackStarted",ue.TrackStopped="trackStopped",ue.ScreenTrackStarted="screenTrackStarted",ue.ScreenTrackStopped="screenTrackStopped",ue.ScreenShareError="screenShareError",ue.LocalAudioLevel="localAudioLevel",ue.RemoteAudioLevel="remoteAudioLevel",ue.AvailableCamsUpdated="availableCamsUpdated",ue.AvailableMicsUpdated="availableMicsUpdated",ue.AvailableSpeakersUpdated="availableSpeakersUpdated",ue.CamUpdated="camUpdated",ue.MicUpdated="micUpdated",ue.SpeakerUpdated="speakerUpdated",ue.DeviceError="deviceError",ue.MediaStateUpdated="mediaStateUpdated",ue.UnsupportedFeature="unsupportedFeature";var he={};w(he,"RTVI_PROTOCOL_VERSION",()=>me),w(he,"RTVI_MESSAGE_LABEL",()=>be),w(he,"RTVIMessageType",()=>ge),w(he,"AggregationType",()=>ve),w(he,"setAboutClient",()=>ye),w(he,"RTVIMessage",()=>we);const me="2.0.0",be="rtvi-ai";var ge,fe,ve,Se;let _e;function ye(e){_e=_e?{..._e,...e}:e}(fe=ge||(ge={})).CLIENT_READY="client-ready",fe.DISCONNECT_BOT="disconnect-bot",fe.CLIENT_MESSAGE="client-message",fe.SEND_TEXT="send-text",fe.UI_EVENT="ui-event",fe.UI_SNAPSHOT="ui-snapshot",fe.UI_CANCEL_JOB_GROUP="ui-cancel-job-group",fe.APPEND_TO_CONTEXT="append-to-context",fe.BOT_READY="bot-ready",fe.ERROR="error",fe.METRICS="metrics",fe.SERVER_MESSAGE="server-message",fe.SERVER_RESPONSE="server-response",fe.ERROR_RESPONSE="error-response",fe.APPEND_TO_CONTEXT_RESULT="append-to-context-result",fe.UI_COMMAND="ui-command",fe.UI_JOB_GROUP="ui-job-group",fe.USER_STARTED_SPEAKING="user-started-speaking",fe.USER_STOPPED_SPEAKING="user-stopped-speaking",fe.BOT_STARTED_SPEAKING="bot-started-speaking",fe.BOT_STOPPED_SPEAKING="bot-stopped-speaking",fe.USER_MUTE_STARTED="user-mute-started",fe.USER_MUTE_STOPPED="user-mute-stopped",fe.USER_TRANSCRIPTION="user-transcription",fe.BOT_OUTPUT="bot-output",fe.BOT_TRANSCRIPTION="bot-transcription",fe.USER_LLM_TEXT="user-llm-text",fe.BOT_LLM_TEXT="bot-llm-text",fe.BOT_LLM_STARTED="bot-llm-started",fe.BOT_LLM_STOPPED="bot-llm-stopped",fe.LLM_FUNCTION_CALL="llm-function-call",fe.LLM_FUNCTION_CALL_STARTED="llm-function-call-started",fe.LLM_FUNCTION_CALL_IN_PROGRESS="llm-function-call-in-progress",fe.LLM_FUNCTION_CALL_STOPPED="llm-function-call-stopped",fe.LLM_FUNCTION_CALL_RESULT="llm-function-call-result",fe.BOT_LLM_SEARCH_RESPONSE="bot-llm-search-response",fe.BOT_TTS_TEXT="bot-tts-text",fe.BOT_TTS_STARTED="bot-tts-started",fe.BOT_TTS_STOPPED="bot-tts-stopped",(Se=ve||(ve={})).WORD="word",Se.SENTENCE="sentence";class we{constructor(e,t,r){this.label=be,this.type=e,this.data=t,this.id=r||function(e){if(a.randomUUID&&!e)return a.randomUUID();const t=(e=e||{}).random??e.rng?.()??function(){if(!i){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");i=crypto.getRandomValues.bind(crypto)}return i(o)}();if(t.length<16)throw new Error("Random bytes length must be >= 16");return t[6]=15&t[6]|64,t[8]=63&t[8]|128,function(e,t=0){return(n[e[t+0]]+n[e[t+1]]+n[e[t+2]]+n[e[t+3]]+"-"+n[e[t+4]]+n[e[t+5]]+"-"+n[e[t+6]]+n[e[t+7]]+"-"+n[e[t+8]]+n[e[t+9]]+"-"+n[e[t+10]]+n[e[t+11]]+n[e[t+12]]+n[e[t+13]]+n[e[t+14]]+n[e[t+15]]).toLowerCase()}(t)}().slice(0,8)}static clientReady(){return new we(ge.CLIENT_READY,{version:me,about:_e||{library:$.name,library_version:$.version}})}static disconnectBot(){return new we(ge.DISCONNECT_BOT,{})}static error(e,t=!1){return new we(ge.ERROR,{message:e,fatal:t})}}function Me(e,t,r){const s=r.value;return r.value=function(...e){if("ready"===this.state)return s.apply(this,e);throw new ie(`Attempt to call ${t.toString()} when transport not in ready state. Await connect() first.`)},r}function ke(e,t,r){const s=r.value,n=["authenticating","connecting","connected","ready"];return r.value=function(...e){if(n.includes(this.state))throw new oe(`Attempt to call ${t.toString()} when client already started. Please call disconnect() before starting again.`);return s.apply(this,e)},r}y(J,X),y(J,Z),y(J,pe),y(J,he),y(J,{});var Ee={};w(Ee,"MessageDispatcher",()=>xe);var Te,Ce,Be={};w(Be,"LogLevel",()=>Te),w(Be,"logger",()=>Ae),(Ce=Te||(Te={}))[Ce.NONE=0]="NONE",Ce[Ce.ERROR=1]="ERROR",Ce[Ce.WARN=2]="WARN",Ce[Ce.INFO=3]="INFO",Ce[Ce.DEBUG=4]="DEBUG";class Le{constructor(){this.level=Te.DEBUG}static getInstance(){return Le.instance||(Le.instance=new Le),Le.instance}setLevel(e){this.level=e}debug(...e){}info(...e){}warn(...e){this.level>=Te.WARN&&console.warn(...e)}error(...e){this.level>=Te.ERROR&&console.error(...e)}}const Ae=Le.getInstance();class xe{constructor(e){this._queue=new Array,this._gcInterval=void 0,this._queue=[],this._sendMethod=e}disconnect(){this.clearQueue(),clearInterval(this._gcInterval),this._gcInterval=void 0}dispatch(e,t=ge.CLIENT_MESSAGE,r=1e4){this._gcInterval||(this._gcInterval=setInterval(()=>{this._gc()},2e3));const s=new we(t,e),n=new Promise((e,t)=>{this._queue.push({message:s,timestamp:Date.now(),timeout:r,resolve:e,reject:t})});Ae.debug("[MessageDispatcher] dispatch",s);try{this._sendMethod(s)}catch(e){return Ae.error("[MessageDispatcher] Error sending message",e),Promise.reject(e)}return this._gc(),n}clearQueue(){this._queue=[]}_resolveReject(e,t=!0){const r=this._queue.find(t=>t.message.id===e.id);return r&&(t?(Ae.debug("[MessageDispatcher] Resolve",e),r.resolve(e)):(Ae.debug("[MessageDispatcher] Reject",e),r.reject(e)),this._queue=this._queue.filter(t=>t.message.id!==e.id),Ae.debug("[MessageDispatcher] Queue",this._queue)),e}resolve(e){return this._resolveReject(e,!0)}reject(e){return this._resolveReject(e,!1)}_gc(){const e=[];this._queue=this._queue.filter(t=>{const r=Date.now()-t.timestamp<t.timeout;return r||e.push(t),r}),e.forEach(e=>{e.message.type===ge.CLIENT_MESSAGE&&e.reject(new we(ge.ERROR_RESPONSE,{error:"Timed out waiting for response",msgType:e.message.data.t,data:e.message.data.d,fatal:!1}))}),Ae.debug("[MessageDispatcher] GC",this._queue)}}var Oe={};function Re(e){if("object"==typeof e&&null!==e&&Object.keys(e).includes("endpoint")){const t=e.endpoint;return"string"==typeof t||t instanceof URL||"undefined"!=typeof Request&&t instanceof Request}return!1}async function Fe(e,t){let r;return t||(t=new AbortController),new Promise((s,n)=>{(async()=>{let i;e.timeout&&(r=setTimeout(async()=>{t.abort(),n(new Error("Timed out"))},e.timeout)),"undefined"!=typeof Request&&e.endpoint instanceof Request?(i=new Request(e.endpoint,{signal:t.signal}),e.requestData&&Ae.warn("[Pipecat Client] requestData in APIRequest is ignored when endpoint is a Request object"),e.headers&&Ae.warn("[Pipecat Client] headers in APIRequest is ignored when endpoint is a Request object")):i=new Request(e.endpoint,{method:"POST",mode:"cors",headers:new Headers({"Content-Type":"application/json",...Object.fromEntries((e.headers??new Headers).entries())}),body:JSON.stringify(e.requestData),signal:t.signal}),Ae.debug(`[Pipecat Client] Fetching from ${i.url}`),fetch(i).then(e=>{if(Ae.debug(`[Pipecat Client] Received response from ${i.url}`,e),e.ok)return e.json();n(e)}).then(e=>{s(e)}).catch(e=>{Ae.error(`[Pipecat Client] Error fetching: ${e}`),n(e)}).finally(()=>{r&&clearTimeout(r)})})()})}w(Oe,"isAPIRequest",()=>Re),w(Oe,"makeRequest",()=>Fe);var Pe={};w(Pe,"Transport",()=>Ne),w(Pe,"TransportWrapper",()=>Ue);class Ne{constructor(){this._state="disconnected",this._maxMessageSize=65536}connect(e){this._abortController=new AbortController;let t=e;try{t=this._validateConnectionParams(e)}catch(e){throw new ee(`Invalid connection params: ${e.message}. Please check your connection params and try again.`)}return this._connect(t)}get startBotParams(){return this._startBotParams}set startBotParams(e){this._startBotParams="undefined"!=typeof Request&&e.endpoint instanceof Request?{...e,endpoint:e.endpoint.clone()}:e}disconnect(){return this._abortController&&this._abortController.abort(),this._disconnect()}get maxMessageSize(){return this._maxMessageSize}}class Ue{constructor(e){this._transport=e,this._proxy=new Proxy(this._transport,{get:(e,t,r)=>{if("function"==typeof e[t]){let r;switch(String(t)){case"initialize":r="Direct calls to initialize() are disabled and used internally by the PipecatClient.";break;case"initDevices":r="Direct calls to initDevices() are disabled. Please use the PipecatClient.initDevices() wrapper or let PipecatClient.connect() call it for you.";break;case"sendReadyMessage":r="Direct calls to sendReadyMessage() are disabled and used internally by the PipecatClient.";break;case"connect":r="Direct calls to connect() are disabled. Please use the PipecatClient.connect() wrapper.";break;case"disconnect":r="Direct calls to disconnect() are disabled. Please use the PipecatClient.disconnect() wrapper."}return r?()=>{throw new Error(r)}:(...r)=>e[t](...r)}return Reflect.get(e,t,r)}})}get proxy(){return this._proxy}}var Ie={};function De(){let e={library:$.name,library_version:$.version,platform_details:{}},t=null;if(window?.navigator?.userAgent)try{t=_.parse(window.navigator.userAgent)}catch(e){}return t?.browser?.name&&(e.platform_details.browser=t.browser.name),"Safari"!==t?.browser?.name||t.browser.version?t?.browser?.version&&(e.platform_details.browser_version=t.browser.version):e.platform_details.browser_version="Web View",t?.platform?.type&&(e.platform_details.platform_type=t.platform.type),t?.engine?.name&&(e.platform_details.engine=t.engine.name),t?.os&&(e.platform=t.os.name,e.platform_version=t.os.version),e}function je(e,t){return(e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length})(e)<=t}w(Ie,"learnAboutClient",()=>De),w(Ie,"messageSizeWithinLimit",()=>je);var ze=function(e,t,r,s){var n,i=arguments.length,o=i<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,r):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,r,s);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(o=(i<3?n(o):i>3?n(t,r,o):n(t,r))||o);return i>3&&o&&Object.defineProperty(t,r,o),o};function He(e){switch(e){case"in-use":return"already-in-use";case"permissions":return"blocked";case"not-found":return"not-found";case"undefined-mediadevices":return"not-supported";case"constraints":return"invalid-constraints";default:return"unknown"}}class Ge extends s{}class Ve extends Ge{constructor(e){super(),this._functionCallCallbacks={},this._botTranscriptionWarned=!1,this._llmFunctionCallWarned=!1,this._mediaState={mic:{state:"uninitialized"},cam:{state:"uninitialized"}},ye(De()),this._transport=e.transport,this._transportWrapper=new Ue(this._transport),this._disconnectOnBotDisconnect=e.disconnectOnBotDisconnect??!0;const t={...e.callbacks,onMessageError:t=>{e?.callbacks?.onMessageError?.(t),this.emit(le.MessageError,t)},onError:t=>{e?.callbacks?.onError?.(t);try{this.emit(le.Error,t)}catch(r){r instanceof Error&&r.message.includes("Unhandled error")?e?.callbacks?.onError||Ae.debug("No onError callback registered to handle error",t):Ae.debug("Could not emit error",t,r)}const r=t.data;r?.fatal&&(Ae.error("Fatal error reported. Disconnecting..."),this.disconnect())},onConnected:()=>{e?.callbacks?.onConnected?.(),this.emit(le.Connected)},onDisconnected:()=>{e?.callbacks?.onDisconnected?.(),this.emit(le.Disconnected)},onTransportStateChanged:t=>{e?.callbacks?.onTransportStateChanged?.(t),this.emit(le.TransportStateChanged,t),"ready"===t&&this._flushPendingUISnapshot()},onParticipantJoined:t=>{e?.callbacks?.onParticipantJoined?.(t),this.emit(le.ParticipantConnected,t)},onParticipantLeft:t=>{e?.callbacks?.onParticipantLeft?.(t),this.emit(le.ParticipantLeft,t)},onTrackStarted:(t,r)=>{e?.callbacks?.onTrackStarted?.(t,r),this.emit(le.TrackStarted,t,r)},onTrackStopped:(t,r)=>{e?.callbacks?.onTrackStopped?.(t,r),this.emit(le.TrackStopped,t,r)},onScreenTrackStarted:(t,r)=>{e?.callbacks?.onScreenTrackStarted?.(t,r),this.emit(le.ScreenTrackStarted,t,r)},onScreenTrackStopped:(t,r)=>{e?.callbacks?.onScreenTrackStopped?.(t,r),this.emit(le.ScreenTrackStopped,t,r)},onScreenShareError:t=>{e?.callbacks?.onScreenShareError?.(t),this.emit(le.ScreenShareError,t)},onUnsupportedFeature:t=>{e?.callbacks?.onUnsupportedFeature?.(t),this.emit(le.UnsupportedFeature,t)},onAvailableCamsUpdated:t=>{e?.callbacks?.onAvailableCamsUpdated?.(t),this.emit(le.AvailableCamsUpdated,t)},onAvailableMicsUpdated:t=>{e?.callbacks?.onAvailableMicsUpdated?.(t),this.emit(le.AvailableMicsUpdated,t)},onAvailableSpeakersUpdated:t=>{e?.callbacks?.onAvailableSpeakersUpdated?.(t),this.emit(le.AvailableSpeakersUpdated,t)},onCamUpdated:t=>{t?.deviceId&&this._markDeviceGranted("cam"),e?.callbacks?.onCamUpdated?.(t),this.emit(le.CamUpdated,t)},onMicUpdated:t=>{t?.deviceId&&this._markDeviceGranted("mic"),e?.callbacks?.onMicUpdated?.(t),this.emit(le.MicUpdated,t)},onSpeakerUpdated:t=>{e?.callbacks?.onSpeakerUpdated?.(t),this.emit(le.SpeakerUpdated,t)},onDeviceError:t=>{this._classifyAndApplyDeviceError(t),e?.callbacks?.onDeviceError?.(t),this.emit(le.DeviceError,t)},onBotStarted:t=>{e?.callbacks?.onBotStarted?.(t),this.emit(le.BotStarted,t)},onBotConnected:t=>{e?.callbacks?.onBotConnected?.(t),this.emit(le.BotConnected,t)},onBotReady:t=>{e?.callbacks?.onBotReady?.(t),this.emit(le.BotReady,t)},onBotDisconnected:t=>{e?.callbacks?.onBotDisconnected?.(t),this.emit(le.BotDisconnected,t),this._disconnectOnBotDisconnect&&(Ae.info("Bot disconnected. Disconnecting client..."),this.disconnect())},onUserStartedSpeaking:()=>{e?.callbacks?.onUserStartedSpeaking?.(),this.emit(le.UserStartedSpeaking)},onUserStoppedSpeaking:()=>{e?.callbacks?.onUserStoppedSpeaking?.(),this.emit(le.UserStoppedSpeaking)},onBotStartedSpeaking:()=>{e?.callbacks?.onBotStartedSpeaking?.(),this.emit(le.BotStartedSpeaking)},onBotStoppedSpeaking:()=>{e?.callbacks?.onBotStoppedSpeaking?.(),this.emit(le.BotStoppedSpeaking)},onRemoteAudioLevel:(t,r)=>{e?.callbacks?.onRemoteAudioLevel?.(t,r),this.emit(le.RemoteAudioLevel,t,r)},onLocalAudioLevel:t=>{e?.callbacks?.onLocalAudioLevel?.(t),this.emit(le.LocalAudioLevel,t)},onUserMuteStarted:()=>{e?.callbacks?.onUserMuteStarted?.(),this.emit(le.UserMuteStarted)},onUserMuteStopped:()=>{e?.callbacks?.onUserMuteStopped?.(),this.emit(le.UserMuteStopped)},onUserTranscript:t=>{e?.callbacks?.onUserTranscript?.(t),this.emit(le.UserTranscript,t)},onBotOutput:t=>{e?.callbacks?.onBotOutput?.(t),this.emit(le.BotOutput,t)},onBotTranscript:t=>{(!!e?.callbacks?.onBotTranscript||this.listenerCount(le.BotTranscript)>0)&&!this._botTranscriptionWarned&&(Ae.warn("[Pipecat Client] Bot transcription is deprecated. Please use the onBotOutput instead."),this._botTranscriptionWarned=!0),e?.callbacks?.onBotTranscript?.(t),this.emit(le.BotTranscript,t)},onBotLlmText:t=>{e?.callbacks?.onBotLlmText?.(t),this.emit(le.BotLlmText,t)},onBotLlmStarted:()=>{e?.callbacks?.onBotLlmStarted?.(),this.emit(le.BotLlmStarted)},onBotLlmStopped:()=>{e?.callbacks?.onBotLlmStopped?.(),this.emit(le.BotLlmStopped)},onBotTtsText:t=>{e?.callbacks?.onBotTtsText?.(t),this.emit(le.BotTtsText,t)},onBotTtsStarted:()=>{e?.callbacks?.onBotTtsStarted?.(),this.emit(le.BotTtsStarted)},onBotTtsStopped:()=>{e?.callbacks?.onBotTtsStopped?.(),this.emit(le.BotTtsStopped)}};this._options={...e,callbacks:t,enableMic:e.enableMic??!0,enableCam:e.enableCam??!1,enableScreenShare:e.enableScreenShare??!1},this._initialize(),Ae.debug("[Pipecat Client] Initialized",this.version)}setLogLevel(e){Ae.setLevel(e)}async initDevices(){Ae.debug("[Pipecat Client] Initializing devices..."),this._setMediaState({mic:{state:"initializing"},cam:{state:"initializing"}});try{await this._transport.initDevices(),this._resolveLingeringInitializing({state:"uninitialized"})}catch(e){throw this._resolveLingeringInitializing({state:"error",reason:"unknown"}),e}finally{await this._enrichFromPermissionsAPI()}}_resolveLingeringInitializing(e){const t={};for(const r of["mic","cam"])"initializing"===this._mediaState[r].state&&(t[r]=e);Object.keys(t).length>0&&this._setMediaState(t)}_markDeviceGranted(e){"granted"!==this._mediaState[e].state&&this._setMediaState({[e]:{state:"granted"}})}async startBot(e){let t;this.needsInit()&&await this.initDevices(),this._transport.state="authenticating",this._transport.startBotParams=e,this._abortController=new AbortController;try{t=await Fe(e,this._abortController)}catch(e){let t,r="An unknown error occurred while starting the bot.";if(e instanceof Response){const s=await e.json();r=s.info??s.detail??e.statusText,t=e.status}else e instanceof Error&&(r=e.message);throw this._options.callbacks?.onError?.(new we(ge.ERROR_RESPONSE,{message:r,fatal:!0})),new re(r,t)}return this._transport.state="authenticated",this._options.callbacks?.onBotStarted?.(t),t}async connect(e){return e&&Re(e)?(Ae.warn("Calling connect with an API endpoint is deprecated. Use startBotAndConnect() instead."),this.startBotAndConnect(e)):new Promise((t,r)=>{(async()=>{this._connectResolve=t,this.needsInit()&&await this.initDevices();try{await this._transport.connect(e),await this._transport.sendReadyMessage()}catch(e){return this.disconnect(),void r(e)}})()})}async startBotAndConnect(e){const t=await this.startBot(e);return this.connect(t)}async disconnect(){this.stopUISnapshotStream(),await this._transport.disconnect(),this._messageDispatcher.disconnect()}_initialize(){this._transport.initialize(this._options,this.handleMessage.bind(this)),this._messageDispatcher=new xe(this._sendMessage.bind(this))}_setMediaState(e){const t={...this._mediaState,...e};this._statusEquals(t.mic,this._mediaState.mic)&&this._statusEquals(t.cam,this._mediaState.cam)||(this._mediaState=t,this._options.callbacks?.onMediaStateChanged?.(this.mediaState),this.emit(le.MediaStateUpdated,this.mediaState))}_statusEquals(e,t){return e.state===t.state&&("error"!==e.state||"error"!==t.state||e.reason===t.reason&&e.details===t.details)}_classifyAndApplyDeviceError(e){const t={state:"error",reason:He(e.type),details:e.details},r={};e.devices.includes("mic")&&(r.mic=t),e.devices.includes("cam")&&(r.cam=t),0!==Object.keys(r).length&&this._setMediaState(r)}async _enrichFromPermissionsAPI(){const e=globalThis.navigator?.permissions;if(!e?.query)return;const t=e.query.bind(e),r={};await Promise.all(["mic","cam"].map(async e=>{try{"denied"===(await t({name:"mic"===e?"microphone":"camera"})).state&&(r[e]={state:"error",reason:"blocked"})}catch{}})),Object.keys(r).length>0&&this._setMediaState(r)}_sendMessage(e){if(!je(e,this._transport.maxMessageSize)){const e=`Message data too large. Max size is ${this._transport.maxMessageSize}`;throw this._options.callbacks?.onError?.(we.error(e,!1)),new ce(e)}try{this._transport.sendMessage(e)}catch(e){throw e instanceof Error?this._options.callbacks?.onError?.(we.error(e.message,!1)):this._options.callbacks?.onError?.(we.error("Unknown error sending message",!1)),e}}get connected(){return["connected","ready"].includes(this._transport.state)}get transport(){return this._transportWrapper.proxy}get state(){return this._transport.state}get mediaState(){return{mic:{...this._mediaState.mic},cam:{...this._mediaState.cam}}}needsInit(){return!1!==this._options.enableMic&&"uninitialized"===this._mediaState.mic.state||!1!==this._options.enableCam&&"uninitialized"===this._mediaState.cam.state}get version(){return M($).version}async getAllMics(){return await this._transport.getAllMics()}async getAllCams(){return await this._transport.getAllCams()}async getAllSpeakers(){return await this._transport.getAllSpeakers()}get selectedMic(){return this._transport.selectedMic}get selectedCam(){try{return this._transport.selectedCam}catch(e){if(e instanceof ae)return this._options.callbacks?.onUnsupportedFeature?.(e),{};throw e}}get selectedSpeaker(){return this._transport.selectedSpeaker}updateMic(e){this._transport.updateMic(e)}updateCam(e){this._transport.updateCam(e)}updateSpeaker(e){this._transport.updateSpeaker(e)}enableMic(e){this._transport.enableMic(e)}get isMicEnabled(){return this._transport.isMicEnabled}enableCam(e){try{this._transport.enableCam(e)}catch(e){if(!(e instanceof ae))throw e;this._options.callbacks?.onUnsupportedFeature?.(e)}}get isCamEnabled(){return this._transport.isCamEnabled}tracks(){return this._transport.tracks()}enableScreenShare(e){try{return this._transport.enableScreenShare(e)}catch(e){if(!(e instanceof ae))throw e;this._options.callbacks?.onUnsupportedFeature?.(e)}}get isSharingScreen(){return this._transport.isSharingScreen}sendClientMessage(e,t){this._sendMessage(new we(ge.CLIENT_MESSAGE,{t:e,d:t}))}sendUIEvent(e,t){this._sendMessage(new we(ge.UI_EVENT,{event:e,payload:t}))}startUISnapshotStream(e={}){this.stopUISnapshotStream(),this._uiSnapshotStreamer=new q(e=>{"ready"===this.state?this._sendUISnapshot(e):this._pendingUISnapshot=e},e),this._uiSnapshotStreamer.start()}stopUISnapshotStream(){this._uiSnapshotStreamer?.stop(),this._uiSnapshotStreamer=void 0,this._pendingUISnapshot=void 0}_sendUISnapshot(e){this._sendMessage(new we(ge.UI_SNAPSHOT,{tree:e}))}_flushPendingUISnapshot(){if(!this._pendingUISnapshot||"ready"!==this.state)return;const e=this._pendingUISnapshot;this._pendingUISnapshot=void 0,this._sendUISnapshot(e)}cancelUIJobGroup(e,t){const r={job_id:e};void 0!==t&&(r.reason=t),this._sendMessage(new we(ge.UI_CANCEL_JOB_GROUP,r))}async sendClientRequest(e,t,r){const s={t:e,d:t};return(await this._messageDispatcher.dispatch(s,ge.CLIENT_MESSAGE,r)).data.d}registerFunctionCallHandler(e,t){this._functionCallCallbacks[e]=t}unregisterFunctionCallHandler(e){delete this._functionCallCallbacks[e]}unregisterAllFunctionCallHandlers(){this._functionCallCallbacks={}}async appendToContext(e){return Ae.warn("appendToContext() is deprecated. Use sendText() instead."),await this._sendMessage(new we(ge.APPEND_TO_CONTEXT,{role:e.role,content:e.content,run_immediately:e.run_immediately})),!0}async sendText(e,t={}){await this._sendMessage(new we(ge.SEND_TEXT,{content:e,options:t}))}disconnectBot(){this._sendMessage(new we(ge.DISCONNECT_BOT,{}))}handleMessage(e){switch(Ae.debug("[RTVI Message]",e),e.type){case ge.BOT_READY:{const t=e.data,r=t.version?t.version.split(".").map(Number):[0,0,0];Ae.debug(`[Pipecat Client] Bot is ready. Version: ${t.version}`),r[0]<2&&Ae.warn(`[Pipecat Client] Bot protocol version ${t.version} is older than this client (${me}). Compatibility issues may occur.`),this._connectResolve?.(e.data),this._options.callbacks?.onBotReady?.(e.data);break}case ge.ERROR:this._options.callbacks?.onError?.(e);break;case ge.SERVER_RESPONSE:this._messageDispatcher.resolve(e);break;case ge.ERROR_RESPONSE:{const t=this._messageDispatcher.reject(e);this._options.callbacks?.onMessageError?.(t);break}case ge.USER_STARTED_SPEAKING:this._options.callbacks?.onUserStartedSpeaking?.();break;case ge.USER_STOPPED_SPEAKING:this._options.callbacks?.onUserStoppedSpeaking?.();break;case ge.BOT_STARTED_SPEAKING:this._options.callbacks?.onBotStartedSpeaking?.();break;case ge.BOT_STOPPED_SPEAKING:this._options.callbacks?.onBotStoppedSpeaking?.();break;case ge.USER_MUTE_STARTED:this._options.callbacks?.onUserMuteStarted?.();break;case ge.USER_MUTE_STOPPED:this._options.callbacks?.onUserMuteStopped?.();break;case ge.USER_TRANSCRIPTION:{const t=e.data;this._options.callbacks?.onUserTranscript?.(t);break}case ge.USER_LLM_TEXT:{const t=e.data;this._options.callbacks?.onUserLlmText?.(t),this.emit(le.UserLlmText,t);break}case ge.BOT_OUTPUT:this._options.callbacks?.onBotOutput?.(e.data);break;case ge.BOT_TRANSCRIPTION:this._options.callbacks?.onBotTranscript?.(e.data);break;case ge.BOT_LLM_TEXT:this._options.callbacks?.onBotLlmText?.(e.data);break;case ge.BOT_LLM_STARTED:this._options.callbacks?.onBotLlmStarted?.();break;case ge.BOT_LLM_STOPPED:this._options.callbacks?.onBotLlmStopped?.();break;case ge.BOT_TTS_TEXT:this._options.callbacks?.onBotTtsText?.(e.data);break;case ge.BOT_TTS_STARTED:this._options.callbacks?.onBotTtsStarted?.();break;case ge.BOT_TTS_STOPPED:this._options.callbacks?.onBotTtsStopped?.();break;case ge.METRICS:this._options.callbacks?.onMetrics?.(e.data),this.emit(le.Metrics,e.data);break;case ge.SERVER_MESSAGE:this._options.callbacks?.onServerMessage?.(e.data),this.emit(le.ServerMessage,e.data);break;case ge.UI_COMMAND:{const t=e.data;this._options.callbacks?.onUICommand?.(t),this.emit(le.UICommand,t);break}case ge.UI_JOB_GROUP:{const t=e.data;this._options.callbacks?.onUIJobGroup?.(t),this.emit(le.UIJobGroup,t);break}case ge.LLM_FUNCTION_CALL_STARTED:{const t=e.data;this._options.callbacks?.onLLMFunctionCallStarted?.(t),this.emit(le.LLMFunctionCallStarted,t);break}case ge.LLM_FUNCTION_CALL_IN_PROGRESS:{const t=e.data;this._maybeTriggerFunctionCallCallback(t),this._options.callbacks?.onLLMFunctionCallInProgress?.(t),this.emit(le.LLMFunctionCallInProgress,t);break}case ge.LLM_FUNCTION_CALL_STOPPED:{const t=e.data;this._options.callbacks?.onLLMFunctionCallStopped?.(t),this.emit(le.LLMFunctionCallStopped,t);break}case ge.LLM_FUNCTION_CALL:{const t=e.data;this._maybeTriggerFunctionCallCallback({function_name:t.function_name,tool_call_id:t.tool_call_id,arguments:t.args}),this._options.callbacks?.onLLMFunctionCall&&(this._llmFunctionCallWarned||(Ae.warn("[Pipecat Client] onLLMFunctionCall is deprecated. Please use onLLMFunctionCallInProgress instead."),this._llmFunctionCallWarned=!0)),this._options.callbacks?.onLLMFunctionCall?.(t),this.emit(le.LLMFunctionCall,t);break}case ge.BOT_LLM_SEARCH_RESPONSE:{const t=e.data;this._options.callbacks?.onBotLlmSearchResponse?.(t),this.emit(le.BotLlmSearchResponse,t);break}default:Ae.debug("[Pipecat Client] Unrecognized message type",e.type)}}_maybeTriggerFunctionCallCallback(e){if(!e.function_name)return;const t=this._functionCallCallbacks[e.function_name];t&&t({functionName:e.function_name??"",arguments:e.arguments??{}}).then(t=>{null!=t&&this._sendMessage(new we(ge.LLM_FUNCTION_CALL_RESULT,{function_name:e.function_name,tool_call_id:e.tool_call_id,arguments:e.arguments??{},result:t}))}).catch(e=>{Ae.error("Error in function call callback",e)})}}ze([ke],Ve.prototype,"startBot",null),ze([ke],Ve.prototype,"connect",null),ze([ke],Ve.prototype,"startBotAndConnect",null),ze([Me],Ve.prototype,"sendClientMessage",null),ze([Me],Ve.prototype,"sendUIEvent",null),ze([Me],Ve.prototype,"cancelUIJobGroup",null),ze([Me],Ve.prototype,"sendClientRequest",null),ze([Me],Ve.prototype,"appendToContext",null),ze([Me],Ve.prototype,"sendText",null),ze([Me],Ve.prototype,"disconnectBot",null),y(k,E),y(k,Y),y(k,Ee),y(k,Be),y(k,Oe),y(k,Pe),y(k,Ie);export{q as A11ySnapshotStreamer,ve as AggregationType,oe as BotAlreadyStartedError,ie as BotNotReadyError,te as ConnectionTimeoutError,de as DeviceError,ne as InvalidTransportParamsError,Te as LogLevel,xe as MessageDispatcher,ce as MessageTooLargeError,Ve as PipecatClient,ee as RTVIError,le as RTVIEvent,we as RTVIMessage,ge as RTVIMessageType,be as RTVI_MESSAGE_LABEL,me as RTVI_PROTOCOL_VERSION,re as StartBotError,Ne as Transport,se as TransportStartError,K as TransportStateEnum,Ue as TransportWrapper,ae as UnsupportedFeatureError,O as findElementByRef,R as findRefForElement,Re as isAPIRequest,De as learnAboutClient,Ae as logger,Fe as makeRequest,je as messageSizeWithinLimit,G as serializeSelection,ye as setAboutClient,V as snapshotDocument};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1interface/voice-core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0-pipecat.0",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -26,7 +26,8 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@1interface/shared-core": "^0.1.0"
29
+ "@pipecat-ai/client-js": "^1.12.0",
30
+ "@1interface/shared-core": "^0.2.0-pipecat.0"
30
31
  },
31
32
  "peerDependencies": {
32
33
  "@reduxjs/toolkit": "^2.0.0",