@hivegpt/hiveai-angular 0.0.582 → 0.0.583

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.
@@ -34,6 +34,9 @@ export class VoiceAgentService {
34
34
  this.callStartTime = 0;
35
35
  this.durationInterval = null;
36
36
  this.localMicStream = null;
37
+ this.remoteAudioContext = null;
38
+ this.pendingRemoteAudio = [];
39
+ this.remoteAudioPlaying = false;
37
40
  this.endCall$ = new Subject();
38
41
  this.subscriptions = new Subscription();
39
42
  this.destroy$ = new Subject();
@@ -49,6 +52,9 @@ export class VoiceAgentService {
49
52
  this.subscriptions.add(this.wsClient.remoteClose$
50
53
  .pipe(takeUntil(this.destroy$))
51
54
  .subscribe(() => void this.handleRemoteClose()));
55
+ this.subscriptions.add(this.wsClient.audioChunk$
56
+ .pipe(takeUntil(this.destroy$))
57
+ .subscribe((chunk) => this.enqueueRemoteAudio(chunk)));
52
58
  }
53
59
  ngOnDestroy() {
54
60
  this.destroy$.next();
@@ -64,6 +70,7 @@ export class VoiceAgentService {
64
70
  this.callStartTime = 0;
65
71
  this.audioAnalyzer.stop();
66
72
  this.stopLocalMic();
73
+ this.resetRemoteAudioPlayback();
67
74
  this.wsClient.disconnect();
68
75
  this.callStateSubject.next('idle');
69
76
  this.statusTextSubject.next('');
@@ -218,6 +225,76 @@ export class VoiceAgentService {
218
225
  this.localMicStream = null;
219
226
  }
220
227
  }
228
+ enqueueRemoteAudio(chunk) {
229
+ this.pendingRemoteAudio.push(chunk.slice(0));
230
+ if (!this.remoteAudioPlaying) {
231
+ void this.playRemoteAudioQueue();
232
+ }
233
+ }
234
+ playRemoteAudioQueue() {
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ this.remoteAudioPlaying = true;
237
+ const context = this.getOrCreateRemoteAudioContext();
238
+ while (this.pendingRemoteAudio.length > 0) {
239
+ const chunk = this.pendingRemoteAudio.shift();
240
+ if (!chunk)
241
+ continue;
242
+ try {
243
+ const decoded = yield this.decodeAudioChunk(context, chunk);
244
+ this.assistantAudioStarted();
245
+ yield this.playDecodedBuffer(context, decoded);
246
+ }
247
+ catch (_a) {
248
+ // Ignore undecodable chunks; server may mix non-audio binary events.
249
+ }
250
+ }
251
+ this.remoteAudioPlaying = false;
252
+ this.assistantAudioStopped();
253
+ });
254
+ }
255
+ getOrCreateRemoteAudioContext() {
256
+ if (!this.remoteAudioContext || this.remoteAudioContext.state === 'closed') {
257
+ this.remoteAudioContext = new AudioContext();
258
+ }
259
+ if (this.remoteAudioContext.state === 'suspended') {
260
+ void this.remoteAudioContext.resume();
261
+ }
262
+ return this.remoteAudioContext;
263
+ }
264
+ decodeAudioChunk(context, chunk) {
265
+ return new Promise((resolve, reject) => {
266
+ context.decodeAudioData(chunk.slice(0), resolve, reject);
267
+ });
268
+ }
269
+ playDecodedBuffer(context, buffer) {
270
+ return new Promise((resolve) => {
271
+ const source = context.createBufferSource();
272
+ source.buffer = buffer;
273
+ source.connect(context.destination);
274
+ source.onended = () => resolve();
275
+ source.start();
276
+ });
277
+ }
278
+ assistantAudioStarted() {
279
+ if (this.callStartTime === 0) {
280
+ this.callStartTime = Date.now();
281
+ this.startDurationTimer();
282
+ }
283
+ this.callStateSubject.next('talking');
284
+ }
285
+ assistantAudioStopped() {
286
+ if (this.callStateSubject.value === 'talking') {
287
+ this.callStateSubject.next('connected');
288
+ }
289
+ }
290
+ resetRemoteAudioPlayback() {
291
+ this.pendingRemoteAudio = [];
292
+ this.remoteAudioPlaying = false;
293
+ if (this.remoteAudioContext && this.remoteAudioContext.state !== 'closed') {
294
+ this.remoteAudioContext.close().catch(() => { });
295
+ }
296
+ this.remoteAudioContext = null;
297
+ }
221
298
  handleRemoteClose() {
222
299
  return __awaiter(this, void 0, void 0, function* () {
223
300
  const state = this.callStateSubject.value;
@@ -228,6 +305,7 @@ export class VoiceAgentService {
228
305
  this.callStartTime = 0;
229
306
  this.audioAnalyzer.stop();
230
307
  this.stopLocalMic();
308
+ this.resetRemoteAudioPlayback();
231
309
  this.callStateSubject.next('ended');
232
310
  this.statusTextSubject.next('Connection lost');
233
311
  });
@@ -239,6 +317,7 @@ export class VoiceAgentService {
239
317
  this.callStartTime = 0;
240
318
  this.audioAnalyzer.stop();
241
319
  this.stopLocalMic();
320
+ this.resetRemoteAudioPlayback();
242
321
  this.wsClient.disconnect();
243
322
  this.callStateSubject.next('ended');
244
323
  this.statusTextSubject.next('Call Ended');
@@ -284,4 +363,4 @@ VoiceAgentService.ctorParameters = () => [
284
363
  { type: PlatformTokenRefreshService },
285
364
  { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
286
365
  ];
287
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBQ2IsTUFBTSxFQUNOLEtBQUssRUFFTCxFQUFFLEVBQ0YsT0FBTyxFQUNQLFlBQVksRUFDWixLQUFLLEdBQ04sTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLEdBQUcsRUFDSCxTQUFTLEVBQ1QsU0FBUyxFQUNULElBQUksRUFDSixTQUFTLEdBQ1YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUMvRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7QUFlL0U7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxpQkFBaUI7SUE4QjVCLFlBQ1UsYUFBbUMsRUFDbkMsUUFBcUMsRUFDckMsb0JBQWlEO0lBQ3pELDhGQUE4RjtJQUNqRSxVQUFrQjtRQUp2QyxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFDbkMsYUFBUSxHQUFSLFFBQVEsQ0FBNkI7UUFDckMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUE2QjtRQUU1QixlQUFV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LE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FDakQsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsY0FBYyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN6QixhQUFhLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztTQUM5QjtJQUNILENBQUM7Ozs7WUE1VEYsVUFBVSxTQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COzs7WUF2QlEsb0JBQW9CO1lBQ3BCLDJCQUEyQjtZQUYzQiwyQkFBMkI7WUE0RFMsTUFBTSx1QkFBOUMsTUFBTSxTQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9uRGVzdHJveSwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgY29tYmluZUxhdGVzdCxcbiAgY29uY2F0LFxuICBtZXJnZSxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIFN1YmplY3QsXG4gIFN1YnNjcmlwdGlvbixcbiAgdGltZXIsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIG1hcCxcbiAgc3RhcnRXaXRoLFxuICBzd2l0Y2hNYXAsXG4gIHRha2UsXG4gIHRha2VVbnRpbCxcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgUGxhdGZvcm1Ub2tlblJlZnJlc2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcGxhdGZvcm0tdG9rZW4tcmVmcmVzaC5zZXJ2aWNlJztcbmltcG9ydCB7IEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIH0gZnJvbSAnLi9hdWRpby1hbmFseXplci5zZXJ2aWNlJztcbmltcG9ydCB7IFdlYlNvY2tldFZvaWNlQ2xpZW50U2VydmljZSB9IGZyb20gJy4vd2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlJztcblxuZXhwb3J0IHR5cGUgQ2FsbFN0YXRlID1cbiAgfCAnaWRsZSdcbiAgfCAnY29ubmVjdGluZydcbiAgfCAnY29ubmVjdGVkJ1xuICB8ICdsaXN0ZW5pbmcnXG4gIHwgJ3RhbGtpbmcnXG4gIHwgJ2VuZGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2NyaXB0RGF0YSB7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVm9pY2UgYWdlbnQgb3JjaGVzdHJhdG9yOiBzaW5nbGUgV2ViU29ja2V0IChgd3NfdXJsYCBmcm9tIFBPU1QgL2FpL2Fzay12b2ljZS1zb2NrZXQpXG4gKiBmb3Igc2Vzc2lvbiBldmVudHMsIHRyYW5zY3JpcHRzLCBhbmQgb3B0aW9uYWwgc3BlYWtpbmcgaGludHM7IGxvY2FsIG1pYyBmb3IgY2FwdHVyZVxuICogYW5kIHdhdmVmb3JtIG9ubHkgKG5vIERhaWx5L1dlYlJUQyByb29tKS5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFZvaWNlQWdlbnRTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBjYWxsU3RhdGVTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDYWxsU3RhdGU+KCdpZGxlJyk7XG4gIHByaXZhdGUgc3RhdHVzVGV4dFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuICBwcml2YXRlIGR1cmF0aW9uU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignMDA6MDAnKTtcbiAgcHJpdmF0ZSBpc01pY011dGVkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGlzVXNlclNwZWFraW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGF1ZGlvTGV2ZWxzU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyW10+KFtdKTtcbiAgcHJpdmF0ZSB1c2VyVHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUcmFuc2NyaXB0RGF0YT4oKTtcbiAgcHJpdmF0ZSBib3RUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcblxuICBwcml2YXRlIGNhbGxTdGFydFRpbWUgPSAwO1xuICBwcml2YXRlIGR1cmF0aW9uSW50ZXJ2YWw6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgbG9jYWxNaWNTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5kQ2FsbCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgY2FsbFN0YXRlJDogT2JzZXJ2YWJsZTxDYWxsU3RhdGU+ID0gdGhpcy5jYWxsU3RhdGVTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBzdGF0dXNUZXh0JDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgZHVyYXRpb24kOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmR1cmF0aW9uU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgaXNNaWNNdXRlZCQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmlzTWljTXV0ZWRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBpc1VzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBhdWRpb0xldmVscyQ6IE9ic2VydmFibGU8bnVtYmVyW10+ID0gdGhpcy5hdWRpb0xldmVsc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPVxuICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBib3RUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGF1ZGlvQW5hbHl6ZXI6IEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgd3NDbGllbnQ6IFdlYlNvY2tldFZvaWNlQ2xpZW50U2VydmljZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtVG9rZW5SZWZyZXNoOiBQbGF0Zm9ybVRva2VuUmVmcmVzaFNlcnZpY2UsXG4gICAgLyoqIGBPYmplY3RgIG5vdCBgb2JqZWN0YCDigJQgbmdjIG1ldGFkYXRhIGNvbGxlY3Rpb24gcmVqZWN0cyB0aGUgYG9iamVjdGAgdHlwZSBpbiBESSBwYXJhbXMuICovXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3QsXG4gICkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuYXVkaW9MZXZlbHMkLnN1YnNjcmliZSgobGV2ZWxzKSA9PlxuICAgICAgICB0aGlzLmF1ZGlvTGV2ZWxzU3ViamVjdC5uZXh0KGxldmVscyksXG4gICAgICApLFxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMud3NDbGllbnQucmVtb3RlQ2xvc2UkXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB2b2lkIHRoaXMuaGFuZGxlUmVtb3RlQ2xvc2UoKSksXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgLyoqIFJlc2V0IHRvIGlkbGUgc3RhdGUgKGUuZy4gd2hlbiBtb2RhbCBvcGVucyBzbyB1c2VyIGNhbiBjbGljayBTdGFydCBDYWxsKS4gKi9cbiAgcmVzZXRUb0lkbGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSA9PT0gJ2lkbGUnKSByZXR1cm47XG4gICAgdGhpcy5lbmRDYWxsJC5uZXh0KCk7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BMb2NhbE1pYygpO1xuICAgIHRoaXMud3NDbGllbnQuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdpZGxlJyk7XG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCcnKTtcbiAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KCcwOjAwJyk7XG4gIH1cblxuICBhc3luYyBjb25uZWN0KFxuICAgIGFwaVVybDogc3RyaW5nLFxuICAgIHRva2VuOiBzdHJpbmcsXG4gICAgYm90SWQ6IHN0cmluZyxcbiAgICBjb252ZXJzYXRpb25JZDogc3RyaW5nLFxuICAgIGFwaUtleTogc3RyaW5nLFxuICAgIGV2ZW50VG9rZW46IHN0cmluZyxcbiAgICBldmVudElkOiBzdHJpbmcsXG4gICAgZXZlbnRVcmw6IHN0cmluZyxcbiAgICBkb21haW5BdXRob3JpdHk6IHN0cmluZyxcbiAgICB1c2Vyc0FwaVVybD86IHN0cmluZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSAhPT0gJ2lkbGUnKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0NhbGwgYWxyZWFkeSBpbiBwcm9ncmVzcycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnY29ubmVjdGluZycpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW5nLi4uJyk7XG5cbiAgICAgIGxldCBhY2Nlc3NUb2tlbiA9IHRva2VuO1xuICAgICAgaWYgKHVzZXJzQXBpVXJsICYmIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBlbnN1cmVkID0gYXdhaXQgdGhpcy5wbGF0Zm9ybVRva2VuUmVmcmVzaFxuICAgICAgICAgICAgLmVuc3VyZVZhbGlkQWNjZXNzVG9rZW4odG9rZW4sIHVzZXJzQXBpVXJsKVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKTtcbiAgICAgICAgICBpZiAoZW5zdXJlZD8uYWNjZXNzVG9rZW4pIHtcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuID0gZW5zdXJlZC5hY2Nlc3NUb2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAnW0hpdmVHcHQgVm9pY2VdIFRva2VuIHJlZnJlc2ggYmVmb3JlIGNvbm5lY3QgZmFpbGVkJyxcbiAgICAgICAgICAgIGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBiYXNlVXJsID0gYXBpVXJsLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG4gICAgICBjb25zdCBwb3N0VXJsID0gYCR7YmFzZVVybH0vYWkvYXNrLXZvaWNlLXNvY2tldGA7XG5cbiAgICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gLFxuICAgICAgICAneC1hcGkta2V5JzogYXBpS2V5LFxuICAgICAgICAnaGl2ZS1ib3QtaWQnOiBib3RJZCxcbiAgICAgICAgJ2RvbWFpbi1hdXRob3JpdHknOiBkb21haW5BdXRob3JpdHksXG4gICAgICAgIGV2ZW50VXJsLFxuICAgICAgICBldmVudElkLFxuICAgICAgICBldmVudFRva2VuLFxuICAgICAgICAnbmdyb2stc2tpcC1icm93c2VyLXdhcm5pbmcnOiAndHJ1ZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChwb3N0VXJsLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgYm90X2lkOiBib3RJZCxcbiAgICAgICAgICBjb252ZXJzYXRpb25faWQ6IGNvbnZlcnNhdGlvbklkLFxuICAgICAgICAgIHZvaWNlOiAnYWxsb3knLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIXJlcy5vaykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgJHtyZXMuc3RhdHVzfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBqc29uID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGNvbnN0IHdzVXJsID1cbiAgICAgICAgKHR5cGVvZiBqc29uPy53c191cmwgPT09ICdzdHJpbmcnICYmIGpzb24ud3NfdXJsKSB8fFxuICAgICAgICAodHlwZW9mIGpzb24/LnJuX3dzX3VybCA9PT0gJ3N0cmluZycgJiYganNvbi5ybl93c191cmwpO1xuICAgICAgaWYgKCF3c1VybCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHdzX3VybCBpbiByZXNwb25zZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1bnRpbENhbGxFbmRzJCA9IG1lcmdlKHRoaXMuZGVzdHJveSQsIHRoaXMuZW5kQ2FsbCQpO1xuXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgICB0aGlzLndzQ2xpZW50LnVzZXJUcmFuc2NyaXB0JFxuICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbENhbGxFbmRzJCkpXG4gICAgICAgICAgLnN1YnNjcmliZSgodCkgPT4gdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QubmV4dCh0KSksXG4gICAgICApO1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgdGhpcy53c0NsaWVudC5ib3RUcmFuc2NyaXB0JFxuICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbENhbGxFbmRzJCkpXG4gICAgICAgICAgLnN1YnNjcmliZSgodCkgPT4gdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KHQpKSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICAgIHRoaXMud3NDbGllbnQub3BlbmVkJFxuICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbENhbGxFbmRzJCksIHRha2UoMSkpXG4gICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB2b2lkIHRoaXMub25XZWJzb2NrZXRPcGVuZWQoKSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLndzQ2xpZW50LmNvbm5lY3Qod3NVcmwpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjb25uZWN0aW5nIHZvaWNlIGFnZW50OicsIGVycm9yKTtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdlbmRlZCcpO1xuICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3Rpb24gZmFpbGVkJyk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9uV2Vic29ja2V0T3BlbmVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgIT09ICdjb25uZWN0aW5nJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zdGFydExvY2FsTWljKCk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3RlZCcpO1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgdGhpcy53aXJlU3BlYWtpbmdTdGF0ZSgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignW0hpdmVHcHQgVm9pY2VdIE1pYyBvciBzZXNzaW9uIHNldHVwIGZhaWxlZCcsIGVycik7XG4gICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnTWljcm9waG9uZSB1bmF2YWlsYWJsZScpO1xuICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB3aXJlU3BlYWtpbmdTdGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCB1bnRpbENhbGxFbmRzJCA9IG1lcmdlKHRoaXMuZGVzdHJveSQsIHRoaXMuZW5kQ2FsbCQpO1xuXG4gICAgY29uc3QgdHJhbnNjcmlwdERyaXZlbkFzc2lzdGFudCQgPSB0aGlzLndzQ2xpZW50LmJvdFRyYW5zY3JpcHQkLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gY29uY2F0KG9mKHRydWUpLCB0aW1lcig4MDApLnBpcGUobWFwKCgpID0+IGZhbHNlKSkpKSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgKTtcblxuICAgIGNvbnN0IGFzc2lzdGFudFRhbGtpbmckID0gbWVyZ2UoXG4gICAgICB0aGlzLndzQ2xpZW50LmFzc2lzdGFudFNwZWFraW5nJCxcbiAgICAgIHRyYW5zY3JpcHREcml2ZW5Bc3Npc3RhbnQkLFxuICAgICkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCBzdGFydFdpdGgoZmFsc2UpKTtcblxuICAgIGNvbnN0IHVzZXJUYWxraW5nJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5hdWRpb0FuYWx5emVyLmlzVXNlclNwZWFraW5nJCxcbiAgICAgIHRoaXMud3NDbGllbnQuc2VydmVyVXNlclNwZWFraW5nJC5waXBlKHN0YXJ0V2l0aChmYWxzZSkpLFxuICAgIF0pLnBpcGUoXG4gICAgICBtYXAoKFtsb2NhbCwgc2VydmVyXSkgPT4gbG9jYWwgfHwgc2VydmVyKSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzdGFydFdpdGgoZmFsc2UpLFxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgY29tYmluZUxhdGVzdChbYXNzaXN0YW50VGFsa2luZyQsIHVzZXJUYWxraW5nJF0pXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbENhbGxFbmRzJCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKFtib3QsIHVzZXJdKSA9PiB7XG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZTtcbiAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdsaXN0ZW5pbmcnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChib3QpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPT09IDApIHtcbiAgICAgICAgICAgICAgdGhpcy5jYWxsU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgdGhpcy5zdGFydER1cmF0aW9uVGltZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCd0YWxraW5nJyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50ID09PSAndGFsa2luZycgfHwgY3VycmVudCA9PT0gJ2xpc3RlbmluZycpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHN0YXJ0TG9jYWxNaWMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zdG9wTG9jYWxNaWMoKTtcbiAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7IGF1ZGlvOiB0cnVlIH0pO1xuICAgIGNvbnN0IHRyYWNrID0gc3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgaWYgKCF0cmFjaykge1xuICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHQpID0+IHQuc3RvcCgpKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYXVkaW8gdHJhY2snKTtcbiAgICB9XG4gICAgdGhpcy5sb2NhbE1pY1N0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLmlzTWljTXV0ZWRTdWJqZWN0Lm5leHQoIXRyYWNrLmVuYWJsZWQpO1xuICAgIHRoaXMuYXVkaW9BbmFseXplci5zdGFydChzdHJlYW0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wTG9jYWxNaWMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9jYWxNaWNTdHJlYW0pIHtcbiAgICAgIHRoaXMubG9jYWxNaWNTdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodCkgPT4gdC5zdG9wKCkpO1xuICAgICAgdGhpcy5sb2NhbE1pY1N0cmVhbSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVSZW1vdGVDbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdpZGxlJyB8fCBzdGF0ZSA9PT0gJ2VuZGVkJykgcmV0dXJuO1xuICAgIHRoaXMuZW5kQ2FsbCQubmV4dCgpO1xuICAgIHRoaXMuc3RvcER1cmF0aW9uVGltZXIoKTtcbiAgICB0aGlzLmNhbGxTdGFydFRpbWUgPSAwO1xuICAgIHRoaXMuYXVkaW9BbmFseXplci5zdG9wKCk7XG4gICAgdGhpcy5zdG9wTG9jYWxNaWMoKTtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3Rpb24gbG9zdCcpO1xuICB9XG5cbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmVuZENhbGwkLm5leHQoKTtcbiAgICB0aGlzLnN0b3BEdXJhdGlvblRpbWVyKCk7XG4gICAgdGhpcy5jYWxsU3RhcnRUaW1lID0gMDtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RvcCgpO1xuICAgIHRoaXMuc3RvcExvY2FsTWljKCk7XG4gICAgdGhpcy53c0NsaWVudC5kaXNjb25uZWN0KCk7XG5cbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHRvZ2dsZU1pYygpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0TXV0ZWQgPSAhdGhpcy5pc01pY011dGVkU3ViamVjdC52YWx1ZTtcbiAgICBjb25zdCB0cmFjayA9IHRoaXMubG9jYWxNaWNTdHJlYW0/LmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgaWYgKHRyYWNrKSB7XG4gICAgICB0cmFjay5lbmFibGVkID0gIW5leHRNdXRlZDtcbiAgICB9XG4gICAgdGhpcy5pc01pY011dGVkU3ViamVjdC5uZXh0KG5leHRNdXRlZCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0RHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVEdXJhdGlvbiA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGhpcy5jYWxsU3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gNjApO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KFxuICAgICAgICAgIGAke21pbnV0ZXN9OiR7U3RyaW5nKHNlY29uZHMpLnBhZFN0YXJ0KDIsICcwJyl9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHVwZGF0ZUR1cmF0aW9uKCk7XG4gICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwodXBkYXRlRHVyYXRpb24sIDEwMDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kdXJhdGlvbkludGVydmFsKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuZHVyYXRpb25JbnRlcnZhbCk7XG4gICAgICB0aGlzLmR1cmF0aW9uSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuIl19
366
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBQ2IsTUFBTSxFQUNOLEtBQUssRUFFTCxFQUFFLEVBQ0YsT0FBTyxFQUNQLFlBQVksRUFDWixLQUFLLEdBQ04sTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLEdBQUcsRUFDSCxTQUFTLEVBQ1QsU0FBUyxFQUNULElBQUksRUFDSixTQUFTLEdBQ1YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUMvRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7QUFlL0U7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxpQkFBaUI7SUFpQzVCLFlBQ1UsYUFBbUMsRUFDbkMsUUFBcUMsRUFDckMsb0JBQWlEO0lBQ3pELDhGQUE4RjtJQUNqRSxVQUFrQjtRQUp2QyxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFDbkMsYUFBUSxHQUFSLFFBQVEsQ0FBNkI7UUFDckMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUE2QjtRQUU1QixlQUFV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LEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQzs7OztZQXZaRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQXZCUSxvQkFBb0I7WUFDcEIsMkJBQTJCO1lBRjNCLDJCQUEyQjtZQStEUyxNQUFNLHVCQUE5QyxNQUFNLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQmVoYXZpb3JTdWJqZWN0LFxuICBjb21iaW5lTGF0ZXN0LFxuICBjb25jYXQsXG4gIG1lcmdlLFxuICBPYnNlcnZhYmxlLFxuICBvZixcbiAgU3ViamVjdCxcbiAgU3Vic2NyaXB0aW9uLFxuICB0aW1lcixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgbWFwLFxuICBzdGFydFdpdGgsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZSxcbiAgdGFrZVVudGlsLFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBQbGF0Zm9ybVRva2VuUmVmcmVzaFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9wbGF0Zm9ybS10b2tlbi1yZWZyZXNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXVkaW9BbmFseXplclNlcnZpY2UgfSBmcm9tICcuL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlIH0gZnJvbSAnLi93ZWJzb2NrZXQtdm9pY2UtY2xpZW50LnNlcnZpY2UnO1xuXG5leHBvcnQgdHlwZSBDYWxsU3RhdGUgPVxuICB8ICdpZGxlJ1xuICB8ICdjb25uZWN0aW5nJ1xuICB8ICdjb25uZWN0ZWQnXG4gIHwgJ2xpc3RlbmluZydcbiAgfCAndGFsa2luZydcbiAgfCAnZW5kZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zY3JpcHREYXRhIHtcbiAgdGV4dDogc3RyaW5nO1xuICBmaW5hbDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBWb2ljZSBhZ2VudCBvcmNoZXN0cmF0b3I6IHNpbmdsZSBXZWJTb2NrZXQgKGB3c191cmxgIGZyb20gUE9TVCAvYWkvYXNrLXZvaWNlLXNvY2tldClcbiAqIGZvciBzZXNzaW9uIGV2ZW50cywgdHJhbnNjcmlwdHMsIGFuZCBvcHRpb25hbCBzcGVha2luZyBoaW50czsgbG9jYWwgbWljIGZvciBjYXB0dXJlXG4gKiBhbmQgd2F2ZWZvcm0gb25seSAobm8gRGFpbHkvV2ViUlRDIHJvb20pLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VBZ2VudFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGNhbGxTdGF0ZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENhbGxTdGF0ZT4oJ2lkbGUnKTtcbiAgcHJpdmF0ZSBzdGF0dXNUZXh0U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG4gIHByaXZhdGUgZHVyYXRpb25TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcwMDowMCcpO1xuICBwcml2YXRlIGlzTWljTXV0ZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgaXNVc2VyU3BlYWtpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgYXVkaW9MZXZlbHNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXJbXT4oW10pO1xuICBwcml2YXRlIHVzZXJUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PFRyYW5zY3JpcHREYXRhPigpO1xuICBwcml2YXRlIGJvdFRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuXG4gIHByaXZhdGUgY2FsbFN0YXJ0VGltZSA9IDA7XG4gIHByaXZhdGUgZHVyYXRpb25JbnRlcnZhbDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBsb2NhbE1pY1N0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZW1vdGVBdWRpb0NvbnRleHQ6IEF1ZGlvQ29udGV4dCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHBlbmRpbmdSZW1vdGVBdWRpbzogQXJyYXlCdWZmZXJbXSA9IFtdO1xuICBwcml2YXRlIHJlbW90ZUF1ZGlvUGxheWluZyA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWRvbmx5IGVuZENhbGwkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNhbGxTdGF0ZSQ6IE9ic2VydmFibGU8Q2FsbFN0YXRlPiA9IHRoaXMuY2FsbFN0YXRlU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgc3RhdHVzVGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuc3RhdHVzVGV4dFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGR1cmF0aW9uJDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5kdXJhdGlvblN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzTWljTXV0ZWQkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5pc01pY011dGVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgaXNVc2VyU3BlYWtpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID1cbiAgICB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYXVkaW9MZXZlbHMkOiBPYnNlcnZhYmxlPG51bWJlcltdPiA9IHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB1c2VyVHJhbnNjcmlwdCQ6IE9ic2VydmFibGU8VHJhbnNjcmlwdERhdGE+ID1cbiAgICB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYm90VHJhbnNjcmlwdCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhdWRpb0FuYWx5emVyOiBBdWRpb0FuYWx5emVyU2VydmljZSxcbiAgICBwcml2YXRlIHdzQ2xpZW50OiBXZWJTb2NrZXRWb2ljZUNsaWVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybVRva2VuUmVmcmVzaDogUGxhdGZvcm1Ub2tlblJlZnJlc2hTZXJ2aWNlLFxuICAgIC8qKiBgT2JqZWN0YCBub3QgYG9iamVjdGAg4oCUIG5nYyBtZXRhZGF0YSBjb2xsZWN0aW9uIHJlamVjdHMgdGhlIGBvYmplY3RgIHR5cGUgaW4gREkgcGFyYW1zLiAqL1xuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxuICApIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5hdWRpb0FuYWx5emVyLmF1ZGlvTGV2ZWxzJC5zdWJzY3JpYmUoKGxldmVscykgPT5cbiAgICAgICAgdGhpcy5hdWRpb0xldmVsc1N1YmplY3QubmV4dChsZXZlbHMpLFxuICAgICAgKSxcbiAgICApO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLndzQ2xpZW50LnJlbW90ZUNsb3NlJFxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdm9pZCB0aGlzLmhhbmRsZVJlbW90ZUNsb3NlKCkpLFxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMud3NDbGllbnQuYXVkaW9DaHVuayRcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKChjaHVuaykgPT4gdGhpcy5lbnF1ZXVlUmVtb3RlQXVkaW8oY2h1bmspKSxcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICAvKiogUmVzZXQgdG8gaWRsZSBzdGF0ZSAoZS5nLiB3aGVuIG1vZGFsIG9wZW5zIHNvIHVzZXIgY2FuIGNsaWNrIFN0YXJ0IENhbGwpLiAqL1xuICByZXNldFRvSWRsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAnaWRsZScpIHJldHVybjtcbiAgICB0aGlzLmVuZENhbGwkLm5leHQoKTtcbiAgICB0aGlzLnN0b3BEdXJhdGlvblRpbWVyKCk7XG4gICAgdGhpcy5jYWxsU3RhcnRUaW1lID0gMDtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RvcCgpO1xuICAgIHRoaXMuc3RvcExvY2FsTWljKCk7XG4gICAgdGhpcy5yZXNldFJlbW90ZUF1ZGlvUGxheWJhY2soKTtcbiAgICB0aGlzLndzQ2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnaWRsZScpO1xuICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnJyk7XG4gICAgdGhpcy5kdXJhdGlvblN1YmplY3QubmV4dCgnMDowMCcpO1xuICB9XG5cbiAgYXN5bmMgY29ubmVjdChcbiAgICBhcGlVcmw6IHN0cmluZyxcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIGJvdElkOiBzdHJpbmcsXG4gICAgY29udmVyc2F0aW9uSWQ6IHN0cmluZyxcbiAgICBhcGlLZXk6IHN0cmluZyxcbiAgICBldmVudFRva2VuOiBzdHJpbmcsXG4gICAgZXZlbnRJZDogc3RyaW5nLFxuICAgIGV2ZW50VXJsOiBzdHJpbmcsXG4gICAgZG9tYWluQXV0aG9yaXR5OiBzdHJpbmcsXG4gICAgdXNlcnNBcGlVcmw/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgIT09ICdpZGxlJykge1xuICAgICAgY29uc29sZS53YXJuKCdDYWxsIGFscmVhZHkgaW4gcHJvZ3Jlc3MnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RpbmcnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ29ubmVjdGluZy4uLicpO1xuXG4gICAgICBsZXQgYWNjZXNzVG9rZW4gPSB0b2tlbjtcbiAgICAgIGlmICh1c2Vyc0FwaVVybCAmJiBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZW5zdXJlZCA9IGF3YWl0IHRoaXMucGxhdGZvcm1Ub2tlblJlZnJlc2hcbiAgICAgICAgICAgIC5lbnN1cmVWYWxpZEFjY2Vzc1Rva2VuKHRva2VuLCB1c2Vyc0FwaVVybClcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAudG9Qcm9taXNlKCk7XG4gICAgICAgICAgaWYgKGVuc3VyZWQ/LmFjY2Vzc1Rva2VuKSB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbiA9IGVuc3VyZWQuYWNjZXNzVG9rZW47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgJ1tIaXZlR3B0IFZvaWNlXSBUb2tlbiByZWZyZXNoIGJlZm9yZSBjb25uZWN0IGZhaWxlZCcsXG4gICAgICAgICAgICBlLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFzZVVybCA9IGFwaVVybC5yZXBsYWNlKC9cXC8kLywgJycpO1xuICAgICAgY29uc3QgcG9zdFVybCA9IGAke2Jhc2VVcmx9L2FpL2Fzay12b2ljZS1zb2NrZXRgO1xuXG4gICAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YWNjZXNzVG9rZW59YCxcbiAgICAgICAgJ3gtYXBpLWtleSc6IGFwaUtleSxcbiAgICAgICAgJ2hpdmUtYm90LWlkJzogYm90SWQsXG4gICAgICAgICdkb21haW4tYXV0aG9yaXR5JzogZG9tYWluQXV0aG9yaXR5LFxuICAgICAgICBldmVudFVybCxcbiAgICAgICAgZXZlbnRJZCxcbiAgICAgICAgZXZlbnRUb2tlbixcbiAgICAgICAgJ25ncm9rLXNraXAtYnJvd3Nlci13YXJuaW5nJzogJ3RydWUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2gocG9zdFVybCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIGJvdF9pZDogYm90SWQsXG4gICAgICAgICAgY29udmVyc2F0aW9uX2lkOiBjb252ZXJzYXRpb25JZCxcbiAgICAgICAgICB2b2ljZTogJ2FsbG95JyxcbiAgICAgICAgfSksXG4gICAgICB9KTtcblxuICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c31gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QganNvbiA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBjb25zdCB3c1VybCA9XG4gICAgICAgICh0eXBlb2YganNvbj8ud3NfdXJsID09PSAnc3RyaW5nJyAmJiBqc29uLndzX3VybCkgfHxcbiAgICAgICAgKHR5cGVvZiBqc29uPy5ybl93c191cmwgPT09ICdzdHJpbmcnICYmIGpzb24ucm5fd3NfdXJsKTtcbiAgICAgIGlmICghd3NVcmwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB3c191cmwgaW4gcmVzcG9uc2UnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdW50aWxDYWxsRW5kcyQgPSBtZXJnZSh0aGlzLmRlc3Ryb3kkLCB0aGlzLmVuZENhbGwkKTtcblxuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgdGhpcy53c0NsaWVudC51c2VyVHJhbnNjcmlwdCRcbiAgICAgICAgICAucGlwZSh0YWtlVW50aWwodW50aWxDYWxsRW5kcyQpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKHQpID0+IHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0Lm5leHQodCkpLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICAgIHRoaXMud3NDbGllbnQuYm90VHJhbnNjcmlwdCRcbiAgICAgICAgICAucGlwZSh0YWtlVW50aWwodW50aWxDYWxsRW5kcyQpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKHQpID0+IHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QubmV4dCh0KSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgICB0aGlzLndzQ2xpZW50Lm9wZW5lZCRcbiAgICAgICAgICAucGlwZSh0YWtlVW50aWwodW50aWxDYWxsRW5kcyQpLCB0YWtlKDEpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdm9pZCB0aGlzLm9uV2Vic29ja2V0T3BlbmVkKCkpLFxuICAgICAgKTtcblxuICAgICAgdGhpcy53c0NsaWVudC5jb25uZWN0KHdzVXJsKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY29ubmVjdGluZyB2b2ljZSBhZ2VudDonLCBlcnJvcik7XG4gICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW9uIGZhaWxlZCcpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBvbldlYnNvY2tldE9wZW5lZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlICE9PSAnY29ubmVjdGluZycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRMb2NhbE1pYygpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0ZWQnKTtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICAgIHRoaXMud2lyZVNwZWFraW5nU3RhdGUoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tIaXZlR3B0IFZvaWNlXSBNaWMgb3Igc2Vzc2lvbiBzZXR1cCBmYWlsZWQnLCBlcnIpO1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ01pY3JvcGhvbmUgdW5hdmFpbGFibGUnKTtcbiAgICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgd2lyZVNwZWFraW5nU3RhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgdW50aWxDYWxsRW5kcyQgPSBtZXJnZSh0aGlzLmRlc3Ryb3kkLCB0aGlzLmVuZENhbGwkKTtcblxuICAgIGNvbnN0IHRyYW5zY3JpcHREcml2ZW5Bc3Npc3RhbnQkID0gdGhpcy53c0NsaWVudC5ib3RUcmFuc2NyaXB0JC5waXBlKFxuICAgICAgc3dpdGNoTWFwKCgpID0+IGNvbmNhdChvZih0cnVlKSwgdGltZXIoODAwKS5waXBlKG1hcCgoKSA9PiBmYWxzZSkpKSksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICk7XG5cbiAgICBjb25zdCBhc3Npc3RhbnRUYWxraW5nJCA9IG1lcmdlKFxuICAgICAgdGhpcy53c0NsaWVudC5hc3Npc3RhbnRTcGVha2luZyQsXG4gICAgICB0cmFuc2NyaXB0RHJpdmVuQXNzaXN0YW50JCxcbiAgICApLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgc3RhcnRXaXRoKGZhbHNlKSk7XG5cbiAgICBjb25zdCB1c2VyVGFsa2luZyQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIHRoaXMuYXVkaW9BbmFseXplci5pc1VzZXJTcGVha2luZyQsXG4gICAgICB0aGlzLndzQ2xpZW50LnNlcnZlclVzZXJTcGVha2luZyQucGlwZShzdGFydFdpdGgoZmFsc2UpKSxcbiAgICBdKS5waXBlKFxuICAgICAgbWFwKChbbG9jYWwsIHNlcnZlcl0pID0+IGxvY2FsIHx8IHNlcnZlciksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgc3RhcnRXaXRoKGZhbHNlKSxcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIGNvbWJpbmVMYXRlc3QoW2Fzc2lzdGFudFRhbGtpbmckLCB1c2VyVGFsa2luZyRdKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodW50aWxDYWxsRW5kcyQpKVxuICAgICAgICAuc3Vic2NyaWJlKChbYm90LCB1c2VyXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWU7XG4gICAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnbGlzdGVuaW5nJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYm90KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jYWxsU3RhcnRUaW1lID09PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgIHRoaXMuc3RhcnREdXJhdGlvblRpbWVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA9PT0gJ3RhbGtpbmcnIHx8IGN1cnJlbnQgPT09ICdsaXN0ZW5pbmcnKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnY29ubmVjdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydExvY2FsTWljKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcExvY2FsTWljKCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyBhdWRpbzogdHJ1ZSB9KTtcbiAgICBjb25zdCB0cmFjayA9IHN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgIGlmICghdHJhY2spIHtcbiAgICAgIHN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKCh0KSA9PiB0LnN0b3AoKSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGF1ZGlvIHRyYWNrJyk7XG4gICAgfVxuICAgIHRoaXMubG9jYWxNaWNTdHJlYW0gPSBzdHJlYW07XG4gICAgdGhpcy5pc01pY011dGVkU3ViamVjdC5uZXh0KCF0cmFjay5lbmFibGVkKTtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RhcnQoc3RyZWFtKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcExvY2FsTWljKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvY2FsTWljU3RyZWFtKSB7XG4gICAgICB0aGlzLmxvY2FsTWljU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHQpID0+IHQuc3RvcCgpKTtcbiAgICAgIHRoaXMubG9jYWxNaWNTdHJlYW0gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW5xdWV1ZVJlbW90ZUF1ZGlvKGNodW5rOiBBcnJheUJ1ZmZlcik6IHZvaWQge1xuICAgIHRoaXMucGVuZGluZ1JlbW90ZUF1ZGlvLnB1c2goY2h1bmsuc2xpY2UoMCkpO1xuICAgIGlmICghdGhpcy5yZW1vdGVBdWRpb1BsYXlpbmcpIHtcbiAgICAgIHZvaWQgdGhpcy5wbGF5UmVtb3RlQXVkaW9RdWV1ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGxheVJlbW90ZUF1ZGlvUXVldWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZW1vdGVBdWRpb1BsYXlpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldE9yQ3JlYXRlUmVtb3RlQXVkaW9Db250ZXh0KCk7XG4gICAgd2hpbGUgKHRoaXMucGVuZGluZ1JlbW90ZUF1ZGlvLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNodW5rID0gdGhpcy5wZW5kaW5nUmVtb3RlQXVkaW8uc2hpZnQoKTtcbiAgICAgIGlmICghY2h1bmspIGNvbnRpbnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb2RlZCA9IGF3YWl0IHRoaXMuZGVjb2RlQXVkaW9DaHVuayhjb250ZXh0LCBjaHVuayk7XG4gICAgICAgIHRoaXMuYXNzaXN0YW50QXVkaW9TdGFydGVkKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucGxheURlY29kZWRCdWZmZXIoY29udGV4dCwgZGVjb2RlZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIHVuZGVjb2RhYmxlIGNodW5rczsgc2VydmVyIG1heSBtaXggbm9uLWF1ZGlvIGJpbmFyeSBldmVudHMuXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVtb3RlQXVkaW9QbGF5aW5nID0gZmFsc2U7XG4gICAgdGhpcy5hc3Npc3RhbnRBdWRpb1N0b3BwZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVSZW1vdGVBdWRpb0NvbnRleHQoKTogQXVkaW9Db250ZXh0IHtcbiAgICBpZiAoIXRoaXMucmVtb3RlQXVkaW9Db250ZXh0IHx8IHRoaXMucmVtb3RlQXVkaW9Db250ZXh0LnN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQgPSBuZXcgQXVkaW9Db250ZXh0KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgIHZvaWQgdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dDtcbiAgfVxuXG4gIHByaXZhdGUgZGVjb2RlQXVkaW9DaHVuayhcbiAgICBjb250ZXh0OiBBdWRpb0NvbnRleHQsXG4gICAgY2h1bms6IEFycmF5QnVmZmVyLFxuICApOiBQcm9taXNlPEF1ZGlvQnVmZmVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGNodW5rLnNsaWNlKDApLCByZXNvbHZlLCByZWplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGF5RGVjb2RlZEJ1ZmZlcihcbiAgICBjb250ZXh0OiBBdWRpb0NvbnRleHQsXG4gICAgYnVmZmVyOiBBdWRpb0J1ZmZlcixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBjb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgc291cmNlLmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgIHNvdXJjZS5jb25uZWN0KGNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgc291cmNlLm9uZW5kZWQgPSAoKSA9PiByZXNvbHZlKCk7XG4gICAgICBzb3VyY2Uuc3RhcnQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXNzaXN0YW50QXVkaW9TdGFydGVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPT09IDApIHtcbiAgICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0aGlzLnN0YXJ0RHVyYXRpb25UaW1lcigpO1xuICAgIH1cbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3Npc3RhbnRBdWRpb1N0b3BwZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSA9PT0gJ3RhbGtpbmcnKSB7XG4gICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnY29ubmVjdGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZXNldFJlbW90ZUF1ZGlvUGxheWJhY2soKTogdm9pZCB7XG4gICAgdGhpcy5wZW5kaW5nUmVtb3RlQXVkaW8gPSBbXTtcbiAgICB0aGlzLnJlbW90ZUF1ZGlvUGxheWluZyA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCAmJiB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgIHRoaXMucmVtb3RlQXVkaW9Db250ZXh0LmNsb3NlKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgIH1cbiAgICB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVJlbW90ZUNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2lkbGUnIHx8IHN0YXRlID09PSAnZW5kZWQnKSByZXR1cm47XG4gICAgdGhpcy5lbmRDYWxsJC5uZXh0KCk7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BMb2NhbE1pYygpO1xuICAgIHRoaXMucmVzZXRSZW1vdGVBdWRpb1BsYXliYWNrKCk7XG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW9uIGxvc3QnKTtcbiAgfVxuXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5lbmRDYWxsJC5uZXh0KCk7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BMb2NhbE1pYygpO1xuICAgIHRoaXMucmVzZXRSZW1vdGVBdWRpb1BsYXliYWNrKCk7XG4gICAgdGhpcy53c0NsaWVudC5kaXNjb25uZWN0KCk7XG5cbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHRvZ2dsZU1pYygpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0TXV0ZWQgPSAhdGhpcy5pc01pY011dGVkU3ViamVjdC52YWx1ZTtcbiAgICBjb25zdCB0cmFjayA9IHRoaXMubG9jYWxNaWNTdHJlYW0/LmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgaWYgKHRyYWNrKSB7XG4gICAgICB0cmFjay5lbmFibGVkID0gIW5leHRNdXRlZDtcbiAgICB9XG4gICAgdGhpcy5pc01pY011dGVkU3ViamVjdC5uZXh0KG5leHRNdXRlZCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0RHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVEdXJhdGlvbiA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGhpcy5jYWxsU3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gNjApO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KFxuICAgICAgICAgIGAke21pbnV0ZXN9OiR7U3RyaW5nKHNlY29uZHMpLnBhZFN0YXJ0KDIsICcwJyl9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHVwZGF0ZUR1cmF0aW9uKCk7XG4gICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwodXBkYXRlRHVyYXRpb24sIDEwMDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kdXJhdGlvbkludGVydmFsKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuZHVyYXRpb25JbnRlcnZhbCk7XG4gICAgICB0aGlzLmR1cmF0aW9uSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -1,3 +1,4 @@
1
+ import { __awaiter } from "tslib";
1
2
  import { Injectable, NgZone } from '@angular/core';
2
3
  import { Subject } from 'rxjs';
3
4
  import * as i0 from "@angular/core";
@@ -20,6 +21,7 @@ export class WebSocketVoiceClientService {
20
21
  this.botTranscriptSubject = new Subject();
21
22
  this.assistantSpeakingSubject = new Subject();
22
23
  this.serverUserSpeakingSubject = new Subject();
24
+ this.audioChunkSubject = new Subject();
23
25
  /** Fires once each time the WebSocket reaches OPEN. */
24
26
  this.opened$ = this.openedSubject.asObservable();
25
27
  /** Fires when the socket closes without a client-initiated {@link disconnect}. */
@@ -30,6 +32,8 @@ export class WebSocketVoiceClientService {
30
32
  this.assistantSpeaking$ = this.assistantSpeakingSubject.asObservable();
31
33
  /** User speaking from server-side VAD, if provided. */
32
34
  this.serverUserSpeaking$ = this.serverUserSpeakingSubject.asObservable();
35
+ /** Binary audio frames from server (when backend streams bot audio over WS). */
36
+ this.audioChunk$ = this.audioChunkSubject.asObservable();
33
37
  }
34
38
  connect(wsUrl) {
35
39
  var _a;
@@ -51,16 +55,7 @@ export class WebSocketVoiceClientService {
51
55
  socket.onmessage = (event) => {
52
56
  if (this.ws !== socket)
53
57
  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
- }
58
+ void this.handleIncomingMessage(event.data);
64
59
  };
65
60
  socket.onerror = () => {
66
61
  this.ngZone.run(() => {
@@ -86,6 +81,54 @@ export class WebSocketVoiceClientService {
86
81
  throw err;
87
82
  }
88
83
  }
84
+ handleIncomingMessage(payload) {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ if (typeof payload === 'string') {
87
+ this.handleJsonString(payload);
88
+ return;
89
+ }
90
+ if (payload instanceof ArrayBuffer) {
91
+ this.handleBinaryMessage(payload);
92
+ return;
93
+ }
94
+ if (payload instanceof Blob) {
95
+ const ab = yield payload.arrayBuffer();
96
+ this.handleBinaryMessage(ab);
97
+ }
98
+ });
99
+ }
100
+ handleJsonString(jsonText) {
101
+ try {
102
+ const msg = JSON.parse(jsonText);
103
+ this.ngZone.run(() => this.handleJsonMessage(msg));
104
+ }
105
+ catch (_a) {
106
+ // Ignore non-JSON
107
+ }
108
+ }
109
+ handleBinaryMessage(buffer) {
110
+ // Some backends wrap JSON events inside binary WS frames.
111
+ const maybeText = this.tryDecodeUtf8(buffer);
112
+ if (maybeText !== null) {
113
+ this.handleJsonString(maybeText);
114
+ return;
115
+ }
116
+ // Otherwise treat binary as streamed assistant audio.
117
+ this.ngZone.run(() => this.audioChunkSubject.next(buffer));
118
+ }
119
+ tryDecodeUtf8(buffer) {
120
+ try {
121
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(buffer);
122
+ const trimmed = text.trim();
123
+ if (!trimmed || (trimmed[0] !== '{' && trimmed[0] !== '[')) {
124
+ return null;
125
+ }
126
+ return trimmed;
127
+ }
128
+ catch (_a) {
129
+ return null;
130
+ }
131
+ }
89
132
  handleJsonMessage(msg) {
90
133
  const type = msg.type;
91
134
  const typeStr = typeof type === 'string' ? type : '';
@@ -160,4 +203,4 @@ WebSocketVoiceClientService.decorators = [
160
203
  WebSocketVoiceClientService.ctorParameters = () => [
161
204
  { type: NgZone }
162
205
  ];
163
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL3dlYnNvY2tldC12b2ljZS1jbGllbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQXVCM0M7Ozs7OztHQU1HO0FBSUgsTUFBTSxPQUFPLDJCQUEyQjtJQWdDdEMsWUFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUEvQjFCLE9BQUUsR0FBcUIsSUFBSSxDQUFDO1FBQ3BDLHNGQUFzRjtRQUM5RSwyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFFL0Isa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3BDLHVCQUFrQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDekMsMEJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQWtCLENBQUM7UUFDdEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUM3Qyw2QkFBd0IsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBQ2xELDhCQUF5QixHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7UUFFM0QsdURBQXVEO1FBQ3ZELFlBQU8sR0FBcUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5RCxrRkFBa0Y7UUFDbEYsaUJBQVksR0FBcUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXhFLG9CQUFlLEdBQ2IsSUFBSSxDQUFD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QUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVELElBQUksV0FBVzs7UUFDYixPQUFPLENBQUEsTUFBQSxJQUFJLENBQUMsRUFBRSwwQ0FBRSxVQUFVLE1BQUssU0FBUyxDQUFDLElBQUksQ0FBQztJQUNoRCxDQUFDOzs7O1lBaktGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7O1lBakNvQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbi8qKiBXZWJTb2NrZXQgbWVzc2FnZSB0eXBlcyBmcm9tIGJhY2tlbmQgKHZvaWNlIHNlc3Npb24gb3ZlciBhIHNpbmdsZSBXUykuICovXG5leHBvcnQgaW50ZXJmYWNlIFdzTWVzc2FnZVVzZXJUcmFuc2NyaXB0IHtcbiAgdHlwZTogJ3VzZXJfdHJhbnNjcmlwdCc7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdzTWVzc2FnZUJvdFRyYW5zY3JpcHQge1xuICB0eXBlOiAnYm90X3RyYW5zY3JpcHQnO1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFdzTWVzc2FnZSA9XG4gIHwgV3NNZXNzYWdlVXNlclRyYW5zY3JpcHRcbiAgfCBXc01lc3NhZ2VCb3RUcmFuc2NyaXB0O1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zY3JpcHREYXRhIHtcbiAgdGV4dDogc3RyaW5nO1xuICBmaW5hbDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBOYXRpdmUgV2ViU29ja2V0IGNsaWVudCBmb3Igdm9pY2Ugc2Vzc2lvbiAoc2lnbmFsaW5nLCB0cmFuc2NyaXB0cywgc3BlYWtpbmcgaGludHMpLlxuICogQ1JJVElDQUw6IFVzZXMgbmF0aXZlIFdlYlNvY2tldCBvbmx5LiBOTyBTb2NrZXQuSU8sIE5PIG5neC1zb2NrZXQtaW8uXG4gKlxuICogQ29ubmVjdHMgdG8gYHdzX3VybGAgZnJvbSBgUE9TVCB7YmFzZVVybH0vYWkvYXNrLXZvaWNlLXNvY2tldGAuXG4gKiBQYXJzZXMgSlNPTiBtZXNzYWdlcyBmb3IgdHJhbnNjcmlwdHMgYW5kIG9wdGlvbmFsIGFzc2lzdGFudC91c2VyIHNwZWFraW5nIGZsYWdzLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlIHtcbiAgcHJpdmF0ZSB3czogV2ViU29ja2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUcnVlIHdoZW4ge0BsaW5rIGRpc2Nvbm5lY3R9IGluaXRpYXRlZCB0aGUgY2xvc2UgKG5vdCBjb3VudGVkIGFzIHJlbW90ZSBjbG9zZSkuICovXG4gIHByaXZhdGUgY2xvc2VJbml0aWF0ZWRCeUNsaWVudCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgb3BlbmVkU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVtb3RlQ2xvc2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSB1c2VyVHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUcmFuc2NyaXB0RGF0YT4oKTtcbiAgcHJpdmF0ZSBib3RUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRTcGVha2luZ1N1YmplY3QgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICBwcml2YXRlIHNlcnZlclVzZXJTcGVha2luZ1N1YmplY3QgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gIC8qKiBGaXJlcyBvbmNlIGVhY2ggdGltZSB0aGUgV2ViU29ja2V0IHJlYWNoZXMgT1BFTi4gKi9cbiAgb3BlbmVkJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMub3BlbmVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogRmlyZXMgd2hlbiB0aGUgc29ja2V0IGNsb3NlcyB3aXRob3V0IGEgY2xpZW50LWluaXRpYXRlZCB7QGxpbmsgZGlzY29ubmVjdH0uICovXG4gIHJlbW90ZUNsb3NlJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPVxuICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPVxuICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIEFzc2lzdGFudC9ib3Qgc3BlYWtpbmcsIHdoZW4gdGhlIHNlcnZlciBzZW5kcyBleHBsaWNpdCBldmVudHMgKHNlZSB7QGxpbmsgaGFuZGxlSnNvbk1lc3NhZ2V9KS4gKi9cbiAgYXNzaXN0YW50U3BlYWtpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID1cbiAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVXNlciBzcGVha2luZyBmcm9tIHNlcnZlci1zaWRlIFZBRCwgaWYgcHJvdmlkZWQuICovXG4gIHNlcnZlclVzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHRoaXMuc2VydmVyVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5nWm9uZTogTmdab25lKSB7fVxuXG4gIGNvbm5lY3Qod3NVcmw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLndzPy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy53cykge1xuICAgICAgdGhpcy5jbG9zZUluaXRpYXRlZEJ5Q2xpZW50ID0gdHJ1ZTtcbiAgICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc29ja2V0ID0gbmV3IFdlYlNvY2tldCh3c1VybCk7XG4gICAgICB0aGlzLndzID0gc29ja2V0O1xuICAgICAgc29ja2V0Lm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgIT09IHNvY2tldCkgcmV0dXJuO1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vcGVuZWRTdWJqZWN0Lm5leHQoKSk7XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICAgIGlmICh0aGlzLndzICE9PSBzb2NrZXQpIHJldHVybjtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudC5kYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IEpTT04ucGFyc2UoZXZlbnQuZGF0YSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlSnNvbk1lc3NhZ2UobXNnKSk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIElnbm9yZSBub24tSlNPTlxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMud3MgPT09IHNvY2tldCAmJiBzb2NrZXQucmVhZHlTdGF0ZSAhPT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBzb2NrZXQub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgPT09IHNvY2tldCkge1xuICAgICAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xvc2VJbml0aWF0ZWRCeUNsaWVudDtcbiAgICAgICAgdGhpcy5jbG9zZUluaXRpYXRlZEJ5Q2xpZW50ID0gZmFsc2U7XG4gICAgICAgIGlmICghY2xpZW50KSB7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0Lm5leHQoKSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdXZWJTb2NrZXRWb2ljZUNsaWVudDogY29ubmVjdCBmYWlsZWQnLCBlcnIpO1xuICAgICAgdGhpcy53cyA9IG51bGw7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uTWVzc2FnZShtc2c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gICAgY29uc3QgdHlwZSA9IG1zZy50eXBlO1xuICAgIGNvbnN0IHR5cGVTdHIgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlIDogJyc7XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3Nlc3Npb25fcmVhZHknIHx8IHR5cGVTdHIgPT09ICdjb25uZWN0ZWQnIHx8IHR5cGVTdHIgPT09ICd2b2ljZV9zZXNzaW9uX3N0YXJ0ZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZVN0ciA9PT0gJ2Fzc2lzdGFudF9zcGVha2luZycgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdib3Rfc3BlYWtpbmcnXG4gICAgKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5hc3Npc3RhbnRTcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAobXNnLmFjdGl2ZSA9PT0gZmFsc2UgfHwgbXNnLnNwZWFraW5nID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3VzZXJfc3BlYWtpbmcnKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5hY3RpdmUgPT09IGZhbHNlIHx8IG1zZy5zcGVha2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdGFydGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZGVsdGEnKSB7XG4gICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZG9uZScgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdyZXNwb25zZS5vdXRwdXRfYXVkaW8uZG9uZSdcbiAgICApIHtcbiAgICAgIHRoaXMuYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAndXNlcl90cmFuc2NyaXB0JyAmJiB0eXBlb2YgbXNnLnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5uZXh0KHtcbiAgICAgICAgdGV4dDogbXNnLnRleHQsXG4gICAgICAgIGZpbmFsOiBtc2cuZmluYWwgPT09IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVTdHIgPT09ICdib3RfdHJhbnNjcmlwdCcgJiYgdHlwZW9mIG1zZy50ZXh0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KG1zZy50ZXh0KTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy53cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgfVxuXG4gIGdldCBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU47XG4gIH1cbn1cbiJdfQ==
206
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL3dlYnNvY2tldC12b2ljZS1jbGllbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUF1QjNDOzs7Ozs7R0FNRztBQUlILE1BQU0sT0FBTywyQkFBMkI7SUFvQ3RDLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBbkMxQixPQUFFLEdBQXFCLElBQUksQ0FBQztRQUNwQyxzRkFBc0Y7UUFDOUUsMkJBQXNCLEdBQUcsS0FBSyxDQUFDO1FBRS9CLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUNwQyx1QkFBa0IsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3pDLDBCQUFxQixHQUFHLElBQUksT0FBTyxFQUFrQixDQUFDO1FBQ3RELHlCQUFvQixHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFDN0MsNkJBQXdCLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNsRCw4QkFBeUIsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBQ25ELHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFFdkQsdURBQXVEO1FBQ3ZELFlBQU8sR0FBcUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5RCxrRkFBa0Y7UUFDbEYsaUJBQVksR0FBcUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXhFLG9CQUFlLEdBQ2IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRTVDLG1CQUFjLEdBQ1osSUFBSSxDQUFDLG9CQUFvQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRTNDLHFHQUFxRztRQUNyRyx1QkFBa0IsR0FDaEIsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRS9DLHVEQUF1RDtRQUN2RCx3QkFBbUIsR0FDakIsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRWhELGdGQUFnRjtRQUNoRixnQkFBVyxHQUE0QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFeEMsQ0FBQztJQUV0QyxPQUFPLENBQUMsS0FBYTs7UUFDbkIsSUFBSSxDQUFBLE1BQUEsSUFBSSxDQUFDLEVBQUUsMENBQUUsVUFBVSxNQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUU7WUFDMUMsT0FBTztTQUNSO1FBQ0QsSUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ1gsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztZQUNuQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ2pCO1FBRUQsSUFBSTtZQUNGLE1BQU0sTUFBTSxHQUFHLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO2dCQUNuQixJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssTUFBTTtvQkFBRSxPQUFPO2dCQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQW1CLEVBQUUsRUFBRTtnQkFDekMsSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLE1BQU07b0JBQUUsT0FBTztnQkFDL0IsS0FBSyxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxPQUFPLEdBQUcsR0FBRyxFQUFFO2dCQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ25CLElBQUksSUFBSSxDQUFDLEVBQUUsS0FBSyxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsTUFBTSxFQUFFO3dCQUNoRSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7cUJBQ2hCO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLE9BQU8sR0FBRyxHQUFHLEVBQUU7Z0JBQ3BCLElBQUksSUFBSSxDQUFDLEVBQUUsS0FBSyxNQUFNLEVBQUU7b0JBQ3RCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDO2lCQUNoQjtnQkFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxLQUFLLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7aUJBQ3ZEO1lBQ0gsQ0FBQyxDQUFDO1NBQ0g7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7WUFDZixNQUFNLEdBQUcsQ0FBQztTQUNYO0lBQ0gsQ0FBQztJQUVhLHFCQUFxQixDQUFDLE9BQWdCOztZQUNsRCxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtnQkFDL0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMvQixPQUFPO2FBQ1I7WUFDRCxJQUFJLE9BQU8sWUFBWSxXQUFXLEVBQUU7Z0JBQ2xDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbEMsT0FBTzthQUNSO1lBQ0QsSUFBSSxPQUFPLFlBQVksSUFBSSxFQUFFO2dCQUMzQixNQUFNLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQzlCO1FBQ0gsQ0FBQztLQUFBO0lBRU8sZ0JBQWdCLENBQUMsUUFBZ0I7UUFDdkMsSUFBSTtZQUNGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUE0QixDQUFDO1lBQzVELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQ3BEO1FBQUMsV0FBTTtZQUNOLGtCQUFrQjtTQUNuQjtJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxNQUFtQjtRQUM3QywwREFBMEQ7UUFDMUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUU7WUFDdEIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pDLE9BQU87U0FDUjtRQUNELHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVPLGFBQWEsQ0FBQyxNQUFtQjtRQUN2QyxJQUFJO1lBQ0YsTUFBTSxJQUFJLEdBQUcsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUU7Z0JBQzFELE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCxPQUFPLE9BQU8sQ0FBQztTQUNoQjtRQUFDLFdBQU07WUFDTixPQUFPLElBQUksQ0FBQztTQUNiO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQixDQUFDLEdBQTRCO1FBQ3BELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDdEIsTUFBTSxPQUFPLEdBQUcsT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUVyRCxJQUFJLE9BQU8sS0FBSyxlQUFlLElBQUksT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLEtBQUssdUJBQXVCLEVBQUU7WUFDakcsT0FBTztTQUNSO1FBRUQsSUFDRSxPQUFPLEtBQUssb0JBQW9CO1lBQ2hDLE9BQU8sS0FBSyxjQUFjLEVBQzFCO1lBQ0EsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLElBQUksSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtnQkFDaEQsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUMxQztpQkFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxRQUFRLEtBQUssS0FBSyxFQUFFO2dCQUN6RCxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzNDO1lBQ0QsT0FBTztTQUNSO1FBRUQsSUFBSSxPQUFPLEtBQUssZUFBZSxFQUFFO1lBQy9CLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUU7Z0JBQ2hELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDM0M7aUJBQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRTtnQkFDekQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QztZQUNELE9BQU87U0FDUjtRQUVELElBQUksT0FBTyxLQUFLLG1DQUFtQyxFQUFFO1lBQ25ELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsT0FBTztTQUNSO1FBQ0QsSUFBSSxPQUFPLEtBQUssbUNBQW1DLEVBQUU7WUFDbkQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxPQUFPO1NBQ1I7UUFFRCxJQUFJLE9BQU8sS0FBSyxzQkFBc0IsRUFBRTtZQUN0QyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLE9BQU87U0FDUjtRQUNELElBQ0UsT0FBTyxLQUFLLHFCQUFxQjtZQUNqQyxPQUFPLEtBQUssNEJBQTRCLEVBQ3hDO1lBQ0EsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxPQUFPO1NBQ1I7UUFFRCxJQUFJLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxPQUFPLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQ2pFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUM7Z0JBQzlCLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtnQkFDZCxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssS0FBSyxJQUFJO2FBQzFCLENBQUMsQ0FBQztZQUNILE9BQU87U0FDUjtRQUNELElBQUksT0FBTyxLQUFLLGdCQUFnQixJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7WUFDaEUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDMUM7SUFDSCxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ1osT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxJQUFJLFdBQVc7O1FBQ2IsT0FBTyxDQUFBLE1BQUEsSUFBSSxDQUFDLEVBQUUsMENBQUUsVUFBVSxNQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDaEQsQ0FBQzs7OztZQTdNRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQWpDb0IsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG4vKiogV2ViU29ja2V0IG1lc3NhZ2UgdHlwZXMgZnJvbSBiYWNrZW5kICh2b2ljZSBzZXNzaW9uIG92ZXIgYSBzaW5nbGUgV1MpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBXc01lc3NhZ2VVc2VyVHJhbnNjcmlwdCB7XG4gIHR5cGU6ICd1c2VyX3RyYW5zY3JpcHQnO1xuICB0ZXh0OiBzdHJpbmc7XG4gIGZpbmFsPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXc01lc3NhZ2VCb3RUcmFuc2NyaXB0IHtcbiAgdHlwZTogJ2JvdF90cmFuc2NyaXB0JztcbiAgdGV4dDogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBXc01lc3NhZ2UgPVxuICB8IFdzTWVzc2FnZVVzZXJUcmFuc2NyaXB0XG4gIHwgV3NNZXNzYWdlQm90VHJhbnNjcmlwdDtcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2NyaXB0RGF0YSB7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw6IGJvb2xlYW47XG59XG5cbi8qKlxuICogTmF0aXZlIFdlYlNvY2tldCBjbGllbnQgZm9yIHZvaWNlIHNlc3Npb24gKHNpZ25hbGluZywgdHJhbnNjcmlwdHMsIHNwZWFraW5nIGhpbnRzKS5cbiAqIENSSVRJQ0FMOiBVc2VzIG5hdGl2ZSBXZWJTb2NrZXQgb25seS4gTk8gU29ja2V0LklPLCBOTyBuZ3gtc29ja2V0LWlvLlxuICpcbiAqIENvbm5lY3RzIHRvIGB3c191cmxgIGZyb20gYFBPU1Qge2Jhc2VVcmx9L2FpL2Fzay12b2ljZS1zb2NrZXRgLlxuICogUGFyc2VzIEpTT04gbWVzc2FnZXMgZm9yIHRyYW5zY3JpcHRzIGFuZCBvcHRpb25hbCBhc3Npc3RhbnQvdXNlciBzcGVha2luZyBmbGFncy5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFdlYlNvY2tldFZvaWNlQ2xpZW50U2VydmljZSB7XG4gIHByaXZhdGUgd3M6IFdlYlNvY2tldCB8IG51bGwgPSBudWxsO1xuICAvKiogVHJ1ZSB3aGVuIHtAbGluayBkaXNjb25uZWN0fSBpbml0aWF0ZWQgdGhlIGNsb3NlIChub3QgY291bnRlZCBhcyByZW1vdGUgY2xvc2UpLiAqL1xuICBwcml2YXRlIGNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSBmYWxzZTtcblxuICBwcml2YXRlIG9wZW5lZFN1YmplY3QgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlbW90ZUNsb3NlU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgdXNlclRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8VHJhbnNjcmlwdERhdGE+KCk7XG4gIHByaXZhdGUgYm90VHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG4gIHByaXZhdGUgYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSBzZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSBhdWRpb0NodW5rU3ViamVjdCA9IG5ldyBTdWJqZWN0PEFycmF5QnVmZmVyPigpO1xuXG4gIC8qKiBGaXJlcyBvbmNlIGVhY2ggdGltZSB0aGUgV2ViU29ja2V0IHJlYWNoZXMgT1BFTi4gKi9cbiAgb3BlbmVkJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMub3BlbmVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogRmlyZXMgd2hlbiB0aGUgc29ja2V0IGNsb3NlcyB3aXRob3V0IGEgY2xpZW50LWluaXRpYXRlZCB7QGxpbmsgZGlzY29ubmVjdH0uICovXG4gIHJlbW90ZUNsb3NlJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPVxuICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPVxuICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIEFzc2lzdGFudC9ib3Qgc3BlYWtpbmcsIHdoZW4gdGhlIHNlcnZlciBzZW5kcyBleHBsaWNpdCBldmVudHMgKHNlZSB7QGxpbmsgaGFuZGxlSnNvbk1lc3NhZ2V9KS4gKi9cbiAgYXNzaXN0YW50U3BlYWtpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID1cbiAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVXNlciBzcGVha2luZyBmcm9tIHNlcnZlci1zaWRlIFZBRCwgaWYgcHJvdmlkZWQuICovXG4gIHNlcnZlclVzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHRoaXMuc2VydmVyVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogQmluYXJ5IGF1ZGlvIGZyYW1lcyBmcm9tIHNlcnZlciAod2hlbiBiYWNrZW5kIHN0cmVhbXMgYm90IGF1ZGlvIG92ZXIgV1MpLiAqL1xuICBhdWRpb0NodW5rJDogT2JzZXJ2YWJsZTxBcnJheUJ1ZmZlcj4gPSB0aGlzLmF1ZGlvQ2h1bmtTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgY29ubmVjdCh3c1VybDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLndzKSB7XG4gICAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgICAgdGhpcy53cy5jbG9zZSgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzb2NrZXQgPSBuZXcgV2ViU29ja2V0KHdzVXJsKTtcbiAgICAgIHRoaXMud3MgPSBzb2NrZXQ7XG4gICAgICBzb2NrZXQub25vcGVuID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy53cyAhPT0gc29ja2V0KSByZXR1cm47XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm9wZW5lZFN1YmplY3QubmV4dCgpKTtcbiAgICAgIH07XG4gICAgICBzb2NrZXQub25tZXNzYWdlID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgIT09IHNvY2tldCkgcmV0dXJuO1xuICAgICAgICB2b2lkIHRoaXMuaGFuZGxlSW5jb21pbmdNZXNzYWdlKGV2ZW50LmRhdGEpO1xuICAgICAgfTtcbiAgICAgIHNvY2tldC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLndzID09PSBzb2NrZXQgJiYgc29ja2V0LnJlYWR5U3RhdGUgIT09IFdlYlNvY2tldC5DTE9TRUQpIHtcbiAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLndzID09PSBzb2NrZXQpIHtcbiAgICAgICAgICB0aGlzLndzID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQ7XG4gICAgICAgIHRoaXMuY2xvc2VJbml0aWF0ZWRCeUNsaWVudCA9IGZhbHNlO1xuICAgICAgICBpZiAoIWNsaWVudCkge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnJlbW90ZUNsb3NlU3ViamVjdC5uZXh0KCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignV2ViU29ja2V0Vm9pY2VDbGllbnQ6IGNvbm5lY3QgZmFpbGVkJywgZXJyKTtcbiAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlSW5jb21pbmdNZXNzYWdlKHBheWxvYWQ6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLmhhbmRsZUpzb25TdHJpbmcocGF5bG9hZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwYXlsb2FkIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHRoaXMuaGFuZGxlQmluYXJ5TWVzc2FnZShwYXlsb2FkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHBheWxvYWQgaW5zdGFuY2VvZiBCbG9iKSB7XG4gICAgICBjb25zdCBhYiA9IGF3YWl0IHBheWxvYWQuYXJyYXlCdWZmZXIoKTtcbiAgICAgIHRoaXMuaGFuZGxlQmluYXJ5TWVzc2FnZShhYik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uU3RyaW5nKGpzb25UZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbXNnID0gSlNPTi5wYXJzZShqc29uVGV4dCkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5oYW5kbGVKc29uTWVzc2FnZShtc2cpKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIElnbm9yZSBub24tSlNPTlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQmluYXJ5TWVzc2FnZShidWZmZXI6IEFycmF5QnVmZmVyKTogdm9pZCB7XG4gICAgLy8gU29tZSBiYWNrZW5kcyB3cmFwIEpTT04gZXZlbnRzIGluc2lkZSBiaW5hcnkgV1MgZnJhbWVzLlxuICAgIGNvbnN0IG1heWJlVGV4dCA9IHRoaXMudHJ5RGVjb2RlVXRmOChidWZmZXIpO1xuICAgIGlmIChtYXliZVRleHQgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuaGFuZGxlSnNvblN0cmluZyhtYXliZVRleHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBPdGhlcndpc2UgdHJlYXQgYmluYXJ5IGFzIHN0cmVhbWVkIGFzc2lzdGFudCBhdWRpby5cbiAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5hdWRpb0NodW5rU3ViamVjdC5uZXh0KGJ1ZmZlcikpO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnlEZWNvZGVVdGY4KGJ1ZmZlcjogQXJyYXlCdWZmZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdGV4dCA9IG5ldyBUZXh0RGVjb2RlcigndXRmLTgnLCB7IGZhdGFsOiB0cnVlIH0pLmRlY29kZShidWZmZXIpO1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHRleHQudHJpbSgpO1xuICAgICAgaWYgKCF0cmltbWVkIHx8ICh0cmltbWVkWzBdICE9PSAneycgJiYgdHJpbW1lZFswXSAhPT0gJ1snKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmltbWVkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uTWVzc2FnZShtc2c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gICAgY29uc3QgdHlwZSA9IG1zZy50eXBlO1xuICAgIGNvbnN0IHR5cGVTdHIgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlIDogJyc7XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3Nlc3Npb25fcmVhZHknIHx8IHR5cGVTdHIgPT09ICdjb25uZWN0ZWQnIHx8IHR5cGVTdHIgPT09ICd2b2ljZV9zZXNzaW9uX3N0YXJ0ZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZVN0ciA9PT0gJ2Fzc2lzdGFudF9zcGVha2luZycgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdib3Rfc3BlYWtpbmcnXG4gICAgKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5hc3Npc3RhbnRTcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAobXNnLmFjdGl2ZSA9PT0gZmFsc2UgfHwgbXNnLnNwZWFraW5nID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3VzZXJfc3BlYWtpbmcnKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5hY3RpdmUgPT09IGZhbHNlIHx8IG1zZy5zcGVha2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdGFydGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZGVsdGEnKSB7XG4gICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZG9uZScgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdyZXNwb25zZS5vdXRwdXRfYXVkaW8uZG9uZSdcbiAgICApIHtcbiAgICAgIHRoaXMuYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAndXNlcl90cmFuc2NyaXB0JyAmJiB0eXBlb2YgbXNnLnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5uZXh0KHtcbiAgICAgICAgdGV4dDogbXNnLnRleHQsXG4gICAgICAgIGZpbmFsOiBtc2cuZmluYWwgPT09IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVTdHIgPT09ICdib3RfdHJhbnNjcmlwdCcgJiYgdHlwZW9mIG1zZy50ZXh0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KG1zZy50ZXh0KTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy53cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgfVxuXG4gIGdldCBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU47XG4gIH1cbn1cbiJdfQ==
@@ -823,6 +823,7 @@ class WebSocketVoiceClientService {
823
823
  this.botTranscriptSubject = new Subject();
824
824
  this.assistantSpeakingSubject = new Subject();
825
825
  this.serverUserSpeakingSubject = new Subject();
826
+ this.audioChunkSubject = new Subject();
826
827
  /** Fires once each time the WebSocket reaches OPEN. */
827
828
  this.opened$ = this.openedSubject.asObservable();
828
829
  /** Fires when the socket closes without a client-initiated {@link disconnect}. */
@@ -833,6 +834,8 @@ class WebSocketVoiceClientService {
833
834
  this.assistantSpeaking$ = this.assistantSpeakingSubject.asObservable();
834
835
  /** User speaking from server-side VAD, if provided. */
835
836
  this.serverUserSpeaking$ = this.serverUserSpeakingSubject.asObservable();
837
+ /** Binary audio frames from server (when backend streams bot audio over WS). */
838
+ this.audioChunk$ = this.audioChunkSubject.asObservable();
836
839
  }
837
840
  connect(wsUrl) {
838
841
  var _a;
@@ -854,16 +857,7 @@ class WebSocketVoiceClientService {
854
857
  socket.onmessage = (event) => {
855
858
  if (this.ws !== socket)
856
859
  return;
857
- if (typeof event.data !== 'string') {
858
- return;
859
- }
860
- try {
861
- const msg = JSON.parse(event.data);
862
- this.ngZone.run(() => this.handleJsonMessage(msg));
863
- }
864
- catch (_a) {
865
- // Ignore non-JSON
866
- }
860
+ void this.handleIncomingMessage(event.data);
867
861
  };
868
862
  socket.onerror = () => {
869
863
  this.ngZone.run(() => {
@@ -889,6 +883,54 @@ class WebSocketVoiceClientService {
889
883
  throw err;
890
884
  }
891
885
  }
886
+ handleIncomingMessage(payload) {
887
+ return __awaiter(this, void 0, void 0, function* () {
888
+ if (typeof payload === 'string') {
889
+ this.handleJsonString(payload);
890
+ return;
891
+ }
892
+ if (payload instanceof ArrayBuffer) {
893
+ this.handleBinaryMessage(payload);
894
+ return;
895
+ }
896
+ if (payload instanceof Blob) {
897
+ const ab = yield payload.arrayBuffer();
898
+ this.handleBinaryMessage(ab);
899
+ }
900
+ });
901
+ }
902
+ handleJsonString(jsonText) {
903
+ try {
904
+ const msg = JSON.parse(jsonText);
905
+ this.ngZone.run(() => this.handleJsonMessage(msg));
906
+ }
907
+ catch (_a) {
908
+ // Ignore non-JSON
909
+ }
910
+ }
911
+ handleBinaryMessage(buffer) {
912
+ // Some backends wrap JSON events inside binary WS frames.
913
+ const maybeText = this.tryDecodeUtf8(buffer);
914
+ if (maybeText !== null) {
915
+ this.handleJsonString(maybeText);
916
+ return;
917
+ }
918
+ // Otherwise treat binary as streamed assistant audio.
919
+ this.ngZone.run(() => this.audioChunkSubject.next(buffer));
920
+ }
921
+ tryDecodeUtf8(buffer) {
922
+ try {
923
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(buffer);
924
+ const trimmed = text.trim();
925
+ if (!trimmed || (trimmed[0] !== '{' && trimmed[0] !== '[')) {
926
+ return null;
927
+ }
928
+ return trimmed;
929
+ }
930
+ catch (_a) {
931
+ return null;
932
+ }
933
+ }
892
934
  handleJsonMessage(msg) {
893
935
  const type = msg.type;
894
936
  const typeStr = typeof type === 'string' ? type : '';
@@ -988,6 +1030,9 @@ class VoiceAgentService {
988
1030
  this.callStartTime = 0;
989
1031
  this.durationInterval = null;
990
1032
  this.localMicStream = null;
1033
+ this.remoteAudioContext = null;
1034
+ this.pendingRemoteAudio = [];
1035
+ this.remoteAudioPlaying = false;
991
1036
  this.endCall$ = new Subject();
992
1037
  this.subscriptions = new Subscription();
993
1038
  this.destroy$ = new Subject();
@@ -1003,6 +1048,9 @@ class VoiceAgentService {
1003
1048
  this.subscriptions.add(this.wsClient.remoteClose$
1004
1049
  .pipe(takeUntil(this.destroy$))
1005
1050
  .subscribe(() => void this.handleRemoteClose()));
1051
+ this.subscriptions.add(this.wsClient.audioChunk$
1052
+ .pipe(takeUntil(this.destroy$))
1053
+ .subscribe((chunk) => this.enqueueRemoteAudio(chunk)));
1006
1054
  }
1007
1055
  ngOnDestroy() {
1008
1056
  this.destroy$.next();
@@ -1018,6 +1066,7 @@ class VoiceAgentService {
1018
1066
  this.callStartTime = 0;
1019
1067
  this.audioAnalyzer.stop();
1020
1068
  this.stopLocalMic();
1069
+ this.resetRemoteAudioPlayback();
1021
1070
  this.wsClient.disconnect();
1022
1071
  this.callStateSubject.next('idle');
1023
1072
  this.statusTextSubject.next('');
@@ -1172,6 +1221,76 @@ class VoiceAgentService {
1172
1221
  this.localMicStream = null;
1173
1222
  }
1174
1223
  }
1224
+ enqueueRemoteAudio(chunk) {
1225
+ this.pendingRemoteAudio.push(chunk.slice(0));
1226
+ if (!this.remoteAudioPlaying) {
1227
+ void this.playRemoteAudioQueue();
1228
+ }
1229
+ }
1230
+ playRemoteAudioQueue() {
1231
+ return __awaiter(this, void 0, void 0, function* () {
1232
+ this.remoteAudioPlaying = true;
1233
+ const context = this.getOrCreateRemoteAudioContext();
1234
+ while (this.pendingRemoteAudio.length > 0) {
1235
+ const chunk = this.pendingRemoteAudio.shift();
1236
+ if (!chunk)
1237
+ continue;
1238
+ try {
1239
+ const decoded = yield this.decodeAudioChunk(context, chunk);
1240
+ this.assistantAudioStarted();
1241
+ yield this.playDecodedBuffer(context, decoded);
1242
+ }
1243
+ catch (_a) {
1244
+ // Ignore undecodable chunks; server may mix non-audio binary events.
1245
+ }
1246
+ }
1247
+ this.remoteAudioPlaying = false;
1248
+ this.assistantAudioStopped();
1249
+ });
1250
+ }
1251
+ getOrCreateRemoteAudioContext() {
1252
+ if (!this.remoteAudioContext || this.remoteAudioContext.state === 'closed') {
1253
+ this.remoteAudioContext = new AudioContext();
1254
+ }
1255
+ if (this.remoteAudioContext.state === 'suspended') {
1256
+ void this.remoteAudioContext.resume();
1257
+ }
1258
+ return this.remoteAudioContext;
1259
+ }
1260
+ decodeAudioChunk(context, chunk) {
1261
+ return new Promise((resolve, reject) => {
1262
+ context.decodeAudioData(chunk.slice(0), resolve, reject);
1263
+ });
1264
+ }
1265
+ playDecodedBuffer(context, buffer) {
1266
+ return new Promise((resolve) => {
1267
+ const source = context.createBufferSource();
1268
+ source.buffer = buffer;
1269
+ source.connect(context.destination);
1270
+ source.onended = () => resolve();
1271
+ source.start();
1272
+ });
1273
+ }
1274
+ assistantAudioStarted() {
1275
+ if (this.callStartTime === 0) {
1276
+ this.callStartTime = Date.now();
1277
+ this.startDurationTimer();
1278
+ }
1279
+ this.callStateSubject.next('talking');
1280
+ }
1281
+ assistantAudioStopped() {
1282
+ if (this.callStateSubject.value === 'talking') {
1283
+ this.callStateSubject.next('connected');
1284
+ }
1285
+ }
1286
+ resetRemoteAudioPlayback() {
1287
+ this.pendingRemoteAudio = [];
1288
+ this.remoteAudioPlaying = false;
1289
+ if (this.remoteAudioContext && this.remoteAudioContext.state !== 'closed') {
1290
+ this.remoteAudioContext.close().catch(() => { });
1291
+ }
1292
+ this.remoteAudioContext = null;
1293
+ }
1175
1294
  handleRemoteClose() {
1176
1295
  return __awaiter(this, void 0, void 0, function* () {
1177
1296
  const state = this.callStateSubject.value;
@@ -1182,6 +1301,7 @@ class VoiceAgentService {
1182
1301
  this.callStartTime = 0;
1183
1302
  this.audioAnalyzer.stop();
1184
1303
  this.stopLocalMic();
1304
+ this.resetRemoteAudioPlayback();
1185
1305
  this.callStateSubject.next('ended');
1186
1306
  this.statusTextSubject.next('Connection lost');
1187
1307
  });
@@ -1193,6 +1313,7 @@ class VoiceAgentService {
1193
1313
  this.callStartTime = 0;
1194
1314
  this.audioAnalyzer.stop();
1195
1315
  this.stopLocalMic();
1316
+ this.resetRemoteAudioPlayback();
1196
1317
  this.wsClient.disconnect();
1197
1318
  this.callStateSubject.next('ended');
1198
1319
  this.statusTextSubject.next('Call Ended');