@hivegpt/hiveai-angular 0.0.589 → 0.0.590

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +26 -0
  2. package/bundles/hivegpt-hiveai-angular.umd.js +3146 -534
  3. package/bundles/hivegpt-hiveai-angular.umd.js.map +1 -1
  4. package/bundles/hivegpt-hiveai-angular.umd.min.js +1 -1
  5. package/bundles/hivegpt-hiveai-angular.umd.min.js.map +1 -1
  6. package/esm2015/hivegpt-hiveai-angular.js +6 -5
  7. package/esm2015/lib/components/NotificationSocket.js +29 -22
  8. package/esm2015/lib/components/bot.service.js +18 -12
  9. package/esm2015/lib/components/chat-drawer/chat-drawer.component.js +2429 -214
  10. package/esm2015/lib/components/chatbot/chatbot.component.js +9 -5
  11. package/esm2015/lib/components/conversation.service.js +13 -5
  12. package/esm2015/lib/components/socket-service.service.js +21 -11
  13. package/esm2015/lib/components/translations/translation.service.js +38 -36
  14. package/esm2015/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.js +46 -35
  15. package/esm2015/lib/components/voice-agent/services/audio-analyzer.service.js +11 -5
  16. package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +226 -151
  17. package/esm2015/lib/components/voice-agent/voice-agent.module.js +6 -2
  18. package/esm2015/lib/components/voice-agent/voice-modal-tokens.js +1 -1
  19. package/esm2015/lib/services/platform-token-refresh.service.js +173 -0
  20. package/esm2015/lib/utils/utils.js +4 -2
  21. package/esm2015/public-api.js +2 -3
  22. package/fesm2015/hivegpt-hiveai-angular.js +2996 -486
  23. package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
  24. package/hivegpt-hiveai-angular.d.ts +5 -4
  25. package/hivegpt-hiveai-angular.d.ts.map +1 -1
  26. package/hivegpt-hiveai-angular.metadata.json +1 -1
  27. package/lib/components/NotificationSocket.d.ts +1 -3
  28. package/lib/components/NotificationSocket.d.ts.map +1 -1
  29. package/lib/components/bot.service.d.ts +1 -2
  30. package/lib/components/bot.service.d.ts.map +1 -1
  31. package/lib/components/chat-drawer/chat-drawer.component.d.ts +285 -52
  32. package/lib/components/chat-drawer/chat-drawer.component.d.ts.map +1 -1
  33. package/lib/components/chatbot/chatbot.component.d.ts +8 -1
  34. package/lib/components/chatbot/chatbot.component.d.ts.map +1 -1
  35. package/lib/components/conversation.service.d.ts +8 -2
  36. package/lib/components/conversation.service.d.ts.map +1 -1
  37. package/lib/components/socket-service.service.d.ts +3 -4
  38. package/lib/components/socket-service.service.d.ts.map +1 -1
  39. package/lib/components/translations/translation.service.d.ts.map +1 -1
  40. package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts +15 -6
  41. package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts.map +1 -1
  42. package/lib/components/voice-agent/services/audio-analyzer.service.d.ts +5 -0
  43. package/lib/components/voice-agent/services/audio-analyzer.service.d.ts.map +1 -1
  44. package/lib/components/voice-agent/services/voice-agent.service.d.ts +39 -10
  45. package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
  46. package/lib/components/voice-agent/voice-agent.module.d.ts +4 -0
  47. package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
  48. package/lib/components/voice-agent/voice-modal-tokens.d.ts +4 -0
  49. package/lib/components/voice-agent/voice-modal-tokens.d.ts.map +1 -1
  50. package/lib/services/platform-token-refresh.service.d.ts +59 -0
  51. package/lib/services/platform-token-refresh.service.d.ts.map +1 -0
  52. package/lib/utils/utils.d.ts +1 -1
  53. package/lib/utils/utils.d.ts.map +1 -1
  54. package/package.json +4 -2
  55. package/public-api.d.ts +1 -2
  56. package/public-api.d.ts.map +1 -1
  57. package/esm2015/lib/models/chat.js +0 -2
  58. package/lib/models/chat.d.ts +0 -134
  59. package/lib/models/chat.d.ts.map +0 -1
@@ -1,18 +1,34 @@
1
1
  import { __awaiter } from "tslib";
2
- import { Injectable } from '@angular/core';
3
- import { BehaviorSubject, Subject } from 'rxjs';
4
- import { PipecatClient, RTVIEvent, } from '@pipecat-ai/client-js';
2
+ import { isPlatformBrowser } from '@angular/common';
3
+ import { Inject, Injectable, NgZone, PLATFORM_ID } from '@angular/core';
4
+ import { BehaviorSubject, Subject, Subscription } from 'rxjs';
5
+ import { take } from 'rxjs/operators';
6
+ import { PipecatClient, RTVIEvent } from '@pipecat-ai/client-js';
5
7
  import { WebSocketTransport } from '@pipecat-ai/websocket-transport';
8
+ import { PlatformTokenRefreshService } from '../../../services/platform-token-refresh.service';
6
9
  import { AudioAnalyzerService } from './audio-analyzer.service';
7
10
  import * as i0 from "@angular/core";
8
11
  import * as i1 from "./audio-analyzer.service";
12
+ import * as i2 from "../../../services/platform-token-refresh.service";
13
+ /**
14
+ * Voice agent orchestrator using the official PipecatClient SDK.
15
+ *
16
+ * Audio flow (mirrors the React reference implementation):
17
+ * - Local mic: acquired by PipecatClient.initDevices(); local track fed to
18
+ * AudioAnalyzerService for waveform visualisation.
19
+ * - Bot audio: received as a MediaStreamTrack via RTVIEvent.TrackStarted,
20
+ * played through a hidden <audio> element.
21
+ * - All binary protobuf framing / RTVI protocol handled by
22
+ * @pipecat-ai/client-js + @pipecat-ai/websocket-transport.
23
+ */
9
24
  export class VoiceAgentService {
10
- constructor(audioAnalyzer) {
25
+ constructor(audioAnalyzer, platformTokenRefresh, ngZone,
26
+ /** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
27
+ platformId) {
11
28
  this.audioAnalyzer = audioAnalyzer;
12
- this.client = null;
13
- this.transport = null;
14
- this.userMediaStream = null;
15
- this.botAudioElement = null;
29
+ this.platformTokenRefresh = platformTokenRefresh;
30
+ this.ngZone = ngZone;
31
+ this.platformId = platformId;
16
32
  this.callStateSubject = new BehaviorSubject('idle');
17
33
  this.statusTextSubject = new BehaviorSubject('');
18
34
  this.durationSubject = new BehaviorSubject('00:00');
@@ -23,6 +39,10 @@ export class VoiceAgentService {
23
39
  this.botTranscriptSubject = new Subject();
24
40
  this.callStartTime = 0;
25
41
  this.durationInterval = null;
42
+ this.pcClient = null;
43
+ this.botAudioElement = null;
44
+ this.subscriptions = new Subscription();
45
+ this.destroy$ = new Subject();
26
46
  this.callState$ = this.callStateSubject.asObservable();
27
47
  this.statusText$ = this.statusTextSubject.asObservable();
28
48
  this.duration$ = this.durationSubject.asObservable();
@@ -31,199 +51,254 @@ export class VoiceAgentService {
31
51
  this.audioLevels$ = this.audioLevelsSubject.asObservable();
32
52
  this.userTranscript$ = this.userTranscriptSubject.asObservable();
33
53
  this.botTranscript$ = this.botTranscriptSubject.asObservable();
34
- this.audioAnalyzer.audioLevels$.subscribe(levels => {
35
- this.audioLevelsSubject.next(levels);
36
- });
37
- this.audioAnalyzer.isUserSpeaking$.subscribe(isSpeaking => {
38
- this.isUserSpeakingSubject.next(isSpeaking);
39
- if (isSpeaking && this.callStateSubject.value === 'connected') {
40
- this.callStateSubject.next('listening');
41
- }
42
- else if (!isSpeaking && this.callStateSubject.value === 'listening') {
43
- this.callStateSubject.next('connected');
44
- }
45
- });
54
+ this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe((levels) => this.audioLevelsSubject.next(levels)));
55
+ }
56
+ ngOnDestroy() {
57
+ this.destroy$.next();
58
+ this.subscriptions.unsubscribe();
59
+ void this.disconnect();
46
60
  }
47
- /** Reset to idle state (e.g. when modal opens so user can click Start Call). */
61
+ /** Reset to idle (e.g. when modal re-opens so user can click Start Call). */
48
62
  resetToIdle() {
49
63
  if (this.callStateSubject.value === 'idle')
50
64
  return;
51
- if (this.durationInterval) {
52
- clearInterval(this.durationInterval);
53
- this.durationInterval = null;
54
- }
55
- this.audioAnalyzer.stop();
56
- this.client = null;
57
- this.transport = null;
58
- if (this.userMediaStream) {
59
- this.userMediaStream.getTracks().forEach(track => track.stop());
60
- this.userMediaStream = null;
61
- }
62
- if (this.botAudioElement) {
63
- this.botAudioElement.pause();
64
- this.botAudioElement.srcObject = null;
65
- this.botAudioElement = null;
66
- }
65
+ void this.disconnect();
67
66
  this.callStateSubject.next('idle');
68
67
  this.statusTextSubject.next('');
69
68
  this.durationSubject.next('0:00');
70
69
  }
71
- connect(apiUrl, token, botId, conversationId, apiKey, eventToken, eventUrl, domainAuthority) {
72
- var _a;
70
+ connect(apiUrl, token, botId, conversationId, apiKey, eventToken, eventId, eventUrl, domainAuthority, usersApiUrl) {
73
71
  return __awaiter(this, void 0, void 0, function* () {
74
72
  if (this.callStateSubject.value !== 'idle') {
75
- console.warn('Call already in progress');
73
+ console.warn('[HiveGpt Voice] Call already in progress');
76
74
  return;
77
75
  }
78
76
  try {
79
77
  this.callStateSubject.next('connecting');
80
78
  this.statusTextSubject.next('Connecting...');
79
+ let accessToken = token;
80
+ if (usersApiUrl && isPlatformBrowser(this.platformId)) {
81
+ try {
82
+ const ensured = yield this.platformTokenRefresh
83
+ .ensureValidAccessToken(token, usersApiUrl)
84
+ .pipe(take(1))
85
+ .toPromise();
86
+ if (ensured === null || ensured === void 0 ? void 0 : ensured.accessToken)
87
+ accessToken = ensured.accessToken;
88
+ }
89
+ catch (e) {
90
+ console.warn('[HiveGpt Voice] Token refresh failed', e);
91
+ }
92
+ }
81
93
  const baseUrl = apiUrl.replace(/\/$/, '');
82
- const connectUrl = `${baseUrl}/ai/ask-voice`;
83
- const headers = new Headers();
84
- headers.set('Authorization', `Bearer ${token}`);
85
- // Do not set Content-Type here — the Pipecat client already sets "application/json" once; adding it again produces "application/json, application/json"
86
- headers.set('domain-authority', domainAuthority);
87
- headers.set('eventtoken', eventToken);
88
- headers.set('eventurl', eventUrl);
89
- headers.set('hive-bot-id', botId);
90
- headers.set('x-api-key', apiKey);
91
- const startBotParams = {
92
- endpoint: connectUrl,
93
- headers,
94
+ const pcClient = new PipecatClient({
95
+ transport: new WebSocketTransport(),
96
+ enableMic: true,
97
+ enableCam: false,
98
+ callbacks: {
99
+ onConnected: () => this.ngZone.run(() => this.onPipecatConnected()),
100
+ onDisconnected: () => this.ngZone.run(() => this.onPipecatDisconnected()),
101
+ onBotReady: () => this.ngZone.run(() => this.onBotReady()),
102
+ onUserTranscript: (data) => this.ngZone.run(() => this.userTranscriptSubject.next({ text: data.text, final: !!data.final })),
103
+ onBotTranscript: (data) => this.ngZone.run(() => this.botTranscriptSubject.next(data.text)),
104
+ onError: (err) => {
105
+ this.ngZone.run(() => {
106
+ console.error('[HiveGpt Voice] PipecatClient error', err);
107
+ this.callStateSubject.next('ended');
108
+ this.statusTextSubject.next('Connection failed');
109
+ });
110
+ },
111
+ },
112
+ });
113
+ this.pcClient = pcClient;
114
+ // Bot audio arrives as a MediaStreamTrack — wire to a hidden <audio> element
115
+ pcClient.on(RTVIEvent.TrackStarted, (track, participant) => {
116
+ if (!(participant === null || participant === void 0 ? void 0 : participant.local) && track.kind === 'audio') {
117
+ this.ngZone.run(() => this.setupBotAudioTrack(track));
118
+ }
119
+ });
120
+ // Speaking state comes straight from RTVI events
121
+ pcClient.on(RTVIEvent.BotStartedSpeaking, () => this.ngZone.run(() => this.onBotStartedSpeaking()));
122
+ pcClient.on(RTVIEvent.BotStoppedSpeaking, () => this.ngZone.run(() => this.onBotStoppedSpeaking()));
123
+ pcClient.on(RTVIEvent.UserStartedSpeaking, () => this.ngZone.run(() => {
124
+ this.isUserSpeakingSubject.next(true);
125
+ this.callStateSubject.next('listening');
126
+ this.statusTextSubject.next('Listening...');
127
+ }));
128
+ pcClient.on(RTVIEvent.UserStoppedSpeaking, () => this.ngZone.run(() => {
129
+ this.isUserSpeakingSubject.next(false);
130
+ if (this.callStateSubject.value === 'listening') {
131
+ // Brief 'Processing...' while we wait for the bot to respond.
132
+ this.callStateSubject.next('connected');
133
+ this.statusTextSubject.next('Processing...');
134
+ }
135
+ }));
136
+ // Acquire mic (triggers browser permission prompt)
137
+ yield pcClient.initDevices();
138
+ // Build headers using the browser Headers API (required by pipecat's APIRequest type)
139
+ const requestHeaders = new Headers();
140
+ requestHeaders.append('Authorization', `Bearer ${accessToken}`);
141
+ requestHeaders.append('x-api-key', apiKey);
142
+ requestHeaders.append('hive-bot-id', botId);
143
+ requestHeaders.append('domain-authority', domainAuthority);
144
+ requestHeaders.append('eventUrl', eventUrl);
145
+ requestHeaders.append('eventId', eventId);
146
+ requestHeaders.append('eventToken', eventToken);
147
+ requestHeaders.append('ngrok-skip-browser-warning', 'true');
148
+ // POST to /ai/ask-voice-socket → receives { ws_url } → WebSocketTransport connects
149
+ yield pcClient.startBotAndConnect({
150
+ endpoint: `${baseUrl}/ai/ask-voice-socket`,
151
+ headers: requestHeaders,
94
152
  requestData: {
95
153
  bot_id: botId,
96
154
  conversation_id: conversationId,
97
155
  voice: 'alloy',
98
156
  },
99
- };
100
- this.transport = new WebSocketTransport();
101
- this.client = new PipecatClient({
102
- transport: this.transport,
103
- enableMic: true,
104
- enableCam: false,
105
157
  });
106
- this.setupEventHandlers();
107
- this.botAudioElement = new Audio();
108
- this.botAudioElement.autoplay = true;
109
- yield this.client.startBotAndConnect(startBotParams);
110
- const tracks = this.client.tracks();
111
- if ((_a = tracks === null || tracks === void 0 ? void 0 : tracks.local) === null || _a === void 0 ? void 0 : _a.audio) {
112
- this.userMediaStream = new MediaStream([tracks.local.audio]);
113
- this.audioAnalyzer.start(this.userMediaStream);
114
- }
115
- this.isMicMutedSubject.next(!this.client.isMicEnabled);
116
- this.callStateSubject.next('connected');
117
- this.statusTextSubject.next('Connected');
118
- this.callStartTime = Date.now();
119
- this.startDurationTimer();
120
158
  }
121
159
  catch (error) {
122
- console.error('Error connecting voice agent:', error);
160
+ console.error('[HiveGpt Voice] connect failed', error);
123
161
  this.callStateSubject.next('ended');
124
- yield this.disconnect();
162
+ yield this.cleanupPipecatClient();
125
163
  this.statusTextSubject.next('Connection failed');
126
164
  throw error;
127
165
  }
128
166
  });
129
167
  }
168
+ onPipecatConnected() {
169
+ // Start the duration timer from the moment the session is live.
170
+ this.callStartTime = Date.now();
171
+ this.startDurationTimer();
172
+ this.callStateSubject.next('connected');
173
+ this.statusTextSubject.next('Connected');
174
+ this.isMicMutedSubject.next(false);
175
+ this.startLocalMicAnalyzer();
176
+ }
177
+ onPipecatDisconnected() {
178
+ this.stopDurationTimer();
179
+ this.callStartTime = 0;
180
+ this.audioAnalyzer.stop();
181
+ this.stopBotAudio();
182
+ this.callStateSubject.next('ended');
183
+ this.statusTextSubject.next('Call Ended');
184
+ }
185
+ onBotReady() {
186
+ var _a, _b, _c;
187
+ // Retry track wiring in case tracks weren't ready at onConnected.
188
+ this.startLocalMicAnalyzer();
189
+ const botTrack = (_c = (_b = (_a = this.pcClient) === null || _a === void 0 ? void 0 : _a.tracks()) === null || _b === void 0 ? void 0 : _b.bot) === null || _c === void 0 ? void 0 : _c.audio;
190
+ if (botTrack)
191
+ this.setupBotAudioTrack(botTrack);
192
+ // Bot is initialised — signal that we're now waiting for user input.
193
+ this.statusTextSubject.next('Listening...');
194
+ }
195
+ startLocalMicAnalyzer() {
196
+ var _a, _b, _c;
197
+ const localTrack = (_c = (_b = (_a = this.pcClient) === null || _a === void 0 ? void 0 : _a.tracks()) === null || _b === void 0 ? void 0 : _b.local) === null || _c === void 0 ? void 0 : _c.audio;
198
+ if (localTrack) {
199
+ this.audioAnalyzer.start(new MediaStream([localTrack]));
200
+ }
201
+ }
202
+ onBotStartedSpeaking() {
203
+ this.callStateSubject.next('talking');
204
+ this.statusTextSubject.next('Talking...');
205
+ // Mark user as no longer speaking when bot takes the turn.
206
+ this.isUserSpeakingSubject.next(false);
207
+ }
208
+ onBotStoppedSpeaking() {
209
+ if (this.callStateSubject.value === 'talking') {
210
+ this.callStateSubject.next('connected');
211
+ this.statusTextSubject.next('Listening...');
212
+ }
213
+ }
214
+ setupBotAudioTrack(track) {
215
+ var _a;
216
+ if (!this.botAudioElement) {
217
+ this.botAudioElement = new Audio();
218
+ this.botAudioElement.autoplay = true;
219
+ }
220
+ const existing = (_a = this.botAudioElement.srcObject) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
221
+ if ((existing === null || existing === void 0 ? void 0 : existing.id) === track.id)
222
+ return;
223
+ this.botAudioElement.srcObject = new MediaStream([track]);
224
+ this.botAudioElement.play().catch((err) => console.warn('[HiveGpt Voice] Bot audio play blocked', err));
225
+ }
226
+ stopBotAudio() {
227
+ var _a;
228
+ if (this.botAudioElement) {
229
+ try {
230
+ this.botAudioElement.pause();
231
+ (_a = this.botAudioElement.srcObject) === null || _a === void 0 ? void 0 : _a.getAudioTracks().forEach((t) => t.stop());
232
+ this.botAudioElement.srcObject = null;
233
+ }
234
+ catch (_b) {
235
+ // ignore
236
+ }
237
+ this.botAudioElement = null;
238
+ }
239
+ }
130
240
  disconnect() {
131
241
  return __awaiter(this, void 0, void 0, function* () {
132
- try {
133
- if (this.durationInterval) {
134
- clearInterval(this.durationInterval);
135
- this.durationInterval = null;
136
- }
137
- this.audioAnalyzer.stop();
138
- if (this.client) {
139
- yield this.client.disconnect();
140
- this.client = null;
141
- }
142
- this.transport = null;
143
- if (this.userMediaStream) {
144
- this.userMediaStream.getTracks().forEach(track => track.stop());
145
- this.userMediaStream = null;
242
+ this.stopDurationTimer();
243
+ this.callStartTime = 0;
244
+ this.audioAnalyzer.stop();
245
+ this.stopBotAudio();
246
+ yield this.cleanupPipecatClient();
247
+ this.callStateSubject.next('ended');
248
+ this.statusTextSubject.next('Call Ended');
249
+ });
250
+ }
251
+ cleanupPipecatClient() {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ if (this.pcClient) {
254
+ try {
255
+ yield this.pcClient.disconnect();
146
256
  }
147
- if (this.botAudioElement) {
148
- this.botAudioElement.pause();
149
- this.botAudioElement.srcObject = null;
150
- this.botAudioElement = null;
257
+ catch (_a) {
258
+ // ignore
151
259
  }
152
- this.callStateSubject.next('ended');
153
- this.statusTextSubject.next('Call Ended');
154
- // Keep current duration so "Call Ended" state can show it (e.g. "Call Ended 1:04")
155
- }
156
- catch (error) {
157
- console.error('Error disconnecting voice agent:', error);
260
+ this.pcClient = null;
158
261
  }
159
262
  });
160
263
  }
161
264
  toggleMic() {
162
- if (!this.client)
265
+ if (!this.pcClient)
163
266
  return;
164
- const newState = !this.client.isMicEnabled;
165
- this.client.enableMic(newState);
166
- this.isMicMutedSubject.next(!newState);
167
- }
168
- setupEventHandlers() {
169
- if (!this.client)
170
- return;
171
- this.client.on(RTVIEvent.BotStartedSpeaking, () => {
172
- this.callStateSubject.next('talking');
173
- });
174
- this.client.on(RTVIEvent.BotStoppedSpeaking, () => {
175
- if (this.callStateSubject.value === 'talking') {
176
- this.callStateSubject.next('connected');
177
- }
178
- });
179
- this.client.on(RTVIEvent.TrackStarted, (track, participant) => {
180
- if (this.botAudioElement && participant && !participant.local && track.kind === 'audio') {
181
- const stream = new MediaStream([track]);
182
- this.botAudioElement.srcObject = stream;
183
- this.botAudioElement.play().catch(console.error);
184
- }
185
- });
186
- this.client.on(RTVIEvent.UserTranscript, (data) => {
187
- var _a;
188
- this.userTranscriptSubject.next({
189
- text: data.text,
190
- final: (_a = data.final) !== null && _a !== void 0 ? _a : false,
191
- });
192
- });
193
- this.client.on(RTVIEvent.BotTranscript, (data) => {
194
- if (data === null || data === void 0 ? void 0 : data.text) {
195
- this.botTranscriptSubject.next(data.text);
196
- }
197
- });
198
- this.client.on(RTVIEvent.Error, () => {
199
- this.statusTextSubject.next('Error occurred');
200
- });
201
- this.client.on(RTVIEvent.Disconnected, () => {
202
- this.callStateSubject.next('ended');
203
- this.statusTextSubject.next('Disconnected');
204
- this.disconnect();
205
- });
267
+ const nextMuted = !this.isMicMutedSubject.value;
268
+ this.pcClient.enableMic(!nextMuted);
269
+ this.isMicMutedSubject.next(nextMuted);
270
+ if (nextMuted)
271
+ this.isUserSpeakingSubject.next(false);
206
272
  }
207
273
  startDurationTimer() {
208
- const updateDuration = () => {
274
+ const tick = () => {
209
275
  if (this.callStartTime > 0) {
210
276
  const elapsed = Math.floor((Date.now() - this.callStartTime) / 1000);
211
- const minutes = Math.floor(elapsed / 60);
212
- const seconds = elapsed % 60;
213
- this.durationSubject.next(`${minutes}:${String(seconds).padStart(2, '0')}`);
277
+ const m = Math.floor(elapsed / 60);
278
+ const s = elapsed % 60;
279
+ this.durationSubject.next(`${m}:${String(s).padStart(2, '0')}`);
214
280
  }
215
281
  };
216
- updateDuration(); // show 0:00 immediately
217
- this.durationInterval = setInterval(updateDuration, 1000);
282
+ tick();
283
+ this.durationInterval = setInterval(tick, 1000);
284
+ }
285
+ stopDurationTimer() {
286
+ if (this.durationInterval) {
287
+ clearInterval(this.durationInterval);
288
+ this.durationInterval = null;
289
+ }
218
290
  }
219
291
  }
220
- VoiceAgentService.ɵprov = i0.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0.ɵɵinject(i1.AudioAnalyzerService)); }, token: VoiceAgentService, providedIn: "root" });
292
+ VoiceAgentService.ɵprov = i0.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0.ɵɵinject(i1.AudioAnalyzerService), i0.ɵɵinject(i2.PlatformTokenRefreshService), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i0.PLATFORM_ID)); }, token: VoiceAgentService, providedIn: "root" });
221
293
  VoiceAgentService.decorators = [
222
294
  { type: Injectable, args: [{
223
- providedIn: 'root'
295
+ providedIn: 'root',
224
296
  },] }
225
297
  ];
226
298
  VoiceAgentService.ctorParameters = () => [
227
- { type: AudioAnalyzerService }
299
+ { type: AudioAnalyzerService },
300
+ { type: PlatformTokenRefreshService },
301
+ { type: NgZone },
302
+ { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
228
303
  ];
229
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVELE9BQU8sRUFDTCxhQUFhLEVBQ2IsU0FBUyxHQUVWLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7OztBQVloRSxNQUFNLE9BQU8saUJBQWlCO0lBbUQ1QixZQUFvQixhQUFtQztRQUFuQyxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFsRC9DLFdBQU0sR0FBeUIsSUFBSSxDQUFDO1FBQ3BDLGNBQVMsR0FBbUQsSUFBSSxDQUFDO1FBQ2pFLG9CQUFlLEdBQXVCLElBQUksQ0FBQztRQUMzQyxvQkFBZSxHQUE0QixJQUFJLENBQUM7UUFFaEQscUJBQWdCLEdBQUcsSUFBSSxlQUFlLENBQVksTUFBTSxDQUFDLENBQUM7UUFDMUQsc0JBQWlCLEdBQUcsSUFBSSxlQUFlLENBQVMsRUFBRSxDQUFDLENBQUM7UUFDcEQsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBUyxPQUFPLENBQUMsQ0FBQztRQUN2RCxzQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUN4RCwwQkFBcUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMs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QUN2QixHQUFHLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUNqRCxDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUM7UUFDRixjQUFjLEVBQUUsQ0FBQyxDQUFDLHdCQUF3QjtRQUMxQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1RCxDQUFDOzs7O1lBcFBGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7O1lBWFEsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBQaXBlY2F0Q2xpZW50LFxuICBSVFZJRXZlbnQsXG4gIEFQSVJlcXVlc3QsXG59IGZyb20gJ0BwaXBlY2F0LWFpL2NsaWVudC1qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRUcmFuc3BvcnQgfSBmcm9tICdAcGlwZWNhdC1haS93ZWJzb2NrZXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIH0gZnJvbSAnLi9hdWRpby1hbmFseXplci5zZXJ2aWNlJztcblxuZXhwb3J0IHR5cGUgQ2FsbFN0YXRlID0gJ2lkbGUnIHwgJ2Nvbm5lY3RpbmcnIHwgJ2Nvbm5lY3RlZCcgfCAndGFsa2luZycgfCAnbGlzdGVuaW5nJyB8ICdlbmRlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNjcmlwdERhdGEge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGZpbmFsOiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBWb2ljZUFnZW50U2VydmljZSB7XG4gIHByaXZhdGUgY2xpZW50OiBQaXBlY2F0Q2xpZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdHJhbnNwb3J0OiBJbnN0YW5jZVR5cGU8dHlwZW9mIFdlYlNvY2tldFRyYW5zcG9ydD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB1c2VyTWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYm90QXVkaW9FbGVtZW50OiBIVE1MQXVkaW9FbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBjYWxsU3RhdGVTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDYWxsU3RhdGU+KCdpZGxlJyk7XG4gIHByaXZhdGUgc3RhdHVzVGV4dFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuICBwcml2YXRlIGR1cmF0aW9uU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignMDA6MDAnKTtcbiAgcHJpdmF0ZSBpc01pY011dGVkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGlzVXNlclNwZWFraW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGF1ZGlvTGV2ZWxzU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyW10+KFtdKTtcbiAgcHJpdmF0ZSB1c2VyVHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUcmFuc2NyaXB0RGF0YT4oKTtcbiAgcHJpdmF0ZSBib3RUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcblxuICBwcml2YXRlIGNhbGxTdGFydFRpbWU6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgZHVyYXRpb25JbnRlcnZhbDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG5cbiAgY2FsbFN0YXRlJDogT2JzZXJ2YWJsZTxDYWxsU3RhdGU+ID0gdGhpcy5jYWxsU3RhdGVTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBzdGF0dXNUZXh0JDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgZHVyYXRpb24kOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmR1cmF0aW9uU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgaXNNaWNNdXRlZCQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmlzTWljTXV0ZWRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBpc1VzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYXVkaW9MZXZlbHMkOiBPYnNlcnZhYmxlPG51bWJlcltdPiA9IHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB1c2VyVHJhbnNjcmlwdCQ6IE9ic2VydmFibGU8VHJhbnNjcmlwdERhdGE+ID0gdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmJvdFRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKiBSZXNldCB0byBpZGxlIHN0YXRlIChlLmcuIHdoZW4gbW9kYWwgb3BlbnMgc28gdXNlciBjYW4gY2xpY2sgU3RhcnQgQ2FsbCkuICovXG4gIHJlc2V0VG9JZGxlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgPT09ICdpZGxlJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLmR1cmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kdXJhdGlvbkludGVydmFsKTtcbiAgICAgIHRoaXMuZHVyYXRpb25JbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuYXVkaW9BbmFseXplci5zdG9wKCk7XG4gICAgdGhpcy5jbGllbnQgPSBudWxsO1xuICAgIHRoaXMudHJhbnNwb3J0ID0gbnVsbDtcbiAgICBpZiAodGhpcy51c2VyTWVkaWFTdHJlYW0pIHtcbiAgICAgIHRoaXMudXNlck1lZGlhU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2godHJhY2sgPT4gdHJhY2suc3RvcCgpKTtcbiAgICAgIHRoaXMudXNlck1lZGlhU3RyZWFtID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMuYm90QXVkaW9FbGVtZW50KSB7XG4gICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgdGhpcy5ib3RBdWRpb0VsZW1lbnQuc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2lkbGUnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJycpO1xuICAgIHRoaXMuZHVyYXRpb25TdWJqZWN0Lm5leHQoJzA6MDAnKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYXVkaW9BbmFseXplcjogQXVkaW9BbmFseXplclNlcnZpY2UpIHtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuYXVkaW9MZXZlbHMkLnN1YnNjcmliZShsZXZlbHMgPT4ge1xuICAgICAgdGhpcy5hdWRpb0xldmVsc1N1YmplY3QubmV4dChsZXZlbHMpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLmlzVXNlclNwZWFraW5nJC5zdWJzY3JpYmUoaXNTcGVha2luZyA9PiB7XG4gICAgICB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5uZXh0KGlzU3BlYWtpbmcpO1xuICAgICAgaWYgKGlzU3BlYWtpbmcgJiYgdGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAnY29ubmVjdGVkJykge1xuICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnbGlzdGVuaW5nJyk7XG4gICAgICB9IGVsc2UgaWYgKCFpc1NwZWFraW5nICYmIHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSA9PT0gJ2xpc3RlbmluZycpIHtcbiAgICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY29ubmVjdChcbiAgICBhcGlVcmw6IHN0cmluZyxcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIGJvdElkOiBzdHJpbmcsXG4gICAgY29udmVyc2F0aW9uSWQ6IHN0cmluZyxcbiAgICBhcGlLZXk6IHN0cmluZyxcbiAgICBldmVudFRva2VuOiBzdHJpbmcsXG4gICAgZXZlbnRVcmw6IHN0cmluZyxcbiAgICBkb21haW5BdXRob3JpdHk6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlICE9PSAnaWRsZScpIHtcbiAgICAgIGNvbnNvbGUud2FybignQ2FsbCBhbHJlYWR5IGluIHByb2dyZXNzJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0aW5nJyk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3RpbmcuLi4nKTtcblxuICAgICAgY29uc3QgYmFzZVVybCA9IGFwaVVybC5yZXBsYWNlKC9cXC8kLywgJycpO1xuICAgICAgY29uc3QgY29ubmVjdFVybCA9IGAke2Jhc2VVcmx9L2FpL2Fzay12b2ljZWA7XG5cbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgaGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7dG9rZW59YCk7XG4gICAgICAvLyBEbyBub3Qgc2V0IENvbnRlbnQtVHlwZSBoZXJlIOKAlCB0aGUgUGlwZWNhdCBjbGllbnQgYWxyZWFkeSBzZXRzIFwiYXBwbGljYXRpb24vanNvblwiIG9uY2U7IGFkZGluZyBpdCBhZ2FpbiBwcm9kdWNlcyBcImFwcGxpY2F0aW9uL2pzb24sIGFwcGxpY2F0aW9uL2pzb25cIlxuICAgICAgaGVhZGVycy5zZXQoJ2RvbWFpbi1hdXRob3JpdHknLCBkb21haW5BdXRob3JpdHkpO1xuICAgICAgaGVhZGVycy5zZXQoJ2V2ZW50dG9rZW4nLCBldmVudFRva2VuKTtcbiAgICAgIGhlYWRlcnMuc2V0KCdldmVudHVybCcsIGV2ZW50VXJsKTtcbiAgICAgIGhlYWRlcnMuc2V0KCdoaXZlLWJvdC1pZCcsIGJvdElkKTtcbiAgICAgIGhlYWRlcnMuc2V0KCd4LWFwaS1rZXknLCBhcGlLZXkpO1xuXG4gICAgICBjb25zdCBzdGFydEJvdFBhcmFtczogQVBJUmVxdWVzdCA9IHtcbiAgICAgICAgZW5kcG9pbnQ6IGNvbm5lY3RVcmwsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHJlcXVlc3REYXRhOiB7XG4gICAgICAgICAgYm90X2lkOiBib3RJZCxcbiAgICAgICAgICBjb252ZXJzYXRpb25faWQ6IGNvbnZlcnNhdGlvbklkLFxuICAgICAgICAgIHZvaWNlOiAnYWxsb3knLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgdGhpcy50cmFuc3BvcnQgPSBuZXcgV2ViU29ja2V0VHJhbnNwb3J0KCk7XG4gICAgICB0aGlzLmNsaWVudCA9IG5ldyBQaXBlY2F0Q2xpZW50KHtcbiAgICAgICAgdHJhbnNwb3J0OiB0aGlzLnRyYW5zcG9ydCxcbiAgICAgICAgZW5hYmxlTWljOiB0cnVlLFxuICAgICAgICBlbmFibGVDYW06IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2V0dXBFdmVudEhhbmRsZXJzKCk7XG5cbiAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50ID0gbmV3IEF1ZGlvKCk7XG4gICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5hdXRvcGxheSA9IHRydWU7XG5cbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnN0YXJ0Qm90QW5kQ29ubmVjdChzdGFydEJvdFBhcmFtcyk7XG5cbiAgICAgIGNvbnN0IHRyYWNrcyA9IHRoaXMuY2xpZW50LnRyYWNrcygpO1xuICAgICAgaWYgKHRyYWNrcz8ubG9jYWw/LmF1ZGlvKSB7XG4gICAgICAgIHRoaXMudXNlck1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFt0cmFja3MubG9jYWwuYXVkaW9dKTtcbiAgICAgICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0YXJ0KHRoaXMudXNlck1lZGlhU3RyZWFtKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc01pY011dGVkU3ViamVjdC5uZXh0KCF0aGlzLmNsaWVudC5pc01pY0VuYWJsZWQpO1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0ZWQnKTtcbiAgICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0aGlzLnN0YXJ0RHVyYXRpb25UaW1lcigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjb25uZWN0aW5nIHZvaWNlIGFnZW50OicsIGVycm9yKTtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdlbmRlZCcpO1xuICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3Rpb24gZmFpbGVkJyk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5kdXJhdGlvbkludGVydmFsKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kdXJhdGlvbkludGVydmFsKTtcbiAgICAgICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcblxuICAgICAgaWYgKHRoaXMuY2xpZW50KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5jbGllbnQgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRyYW5zcG9ydCA9IG51bGw7XG5cbiAgICAgIGlmICh0aGlzLnVzZXJNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnVzZXJNZWRpYVN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKHRyYWNrID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgIHRoaXMudXNlck1lZGlhU3RyZWFtID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYm90QXVkaW9FbGVtZW50KSB7XG4gICAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50LnBhdXNlKCk7XG4gICAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50LnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgICAgIC8vIEtlZXAgY3VycmVudCBkdXJhdGlvbiBzbyBcIkNhbGwgRW5kZWRcIiBzdGF0ZSBjYW4gc2hvdyBpdCAoZS5nLiBcIkNhbGwgRW5kZWQgMTowNFwiKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBkaXNjb25uZWN0aW5nIHZvaWNlIGFnZW50OicsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVNaWMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkgcmV0dXJuO1xuICAgIGNvbnN0IG5ld1N0YXRlID0gIXRoaXMuY2xpZW50LmlzTWljRW5hYmxlZDtcbiAgICB0aGlzLmNsaWVudC5lbmFibGVNaWMobmV3U3RhdGUpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dCghbmV3U3RhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cEV2ZW50SGFuZGxlcnMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkgcmV0dXJuO1xuXG4gICAgdGhpcy5jbGllbnQub24oUlRWSUV2ZW50LkJvdFN0YXJ0ZWRTcGVha2luZywgKCkgPT4ge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ3RhbGtpbmcnKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2xpZW50Lm9uKFJUVklFdmVudC5Cb3RTdG9wcGVkU3BlYWtpbmcsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgPT09ICd0YWxraW5nJykge1xuICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnY29ubmVjdGVkJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNsaWVudC5vbihSVFZJRXZlbnQuVHJhY2tTdGFydGVkLCAodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2ssIHBhcnRpY2lwYW50PzogeyBsb2NhbD86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgaWYgKHRoaXMuYm90QXVkaW9FbGVtZW50ICYmIHBhcnRpY2lwYW50ICYmICFwYXJ0aWNpcGFudC5sb2NhbCAmJiB0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbShbdHJhY2tdKTtcbiAgICAgICAgdGhpcy5ib3RBdWRpb0VsZW1lbnQuc3JjT2JqZWN0ID0gc3RyZWFtO1xuICAgICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5wbGF5KCkuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNsaWVudC5vbihSVFZJRXZlbnQuVXNlclRyYW5zY3JpcHQsIChkYXRhOiB7IHRleHQ6IHN0cmluZzsgZmluYWw/OiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0Lm5leHQoe1xuICAgICAgICB0ZXh0OiBkYXRhLnRleHQsXG4gICAgICAgIGZpbmFsOiBkYXRhLmZpbmFsID8/IGZhbHNlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNsaWVudC5vbihSVFZJRXZlbnQuQm90VHJhbnNjcmlwdCwgKGRhdGE6IHsgdGV4dD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBpZiAoZGF0YT8udGV4dCkge1xuICAgICAgICB0aGlzLmJvdFRyYW5zY3JpcHRTdWJqZWN0Lm5leHQoZGF0YS50ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuY2xpZW50Lm9uKFJUVklFdmVudC5FcnJvciwgKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdFcnJvciBvY2N1cnJlZCcpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jbGllbnQub24oUlRWSUV2ZW50LkRpc2Nvbm5lY3RlZCwgKCkgPT4ge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Rpc2Nvbm5lY3RlZCcpO1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0RHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVEdXJhdGlvbiA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGhpcy5jYWxsU3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gNjApO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KFxuICAgICAgICAgIGAke21pbnV0ZXN9OiR7U3RyaW5nKHNlY29uZHMpLnBhZFN0YXJ0KDIsICcwJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG4gICAgdXBkYXRlRHVyYXRpb24oKTsgLy8gc2hvdyAwOjAwIGltbWVkaWF0ZWx5XG4gICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwodXBkYXRlRHVyYXRpb24sIDEwMDApO1xuICB9XG59XG4iXX0=
304
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQWEsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25GLE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUMvRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7OztBQWVoRTs7Ozs7Ozs7OztHQVVHO0FBSUgsTUFBTSxPQUFPLGlCQUFpQjtJQTRCNUIsWUFDVSxhQUFtQyxFQUNuQyxvQkFBaUQsRUFDakQsTUFBYztJQUN0Qiw4RkFBOEY7SUFDakUsVUFBa0I7UUFKdkMsa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ25DLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBNkI7UUFDakQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUVPLGVBQVUsR0FBVixVQUFVLENBQVE7UUFoQ3pDLHFCQUFnQixHQUFHLElBQUksZUFBZSxDQUFZLE1BQU0sQ0FBQyxDQUFDO1FBQzFELHNCQUFpQixHQUFHLElBQUksZUFBZSxDQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELG9CQUFlLEdBQUcsSUFBSSxlQUFlLENBQVMsT0FBTyxDQUFDLENBQUM7UUFDdkQsc0JBQWlCLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDeEQsMEJBQXFCLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDNUQsdUJBQWtCLEdBQUcsSUFBSSxlQUFlLENBQVcsRUFBRSxDQUFDLENBQUM7UUFDdkQsMEJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQWtCLENBQUM7UUFDdEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUU3QyxrQkFBYSxHQUFHLENBQUMsQ0FBQztRQUNsQixxQkFBZ0IsR0FBMEMsSUFBSSxDQUFDO1FBRS9ELGFBQVEsR0FBeUIsSUFBSSxDQUFDO1FBQ3RDLG9CQUFlLEdBQTRCLElBQUksQ0FBQztRQUVoRCxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDbkMsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFdkMsZUFBVSxHQUEwQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekUsZ0JBQVcsR0FBdUIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hFLGNBQVMsR0FBdUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwRSxnQkFBVyxHQUF3QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekUsb0JBQWUsR0FBd0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2pGLGlCQUFZLEdBQXlCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM1RSxvQkFBZSxHQUErQixJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEYsbUJBQWMsR0FBdUIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBUzVFLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNuRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUNyQyxDQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQyxLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsNkVBQTZFO0lBQzdFLFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEtBQUssTUFBTTtZQUFFLE9BQU87UUFDbkQsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFSyxPQUFPLENBQ1gsTUFBYyxFQUNkLEtBQWEsRUFDYixLQUFhLEVBQ2IsY0FBc0IsRUFDdEIsTUFBYyxFQUNkLFVBQWtCLEVBQ2xCLE9BQWUsRUFDZixRQUFnQixFQUNoQixlQUF1QixFQUN2QixXQUFvQjs7WUFFcEIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxLQUFLLE1BQU0sRUFBRTtnQkFDMUMsT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO2dCQUN6RCxPQUFPO2FBQ1I7WUFFRCxJQUFJO2dCQUNGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBRTdDLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxXQUFXLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFO29CQUNyRCxJQUFJO3dCQUNGLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQjs2QkFDNUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQzs2QkFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs2QkFDYixTQUFTLEVBQUUsQ0FBQzt3QkFDZixJQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxXQUFXOzRCQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO3FCQUM3RDtvQkFBQyxPQUFPLENBQUMsRUFBRTt3QkFDVixPQUFPLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUN6RDtpQkFDRjtnQkFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFFMUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxhQUFhLENBQUM7b0JBQ2pDLFNBQVMsRUFBRSxJQUFJLGtCQUFrQixFQUFFO29CQUNuQyxTQUFTLEVBQUUsSUFBSTtvQkFDZixTQUFTLEVBQUUsS0FBSztvQkFDaEIsU0FBUyxFQUFFO3dCQUNULFdBQVcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQzt3QkFDbkUsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO3dCQUN6RSxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO3dCQUMxRCxnQkFBZ0IsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUNuQixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FDMUU7d0JBQ0gsZUFBZSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2xFLE9BQU8sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFOzRCQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQ0FDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQ0FDMUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQ0FDcEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDOzRCQUNuRCxDQUFDLENBQUMsQ0FBQzt3QkFDTCxDQUFDO3FCQUNGO2lCQUNGLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztnQkFFekIsNkVBQTZFO2dCQUM3RSxRQUFRLENBQUMsRUFBRSxDQUNULFNBQVMsQ0FBQyxZQUFZLEVBQ3RCLENBQUMsS0FBdUIsRUFBRSxXQUFpQyxFQUFFLEVBQUU7b0JBQzdELElBQUksQ0FBQyxDQUFBLFdBQVcsYUFBWCxXQUFXLHVCQUFYLFdBQVcsQ0FBRSxLQUFLLENBQUEsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTt3QkFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7cUJBQ3ZEO2dCQUNILENBQUMsQ0FDRixDQUFDO2dCQUVGLGlEQUFpRDtnQkFDakQsUUFBUSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQ25ELENBQUM7Z0JBQ0YsUUFBUSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQ25ELENBQUM7Z0JBQ0YsUUFBUSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFLENBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDdEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDeEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDOUMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztnQkFDRixRQUFRLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsQ0FDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO29CQUNuQixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN2QyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEtBQUssV0FBVyxFQUFFO3dCQUMvQyw4REFBOEQ7d0JBQzlELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQ3hDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7cUJBQzlDO2dCQUNILENBQUMsQ0FBQyxDQUNILENBQUM7Z0JBRUYsbURBQW1EO2dCQUNuRCxNQUFNLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFFN0Isc0ZBQXNGO2dCQUN0RixNQUFNLGNBQWMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNyQyxjQUFjLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxVQUFVLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQ2hFLGNBQWMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMzQyxjQUFjLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDNUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxlQUFlLENBQUMsQ0FBQztnQkFDM0QsY0FBYyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQzVDLGNBQWMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUMxQyxjQUFjLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDaEQsY0FBYyxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFFNUQsbUZBQW1GO2dCQUNuRixNQUFNLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztvQkFDaEMsUUFBUSxFQUFFLEdBQUcsT0FBTyxzQkFBc0I7b0JBQzFDLE9BQU8sRUFBRSxjQUFjO29CQUN2QixXQUFXLEVBQUU7d0JBQ1gsTUFBTSxFQUFFLEtBQUs7d0JBQ2IsZUFBZSxFQUFFLGNBQWM7d0JBQy9CLEtBQUssRUFBRSxPQUFPO3FCQUNmO2lCQUNGLENBQUMsQ0FBQzthQUNKO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDdkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUNqRCxNQUFNLEtBQUssQ0FBQzthQUNiO1FBQ0gsQ0FBQztLQUFBO0lBRU8sa0JBQWtCO1FBQ3hCLGdFQUFnRTtRQUNoRSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRU8scUJBQXFCO1FBQzNCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRU8sVUFBVTs7UUFDaEIsa0VBQWtFO1FBQ2xFLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLE1BQU0sUUFBUSxHQUFHLE1BQUEsTUFBQyxNQUFBLElBQUksQ0FBQyxRQUFRLDBDQUFFLE1BQU0sRUFBNkMsMENBQ2hGLEdBQUcsMENBQUUsS0FBSyxDQUFDO1FBQ2YsSUFBSSxRQUFRO1lBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELHFFQUFxRTtRQUNyRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFTyxxQkFBcUI7O1FBQzNCLE1BQU0sVUFBVSxHQUFHLE1BQUEsTUFBQyxNQUFBLElBQUksQ0FBQyxRQUFRLDBDQUFFLE1BQU0sRUFBK0MsMENBQ3BGLEtBQUssMENBQUUsS0FBSyxDQUFDO1FBQ2pCLElBQUksVUFBVSxFQUFFO1lBQ2QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxXQUFXLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDekQ7SUFDSCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxQywyREFBMkQ7UUFDM0QsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDN0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQzdDO0lBQ0gsQ0FBQztJQUVPLGtCQUFrQixDQUFDLEtBQXVCOztRQUNoRCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1NBQ3RDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQWdDLDBDQUNuRSxjQUFjLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFBLFFBQVEsYUFBUixRQUFRLHVCQUFSLFFBQVEsQ0FBRSxFQUFFLE1BQUssS0FBSyxDQUFDLEVBQUU7WUFBRSxPQUFPO1FBRXRDLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxHQUFHLElBQUksV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQ3hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxDQUFDLENBQzVELENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWTs7UUFDbEIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3hCLElBQUk7Z0JBQ0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0IsTUFBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQWdDLDBDQUNsRCxjQUFjLEdBQ2YsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2FBQ3ZDO1lBQUMsV0FBTTtnQkFDTixTQUFTO2FBQ1Y7WUFDRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztTQUM3QjtJQUNILENBQUM7SUFFSyxVQUFVOztZQUNkLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzVDLENBQUM7S0FBQTtJQUVhLG9CQUFvQjs7WUFDaEMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNqQixJQUFJO29CQUNGLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztpQkFDbEM7Z0JBQUMsV0FBTTtvQkFDTixTQUFTO2lCQUNWO2dCQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2FBQ3RCO1FBQ0gsQ0FBQztLQUFBO0lBRUQsU0FBUztRQUNQLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDM0IsTUFBTSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDO1FBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2QyxJQUFJLFNBQVM7WUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsTUFBTSxJQUFJLEdBQUcsR0FBRyxFQUFFO1lBQ2hCLElBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLEVBQUU7Z0JBQzFCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDbkMsTUFBTSxDQUFDLEdBQUcsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ2pFO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxFQUFFLENBQUM7UUFDUCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQzs7OztZQTlURixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQTVCUSxvQkFBb0I7WUFEcEIsMkJBQTJCO1lBTFAsTUFBTTtZQW9FVSxNQUFNLHVCQUE5QyxNQUFNLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgTmdab25lLCBPbkRlc3Ryb3ksIFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFBpcGVjYXRDbGllbnQsIFJUVklFdmVudCB9IGZyb20gJ0BwaXBlY2F0LWFpL2NsaWVudC1qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRUcmFuc3BvcnQgfSBmcm9tICdAcGlwZWNhdC1haS93ZWJzb2NrZXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IFBsYXRmb3JtVG9rZW5SZWZyZXNoU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3BsYXRmb3JtLXRva2VuLXJlZnJlc2guc2VydmljZSc7XG5pbXBvcnQgeyBBdWRpb0FuYWx5emVyU2VydmljZSB9IGZyb20gJy4vYXVkaW8tYW5hbHl6ZXIuc2VydmljZSc7XG5cbmV4cG9ydCB0eXBlIENhbGxTdGF0ZSA9XG4gIHwgJ2lkbGUnXG4gIHwgJ2Nvbm5lY3RpbmcnXG4gIHwgJ2Nvbm5lY3RlZCdcbiAgfCAnbGlzdGVuaW5nJ1xuICB8ICd0YWxraW5nJ1xuICB8ICdlbmRlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNjcmlwdERhdGEge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGZpbmFsOiBib29sZWFuO1xufVxuXG4vKipcbiAqIFZvaWNlIGFnZW50IG9yY2hlc3RyYXRvciB1c2luZyB0aGUgb2ZmaWNpYWwgUGlwZWNhdENsaWVudCBTREsuXG4gKlxuICogQXVkaW8gZmxvdyAobWlycm9ycyB0aGUgUmVhY3QgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uKTpcbiAqICAtIExvY2FsIG1pYzogYWNxdWlyZWQgYnkgUGlwZWNhdENsaWVudC5pbml0RGV2aWNlcygpOyBsb2NhbCB0cmFjayBmZWQgdG9cbiAqICAgIEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIGZvciB3YXZlZm9ybSB2aXN1YWxpc2F0aW9uLlxuICogIC0gQm90IGF1ZGlvOiByZWNlaXZlZCBhcyBhIE1lZGlhU3RyZWFtVHJhY2sgdmlhIFJUVklFdmVudC5UcmFja1N0YXJ0ZWQsXG4gKiAgICBwbGF5ZWQgdGhyb3VnaCBhIGhpZGRlbiA8YXVkaW8+IGVsZW1lbnQuXG4gKiAgLSBBbGwgYmluYXJ5IHByb3RvYnVmIGZyYW1pbmcgLyBSVFZJIHByb3RvY29sIGhhbmRsZWQgYnlcbiAqICAgIEBwaXBlY2F0LWFpL2NsaWVudC1qcyArIEBwaXBlY2F0LWFpL3dlYnNvY2tldC10cmFuc3BvcnQuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBWb2ljZUFnZW50U2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgY2FsbFN0YXRlU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q2FsbFN0YXRlPignaWRsZScpO1xuICBwcml2YXRlIHN0YXR1c1RleHRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgcHJpdmF0ZSBkdXJhdGlvblN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJzAwOjAwJyk7XG4gIHByaXZhdGUgaXNNaWNNdXRlZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBpc1VzZXJTcGVha2luZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBhdWRpb0xldmVsc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcltdPihbXSk7XG4gIHByaXZhdGUgdXNlclRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8VHJhbnNjcmlwdERhdGE+KCk7XG4gIHByaXZhdGUgYm90VHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG5cbiAgcHJpdmF0ZSBjYWxsU3RhcnRUaW1lID0gMDtcbiAgcHJpdmF0ZSBkdXJhdGlvbkludGVydmFsOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHBjQ2xpZW50OiBQaXBlY2F0Q2xpZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYm90QXVkaW9FbGVtZW50OiBIVE1MQXVkaW9FbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjYWxsU3RhdGUkOiBPYnNlcnZhYmxlPENhbGxTdGF0ZT4gPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHN0YXR1c1RleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLnN0YXR1c1RleHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBkdXJhdGlvbiQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuZHVyYXRpb25TdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBpc01pY011dGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNNaWNNdXRlZFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzVXNlclNwZWFraW5nJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBhdWRpb0xldmVscyQ6IE9ic2VydmFibGU8bnVtYmVyW10+ID0gdGhpcy5hdWRpb0xldmVsc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPSB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYm90VHJhbnNjcmlwdCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhdWRpb0FuYWx5emVyOiBBdWRpb0FuYWx5emVyU2VydmljZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtVG9rZW5SZWZyZXNoOiBQbGF0Zm9ybVRva2VuUmVmcmVzaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICAvKiogYE9iamVjdGAgbm90IGBvYmplY3RgIOKAlCBuZ2MgbWV0YWRhdGEgY29sbGVjdGlvbiByZWplY3RzIHRoZSBgb2JqZWN0YCB0eXBlIGluIERJIHBhcmFtcy4gKi9cbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuYXVkaW9BbmFseXplci5hdWRpb0xldmVscyQuc3Vic2NyaWJlKChsZXZlbHMpID0+XG4gICAgICAgIHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0Lm5leHQobGV2ZWxzKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIHZvaWQgdGhpcy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICAvKiogUmVzZXQgdG8gaWRsZSAoZS5nLiB3aGVuIG1vZGFsIHJlLW9wZW5zIHNvIHVzZXIgY2FuIGNsaWNrIFN0YXJ0IENhbGwpLiAqL1xuICByZXNldFRvSWRsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAnaWRsZScpIHJldHVybjtcbiAgICB2b2lkIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdpZGxlJyk7XG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCcnKTtcbiAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KCcwOjAwJyk7XG4gIH1cblxuICBhc3luYyBjb25uZWN0KFxuICAgIGFwaVVybDogc3RyaW5nLFxuICAgIHRva2VuOiBzdHJpbmcsXG4gICAgYm90SWQ6IHN0cmluZyxcbiAgICBjb252ZXJzYXRpb25JZDogc3RyaW5nLFxuICAgIGFwaUtleTogc3RyaW5nLFxuICAgIGV2ZW50VG9rZW46IHN0cmluZyxcbiAgICBldmVudElkOiBzdHJpbmcsXG4gICAgZXZlbnRVcmw6IHN0cmluZyxcbiAgICBkb21haW5BdXRob3JpdHk6IHN0cmluZyxcbiAgICB1c2Vyc0FwaVVybD86IHN0cmluZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSAhPT0gJ2lkbGUnKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tIaXZlR3B0IFZvaWNlXSBDYWxsIGFscmVhZHkgaW4gcHJvZ3Jlc3MnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RpbmcnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ29ubmVjdGluZy4uLicpO1xuXG4gICAgICBsZXQgYWNjZXNzVG9rZW4gPSB0b2tlbjtcbiAgICAgIGlmICh1c2Vyc0FwaVVybCAmJiBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZW5zdXJlZCA9IGF3YWl0IHRoaXMucGxhdGZvcm1Ub2tlblJlZnJlc2hcbiAgICAgICAgICAgIC5lbnN1cmVWYWxpZEFjY2Vzc1Rva2VuKHRva2VuLCB1c2Vyc0FwaVVybClcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAudG9Qcm9taXNlKCk7XG4gICAgICAgICAgaWYgKGVuc3VyZWQ/LmFjY2Vzc1Rva2VuKSBhY2Nlc3NUb2tlbiA9IGVuc3VyZWQuYWNjZXNzVG9rZW47XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1tIaXZlR3B0IFZvaWNlXSBUb2tlbiByZWZyZXNoIGZhaWxlZCcsIGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBhcGlVcmwucmVwbGFjZSgvXFwvJC8sICcnKTtcblxuICAgICAgY29uc3QgcGNDbGllbnQgPSBuZXcgUGlwZWNhdENsaWVudCh7XG4gICAgICAgIHRyYW5zcG9ydDogbmV3IFdlYlNvY2tldFRyYW5zcG9ydCgpLFxuICAgICAgICBlbmFibGVNaWM6IHRydWUsXG4gICAgICAgIGVuYWJsZUNhbTogZmFsc2UsXG4gICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgIG9uQ29ubmVjdGVkOiAoKSA9PiB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vblBpcGVjYXRDb25uZWN0ZWQoKSksXG4gICAgICAgICAgb25EaXNjb25uZWN0ZWQ6ICgpID0+IHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm9uUGlwZWNhdERpc2Nvbm5lY3RlZCgpKSxcbiAgICAgICAgICBvbkJvdFJlYWR5OiAoKSA9PiB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vbkJvdFJlYWR5KCkpLFxuICAgICAgICAgIG9uVXNlclRyYW5zY3JpcHQ6IChkYXRhKSA9PlxuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+XG4gICAgICAgICAgICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0Lm5leHQoeyB0ZXh0OiBkYXRhLnRleHQsIGZpbmFsOiAhIWRhdGEuZmluYWwgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIG9uQm90VHJhbnNjcmlwdDogKGRhdGEpID0+XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KGRhdGEudGV4dCkpLFxuICAgICAgICAgIG9uRXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tIaXZlR3B0IFZvaWNlXSBQaXBlY2F0Q2xpZW50IGVycm9yJywgZXJyKTtcbiAgICAgICAgICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICAgICAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ29ubmVjdGlvbiBmYWlsZWQnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5wY0NsaWVudCA9IHBjQ2xpZW50O1xuXG4gICAgICAvLyBCb3QgYXVkaW8gYXJyaXZlcyBhcyBhIE1lZGlhU3RyZWFtVHJhY2sg4oCUIHdpcmUgdG8gYSBoaWRkZW4gPGF1ZGlvPiBlbGVtZW50XG4gICAgICBwY0NsaWVudC5vbihcbiAgICAgICAgUlRWSUV2ZW50LlRyYWNrU3RhcnRlZCxcbiAgICAgICAgKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCBwYXJ0aWNpcGFudD86IHsgbG9jYWw/OiBib29sZWFuIH0pID0+IHtcbiAgICAgICAgICBpZiAoIXBhcnRpY2lwYW50Py5sb2NhbCAmJiB0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5zZXR1cEJvdEF1ZGlvVHJhY2sodHJhY2spKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICAvLyBTcGVha2luZyBzdGF0ZSBjb21lcyBzdHJhaWdodCBmcm9tIFJUVkkgZXZlbnRzXG4gICAgICBwY0NsaWVudC5vbihSVFZJRXZlbnQuQm90U3RhcnRlZFNwZWFraW5nLCAoKSA9PlxuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vbkJvdFN0YXJ0ZWRTcGVha2luZygpKSxcbiAgICAgICk7XG4gICAgICBwY0NsaWVudC5vbihSVFZJRXZlbnQuQm90U3RvcHBlZFNwZWFraW5nLCAoKSA9PlxuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vbkJvdFN0b3BwZWRTcGVha2luZygpKSxcbiAgICAgICk7XG4gICAgICBwY0NsaWVudC5vbihSVFZJRXZlbnQuVXNlclN0YXJ0ZWRTcGVha2luZywgKCkgPT5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdsaXN0ZW5pbmcnKTtcbiAgICAgICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0xpc3RlbmluZy4uLicpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBwY0NsaWVudC5vbihSVFZJRXZlbnQuVXNlclN0b3BwZWRTcGVha2luZywgKCkgPT5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgICAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAnbGlzdGVuaW5nJykge1xuICAgICAgICAgICAgLy8gQnJpZWYgJ1Byb2Nlc3NpbmcuLi4nIHdoaWxlIHdlIHdhaXQgZm9yIHRoZSBib3QgdG8gcmVzcG9uZC5cbiAgICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnUHJvY2Vzc2luZy4uLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyBBY3F1aXJlIG1pYyAodHJpZ2dlcnMgYnJvd3NlciBwZXJtaXNzaW9uIHByb21wdClcbiAgICAgIGF3YWl0IHBjQ2xpZW50LmluaXREZXZpY2VzKCk7XG5cbiAgICAgIC8vIEJ1aWxkIGhlYWRlcnMgdXNpbmcgdGhlIGJyb3dzZXIgSGVhZGVycyBBUEkgKHJlcXVpcmVkIGJ5IHBpcGVjYXQncyBBUElSZXF1ZXN0IHR5cGUpXG4gICAgICBjb25zdCByZXF1ZXN0SGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7YWNjZXNzVG9rZW59YCk7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ3gtYXBpLWtleScsIGFwaUtleSk7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ2hpdmUtYm90LWlkJywgYm90SWQpO1xuICAgICAgcmVxdWVzdEhlYWRlcnMuYXBwZW5kKCdkb21haW4tYXV0aG9yaXR5JywgZG9tYWluQXV0aG9yaXR5KTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgnZXZlbnRVcmwnLCBldmVudFVybCk7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ2V2ZW50SWQnLCBldmVudElkKTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgnZXZlbnRUb2tlbicsIGV2ZW50VG9rZW4pO1xuICAgICAgcmVxdWVzdEhlYWRlcnMuYXBwZW5kKCduZ3Jvay1za2lwLWJyb3dzZXItd2FybmluZycsICd0cnVlJyk7XG5cbiAgICAgIC8vIFBPU1QgdG8gL2FpL2Fzay12b2ljZS1zb2NrZXQg4oaSIHJlY2VpdmVzIHsgd3NfdXJsIH0g4oaSIFdlYlNvY2tldFRyYW5zcG9ydCBjb25uZWN0c1xuICAgICAgYXdhaXQgcGNDbGllbnQuc3RhcnRCb3RBbmRDb25uZWN0KHtcbiAgICAgICAgZW5kcG9pbnQ6IGAke2Jhc2VVcmx9L2FpL2Fzay12b2ljZS1zb2NrZXRgLFxuICAgICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVycyxcbiAgICAgICAgcmVxdWVzdERhdGE6IHtcbiAgICAgICAgICBib3RfaWQ6IGJvdElkLFxuICAgICAgICAgIGNvbnZlcnNhdGlvbl9pZDogY29udmVyc2F0aW9uSWQsXG4gICAgICAgICAgdm9pY2U6ICdhbGxveScsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW0hpdmVHcHQgVm9pY2VdIGNvbm5lY3QgZmFpbGVkJywgZXJyb3IpO1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICBhd2FpdCB0aGlzLmNsZWFudXBQaXBlY2F0Q2xpZW50KCk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3Rpb24gZmFpbGVkJyk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uUGlwZWNhdENvbm5lY3RlZCgpOiB2b2lkIHtcbiAgICAvLyBTdGFydCB0aGUgZHVyYXRpb24gdGltZXIgZnJvbSB0aGUgbW9tZW50IHRoZSBzZXNzaW9uIGlzIGxpdmUuXG4gICAgdGhpcy5jYWxsU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnN0YXJ0RHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3RlZCcpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dChmYWxzZSk7XG4gICAgdGhpcy5zdGFydExvY2FsTWljQW5hbHl6ZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25QaXBlY2F0RGlzY29ubmVjdGVkKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcER1cmF0aW9uVGltZXIoKTtcbiAgICB0aGlzLmNhbGxTdGFydFRpbWUgPSAwO1xuICAgIHRoaXMuYXVkaW9BbmFseXplci5zdG9wKCk7XG4gICAgdGhpcy5zdG9wQm90QXVkaW8oKTtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Cb3RSZWFkeSgpOiB2b2lkIHtcbiAgICAvLyBSZXRyeSB0cmFjayB3aXJpbmcgaW4gY2FzZSB0cmFja3Mgd2VyZW4ndCByZWFkeSBhdCBvbkNvbm5lY3RlZC5cbiAgICB0aGlzLnN0YXJ0TG9jYWxNaWNBbmFseXplcigpO1xuICAgIGNvbnN0IGJvdFRyYWNrID0gKHRoaXMucGNDbGllbnQ/LnRyYWNrcygpIGFzIHsgYm90PzogeyBhdWRpbz86IE1lZGlhU3RyZWFtVHJhY2sgfSB9KVxuICAgICAgPy5ib3Q/LmF1ZGlvO1xuICAgIGlmIChib3RUcmFjaykgdGhpcy5zZXR1cEJvdEF1ZGlvVHJhY2soYm90VHJhY2spO1xuICAgIC8vIEJvdCBpcyBpbml0aWFsaXNlZCDigJQgc2lnbmFsIHRoYXQgd2UncmUgbm93IHdhaXRpbmcgZm9yIHVzZXIgaW5wdXQuXG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdMaXN0ZW5pbmcuLi4nKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRMb2NhbE1pY0FuYWx5emVyKCk6IHZvaWQge1xuICAgIGNvbnN0IGxvY2FsVHJhY2sgPSAodGhpcy5wY0NsaWVudD8udHJhY2tzKCkgYXMgeyBsb2NhbD86IHsgYXVkaW8/OiBNZWRpYVN0cmVhbVRyYWNrIH0gfSlcbiAgICAgID8ubG9jYWw/LmF1ZGlvO1xuICAgIGlmIChsb2NhbFRyYWNrKSB7XG4gICAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RhcnQobmV3IE1lZGlhU3RyZWFtKFtsb2NhbFRyYWNrXSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25Cb3RTdGFydGVkU3BlYWtpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ3RhbGtpbmcnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ1RhbGtpbmcuLi4nKTtcbiAgICAvLyBNYXJrIHVzZXIgYXMgbm8gbG9uZ2VyIHNwZWFraW5nIHdoZW4gYm90IHRha2VzIHRoZSB0dXJuLlxuICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkJvdFN0b3BwZWRTcGVha2luZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAndGFsa2luZycpIHtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnTGlzdGVuaW5nLi4uJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cEJvdEF1ZGlvVHJhY2sodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYm90QXVkaW9FbGVtZW50KSB7XG4gICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudCA9IG5ldyBBdWRpbygpO1xuICAgICAgdGhpcy5ib3RBdWRpb0VsZW1lbnQuYXV0b3BsYXkgPSB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZyA9ICh0aGlzLmJvdEF1ZGlvRWxlbWVudC5zcmNPYmplY3QgYXMgTWVkaWFTdHJlYW0gfCBudWxsKVxuICAgICAgPy5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgIGlmIChleGlzdGluZz8uaWQgPT09IHRyYWNrLmlkKSByZXR1cm47XG5cbiAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3RyYWNrXSk7XG4gICAgdGhpcy5ib3RBdWRpb0VsZW1lbnQucGxheSgpLmNhdGNoKChlcnIpID0+XG4gICAgICBjb25zb2xlLndhcm4oJ1tIaXZlR3B0IFZvaWNlXSBCb3QgYXVkaW8gcGxheSBibG9ja2VkJywgZXJyKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wQm90QXVkaW8oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYm90QXVkaW9FbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgICAodGhpcy5ib3RBdWRpb0VsZW1lbnQuc3JjT2JqZWN0IGFzIE1lZGlhU3RyZWFtIHwgbnVsbClcbiAgICAgICAgICA/LmdldEF1ZGlvVHJhY2tzKClcbiAgICAgICAgICAuZm9yRWFjaCgodCkgPT4gdC5zdG9wKCkpO1xuICAgICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgICAgfVxuICAgICAgdGhpcy5ib3RBdWRpb0VsZW1lbnQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BCb3RBdWRpbygpO1xuICAgIGF3YWl0IHRoaXMuY2xlYW51cFBpcGVjYXRDbGllbnQoKTtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xlYW51cFBpcGVjYXRDbGllbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucGNDbGllbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMucGNDbGllbnQuZGlzY29ubmVjdCgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgICAgfVxuICAgICAgdGhpcy5wY0NsaWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlTWljKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wY0NsaWVudCkgcmV0dXJuO1xuICAgIGNvbnN0IG5leHRNdXRlZCA9ICF0aGlzLmlzTWljTXV0ZWRTdWJqZWN0LnZhbHVlO1xuICAgIHRoaXMucGNDbGllbnQuZW5hYmxlTWljKCFuZXh0TXV0ZWQpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dChuZXh0TXV0ZWQpO1xuICAgIGlmIChuZXh0TXV0ZWQpIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydER1cmF0aW9uVGltZXIoKTogdm9pZCB7XG4gICAgY29uc3QgdGljayA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGhpcy5jYWxsU3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBtID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gNjApO1xuICAgICAgICBjb25zdCBzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KGAke219OiR7U3RyaW5nKHMpLnBhZFN0YXJ0KDIsICcwJyl9YCk7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aWNrKCk7XG4gICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwodGljaywgMTAwMCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BEdXJhdGlvblRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmR1cmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kdXJhdGlvbkludGVydmFsKTtcbiAgICAgIHRoaXMuZHVyYXRpb25JbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -3,6 +3,10 @@ import { CommonModule } from '@angular/common';
3
3
  import { VoiceAgentModalComponent } from './components/voice-agent-modal/voice-agent-modal.component';
4
4
  import { VoiceAgentService } from './services/voice-agent.service';
5
5
  import { AudioAnalyzerService } from './services/audio-analyzer.service';
6
+ /**
7
+ * Voice agent module. Uses @pipecat-ai/client-js + @pipecat-ai/websocket-transport
8
+ * (peer dependencies) for WebSocket transport, RTVI protocol, and audio.
9
+ */
6
10
  export class VoiceAgentModule {
7
11
  }
8
12
  VoiceAgentModule.decorators = [
@@ -15,11 +19,11 @@ VoiceAgentModule.decorators = [
15
19
  ],
16
20
  providers: [
17
21
  VoiceAgentService,
18
- AudioAnalyzerService
22
+ AudioAnalyzerService,
19
23
  ],
20
24
  exports: [
21
25
  VoiceAgentModalComponent
22
26
  ]
23
27
  },] }
24
28
  ];
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQubW9kdWxlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3ZvaWNlLWFnZW50Lm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN0RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQWlCekUsTUFBTSxPQUFPLGdCQUFnQjs7O1lBZjVCLFFBQVEsU0FBQztnQkFDUixZQUFZLEVBQUU7b0JBQ1osd0JBQXdCO2lCQUN6QjtnQkFDRCxPQUFPLEVBQUU7b0JBQ1AsWUFBWTtpQkFDYjtnQkFDRCxTQUFTLEVBQUU7b0JBQ1QsaUJBQWlCO29CQUNqQixvQkFBb0I7aUJBQ3JCO2dCQUNELE9BQU8sRUFBRTtvQkFDUCx3QkFBd0I7aUJBQ3pCO2FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFZvaWNlQWdlbnRNb2RhbENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy92b2ljZS1hZ2VudC1tb2RhbC92b2ljZS1hZ2VudC1tb2RhbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVm9pY2VBZ2VudFNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL3ZvaWNlLWFnZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXVkaW9BbmFseXplclNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtcbiAgICBWb2ljZUFnZW50TW9kYWxDb21wb25lbnRcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZVxuICBdLFxuICBwcm92aWRlcnM6IFtcbiAgICBWb2ljZUFnZW50U2VydmljZSxcbiAgICBBdWRpb0FuYWx5emVyU2VydmljZVxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgVm9pY2VBZ2VudE1vZGFsQ29tcG9uZW50XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VBZ2VudE1vZHVsZSB7IH1cbiJdfQ==
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQubW9kdWxlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3ZvaWNlLWFnZW50Lm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN0RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUV6RTs7O0dBR0c7QUFnQkgsTUFBTSxPQUFPLGdCQUFnQjs7O1lBZjVCLFFBQVEsU0FBQztnQkFDUixZQUFZLEVBQUU7b0JBQ1osd0JBQXdCO2lCQUN6QjtnQkFDRCxPQUFPLEVBQUU7b0JBQ1AsWUFBWTtpQkFDYjtnQkFDRCxTQUFTLEVBQUU7b0JBQ1QsaUJBQWlCO29CQUNqQixvQkFBb0I7aUJBQ3JCO2dCQUNELE9BQU8sRUFBRTtvQkFDUCx3QkFBd0I7aUJBQ3pCO2FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFZvaWNlQWdlbnRNb2RhbENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy92b2ljZS1hZ2VudC1tb2RhbC92b2ljZS1hZ2VudC1tb2RhbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVm9pY2VBZ2VudFNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL3ZvaWNlLWFnZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXVkaW9BbmFseXplclNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UnO1xuXG4vKipcbiAqIFZvaWNlIGFnZW50IG1vZHVsZS4gVXNlcyBAcGlwZWNhdC1haS9jbGllbnQtanMgKyBAcGlwZWNhdC1haS93ZWJzb2NrZXQtdHJhbnNwb3J0XG4gKiAocGVlciBkZXBlbmRlbmNpZXMpIGZvciBXZWJTb2NrZXQgdHJhbnNwb3J0LCBSVFZJIHByb3RvY29sLCBhbmQgYXVkaW8uXG4gKi9cbkBOZ01vZHVsZSh7XG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFZvaWNlQWdlbnRNb2RhbENvbXBvbmVudFxuICBdLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIHByb3ZpZGVyczogW1xuICAgIFZvaWNlQWdlbnRTZXJ2aWNlLFxuICAgIEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlLFxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgVm9pY2VBZ2VudE1vZGFsQ29tcG9uZW50XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VBZ2VudE1vZHVsZSB7IH1cbiJdfQ==
@@ -1,4 +1,4 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  export const VOICE_MODAL_CONFIG = new InjectionToken('VOICE_MODAL_CONFIG');
3
3
  export const VOICE_MODAL_CLOSE_CALLBACK = new InjectionToken('VOICE_MODAL_CLOSE_CALLBACK');
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtbW9kYWwtdG9rZW5zLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3ZvaWNlLW1vZGFsLXRva2Vucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBZ0IvQyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLGNBQWMsQ0FBbUIsb0JBQW9CLENBQUMsQ0FBQztBQUM3RixNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLGNBQWMsQ0FBYSw0QkFBNEIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBWb2ljZU1vZGFsQ29uZmlnIHtcbiAgYXBpVXJsOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIGJvdElkOiBzdHJpbmc7XG4gIGNvbnZlcnNhdGlvbklkOiBzdHJpbmc7XG4gIGFwaUtleTogc3RyaW5nO1xuICBldmVudFRva2VuOiBzdHJpbmc7XG4gIGV2ZW50VXJsOiBzdHJpbmc7XG4gIGRvbWFpbkF1dGhvcml0eTogc3RyaW5nO1xuICBhZ2VudE5hbWU6IHN0cmluZztcbiAgYWdlbnRSb2xlOiBzdHJpbmc7XG4gIGFnZW50QXZhdGFyPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgVk9JQ0VfTU9EQUxfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPFZvaWNlTW9kYWxDb25maWc+KCdWT0lDRV9NT0RBTF9DT05GSUcnKTtcbmV4cG9ydCBjb25zdCBWT0lDRV9NT0RBTF9DTE9TRV9DQUxMQkFDSyA9IG5ldyBJbmplY3Rpb25Ub2tlbjwoKSA9PiB2b2lkPignVk9JQ0VfTU9EQUxfQ0xPU0VfQ0FMTEJBQ0snKTtcbiJdfQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtbW9kYWwtdG9rZW5zLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3ZvaWNlLW1vZGFsLXRva2Vucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBb0IvQyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLGNBQWMsQ0FBbUIsb0JBQW9CLENBQUMsQ0FBQztBQUM3RixNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLGNBQWMsQ0FBYSw0QkFBNEIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBWb2ljZU1vZGFsQ29uZmlnIHtcbiAgYXBpVXJsOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIGJvdElkOiBzdHJpbmc7XG4gIGNvbnZlcnNhdGlvbklkOiBzdHJpbmc7XG4gIGFwaUtleTogc3RyaW5nO1xuICBldmVudFRva2VuOiBzdHJpbmc7XG4gIC8qKiBFdmVudCBzY29wZSBpZCAoc2FtZSBhcyBob3N0IGBldmVudElkYCAvIEFQSSBgZXZlbnRzLzpldmVudElkLy4uLmApLiAqL1xuICBldmVudElkOiBzdHJpbmc7XG4gIGV2ZW50VXJsOiBzdHJpbmc7XG4gIGRvbWFpbkF1dGhvcml0eTogc3RyaW5nO1xuICBhZ2VudE5hbWU6IHN0cmluZztcbiAgYWdlbnRSb2xlOiBzdHJpbmc7XG4gIGFnZW50QXZhdGFyPzogc3RyaW5nO1xuICAvKiogU2FtZSBiYXNlIGFzIGhvc3QgYFVTRVJTX0FQSWAgKGUuZy4gYGh0dHBzOi8vZXMtdXNlci5zb2NpYWwyNy5jb20vYXBpYCkgZm9yIHByb2FjdGl2ZSB0b2tlbiByZWZyZXNoLiAqL1xuICB1c2Vyc0FwaVVybD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IFZPSUNFX01PREFMX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxWb2ljZU1vZGFsQ29uZmlnPignVk9JQ0VfTU9EQUxfQ09ORklHJyk7XG5leHBvcnQgY29uc3QgVk9JQ0VfTU9EQUxfQ0xPU0VfQ0FMTEJBQ0sgPSBuZXcgSW5qZWN0aW9uVG9rZW48KCkgPT4gdm9pZD4oJ1ZPSUNFX01PREFMX0NMT1NFX0NBTExCQUNLJyk7XG4iXX0=