@sinequa/assistant 3.9.2 → 3.9.3

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 (43) hide show
  1. package/chat/chat.component.d.ts +35 -38
  2. package/chat/chat.service.d.ts +190 -84
  3. package/chat/debug-message/debug-message-details/debug-message-details.component.d.ts +19 -0
  4. package/chat/debug-message/debug-message.component.d.ts +9 -12
  5. package/chat/debug-message/debug-message.service.d.ts +15 -0
  6. package/chat/documents-upload/document-list/document-list.component.d.ts +1 -0
  7. package/chat/public-api.d.ts +0 -2
  8. package/chat/saved-chats/i18n/en.json +1 -1
  9. package/chat/saved-chats/i18n/fr.json +1 -1
  10. package/chat/saved-chats/saved-chats.component.d.ts +1 -0
  11. package/chat/saved-chats/saved-chats.service.d.ts +27 -0
  12. package/chat/services/assistant-configuration.service.d.ts +34 -0
  13. package/chat/services/assistant-metadata.service.d.ts +18 -0
  14. package/chat/services/assistant-tokens-tracking.service.d.ts +23 -0
  15. package/chat/services/assistant-ws-frames.service.d.ts +50 -0
  16. package/chat/services/signalR-connection.service.d.ts +25 -0
  17. package/chat/types.d.ts +12 -3
  18. package/chat/utils/utils.service.d.ts +67 -0
  19. package/esm2022/chat/chat.component.mjs +198 -227
  20. package/esm2022/chat/chat.service.mjs +450 -267
  21. package/esm2022/chat/debug-message/debug-message-details/debug-message-details.component.mjs +43 -0
  22. package/esm2022/chat/debug-message/debug-message.component.mjs +27 -30
  23. package/esm2022/chat/debug-message/debug-message.service.mjs +52 -0
  24. package/esm2022/chat/dialogs/rename-saved-chat.component.mjs +6 -5
  25. package/esm2022/chat/documents-upload/document-list/document-list.component.mjs +4 -2
  26. package/esm2022/chat/public-api.mjs +1 -3
  27. package/esm2022/chat/saved-chats/saved-chats.component.mjs +11 -10
  28. package/esm2022/chat/saved-chats/saved-chats.service.mjs +165 -0
  29. package/esm2022/chat/services/assistant-configuration.service.mjs +171 -0
  30. package/esm2022/chat/services/assistant-metadata.service.mjs +67 -0
  31. package/esm2022/chat/services/assistant-tokens-tracking.service.mjs +57 -0
  32. package/esm2022/chat/services/assistant-ws-frames.service.mjs +392 -0
  33. package/esm2022/chat/services/signalR-connection.service.mjs +109 -0
  34. package/esm2022/chat/types.mjs +1 -1
  35. package/esm2022/chat/unified-plugins/embedded-image-reference.plugin.mjs +2 -3
  36. package/esm2022/chat/utils/utils.service.mjs +170 -0
  37. package/fesm2022/sinequa-assistant-chat.mjs +2020 -1648
  38. package/fesm2022/sinequa-assistant-chat.mjs.map +1 -1
  39. package/package.json +1 -1
  40. package/chat/rest-chat.service.d.ts +0 -31
  41. package/chat/websocket-chat.service.d.ts +0 -102
  42. package/esm2022/chat/rest-chat.service.mjs +0 -300
  43. package/esm2022/chat/websocket-chat.service.mjs +0 -659
@@ -0,0 +1,392 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { TranslocoService } from '@jsverse/transloco';
3
+ import { Observable, Subject, fromEvent, merge, of, throwError } from 'rxjs';
4
+ import { map, mergeMap, takeUntil, tap, take, switchMap, finalize } from 'rxjs/operators';
5
+ import { guid } from "@sinequa/atomic";
6
+ import { AppService } from './app.service';
7
+ import { AssistantUtils } from '../utils/utils.service';
8
+ import { NotificationsService } from './notification.service';
9
+ import * as i0 from "@angular/core";
10
+ export class AssistantWsFramesService {
11
+ constructor() {
12
+ this.appService = inject(AppService);
13
+ this.transloco = inject(TranslocoService);
14
+ this.assistantUtils = inject(AssistantUtils);
15
+ this.notificationsService = inject(NotificationsService);
16
+ this._messageHandlers = new Map();
17
+ this._actionMap = new Map();
18
+ this._progress = undefined;
19
+ this._attachments = [];
20
+ this._debugMessages = [];
21
+ }
22
+ init(context) {
23
+ if (this.context) {
24
+ console.warn('AssistantWsFramesService already initialized.');
25
+ return;
26
+ }
27
+ this.context = context;
28
+ }
29
+ ensureInitialized() {
30
+ if (!this.context) {
31
+ throw new Error('AssistantWsFramesService not initialized. Call init() first.');
32
+ }
33
+ }
34
+ fetch(messages, query) {
35
+ this.ensureInitialized();
36
+ const context = this.context;
37
+ const assistantConfig = context.getAssistantConfig();
38
+ // Start streaming by invoking the Chat method
39
+ context.setStreamingStatus(true);
40
+ // Prepare the payload to send to the Chat method
41
+ const data = {
42
+ history: messages,
43
+ functions: assistantConfig.defaultValues.functions?.filter(func => func.enabled).map(func => func.name),
44
+ debug: assistantConfig.defaultValues.debug,
45
+ serviceSettings: {
46
+ service_id: assistantConfig.defaultValues.service_id,
47
+ model_id: assistantConfig.defaultValues.model_id,
48
+ top_p: assistantConfig.defaultValues.top_p,
49
+ temperature: assistantConfig.defaultValues.temperature,
50
+ max_tokens: assistantConfig.defaultValues.max_tokens,
51
+ ...assistantConfig.additionalServiceSettings
52
+ },
53
+ appQuery: {
54
+ app: this.appService.appName,
55
+ query
56
+ },
57
+ instanceId: context.getChatInstanceId(),
58
+ chatId: context.getChatId(),
59
+ genericChatErrorMessage: assistantConfig.globalSettings.genericChatErrorMessage ? this.transloco.translate(assistantConfig.globalSettings.genericChatErrorMessage) : ""
60
+ };
61
+ // Initialize the response with an empty assistant message
62
+ // here display: true is needed in order to be able to show the progress
63
+ // here messageId is needed but it is temporary and will be replaced by the correct messageId generated by the assistant when the message starts streaming
64
+ this._response = [{ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid() } }];
65
+ // Create a Subject to signal completion
66
+ const completion$ = new Subject();
67
+ // Create observables for each non-global handler in the _messageHandlers map (default and eventual custom ones) once it is triggered by the hub connection
68
+ const observables = Array
69
+ .from(this._messageHandlers.entries())
70
+ .filter(([eventName, eventHandler]) => !eventHandler.isGlobalHandler)
71
+ .map(([eventName, eventHandler]) => fromEvent(context.getHubConnection(), eventName).pipe(mergeMap((event) => {
72
+ // Wrap the handler in a try-catch block to prevent the entire stream from failing if an error occurs in a single handler
73
+ try {
74
+ // Execute the handler and emit the result
75
+ // NB: here we could use [eventHandler.handler(event)] which behind the scenes mergeMap interprets this array as an observable sequence with one item, which it then emits
76
+ return of(eventHandler.handler(event));
77
+ }
78
+ catch (error) {
79
+ console.error(`Error in event handler for ${eventName}:`, error);
80
+ // Use throwError to propagate the error downstream
81
+ return throwError(() => new Error(`Error in event handler for ${eventName}: ${error}`));
82
+ }
83
+ })));
84
+ // Then merge them into a single observable in order to simulate the streaming behavior
85
+ const combined$ = merge(...observables).pipe(map(() => {
86
+ // Define $progress from the _actionMap
87
+ const actions = Array.from(this._actionMap.values());
88
+ this._progress = actions.length > 0
89
+ ? actions.map((a) => ({
90
+ title: a.displayName ?? "",
91
+ content: a.displayValue ?? "",
92
+ done: a.executionTime !== undefined,
93
+ time: a.executionTime,
94
+ }))
95
+ : undefined;
96
+ // Always update ONLY the first assistant message of the _response with the new $progress, $attachment and $debug
97
+ // Assuming that the first assistant message is always visible since the hub does not send hidden messages by design
98
+ // So even if the first assistant message is hidden (display: false), the _response[0] will and should contain :
99
+ // - $progress, $attachment and $debug
100
+ // - the content of the first visible assistant message in the workflow
101
+ // This is mandatory in order to match the behavior of consecutive messages and maintain consistency with the chatHistory
102
+ if (!!this._progress || this._attachments.length > 0 || this._debugMessages.length > 0) {
103
+ this._response[0].additionalProperties.$progress = this._progress;
104
+ this._response[0].additionalProperties.$attachment = this._attachments;
105
+ this._response[0].additionalProperties.$debug = this._debugMessages;
106
+ }
107
+ // Return the result
108
+ return { history: [...messages, ...this._response], executionTime: this._executionTime, executionTimeMilliseconds: this._executionTimeMilliseconds };
109
+ }),
110
+ // Complete the observable when completion$ emits
111
+ takeUntil(completion$));
112
+ // return a new Observable that emits the result of the combined stream and handles the eventual errors of the invocation of the Chat method
113
+ return new Observable(observer => {
114
+ // Subscribe to combined stream
115
+ combined$.subscribe({
116
+ next: (value) => observer.next(value),
117
+ error: (err) => observer.error(err)
118
+ });
119
+ // Invoke the Chat method and handle errors
120
+ context.getHubConnection().invoke('Chat', data)
121
+ .then(() => {
122
+ const chatHistory = context.getChatHistory();
123
+ // If a valid assistant message with (display: true) was found, update it
124
+ // and it should always the case
125
+ const index = this.assistantUtils.firstVisibleAssistantMessageIndex(chatHistory);
126
+ if (index !== -1) {
127
+ chatHistory[index].additionalProperties.$progress = this._progress;
128
+ chatHistory[index].additionalProperties.$attachment = this._attachments;
129
+ chatHistory[index].additionalProperties.$debug = this._debugMessages;
130
+ context.setChatHistory(chatHistory);
131
+ }
132
+ // Save/update the chat if savedChat enabled
133
+ if (assistantConfig.savedChatSettings.enabled && context.getChatHistory().some((msg) => msg.additionalProperties?.isUserInput === true)) {
134
+ context.isExistingSavedChat(context.getChatId()).pipe(take(1), switchMap((exists) => exists
135
+ ? context.updateSavedChat(context.getChatId(), undefined, context.getChatHistory())
136
+ : context.addSavedChat(context.getChatId(), context.getChatHistory()).pipe(tap(() => context.listSavedChat()))), finalize(() => context.setStreamingStatus(false))).subscribe({
137
+ next: () => { },
138
+ error: (error) => observer.error(error),
139
+ complete: () => observer.complete()
140
+ });
141
+ }
142
+ else {
143
+ context.setStreamingStatus(false);
144
+ observer.complete();
145
+ }
146
+ })
147
+ .catch(error => {
148
+ console.error('Error invoking Chat:', error);
149
+ context.setStreamingStatus(false);
150
+ // Emit the error to the newly created observable
151
+ observer.error(error);
152
+ // Return a resolved promise to handle the error and prevent unhandled promise rejection
153
+ return Promise.resolve();
154
+ })
155
+ .finally(() => {
156
+ // This block concerns ONLY the completion of the "Chat" method invocation.
157
+ // This means the completion of the combined$ stream.
158
+ // It does not take into account the completion of the entire fetch method (the observable returned by fetch) and which depends on the completion of the save chat action if enabled
159
+ this._response = []; // Clear the _response
160
+ this._actionMap.clear(); // Clear the _actionMap
161
+ this._progress = undefined; // Clear the _progress
162
+ this._attachments = []; // Clear the _attachments
163
+ this._debugMessages = []; // Clear the _debugMessages
164
+ this._executionTime = ""; // Clear the _executionTime
165
+ this._executionTimeMilliseconds = undefined; // Clear the _executionTimeMilliseconds
166
+ completion$.next(); // Emit a signal to complete the observables
167
+ completion$.complete(); // Complete the subject
168
+ });
169
+ });
170
+ }
171
+ initMessageHandlers() {
172
+ this.ensureInitialized();
173
+ const context = this.context;
174
+ this.addMessageHandler("Error", {
175
+ handler: (error) => {
176
+ if (error.indexOf('SavedChatList') !== -1) {
177
+ context.setSavedChatsErrorStatus(true);
178
+ }
179
+ console.error(error);
180
+ this.notificationsService.error(error);
181
+ },
182
+ isGlobalHandler: true
183
+ });
184
+ this.addMessageHandler("Quota", {
185
+ handler: (message) => {
186
+ try {
187
+ context.updateQuota(message.quota);
188
+ }
189
+ catch (error) {
190
+ console.error(error);
191
+ }
192
+ },
193
+ isGlobalHandler: true
194
+ });
195
+ this.addMessageHandler("Debug", { handler: () => { }, isGlobalHandler: true });
196
+ this.addMessageHandler("ActionStart", {
197
+ handler: (action) => this._actionMap.set(action.guid, action),
198
+ isGlobalHandler: false
199
+ });
200
+ this.addMessageHandler("ActionResult", {
201
+ handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
202
+ isGlobalHandler: false
203
+ });
204
+ this.addMessageHandler("ActionStop", {
205
+ handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
206
+ isGlobalHandler: false
207
+ });
208
+ this.addMessageHandler("ContextMessage", {
209
+ handler: (message) => { this._attachments.push(message.additionalProperties); },
210
+ isGlobalHandler: false
211
+ });
212
+ this.addMessageHandler("Message", {
213
+ handler: (message) => {
214
+ this._response.at(-1).content += message.delta ?? "";
215
+ this._response.at(-1).additionalProperties.messageId = message.messageId;
216
+ },
217
+ isGlobalHandler: false
218
+ });
219
+ this.addMessageHandler("History", {
220
+ handler: (history) => {
221
+ // The ChatHistory is updated: it is the current copy concatenated with the new items ONLY (it can have multiple messages: the context messages + the response message)
222
+ // This is mandatory to not lose the previous updates of the chatHistory when the assistant is streaming multiple message steps
223
+ const currentChatHistory = (context.getChatHistory() || []);
224
+ const newHistory = [...currentChatHistory, ...(history.history.slice(currentChatHistory.length))];
225
+ context.setChatHistory(newHistory);
226
+ // Emit the updated chat usage metrics
227
+ const lastMessage = newHistory.at(-1);
228
+ if (lastMessage?.additionalProperties.usageMetrics) {
229
+ context.updateChatUsageMetrics(lastMessage.additionalProperties.usageMetrics);
230
+ }
231
+ this._executionTime = history.executionTime;
232
+ this._executionTimeMilliseconds = history.executionTimeMilliseconds;
233
+ },
234
+ isGlobalHandler: false
235
+ });
236
+ this.addMessageHandler("SuggestedActions", {
237
+ handler: (message) => {
238
+ // Since after the "History" and "MessageBreak" that this event is caught,
239
+ // $suggestedAction needs to be updated directly to the last visible "assistant" message in the _response and the chatHistory
240
+ this._response.at(-1).additionalProperties.$suggestedAction = (this._response.at(-1).additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
241
+ const chatHistory = context.getChatHistory();
242
+ const index = this.assistantUtils.lastVisibleAssistantMessageIndex(chatHistory);
243
+ if (index !== -1) {
244
+ chatHistory[index].additionalProperties.$suggestedAction = (chatHistory[index].additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
245
+ context.setChatHistory(chatHistory);
246
+ }
247
+ },
248
+ isGlobalHandler: false
249
+ });
250
+ this.addMessageHandler("DebugDisplay", {
251
+ handler: (message) => this._debugMessages = this._debugMessages.concat(message),
252
+ isGlobalHandler: false
253
+ });
254
+ this.addMessageHandler("MessageBreak", {
255
+ handler: () => {
256
+ // Systematically happens right after the "History" event
257
+ // This is the moment when the assistant message is fully streamed
258
+ const assistantConfig = context.getAssistantConfig();
259
+ const chatHistory = context.getChatHistory();
260
+ if (!assistantConfig || !chatHistory || !chatHistory.length)
261
+ return;
262
+ const lastChatMessage = chatHistory.at(-1);
263
+ const details = {
264
+ 'duration': this._executionTimeMilliseconds !== undefined ? this._executionTimeMilliseconds : this._executionTime,
265
+ 'role': lastChatMessage.role,
266
+ 'rank': chatHistory.length,
267
+ 'message-id': lastChatMessage.additionalProperties.messageId,
268
+ 'generation-tokencount': lastChatMessage.additionalProperties.usageMetrics?.completionTokenCount,
269
+ 'prompt-tokencount': lastChatMessage.additionalProperties.usageMetrics?.promptTokenCount,
270
+ 'attachments': JSON.stringify(this._attachments.map(({ recordId, contextId, parts, type }) => ({
271
+ recordId,
272
+ contextId,
273
+ parts: parts.map(({ partId, text }) => {
274
+ if (!!assistantConfig.auditSettings?.logContent)
275
+ return { partId, text };
276
+ return { partId };
277
+ }),
278
+ type
279
+ })))
280
+ };
281
+ if (!!assistantConfig.auditSettings?.logContent) {
282
+ if (typeof lastChatMessage.content === 'string') {
283
+ details['text'] = lastChatMessage.content;
284
+ }
285
+ else if (Array.isArray(lastChatMessage.content)) {
286
+ details['text'] = lastChatMessage.content.find((msg) => msg.type === "text").text;
287
+ }
288
+ }
289
+ context.generateAuditEvent('ast-message.message', details);
290
+ // Push a new assistant message to the _response array ONLY if the content of the last message is not empty
291
+ if (this._response.at(-1).content !== "") {
292
+ this._response.push({ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid() } });
293
+ }
294
+ },
295
+ isGlobalHandler: false
296
+ });
297
+ }
298
+ overrideMessageHandlers(_messageHandlers) {
299
+ this.ensureInitialized();
300
+ // Clear the already registered global chat handlers before merging the new ones
301
+ this._messageHandlers.forEach((eventHandler, eventName) => {
302
+ if (eventHandler.isGlobalHandler) {
303
+ this.unsubscribeMessageHandler(eventName);
304
+ }
305
+ });
306
+ // Merge the new event handlers with the existing ones
307
+ this._messageHandlers = new Map([...this._messageHandlers, ..._messageHandlers]);
308
+ // Register the global handlers among the merged map
309
+ this._messageHandlers.forEach((eventHandler, eventName) => {
310
+ if (eventHandler.isGlobalHandler) {
311
+ this.registerMessageHandler(eventName, eventHandler);
312
+ }
313
+ });
314
+ }
315
+ addMessageHandler(eventName, eventHandler) {
316
+ this.ensureInitialized();
317
+ this._messageHandlers.set(eventName, eventHandler);
318
+ if (eventHandler.isGlobalHandler) {
319
+ this.registerMessageHandler(eventName, eventHandler);
320
+ }
321
+ }
322
+ registerMessageHandler(eventName, eventHandler) {
323
+ this.ensureInitialized();
324
+ const connection = this.context.getHubConnection();
325
+ if (!connection) {
326
+ console.log("No connection found to register the listener" + eventName);
327
+ return;
328
+ }
329
+ connection.on(eventName, (data) => {
330
+ eventHandler.handler(data);
331
+ });
332
+ }
333
+ removeMessageHandler(eventName) {
334
+ this.ensureInitialized();
335
+ this._messageHandlers.delete(eventName);
336
+ this.unsubscribeMessageHandler(eventName);
337
+ }
338
+ unsubscribeMessageHandler(eventName) {
339
+ this.ensureInitialized();
340
+ const connection = this.context.getHubConnection();
341
+ connection?.off(eventName);
342
+ }
343
+ stopGeneration() {
344
+ this.ensureInitialized();
345
+ const context = this.context;
346
+ const connection = context.getHubConnection();
347
+ // Start stopping generation by invoking the CancelTasks method
348
+ context.setStoppingGenerationStatus(true);
349
+ // Create a Subject to hold the result of the CancelTasks method
350
+ const stopGenerationSubject$ = new Subject();
351
+ connection.on('CancelTasks', (res) => {
352
+ // When the generation is stopped before streaming any VISIBLE assistant message, this means that $progress, $attachment and $debug properties will be lost.
353
+ // However, the "ContextMessage" frames will be persisted in the chatHistory and the assistant may reference them in the next generation.
354
+ // This leads to the problem of referencing undisplayed attachments in the next generation.
355
+ // To solve this problem, we need to persist $progress, $attachment and $debug properties by adding a new assistant message with empty content and these properties.
356
+ // In the other hand, this leads to the problem of having many empty assistant messages in the chat history, if a stop generation happens multiple times in a row with no content generated yet.
357
+ // To solve this problem mentioned in the ticket ES-27024, we need to allow such operation ONLY if the last assistant message's content in the chat history is not empty.
358
+ const chatHistory = context.getChatHistory();
359
+ const isLastChatHistoryMessageAssistantContentEmpty = chatHistory?.length
360
+ && chatHistory.at(-1)?.role === "assistant"
361
+ && (chatHistory.at(-1)?.content === ""
362
+ ||
363
+ chatHistory.at(-1)?.content?.find((msg) => msg.type === "text")?.text === "");
364
+ if (this._response && this._response.length === 1 && this._response[0].content === "" && !isLastChatHistoryMessageAssistantContentEmpty) {
365
+ const newChatHistory = chatHistory ? [...chatHistory] : [];
366
+ newChatHistory.push({ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid(), $progress: this._progress, $attachment: this._attachments, $debug: this._debugMessages } });
367
+ context.setChatHistory(newChatHistory);
368
+ }
369
+ // Emit the result of the CancelTasks method
370
+ stopGenerationSubject$.next(!!res);
371
+ // Complete the subject
372
+ stopGenerationSubject$.complete();
373
+ // Complete stopping generation
374
+ context.setStoppingGenerationStatus(false);
375
+ });
376
+ // Invoke the CancelTasks method and handle errors
377
+ connection.invoke('CancelTasks')
378
+ .catch(error => {
379
+ console.error('Error invoking CancelTasks:', error);
380
+ stopGenerationSubject$.error(new Error(error));
381
+ context.setStoppingGenerationStatus(false);
382
+ return Promise.resolve();
383
+ });
384
+ return stopGenerationSubject$.asObservable();
385
+ }
386
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
387
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService }); }
388
+ }
389
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService, decorators: [{
390
+ type: Injectable
391
+ }] });
392
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzaXN0YW50LXdzLWZyYW1lcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvc2VydmljZXMvYXNzaXN0YW50LXdzLWZyYW1lcy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM3RSxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFMUYsT0FBTyxFQUFFLElBQUksRUFBUyxNQUFNLGlCQUFpQixDQUFDO0FBMkI5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUF5QjlELE1BQU0sT0FBTyx3QkFBd0I7SUFEckM7UUFJVSxlQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hDLGNBQVMsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNyQyxtQkFBYyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN4Qyx5QkFBb0IsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUVwRCxxQkFBZ0IsR0FBcUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUUvRCxlQUFVLEdB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QyxHQUFHLENBQUMsQ0FBQztZQUNuQyx1QkFBdUI7WUFDdkIsc0JBQXNCLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEMsK0JBQStCO1lBQy9CLE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILGtEQUFrRDtRQUNsRCxVQUFVLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQzthQUM3QixLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLDZCQUE2QixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELHNCQUFzQixDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUVMLE9BQU8sc0JBQXNCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDL0MsQ0FBQzsrR0FuYVUsd0JBQXdCO21IQUF4Qix3QkFBd0I7OzRGQUF4Qix3QkFBd0I7a0JBRHBDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh1YkNvbm5lY3Rpb24gfSBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xuaW1wb3J0IHsgVHJhbnNsb2NvU2VydmljZSB9IGZyb20gJ0Bqc3ZlcnNlL3RyYW5zbG9jbyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBmcm9tRXZlbnQsIG1lcmdlLCBvZiwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBtZXJnZU1hcCwgdGFrZVVudGlsLCB0YXAsIHRha2UsIHN3aXRjaE1hcCwgZmluYWxpemUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGd1aWQsIFF1ZXJ5IH0gZnJvbSBcIkBzaW5lcXVhL2F0b21pY1wiO1xuXG5pbXBvcnQge1xuICBBY3Rpb25NZXNzYWdlLFxuICBBY3Rpb25SZXN1bHRFdmVudCxcbiAgQWN0aW9uU3RhcnRFdmVudCxcbiAgQWN0aW9uU3RvcEV2ZW50LFxuICBDaGF0Q29uZmlnLFxuICBDaGF0Q29udGV4dEF0dGFjaG1lbnQsXG4gIENoYXRNZXNzYWdlLFxuICBDaGF0UGF5bG9hZCxcbiAgQ2hhdFByb2dyZXNzLFxuICBDaGF0UmVzcG9uc2UsXG4gIENoYXRVc2FnZU1ldHJpY3MsXG4gIENvbnRleHRNZXNzYWdlRXZlbnQsXG4gIERlYnVnTWVzc2FnZSxcbiAgRGVidWdNZXNzYWdlRXZlbnQsXG4gIEVycm9yRXZlbnQsXG4gIEhpc3RvcnlFdmVudCxcbiAgTWVzc2FnZUhhbmRsZXIsXG4gIE1lc3NhZ2VFdmVudCxcbiAgUXVvdGEsXG4gIFF1b3RhRXZlbnQsXG4gIFNhdmVkQ2hhdFJlc3BvbnNlLFxuICBTdWdnZXN0ZWRBY3Rpb25zRXZlbnRcbn0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBBcHBTZXJ2aWNlIH0gZnJvbSAnLi9hcHAuc2VydmljZSc7XG5pbXBvcnQgeyBBc3Npc3RhbnRVdGlscyB9IGZyb20gJy4uL3V0aWxzL3V0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uc1NlcnZpY2UgfSBmcm9tICcuL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IE1lc3NhZ2VDb250ZW50LCBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tICcuLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2lzdGFudFdzRnJhbWVzQ29udGV4dCB7XG4gIGdldEFzc2lzdGFudENvbmZpZzogKCkgPT4gQ2hhdENvbmZpZyB8IHVuZGVmaW5lZDtcbiAgZ2V0Q2hhdEluc3RhbmNlSWQ6ICgpID0+IHN0cmluZztcbiAgZ2V0Q2hhdElkOiAoKSA9PiBzdHJpbmc7XG4gIGdldEh1YkNvbm5lY3Rpb246ICgpID0+IEh1YkNvbm5lY3Rpb24gfCB1bmRlZmluZWQ7XG4gIGdldENoYXRIaXN0b3J5OiAoKSA9PiBDaGF0TWVzc2FnZVtdIHwgdW5kZWZpbmVkO1xuXG4gIHNldFN0cmVhbWluZ1N0YXR1czogKGlzU3RyZWFtaW5nOiBib29sZWFuKSA9PiB2b2lkO1xuICBzZXRDaGF0SGlzdG9yeTogKGhpc3Rvcnk6IENoYXRNZXNzYWdlW10gfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gIHNldFN0b3BwaW5nR2VuZXJhdGlvblN0YXR1czogKGlzU3RvcHBpbmc6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldFNhdmVkQ2hhdHNFcnJvclN0YXR1czogKGhhc0Vycm9yOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIHVwZGF0ZVF1b3RhOiAocXVvdGE6IFF1b3RhLCBwcm9wYWdhdGVFcnJvcj86IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUNoYXRVc2FnZU1ldHJpY3M6IChtZXRyaWNzOiBDaGF0VXNhZ2VNZXRyaWNzKSA9PiB2b2lkO1xuICBnZW5lcmF0ZUF1ZGl0RXZlbnQ6ICh0eXBlOiBzdHJpbmcsIGRldGFpbHM6IFJlY29yZDxzdHJpbmcsIGFueT4sIGlkPzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBhZGRTYXZlZENoYXQ6IChpZDogc3RyaW5nLCBtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSkgPT4gT2JzZXJ2YWJsZTxTYXZlZENoYXRSZXNwb25zZT47XG4gIHVwZGF0ZVNhdmVkQ2hhdDogKGlkOiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIG1lc3NhZ2VzPzogQ2hhdE1lc3NhZ2VbXSkgPT4gT2JzZXJ2YWJsZTxTYXZlZENoYXRSZXNwb25zZT47XG4gIGxpc3RTYXZlZENoYXQ6ICgpID0+IHZvaWQ7XG4gIGlzRXhpc3RpbmdTYXZlZENoYXQ6IChpZDogc3RyaW5nKSA9PiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQXNzaXN0YW50V3NGcmFtZXNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBjb250ZXh0OiBBc3Npc3RhbnRXc0ZyYW1lc0NvbnRleHQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBhcHBTZXJ2aWNlID0gaW5qZWN0KEFwcFNlcnZpY2UpO1xuICBwcml2YXRlIHRyYW5zbG9jbyA9IGluamVjdChUcmFuc2xvY29TZXJ2aWNlKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRVdGlscyA9IGluamVjdChBc3Npc3RhbnRVdGlscyk7XG4gIHByaXZhdGUgbm90aWZpY2F0aW9uc1NlcnZpY2UgPSBpbmplY3QoTm90aWZpY2F0aW9uc1NlcnZpY2UpO1xuXG4gIHByaXZhdGUgX21lc3NhZ2VIYW5kbGVyczogTWFwPHN0cmluZywgTWVzc2FnZUhhbmRsZXI8YW55Pj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgX3Jlc3BvbnNlOiBDaGF0TWVzc2FnZVtdO1xuICBwcml2YXRlIF9hY3Rpb25NYXAgPSBuZXcgTWFwPHN0cmluZywgQWN0aW9uTWVzc2FnZT4oKTtcbiAgcHJpdmF0ZSBfcHJvZ3Jlc3M6IENoYXRQcm9ncmVzc1tdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBwcml2YXRlIF9leGVjdXRpb25UaW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHM/OiBudW1iZXI7XG4gIHByaXZhdGUgX2F0dGFjaG1lbnRzOiBDaGF0Q29udGV4dEF0dGFjaG1lbnRbXSA9IFtdO1xuICBwcml2YXRlIF9kZWJ1Z01lc3NhZ2VzOiBEZWJ1Z01lc3NhZ2VbXSA9IFtdO1xuXG4gIHB1YmxpYyBpbml0KGNvbnRleHQ6IEFzc2lzdGFudFdzRnJhbWVzQ29udGV4dCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbnRleHQpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzaXN0YW50V3NGcmFtZXNTZXJ2aWNlIGFscmVhZHkgaW5pdGlhbGl6ZWQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Fzc2lzdGFudFdzRnJhbWVzU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LicpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSwgcXVlcnk6IFF1ZXJ5KTogT2JzZXJ2YWJsZTxDaGF0UmVzcG9uc2U+IHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dCE7XG4gICAgY29uc3QgYXNzaXN0YW50Q29uZmlnID0gY29udGV4dC5nZXRBc3Npc3RhbnRDb25maWcoKSE7XG5cbiAgICAgLy8gU3RhcnQgc3RyZWFtaW5nIGJ5IGludm9raW5nIHRoZSBDaGF0IG1ldGhvZFxuICAgIGNvbnRleHQuc2V0U3RyZWFtaW5nU3RhdHVzKHRydWUpO1xuXG4gICAgLy8gUHJlcGFyZSB0aGUgcGF5bG9hZCB0byBzZW5kIHRvIHRoZSBDaGF0IG1ldGhvZFxuICAgIGNvbnN0IGRhdGE6IENoYXRQYXlsb2FkID0ge1xuICAgICAgaGlzdG9yeTogbWVzc2FnZXMsXG4gICAgICBmdW5jdGlvbnM6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkKS5tYXAoZnVuYyA9PiBmdW5jLm5hbWUpLFxuICAgICAgZGVidWc6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLmRlYnVnLFxuICAgICAgc2VydmljZVNldHRpbmdzOiB7XG4gICAgICAgIHNlcnZpY2VfaWQ6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLnNlcnZpY2VfaWQsXG4gICAgICAgIG1vZGVsX2lkOiBhc3Npc3RhbnRDb25maWcuZGVmYXVsdFZhbHVlcy5tb2RlbF9pZCxcbiAgICAgICAgdG9wX3A6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLnRvcF9wLFxuICAgICAgICB0ZW1wZXJhdHVyZTogYXNzaXN0YW50Q29uZmlnLmRlZmF1bHRWYWx1ZXMudGVtcGVyYXR1cmUsXG4gICAgICAgIG1heF90b2tlbnM6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLm1heF90b2tlbnMsXG4gICAgICAgIC4uLmFzc2lzdGFudENvbmZpZy5hZGRpdGlvbmFsU2VydmljZVNldHRpbmdzXG4gICAgICB9LFxuICAgICAgYXBwUXVlcnk6IHtcbiAgICAgICAgYXBwOiB0aGlzLmFwcFNlcnZpY2UuYXBwTmFtZSxcbiAgICAgICAgcXVlcnlcbiAgICAgIH0sXG4gICAgICBpbnN0YW5jZUlkOiBjb250ZXh0LmdldENoYXRJbnN0YW5jZUlkKCksXG4gICAgICBjaGF0SWQ6IGNvbnRleHQuZ2V0Q2hhdElkKCksXG4gICAgICBnZW5lcmljQ2hhdEVycm9yTWVzc2FnZTogYXNzaXN0YW50Q29uZmlnLmdsb2JhbFNldHRpbmdzLmdlbmVyaWNDaGF0RXJyb3JNZXNzYWdlID8gdGhpcy50cmFuc2xvY28udHJhbnNsYXRlKGFzc2lzdGFudENvbmZpZy5nbG9iYWxTZXR0aW5ncy5nZW5lcmljQ2hhdEVycm9yTWVzc2FnZSkgOiBcIlwiXG4gICAgfTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIHJlc3BvbnNlIHdpdGggYW4gZW1wdHkgYXNzaXN0YW50IG1lc3NhZ2VcbiAgICAvLyBoZXJlIGRpc3BsYXk6IHRydWUgaXMgbmVlZGVkIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gc2hvdyB0aGUgcHJvZ3Jlc3NcbiAgICAvLyBoZXJlIG1lc3NhZ2VJZCBpcyBuZWVkZWQgYnV0IGl0IGlzIHRlbXBvcmFyeSBhbmQgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgY29ycmVjdCBtZXNzYWdlSWQgZ2VuZXJhdGVkIGJ5IHRoZSBhc3Npc3RhbnQgd2hlbiB0aGUgbWVzc2FnZSBzdGFydHMgc3RyZWFtaW5nXG4gICAgdGhpcy5fcmVzcG9uc2UgPSBbeyByb2xlOiBcImFzc2lzdGFudFwiLCBjb250ZW50OiBcIlwiLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH1dO1xuXG4gICAgLy8gQ3JlYXRlIGEgU3ViamVjdCB0byBzaWduYWwgY29tcGxldGlvblxuICAgIGNvbnN0IGNvbXBsZXRpb24kID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8vIENyZWF0ZSBvYnNlcnZhYmxlcyBmb3IgZWFjaCBub24tZ2xvYmFsIGhhbmRsZXIgaW4gdGhlIF9tZXNzYWdlSGFuZGxlcnMgbWFwIChkZWZhdWx0IGFuZCBldmVudHVhbCBjdXN0b20gb25lcykgb25jZSBpdCBpcyB0cmlnZ2VyZWQgYnkgdGhlIGh1YiBjb25uZWN0aW9uXG4gICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSBBcnJheVxuICAgICAgLmZyb20odGhpcy5fbWVzc2FnZUhhbmRsZXJzLmVudHJpZXMoKSlcbiAgICAgIC5maWx0ZXIoKFtldmVudE5hbWUsIGV2ZW50SGFuZGxlcl0pID0+ICFldmVudEhhbmRsZXIuaXNHbG9iYWxIYW5kbGVyKVxuICAgICAgLm1hcCgoW2V2ZW50TmFtZSwgZXZlbnRIYW5kbGVyXSkgPT4gZnJvbUV2ZW50PGFueT4oY29udGV4dC5nZXRIdWJDb25uZWN0aW9uKCkhLCBldmVudE5hbWUpLnBpcGUoXG4gICAgICAgICAgbWVyZ2VNYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBXcmFwIHRoZSBoYW5kbGVyIGluIGEgdHJ5LWNhdGNoIGJsb2NrIHRvIHByZXZlbnQgdGhlIGVudGlyZSBzdHJlYW0gZnJvbSBmYWlsaW5nIGlmIGFuIGVycm9yIG9jY3VycyBpbiBhIHNpbmdsZSBoYW5kbGVyXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyBFeGVjdXRlIHRoZSBoYW5kbGVyIGFuZCBlbWl0IHRoZSByZXN1bHRcbiAgICAgICAgICAgICAgLy8gTkI6IGhlcmUgd2UgY291bGQgdXNlIFtldmVudEhhbmRsZXIuaGFuZGxlcihldmVudCldIHdoaWNoIGJlaGluZCB0aGUgc2NlbmVzIG1lcmdlTWFwIGludGVycHJldHMgdGhpcyBhcnJheSBhcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggb25lIGl0ZW0sIHdoaWNoIGl0IHRoZW4gZW1pdHNcbiAgICAgICAgICAgICAgcmV0dXJuIG9mKGV2ZW50SGFuZGxlci5oYW5kbGVyKGV2ZW50KSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06YCwgZXJyb3IpO1xuICAgICAgICAgICAgICAvLyBVc2UgdGhyb3dFcnJvciB0byBwcm9wYWdhdGUgdGhlIGVycm9yIGRvd25zdHJlYW1cbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06ICR7ZXJyb3J9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICkpO1xuXG4gICAgLy8gVGhlbiBtZXJnZSB0aGVtIGludG8gYSBzaW5nbGUgb2JzZXJ2YWJsZSBpbiBvcmRlciB0byBzaW11bGF0ZSB0aGUgc3RyZWFtaW5nIGJlaGF2aW9yXG4gICAgY29uc3QgY29tYmluZWQkID0gbWVyZ2UoLi4ub2JzZXJ2YWJsZXMpLnBpcGUoXG4gICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAvLyBEZWZpbmUgJHByb2dyZXNzIGZyb20gdGhlIF9hY3Rpb25NYXBcbiAgICAgICAgY29uc3QgYWN0aW9ucyA9IEFycmF5LmZyb20odGhpcy5fYWN0aW9uTWFwLnZhbHVlcygpKTtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSBhY3Rpb25zLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhY3Rpb25zLm1hcCgoYSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGEuZGlzcGxheU5hbWUgPz8gXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogYS5kaXNwbGF5VmFsdWUgPz8gXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZTogYS5leGVjdXRpb25UaW1lICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWU6IGEuZXhlY3V0aW9uVGltZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBBbHdheXMgdXBkYXRlIE9OTFkgdGhlIGZpcnN0IGFzc2lzdGFudCBtZXNzYWdlIG9mIHRoZSBfcmVzcG9uc2Ugd2l0aCB0aGUgbmV3ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1Z1xuICAgICAgICAvLyBBc3N1bWluZyB0aGF0IHRoZSBmaXJzdCBhc3Npc3RhbnQgbWVzc2FnZSBpcyBhbHdheXMgdmlzaWJsZSBzaW5jZSB0aGUgaHViIGRvZXMgbm90IHNlbmQgaGlkZGVuIG1lc3NhZ2VzIGJ5IGRlc2lnblxuICAgICAgICAvLyBTbyBldmVuIGlmIHRoZSBmaXJzdCBhc3Npc3RhbnQgbWVzc2FnZSBpcyBoaWRkZW4gKGRpc3BsYXk6IGZhbHNlKSwgdGhlIF9yZXNwb25zZVswXSB3aWxsIGFuZCBzaG91bGQgY29udGFpbiA6XG4gICAgICAgIC8vICAtICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1Z1xuICAgICAgICAvLyAgLSB0aGUgY29udGVudCBvZiB0aGUgZmlyc3QgdmlzaWJsZSBhc3Npc3RhbnQgbWVzc2FnZSBpbiB0aGUgd29ya2Zsb3dcbiAgICAgICAgLy8gVGhpcyBpcyBtYW5kYXRvcnkgaW4gb3JkZXIgdG8gbWF0Y2ggdGhlIGJlaGF2aW9yIG9mIGNvbnNlY3V0aXZlIG1lc3NhZ2VzIGFuZCBtYWludGFpbiBjb25zaXN0ZW5jeSB3aXRoIHRoZSBjaGF0SGlzdG9yeVxuICAgICAgICBpZighIXRoaXMuX3Byb2dyZXNzIHx8IHRoaXMuX2F0dGFjaG1lbnRzLmxlbmd0aCA+IDAgfHwgdGhpcy5fZGVidWdNZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VbMF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzID0gdGhpcy5fcHJvZ3Jlc3M7XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VbMF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgPSB0aGlzLl9hdHRhY2htZW50cztcbiAgICAgICAgICB0aGlzLl9yZXNwb25zZVswXS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGVidWcgPSB0aGlzLl9kZWJ1Z01lc3NhZ2VzO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiB0aGUgcmVzdWx0XG4gICAgICAgIHJldHVybiB7IGhpc3Rvcnk6IFsuLi5tZXNzYWdlcywgLi4udGhpcy5fcmVzcG9uc2VdLCBleGVjdXRpb25UaW1lOiB0aGlzLl9leGVjdXRpb25UaW1lLCBleGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzOiB0aGlzLl9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIH07XG4gICAgICB9KSxcbiAgICAgIC8vIENvbXBsZXRlIHRoZSBvYnNlcnZhYmxlIHdoZW4gY29tcGxldGlvbiQgZW1pdHNcbiAgICAgIHRha2VVbnRpbChjb21wbGV0aW9uJCksXG4gICAgKTtcblxuICAgIC8vIHJldHVybiBhIG5ldyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgdGhlIHJlc3VsdCBvZiB0aGUgY29tYmluZWQgc3RyZWFtIGFuZCBoYW5kbGVzIHRoZSBldmVudHVhbCBlcnJvcnMgb2YgdGhlIGludm9jYXRpb24gb2YgdGhlIENoYXQgbWV0aG9kXG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgIC8vIFN1YnNjcmliZSB0byBjb21iaW5lZCBzdHJlYW1cbiAgICAgIGNvbWJpbmVkJC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAodmFsdWUpID0+IG9ic2VydmVyLm5leHQodmFsdWUpLFxuICAgICAgICBlcnJvcjogKGVycikgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEludm9rZSB0aGUgQ2hhdCBtZXRob2QgYW5kIGhhbmRsZSBlcnJvcnNcbiAgICAgIGNvbnRleHQuZ2V0SHViQ29ubmVjdGlvbigpIS5pbnZva2UoJ0NoYXQnLCBkYXRhKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hhdEhpc3RvcnkgPSBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhO1xuICAgICAgICAgIC8vIElmIGEgdmFsaWQgYXNzaXN0YW50IG1lc3NhZ2Ugd2l0aCAoZGlzcGxheTogdHJ1ZSkgd2FzIGZvdW5kLCB1cGRhdGUgaXRcbiAgICAgICAgICAvLyBhbmQgaXQgc2hvdWxkIGFsd2F5cyB0aGUgY2FzZVxuICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5maXJzdFZpc2libGVBc3Npc3RhbnRNZXNzYWdlSW5kZXgoY2hhdEhpc3RvcnkpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNoYXRIaXN0b3J5W2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgPSB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgICAgIGNoYXRIaXN0b3J5W2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kYXR0YWNobWVudCA9IHRoaXMuX2F0dGFjaG1lbnRzO1xuICAgICAgICAgICAgY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkZWJ1ZyA9IHRoaXMuX2RlYnVnTWVzc2FnZXM7XG4gICAgICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KGNoYXRIaXN0b3J5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTYXZlL3VwZGF0ZSB0aGUgY2hhdCBpZiBzYXZlZENoYXQgZW5hYmxlZFxuICAgICAgICAgIGlmIChhc3Npc3RhbnRDb25maWcuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCAmJiBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhLnNvbWUoKG1zZykgPT4gbXNnLmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy5pc1VzZXJJbnB1dCA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgICAgIGNvbnRleHQuaXNFeGlzdGluZ1NhdmVkQ2hhdChjb250ZXh0LmdldENoYXRJZCgpKS5waXBlKFxuICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICBzd2l0Y2hNYXAoKGV4aXN0cykgPT5cbiAgICAgICAgICAgICAgICBleGlzdHNcbiAgICAgICAgICAgICAgICAgID8gY29udGV4dC51cGRhdGVTYXZlZENoYXQoY29udGV4dC5nZXRDaGF0SWQoKSwgdW5kZWZpbmVkLCBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhKVxuICAgICAgICAgICAgICAgICAgOiBjb250ZXh0LmFkZFNhdmVkQ2hhdChjb250ZXh0LmdldENoYXRJZCgpLCBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIHRhcCgoKSA9PiBjb250ZXh0Lmxpc3RTYXZlZENoYXQoKSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiBjb250ZXh0LnNldFN0cmVhbWluZ1N0YXR1cyhmYWxzZSkpXG4gICAgICAgICAgICApLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgIG5leHQ6ICgpID0+IHt9LFxuICAgICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiBvYnNlcnZlci5lcnJvcihlcnJvciksXG4gICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5zZXRTdHJlYW1pbmdTdGF0dXMoZmFsc2UpO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgQ2hhdDonLCBlcnJvcik7XG4gICAgICAgICAgY29udGV4dC5zZXRTdHJlYW1pbmdTdGF0dXMoZmFsc2UpO1xuICAgICAgICAgIC8vIEVtaXQgdGhlIGVycm9yIHRvIHRoZSBuZXdseSBjcmVhdGVkIG9ic2VydmFibGVcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgIC8vIFRoaXMgYmxvY2sgY29uY2VybnMgT05MWSB0aGUgY29tcGxldGlvbiBvZiB0aGUgXCJDaGF0XCIgbWV0aG9kIGludm9jYXRpb24uXG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGUgY29tcGxldGlvbiBvZiB0aGUgY29tYmluZWQkIHN0cmVhbS5cbiAgICAgICAgICAvLyBJdCBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCB0aGUgY29tcGxldGlvbiBvZiB0aGUgZW50aXJlIGZldGNoIG1ldGhvZCAodGhlIG9ic2VydmFibGUgcmV0dXJuZWQgYnkgZmV0Y2gpIGFuZCB3aGljaCBkZXBlbmRzIG9uIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBzYXZlIGNoYXQgYWN0aW9uIGlmIGVuYWJsZWRcbiAgICAgICAgICB0aGlzLl9yZXNwb25zZSA9IFtdOyAvLyBDbGVhciB0aGUgX3Jlc3BvbnNlXG4gICAgICAgICAgdGhpcy5fYWN0aW9uTWFwLmNsZWFyKCk7IC8vIENsZWFyIHRoZSBfYWN0aW9uTWFwXG4gICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSB1bmRlZmluZWQ7IC8vIENsZWFyIHRoZSBfcHJvZ3Jlc3NcbiAgICAgICAgICB0aGlzLl9hdHRhY2htZW50cyA9IFtdOyAvLyBDbGVhciB0aGUgX2F0dGFjaG1lbnRzXG4gICAgICAgICAgdGhpcy5fZGVidWdNZXNzYWdlcyA9IFtdOyAvLyBDbGVhciB0aGUgX2RlYnVnTWVzc2FnZXNcbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lID0gXCJcIjsgLy8gQ2xlYXIgdGhlIF9leGVjdXRpb25UaW1lXG4gICAgICAgICAgdGhpcy5fZXhlY3V0aW9uVGltZU1pbGxpc2Vjb25kcyA9IHVuZGVmaW5lZDsgLy8gQ2xlYXIgdGhlIF9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzXG4gICAgICAgICAgY29tcGxldGlvbiQubmV4dCgpOyAvLyBFbWl0IGEgc2lnbmFsIHRvIGNvbXBsZXRlIHRoZSBvYnNlcnZhYmxlc1xuICAgICAgICAgIGNvbXBsZXRpb24kLmNvbXBsZXRlKCk7IC8vIENvbXBsZXRlIHRoZSBzdWJqZWN0XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGluaXRNZXNzYWdlSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQhO1xuXG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkVycm9yXCIsIHtcbiAgICAgICAgaGFuZGxlcjogKGVycm9yOiBFcnJvckV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yLmluZGV4T2YoJ1NhdmVkQ2hhdExpc3QnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc2V0U2F2ZWRDaGF0c0Vycm9yU3RhdHVzKHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiB0cnVlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiUXVvdGFcIiwge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogUXVvdGFFdmVudCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb250ZXh0LnVwZGF0ZVF1b3RhKG1lc3NhZ2UucXVvdGEpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogdHJ1ZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkRlYnVnXCIsIHsgaGFuZGxlcjogKCkgPT4ge30sIGlzR2xvYmFsSGFuZGxlcjogdHJ1ZSB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiQWN0aW9uU3RhcnRcIiwge1xuICAgICAgaGFuZGxlcjogKGFjdGlvbjogQWN0aW9uU3RhcnRFdmVudCkgPT4gdGhpcy5fYWN0aW9uTWFwLnNldChhY3Rpb24uZ3VpZCwgYWN0aW9uKSxcbiAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiQWN0aW9uUmVzdWx0XCIsIHtcbiAgICAgIGhhbmRsZXI6IChhY3Rpb246IEFjdGlvblJlc3VsdEV2ZW50KSA9PiB0aGlzLl9hY3Rpb25NYXAuc2V0KGFjdGlvbi5ndWlkLCB7IC4uLnRoaXMuX2FjdGlvbk1hcC5nZXQoYWN0aW9uLmd1aWQpLCAuLi5hY3Rpb24gfSksXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkFjdGlvblN0b3BcIiwge1xuICAgICAgaGFuZGxlcjogKGFjdGlvbjogQWN0aW9uU3RvcEV2ZW50KSA9PiB0aGlzLl9hY3Rpb25NYXAuc2V0KGFjdGlvbi5ndWlkLCB7IC4uLnRoaXMuX2FjdGlvbk1hcC5nZXQoYWN0aW9uLmd1aWQpLCAuLi5hY3Rpb24gfSksXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkNvbnRleHRNZXNzYWdlXCIsIHtcbiAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBDb250ZXh0TWVzc2FnZUV2ZW50KSA9PiB7IHRoaXMuX2F0dGFjaG1lbnRzLnB1c2gobWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcyk7IH0sXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIk1lc3NhZ2VcIiwge1xuICAgICAgaGFuZGxlcjogKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkgPT4ge1xuICAgICAgICB0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmNvbnRlbnQgKz0gbWVzc2FnZS5kZWx0YSA/PyBcIlwiO1xuICAgICAgICB0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCA9IG1lc3NhZ2UubWVzc2FnZUlkO1xuICAgICAgfSxcbiAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiSGlzdG9yeVwiLCB7XG4gICAgICAgIGhhbmRsZXI6IChoaXN0b3J5OiBIaXN0b3J5RXZlbnQpID0+IHtcbiAgICAgICAgICAvLyBUaGUgQ2hhdEhpc3RvcnkgaXMgdXBkYXRlZDogaXQgaXMgdGhlIGN1cnJlbnQgY29weSBjb25jYXRlbmF0ZWQgd2l0aCB0aGUgbmV3IGl0ZW1zIE9OTFkgKGl0IGNhbiBoYXZlIG11bHRpcGxlIG1lc3NhZ2VzOiB0aGUgY29udGV4dCBtZXNzYWdlcyArIHRoZSByZXNwb25zZSBtZXNzYWdlKVxuICAgICAgICAgIC8vIFRoaXMgaXMgbWFuZGF0b3J5IHRvIG5vdCBsb3NlIHRoZSBwcmV2aW91cyB1cGRhdGVzIG9mIHRoZSBjaGF0SGlzdG9yeSB3aGVuIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG11bHRpcGxlIG1lc3NhZ2Ugc3RlcHNcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q2hhdEhpc3RvcnkgPSAoY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpIHx8IFtdKSBhcyBDaGF0TWVzc2FnZVtdO1xuICAgICAgICAgIGNvbnN0IG5ld0hpc3RvcnkgPSBbLi4uY3VycmVudENoYXRIaXN0b3J5LCAuLi4oaGlzdG9yeS5oaXN0b3J5LnNsaWNlKGN1cnJlbnRDaGF0SGlzdG9yeS5sZW5ndGgpKV0gYXMgQ2hhdE1lc3NhZ2VbXTtcbiAgICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KG5ld0hpc3RvcnkpO1xuXG4gICAgICAgICAgLy8gRW1pdCB0aGUgdXBkYXRlZCBjaGF0IHVzYWdlIG1ldHJpY3NcbiAgICAgICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG5ld0hpc3RvcnkuYXQoLTEpO1xuICAgICAgICAgIGlmIChsYXN0TWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKSB7XG4gICAgICAgICAgICBjb250ZXh0LnVwZGF0ZUNoYXRVc2FnZU1ldHJpY3MobGFzdE1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fZXhlY3V0aW9uVGltZSA9IGhpc3RvcnkuZXhlY3V0aW9uVGltZTtcbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzID0gaGlzdG9yeS5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzO1xuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiU3VnZ2VzdGVkQWN0aW9uc1wiLCB7XG4gICAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBTdWdnZXN0ZWRBY3Rpb25zRXZlbnQpID0+IHtcbiAgICAgICAgICAvLyBTaW5jZSBhZnRlciB0aGUgXCJIaXN0b3J5XCIgYW5kIFwiTWVzc2FnZUJyZWFrXCIgdGhhdCB0aGlzIGV2ZW50IGlzIGNhdWdodCxcbiAgICAgICAgICAvLyAkc3VnZ2VzdGVkQWN0aW9uIG5lZWRzIHRvIGJlIHVwZGF0ZWQgZGlyZWN0bHkgdG8gdGhlIGxhc3QgdmlzaWJsZSBcImFzc2lzdGFudFwiIG1lc3NhZ2UgaW4gdGhlIF9yZXNwb25zZSBhbmQgdGhlIGNoYXRIaXN0b3J5XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2UuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uID0gKHRoaXMuX3Jlc3BvbnNlLmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMuJHN1Z2dlc3RlZEFjdGlvbiB8fCBbXSkuY29uY2F0KG1lc3NhZ2Uuc3VnZ2VzdGVkQWN0aW9ucyk7XG4gICAgICAgICAgY29uc3QgY2hhdEhpc3RvcnkgPSBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhO1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5sYXN0VmlzaWJsZUFzc2lzdGFudE1lc3NhZ2VJbmRleChjaGF0SGlzdG9yeSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gPSAoY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gfHwgW10pLmNvbmNhdChtZXNzYWdlLnN1Z2dlc3RlZEFjdGlvbnMpO1xuICAgICAgICAgICAgY29udGV4dC5zZXRDaGF0SGlzdG9yeShjaGF0SGlzdG9yeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiRGVidWdEaXNwbGF5XCIsIHtcbiAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBEZWJ1Z01lc3NhZ2VFdmVudCkgPT4gdGhpcy5fZGVidWdNZXNzYWdlcyA9IHRoaXMuX2RlYnVnTWVzc2FnZXMuY29uY2F0KG1lc3NhZ2UpLFxuICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgIH0pO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXCJNZXNzYWdlQnJlYWtcIiwge1xuICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgLy8gU3lzdGVtYXRpY2FsbHkgaGFwcGVucyByaWdodCBhZnRlciB0aGUgXCJIaXN0b3J5XCIgZXZlbnRcbiAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBtb21lbnQgd2hlbiB0aGUgYXNzaXN0YW50IG1lc3NhZ2UgaXMgZnVsbHkgc3RyZWFtZWRcbiAgICAgICAgICBjb25zdCBhc3Npc3RhbnRDb25maWcgPSBjb250ZXh0LmdldEFzc2lzdGFudENvbmZpZygpO1xuICAgICAgICAgIGNvbnN0IGNoYXRIaXN0b3J5ID0gY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpO1xuICAgICAgICAgIGlmICghYXNzaXN0YW50Q29uZmlnIHx8ICFjaGF0SGlzdG9yeSB8fCAhY2hhdEhpc3RvcnkubGVuZ3RoKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBsYXN0Q2hhdE1lc3NhZ2UgPSBjaGF0SGlzdG9yeS5hdCgtMSkhO1xuXG4gICAgICAgICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICAgICAgICdkdXJhdGlvbic6IHRoaXMuX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCA/IHRoaXMuX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHMgOiB0aGlzLl9leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgJ3JvbGUnOiBsYXN0Q2hhdE1lc3NhZ2Uucm9sZSxcbiAgICAgICAgICAgICdyYW5rJzogY2hhdEhpc3RvcnkubGVuZ3RoLFxuICAgICAgICAgICAgJ21lc3NhZ2UtaWQnOiBsYXN0Q2hhdE1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkLFxuICAgICAgICAgICAgJ2dlbmVyYXRpb24tdG9rZW5jb3VudCc6IGxhc3RDaGF0TWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy51c2FnZU1ldHJpY3M/LmNvbXBsZXRpb25Ub2tlbkNvdW50LFxuICAgICAgICAgICAgJ3Byb21wdC10b2tlbmNvdW50JzogbGFzdENoYXRNZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcz8ucHJvbXB0VG9rZW5Db3VudCxcbiAgICAgICAgICAgICdhdHRhY2htZW50cyc6IEpTT04uc3RyaW5naWZ5KHRoaXMuX2F0dGFjaG1lbnRzLm1hcCgoeyByZWNvcmRJZCwgY29udGV4dElkLCBwYXJ0cywgdHlwZSB9KSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0czogcGFydHMubWFwKCh7IHBhcnRJZCwgdGV4dCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFhc3Npc3RhbnRDb25maWcuYXVkaXRTZXR0aW5ncz8ubG9nQ29udGVudCkgcmV0dXJuIHsgcGFydElkLCB0ZXh0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBwYXJ0SWQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pKSlcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmICghIWFzc2lzdGFudENvbmZpZy5hdWRpdFNldHRpbmdzPy5sb2dDb250ZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxhc3RDaGF0TWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAoZGV0YWlscyBhcyBhbnkpWyd0ZXh0J10gPSBsYXN0Q2hhdE1lc3NhZ2UuY29udGVudDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShsYXN0Q2hhdE1lc3NhZ2UuY29udGVudCkpIHtcbiAgICAgICAgICAgICAgKGRldGFpbHMgYXMgYW55KVsndGV4dCddID0gKGxhc3RDaGF0TWVzc2FnZS5jb250ZW50LmZpbmQoKG1zZykgPT4gbXNnLnR5cGUgPT09IFwidGV4dFwiKSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGV4dC5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCBkZXRhaWxzKTtcbiAgICAgICAgICAvLyBQdXNoIGEgbmV3IGFzc2lzdGFudCBtZXNzYWdlIHRvIHRoZSBfcmVzcG9uc2UgYXJyYXkgT05MWSBpZiB0aGUgY29udGVudCBvZiB0aGUgbGFzdCBtZXNzYWdlIGlzIG5vdCBlbXB0eVxuICAgICAgICAgIGlmICh0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmNvbnRlbnQgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlLnB1c2goe3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCl9fSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZU1lc3NhZ2VIYW5kbGVyczxUPihfbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxUPj4pOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgLy8gQ2xlYXIgdGhlIGFscmVhZHkgcmVnaXN0ZXJlZCBnbG9iYWwgY2hhdCBoYW5kbGVycyBiZWZvcmUgbWVyZ2luZyB0aGUgbmV3IG9uZXNcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlcnMuZm9yRWFjaCgoZXZlbnRIYW5kbGVyLCBldmVudE5hbWUpID0+IHtcbiAgICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gTWVyZ2UgdGhlIG5ldyBldmVudCBoYW5kbGVycyB3aXRoIHRoZSBleGlzdGluZyBvbmVzXG4gICAgdGhpcy5fbWVzc2FnZUhhbmRsZXJzID0gbmV3IE1hcChbLi4udGhpcy5fbWVzc2FnZUhhbmRsZXJzLCAuLi5fbWVzc2FnZUhhbmRsZXJzXSk7XG4gICAgLy8gUmVnaXN0ZXIgdGhlIGdsb2JhbCBoYW5kbGVycyBhbW9uZyB0aGUgbWVyZ2VkIG1hcFxuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5mb3JFYWNoKChldmVudEhhbmRsZXIsIGV2ZW50TmFtZSkgPT4ge1xuICAgICAgaWYoZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcikge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZE1lc3NhZ2VIYW5kbGVyPFQ+KGV2ZW50TmFtZTogc3RyaW5nLCBldmVudEhhbmRsZXI6IE1lc3NhZ2VIYW5kbGVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI8VD4oZXZlbnROYW1lOiBzdHJpbmcsIGV2ZW50SGFuZGxlcjogTWVzc2FnZUhhbmRsZXI8VD4pOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuY29udGV4dCEuZ2V0SHViQ29ubmVjdGlvbigpO1xuICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgY29uc29sZS5sb2coXCJObyBjb25uZWN0aW9uIGZvdW5kIHRvIHJlZ2lzdGVyIHRoZSBsaXN0ZW5lclwiICsgZXZlbnROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29ubmVjdGlvbi5vbihldmVudE5hbWUsIChkYXRhOiBUKSA9PiB7XG4gICAgICBldmVudEhhbmRsZXIuaGFuZGxlcihkYXRhKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgdGhpcy51bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZSk7XG4gIH1cblxuICBwdWJsaWMgdW5zdWJzY3JpYmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb250ZXh0IS5nZXRIdWJDb25uZWN0aW9uKCk7XG4gICAgY29ubmVjdGlvbj8ub2ZmKGV2ZW50TmFtZSk7XG4gIH1cblxuICBwdWJsaWMgc3RvcEdlbmVyYXRpb24oKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQhO1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb250ZXh0LmdldEh1YkNvbm5lY3Rpb24oKSE7XG5cbiAgICAgLy8gU3RhcnQgc3RvcHBpbmcgZ2VuZXJhdGlvbiBieSBpbnZva2luZyB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgY29udGV4dC5zZXRTdG9wcGluZ0dlbmVyYXRpb25TdGF0dXModHJ1ZSk7XG4gICAgLy8gQ3JlYXRlIGEgU3ViamVjdCB0byBob2xkIHRoZSByZXN1bHQgb2YgdGhlIENhbmNlbFRhc2tzIG1ldGhvZFxuICAgIGNvbnN0IHN0b3BHZW5lcmF0aW9uU3ViamVjdCQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgY29ubmVjdGlvbi5vbignQ2FuY2VsVGFza3MnLCAocmVzKSA9PiB7XG4gICAgICAvLyBXaGVuIHRoZSBnZW5lcmF0aW9uIGlzIHN0b3BwZWQgYmVmb3JlIHN0cmVhbWluZyBhbnkgVklTSUJMRSBhc3Npc3RhbnQgbWVzc2FnZSwgdGhpcyBtZWFucyB0aGF0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIHdpbGwgYmUgbG9zdC5cbiAgICAgIC8vIEhvd2V2ZXIsIHRoZSBcIkNvbnRleHRNZXNzYWdlXCIgZnJhbWVzIHdpbGwgYmUgcGVyc2lzdGVkIGluIHRoZSBjaGF0SGlzdG9yeSBhbmQgdGhlIGFzc2lzdGFudCBtYXkgcmVmZXJlbmNlIHRoZW0gaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRoaXMgbGVhZHMgdG8gdGhlIHByb2JsZW0gb2YgcmVmZXJlbmNpbmcgdW5kaXNwbGF5ZWQgYXR0YWNobWVudHMgaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRvIHNvbHZlIHRoaXMgcHJvYmxlbSwgd2UgbmVlZCB0byBwZXJzaXN0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIGJ5IGFkZGluZyBhIG5ldyBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIGVtcHR5IGNvbnRlbnQgYW5kIHRoZXNlIHByb3BlcnRpZXMuXG4gICAgICAvLyBJbiB0aGUgb3RoZXIgaGFuZCwgdGhpcyBsZWFkcyB0byB0aGUgcHJvYmxlbSBvZiBoYXZpbmcgbWFueSBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQgaGlzdG9yeSwgaWYgYSBzdG9wIGdlbmVyYXRpb24gaGFwcGVucyBtdWx0aXBsZSB0aW1lcyBpbiBhIHJvdyB3aXRoIG5vIGNvbnRlbnQgZ2VuZXJhdGVkIHlldC5cbiAgICAgIC8vIFRvIHNvbHZlIHRoaXMgcHJvYmxlbSBtZW50aW9uZWQgaW4gdGhlIHRpY2tldCBFUy0yNzAyNCwgd2UgbmVlZCB0byBhbGxvdyBzdWNoIG9wZXJhdGlvbiBPTkxZIGlmIHRoZSBsYXN0IGFzc2lzdGFudCBtZXNzYWdlJ3MgY29udGVudCBpbiB0aGUgY2hhdCBoaXN0b3J5IGlzIG5vdCBlbXB0eS5cbiAgICAgIGNvbnN0IGNoYXRIaXN0b3J5ID0gY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpO1xuICAgICAgY29uc3QgaXNMYXN0Q2hhdEhpc3RvcnlNZXNzYWdlQXNzaXN0YW50Q29udGVudEVtcHR5ID0gY2hhdEhpc3Rvcnk/Lmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICBjaGF0SGlzdG9yeS5hdCgtMSk/LnJvbGUgPT09IFwiYXNzaXN0YW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2hhdEhpc3RvcnkuYXQoLTEpPy5jb250ZW50ID09PSBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoY2hhdEhpc3RvcnkuYXQoLTEpPy5jb250ZW50IGFzIE1lc3NhZ2VDb250ZW50W10pPy5maW5kKChtc2cpID0+IG1zZy50eXBlID09PSBcInRleHRcIikgYXMgVGV4dE1lc3NhZ2VDb250ZW50KT8udGV4dCA9PT0gXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgIGlmICh0aGlzLl9yZXNwb25zZSAmJiB0aGlzLl9yZXNwb25zZS5sZW5ndGggPT09IDEgJiYgdGhpcy5fcmVzcG9uc2VbMF0uY29udGVudCA9PT0gXCJcIiAmJiAhaXNMYXN0Q2hhdEhpc3RvcnlNZXNzYWdlQXNzaXN0YW50Q29udGVudEVtcHR5KSB7XG4gICAgICAgIGNvbnN0IG5ld0NoYXRIaXN0b3J5ID0gY2hhdEhpc3RvcnkgPyBbLi4uY2hhdEhpc3RvcnldIDogW107XG4gICAgICAgIG5ld0NoYXRIaXN0b3J5LnB1c2goe3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCksICRwcm9ncmVzczogdGhpcy5fcHJvZ3Jlc3MsICRhdHRhY2htZW50OiB0aGlzLl9hdHRhY2htZW50cywgJGRlYnVnOiB0aGlzLl9kZWJ1Z01lc3NhZ2VzfX0pO1xuICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KG5ld0NoYXRIaXN0b3J5KTtcbiAgICAgIH1cbiAgICAgIC8vIEVtaXQgdGhlIHJlc3VsdCBvZiB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgICBzdG9wR2VuZXJhdGlvblN1YmplY3QkLm5leHQoISFyZXMpO1xuICAgICAgLy8gQ29tcGxldGUgdGhlIHN1YmplY3RcbiAgICAgIHN0b3BHZW5lcmF0aW9uU3ViamVjdCQuY29tcGxldGUoKTtcbiAgICAgIC8vIENvbXBsZXRlIHN0b3BwaW5nIGdlbmVyYXRpb25cbiAgICAgIGNvbnRleHQuc2V0U3RvcHBpbmdHZW5lcmF0aW9uU3RhdHVzKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kIGFuZCBoYW5kbGUgZXJyb3JzXG4gICAgY29ubmVjdGlvbi5pbnZva2UoJ0NhbmNlbFRhc2tzJylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIENhbmNlbFRhc2tzOicsIGVycm9yKTtcbiAgICAgICAgc3RvcEdlbmVyYXRpb25TdWJqZWN0JC5lcnJvcihuZXcgRXJyb3IoZXJyb3IgYXMgc3RyaW5nKSk7XG4gICAgICAgIGNvbnRleHQuc2V0U3RvcHBpbmdHZW5lcmF0aW9uU3RhdHVzKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gc3RvcEdlbmVyYXRpb25TdWJqZWN0JC5hc09ic2VydmFibGUoKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,109 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { HttpTransportType, LogLevel } from '@microsoft/signalr';
3
+ import { getToken } from '@sinequa/atomic';
4
+ import { AssistantUtils } from '../utils/utils.service';
5
+ import { SignalRWebService } from './signalR.web.service';
6
+ import * as i0 from "@angular/core";
7
+ export class SignalRConnectionService {
8
+ constructor() {
9
+ this.signalRWebService = inject(SignalRWebService);
10
+ this.assistantUtils = inject(AssistantUtils);
11
+ }
12
+ init(config) {
13
+ if (this.operationConfig) {
14
+ console.warn('SignalRConnectionService already initialized.');
15
+ return;
16
+ }
17
+ this.operationConfig = config;
18
+ }
19
+ ensureInitialized() {
20
+ if (!this.operationConfig) {
21
+ throw new Error('SignalRConnectionService not initialized. Call init() first.');
22
+ }
23
+ }
24
+ _getLogLevel() {
25
+ this.ensureInitialized();
26
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
27
+ switch (assistantConfig?.connectionSettings.signalRLogLevel) {
28
+ case "Critical": return LogLevel.Critical;
29
+ case "Debug": return LogLevel.Debug;
30
+ case "Error": return LogLevel.Error;
31
+ case "Information": return LogLevel.Information;
32
+ case "None": return LogLevel.None;
33
+ case "Trace": return LogLevel.Trace;
34
+ case "Warning": return LogLevel.Warning;
35
+ default: return LogLevel.None;
36
+ }
37
+ }
38
+ _getTransports() {
39
+ this.ensureInitialized();
40
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
41
+ switch (assistantConfig?.connectionSettings.signalRTransport) {
42
+ case "WebSockets": return HttpTransportType.WebSockets;
43
+ case "ServerSentEvents": return HttpTransportType.ServerSentEvents;
44
+ case "LongPolling": return HttpTransportType.LongPolling;
45
+ default: return HttpTransportType.None;
46
+ }
47
+ }
48
+ getDefaultOptions() {
49
+ this.ensureInitialized();
50
+ let headers = {
51
+ "sinequa-force-camel-case": "true",
52
+ "x-language": this.assistantUtils.getCurrentLocaleName(),
53
+ "ui-language": this.assistantUtils.getCurrentLocaleName(),
54
+ };
55
+ const token = getToken();
56
+ if (token) {
57
+ headers = { ...headers, "sinequa-csrf-token": token };
58
+ }
59
+ return {
60
+ transport: this._getTransports(),
61
+ withCredentials: true,
62
+ headers,
63
+ skipNegotiation: false,
64
+ accessTokenFactory: () => token || ""
65
+ };
66
+ }
67
+ buildConnection(options) {
68
+ this.ensureInitialized();
69
+ return new Promise((resolve, reject) => {
70
+ const wsRequestUrl = this.operationConfig.getWsRequestUrl();
71
+ if (!wsRequestUrl) {
72
+ reject(new Error("No endpoint provided to connect the websocket to"));
73
+ return;
74
+ }
75
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
76
+ const logLevel = this._getLogLevel();
77
+ const defaultOpts = this.getDefaultOptions();
78
+ if (assistantConfig?.connectionSettings.signalRSkipNegotiation === true) {
79
+ options = { ...options, skipNegotiation: true };
80
+ }
81
+ const connection = this.signalRWebService.buildConnection(wsRequestUrl, { ...defaultOpts, ...options }, logLevel, true);
82
+ const signalRServerTimeoutInMilliseconds = assistantConfig?.connectionSettings.signalRServerTimeoutInMilliseconds;
83
+ if (signalRServerTimeoutInMilliseconds && connection) {
84
+ connection.serverTimeoutInMilliseconds = signalRServerTimeoutInMilliseconds;
85
+ }
86
+ this.operationConfig.setHubConnection(connection);
87
+ resolve();
88
+ });
89
+ }
90
+ startConnection() {
91
+ this.ensureInitialized();
92
+ const connection = this.operationConfig.getHubConnection();
93
+ return this.signalRWebService.startConnection(connection);
94
+ }
95
+ stopConnection() {
96
+ this.ensureInitialized();
97
+ const connection = this.operationConfig.getHubConnection();
98
+ return this.signalRWebService.stopConnection(connection);
99
+ }
100
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
101
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, providedIn: 'root' }); }
102
+ }
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, decorators: [{
104
+ type: Injectable,
105
+ args: [{
106
+ providedIn: 'root'
107
+ }]
108
+ }] });
109
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsUi1jb25uZWN0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9zZXJ2aWNlcy9zaWduYWxSLWNvbm5lY3Rpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWlCLGlCQUFpQixFQUFFLFFBQVEsRUFBa0IsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxpQkFBaUIsRUFBcUIsTUFBTSx1QkFBdUIsQ0FBQzs7QUFhN0UsTUFBTSxPQUFPLHdCQUF3QjtJQUhyQztRQUtVLHNCQUFpQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzlDLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0tBbUdqRDtJQWpHUSxJQUFJLENBQUMsTUFBd0M7UUFDbEQsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1lBQzlELE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUM7SUFDaEMsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztRQUNsRixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsTUFBTSxlQUFlLEdBQUcsSUFBSSxD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QU07OzRGQUVQLHdCQUF3QjtrQkFIcEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh1YkNvbm5lY3Rpb24sIEh0dHBUcmFuc3BvcnRUeXBlLCBMb2dMZXZlbCwgTWVzc2FnZUhlYWRlcnMgfSBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xuaW1wb3J0IHsgZ2V0VG9rZW4gfSBmcm9tICdAc2luZXF1YS9hdG9taWMnO1xuaW1wb3J0IHsgQXNzaXN0YW50VXRpbHMgfSBmcm9tICcuLi91dGlscy91dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hbFJXZWJTZXJ2aWNlLCBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4vc2lnbmFsUi53ZWIuc2VydmljZSc7XG5pbXBvcnQgeyBDaGF0Q29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25hbFJDb25uZWN0aW9uT3BlcmF0aW9uQ29uZmlnIHtcbiAgZ2V0V3NSZXF1ZXN0VXJsOiAoKSA9PiBzdHJpbmc7XG4gIGdldEFzc2lzdGFudENvbmZpZ1ZhbHVlOiAoKSA9PiBDaGF0Q29uZmlnIHwgdW5kZWZpbmVkO1xuICBnZXRIdWJDb25uZWN0aW9uOiAoKSA9PiBIdWJDb25uZWN0aW9uIHwgdW5kZWZpbmVkO1xuICBzZXRIdWJDb25uZWN0aW9uOiAoY29ubmVjdGlvbjogSHViQ29ubmVjdGlvbiB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU2lnbmFsUkNvbm5lY3Rpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBvcGVyYXRpb25Db25maWc6IFNpZ25hbFJDb25uZWN0aW9uT3BlcmF0aW9uQ29uZmlnIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHNpZ25hbFJXZWJTZXJ2aWNlID0gaW5qZWN0KFNpZ25hbFJXZWJTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRVdGlscyA9IGluamVjdChBc3Npc3RhbnRVdGlscyk7XG5cbiAgcHVibGljIGluaXQoY29uZmlnOiBTaWduYWxSQ29ubmVjdGlvbk9wZXJhdGlvbkNvbmZpZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wZXJhdGlvbkNvbmZpZykge1xuICAgICAgY29uc29sZS53YXJuKCdTaWduYWxSQ29ubmVjdGlvblNlcnZpY2UgYWxyZWFkeSBpbml0aWFsaXplZC4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5vcGVyYXRpb25Db25maWcgPSBjb25maWc7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5vcGVyYXRpb25Db25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2lnbmFsUkNvbm5lY3Rpb25TZXJ2aWNlIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0TG9nTGV2ZWwoKTogTG9nTGV2ZWwge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBhc3Npc3RhbnRDb25maWcgPSB0aGlzLm9wZXJhdGlvbkNvbmZpZyEuZ2V0QXNzaXN0YW50Q29uZmlnVmFsdWUoKTtcbiAgICBzd2l0Y2ggKGFzc2lzdGFudENvbmZpZz8uY29ubmVjdGlvblNldHRpbmdzLnNpZ25hbFJMb2dMZXZlbCkge1xuICAgICAgY2FzZSBcIkNyaXRpY2FsXCI6IHJldHVybiBMb2dMZXZlbC5Dcml0aWNhbDtcbiAgICAgIGNhc2UgXCJEZWJ1Z1wiOiByZXR1cm4gTG9nTGV2ZWwuRGVidWc7XG4gICAgICBjYXNlIFwiRXJyb3JcIjogcmV0dXJuIExvZ0xldmVsLkVycm9yO1xuICAgICAgY2FzZSBcIkluZm9ybWF0aW9uXCI6IHJldHVybiBMb2dMZXZlbC5JbmZvcm1hdGlvbjtcbiAgICAgIGNhc2UgXCJOb25lXCI6IHJldHVybiBMb2dMZXZlbC5Ob25lO1xuICAgICAgY2FzZSBcIlRyYWNlXCI6IHJldHVybiBMb2dMZXZlbC5UcmFjZTtcbiAgICAgIGNhc2UgXCJXYXJuaW5nXCI6IHJldHVybiBMb2dMZXZlbC5XYXJuaW5nO1xuICAgICAgZGVmYXVsdDogcmV0dXJuIExvZ0xldmVsLk5vbmU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VHJhbnNwb3J0cygpOiBIdHRwVHJhbnNwb3J0VHlwZSB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGFzc2lzdGFudENvbmZpZyA9IHRoaXMub3BlcmF0aW9uQ29uZmlnIS5nZXRBc3Npc3RhbnRDb25maWdWYWx1ZSgpO1xuICAgIHN3aXRjaCAoYXNzaXN0YW50Q29uZmlnPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUlRyYW5zcG9ydCkge1xuICAgICAgY2FzZSBcIldlYlNvY2tldHNcIjogcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLldlYlNvY2tldHM7XG4gICAgICBjYXNlIFwiU2VydmVyU2VudEV2ZW50c1wiOiByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cztcbiAgICAgIGNhc2UgXCJMb25nUG9sbGluZ1wiOiByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuTG9uZ1BvbGxpbmc7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuTm9uZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldERlZmF1bHRPcHRpb25zKCk6IENvbm5lY3Rpb25PcHRpb25zIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgbGV0IGhlYWRlcnM6IE1lc3NhZ2VIZWFkZXJzID0ge1xuICAgICAgXCJzaW5lcXVhLWZvcmNlLWNhbWVsLWNhc2VcIjogXCJ0cnVlXCIsXG4gICAgICBcIngtbGFuZ3VhZ2VcIjogdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRDdXJyZW50TG9jYWxlTmFtZSgpLFxuICAgICAgXCJ1aS1sYW5ndWFnZVwiOiB0aGlzLmFzc2lzdGFudFV0aWxzLmdldEN1cnJlbnRMb2NhbGVOYW1lKCksXG4gICAgfTtcbiAgICBjb25zdCB0b2tlbiA9IGdldFRva2VuKCk7XG4gICAgaWYgKHRva2VuKSB7XG4gICAgICBoZWFkZXJzID0geyAuLi5oZWFkZXJzLCBcInNpbmVxdWEtY3NyZi10b2tlblwiOiB0b2tlbiB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc3BvcnQ6IHRoaXMuX2dldFRyYW5zcG9ydHMoKSxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogdHJ1ZSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBza2lwTmVnb3RpYXRpb246IGZhbHNlLFxuICAgICAgYWNjZXNzVG9rZW5GYWN0b3J5OiAoKSA9PiB0b2tlbiB8fCBcIlwiXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBidWlsZENvbm5lY3Rpb24ob3B0aW9ucz86IENvbm5lY3Rpb25PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB3c1JlcXVlc3RVcmwgPSB0aGlzLm9wZXJhdGlvbkNvbmZpZyEuZ2V0V3NSZXF1ZXN0VXJsKCk7XG4gICAgICBpZiAoIXdzUmVxdWVzdFVybCkge1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiTm8gZW5kcG9pbnQgcHJvdmlkZWQgdG8gY29ubmVjdCB0aGUgd2Vic29ja2V0IHRvXCIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgYXNzaXN0YW50Q29uZmlnID0gdGhpcy5vcGVyYXRpb25Db25maWchLmdldEFzc2lzdGFudENvbmZpZ1ZhbHVlKCk7XG4gICAgICBjb25zdCBsb2dMZXZlbCA9IHRoaXMuX2dldExvZ0xldmVsKCk7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0cyA9IHRoaXMuZ2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICAgIGlmIChhc3Npc3RhbnRDb25maWc/LmNvbm5lY3Rpb25TZXR0aW5ncy5zaWduYWxSU2tpcE5lZ290aWF0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7Li4ub3B0aW9ucywgc2tpcE5lZ290aWF0aW9uOiB0cnVlfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnNpZ25hbFJXZWJTZXJ2aWNlLmJ1aWxkQ29ubmVjdGlvbih3c1JlcXVlc3RVcmwsIHsgLi4uZGVmYXVsdE9wdHMsIC4uLm9wdGlvbnMgfSwgbG9nTGV2ZWwsIHRydWUpO1xuXG4gICAgICBjb25zdCBzaWduYWxSU2VydmVyVGltZW91dEluTWlsbGlzZWNvbmRzID0gYXNzaXN0YW50Q29uZmlnPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUlNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICAgIGlmIChzaWduYWxSU2VydmVyVGltZW91dEluTWlsbGlzZWNvbmRzICYmIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgY29ubmVjdGlvbi5zZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBzaWduYWxSU2VydmVyVGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgICAgfVxuICAgICAgdGhpcy5vcGVyYXRpb25Db25maWchLnNldEh1YkNvbm5lY3Rpb24oY29ubmVjdGlvbik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhcnRDb25uZWN0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5vcGVyYXRpb25Db25maWchLmdldEh1YkNvbm5lY3Rpb24oKTtcbiAgICByZXR1cm4gdGhpcy5zaWduYWxSV2ViU2VydmljZS5zdGFydENvbm5lY3Rpb24oY29ubmVjdGlvbik7XG4gIH1cblxuICBwdWJsaWMgc3RvcENvbm5lY3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLm9wZXJhdGlvbkNvbmZpZyEuZ2V0SHViQ29ubmVjdGlvbigpO1xuICAgIHJldHVybiB0aGlzLnNpZ25hbFJXZWJTZXJ2aWNlLnN0b3BDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuICB9XG59XG4iXX0=