@hivegpt/hiveai-angular 0.0.582 → 0.0.584
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/bundles/hivegpt-hiveai-angular.umd.js +209 -382
- package/bundles/hivegpt-hiveai-angular.umd.js.map +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js.map +1 -1
- package/esm2015/hivegpt-hiveai-angular.js +4 -5
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +174 -165
- package/esm2015/lib/components/voice-agent/voice-agent.module.js +3 -5
- package/fesm2015/hivegpt-hiveai-angular.js +173 -323
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.d.ts +3 -4
- package/hivegpt-hiveai-angular.d.ts.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +24 -15
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/lib/components/voice-agent/voice-agent.module.d.ts +2 -2
- package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/esm2015/lib/components/voice-agent/services/websocket-voice-client.service.js +0 -163
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts +0 -52
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts.map +0 -1
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
import { OnDestroy } from '@angular/core';
|
|
1
|
+
import { NgZone, OnDestroy } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { PlatformTokenRefreshService } from '../../../services/platform-token-refresh.service';
|
|
4
4
|
import { AudioAnalyzerService } from './audio-analyzer.service';
|
|
5
|
-
import { WebSocketVoiceClientService } from './websocket-voice-client.service';
|
|
6
5
|
export declare type CallState = 'idle' | 'connecting' | 'connected' | 'listening' | 'talking' | 'ended';
|
|
7
6
|
export interface TranscriptData {
|
|
8
7
|
text: string;
|
|
9
8
|
final: boolean;
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
|
-
* Voice agent orchestrator
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Voice agent orchestrator using the official PipecatClient SDK.
|
|
12
|
+
*
|
|
13
|
+
* Audio flow (mirrors the React reference implementation):
|
|
14
|
+
* - Local mic: acquired by PipecatClient.initDevices(); local track fed to
|
|
15
|
+
* AudioAnalyzerService for waveform visualisation.
|
|
16
|
+
* - Bot audio: received as a MediaStreamTrack via RTVIEvent.TrackStarted,
|
|
17
|
+
* played through a hidden <audio> element.
|
|
18
|
+
* - All binary protobuf framing / RTVI protocol handled by
|
|
19
|
+
* @pipecat-ai/client-js + @pipecat-ai/websocket-transport.
|
|
15
20
|
*/
|
|
16
21
|
export declare class VoiceAgentService implements OnDestroy {
|
|
17
22
|
private audioAnalyzer;
|
|
18
|
-
private wsClient;
|
|
19
23
|
private platformTokenRefresh;
|
|
24
|
+
private ngZone;
|
|
20
25
|
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
21
26
|
private platformId;
|
|
22
27
|
private callStateSubject;
|
|
@@ -29,8 +34,8 @@ export declare class VoiceAgentService implements OnDestroy {
|
|
|
29
34
|
private botTranscriptSubject;
|
|
30
35
|
private callStartTime;
|
|
31
36
|
private durationInterval;
|
|
32
|
-
private
|
|
33
|
-
private
|
|
37
|
+
private pcClient;
|
|
38
|
+
private botAudioElement;
|
|
34
39
|
private subscriptions;
|
|
35
40
|
private destroy$;
|
|
36
41
|
callState$: Observable<CallState>;
|
|
@@ -41,19 +46,23 @@ export declare class VoiceAgentService implements OnDestroy {
|
|
|
41
46
|
audioLevels$: Observable<number[]>;
|
|
42
47
|
userTranscript$: Observable<TranscriptData>;
|
|
43
48
|
botTranscript$: Observable<string>;
|
|
44
|
-
constructor(audioAnalyzer: AudioAnalyzerService,
|
|
49
|
+
constructor(audioAnalyzer: AudioAnalyzerService, platformTokenRefresh: PlatformTokenRefreshService, ngZone: NgZone,
|
|
45
50
|
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
46
51
|
platformId: Object);
|
|
47
52
|
ngOnDestroy(): void;
|
|
48
|
-
/** Reset to idle
|
|
53
|
+
/** Reset to idle (e.g. when modal re-opens so user can click Start Call). */
|
|
49
54
|
resetToIdle(): void;
|
|
50
55
|
connect(apiUrl: string, token: string, botId: string, conversationId: string, apiKey: string, eventToken: string, eventId: string, eventUrl: string, domainAuthority: string, usersApiUrl?: string): Promise<void>;
|
|
51
|
-
private
|
|
52
|
-
private
|
|
53
|
-
private
|
|
54
|
-
private
|
|
55
|
-
private
|
|
56
|
+
private onPipecatConnected;
|
|
57
|
+
private onPipecatDisconnected;
|
|
58
|
+
private onBotReady;
|
|
59
|
+
private startLocalMicAnalyzer;
|
|
60
|
+
private onBotStartedSpeaking;
|
|
61
|
+
private onBotStoppedSpeaking;
|
|
62
|
+
private setupBotAudioTrack;
|
|
63
|
+
private stopBotAudio;
|
|
56
64
|
disconnect(): Promise<void>;
|
|
65
|
+
private cleanupPipecatClient;
|
|
57
66
|
toggleMic(): void;
|
|
58
67
|
private startDurationTimer;
|
|
59
68
|
private stopDurationTimer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-agent.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/voice-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,SAAS,EAAe,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"voice-agent.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/voice-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,MAAM,EAAE,SAAS,EAAe,MAAM,eAAe,CAAC;AACnF,OAAO,EAAmB,UAAU,EAAyB,MAAM,MAAM,CAAC;AAI1E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kDAAkD,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,oBAAY,SAAS,GACjB,MAAM,GACN,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,qBAGa,iBAAkB,YAAW,SAAS;IA6B/C,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IACd,8FAA8F;IACzE,OAAO,CAAC,UAAU;IAhCzC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,iBAAiB,CAAmC;IAC5D,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,qBAAqB,CAAuC;IACpE,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,qBAAqB,CAAiC;IAC9D,OAAO,CAAC,oBAAoB,CAAyB;IAErD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,gBAAgB,CAA+C;IAEvE,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,eAAe,CAAiC;IAExD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAuB;IAEvC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,CAAwC;IACzE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,CAAyC;IACxE,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAuC;IACpE,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAyC;IACzE,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,CAA6C;IACjF,YAAY,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAA0C;IAC5E,eAAe,EAAE,UAAU,CAAC,cAAc,CAAC,CAA6C;IACxF,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CAA4C;gBAGpE,aAAa,EAAE,oBAAoB,EACnC,oBAAoB,EAAE,2BAA2B,EACjD,MAAM,EAAE,MAAM;IACtB,8FAA8F;IACjE,UAAU,EAAE,MAAM;IASjD,WAAW,IAAI,IAAI;IAMnB,6EAA6E;IAC7E,WAAW,IAAI,IAAI;IAQb,OAAO,CACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAoHhB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;IAed,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAUnB,oBAAoB;IAWlC,SAAS,IAAI,IAAI;IAQjB,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,iBAAiB;CAM1B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Voice agent module. Uses
|
|
3
|
-
*
|
|
2
|
+
* Voice agent module. Uses @pipecat-ai/client-js + @pipecat-ai/websocket-transport
|
|
3
|
+
* (peer dependencies) for WebSocket transport, RTVI protocol, and audio.
|
|
4
4
|
*/
|
|
5
5
|
export declare class VoiceAgentModule {
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-agent.module.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/voice-agent.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"voice-agent.module.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/voice-agent.module.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qBAea,gBAAgB;CAAI"}
|
package/package.json
CHANGED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { Injectable, NgZone } from '@angular/core';
|
|
2
|
-
import { Subject } from 'rxjs';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
/**
|
|
5
|
-
* Native WebSocket client for voice session (signaling, transcripts, speaking hints).
|
|
6
|
-
* CRITICAL: Uses native WebSocket only. NO Socket.IO, NO ngx-socket-io.
|
|
7
|
-
*
|
|
8
|
-
* Connects to `ws_url` from `POST {baseUrl}/ai/ask-voice-socket`.
|
|
9
|
-
* Parses JSON messages for transcripts and optional assistant/user speaking flags.
|
|
10
|
-
*/
|
|
11
|
-
export class WebSocketVoiceClientService {
|
|
12
|
-
constructor(ngZone) {
|
|
13
|
-
this.ngZone = ngZone;
|
|
14
|
-
this.ws = null;
|
|
15
|
-
/** True when {@link disconnect} initiated the close (not counted as remote close). */
|
|
16
|
-
this.closeInitiatedByClient = false;
|
|
17
|
-
this.openedSubject = new Subject();
|
|
18
|
-
this.remoteCloseSubject = new Subject();
|
|
19
|
-
this.userTranscriptSubject = new Subject();
|
|
20
|
-
this.botTranscriptSubject = new Subject();
|
|
21
|
-
this.assistantSpeakingSubject = new Subject();
|
|
22
|
-
this.serverUserSpeakingSubject = new Subject();
|
|
23
|
-
/** Fires once each time the WebSocket reaches OPEN. */
|
|
24
|
-
this.opened$ = this.openedSubject.asObservable();
|
|
25
|
-
/** Fires when the socket closes without a client-initiated {@link disconnect}. */
|
|
26
|
-
this.remoteClose$ = this.remoteCloseSubject.asObservable();
|
|
27
|
-
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
28
|
-
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
29
|
-
/** Assistant/bot speaking, when the server sends explicit events (see {@link handleJsonMessage}). */
|
|
30
|
-
this.assistantSpeaking$ = this.assistantSpeakingSubject.asObservable();
|
|
31
|
-
/** User speaking from server-side VAD, if provided. */
|
|
32
|
-
this.serverUserSpeaking$ = this.serverUserSpeakingSubject.asObservable();
|
|
33
|
-
}
|
|
34
|
-
connect(wsUrl) {
|
|
35
|
-
var _a;
|
|
36
|
-
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (this.ws) {
|
|
40
|
-
this.closeInitiatedByClient = true;
|
|
41
|
-
this.ws.close();
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
const socket = new WebSocket(wsUrl);
|
|
45
|
-
this.ws = socket;
|
|
46
|
-
socket.onopen = () => {
|
|
47
|
-
if (this.ws !== socket)
|
|
48
|
-
return;
|
|
49
|
-
this.ngZone.run(() => this.openedSubject.next());
|
|
50
|
-
};
|
|
51
|
-
socket.onmessage = (event) => {
|
|
52
|
-
if (this.ws !== socket)
|
|
53
|
-
return;
|
|
54
|
-
if (typeof event.data !== 'string') {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const msg = JSON.parse(event.data);
|
|
59
|
-
this.ngZone.run(() => this.handleJsonMessage(msg));
|
|
60
|
-
}
|
|
61
|
-
catch (_a) {
|
|
62
|
-
// Ignore non-JSON
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
socket.onerror = () => {
|
|
66
|
-
this.ngZone.run(() => {
|
|
67
|
-
if (this.ws === socket && socket.readyState !== WebSocket.CLOSED) {
|
|
68
|
-
socket.close();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
socket.onclose = () => {
|
|
73
|
-
if (this.ws === socket) {
|
|
74
|
-
this.ws = null;
|
|
75
|
-
}
|
|
76
|
-
const client = this.closeInitiatedByClient;
|
|
77
|
-
this.closeInitiatedByClient = false;
|
|
78
|
-
if (!client) {
|
|
79
|
-
this.ngZone.run(() => this.remoteCloseSubject.next());
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
catch (err) {
|
|
84
|
-
console.error('WebSocketVoiceClient: connect failed', err);
|
|
85
|
-
this.ws = null;
|
|
86
|
-
throw err;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
handleJsonMessage(msg) {
|
|
90
|
-
const type = msg.type;
|
|
91
|
-
const typeStr = typeof type === 'string' ? type : '';
|
|
92
|
-
if (typeStr === 'session_ready' || typeStr === 'connected' || typeStr === 'voice_session_started') {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (typeStr === 'assistant_speaking' ||
|
|
96
|
-
typeStr === 'bot_speaking') {
|
|
97
|
-
if (msg.active === true || msg.speaking === true) {
|
|
98
|
-
this.assistantSpeakingSubject.next(true);
|
|
99
|
-
}
|
|
100
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
101
|
-
this.assistantSpeakingSubject.next(false);
|
|
102
|
-
}
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (typeStr === 'user_speaking') {
|
|
106
|
-
if (msg.active === true || msg.speaking === true) {
|
|
107
|
-
this.serverUserSpeakingSubject.next(true);
|
|
108
|
-
}
|
|
109
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
110
|
-
this.serverUserSpeakingSubject.next(false);
|
|
111
|
-
}
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (typeStr === 'input_audio_buffer.speech_started') {
|
|
115
|
-
this.serverUserSpeakingSubject.next(true);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (typeStr === 'input_audio_buffer.speech_stopped') {
|
|
119
|
-
this.serverUserSpeakingSubject.next(false);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
if (typeStr === 'response.audio.delta') {
|
|
123
|
-
this.assistantSpeakingSubject.next(true);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (typeStr === 'response.audio.done' ||
|
|
127
|
-
typeStr === 'response.output_audio.done') {
|
|
128
|
-
this.assistantSpeakingSubject.next(false);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (typeStr === 'user_transcript' && typeof msg.text === 'string') {
|
|
132
|
-
this.userTranscriptSubject.next({
|
|
133
|
-
text: msg.text,
|
|
134
|
-
final: msg.final === true,
|
|
135
|
-
});
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (typeStr === 'bot_transcript' && typeof msg.text === 'string') {
|
|
139
|
-
this.botTranscriptSubject.next(msg.text);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
disconnect() {
|
|
143
|
-
if (!this.ws) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
this.closeInitiatedByClient = true;
|
|
147
|
-
this.ws.close();
|
|
148
|
-
}
|
|
149
|
-
get isConnected() {
|
|
150
|
-
var _a;
|
|
151
|
-
return ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
WebSocketVoiceClientService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebSocketVoiceClientService_Factory() { return new WebSocketVoiceClientService(i0.ɵɵinject(i0.NgZone)); }, token: WebSocketVoiceClientService, providedIn: "root" });
|
|
155
|
-
WebSocketVoiceClientService.decorators = [
|
|
156
|
-
{ type: Injectable, args: [{
|
|
157
|
-
providedIn: 'root',
|
|
158
|
-
},] }
|
|
159
|
-
];
|
|
160
|
-
WebSocketVoiceClientService.ctorParameters = () => [
|
|
161
|
-
{ type: NgZone }
|
|
162
|
-
];
|
|
163
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL3dlYnNvY2tldC12b2ljZS1jbGllbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQXVCM0M7Ozs7OztHQU1HO0FBSUgsTUFBTSxPQUFPLDJCQUEyQjtJQWdDdEMsWUFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUEvQjFCLE9BQUUsR0FBcUIsSUFBSSxDQUFDO1FBQ3BDLHNGQUFzRjtRQUM5RSwyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFFL0Isa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3BDLHVCQUFrQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDekMsMEJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQWtCLENBQUM7UUFDdEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUM3Qyw2QkFBd0IsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBQ2xELDhCQUF5QixHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7UUFFM0QsdURBQXVEO1FBQ3ZELFlBQU8sR0FBcUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5RCxrRkFBa0Y7UUFDbEYsaUJBQVksR0FBcUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXhFLG9CQUFlLEdBQ2IsSUFBSSxDQUFD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QUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVELElBQUksV0FBVzs7UUFDYixPQUFPLENBQUEsTUFBQSxJQUFJLENBQUMsRUFBRSwwQ0FBRSxVQUFVLE1BQUssU0FBUyxDQUFDLElBQUksQ0FBQztJQUNoRCxDQUFDOzs7O1lBaktGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7O1lBakNvQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbi8qKiBXZWJTb2NrZXQgbWVzc2FnZSB0eXBlcyBmcm9tIGJhY2tlbmQgKHZvaWNlIHNlc3Npb24gb3ZlciBhIHNpbmdsZSBXUykuICovXG5leHBvcnQgaW50ZXJmYWNlIFdzTWVzc2FnZVVzZXJUcmFuc2NyaXB0IHtcbiAgdHlwZTogJ3VzZXJfdHJhbnNjcmlwdCc7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdzTWVzc2FnZUJvdFRyYW5zY3JpcHQge1xuICB0eXBlOiAnYm90X3RyYW5zY3JpcHQnO1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFdzTWVzc2FnZSA9XG4gIHwgV3NNZXNzYWdlVXNlclRyYW5zY3JpcHRcbiAgfCBXc01lc3NhZ2VCb3RUcmFuc2NyaXB0O1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zY3JpcHREYXRhIHtcbiAgdGV4dDogc3RyaW5nO1xuICBmaW5hbDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBOYXRpdmUgV2ViU29ja2V0IGNsaWVudCBmb3Igdm9pY2Ugc2Vzc2lvbiAoc2lnbmFsaW5nLCB0cmFuc2NyaXB0cywgc3BlYWtpbmcgaGludHMpLlxuICogQ1JJVElDQUw6IFVzZXMgbmF0aXZlIFdlYlNvY2tldCBvbmx5LiBOTyBTb2NrZXQuSU8sIE5PIG5neC1zb2NrZXQtaW8uXG4gKlxuICogQ29ubmVjdHMgdG8gYHdzX3VybGAgZnJvbSBgUE9TVCB7YmFzZVVybH0vYWkvYXNrLXZvaWNlLXNvY2tldGAuXG4gKiBQYXJzZXMgSlNPTiBtZXNzYWdlcyBmb3IgdHJhbnNjcmlwdHMgYW5kIG9wdGlvbmFsIGFzc2lzdGFudC91c2VyIHNwZWFraW5nIGZsYWdzLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlIHtcbiAgcHJpdmF0ZSB3czogV2ViU29ja2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUcnVlIHdoZW4ge0BsaW5rIGRpc2Nvbm5lY3R9IGluaXRpYXRlZCB0aGUgY2xvc2UgKG5vdCBjb3VudGVkIGFzIHJlbW90ZSBjbG9zZSkuICovXG4gIHByaXZhdGUgY2xvc2VJbml0aWF0ZWRCeUNsaWVudCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgb3BlbmVkU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVtb3RlQ2xvc2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSB1c2VyVHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUcmFuc2NyaXB0RGF0YT4oKTtcbiAgcHJpdmF0ZSBib3RUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRTcGVha2luZ1N1YmplY3QgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICBwcml2YXRlIHNlcnZlclVzZXJTcGVha2luZ1N1YmplY3QgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gIC8qKiBGaXJlcyBvbmNlIGVhY2ggdGltZSB0aGUgV2ViU29ja2V0IHJlYWNoZXMgT1BFTi4gKi9cbiAgb3BlbmVkJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMub3BlbmVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogRmlyZXMgd2hlbiB0aGUgc29ja2V0IGNsb3NlcyB3aXRob3V0IGEgY2xpZW50LWluaXRpYXRlZCB7QGxpbmsgZGlzY29ubmVjdH0uICovXG4gIHJlbW90ZUNsb3NlJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPVxuICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPVxuICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIEFzc2lzdGFudC9ib3Qgc3BlYWtpbmcsIHdoZW4gdGhlIHNlcnZlciBzZW5kcyBleHBsaWNpdCBldmVudHMgKHNlZSB7QGxpbmsgaGFuZGxlSnNvbk1lc3NhZ2V9KS4gKi9cbiAgYXNzaXN0YW50U3BlYWtpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID1cbiAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVXNlciBzcGVha2luZyBmcm9tIHNlcnZlci1zaWRlIFZBRCwgaWYgcHJvdmlkZWQuICovXG4gIHNlcnZlclVzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHRoaXMuc2VydmVyVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5nWm9uZTogTmdab25lKSB7fVxuXG4gIGNvbm5lY3Qod3NVcmw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLndzPy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy53cykge1xuICAgICAgdGhpcy5jbG9zZUluaXRpYXRlZEJ5Q2xpZW50ID0gdHJ1ZTtcbiAgICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc29ja2V0ID0gbmV3IFdlYlNvY2tldCh3c1VybCk7XG4gICAgICB0aGlzLndzID0gc29ja2V0O1xuICAgICAgc29ja2V0Lm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgIT09IHNvY2tldCkgcmV0dXJuO1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vcGVuZWRTdWJqZWN0Lm5leHQoKSk7XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICAgIGlmICh0aGlzLndzICE9PSBzb2NrZXQpIHJldHVybjtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudC5kYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IEpTT04ucGFyc2UoZXZlbnQuZGF0YSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlSnNvbk1lc3NhZ2UobXNnKSk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIElnbm9yZSBub24tSlNPTlxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMud3MgPT09IHNvY2tldCAmJiBzb2NrZXQucmVhZHlTdGF0ZSAhPT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBzb2NrZXQub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgPT09IHNvY2tldCkge1xuICAgICAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xvc2VJbml0aWF0ZWRCeUNsaWVudDtcbiAgICAgICAgdGhpcy5jbG9zZUluaXRpYXRlZEJ5Q2xpZW50ID0gZmFsc2U7XG4gICAgICAgIGlmICghY2xpZW50KSB7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0Lm5leHQoKSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdXZWJTb2NrZXRWb2ljZUNsaWVudDogY29ubmVjdCBmYWlsZWQnLCBlcnIpO1xuICAgICAgdGhpcy53cyA9IG51bGw7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uTWVzc2FnZShtc2c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gICAgY29uc3QgdHlwZSA9IG1zZy50eXBlO1xuICAgIGNvbnN0IHR5cGVTdHIgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlIDogJyc7XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3Nlc3Npb25fcmVhZHknIHx8IHR5cGVTdHIgPT09ICdjb25uZWN0ZWQnIHx8IHR5cGVTdHIgPT09ICd2b2ljZV9zZXNzaW9uX3N0YXJ0ZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZVN0ciA9PT0gJ2Fzc2lzdGFudF9zcGVha2luZycgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdib3Rfc3BlYWtpbmcnXG4gICAgKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5hc3Npc3RhbnRTcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAobXNnLmFjdGl2ZSA9PT0gZmFsc2UgfHwgbXNnLnNwZWFraW5nID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3VzZXJfc3BlYWtpbmcnKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5hY3RpdmUgPT09IGZhbHNlIHx8IG1zZy5zcGVha2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdGFydGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZGVsdGEnKSB7XG4gICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZG9uZScgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdyZXNwb25zZS5vdXRwdXRfYXVkaW8uZG9uZSdcbiAgICApIHtcbiAgICAgIHRoaXMuYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAndXNlcl90cmFuc2NyaXB0JyAmJiB0eXBlb2YgbXNnLnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5uZXh0KHtcbiAgICAgICAgdGV4dDogbXNnLnRleHQsXG4gICAgICAgIGZpbmFsOiBtc2cuZmluYWwgPT09IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVTdHIgPT09ICdib3RfdHJhbnNjcmlwdCcgJiYgdHlwZW9mIG1zZy50ZXh0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KG1zZy50ZXh0KTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy53cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgfVxuXG4gIGdldCBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU47XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { NgZone } from '@angular/core';
|
|
2
|
-
import { Observable } from 'rxjs';
|
|
3
|
-
/** WebSocket message types from backend (voice session over a single WS). */
|
|
4
|
-
export interface WsMessageUserTranscript {
|
|
5
|
-
type: 'user_transcript';
|
|
6
|
-
text: string;
|
|
7
|
-
final?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface WsMessageBotTranscript {
|
|
10
|
-
type: 'bot_transcript';
|
|
11
|
-
text: string;
|
|
12
|
-
}
|
|
13
|
-
export declare type WsMessage = WsMessageUserTranscript | WsMessageBotTranscript;
|
|
14
|
-
export interface TranscriptData {
|
|
15
|
-
text: string;
|
|
16
|
-
final: boolean;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Native WebSocket client for voice session (signaling, transcripts, speaking hints).
|
|
20
|
-
* CRITICAL: Uses native WebSocket only. NO Socket.IO, NO ngx-socket-io.
|
|
21
|
-
*
|
|
22
|
-
* Connects to `ws_url` from `POST {baseUrl}/ai/ask-voice-socket`.
|
|
23
|
-
* Parses JSON messages for transcripts and optional assistant/user speaking flags.
|
|
24
|
-
*/
|
|
25
|
-
export declare class WebSocketVoiceClientService {
|
|
26
|
-
private ngZone;
|
|
27
|
-
private ws;
|
|
28
|
-
/** True when {@link disconnect} initiated the close (not counted as remote close). */
|
|
29
|
-
private closeInitiatedByClient;
|
|
30
|
-
private openedSubject;
|
|
31
|
-
private remoteCloseSubject;
|
|
32
|
-
private userTranscriptSubject;
|
|
33
|
-
private botTranscriptSubject;
|
|
34
|
-
private assistantSpeakingSubject;
|
|
35
|
-
private serverUserSpeakingSubject;
|
|
36
|
-
/** Fires once each time the WebSocket reaches OPEN. */
|
|
37
|
-
opened$: Observable<void>;
|
|
38
|
-
/** Fires when the socket closes without a client-initiated {@link disconnect}. */
|
|
39
|
-
remoteClose$: Observable<void>;
|
|
40
|
-
userTranscript$: Observable<TranscriptData>;
|
|
41
|
-
botTranscript$: Observable<string>;
|
|
42
|
-
/** Assistant/bot speaking, when the server sends explicit events (see {@link handleJsonMessage}). */
|
|
43
|
-
assistantSpeaking$: Observable<boolean>;
|
|
44
|
-
/** User speaking from server-side VAD, if provided. */
|
|
45
|
-
serverUserSpeaking$: Observable<boolean>;
|
|
46
|
-
constructor(ngZone: NgZone);
|
|
47
|
-
connect(wsUrl: string): void;
|
|
48
|
-
private handleJsonMessage;
|
|
49
|
-
disconnect(): void;
|
|
50
|
-
get isConnected(): boolean;
|
|
51
|
-
}
|
|
52
|
-
//# sourceMappingURL=websocket-voice-client.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-voice-client.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/websocket-voice-client.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAE3C,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oBAAY,SAAS,GACjB,uBAAuB,GACvB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAGa,2BAA2B;IAgC1B,OAAO,CAAC,MAAM;IA/B1B,OAAO,CAAC,EAAE,CAA0B;IACpC,sFAAsF;IACtF,OAAO,CAAC,sBAAsB,CAAS;IAEvC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,qBAAqB,CAAiC;IAC9D,OAAO,CAAC,oBAAoB,CAAyB;IACrD,OAAO,CAAC,wBAAwB,CAA0B;IAC1D,OAAO,CAAC,yBAAyB,CAA0B;IAE3D,uDAAuD;IACvD,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAqC;IAE9D,kFAAkF;IAClF,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,CAA0C;IAExE,eAAe,EAAE,UAAU,CAAC,cAAc,CAAC,CACC;IAE5C,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CACS;IAE3C,qGAAqG;IACrG,kBAAkB,EAAE,UAAU,CAAC,OAAO,CAAC,CACQ;IAE/C,uDAAuD;IACvD,mBAAmB,EAAE,UAAU,CAAC,OAAO,CAAC,CACQ;gBAE5B,MAAM,EAAE,MAAM;IAElC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAoD5B,OAAO,CAAC,iBAAiB;IA8DzB,UAAU,IAAI,IAAI;IAQlB,IAAI,WAAW,IAAI,OAAO,CAEzB;CACF"}
|