@1interface/voice-core 0.7.1 → 0.8.1
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/browserAudioPlatform-BlQ_Ssdk.js +1 -0
- package/dist/browserAudioPlatform-DyVOp76o.cjs +1 -0
- package/dist/index.d.ts +56 -10
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/sessionHelpers-ALyIwLPk.cjs +1 -0
- package/dist/sessionHelpers-BIwU9Fpt.js +1 -0
- package/dist/useVoiceSessionCore-Bir8eqjh.cjs +1 -0
- package/dist/useVoiceSessionCore-Cwkj3eVq.js +1 -0
- package/dist/webrtc.d.ts +76 -0
- package/dist/webrtc.js +1 -0
- package/dist/webrtc.mjs +1 -0
- package/dist/ws.d.ts +168 -0
- package/dist/ws.js +1 -0
- package/dist/ws.mjs +1 -0
- package/package.json +12 -2
- package/dist/index.module-DCaqEXL5.cjs +0 -1
- package/dist/index.module-S2alA3-r.js +0 -1
package/dist/ws.d.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { AttachedDocument } from '@1interface/shared-core';
|
|
2
|
+
import { Message } from '@1interface/shared-core';
|
|
3
|
+
import { ModelContextPart } from '@1interface/shared-core';
|
|
4
|
+
import { PaymentInitPayload } from '@1interface/shared-core';
|
|
5
|
+
import { RequestDocumentsPayload } from '@1interface/shared-core';
|
|
6
|
+
import { VoiceTransport } from '@1interface/shared-core';
|
|
7
|
+
|
|
8
|
+
export declare class BrowserPcmCapture implements PcmCapture {
|
|
9
|
+
private ctx;
|
|
10
|
+
private stream;
|
|
11
|
+
private source;
|
|
12
|
+
private gain;
|
|
13
|
+
private worklet;
|
|
14
|
+
private visibilityHandler;
|
|
15
|
+
private opening;
|
|
16
|
+
private cancelled;
|
|
17
|
+
private opts;
|
|
18
|
+
private muted;
|
|
19
|
+
open(opts: PcmCaptureOpenOptions): void;
|
|
20
|
+
setMuted(muted: boolean): void;
|
|
21
|
+
close(): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export declare class BrowserPcmPlayer implements PcmPlayer {
|
|
25
|
+
private ctx;
|
|
26
|
+
private masterGain;
|
|
27
|
+
private sinkId;
|
|
28
|
+
private nextPlayTime;
|
|
29
|
+
private doneTimer;
|
|
30
|
+
private isFirstChunk;
|
|
31
|
+
private prerollProvider;
|
|
32
|
+
private activeSources;
|
|
33
|
+
setPrerollProvider(provider: (() => number) | null): void;
|
|
34
|
+
private ensureContext;
|
|
35
|
+
private applySink;
|
|
36
|
+
play(pcm: ArrayBuffer): void;
|
|
37
|
+
get remainingSeconds(): number;
|
|
38
|
+
onDrained(callback: () => void): void;
|
|
39
|
+
resetForNewSegment(): void;
|
|
40
|
+
setSinkId(deviceId: string | null): void;
|
|
41
|
+
stop(): void;
|
|
42
|
+
destroy(): void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export declare class BrowserThinkingSound implements ThinkingSound {
|
|
46
|
+
private audio;
|
|
47
|
+
private timer;
|
|
48
|
+
private pendingPlay;
|
|
49
|
+
private pendingAction;
|
|
50
|
+
private pendingStartSeconds;
|
|
51
|
+
private ensureAudio;
|
|
52
|
+
private trackUnlock;
|
|
53
|
+
unlock(): void;
|
|
54
|
+
start(remainingAudioSeconds: number): void;
|
|
55
|
+
pause(): void;
|
|
56
|
+
resume(remainingAudioSeconds?: number): void;
|
|
57
|
+
stop(): void;
|
|
58
|
+
destroy(): void;
|
|
59
|
+
private clearTimer;
|
|
60
|
+
private schedule;
|
|
61
|
+
private doPlay;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export declare function computeAdaptivePreroll(arrivals: number[]): number;
|
|
65
|
+
|
|
66
|
+
declare interface PcmCapture {
|
|
67
|
+
open(opts: PcmCaptureOpenOptions): void;
|
|
68
|
+
setMuted(muted: boolean): void;
|
|
69
|
+
close(): void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare interface PcmCaptureOpenOptions {
|
|
73
|
+
micDeviceId: string | null;
|
|
74
|
+
initialMuted: boolean;
|
|
75
|
+
onChunk: (buffer: ArrayBuffer) => void;
|
|
76
|
+
onLoadingChange?: (loading: boolean) => void;
|
|
77
|
+
onError?: (error: unknown) => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare interface PcmPlayer {
|
|
81
|
+
play(pcm: ArrayBuffer): void;
|
|
82
|
+
readonly remainingSeconds: number;
|
|
83
|
+
setPrerollProvider(provider: (() => number) | null): void;
|
|
84
|
+
onDrained(callback: () => void): void;
|
|
85
|
+
resetForNewSegment(): void;
|
|
86
|
+
setSinkId(deviceId: string | null): void;
|
|
87
|
+
stop(): void;
|
|
88
|
+
destroy(): void;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare interface ThinkingSound {
|
|
92
|
+
unlock(): void;
|
|
93
|
+
start(remainingAudioSeconds: number): void;
|
|
94
|
+
pause(): void;
|
|
95
|
+
resume(remainingAudioSeconds?: number): void;
|
|
96
|
+
stop(): void;
|
|
97
|
+
destroy(): void;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export declare const useVoiceWsProviderValue: ({ conversationId, voiceBridge, transport, assistantStartsConversation, }: VoiceWsProviderParams) => VoiceContextValue;
|
|
101
|
+
|
|
102
|
+
declare const VOICE_DISPLAY_STATES: {
|
|
103
|
+
readonly OFFLINE: "offline";
|
|
104
|
+
readonly CONNECTING: "connecting";
|
|
105
|
+
readonly READY: "ready";
|
|
106
|
+
readonly IDLE: "idle";
|
|
107
|
+
readonly LISTENING: "listening";
|
|
108
|
+
readonly MUTED: "muted";
|
|
109
|
+
readonly PROCESSING: "processing";
|
|
110
|
+
readonly SPEAKING: "speaking";
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
declare const VOICE_PIPELINE_STATUSES: {
|
|
114
|
+
readonly IDLE: "idle";
|
|
115
|
+
readonly LISTENING: "listening";
|
|
116
|
+
readonly PROCESSING: "processing";
|
|
117
|
+
readonly SPEAKING: "speaking";
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
declare interface VoiceChatBridge {
|
|
121
|
+
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
|
|
122
|
+
updateStreamingMessage: (chatMsgId: string, content: string) => void;
|
|
123
|
+
commitStreamingMessages: () => void;
|
|
124
|
+
discardStreamingMessages: () => void;
|
|
125
|
+
setVoiceSendText: (fn: ((text: string, options?: VoiceSendTextOptions) => void) | null) => void;
|
|
126
|
+
onPaymentInit?: (init: PaymentInitPayload) => void;
|
|
127
|
+
onRequestDocuments?: (payload: RequestDocumentsPayload) => void;
|
|
128
|
+
onConversationTitle?: (title: string) => void;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
declare interface VoiceContextValue {
|
|
132
|
+
displayState: VoiceDisplayState;
|
|
133
|
+
pipelineStatus: VoicePipelineStatus;
|
|
134
|
+
isAgentWorking: boolean;
|
|
135
|
+
enterVoiceMode: () => Promise<boolean>;
|
|
136
|
+
exitVoiceMode: () => void;
|
|
137
|
+
toggleMute: () => void;
|
|
138
|
+
sendText: (text: string, options?: VoiceSendTextOptions) => void;
|
|
139
|
+
muted: boolean;
|
|
140
|
+
serverMuted: boolean;
|
|
141
|
+
sessionEndedSignal: number;
|
|
142
|
+
setInputDevice: (deviceId: string) => void;
|
|
143
|
+
setOutputDevice: (deviceId: string) => void;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
declare type VoiceDisplayState = (typeof VOICE_DISPLAY_STATES)[keyof typeof VOICE_DISPLAY_STATES];
|
|
147
|
+
|
|
148
|
+
declare type VoicePipelineStatus = (typeof VOICE_PIPELINE_STATUSES)[keyof typeof VOICE_PIPELINE_STATUSES];
|
|
149
|
+
|
|
150
|
+
declare interface VoiceProviderBaseParams {
|
|
151
|
+
conversationId: string | null;
|
|
152
|
+
voiceBridge: VoiceChatBridge;
|
|
153
|
+
assistantStartsConversation: boolean;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
declare interface VoiceSendTextOptions {
|
|
157
|
+
modelContext?: ModelContextPart[];
|
|
158
|
+
documents?: AttachedDocument[];
|
|
159
|
+
messageType?: string[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export declare interface VoiceWsProviderParams extends VoiceProviderBaseParams {
|
|
163
|
+
transport: VoiceWsTransport;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
declare type VoiceWsTransport = Exclude<VoiceTransport, 'pipecat_webrtc'>;
|
|
167
|
+
|
|
168
|
+
export { }
|
package/dist/ws.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./sessionHelpers-ALyIwLPk.cjs"),t=require("react"),n=require("react-redux"),r=require("./browserAudioPlatform-DyVOp76o.cjs"),s=require("@1interface/shared-core"),i=require("./useVoiceSessionCore-Bir8eqjh.cjs"),c="audio-recorder",o=new Set([1006,1011,1012,1013,1014]),a="Token expired",u="stop_playback",l=`\nconst TARGET_RATE = ${e.VOICE_SAMPLE_RATE};\nconst CHUNK_SAMPLES = 2048;\n\nclass RecorderProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.pending = new Int16Array(CHUNK_SAMPLES);\n this.filled = 0;\n // Fractional read position carried across blocks so resampling has no seams.\n this.phase = 0;\n this.port.onmessage = (e) => {\n if (e.data && e.data.type === 'reset') this.filled = 0;\n };\n }\n\n resample(samples) {\n const step = sampleRate / TARGET_RATE;\n const out = [];\n let pos = this.phase;\n while (pos < samples.length) {\n const lo = Math.floor(pos);\n const frac = pos - lo;\n const hi = lo + 1 < samples.length ? samples[lo + 1] : samples[lo];\n out.push(samples[lo] * (1 - frac) + hi * frac);\n pos += step;\n }\n this.phase = pos - samples.length;\n return out;\n }\n\n process(inputs) {\n const channel = inputs[0] && inputs[0][0];\n if (!channel || channel.length === 0) return true;\n const frame = sampleRate === TARGET_RATE ? channel : this.resample(channel);\n for (let i = 0; i < frame.length; i++) {\n const s = Math.max(-1, Math.min(1, frame[i]));\n this.pending[this.filled++] = s < 0 ? s * 32768 : s * 32767;\n if (this.filled === CHUNK_SAMPLES) {\n const buffer = this.pending.buffer.slice(0);\n this.port.postMessage({ type: 'chunk', buffer }, [buffer]);\n this.filled = 0;\n }\n }\n return true;\n }\n}\n\nregisterProcessor('${c}', RecorderProcessor);\n`;let d=null;const h="reset";class p{ctx=null;stream=null;source=null;gain=null;worklet=null;visibilityHandler=null;opening=!1;cancelled=!1;opts=null;muted=!1;open(t){this.opening||this.ctx||(this.cancelled=!1,this.opening=!0,this.opts=t,this.muted=Boolean(t.initialMuted),t.onLoadingChange?.(!0),(async()=>{let n=null,r=null,i=null,o=null,a=null;try{try{n=new AudioContext({sampleRate:e.VOICE_SAMPLE_RATE})}catch{n=new AudioContext}if(this.cancelled)return void await n.close().catch(()=>{});if(await n.audioWorklet.addModule((d||(d=URL.createObjectURL(new Blob([l],{type:"text/javascript"}))),d)),this.cancelled)return void await n.close().catch(()=>{});if(r=await navigator.mediaDevices.getUserMedia({audio:{...t.micDeviceId?{deviceId:{exact:t.micDeviceId}}:{},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!1,channelCount:1,sampleRate:e.VOICE_SAMPLE_RATE,echoCancellationType:{ideal:"system"}}}),this.cancelled)return r.getTracks().forEach(e=>e.stop()),void await n.close().catch(()=>{});if(i=n.createMediaStreamSource(r),o=n.createGain(),o.gain.setValueAtTime(this.muted?0:1,n.currentTime),a=new AudioWorkletNode(n,c),a.port.onmessage=e=>{if(this.cancelled)return;const t=e.data;"chunk"===t?.type&&t.buffer instanceof ArrayBuffer&&this.opts?.onChunk(t.buffer)},i.connect(o).connect(a).connect(n.destination),"suspended"===n.state&&await n.resume().catch(()=>{}),this.cancelled)return a.disconnect(),o.disconnect(),i.disconnect(),r.getTracks().forEach(e=>e.stop()),void await n.close().catch(()=>{});this.ctx=n,this.stream=r,this.source=i,this.gain=o,this.worklet=a;const s=()=>{"visible"===document.visibilityState&&"suspended"===n.state&&n.resume().catch(()=>{})};document.addEventListener("visibilitychange",s),this.visibilityHandler=s,this.opts?.onLoadingChange?.(!1)}catch(e){s.logger.error({message:"Mic capture failed",api_name:"voice-mic",error_message:e instanceof Error?e.message:String(e)}),n?.close().catch(()=>{}),r?.getTracks().forEach(e=>e.stop()),a?.disconnect(),o?.disconnect(),i?.disconnect(),this.cancelled||(this.opts?.onError?.(e),this.opts?.onLoadingChange?.(!1))}finally{this.opening=!1}})())}setMuted(e){this.muted=e;const t=this.ctx,n=this.gain;t&&n&&(n.gain.setValueAtTime(e?0:1,t.currentTime),e&&this.worklet?.port.postMessage({type:h}))}close(){this.cancelled=!0,this.worklet?.port.postMessage({type:h}),this.worklet?.disconnect(),this.gain?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.ctx?.close().catch(()=>{}),this.ctx=null,this.stream=null,this.source=null,this.gain=null,this.worklet=null,this.opts=null}}function g(e){if(e.length<5)return.2;let t=0,n=0;for(let r=1;r<e.length;r++){const s=e[r]-e[r-1];t+=s,s>n&&(n=s)}return Math.min(.5,Math.max(.1,(n-t/(e.length-1))/1e3))}class S{ctx=null;masterGain=null;sinkId=null;nextPlayTime=0;doneTimer=null;isFirstChunk=!0;prerollProvider=null;activeSources=new Set;setPrerollProvider(e){this.prerollProvider=e}ensureContext(){if(!this.ctx){try{this.ctx=new AudioContext({sampleRate:e.VOICE_SAMPLE_RATE})}catch{this.ctx=new AudioContext}this.masterGain=this.ctx.createGain(),this.masterGain.connect(this.ctx.destination),this.sinkId&&this.applySink(this.ctx,this.sinkId)}return this.ctx}applySink(e,t){"function"==typeof e.setSinkId&&e.setSinkId(t).catch(e=>{s.logger.warn({message:"Voice speaker switch failed",api_name:"voice-audio",error_message:e instanceof Error?e.message:String(e)})})}play(t){const n=this.ensureContext();"suspended"===n.state&&n.resume().catch(()=>{});const r=new Int16Array(t),s=new Float32Array(r.length);for(let e=0;e<r.length;e++)s[e]=r[e]/32768;const i=n.createBuffer(1,s.length,e.VOICE_SAMPLE_RATE);i.getChannelData(0).set(s);const c=n.createBufferSource();c.buffer=i,c.connect(this.masterGain),this.activeSources.add(c),c.onended=()=>this.activeSources.delete(c);const o=n.currentTime;let a=Math.max(o,this.nextPlayTime);if(this.isFirstChunk){this.isFirstChunk=!1;const e=this.prerollProvider?this.prerollProvider():.2;a=Math.max(a,o+e)}c.start(a),this.nextPlayTime=a+i.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}setSinkId(e){this.sinkId=e||null,this.ctx&&this.applySink(this.ctx,this.sinkId??"")}stop(){this.doneTimer&&(clearTimeout(this.doneTimer),this.doneTimer=null);for(const e of this.activeSources)try{e.stop()}catch{}this.activeSources.clear(),this.nextPlayTime=0,this.isFirstChunk=!0}destroy(){this.stop(),this.ctx&&(this.ctx.close().catch(()=>{}),this.ctx=null,this.masterGain=null)}}class m{audio=null;timer=null;pendingPlay=null;pendingAction=null;pendingStartSeconds=0;ensureAudio(){if(!this.audio){const e=r.takePrimedChime();this.audio=e?.audio??r.createChimeElement(),e?.settled&&this.trackUnlock(e.settled)}return this.audio}trackUnlock(e){this.pendingPlay=e,e.then(()=>{this.pendingPlay=null;const e=this.pendingAction;this.pendingAction=null,"start"===e&&this.schedule(this.pendingStartSeconds)})}unlock(){const e=this.ensureAudio();if(this.pendingPlay||!e.paused)return;const t=r.unlockAudioElement(e);t&&this.trackUnlock(t)}start(e){if(this.ensureAudio(),this.pendingPlay)return this.pendingAction="start",void(this.pendingStartSeconds=e);this.timer||this.audio&&!this.audio.paused||(this.stop(),this.schedule(e))}pause(){this.clearTimer(),this.pendingPlay?this.pendingAction="pause":this.audio&&!this.audio.paused&&this.audio.pause()}resume(e=0){this.audio&&this.schedule(e)}stop(){this.clearTimer(),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)}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}schedule(e){this.clearTimer();const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this.doPlay()},t)}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={...r.browserAudioPlatform,createPcmCapture:()=>new p,createPcmPlayer:()=>new S,createThinkingSound:()=>new m},f="voice-ws",T=1e3;exports.BrowserPcmCapture=p,exports.BrowserPcmPlayer=S,exports.BrowserThinkingSound=m,exports.computeAdaptivePreroll=g,exports.useVoiceWsProviderValue=({conversationId:c,voiceBridge:l,transport:d,assistantStartsConversation:h})=>{const p=function(c,l,d,h){const p=n.useDispatch(),S=n.useStore(),m=(e=>e===r.browserAudioPlatform?E:e)(e.useAudioPlatform()),_=t.useRef(m);t.useEffect(()=>{_.current=m});const C=n.useSelector(e=>e.auth.accessToken),I=t.useRef(!1),k=t.useRef(()=>{}),{bridgeRef:P,botTurnMsgIdRef:A,liveSegmentsRef:v,startResponseTimer:R,clearIndicator:y,sharedDeps:N,commitBotTurn:O,discardBotTurn:b,openBotTurnIfNeeded:w,ingestBotSegment:x,routeServerMessage:M}=i.useVoiceSessionCore(c,l,{apiName:f,onClearStatus:()=>k.current()}),V=t.useRef(null),L=t.useRef(null),D=t.useRef(null),W=t.useRef(null),U=t.useRef(0),G=t.useRef(0),B=t.useRef(!1),H=t.useRef(!0),F=t.useRef(null),K=t.useRef(null),j=t.useRef(null),q=t.useRef(null),J=t.useRef(0),X=t.useRef(0),Y=t.useRef(0),$=t.useRef(null),Z=t.useRef(0),z=t.useRef(null),Q=t.useRef(null),ee=t.useRef(0),te=t.useRef(!1),ne=t.useRef(null),re=t.useRef(null),se=t.useRef(!1),ie=t.useRef([]),ce=t.useRef(null),oe=t.useRef(!1),ae=t.useRef(null),ue=t.useRef(!1),le=e=>{e.current&&(clearTimeout(e.current),e.current=null)},de=()=>{se.current=!0,re.current&&(re.current.userSpokeSince=!0)},he=t.useCallback(()=>{const e=A.current;e&&(re.current={id:e,at:Date.now(),userSpokeSince:se.current}),O()},[A,O]),pe=t.useCallback(()=>{le(ae),S.getState().voice.serverMuted&&p(e.setServerMuted(!1))},[p,S]),ge=t.useCallback(async t=>{try{const n=await navigator.mediaDevices.enumerateDevices();if(t!==U.current)return;const r=e=>({deviceId:e.deviceId,label:e.label});p(e.setMicrophones(n.filter(e=>"audioinput"===e.kind).map(r))),p(e.setSpeakers(n.filter(e=>"audiooutput"===e.kind).map(r)))}catch(e){s.logger.warn({message:"Voice device enumeration failed",api_name:f,conversation_id:c??void 0,error_message:e instanceof Error?e.message:String(e)})}},[p,c]),Se=t.useCallback(()=>{L.current?.close(),L.current=null},[]),me=t.useCallback(e=>{Se();const t=_.current.createPcmCapture;if(!t)return;const n=t.call(_.current);L.current=n,n.open({micDeviceId:S.getState().voice.selectedMicId||null,initialMuted:!H.current,onChunk:t=>{const n=V.current;e===U.current&&n&&n.readyState===WebSocket.OPEN&&n.send(t)},onError:t=>{e===U.current&&(s.logger.error({message:"Voice WS mic capture failed",api_name:f,conversation_id:c??void 0,error_message:t instanceof Error?t.message:String(t)}),s.showErrorToast("Microphone could not be started. Please check your input device."))}})},[Se,S,c]),Ee=t.useCallback(()=>{le(Q),ee.current+=1,te.current=!0,D.current?.stop()},[]),fe=t.useCallback(()=>{W.current?.stop()},[]);t.useEffect(()=>{k.current=()=>{I.current=!1,ne.current=null,fe(),y(s.INDICATOR_TIMER_ACTIONS.KEEP)}},[fe,y]);const Te=t.useCallback(t=>{const n=D.current,r=++ee.current,s=()=>{t===U.current&&r===ee.current&&(le(Q),S.getState().voice.pipelineStatus===e.VOICE_PIPELINE_STATUSES.SPEAKING&&p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.IDLE)),I.current&&(p(e.setIsAgentWorking(!0)),p(e.setStatusText(ne.current)),W.current?.resume()),ue.current||(ue.current=!0,h&&pe()))};n?(le(Q),Q.current=setTimeout(s,1e3*n.remainingSeconds+5e3),n.onDrained(s)):s()},[p,S,h,pe]),_e=t.useCallback(()=>le(F),[]),Ce=t.useCallback(()=>{K.current&&(clearInterval(K.current),K.current=null)},[]),Ie=t.useCallback(t=>{_e(),Ce(),le(z),le(ae),Ee(),fe(),Se(),V.current=null,B.current=!1,I.current=!1,ne.current=null,re.current=null,se.current=!1,Z.current=0,ie.current=[],te.current=!1,p(e.setMicrophones([])),p(e.setSpeakers([])),p(e.setListeningEnabled(!1)),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.IDLE)),p(e.setConnectionStatus(e.VOICE_CONNECTION_STATUSES.DISCONNECTED)),p(e.setInterimTranscript(null)),p(e.setServerMuted(!1)),t?O():b(),y(s.INDICATOR_TIMER_ACTIONS.CANCEL)},[p,_e,Ce,Ee,fe,Se,O,b,y]),ke=t.useRef(async()=>{}),Pe=t.useRef(()=>{}),Ae=t.useCallback((t,n,r,i)=>{if(t!==U.current)return;const u=$.current;$.current=null,s.logger.info({message:"Voice WS closed",api_name:f,conversation_id:c??void 0,code:n,reason:r||void 0,socket_opened:i,drop_outcome:u??"transient"}),U.current+=1,Ie(!0);const l=G.current;if(1008===n||"Idle timeout"===r||"terminal"===u)return void p(e.signalSessionEnded());const d=X.current<e.VOICE_MAX_AUTH_REFRESHES&&null!=c;if((!i||"auth"===u||r===a)&&(d||"auth"===u||r===a))return d?(X.current+=1,void(async()=>{let t=!1;try{t=!!await(s.getTokenRefreshHandler()?.())}catch{}l===G.current&&(t?ke.current():(s.logger.warn({message:"Voice WS token refresh failed — no reconnect",api_name:f,conversation_id:c??void 0}),s.showErrorToast(e.VOICE_CONNECT_ERROR_MESSAGE),p(e.signalSessionEnded())))})()):(s.logger.warn({message:"Voice WS auth refresh budget exhausted — giving up",api_name:f,conversation_id:c??void 0}),s.showErrorToast(e.VOICE_CONNECT_ERROR_MESSAGE),void p(e.signalSessionEnded()));if("retry"!==u&&i&&!o.has(n)||null==c)p(e.signalSessionEnded());else{if(J.current>=e.VOICE_MAX_AUTO_RECONNECTS)return s.logger.warn({message:"Voice WS auto-reconnect cap reached — giving up",api_name:f,conversation_id:c??void 0,reconnect_attempts:J.current}),s.showErrorToast("Voice connection lost. Please try again."),void p(e.signalSessionEnded());J.current+=1,s.logger.info({message:"Voice WS scheduling auto-reconnect",api_name:f,conversation_id:c??void 0,reconnect_attempts:J.current,delay_ms:e.VOICE_RECONNECT_DELAY_MS}),le(q),q.current=setTimeout(()=>{q.current=null,ke.current()},e.VOICE_RECONNECT_DELAY_MS)}},[p,Ie,c]),ve=t.useCallback((e,t)=>{if(e!==U.current||te.current)return;const n=ie.current;n.push(Date.now()),n.length>30&&n.shift(),D.current?.play(t)},[]),Re=t.useCallback((t,n)=>{if(t!==U.current)return;const r=n.data??{};switch(n.type){case"tts_start":Z.current=Date.now(),le(Q),ee.current+=1,se.current=!1,te.current=!1,ie.current=[],W.current?.pause(),D.current?.resetForNewSegment(),w(),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.SPEAKING)),y(I.current?s.INDICATOR_TIMER_ACTIONS.KEEP:s.INDICATOR_TIMER_ACTIONS.FINALIZE),ae.current&&(le(ae),ae.current=setTimeout(()=>{ae.current=null,t===U.current&&pe()},6e4));break;case"text_delta":{const e="string"==typeof r.token?r.token:"";if(!e)break;w(),x(i.foldRealtimeBotOutput(v.current,e));break}case"tts_end":{const n=!0===r.cancelled;if(s.logger.debug({message:"Voice WS tts_end",api_name:f,conversation_id:c??void 0,cancelled:n}),ce.current=g(ie.current),he(),n){Ee(),S.getState().voice.pipelineStatus===e.VOICE_PIPELINE_STATUSES.SPEAKING&&p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.IDLE));break}Te(t);break}case"stt_result":{const t="string"==typeof r.text?r.text.trim():"";if(!t)break;p(e.setInterimTranscript(null));const n=e.makeUserMessage(t),s=re.current,i=s&&!s.userSpokeSince&&Date.now()-s.at<=5e3?s.id:null;P.current.setMessages(e=>{const t=i?e.findIndex(e=>e.id===i):-1;return-1===t?[...e,n]:[...e.slice(0,t),n,...e.slice(t)]});break}case"speech_started":{if(Date.now()-Z.current<500)break;const n=V.current;n&&n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({type:u})),le(Q),ee.current+=1,le(z),z.current=setTimeout(()=>{z.current=null,t===U.current&&Ee()},400),he(),de(),W.current?.stop(),p(e.setInterimTranscript(null)),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.LISTENING)),I.current||y(s.INDICATOR_TIMER_ACTIONS.KEEP);break}case"speech_stopped":if(de(),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.PROCESSING)),I.current)break;p(e.setIsAgentWorking(!0)),p(e.setStatusText(null)),R();break;case"error":{const t="string"==typeof r.message?r.message:"Voice error";if(s.handleSharedEvent({kind:"error",error:t},N),k.current(),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.IDLE)),y(s.INDICATOR_TIMER_ACTIONS.CANCEL),e.VOICE_AUTH_ERROR_PATTERNS.some(e=>e.test(t)))$.current="auth";else{if(!e.VOICE_TERMINAL_ERROR_PATTERNS.some(e=>e.test(t)))break;$.current="terminal"}s.logger.warn({message:"Voice WS fatal error — closing socket",api_name:f,conversation_id:c??void 0,drop_outcome:$.current}),V.current?.close(T);break}case"pong":j.current=null,J.current=0,X.current=0,Y.current=0;break;case e.VOICE_SERVER_MSG_TYPES.STATUS_UPDATE:I.current=!0,ne.current="string"==typeof r.text?r.text:null,M(n),W.current?.start(D.current?.remainingSeconds??0);break;default:M(n)}},[p,S,c,w,y,x,v,he,Ee,Te,P,R,N,M,pe]),ye=t.useCallback((e,t)=>{Ce(),j.current=null,K.current=setInterval(()=>{if(e!==U.current||t.readyState!==WebSocket.OPEN)return void Ce();const n=j.current;if(null!==n&&Date.now()-n>3e4)return s.logger.warn({message:"Voice WS pong watchdog tripped — forcing reconnect",api_name:f,conversation_id:c??void 0}),Ce(),$.current="retry",t.close(T),void Ae(e,T,"watchdog",!0);null===n&&(j.current=Date.now()),t.send(JSON.stringify({type:"ping"}))},2e4)},[Ce,Ae,c]),Ne=t.useCallback(()=>{const e=W.current??_.current.createThinkingSound?.()??null;W.current=e,e?.unlock()},[]),Oe=t.useCallback(async()=>{if(V.current||B.current)return;if(!c)return;const t=_.current;if(!t.createPcmCapture||!t.createPcmPlayer)return s.logger.error({message:"Voice WS transport unsupported on this platform (no PCM seams)",api_name:f,conversation_id:c,transport:d}),s.showErrorToast(e.VOICE_CONNECT_ERROR_MESSAGE),void p(e.signalSessionEnded());if(B.current=!0,s.logger.info({message:"Voice WS connecting",api_name:f,conversation_id:c,transport:d,assistant_starts:h}),s.isTokenAboutToExpire(s.readTokenExpiresAt())&&Y.current<e.VOICE_MAX_AUTH_REFRESHES){Y.current+=1;const e=G.current;try{await Promise.resolve(s.getTokenRefreshHandler()?.())}catch{}if(e!==G.current)return}const n=++U.current;let r;$.current=null,ue.current=!1,p(e.setConnectionStatus(e.VOICE_CONNECTION_STATUSES.CONNECTING));try{r=new WebSocket(function(e,t){const n=t===s.VOICE_TRANSPORTS.PIPECAT_WS?s.API_ENDPOINTS.CONVERSATION_PIPECAT_WS(e):s.API_ENDPOINTS.CONVERSATION_STREAM(e),r="undefined"!=typeof window?window.location?.origin:void 0,i=new URL(n,r);i.protocol="https:"===i.protocol?"wss:":"ws:";const c=s.readAccessToken();c&&i.searchParams.append("access_token",c);const o=function(){for(const[e,t]of Object.entries(s.getCustomHeaders()))if("x-client-id"===e.toLowerCase()&&t)return t;return null}();return o&&i.searchParams.append("client_id",o),i.toString()}(c,d))}catch(t){return s.logger.error({message:"Voice WS could not open socket",api_name:f,conversation_id:c,error_message:t instanceof Error?t.message:String(t)}),s.showErrorToast(e.VOICE_CONNECT_ERROR_MESSAGE),p(e.signalSessionEnded()),void Ie(!1)}r.binaryType="arraybuffer",V.current=r,Ne();const i=D.current??t.createPcmPlayer();D.current=i,i.setPrerollProvider(()=>ce.current??.2),i.setSinkId(S.getState().voice.selectedSpeakerId||null);let o=!1,a=!1;_e(),F.current=setTimeout(()=>{n===U.current&&(s.logger.warn({message:"Voice WS connect timed out",api_name:f,conversation_id:c}),s.showErrorToast("Voice connection timed out. Please try again."),p(e.signalSessionEnded()),Pe.current())},e.VOICE_CONNECT_TIMEOUT_MS),r.onopen=()=>{if(n!==U.current)return;o=!0,_e(),s.logger.info({message:"Voice WS connected",api_name:f,conversation_id:c,transport:d}),p(e.setConnectionStatus(e.VOICE_CONNECTION_STATUSES.CONNECTED)),p(e.setListeningEnabled(!0)),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.IDLE)),ie.current=[];const t=h&&!oe.current;t&&(H.current=!1),me(n),ge(n),ye(n,r),t&&(oe.current=!0,r.send(JSON.stringify({type:"start_conversation"})),p(e.setServerMuted(!0)),L.current?.setMuted(!0),p(e.setIsAgentWorking(!0)),R(),le(ae),ae.current=setTimeout(()=>{ae.current=null,n===U.current&&(s.logger.warn({message:"Voice WS greeting hold released by safety timer",api_name:f,conversation_id:c}),pe())},1e4))},r.onmessage=e=>{if(n!==U.current)return;if(e.data instanceof ArrayBuffer)return void ve(n,e.data);if("string"!=typeof e.data)return;let t=null;try{t=JSON.parse(e.data)}catch{return}t&&"string"==typeof t.type&&Re(n,t)},r.onerror=()=>{n===U.current&&s.logger.warn({message:"Voice WS socket error",api_name:f,conversation_id:c,socket_opened:o})},r.onclose=e=>{a||(a=!0,Ae(n,e.code,e.reason,o))}},[c,d,S,p,h,Ie,_e,Ne,me,ge,ye,R,pe,ve,Re,Ae]),be=t.useCallback((t=!0)=>{s.logger.info({message:"Voice WS disconnect (intentional teardown)",api_name:f,conversation_id:c??void 0,commit_turn:t}),G.current+=1,U.current+=1,Y.current=0,le(q),J.current=0,X.current=0,$.current=null,oe.current=!1,H.current=!0,p(e.setMuted(!1));const n=V.current;!n||n.readyState!==WebSocket.CONNECTING&&n.readyState!==WebSocket.OPEN||n.close(T),Ie(t)},[p,Ie,c]),we=t.useCallback(e=>{H.current=e,L.current?.setMuted(!e)},[]),xe=t.useCallback(t=>{p(e.setSelectedMicId(t)),V.current&&L.current&&me(U.current)},[p,me]),Me=t.useCallback(t=>{p(e.setSelectedSpeakerId(t)),D.current?.setSinkId(t||null)},[p]),Ve=t.useCallback((t,n)=>{const r=V.current;if(!r||r.readyState!==WebSocket.OPEN)return;const i=n?.modelContext;s.logger.info({message:"Voice WS text_message",api_name:f,conversation_id:c??void 0,has_model_context:Boolean(i?.length)}),r.send(JSON.stringify({type:u})),Ee(),fe(),A.current&&he(),de(),r.send(JSON.stringify({type:"text_message",text:t,...i?.length?{model_context:i}:{}})),P.current.setMessages(r=>[...r,e.makeUserMessage(t,void 0,n?.documents,n?.messageType)]),p(e.setIsAgentWorking(!0)),p(e.setStatusText(null)),R(),p(e.setPipelineStatus(e.VOICE_PIPELINE_STATUSES.PROCESSING))},[p,R,he,Ee,fe,A,P,c]);t.useEffect(()=>{Pe.current=be},[be]),t.useEffect(()=>{ke.current=Oe},[Oe]);const Le=t.useRef(c),De=t.useRef(!1);t.useEffect(()=>{const e=Le.current;if(Le.current=c,e===c)return;const t=B.current;t&&(De.current=!0),t&&be(!1),De.current&&null!=c&&(De.current=!1,Oe())},[c,be,Oe]);const We=t.useRef(C);return t.useEffect(()=>{const e=We.current;We.current=C,e&&!C&&B.current&&be(!1)},[C,be]),t.useEffect(()=>()=>{Pe.current(),D.current?.destroy(),D.current=null,W.current?.destroy(),W.current=null},[]),{connect:Oe,disconnect:be,sendText:Ve,setMicEnabled:we,setInputDevice:xe,setOutputDevice:Me,primeAudio:Ne}}(c,l,d,h);return e.useVoiceContextValue(p,{voiceBridge:l})};
|
package/dist/ws.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,u as t,g as n,s as r,a as s,b as i,c,V as o,d as a,e as u,f as l,n as d,o as h,v as p,p as m,q as g,B as f,k as S,l as v,h as y,i as k,m as _,t as T,w as P,x as w,y as E,z as x}from"./sessionHelpers-BIwU9Fpt.js";import{useRef as b,useEffect as A,useCallback as C}from"react";import{useDispatch as I,useStore as N,useSelector as M}from"react-redux";import{c as W,u as V,t as D,b as R}from"./browserAudioPlatform-BlQ_Ssdk.js";import{logger as O,VOICE_TRANSPORTS as L,API_ENDPOINTS as G,readAccessToken as B,getCustomHeaders as U,showErrorToast as F,INDICATOR_TIMER_ACTIONS as H,getTokenRefreshHandler as K,handleSharedEvent as j,isTokenAboutToExpire as J,readTokenExpiresAt as $}from"@1interface/shared-core";import{u as q,f as z}from"./useVoiceSessionCore-Cwkj3eVq.js";const Z="audio-recorder",Q=new Set([1006,1011,1012,1013,1014]),X="Token expired",Y="stop_playback",ee=`\nconst TARGET_RATE = ${e};\nconst CHUNK_SAMPLES = 2048;\n\nclass RecorderProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.pending = new Int16Array(CHUNK_SAMPLES);\n this.filled = 0;\n // Fractional read position carried across blocks so resampling has no seams.\n this.phase = 0;\n this.port.onmessage = (e) => {\n if (e.data && e.data.type === 'reset') this.filled = 0;\n };\n }\n\n resample(samples) {\n const step = sampleRate / TARGET_RATE;\n const out = [];\n let pos = this.phase;\n while (pos < samples.length) {\n const lo = Math.floor(pos);\n const frac = pos - lo;\n const hi = lo + 1 < samples.length ? samples[lo + 1] : samples[lo];\n out.push(samples[lo] * (1 - frac) + hi * frac);\n pos += step;\n }\n this.phase = pos - samples.length;\n return out;\n }\n\n process(inputs) {\n const channel = inputs[0] && inputs[0][0];\n if (!channel || channel.length === 0) return true;\n const frame = sampleRate === TARGET_RATE ? channel : this.resample(channel);\n for (let i = 0; i < frame.length; i++) {\n const s = Math.max(-1, Math.min(1, frame[i]));\n this.pending[this.filled++] = s < 0 ? s * 32768 : s * 32767;\n if (this.filled === CHUNK_SAMPLES) {\n const buffer = this.pending.buffer.slice(0);\n this.port.postMessage({ type: 'chunk', buffer }, [buffer]);\n this.filled = 0;\n }\n }\n return true;\n }\n}\n\nregisterProcessor('${Z}', RecorderProcessor);\n`;let te=null;const ne="reset";class re{ctx=null;stream=null;source=null;gain=null;worklet=null;visibilityHandler=null;opening=!1;cancelled=!1;opts=null;muted=!1;open(t){this.opening||this.ctx||(this.cancelled=!1,this.opening=!0,this.opts=t,this.muted=Boolean(t.initialMuted),t.onLoadingChange?.(!0),(async()=>{let n=null,r=null,s=null,i=null,c=null;try{try{n=new AudioContext({sampleRate:e})}catch{n=new AudioContext}if(this.cancelled)return void await n.close().catch(()=>{});if(await n.audioWorklet.addModule((te||(te=URL.createObjectURL(new Blob([ee],{type:"text/javascript"}))),te)),this.cancelled)return void await n.close().catch(()=>{});if(r=await navigator.mediaDevices.getUserMedia({audio:{...t.micDeviceId?{deviceId:{exact:t.micDeviceId}}:{},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!1,channelCount:1,sampleRate:e,echoCancellationType:{ideal:"system"}}}),this.cancelled)return r.getTracks().forEach(e=>e.stop()),void await n.close().catch(()=>{});if(s=n.createMediaStreamSource(r),i=n.createGain(),i.gain.setValueAtTime(this.muted?0:1,n.currentTime),c=new AudioWorkletNode(n,Z),c.port.onmessage=e=>{if(this.cancelled)return;const t=e.data;"chunk"===t?.type&&t.buffer instanceof ArrayBuffer&&this.opts?.onChunk(t.buffer)},s.connect(i).connect(c).connect(n.destination),"suspended"===n.state&&await n.resume().catch(()=>{}),this.cancelled)return c.disconnect(),i.disconnect(),s.disconnect(),r.getTracks().forEach(e=>e.stop()),void await n.close().catch(()=>{});this.ctx=n,this.stream=r,this.source=s,this.gain=i,this.worklet=c;const o=()=>{"visible"===document.visibilityState&&"suspended"===n.state&&n.resume().catch(()=>{})};document.addEventListener("visibilitychange",o),this.visibilityHandler=o,this.opts?.onLoadingChange?.(!1)}catch(e){O.error({message:"Mic capture failed",api_name:"voice-mic",error_message:e instanceof Error?e.message:String(e)}),n?.close().catch(()=>{}),r?.getTracks().forEach(e=>e.stop()),c?.disconnect(),i?.disconnect(),s?.disconnect(),this.cancelled||(this.opts?.onError?.(e),this.opts?.onLoadingChange?.(!1))}finally{this.opening=!1}})())}setMuted(e){this.muted=e;const t=this.ctx,n=this.gain;t&&n&&(n.gain.setValueAtTime(e?0:1,t.currentTime),e&&this.worklet?.port.postMessage({type:ne}))}close(){this.cancelled=!0,this.worklet?.port.postMessage({type:ne}),this.worklet?.disconnect(),this.gain?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.ctx?.close().catch(()=>{}),this.ctx=null,this.stream=null,this.source=null,this.gain=null,this.worklet=null,this.opts=null}}function se(e){if(e.length<5)return.2;let t=0,n=0;for(let r=1;r<e.length;r++){const s=e[r]-e[r-1];t+=s,s>n&&(n=s)}return Math.min(.5,Math.max(.1,(n-t/(e.length-1))/1e3))}class ie{ctx=null;masterGain=null;sinkId=null;nextPlayTime=0;doneTimer=null;isFirstChunk=!0;prerollProvider=null;activeSources=new Set;setPrerollProvider(e){this.prerollProvider=e}ensureContext(){if(!this.ctx){try{this.ctx=new AudioContext({sampleRate:e})}catch{this.ctx=new AudioContext}this.masterGain=this.ctx.createGain(),this.masterGain.connect(this.ctx.destination),this.sinkId&&this.applySink(this.ctx,this.sinkId)}return this.ctx}applySink(e,t){"function"==typeof e.setSinkId&&e.setSinkId(t).catch(e=>{O.warn({message:"Voice speaker switch failed",api_name:"voice-audio",error_message:e instanceof Error?e.message:String(e)})})}play(t){const n=this.ensureContext();"suspended"===n.state&&n.resume().catch(()=>{});const r=new Int16Array(t),s=new Float32Array(r.length);for(let e=0;e<r.length;e++)s[e]=r[e]/32768;const i=n.createBuffer(1,s.length,e);i.getChannelData(0).set(s);const c=n.createBufferSource();c.buffer=i,c.connect(this.masterGain),this.activeSources.add(c),c.onended=()=>this.activeSources.delete(c);const o=n.currentTime;let a=Math.max(o,this.nextPlayTime);if(this.isFirstChunk){this.isFirstChunk=!1;const e=this.prerollProvider?this.prerollProvider():.2;a=Math.max(a,o+e)}c.start(a),this.nextPlayTime=a+i.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}setSinkId(e){this.sinkId=e||null,this.ctx&&this.applySink(this.ctx,this.sinkId??"")}stop(){this.doneTimer&&(clearTimeout(this.doneTimer),this.doneTimer=null);for(const e of this.activeSources)try{e.stop()}catch{}this.activeSources.clear(),this.nextPlayTime=0,this.isFirstChunk=!0}destroy(){this.stop(),this.ctx&&(this.ctx.close().catch(()=>{}),this.ctx=null,this.masterGain=null)}}class ce{audio=null;timer=null;pendingPlay=null;pendingAction=null;pendingStartSeconds=0;ensureAudio(){if(!this.audio){const e=D();this.audio=e?.audio??W(),e?.settled&&this.trackUnlock(e.settled)}return this.audio}trackUnlock(e){this.pendingPlay=e,e.then(()=>{this.pendingPlay=null;const e=this.pendingAction;this.pendingAction=null,"start"===e&&this.schedule(this.pendingStartSeconds)})}unlock(){const e=this.ensureAudio();if(this.pendingPlay||!e.paused)return;const t=V(e);t&&this.trackUnlock(t)}start(e){if(this.ensureAudio(),this.pendingPlay)return this.pendingAction="start",void(this.pendingStartSeconds=e);this.timer||this.audio&&!this.audio.paused||(this.stop(),this.schedule(e))}pause(){this.clearTimer(),this.pendingPlay?this.pendingAction="pause":this.audio&&!this.audio.paused&&this.audio.pause()}resume(e=0){this.audio&&this.schedule(e)}stop(){this.clearTimer(),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)}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}schedule(e){this.clearTimer();const t=Math.round(1e3*e)+300;this.timer=setTimeout(()=>{this.timer=null,this.doPlay()},t)}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 oe={...R,createPcmCapture:()=>new re,createPcmPlayer:()=>new ie,createThinkingSound:()=>new ce},ae="voice-ws",ue=1e3;const le=({conversationId:e,voiceBridge:W,transport:V,assistantStartsConversation:D})=>{const Z=function(e,x,W,V){const D=I(),Z=N(),ee=(e=>e===R?oe:e)(t()),te=b(ee);A(()=>{te.current=ee});const ne=M(e=>e.auth.accessToken),re=b(!1),ie=b(()=>{}),{bridgeRef:ce,botTurnMsgIdRef:le,liveSegmentsRef:de,startResponseTimer:he,clearIndicator:pe,sharedDeps:me,commitBotTurn:ge,discardBotTurn:fe,openBotTurnIfNeeded:Se,ingestBotSegment:ve,routeServerMessage:ye}=q(e,x,{apiName:ae,onClearStatus:()=>ie.current()}),ke=b(null),_e=b(null),Te=b(null),Pe=b(null),we=b(0),Ee=b(0),xe=b(!1),be=b(!0),Ae=b(null),Ce=b(null),Ie=b(null),Ne=b(null),Me=b(0),We=b(0),Ve=b(0),De=b(null),Re=b(0),Oe=b(null),Le=b(null),Ge=b(0),Be=b(!1),Ue=b(null),Fe=b(null),He=b(!1),Ke=b([]),je=b(null),Je=b(!1),$e=b(null),qe=b(!1),ze=e=>{e.current&&(clearTimeout(e.current),e.current=null)},Ze=()=>{He.current=!0,Fe.current&&(Fe.current.userSpokeSince=!0)},Qe=C(()=>{const e=le.current;e&&(Fe.current={id:e,at:Date.now(),userSpokeSince:He.current}),ge()},[le,ge]),Xe=C(()=>{ze($e),Z.getState().voice.serverMuted&&D(n(!1))},[D,Z]),Ye=C(async t=>{try{const e=await navigator.mediaDevices.enumerateDevices();if(t!==we.current)return;const n=e=>({deviceId:e.deviceId,label:e.label});D(r(e.filter(e=>"audioinput"===e.kind).map(n))),D(s(e.filter(e=>"audiooutput"===e.kind).map(n)))}catch(t){O.warn({message:"Voice device enumeration failed",api_name:ae,conversation_id:e??void 0,error_message:t instanceof Error?t.message:String(t)})}},[D,e]),et=C(()=>{_e.current?.close(),_e.current=null},[]),tt=C(t=>{et();const n=te.current.createPcmCapture;if(!n)return;const r=n.call(te.current);_e.current=r,r.open({micDeviceId:Z.getState().voice.selectedMicId||null,initialMuted:!be.current,onChunk:e=>{const n=ke.current;t===we.current&&n&&n.readyState===WebSocket.OPEN&&n.send(e)},onError:n=>{t===we.current&&(O.error({message:"Voice WS mic capture failed",api_name:ae,conversation_id:e??void 0,error_message:n instanceof Error?n.message:String(n)}),F("Microphone could not be started. Please check your input device."))}})},[et,Z,e]),nt=C(()=>{ze(Le),Ge.current+=1,Be.current=!0,Te.current?.stop()},[]),rt=C(()=>{Pe.current?.stop()},[]);A(()=>{ie.current=()=>{re.current=!1,Ue.current=null,rt(),pe(H.KEEP)}},[rt,pe]);const st=C(e=>{const t=Te.current,n=++Ge.current,r=()=>{e===we.current&&n===Ge.current&&(ze(Le),Z.getState().voice.pipelineStatus===o.SPEAKING&&D(c(o.IDLE)),re.current&&(D(y(!0)),D(k(Ue.current)),Pe.current?.resume()),qe.current||(qe.current=!0,V&&Xe()))};t?(ze(Le),Le.current=setTimeout(r,1e3*t.remainingSeconds+5e3),t.onDrained(r)):r()},[D,Z,V,Xe]),it=C(()=>ze(Ae),[]),ct=C(()=>{Ce.current&&(clearInterval(Ce.current),Ce.current=null)},[]),ot=C(e=>{it(),ct(),ze(Oe),ze($e),nt(),rt(),et(),ke.current=null,xe.current=!1,re.current=!1,Ue.current=null,Fe.current=null,He.current=!1,Re.current=0,Ke.current=[],Be.current=!1,D(r([])),D(s([])),D(i(!1)),D(c(o.IDLE)),D(a(u.DISCONNECTED)),D(l(null)),D(n(!1)),e?ge():fe(),pe(H.CANCEL)},[D,it,ct,nt,rt,et,ge,fe,pe]),at=b(async()=>{}),ut=b(()=>{}),lt=C((t,n,r,s)=>{if(t!==we.current)return;const i=De.current;De.current=null,O.info({message:"Voice WS closed",api_name:ae,conversation_id:e??void 0,code:n,reason:r||void 0,socket_opened:s,drop_outcome:i??"transient"}),we.current+=1,ot(!0);const c=Ee.current;if(1008===n||"Idle timeout"===r||"terminal"===i)return void D(d());const o=We.current<h&&null!=e;if((!s||"auth"===i||r===X)&&(o||"auth"===i||r===X))return o?(We.current+=1,void(async()=>{let t=!1;try{t=!!await(K()?.())}catch{}c===Ee.current&&(t?at.current():(O.warn({message:"Voice WS token refresh failed — no reconnect",api_name:ae,conversation_id:e??void 0}),F(p),D(d())))})()):(O.warn({message:"Voice WS auth refresh budget exhausted — giving up",api_name:ae,conversation_id:e??void 0}),F(p),void D(d()));if("retry"!==i&&s&&!Q.has(n)||null==e)D(d());else{if(Me.current>=m)return O.warn({message:"Voice WS auto-reconnect cap reached — giving up",api_name:ae,conversation_id:e??void 0,reconnect_attempts:Me.current}),F("Voice connection lost. Please try again."),void D(d());Me.current+=1,O.info({message:"Voice WS scheduling auto-reconnect",api_name:ae,conversation_id:e??void 0,reconnect_attempts:Me.current,delay_ms:g}),ze(Ne),Ne.current=setTimeout(()=>{Ne.current=null,at.current()},g)}},[D,ot,e]),dt=C((e,t)=>{if(e!==we.current||Be.current)return;const n=Ke.current;n.push(Date.now()),n.length>30&&n.shift(),Te.current?.play(t)},[]),ht=C((t,n)=>{if(t!==we.current)return;const r=n.data??{};switch(n.type){case"tts_start":Re.current=Date.now(),ze(Le),Ge.current+=1,He.current=!1,Be.current=!1,Ke.current=[],Pe.current?.pause(),Te.current?.resetForNewSegment(),Se(),D(c(o.SPEAKING)),pe(re.current?H.KEEP:H.FINALIZE),$e.current&&(ze($e),$e.current=setTimeout(()=>{$e.current=null,t===we.current&&Xe()},6e4));break;case"text_delta":{const e="string"==typeof r.token?r.token:"";if(!e)break;Se(),ve(z(de.current,e));break}case"tts_end":{const n=!0===r.cancelled;if(O.debug({message:"Voice WS tts_end",api_name:ae,conversation_id:e??void 0,cancelled:n}),je.current=se(Ke.current),Qe(),n){nt(),Z.getState().voice.pipelineStatus===o.SPEAKING&&D(c(o.IDLE));break}st(t);break}case"stt_result":{const e="string"==typeof r.text?r.text.trim():"";if(!e)break;D(l(null));const t=_(e),n=Fe.current,s=n&&!n.userSpokeSince&&Date.now()-n.at<=5e3?n.id:null;ce.current.setMessages(e=>{const n=s?e.findIndex(e=>e.id===s):-1;return-1===n?[...e,t]:[...e.slice(0,n),t,...e.slice(n)]});break}case"speech_started":{if(Date.now()-Re.current<500)break;const e=ke.current;e&&e.readyState===WebSocket.OPEN&&e.send(JSON.stringify({type:Y})),ze(Le),Ge.current+=1,ze(Oe),Oe.current=setTimeout(()=>{Oe.current=null,t===we.current&&nt()},400),Qe(),Ze(),Pe.current?.stop(),D(l(null)),D(c(o.LISTENING)),re.current||pe(H.KEEP);break}case"speech_stopped":if(Ze(),D(c(o.PROCESSING)),re.current)break;D(y(!0)),D(k(null)),he();break;case"error":{const t="string"==typeof r.message?r.message:"Voice error";if(j({kind:"error",error:t},me),ie.current(),D(c(o.IDLE)),pe(H.CANCEL),S.some(e=>e.test(t)))De.current="auth";else{if(!v.some(e=>e.test(t)))break;De.current="terminal"}O.warn({message:"Voice WS fatal error — closing socket",api_name:ae,conversation_id:e??void 0,drop_outcome:De.current}),ke.current?.close(ue);break}case"pong":Ie.current=null,Me.current=0,We.current=0,Ve.current=0;break;case f.STATUS_UPDATE:re.current=!0,Ue.current="string"==typeof r.text?r.text:null,ye(n),Pe.current?.start(Te.current?.remainingSeconds??0);break;default:ye(n)}},[D,Z,e,Se,pe,ve,de,Qe,nt,st,ce,he,me,ye,Xe]),pt=C((t,n)=>{ct(),Ie.current=null,Ce.current=setInterval(()=>{if(t!==we.current||n.readyState!==WebSocket.OPEN)return void ct();const r=Ie.current;if(null!==r&&Date.now()-r>3e4)return O.warn({message:"Voice WS pong watchdog tripped — forcing reconnect",api_name:ae,conversation_id:e??void 0}),ct(),De.current="retry",n.close(ue),void lt(t,ue,"watchdog",!0);null===r&&(Ie.current=Date.now()),n.send(JSON.stringify({type:"ping"}))},2e4)},[ct,lt,e]),mt=C(()=>{const e=Pe.current??te.current.createThinkingSound?.()??null;Pe.current=e,e?.unlock()},[]),gt=C(async()=>{if(ke.current||xe.current)return;if(!e)return;const t=te.current;if(!t.createPcmCapture||!t.createPcmPlayer)return O.error({message:"Voice WS transport unsupported on this platform (no PCM seams)",api_name:ae,conversation_id:e,transport:W}),F(p),void D(d());if(xe.current=!0,O.info({message:"Voice WS connecting",api_name:ae,conversation_id:e,transport:W,assistant_starts:V}),J($())&&Ve.current<h){Ve.current+=1;const e=Ee.current;try{await Promise.resolve(K()?.())}catch{}if(e!==Ee.current)return}const r=++we.current;let s;De.current=null,qe.current=!1,D(a(u.CONNECTING));try{s=new WebSocket(function(e,t){const n=t===L.PIPECAT_WS?G.CONVERSATION_PIPECAT_WS(e):G.CONVERSATION_STREAM(e),r="undefined"!=typeof window?window.location?.origin:void 0,s=new URL(n,r);s.protocol="https:"===s.protocol?"wss:":"ws:";const i=B();i&&s.searchParams.append("access_token",i);const c=function(){for(const[e,t]of Object.entries(U()))if("x-client-id"===e.toLowerCase()&&t)return t;return null}();return c&&s.searchParams.append("client_id",c),s.toString()}(e,W))}catch(t){return O.error({message:"Voice WS could not open socket",api_name:ae,conversation_id:e,error_message:t instanceof Error?t.message:String(t)}),F(p),D(d()),void ot(!1)}s.binaryType="arraybuffer",ke.current=s,mt();const l=Te.current??t.createPcmPlayer();Te.current=l,l.setPrerollProvider(()=>je.current??.2),l.setSinkId(Z.getState().voice.selectedSpeakerId||null);let m=!1,g=!1;it(),Ae.current=setTimeout(()=>{r===we.current&&(O.warn({message:"Voice WS connect timed out",api_name:ae,conversation_id:e}),F("Voice connection timed out. Please try again."),D(d()),ut.current())},T),s.onopen=()=>{if(r!==we.current)return;m=!0,it(),O.info({message:"Voice WS connected",api_name:ae,conversation_id:e,transport:W}),D(a(u.CONNECTED)),D(i(!0)),D(c(o.IDLE)),Ke.current=[];const t=V&&!Je.current;t&&(be.current=!1),tt(r),Ye(r),pt(r,s),t&&(Je.current=!0,s.send(JSON.stringify({type:"start_conversation"})),D(n(!0)),_e.current?.setMuted(!0),D(y(!0)),he(),ze($e),$e.current=setTimeout(()=>{$e.current=null,r===we.current&&(O.warn({message:"Voice WS greeting hold released by safety timer",api_name:ae,conversation_id:e}),Xe())},1e4))},s.onmessage=e=>{if(r!==we.current)return;if(e.data instanceof ArrayBuffer)return void dt(r,e.data);if("string"!=typeof e.data)return;let t=null;try{t=JSON.parse(e.data)}catch{return}t&&"string"==typeof t.type&&ht(r,t)},s.onerror=()=>{r===we.current&&O.warn({message:"Voice WS socket error",api_name:ae,conversation_id:e,socket_opened:m})},s.onclose=e=>{g||(g=!0,lt(r,e.code,e.reason,m))}},[e,W,Z,D,V,ot,it,mt,tt,Ye,pt,he,Xe,dt,ht,lt]),ft=C((t=!0)=>{O.info({message:"Voice WS disconnect (intentional teardown)",api_name:ae,conversation_id:e??void 0,commit_turn:t}),Ee.current+=1,we.current+=1,Ve.current=0,ze(Ne),Me.current=0,We.current=0,De.current=null,Je.current=!1,be.current=!0,D(P(!1));const n=ke.current;!n||n.readyState!==WebSocket.CONNECTING&&n.readyState!==WebSocket.OPEN||n.close(ue),ot(t)},[D,ot,e]),St=C(e=>{be.current=e,_e.current?.setMuted(!e)},[]),vt=C(e=>{D(w(e)),ke.current&&_e.current&&tt(we.current)},[D,tt]),yt=C(e=>{D(E(e)),Te.current?.setSinkId(e||null)},[D]),kt=C((t,n)=>{const r=ke.current;if(!r||r.readyState!==WebSocket.OPEN)return;const s=n?.modelContext;O.info({message:"Voice WS text_message",api_name:ae,conversation_id:e??void 0,has_model_context:Boolean(s?.length)}),r.send(JSON.stringify({type:Y})),nt(),rt(),le.current&&Qe(),Ze(),r.send(JSON.stringify({type:"text_message",text:t,...s?.length?{model_context:s}:{}})),ce.current.setMessages(e=>[...e,_(t,void 0,n?.documents,n?.messageType)]),D(y(!0)),D(k(null)),he(),D(c(o.PROCESSING))},[D,he,Qe,nt,rt,le,ce,e]);A(()=>{ut.current=ft},[ft]),A(()=>{at.current=gt},[gt]);const _t=b(e),Tt=b(!1);A(()=>{const t=_t.current;if(_t.current=e,t===e)return;const n=xe.current;n&&(Tt.current=!0),n&&ft(!1),Tt.current&&null!=e&&(Tt.current=!1,gt())},[e,ft,gt]);const Pt=b(ne);return A(()=>{const e=Pt.current;Pt.current=ne,e&&!ne&&xe.current&&ft(!1)},[ne,ft]),A(()=>()=>{ut.current(),Te.current?.destroy(),Te.current=null,Pe.current?.destroy(),Pe.current=null},[]),{connect:gt,disconnect:ft,sendText:kt,setMicEnabled:St,setInputDevice:vt,setOutputDevice:yt,primeAudio:mt}}(e,W,V,D);return x(Z,{voiceBridge:W})};export{re as BrowserPcmCapture,ie as BrowserPcmPlayer,ce as BrowserThinkingSound,se as computeAdaptivePreroll,le as useVoiceWsProviderValue};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1interface/voice-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"import": "./dist/index.mjs",
|
|
14
14
|
"require": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./webrtc": {
|
|
17
|
+
"types": "./dist/webrtc.d.ts",
|
|
18
|
+
"import": "./dist/webrtc.mjs",
|
|
19
|
+
"require": "./dist/webrtc.js"
|
|
20
|
+
},
|
|
21
|
+
"./ws": {
|
|
22
|
+
"types": "./dist/ws.d.ts",
|
|
23
|
+
"import": "./dist/ws.mjs",
|
|
24
|
+
"require": "./dist/ws.js"
|
|
15
25
|
}
|
|
16
26
|
},
|
|
17
27
|
"files": [
|
|
@@ -27,7 +37,7 @@
|
|
|
27
37
|
},
|
|
28
38
|
"dependencies": {
|
|
29
39
|
"@pipecat-ai/client-js": "^1.11.0",
|
|
30
|
-
"@1interface/shared-core": "^0.
|
|
40
|
+
"@1interface/shared-core": "^0.18.0"
|
|
31
41
|
},
|
|
32
42
|
"peerDependencies": {
|
|
33
43
|
"@reduxjs/toolkit": "^2.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
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;
|