@chat21/chat21-web-widget 5.1.30 → 5.1.32-rc1

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.
Files changed (55) hide show
  1. package/.github/workflows/docker-community-push-latest.yml +23 -13
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
  3. package/CHANGELOG.md +38 -2
  4. package/Dockerfile +4 -5
  5. package/angular.json +5 -2
  6. package/docs/changelog/this-branch.md +36 -0
  7. package/package.json +4 -1
  8. package/src/app/app.component.ts +10 -9
  9. package/src/app/app.module.ts +9 -0
  10. package/src/app/component/conversation-detail/conversation/conversation.component.html +7 -1
  11. package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -2
  12. package/src/app/component/conversation-detail/conversation/conversation.component.ts +34 -5
  13. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +2 -2
  14. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -1
  15. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +2 -0
  16. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +143 -78
  17. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +131 -13
  18. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +108 -7
  19. package/src/app/component/last-message/last-message.component.ts +4 -1
  20. package/src/app/component/message/audio/audio.component.ts +0 -5
  21. package/src/app/component/message/audio-sync/audio-sync.component.html +19 -0
  22. package/src/app/component/message/audio-sync/audio-sync.component.scss +65 -0
  23. package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +23 -0
  24. package/src/app/component/message/audio-sync/audio-sync.component.ts +197 -0
  25. package/src/app/component/message/bubble-message/bubble-message.component.html +6 -1
  26. package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
  27. package/src/app/providers/global-settings.service.ts +21 -0
  28. package/src/app/providers/translator.service.ts +2 -0
  29. package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +12 -0
  30. package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +171 -0
  31. package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +39 -0
  32. package/src/app/providers/voice/audio.types.ts +34 -0
  33. package/src/app/providers/voice/vad.service.spec.ts +28 -0
  34. package/src/app/providers/voice/vad.service.ts +70 -0
  35. package/src/app/providers/voice/voice.service.spec.ts +60 -0
  36. package/src/app/providers/voice/voice.service.ts +264 -0
  37. package/src/app/sass/_variables.scss +1 -0
  38. package/src/app/shims/onnxruntime-web-wasm.ts +4 -0
  39. package/src/app/utils/conversation-sender-classifier.ts +21 -0
  40. package/src/app/utils/globals.ts +7 -1
  41. package/src/assets/i18n/en.json +1 -0
  42. package/src/assets/i18n/es.json +1 -0
  43. package/src/assets/i18n/fr.json +1 -0
  44. package/src/assets/i18n/it.json +1 -0
  45. package/src/assets/onnx/ort-wasm-simd-threaded.mjs +59 -0
  46. package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
  47. package/src/assets/vad/silero_vad_legacy.onnx +0 -0
  48. package/src/assets/vad/vad.worklet.bundle.min.js +1 -0
  49. package/src/chat21-core/models/message.ts +2 -1
  50. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +3 -2
  51. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +12 -0
  52. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  53. package/src/chat21-core/utils/utils-message.ts +7 -0
  54. package/src/chat21-core/utils/utils.ts +5 -2
  55. package/tsconfig.json +5 -0
@@ -0,0 +1,28 @@
1
+ import { Location } from '@angular/common';
2
+ import { TestBed } from '@angular/core/testing';
3
+
4
+ import { VadService } from './vad.service';
5
+
6
+ describe('VadService', () => {
7
+ let service: VadService;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({
11
+ providers: [
12
+ VadService,
13
+ {
14
+ provide: Location,
15
+ useValue: {
16
+ prepareExternalUrl: (url: string) => `/${url}`,
17
+ },
18
+ },
19
+ ],
20
+ });
21
+ service = TestBed.inject(VadService);
22
+ });
23
+
24
+ it('should expose VAD and ONNX WASM base URLs with trailing slash', () => {
25
+ expect(service.getVadAssetBaseUrl()).toBe('/assets/vad/');
26
+ expect(service.getOnnxWasmBaseUrl()).toBe('/assets/onnx/');
27
+ });
28
+ });
@@ -0,0 +1,70 @@
1
+ import { Location } from '@angular/common';
2
+ import { Injectable } from '@angular/core';
3
+ import { MicVAD, getDefaultRealTimeVADOptions } from '@ricky0123/vad-web';
4
+ import type { RealTimeVADOptions } from '@ricky0123/vad-web';
5
+
6
+ /**
7
+ * MicVAD (@ricky0123/vad-web): modelli in assets/vad/, WASM ONNX in assets/onnx/
8
+ * (allineato a ort.env.wasm.wasmPaths = "/assets/onnx/").
9
+ */
10
+ @Injectable({ providedIn: 'root' })
11
+ export class VadService {
12
+ private onnxRuntimeEnvPromise: Promise<void> | null = null;
13
+
14
+ constructor(private readonly location: Location) {}
15
+
16
+ /**
17
+ * Base URL per silero_vad_legacy.onnx / vad.worklet.bundle.min.js
18
+ * (MicVAD usa baseAssetPath + nome file interno, non modelURL singolo).
19
+ */
20
+ getVadAssetBaseUrl(): string {
21
+ return this.ensureTrailingSlash(this.location.prepareExternalUrl('assets/vad/'));
22
+ }
23
+
24
+ /** Base URL per ort-wasm-*.mjs / .wasm (es. /assets/onnx/). */
25
+ getOnnxWasmBaseUrl(): string {
26
+ return this.ensureTrailingSlash(this.location.prepareExternalUrl('assets/onnx/'));
27
+ }
28
+
29
+ /**
30
+ * Pre-configura il modulo onnxruntime-web/wasm (stesso usato da MicVAD):
31
+ * wasmPaths + numThreads prima del primo MicVAD.new.
32
+ */
33
+ ensureOnnxRuntimeEnv(): Promise<void> {
34
+ if (!this.onnxRuntimeEnvPromise) {
35
+ this.onnxRuntimeEnvPromise = (async () => {
36
+ const ort = await import('onnxruntime-web/wasm');
37
+ const wasmBase = this.getOnnxWasmBaseUrl();
38
+ ort.env.wasm.wasmPaths = wasmBase;
39
+ ort.env.wasm.numThreads = 1;
40
+ ort.env.logLevel = 'error';
41
+ })();
42
+ }
43
+ return this.onnxRuntimeEnvPromise;
44
+ }
45
+
46
+ async createMicVad(overrides: Partial<RealTimeVADOptions>): Promise<MicVAD> {
47
+ await this.ensureOnnxRuntimeEnv();
48
+ const base = getDefaultRealTimeVADOptions('legacy');
49
+ const vadBase = this.getVadAssetBaseUrl();
50
+ const ortWasmBase = this.getOnnxWasmBaseUrl();
51
+
52
+ return MicVAD.new({
53
+ ...base,
54
+ startOnLoad: false,
55
+ baseAssetPath: vadBase,
56
+ onnxWASMBasePath: ortWasmBase,
57
+ ortConfig: (ort) => {
58
+ base.ortConfig?.(ort);
59
+ ort.env.wasm.wasmPaths = ortWasmBase;
60
+ ort.env.wasm.numThreads = 1;
61
+ ort.env.logLevel = 'error';
62
+ },
63
+ ...overrides,
64
+ });
65
+ }
66
+
67
+ private ensureTrailingSlash(path: string): string {
68
+ return path.endsWith('/') ? path : `${path}/`;
69
+ }
70
+ }
@@ -0,0 +1,60 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { VoiceService } from './voice.service';
4
+ import { VadService } from './vad.service';
5
+
6
+ describe('VoiceService', () => {
7
+ let service: VoiceService;
8
+ let vadService: jasmine.SpyObj<VadService>;
9
+
10
+ let mockVad: { start: jasmine.Spy; pause: jasmine.Spy; destroy: jasmine.Spy };
11
+
12
+ beforeEach(() => {
13
+ mockVad = {
14
+ start: jasmine.createSpy('start').and.returnValue(Promise.resolve()),
15
+ pause: jasmine.createSpy('pause').and.returnValue(Promise.resolve()),
16
+ destroy: jasmine.createSpy('destroy').and.returnValue(Promise.resolve()),
17
+ };
18
+ vadService = jasmine.createSpyObj('VadService', ['ensureOnnxRuntimeEnv', 'createMicVad']);
19
+ vadService.ensureOnnxRuntimeEnv.and.returnValue(Promise.resolve());
20
+ vadService.createMicVad.and.returnValue(Promise.resolve(mockVad as any));
21
+
22
+ TestBed.configureTestingModule({
23
+ providers: [VoiceService, { provide: VadService, useValue: vadService }],
24
+ });
25
+ service = TestBed.inject(VoiceService);
26
+ });
27
+
28
+ it('startSession should call ensureOnnxRuntimeEnv', async () => {
29
+ const stream = new MediaStream();
30
+ spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
31
+
32
+ await service.startSession({});
33
+
34
+ expect(vadService.ensureOnnxRuntimeEnv).toHaveBeenCalled();
35
+ });
36
+
37
+ it('startSession should request mic, create MicVAD, and start', async () => {
38
+ const stream = new MediaStream();
39
+ spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
40
+
41
+ await service.startSession({
42
+ onRecordingComplete: () => {},
43
+ });
44
+
45
+ expect(navigator.mediaDevices.getUserMedia).toHaveBeenCalled();
46
+ expect(vadService.createMicVad).toHaveBeenCalled();
47
+ expect(mockVad.start).toHaveBeenCalled();
48
+ });
49
+
50
+ it('stopSession should destroy VAD and stop tracks', async () => {
51
+ const track = jasmine.createSpyObj<MediaStreamTrack>('MediaStreamTrack', ['stop']);
52
+ const stream = new MediaStream([track]);
53
+ spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
54
+
55
+ await service.startSession({ onRecordingComplete: () => {} });
56
+ await service.stopSession();
57
+
58
+ expect(track.stop).toHaveBeenCalled();
59
+ });
60
+ });
@@ -0,0 +1,264 @@
1
+ import { Inject, Injectable, Optional } from '@angular/core';
2
+ import type { MicVAD } from '@ricky0123/vad-web';
3
+ import { getDefaultRealTimeVADOptions } from '@ricky0123/vad-web';
4
+ import { BehaviorSubject, Observable, Subject } from 'rxjs';
5
+ import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
6
+ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
7
+
8
+ import {
9
+ DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS,
10
+ VoiceSegmentPayload,
11
+ VoiceSessionStartOptions,
12
+ } from './audio.types';
13
+ import { SpeechToTextProvider } from './STT&TTS/speech-provider.abstract';
14
+ import { VadService } from './vad.service';
15
+
16
+ const VOICE_RECORDING_MIME = 'audio/webm';
17
+
18
+ /**
19
+ * Voce: VadService (ONNX WASM) → MicVAD → MediaRecorder su ogni segmento parlato.
20
+ * Opzionalmente STT (`SpeechToTextProvider`) arricchisce il payload con `transcript`.
21
+ */
22
+ @Injectable({ providedIn: 'root' })
23
+ export class VoiceService {
24
+ private vad?: MicVAD;
25
+ private stream?: MediaStream;
26
+ private mediaRecorder?: MediaRecorder;
27
+ private audioChunks: Blob[] = [];
28
+ private sessionConstraints: MediaStreamConstraints = DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS;
29
+ private onRecordingComplete?: (result: VoiceSegmentPayload) => void;
30
+ private enableTranscription = true;
31
+
32
+ private readonly audioSegmentSubject = new Subject<VoiceSegmentPayload>();
33
+ /** Emesso a ogni fine segmento parlato: audio WebM + opzionalmente `transcript` / `transcriptionError`. */
34
+ readonly audioSegment$: Observable<VoiceSegmentPayload> = this.audioSegmentSubject.asObservable();
35
+
36
+ // 🔊 REALTIME VOLUME STREAM
37
+ private readonly volumeSubject = new BehaviorSubject<number>(0);
38
+ readonly volume$: Observable<number> = this.volumeSubject.asObservable();
39
+
40
+ // 🎧 AUDIO ANALYSER
41
+ private audioContext?: AudioContext;
42
+ private analyser?: AnalyserNode;
43
+ /** Buffer dedicato (`ArrayBuffer`) per compatibilità con `getByteFrequencyData`. */
44
+ private dataArray?: Uint8Array;
45
+
46
+ private readonly logger: LoggerService = LoggerInstance.getInstance();
47
+
48
+ constructor(
49
+ private readonly vadService: VadService,
50
+ @Optional() @Inject(SpeechToTextProvider) private readonly speechToText: SpeechToTextProvider | null,
51
+ ) {}
52
+
53
+ get isSessionActive(): boolean {
54
+ return !!this.vad || !!this.stream;
55
+ }
56
+
57
+ /**
58
+ * Richiede il microfono, avvia VAD in ascolto (inizio/fine parlato) e registra in WebM per segmento.
59
+ */
60
+ async startSession(options: VoiceSessionStartOptions = {}): Promise<void> {
61
+ await this.stopSession();
62
+
63
+ this.sessionConstraints = options.constraints ?? DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS;
64
+ this.onRecordingComplete = options.onRecordingComplete;
65
+ this.enableTranscription = options.enableTranscription !== false;
66
+
67
+ await this.vadService.ensureOnnxRuntimeEnv();
68
+
69
+ this.stream = await navigator.mediaDevices.getUserMedia(this.sessionConstraints);
70
+
71
+ // 🎧 AUDIO ANALYSER INIT
72
+ this.initAudioAnalyser(this.stream);
73
+
74
+ const vadDefaults = getDefaultRealTimeVADOptions('legacy');
75
+
76
+ this.vad = await this.vadService.createMicVad({
77
+ getStream: async () => this.stream as MediaStream,
78
+ pauseStream: vadDefaults.pauseStream,
79
+ resumeStream: async () => {
80
+ this.stream = await navigator.mediaDevices.getUserMedia(this.sessionConstraints);
81
+ this.initAudioAnalyser(this.stream);
82
+ return this.stream;
83
+ },
84
+ onSpeechStart: () => {
85
+ this.logger.log('[VoiceService] speech start');
86
+ this.startMediaRecorderSegment();
87
+ },
88
+ onSpeechEnd: () => {
89
+ this.logger.log('[VoiceService] speech end');
90
+ this.stopMediaRecorderSegment();
91
+ },
92
+ minSpeechMs: 480,
93
+ redemptionMs: 1920,
94
+ preSpeechPadMs: 960,
95
+ });
96
+
97
+ await this.vad.start();
98
+
99
+ // 🔁 start volume loop
100
+ this.startVolumeLoop();
101
+ }
102
+
103
+ async stopSession(): Promise<void> {
104
+ if (this.mediaRecorder?.state === 'recording') {
105
+ this.mediaRecorder.stop();
106
+ }
107
+
108
+ this.mediaRecorder = undefined;
109
+ this.audioChunks = [];
110
+
111
+ if (this.vad) {
112
+ try {
113
+ await this.vad.pause();
114
+ await this.vad.destroy();
115
+ } catch (e) {
116
+ this.logger.log('[VoiceService] stopSession VAD cleanup', e);
117
+ }
118
+ this.vad = undefined;
119
+ }
120
+
121
+ if (this.stream) {
122
+ this.stream.getTracks().forEach((t) => t.stop());
123
+ this.stream = undefined;
124
+ }
125
+
126
+ // 🎧 cleanup audio context
127
+ this.audioContext?.close();
128
+ this.audioContext = undefined;
129
+ this.analyser = undefined;
130
+ this.dataArray = undefined;
131
+
132
+ this.volumeSubject.next(0);
133
+
134
+ this.onRecordingComplete = undefined;
135
+ }
136
+
137
+ /**
138
+ * 🎧 AUDIO ANALYSER INIT
139
+ */
140
+ private initAudioAnalyser(stream: MediaStream): void {
141
+ this.audioContext = new AudioContext();
142
+
143
+ const source = this.audioContext.createMediaStreamSource(stream);
144
+
145
+ this.analyser = this.audioContext.createAnalyser();
146
+ this.analyser.fftSize = 256;
147
+
148
+ const bins = this.analyser.frequencyBinCount;
149
+ this.dataArray = new Uint8Array(new ArrayBuffer(bins));
150
+
151
+ source.connect(this.analyser);
152
+ }
153
+
154
+ /**
155
+ * 🔁 VOLUME LOOP
156
+ */
157
+ private startVolumeLoop(): void {
158
+ const tick = () => {
159
+ if (!this.analyser || !this.dataArray) {
160
+ requestAnimationFrame(tick);
161
+ return;
162
+ }
163
+
164
+ this.analyser.getByteFrequencyData(this.dataArray);
165
+
166
+ let sum = 0;
167
+ for (let i = 0; i < this.dataArray.length; i++) {
168
+ sum += this.dataArray[i];
169
+ }
170
+
171
+ const volume = sum / this.dataArray.length;
172
+
173
+ this.volumeSubject.next(volume);
174
+
175
+ requestAnimationFrame(tick);
176
+ };
177
+
178
+ tick();
179
+ }
180
+
181
+ /**
182
+ * 🎙️ RECORD SEGMENT START
183
+ */
184
+ private startMediaRecorderSegment(): void {
185
+ if (this.mediaRecorder?.state === 'recording') return;
186
+ if (!this.stream) return;
187
+
188
+ this.audioChunks = [];
189
+
190
+ this.mediaRecorder = new MediaRecorder(this.stream, {
191
+ mimeType: VOICE_RECORDING_MIME,
192
+ });
193
+
194
+ this.mediaRecorder.ondataavailable = (event) => {
195
+ if (event.data.size > 0) {
196
+ this.audioChunks.push(event.data);
197
+ }
198
+ };
199
+
200
+ this.mediaRecorder.start();
201
+ }
202
+
203
+ /**
204
+ * 🛑 RECORD SEGMENT STOP
205
+ */
206
+ private stopMediaRecorderSegment(): void {
207
+ if (!this.mediaRecorder) return;
208
+
209
+ this.mediaRecorder.stop();
210
+
211
+ this.mediaRecorder.onstop = () => {
212
+ const blob = new Blob(this.audioChunks, {
213
+ type: VOICE_RECORDING_MIME,
214
+ });
215
+
216
+ void this.finalizeSegment(blob, VOICE_RECORDING_MIME);
217
+ };
218
+ }
219
+
220
+ /**
221
+ * 🧠 FINALIZE SEGMENT (STT optional)
222
+ */
223
+ private async finalizeSegment(blob: Blob, mimeType: string): Promise<void> {
224
+ const base: VoiceSegmentPayload = { blob, mimeType };
225
+
226
+ const runStt =
227
+ this.enableTranscription &&
228
+ !!this.speechToText &&
229
+ blob.size > 0;
230
+
231
+ if (!runStt) {
232
+ this.emitSegmentPayload(base);
233
+ return;
234
+ }
235
+
236
+ try {
237
+ const { text } = await this.speechToText.transcribe({
238
+ audio: blob,
239
+ mimeType,
240
+ });
241
+
242
+ this.emitSegmentPayload({ ...base, transcript: text });
243
+ } catch (e) {
244
+ const msg = e instanceof Error ? e.message : String(e);
245
+ this.logger.log('[VoiceService] transcription failed', msg);
246
+
247
+ this.emitSegmentPayload({
248
+ ...base,
249
+ transcriptionError: msg,
250
+ });
251
+ }
252
+ }
253
+
254
+ /**
255
+ * 📡 EMIT RESULT
256
+ */
257
+ private emitSegmentPayload(payload: VoiceSegmentPayload): void {
258
+ this.logger.log( '[VoiceService] segment ready', payload.transcript ?? payload.transcriptionError ?? payload.blob.size);
259
+
260
+ this.audioSegmentSubject.next(payload);
261
+
262
+ this.onRecordingComplete?.(payload);
263
+ }
264
+ }
@@ -36,6 +36,7 @@
36
36
 
37
37
  --chat-footer-height: 64px;
38
38
  --chat-footer-logo-height: 30px;
39
+ --chat-footer-close-button-height: 30px;
39
40
  --chat-footer-border-radius: 16px;
40
41
  --chat-footer-background-color: #f6f7fb;
41
42
  --chat-footer-color: #1a1a1a;
@@ -0,0 +1,4 @@
1
+ export * from "onnxruntime-web";
2
+ import * as ort from "onnxruntime-web";
3
+
4
+ export default ort;
@@ -84,6 +84,14 @@ function isSystemMessage(msg: MessageModel | null | undefined): boolean {
84
84
  return sender === 'system' || senderFullnameLower === 'system';
85
85
  }
86
86
 
87
+ function isAgentHandoffCommandClientMessage(msg: MessageModel | null | undefined, clientSenderId?: string): boolean {
88
+ if (!msg) return false;
89
+ if (!clientSenderId) return false;
90
+ if ((msg as any).sender !== clientSenderId) return false;
91
+ const text = ((msg as any).text || '').toString().trim().toLowerCase();
92
+ return text === '\\agent';
93
+ }
94
+
87
95
  export function computeConversationBadgeState(messages: MessageModel[], clientSenderId?: string): ConversationBadgeState {
88
96
  const msgs = messages || [];
89
97
  const serverMsgs = msgs.filter(m => !!m && (!clientSenderId || (m as any).sender !== clientSenderId));
@@ -93,6 +101,19 @@ export function computeConversationBadgeState(messages: MessageModel[], clientSe
93
101
 
94
102
  let latestNonSystemResponderKind: 'bot' | 'human' | null = null;
95
103
 
104
+ // Priority rule: explicit client command "\agent" requests human handoff.
105
+ // If the latest messages are all from the client (i.e. after the last server message)
106
+ // and among those there is a "\agent" command, consider the conversation "human"
107
+ // even before any server-side system message (e.g. MEMBER_JOINED_GROUP) arrives.
108
+ const lastServerTs = getTimestamp(latestServerMsg);
109
+ const clientMsgsAfterLastServer = clientSenderId
110
+ ? msgs.filter(m => !!m && (m as any).sender === clientSenderId && getTimestamp(m) > lastServerTs)
111
+ : [];
112
+ const hasAgentCommandInPendingClientMsgs = clientMsgsAfterLastServer.some(m => isAgentHandoffCommandClientMessage(m, clientSenderId));
113
+
114
+ if (hasAgentCommandInPendingClientMsgs) {
115
+ latestNonSystemResponderKind = 'human';
116
+ } else
96
117
  // Priority rule: if the latest server message is a system handoff to a human, force "human".
97
118
  if (isHumanHandoffSystemMessage(latestServerMsg, clientSenderId)) {
98
119
  latestNonSystemResponderKind = 'human';
@@ -219,6 +219,7 @@ export class Globals {
219
219
  showEmojiFooterButton: boolean // ******* new ********
220
220
  showAttachmentFooterButton: boolean // ******* new ********
221
221
  showAudioRecorderFooterButton: boolean // ******* new ********
222
+ showAudioStreamFooterButton: boolean // ******* new ********
222
223
 
223
224
  allowedOnSpecificUrl: boolean // ******* new ********
224
225
  allowedOnSpecificUrlList: Array<string> // ******* new ********
@@ -227,6 +228,8 @@ export class Globals {
227
228
  fontFamilySource: string; // ******* new ********
228
229
 
229
230
  size: 'min' | 'max' | 'top'; // ******* new ********
231
+
232
+ closeChatInConversation: boolean; // ******* new ********
230
233
  constructor(
231
234
  ) { }
232
235
 
@@ -435,6 +438,8 @@ export class Globals {
435
438
  this.showAttachmentFooterButton = true;
436
439
  /** show/hide rec audio option in footer chat-detail page */
437
440
  this.showAudioRecorderFooterButton = true;
441
+ /** show/hide stream audio option in footer chat-detail page */
442
+ this.showAudioStreamFooterButton = true;
438
443
  /** enabled to set a list of pattern url able to load the widget **/
439
444
  this.allowedOnSpecificUrl = false
440
445
  /** set a list of pattern url able to load the widget */
@@ -443,7 +448,8 @@ export class Globals {
443
448
  this.hasCalloutInWidgetConfig = false;
444
449
  /** set widget size from 3 different positions: min, max, top */
445
450
  this.size = 'min';
446
-
451
+ /** enable to close the chat in conversation */
452
+ this.closeChatInConversation = false;
447
453
  // ============ END: SET EXTERNAL PARAMETERS ==============//
448
454
 
449
455
 
@@ -97,5 +97,6 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji not allowed",
98
98
  "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
99
99
  "MAX_ATTACHMENT": "Max allowed size {{FILE_SIZE_LIMIT}}Mb",
100
+ "MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
100
101
  "EMOJI": "Emoji"
101
102
  }
@@ -97,5 +97,6 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji no permitido",
98
98
  "DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
99
99
  "MAX_ATTACHMENT": "Tamaño máximo permitido {{FILE_SIZE_LIMIT}}Mb",
100
+ "MAX_ATTACHMENT_ERROR": "El archivo supera el tamaño máximo permitido",
100
101
  "EMOJI": "Emoji"
101
102
  }
@@ -97,5 +97,6 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji non autorisé",
98
98
  "DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
99
99
  "MAX_ATTACHMENT": "Taille maximale autorisée {{FILE_SIZE_LIMIT}}Mo",
100
+ "MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
100
101
  "EMOJI": "Emoji"
101
102
  }
@@ -95,5 +95,6 @@
95
95
  "EMOJI_NOT_ELLOWED":"Emoji non consentiti",
96
96
  "DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
97
97
  "MAX_ATTACHMENT": "Dimensione massima consentita {{FILE_SIZE_LIMIT}}Mb",
98
+ "MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
98
99
  "EMOJI": "Emoji"
99
100
  }
@@ -0,0 +1,59 @@
1
+ async function ortWasmThreaded(moduleArg={}){var moduleRtn;var h=moduleArg,aa=!!globalThis.window,k=!!globalThis.WorkerGlobalScope,m=globalThis.process?.versions?.node&&"renderer"!=globalThis.process?.type,n=k&&self.name?.startsWith("em-pthread");if(m){const {createRequire:a}=await import("module");var require=a(import.meta.url),ba=require("worker_threads");global.Worker=ba.Worker;n=(k=!ba.ic)&&"em-pthread"==ba.workerData}h.mountExternalData=(a,b)=>{a.startsWith("./")&&(a=a.substring(2));(h.Sb||(h.Sb=new Map)).set(a,b)};
2
+ h.unmountExternalData=()=>{delete h.Sb};var SharedArrayBuffer=globalThis.SharedArrayBuffer??(new WebAssembly.Memory({initial:0,maximum:0,kc:!0})).buffer.constructor,ca="./this.program",da=(a,b)=>{throw b;},ea=import.meta.url,fa="",ha,ia;
3
+ if(m){var fs=require("fs");ea.startsWith("file:")&&(fa=require("path").dirname(require("url").fileURLToPath(ea))+"/");ia=a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a)};ha=async a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a,void 0)};1<process.argv.length&&(ca=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);da=(a,b)=>{process.exitCode=a;throw b;}}else if(aa||k){try{fa=(new URL(".",ea)).href}catch{}m||(k&&(ia=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";
4
+ b.send(null);return new Uint8Array(b.response)}),ha=async a=>{if(ja(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?d(e.response):c(e.status)};e.onerror=c;e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url);})}var ka=console.log.bind(console),la=console.error.bind(console);
5
+ if(m){var ma=require("util"),na=a=>"object"==typeof a?ma.inspect(a):a;ka=(...a)=>fs.writeSync(1,a.map(na).join(" ")+"\n");la=(...a)=>fs.writeSync(2,a.map(na).join(" ")+"\n")}var oa=ka,p=la,q,r,pa=!1,t,ja=a=>a.startsWith("file://");function v(){x.buffer!=z.buffer&&qa()}var ra,sa;
6
+ if(m&&n){var ta=ba.parentPort;ta.on("message",a=>global.onmessage?.({data:a}));Object.assign(globalThis,{self:global,postMessage:a=>ta.postMessage(a)});process.on("uncaughtException",a=>{postMessage({Qb:"uncaughtException",error:a});process.exit(1)})}var ua;
7
+ if(n){var va=!1;self.onunhandledrejection=b=>{throw b.reason||b;};function a(b){try{var d=b.data,c=d.Qb;if("load"===c){let e=[];self.onmessage=f=>e.push(f);ua=()=>{postMessage({Qb:"loaded"});for(let f of e)a(f);self.onmessage=a};for(const f of d.$b)if(!h[f]||h[f].proxy)h[f]=(...g)=>{postMessage({Qb:"callHandler",Zb:f,args:g})},"print"==f&&(oa=h[f]),"printErr"==f&&(p=h[f]);x=d.ec;qa();r=d.fc;wa();xa()}else if("run"===c){ya(d.Pb);za(d.Pb,0,0,1,0,0);Aa();Ba(d.Pb);va||=!0;try{Ca(d.cc,d.Ub)}catch(e){if("unwind"!=
8
+ e)throw e;}}else"setimmediate"!==d.target&&("checkMailbox"===c?va&&Da():c&&(p(`worker: received unknown command ${c}`),p(d)))}catch(e){throw Ea(),e;}}self.onmessage=a}var z,A,Fa,C,D,Ga,G,H,Ha=!1;function qa(){var a=x.buffer;h.HEAP8=z=new Int8Array(a);Fa=new Int16Array(a);h.HEAPU8=A=new Uint8Array(a);new Uint16Array(a);h.HEAP32=C=new Int32Array(a);h.HEAPU32=D=new Uint32Array(a);Ga=new Float32Array(a);G=new Float64Array(a);H=new BigInt64Array(a);new BigUint64Array(a)}
9
+ function Ia(){Ha=!0;n?ua():I.Ua()}function J(a){a="Aborted("+a+")";p(a);pa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");sa?.(a);throw a;}var Ja;async function Ka(a){if(!q)try{var b=await ha(a);return new Uint8Array(b)}catch{}if(a==Ja&&q)a=new Uint8Array(q);else if(ia)a=ia(a);else throw"both async and sync fetching of the wasm failed";return a}
10
+ async function La(a,b){try{var d=await Ka(a);return await WebAssembly.instantiate(d,b)}catch(c){p(`failed to asynchronously prepare wasm: ${c}`),J(c)}}async function Na(a){var b=Ja;if(!q&&!ja(b)&&!m)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){p(`wasm streaming compile failed: ${c}`),p("falling back to ArrayBuffer instantiation")}return La(b,a)}
11
+ function Oa(){Pa={S:Qa,f:Ra,w:Sa,e:Ta,j:Ua,g:Va,T:Wa,b:Xa,G:Ya,ua:Za,k:$a,K:ab,Ka:bb,qa:cb,sa:db,La:eb,Ia:fb,Ba:gb,Ha:hb,Z:ib,ra:jb,oa:kb,Ja:lb,pa:mb,Qa:nb,Ea:ob,ma:pb,va:qb,ja:rb,U:sb,Da:Ba,Na:tb,ya:ub,za:vb,Aa:wb,wa:xb,xa:yb,ka:zb,Sa:Ab,Pa:Bb,W:Cb,V:Db,Oa:Eb,F:Fb,Ma:Gb,na:Hb,u:Ib,H:Jb,R:Kb,la:Lb,da:Mb,Ta:Nb,Fa:Ob,Ga:Pb,ta:Qb,L:Rb,Y:Sb,Ca:Tb,X:Ub,$:Vb,M:Wb,aa:Xb,N:Yb,v:Zb,c:$b,m:ac,n:bc,r:cc,ea:dc,x:ec,o:fc,O:gc,D:hc,I:ic,ba:jc,ca:kc,Q:lc,P:mc,fa:nc,z:oc,E:pc,d:qc,q:rc,i:sc,_:tc,l:uc,p:vc,s:wc,t:xc,
12
+ y:yc,ga:zc,B:Ac,J:Bc,C:Cc,ha:Dc,ia:Ec,A:Fc,h:Gc,a:x,Ra:Hc};return{a:Pa}}
13
+ async function wa(){function a(c,e){I=c.exports;I=Ic();Jc.push(I.wb);c=I;h._OrtInit=c.Va;h._OrtGetLastError=c.Wa;h._OrtCreateSessionOptions=c.Xa;h._OrtAppendExecutionProvider=c.Ya;h._OrtAddFreeDimensionOverride=c.Za;h._OrtAddSessionConfigEntry=c._a;h._OrtReleaseSessionOptions=c.$a;h._OrtCreateSession=c.ab;h._OrtReleaseSession=c.bb;h._OrtGetInputOutputCount=c.cb;h._OrtGetInputOutputMetadata=c.db;h._OrtFree=c.eb;h._OrtCreateTensor=c.fb;h._OrtGetTensorData=c.gb;h._OrtReleaseTensor=c.hb;h._OrtCreateRunOptions=
14
+ c.ib;h._OrtAddRunConfigEntry=c.jb;h._OrtReleaseRunOptions=c.kb;h._OrtCreateBinding=c.lb;h._OrtBindInput=c.mb;h._OrtBindOutput=c.nb;h._OrtClearBoundOutputs=c.ob;h._OrtReleaseBinding=c.pb;h._OrtRunWithBinding=c.qb;h._OrtRun=c.rb;h._OrtEndProfiling=c.sb;Kc=c.tb;Lc=h._free=c.ub;Mc=h._malloc=c.vb;za=c.yb;Ea=c.zb;Nc=c.Ab;Oc=c.Bb;Pc=c.Cb;Qc=c.Db;Rc=c.Eb;K=c.Fb;L=c.Gb;Sc=c.Hb;M=c.Ib;Tc=c.Jb;N=c.Kb;Uc=c.Lb;Vc=c.Mb;Wc=c.Nb;Xc=c.Ob;Yc=c.xb;r=e;return I}var b=Oa();if(h.instantiateWasm)return new Promise(c=>{h.instantiateWasm(b,
15
+ (e,f)=>{c(a(e,f))})});if(n){var d=new WebAssembly.Instance(r,Oa());return a(d,r)}Ja??=h.locateFile?h.locateFile?h.locateFile("ort-wasm-simd-threaded.wasm",fa):fa+"ort-wasm-simd-threaded.wasm":(new URL("ort-wasm-simd-threaded.wasm",import.meta.url)).href;return function(c){return a(c.instance,c.module)}(await Na(b))}class Zc{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
16
+ var $c=a=>{a.terminate();a.onmessage=()=>{}},ad=[],O=0,P=null,dd=a=>{0==Q.length&&(bd(),cd(Q[0]));var b=Q.pop();if(!b)return 6;R.push(b);S[a.Pb]=b;b.Pb=a.Pb;var d={Qb:"run",cc:a.bc,Ub:a.Ub,Pb:a.Pb};m&&b.unref();b.postMessage(d,a.Yb);return 0},T=0,U=(a,b,...d)=>{var c=16*d.length,e=N(),f=Tc(c),g=f>>>3,l;for(l of d)"bigint"==typeof l?((v(),H)[g++>>>0]=1n,(v(),H)[g++>>>0]=l):((v(),H)[g++>>>0]=0n,(v(),G)[g++>>>0]=l);a=Nc(a,0,c,f,b);M(e);return a};
17
+ function Hc(a){if(n)return U(0,1,a);t=a;if(!(0<T)){for(var b of R)$c(b);for(b of Q)$c(b);Q=[];R=[];S={};pa=!0}da(a,new Zc(a))}function ed(a){if(n)return U(1,0,a);Qb(a)}var Qb=a=>{t=a;if(n)throw ed(a),"unwind";Hc(a)},Q=[],R=[],Jc=[],S={};function fd(){for(var a=h.numThreads-1;a--;)bd();ad.push(async()=>{var b=gd();O++;await b;O--;0==O&&P&&(b=P,P=null,b())})}var hd=a=>{var b=a.Pb;delete S[b];Q.push(a);R.splice(R.indexOf(a),1);a.Pb=0;Oc(b)};function Aa(){Jc.forEach(a=>a())}
18
+ var cd=a=>new Promise(b=>{a.onmessage=f=>{var g=f.data;f=g.Qb;if(g.Tb&&g.Tb!=Kc()){var l=S[g.Tb];l?l.postMessage(g,g.Yb):p(`Internal error! Worker sent a message "${f}" to target pthread ${g.Tb}, but that thread no longer exists!`)}else if("checkMailbox"===f)Da();else if("spawnThread"===f)dd(g);else if("cleanupThread"===f)jd(()=>{hd(S[g.dc])});else if("loaded"===f)a.loaded=!0,m&&!a.Pb&&a.unref(),b(a);else if("setimmediate"===g.target)a.postMessage(g);else if("uncaughtException"===f)a.onerror(g.error);
19
+ else if("callHandler"===f)h[g.Zb](...g.args);else f&&p(`worker sent an unknown command ${f}`)};a.onerror=f=>{p(`${"worker sent an error!"} ${f.filename}:${f.lineno}: ${f.message}`);throw f;};m&&(a.on("message",f=>a.onmessage({data:f})),a.on("error",f=>a.onerror(f)));var d=[],c=[],e;for(e of c)h.propertyIsEnumerable(e)&&d.push(e);a.postMessage({Qb:"load",$b:d,ec:x,fc:r})});async function gd(){if(!n)return Promise.all(Q.map(cd))}
20
+ function bd(){var a=new Worker(new URL(import.meta.url),{type:"module",workerData:"em-pthread",name:"em-pthread"});Q.push(a)}function ya(a){var b=(v(),D)[a+52>>>2>>>0];a=(v(),D)[a+56>>>2>>>0];Sc(b,b-a);M(b)}var kd=[],V=a=>{var b=kd[a];b||(kd[a]=b=Yc.get(a));return b},Ca=(a,b)=>{T=0;a=V(a)(b);0<T?t=a:Pc(a)},x,ld=[],md=0;function Ra(a){a>>>=0;var b=new nd(a);0==(v(),z)[b.Rb+12>>>0]&&(od(b,!0),md--);pd(b,!1);ld.push(b);return Xc(a)}
21
+ var W=0,Sa=()=>{K(0,0);var a=ld.pop();Uc(a.Vb);W=0};function od(a,b){b=b?1:0;(v(),z)[a.Rb+12>>>0]=b}function pd(a,b){b=b?1:0;(v(),z)[a.Rb+13>>>0]=b}class nd{constructor(a){this.Vb=a;this.Rb=a-24}}var qd=a=>{var b=W;if(!b)return L(0),0;var d=new nd(b);(v(),D)[d.Rb+16>>>2>>>0]=b;var c=(v(),D)[d.Rb+4>>>2>>>0];if(!c)return L(0),b;for(var e of a){if(0===e||e===c)break;if(Wc(e,c,d.Rb+16))return L(e),b}L(c);return b};function Ta(){return qd([])}function Ua(a){return qd([a>>>0])}
22
+ function Va(a,b,d,c){return qd([a>>>0,b>>>0,d>>>0,c>>>0])}var Wa=()=>{var a=ld.pop();a||J("no exception to throw");var b=a.Vb;0==(v(),z)[a.Rb+13>>>0]&&(ld.push(a),pd(a,!0),od(a,!1),md++);Vc(b);W=b;throw W;};function Xa(a,b,d){a>>>=0;var c=new nd(a);b>>>=0;d>>>=0;(v(),D)[c.Rb+16>>>2>>>0]=0;(v(),D)[c.Rb+4>>>2>>>0]=b;(v(),D)[c.Rb+8>>>2>>>0]=d;Vc(a);W=a;md++;throw W;}var Ya=()=>md;function rd(a,b,d,c){return n?U(2,1,a,b,d,c):Za(a,b,d,c)}
23
+ function Za(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;if(!globalThis.SharedArrayBuffer)return 6;var e=[];if(n&&0===e.length)return rd(a,b,d,c);a={bc:d,Pb:a,Ub:c,Yb:e};return n?(a.Qb="spawnThread",postMessage(a,e),0):dd(a)}function $a(a){W||=a>>>0;throw W;}
24
+ var sd=globalThis.TextDecoder&&new TextDecoder,td=(a,b=0,d,c)=>{b>>>=0;var e=b;d=e+d;if(c)c=d;else{for(;a[e]&&!(e>=d);)++e;c=e}if(16<c-b&&a.buffer&&sd)return sd.decode(a.buffer instanceof ArrayBuffer?a.subarray(b,c):a.slice(b,c));for(e="";b<c;)if(d=a[b++],d&128){var f=a[b++]&63;if(192==(d&224))e+=String.fromCharCode((d&31)<<6|f);else{var g=a[b++]&63;d=224==(d&240)?(d&15)<<12|f<<6|g:(d&7)<<18|f<<12|g<<6|a[b++]&63;65536>d?e+=String.fromCharCode(d):(d-=65536,e+=String.fromCharCode(55296|d>>10,56320|
25
+ d&1023))}}else e+=String.fromCharCode(d);return e},ud=(a,b,d)=>(a>>>=0)?td((v(),A),a,b,d):"";function ab(a,b,d){return n?U(3,1,a,b,d):0}function bb(a,b){if(n)return U(4,1,a,b)}function cb(a,b){if(n)return U(5,1,a,b)}function db(a,b,d){if(n)return U(6,1,a,b,d)}function eb(a,b,d){return n?U(7,1,a,b,d):0}function fb(a,b){if(n)return U(8,1,a,b)}function gb(a,b,d){if(n)return U(9,1,a,b,d)}function hb(a,b,d,c){if(n)return U(10,1,a,b,d,c)}function ib(a,b,d,c){if(n)return U(11,1,a,b,d,c)}
26
+ function jb(a,b,d,c){if(n)return U(12,1,a,b,d,c)}function kb(a){if(n)return U(13,1,a)}function lb(a,b){if(n)return U(14,1,a,b)}function mb(a,b,d){if(n)return U(15,1,a,b,d)}var nb=()=>J("");function ob(a){za(a>>>0,!k,1,!aa,131072,!1);Aa()}
27
+ var jd=a=>{if(!pa)try{if(a(),!(0<T))try{n?Kc()&&Pc(t):Qb(t)}catch(b){b instanceof Zc||"unwind"==b||da(1,b)}}catch(b){b instanceof Zc||"unwind"==b||da(1,b)}},vd=!Atomics.waitAsync||globalThis.navigator?.userAgent&&91>Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)||[])[2]);function Ba(a){a>>>=0;vd||(Atomics.waitAsync((v(),C),a>>>2,a).value.then(Da),a+=128,Atomics.store((v(),C),a>>>2,1))}var Da=()=>jd(()=>{var a=Kc();a&&(Ba(a),Rc())});
28
+ function pb(a,b){a>>>=0;a==b>>>0?setTimeout(Da):n?postMessage({Tb:a,Qb:"checkMailbox"}):(a=S[a])&&a.postMessage({Qb:"checkMailbox"})}var wd=[];function qb(a,b,d,c,e){b>>>=0;e>>>=0;wd.length=0;d=e>>>3;for(c=e+c>>>3;d<c;){var f;(v(),H)[d++>>>0]?f=(v(),H)[d++>>>0]:f=(v(),G)[d++>>>0];wd.push(f)}return(b?xd[b]:yd[a])(...wd)}var rb=()=>{T=0};function sb(a){a>>>=0;n?postMessage({Qb:"cleanupThread",dc:a}):hd(S[a])}function tb(a){m&&S[a>>>0].ref()}
29
+ function ub(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getUTCSeconds();(v(),C)[b+4>>>2>>>0]=a.getUTCMinutes();(v(),C)[b+8>>>2>>>0]=a.getUTCHours();(v(),C)[b+12>>>2>>>0]=a.getUTCDate();(v(),C)[b+16>>>2>>>0]=a.getUTCMonth();(v(),C)[b+20>>>2>>>0]=a.getUTCFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;(v(),C)[b+28>>>2>>>0]=a}
30
+ var zd=a=>0===a%4&&(0!==a%100||0===a%400),Ad=[0,31,60,91,121,152,182,213,244,274,305,335],Bd=[0,31,59,90,120,151,181,212,243,273,304,334];
31
+ function vb(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getSeconds();(v(),C)[b+4>>>2>>>0]=a.getMinutes();(v(),C)[b+8>>>2>>>0]=a.getHours();(v(),C)[b+12>>>2>>>0]=a.getDate();(v(),C)[b+16>>>2>>>0]=a.getMonth();(v(),C)[b+20>>>2>>>0]=a.getFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getDay();var d=(zd(a.getFullYear())?Ad:Bd)[a.getMonth()]+a.getDate()-1|0;(v(),C)[b+28>>>2>>>0]=d;(v(),C)[b+36>>>2>>>0]=-(60*a.getTimezoneOffset());d=(new Date(a.getFullYear(),
32
+ 6,1)).getTimezoneOffset();var c=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;(v(),C)[b+32>>>2>>>0]=a}
33
+ function wb(a){a>>>=0;var b=new Date((v(),C)[a+20>>>2>>>0]+1900,(v(),C)[a+16>>>2>>>0],(v(),C)[a+12>>>2>>>0],(v(),C)[a+8>>>2>>>0],(v(),C)[a+4>>>2>>>0],(v(),C)[a>>>2>>>0],0),d=(v(),C)[a+32>>>2>>>0],c=b.getTimezoneOffset(),e=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),f=(new Date(b.getFullYear(),0,1)).getTimezoneOffset(),g=Math.min(f,e);0>d?(v(),C)[a+32>>>2>>>0]=Number(e!=f&&g==c):0<d!=(g==c)&&(e=Math.max(f,e),b.setTime(b.getTime()+6E4*((0<d?g:e)-c)));(v(),C)[a+24>>>2>>>0]=b.getDay();d=(zd(b.getFullYear())?
34
+ Ad:Bd)[b.getMonth()]+b.getDate()-1|0;(v(),C)[a+28>>>2>>>0]=d;(v(),C)[a>>>2>>>0]=b.getSeconds();(v(),C)[a+4>>>2>>>0]=b.getMinutes();(v(),C)[a+8>>>2>>>0]=b.getHours();(v(),C)[a+12>>>2>>>0]=b.getDate();(v(),C)[a+16>>>2>>>0]=b.getMonth();(v(),C)[a+20>>>2>>>0]=b.getYear();a=b.getTime();return BigInt(isNaN(a)?-1:a/1E3)}function xb(a,b,d,c,e,f,g){return n?U(16,1,a,b,d,c,e,f,g):-52}function yb(a,b,d,c,e,f){if(n)return U(17,1,a,b,d,c,e,f)}var X={},Ib=()=>performance.timeOrigin+performance.now();
35
+ function zb(a,b){if(n)return U(18,1,a,b);X[a]&&(clearTimeout(X[a].id),delete X[a]);if(!b)return 0;var d=setTimeout(()=>{delete X[a];jd(()=>Qc(a,performance.timeOrigin+performance.now()))},b);X[a]={id:d,lc:b};return 0}
36
+ var Y=(a,b,d)=>{var c=(v(),A);b>>>=0;if(0<d){var e=b;d=b+d-1;for(var f=0;f<a.length;++f){var g=a.codePointAt(f);if(127>=g){if(b>=d)break;c[b++>>>0]=g}else if(2047>=g){if(b+1>=d)break;c[b++>>>0]=192|g>>6;c[b++>>>0]=128|g&63}else if(65535>=g){if(b+2>=d)break;c[b++>>>0]=224|g>>12;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63}else{if(b+3>=d)break;c[b++>>>0]=240|g>>18;c[b++>>>0]=128|g>>12&63;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63;f++}}c[b>>>0]=0;a=b-e}else a=0;return a};
37
+ function Ab(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;var e=(new Date).getFullYear(),f=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();var g=Math.max(f,e);(v(),D)[a>>>2>>>0]=60*g;(v(),C)[b>>>2>>>0]=Number(f!=e);b=l=>{var u=Math.abs(l);return`UTC${0<=l?"-":"+"}${String(Math.floor(u/60)).padStart(2,"0")}${String(u%60).padStart(2,"0")}`};a=b(f);b=b(e);e<f?(Y(a,d,17),Y(b,c,17)):(Y(a,c,17),Y(b,d,17))}var Eb=()=>Date.now(),Cd=1;
38
+ function Bb(a,b,d){d>>>=0;if(!(0<=a&&3>=a))return 28;if(0===a)a=Date.now();else if(Cd)a=performance.timeOrigin+performance.now();else return 52;a=Math.round(1E6*a);(v(),H)[d>>>3>>>0]=BigInt(a);return 0}var Dd=[];function Cb(a,b,d){a>>>=0;b>>>=0;d>>>=0;Dd.length=0;for(var c;c=(v(),A)[b++>>>0];){var e=105!=c;e&=112!=c;d+=e&&d%8?4:0;Dd.push(112==c?(v(),D)[d>>>2>>>0]:106==c?(v(),H)[d>>>3>>>0]:105==c?(v(),C)[d>>>2>>>0]:(v(),G)[d>>>3>>>0]);d+=e?8:4}return xd[a](...Dd)}var Db=()=>{};
39
+ function Fb(a,b){return p(ud(a>>>0,b>>>0))}var Gb=()=>{T+=1;throw"unwind";};function Hb(){return 4294901760}var Jb=()=>m?require("os").cpus().length:navigator.hardwareConcurrency,Z={},Ed=a=>{for(var b=0,d=0;d<a.length;++d){var c=a.charCodeAt(d);127>=c?b++:2047>=c?b+=2:55296<=c&&57343>=c?(b+=4,++d):b+=3}return b},Fd=a=>{var b;return(b=/\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(a))?+b[1]:(b=/:(\d+):\d+(?:\)|$)/.exec(a))?2147483648|+b[1]:0},Gd=a=>{for(var b of a)(a=Fd(b))&&(Z[a]=b)};
40
+ function Mb(){var a=Error().stack.toString().split("\n");"Error"==a[0]&&a.shift();Gd(a);Z.Wb=Fd(a[3]);Z.ac=a;return Z.Wb}function Kb(a){a=Z[a>>>0];if(!a)return 0;var b;if(b=/^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^\s+at (.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^(.+?)@/.exec(a))a=b[1];else return 0;Lc(Kb.Xb??0);b=Ed(a)+1;var d=Mc(b);d&&Y(a,d,b);Kb.Xb=d;return Kb.Xb}
41
+ function Lb(a){a>>>=0;var b=(v(),A).length;if(a<=b||4294901760<a)return!1;for(var d=1;4>=d;d*=2){var c=b*(1+.2/d);c=Math.min(c,a+100663296);a:{c=(Math.min(4294901760,65536*Math.ceil(Math.max(a,c)/65536))-x.buffer.byteLength+65535)/65536|0;try{x.grow(c);qa();var e=1;break a}catch(f){}e=void 0}if(e)return!0}return!1}
42
+ function Nb(a,b,d){a>>>=0;b>>>=0;if(Z.Wb==a)var c=Z.ac;else c=Error().stack.toString().split("\n"),"Error"==c[0]&&c.shift(),Gd(c);for(var e=3;c[e]&&Fd(c[e])!=a;)++e;for(a=0;a<d&&c[a+e];++a)(v(),C)[b+4*a>>>2>>>0]=Fd(c[a+e]);return a}
43
+ var Hd={},Jd=()=>{if(!Id){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8",_:ca||"./this.program"},b;for(b in Hd)void 0===Hd[b]?delete a[b]:a[b]=Hd[b];var d=[];for(b in a)d.push(`${b}=${a[b]}`);Id=d}return Id},Id;function Ob(a,b){if(n)return U(19,1,a,b);a>>>=0;b>>>=0;var d=0,c=0,e;for(e of Jd()){var f=b+d;(v(),D)[a+c>>>2>>>0]=f;d+=Y(e,f,Infinity)+1;c+=4}return 0}
44
+ function Pb(a,b){if(n)return U(20,1,a,b);a>>>=0;b>>>=0;var d=Jd();(v(),D)[a>>>2>>>0]=d.length;a=0;for(var c of d)a+=Ed(c)+1;(v(),D)[b>>>2>>>0]=a;return 0}function Rb(a){return n?U(21,1,a):52}function Sb(a,b,d,c){return n?U(22,1,a,b,d,c):52}function Tb(a,b,d,c){return n?U(23,1,a,b,d,c):70}var Kd=[null,[],[]];
45
+ function Ub(a,b,d,c){if(n)return U(24,1,a,b,d,c);b>>>=0;d>>>=0;c>>>=0;for(var e=0,f=0;f<d;f++){var g=(v(),D)[b>>>2>>>0],l=(v(),D)[b+4>>>2>>>0];b+=8;for(var u=0;u<l;u++){var w=a,y=(v(),A)[g+u>>>0],B=Kd[w];0===y||10===y?((1===w?oa:p)(td(B)),B.length=0):B.push(y)}e+=l}(v(),D)[c>>>2>>>0]=e;return 0}function Gc(a){return a>>>0}n||fd();n||(x=new WebAssembly.Memory({initial:256,maximum:65536,shared:!0}),qa());h.wasmBinary&&(q=h.wasmBinary);h.stackSave=()=>N();h.stackRestore=a=>M(a);h.stackAlloc=a=>Tc(a);
46
+ h.setValue=function(a,b,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":(v(),z)[a>>>0]=b;break;case "i8":(v(),z)[a>>>0]=b;break;case "i16":(v(),Fa)[a>>>1>>>0]=b;break;case "i32":(v(),C)[a>>>2>>>0]=b;break;case "i64":(v(),H)[a>>>3>>>0]=BigInt(b);break;case "float":(v(),Ga)[a>>>2>>>0]=b;break;case "double":(v(),G)[a>>>3>>>0]=b;break;case "*":(v(),D)[a>>>2>>>0]=b;break;default:J(`invalid type for setValue: ${d}`)}};
47
+ h.getValue=function(a,b="i8"){b.endsWith("*")&&(b="*");switch(b){case "i1":return(v(),z)[a>>>0];case "i8":return(v(),z)[a>>>0];case "i16":return(v(),Fa)[a>>>1>>>0];case "i32":return(v(),C)[a>>>2>>>0];case "i64":return(v(),H)[a>>>3>>>0];case "float":return(v(),Ga)[a>>>2>>>0];case "double":return(v(),G)[a>>>3>>>0];case "*":return(v(),D)[a>>>2>>>0];default:J(`invalid type for getValue: ${b}`)}};h.UTF8ToString=ud;h.stringToUTF8=Y;h.lengthBytesUTF8=Ed;
48
+ var yd=[Hc,ed,rd,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb,mb,xb,yb,zb,Ob,Pb,Rb,Sb,Tb,Ub],xd={887900:(a,b,d,c,e)=>{if("undefined"==typeof h||!h.Sb)return 1;a=ud(Number(a>>>0));a.startsWith("./")&&(a=a.substring(2));a=h.Sb.get(a);if(!a)return 2;b=Number(b>>>0);d=Number(d>>>0);c=Number(c>>>0);if(b+d>a.byteLength)return 3;try{const f=a.subarray(b,b+d);switch(e){case 0:(v(),A).set(f,c>>>0);break;case 1:h.hc?h.hc(c,f):h.jc(c,f);break;default:return 4}return 0}catch{return 4}},888724:()=>"undefined"!==typeof wasmOffsetConverter};
49
+ function Qa(){return"undefined"!==typeof wasmOffsetConverter}var Kc,Lc,Mc,za,Ea,Nc,Oc,Pc,Qc,Rc,K,L,Sc,M,Tc,N,Uc,Vc,Wc,Xc,Yc,Pa;function bc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function ac(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function sc(a,b,d){var c=N();try{V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function $b(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}
50
+ function qc(a){var b=N();try{V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function fc(a,b,d,c,e,f,g){var l=N();try{return V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function rc(a,b){var d=N();try{V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}function wc(a,b,d,c,e,f){var g=N();try{V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function uc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}
51
+ function vc(a,b,d,c,e){var f=N();try{V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}function xc(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Ec(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Dc(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function cc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
52
+ function yc(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function Bc(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}function ec(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function oc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0);return 0n}}
53
+ function zc(a,b,d,c,e,f,g,l,u){var w=N();try{V(a)(b,d,c,e,f,g,l,u)}catch(y){M(w);if(y!==y+0)throw y;K(1,0)}}function Zb(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function lc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function nc(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0);return 0n}}function Fc(a,b,d,c,e){var f=N();try{V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
54
+ function mc(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0);return 0n}}function ic(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function dc(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function gc(a,b,d,c,e,f,g,l){var u=N();try{return V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}
55
+ function pc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0);return 0n}}function Yb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function Wb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function hc(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{return V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}
56
+ function Ac(a,b,d,c,e,f,g,l,u,w,y){var B=N();try{V(a)(b,d,c,e,f,g,l,u,w,y)}catch(E){M(B);if(E!==E+0)throw E;K(1,0)}}function Cc(a,b,d,c,e,f,g,l,u,w,y,B,E,F,Ld,Md){var Nd=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B,E,F,Ld,Md)}catch(Ma){M(Nd);if(Ma!==Ma+0)throw Ma;K(1,0)}}function kc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function jc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
57
+ function Xb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function Vb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function tc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function Ic(){var a=I;a=Object.assign({},a);var b=c=>()=>c()>>>0,d=c=>e=>c(e)>>>0;a.tb=b(a.tb);a.vb=d(a.vb);a.Jb=d(a.Jb);a.Kb=b(a.Kb);a.Ob=d(a.Ob);return a}
58
+ function xa(){if(0<O)P=xa;else if(n)ra?.(h),Ia();else{for(var a=ad;0<a.length;)a.shift()(h);0<O?P=xa:(h.calledRun=!0,pa||(Ia(),ra?.(h)))}}var I;n||(I=await (wa()),xa());h.PTR_SIZE=4;Ha?moduleRtn=h:moduleRtn=new Promise((a,b)=>{ra=a;sa=b});
59
+ ;return moduleRtn}export default ortWasmThreaded;var isPthread=globalThis.self?.name?.startsWith("em-pthread");var isNode=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(isNode)isPthread=(await import("worker_threads")).workerData==="em-pthread";isPthread&&ortWasmThreaded();
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={710:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.log=void 0;const s=e=>t=>{console.log(`VAD | ${e} >`,t)};t.log={error:s("error"),debug:s("debug"),warn:s("warn")}},954:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.Message=void 0,function(e){e.AudioFrame="AUDIO_FRAME",e.SpeechStart="SPEECH_START",e.VADMisfire="VAD_MISFIRE",e.SpeechEnd="SPEECH_END",e.SpeechStop="SPEECH_STOP",e.SpeechRealStart="SPEECH_REAL_START",e.FrameProcessed="FRAME_PROCESSED"}(s||(t.Message=s={}))},825:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Resampler=void 0;const r=s(710);t.Resampler=class{constructor(e){this.options=e,this.process=e=>{const t=[];for(const s of e)for(this.inputBuffer.push(s);this.hasEnoughDataForFrame();){const e=this.generateOutputFrame();t.push(e)}return t},e.nativeSampleRate<16e3&&r.log.error("nativeSampleRate is too low. Should have 16000 = targetSampleRate <= nativeSampleRate"),this.inputBuffer=[]}async*stream(e){for(const t of e)for(this.inputBuffer.push(t);this.hasEnoughDataForFrame();){const e=this.generateOutputFrame();yield e}}hasEnoughDataForFrame(){return this.inputBuffer.length*this.options.targetSampleRate/this.options.nativeSampleRate>=this.options.targetFrameSize}generateOutputFrame(){const e=new Float32Array(this.options.targetFrameSize);let t=0,s=0;for(;t<this.options.targetFrameSize;){let r=0,o=0;for(;s<Math.min(this.inputBuffer.length,(t+1)*this.options.nativeSampleRate/this.options.targetSampleRate);){const e=this.inputBuffer[s];void 0!==e&&(r+=e,o++),s++}e[t]=r/o,t++}return this.inputBuffer=this.inputBuffer.slice(s),e}}}},t={};function s(r){var o=t[r];if(void 0!==o)return o.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,s),a.exports}(()=>{const e=s(710),t=s(954),r=s(825);class o extends AudioWorkletProcessor{constructor(s){super(),this._stopProcessing=!1,this.options=s.processorOptions,this.port.onmessage=s=>{s.data===t.Message.SpeechStop&&(e.log.debug("Worklet received speech stop message"),this._stopProcessing=!0)},this.resampler=new r.Resampler({nativeSampleRate:sampleRate,targetSampleRate:16e3,targetFrameSize:this.options.frameSamples})}process(e){if(this._stopProcessing)return!1;const s=e[0];if(void 0===s)return!0;const r=s[0];if(void 0===r)return!0;const o=this.resampler.process(r);for(const e of o)this.port.postMessage({message:t.Message.AudioFrame,data:e.buffer},[e.buffer]);return!0}}registerProcessor("vad-helper-worklet",o)})()})();