@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinequa/assistant",
3
- "version": "3.9.2",
3
+ "version": "3.9.3",
4
4
  "author": "Sinequa",
5
5
  "peerDependencies": {
6
6
  "@fortawesome/fontawesome-free": "^5.13.0",
@@ -1,31 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { Query } from "@sinequa/atomic";
3
- import { ChatService } from './chat.service';
4
- import { ChatMessage, ChatResponse, DeleteSavedChatResponse, GllmFunction, GllmModelDescription, SavedChatHistory, SavedChatResponse } from './types';
5
- import * as i0 from "@angular/core";
6
- export declare class RestChatService extends ChatService {
7
- constructor();
8
- /**
9
- * Initialize the chat process after the login is complete.
10
- * It listens for the 'login-complete' event, initializes necessary URL, and performs parallel requests for models, functions and quota data.
11
- * @returns An Observable<boolean> indicating the success of the initialization process.
12
- */
13
- init(): Observable<boolean>;
14
- /**
15
- * Define the GLLM plugin to use for the http requests
16
- * It can be overridden by the app config
17
- */
18
- getRequestsUrl(): void;
19
- overrideUser(): void;
20
- listModels(): Observable<GllmModelDescription[] | undefined>;
21
- listFunctions(): Observable<GllmFunction[] | undefined>;
22
- fetch(messages: ChatMessage[], query: Query): Observable<ChatResponse>;
23
- stopGeneration(): Observable<any>;
24
- listSavedChat(): void;
25
- addSavedChat(messages: ChatMessage[]): Observable<SavedChatResponse>;
26
- getSavedChat(id: string): Observable<SavedChatHistory | undefined>;
27
- updateSavedChat(id: string, name?: string, messages?: ChatMessage[]): Observable<SavedChatResponse>;
28
- deleteSavedChat(ids: string[]): Observable<DeleteSavedChatResponse>;
29
- static ɵfac: i0.ɵɵFactoryDeclaration<RestChatService, never>;
30
- static ɵprov: i0.ɵɵInjectableDeclaration<RestChatService>;
31
- }
@@ -1,102 +0,0 @@
1
- import { HubConnection } from "@microsoft/signalr";
2
- import { Observable } from "rxjs";
3
- import { Query } from "@sinequa/atomic";
4
- import { ChatService } from "./chat.service";
5
- import { ConnectionOptions, SignalRWebService } from "./services/signalR.web.service";
6
- import { ChatMessage, ChatResponse, DeleteSavedChatResponse, GllmFunction, GllmModelDescription, MessageHandler, SavedChatHistory, SavedChatResponse } from "./types";
7
- import * as i0 from "@angular/core";
8
- export declare class WebSocketChatService extends ChatService {
9
- connection: HubConnection | undefined;
10
- private _messageHandlers;
11
- private _response;
12
- private _actionMap;
13
- private _progress;
14
- private _executionTime;
15
- private _executionTimeMilliseconds?;
16
- private _attachments;
17
- private _debugMessages;
18
- signalRService: SignalRWebService;
19
- constructor();
20
- /**
21
- * Initialize the assistant process.
22
- * It includes building and starting a connection, executing parallel requests for models and functions, and handling errors during the process.
23
- * ⚠️ This method MUST be called ONLY if the user is loggedIn and once when the assistant is initialized.
24
- *
25
- * @returns An Observable<boolean> indicating the success of the initialization process.
26
- */
27
- init(): Observable<boolean>;
28
- /**
29
- * Define the assistant endpoint to use for the websocket requests
30
- * It can be overridden by the app config
31
- */
32
- getRequestsUrl(): void;
33
- overrideUser(): void;
34
- listModels(): Observable<GllmModelDescription[] | undefined>;
35
- listFunctions(): Observable<GllmFunction[] | undefined>;
36
- fetch(messages: ChatMessage[], query: Query): Observable<ChatResponse>;
37
- stopGeneration(): Observable<boolean>;
38
- listSavedChat(): void;
39
- getSavedChat(id: string): Observable<SavedChatHistory | undefined>;
40
- addSavedChat(messages: ChatMessage[]): Observable<SavedChatResponse>;
41
- updateSavedChat(id: string, name?: string, messages?: ChatMessage[]): Observable<SavedChatResponse>;
42
- deleteSavedChat(ids: string[]): Observable<DeleteSavedChatResponse>;
43
- /**
44
- * Initialize out-of-the-box handlers
45
- * It is a placeholder for non-streaming scenarios, where you invoke a specific hub method, and the server responds with frame message(s)
46
- */
47
- initMessageHandlers(): void;
48
- /**
49
- * Override and register the entire _messageHandlers map by merging the provided map with the default one
50
- * @param _messageHandlers
51
- */
52
- overrideMessageHandlers<T>(_messageHandlers: Map<string, MessageHandler<T>>): void;
53
- /**
54
- * Add a listener for a specific event.
55
- * If a listener for this same event already exists, it will be overridden.
56
- * If the listener has "isGlobalHandler" set to true, it will be registered to the hub connection.
57
- * @param eventName Name of the event to register a listener for
58
- * @param eventHandler The handler to be called when the event is received
59
- */
60
- addMessageHandler<T>(eventName: string, eventHandler: MessageHandler<T>): void;
61
- /**
62
- * Dynamically register a listener for a specific event.
63
- * If a listener for this event already exists, it will be overridden.
64
- * @param eventName Name of the event to register a listener for
65
- * @param eventHandler The handler to be called when the event is received
66
- */
67
- protected registerMessageHandler<T>(eventName: string, eventHandler: MessageHandler<T>): void;
68
- /**
69
- * Remove a listener for a specific event from the _messageHandlers map and unsubscribe from receiving messages for this event from the SignalR hub.
70
- * @param eventName Name of the event to remove the listener for
71
- */
72
- removeMessageHandler(eventName: string): void;
73
- /**
74
- * Unsubscribe from receiving messages for a specific event from the SignalR hub.
75
- * ALL its related listeners will be removed from hub connection
76
- * This is needed to prevent accumulating old listeners when overriding the entire _messageHandlers map
77
- * @param eventName Name of the event
78
- */
79
- protected unsubscribeMessageHandler(eventName: string): void;
80
- /**
81
- * Build a connection to the signalR websocket and register default listeners to the methods defined in the server hub class
82
- * @param options The options for the connection. It overrides the default options
83
- * @param logLevel Define the log level displayed in the console
84
- * @returns Promise that resolves when the connection is built
85
- */
86
- buildConnection(options?: ConnectionOptions): Promise<void>;
87
- /**
88
- * Start the connection
89
- * @returns Promise that resolves when the connection is started
90
- */
91
- startConnection(): Promise<void>;
92
- /**
93
- * Stop the connection
94
- * @returns Promise that resolves when the connection is stopped
95
- */
96
- stopConnection(): Promise<void>;
97
- private _getTransports;
98
- private _getLogLevel;
99
- get defaultOptions(): ConnectionOptions;
100
- static ɵfac: i0.ɵɵFactoryDeclaration<WebSocketChatService, never>;
101
- static ɵprov: i0.ɵɵInjectableDeclaration<WebSocketChatService>;
102
- }
@@ -1,300 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { catchError, finalize, forkJoin, from, fromEvent, map, merge, of, shareReplay, switchMap, take, tap, throwError } from 'rxjs';
3
- import { get, isAuthenticated, post } from "@sinequa/atomic";
4
- import { ChatService } from './chat.service';
5
- import * as i0 from "@angular/core";
6
- export class RestChatService extends ChatService {
7
- constructor() {
8
- super();
9
- }
10
- /**
11
- * Initialize the chat process after the login is complete.
12
- * It listens for the 'login-complete' event, initializes necessary URL, and performs parallel requests for models, functions and quota data.
13
- * @returns An Observable<boolean> indicating the success of the initialization process.
14
- */
15
- init() {
16
- const allEvent$ = merge(fromEvent(document, 'authenticated').pipe(tap(() => console.log("authenticated"))), of(isAuthenticated()).pipe(tap(() => console.log("isAuthenticated"))));
17
- return allEvent$.pipe(tap(() => this.getRequestsUrl()),
18
- // Execute parallel requests for models and functions
19
- switchMap(() => forkJoin([
20
- this.listModels(),
21
- this.listFunctions()
22
- ])),
23
- // Map the results of parallel requests to a boolean indicating success
24
- map(([models, functions]) => {
25
- const result = !!models && !!functions;
26
- this.initProcess$.next(result);
27
- return result;
28
- }),
29
- // Any errors during the process are caught, logged, and re-thrown to propagate the error further
30
- catchError((error) => {
31
- console.error('Error occurred:', error);
32
- return throwError(() => error);
33
- }),
34
- // cache and replay the emitted value for subsequent subscribers, ensuring the initialization logic is only executed once even if there are multiple subscribers
35
- shareReplay(1));
36
- }
37
- /**
38
- * Define the GLLM plugin to use for the http requests
39
- * It can be overridden by the app config
40
- */
41
- getRequestsUrl() {
42
- if (this.assistantConfig$.value.connectionSettings.restEndpoint) {
43
- this.REQUEST_URL = this.assistantConfig$.value.connectionSettings.restEndpoint;
44
- }
45
- else {
46
- throw new Error(`The property 'restEndpoint' must be provided when attempting to use 'REST' in assistant instance`);
47
- }
48
- }
49
- overrideUser() {
50
- const error = new Error('Override user is not supported in REST');
51
- console.error(error);
52
- }
53
- listModels() {
54
- const data = {
55
- action: "listmodels",
56
- debug: this.assistantConfig$.value.defaultValues.debug.toString()
57
- };
58
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
59
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
60
- return acc;
61
- }, {}));
62
- return from(get(`plugin/${this.REQUEST_URL}`, searchParams))
63
- .pipe(map(res => res.models), tap(models => this.models = models?.filter(model => !!model.enable)), catchError((error) => {
64
- console.error('Error invoking listmodels:', error);
65
- return throwError(() => error);
66
- }));
67
- }
68
- listFunctions() {
69
- const data = {
70
- action: "listfunctions",
71
- debug: this.assistantConfig$.value.defaultValues.debug.toString()
72
- };
73
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
74
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
75
- return acc;
76
- }, {}));
77
- return from(get(`plugin/${this.REQUEST_URL}`, searchParams))
78
- .pipe(map(res => res.functions), tap((functions) => this.functions = functions?.filter(func => func.enabled && !!this.assistantConfig$.value.defaultValues.functions.find(fn => fn.name === func.functionName))), catchError((error) => {
79
- console.error('Error invoking listfunctions:', error);
80
- return throwError(() => error);
81
- }));
82
- }
83
- fetch(messages, query) {
84
- // Start streaming by invoking the Chat method
85
- this.streaming$.next(true);
86
- // Prepare the payload to send to the Chat method
87
- const data = {
88
- action: "chat",
89
- history: messages,
90
- functions: this.assistantConfig$.value.defaultValues.functions?.filter(func => func.enabled).map(func => func.name),
91
- debug: this.assistantConfig$.value.defaultValues.debug,
92
- serviceSettings: {
93
- service_id: this.assistantConfig$.value.defaultValues.service_id,
94
- model_id: this.assistantConfig$.value.defaultValues.model_id,
95
- top_p: this.assistantConfig$.value.defaultValues.top_p,
96
- temperature: this.assistantConfig$.value.defaultValues.temperature,
97
- max_tokens: this.assistantConfig$.value.defaultValues.max_tokens,
98
- ...this.assistantConfig$.value.additionalServiceSettings
99
- },
100
- appQuery: {
101
- app: this.appService.appName,
102
- query
103
- },
104
- genericChatErrorMessage: this.assistantConfig$.value.globalSettings.genericChatErrorMessage
105
- };
106
- if (this.assistantConfig$.value.savedChatSettings.enabled) {
107
- data.instanceId = this.chatInstanceId;
108
- data.savedChatId = this.savedChatId;
109
- }
110
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
111
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
112
- return acc;
113
- }, {}));
114
- // Request the Chat endpoint
115
- const paramsObject = Object.fromEntries(searchParams.entries());
116
- return from(post(`plugin/${this.REQUEST_URL}`, paramsObject))
117
- .pipe(tap((res) => this.updateQuota(res.quota, true)), map((res) => {
118
- // Define $progress from the actions property of the response
119
- let $progress;
120
- if (res.actions?.length > 0) {
121
- const actions = Object.values(res.actions.reduce((acc, item) => {
122
- acc[item.guid] = { ...(acc[item.guid] || {}), ...item };
123
- return acc;
124
- }, {}));
125
- $progress = actions.map((a) => ({
126
- title: a.displayName ?? "",
127
- content: a.displayValue ?? "",
128
- done: a.executionTime !== undefined,
129
- time: a.executionTime,
130
- }));
131
- }
132
- // Re-attach the $progress and $attachment of the last response to the last assistant's response in the chat history
133
- const response = { ...res.history.at(-1) };
134
- if ($progress)
135
- response.additionalProperties.$progress = $progress;
136
- if (res.context)
137
- response.additionalProperties.$attachment = res.context.map((ctx) => ctx.additionalProperties);
138
- if (res.suggestedActions)
139
- response.additionalProperties.$suggestedAction = res.suggestedActions;
140
- // Emit the updated chat usage metrics once the generation of the assistant response is completed
141
- if (!!response.additionalProperties.usageMetrics) {
142
- this.updateChatUsageMetrics(response.additionalProperties.usageMetrics);
143
- }
144
- // Update the chat history with the incoming history property of the res AND the processed response message
145
- this.chatHistory = res.history;
146
- this.chatHistory[this.chatHistory.length - 1] = response;
147
- // Save/update the chat if savedChat enabled
148
- if (this.assistantConfig$.value.savedChatSettings.enabled && this.chatHistory.some((msg) => msg.additionalProperties?.isUserInput === true)) {
149
- const action = !this.savedChatId ? this.addSavedChat(this.chatHistory) : this.updateSavedChat(this.savedChatId, undefined, this.chatHistory);
150
- action.pipe(take(1)).subscribe();
151
- }
152
- // Generate audit event
153
- const details = {
154
- 'duration': res.executionTimeMilliseconds || res.executionTime,
155
- 'role': response.role, // 'assistant'
156
- 'rank': this.chatHistory.length - 1,
157
- 'generation-tokencount': response.additionalProperties.usageMetrics?.completionTokenCount,
158
- 'prompt-tokencount': response.additionalProperties.usageMetrics?.promptTokenCount,
159
- 'attachments': response.additionalProperties.$attachment?.map(({ recordId, contextId, parts, type }) => ({
160
- recordId,
161
- contextId,
162
- parts: parts.map(({ partId, text }) => {
163
- if (!!this.assistantConfig$.value?.auditSettings?.logContent)
164
- return { partId, text };
165
- return { partId };
166
- }),
167
- type
168
- }))
169
- };
170
- if (!!this.assistantConfig$.value?.auditSettings?.logContent)
171
- details['text'] = response.content;
172
- this.generateAuditEvent('ast-message', details);
173
- // Return the result
174
- return { history: [...messages, response], executionTime: res.executionTime, executionTimeMilliseconds: res.executionTimeMilliseconds };
175
- }), finalize(() => this.streaming$.next(false)));
176
- }
177
- stopGeneration() {
178
- const error = new Error('Not supported in REST');
179
- console.error(error);
180
- return throwError(() => error);
181
- }
182
- listSavedChat() {
183
- if (!this.assistantConfig$.value.savedChatSettings.enabled) {
184
- return;
185
- }
186
- const data = {
187
- action: "SavedChatList",
188
- instanceId: this.chatInstanceId,
189
- debug: this.assistantConfig$.value.defaultValues.debug
190
- };
191
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
192
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
193
- return acc;
194
- }, {}));
195
- from(get(`plugin/${this.REQUEST_URL}`, searchParams))
196
- .subscribe({
197
- next: res => {
198
- this.savedChats$.next(res.savedChat);
199
- this.savedChatsError$.next(false);
200
- },
201
- error: error => {
202
- console.error('Error occurred while calling the SavedChatList API:', error.error.errorMessage);
203
- this.savedChatsError$.next(true);
204
- this.notificationsService.error('Error occurred while calling the SavedChatList API:', error.error.errorMessage);
205
- }
206
- });
207
- }
208
- addSavedChat(messages) {
209
- const data = {
210
- action: "SavedChatAdd",
211
- instanceId: this.chatInstanceId,
212
- savedChatId: this.chatId,
213
- history: messages,
214
- debug: this.assistantConfig$.value.defaultValues.debug
215
- };
216
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
217
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
218
- return acc;
219
- }, {}));
220
- // Request the Chat endpoint
221
- const paramsObject = Object.fromEntries(searchParams.entries());
222
- return from(post(`plugin/${this.REQUEST_URL}`, paramsObject))
223
- .pipe(tap(res => {
224
- this.generateAuditEvent('ast-saved-chat.add', { duration: res.executionTimeMilliseconds }, res.savedChat.id); // Generate audit event
225
- this.setSavedChatId(res.savedChat.id); // Persist the savedChatId
226
- }), catchError((error) => {
227
- console.error('Error occurred while calling the SavedChatAdd API:', error.error.errorMessage);
228
- this.notificationsService.error('Error occurred while calling the SavedChatAdd API:', error.error.errorMessage);
229
- return throwError(() => error);
230
- }));
231
- }
232
- getSavedChat(id) {
233
- const data = {
234
- action: "SavedChatGet",
235
- instanceId: this.chatInstanceId,
236
- savedChatId: id,
237
- debug: this.assistantConfig$.value.defaultValues.debug
238
- };
239
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
240
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
241
- return acc;
242
- }, {}));
243
- return from(get(`plugin/${this.REQUEST_URL}`, searchParams))
244
- .pipe(tap(res => this.generateAuditEvent('ast-saved-chat.load', { duration: res.executionTimeMilliseconds }, res.savedChat.id)), map(res => res.savedChat), catchError((error) => {
245
- console.error('Error occurred while calling the SavedChatGet API:', error.error.errorMessage);
246
- this.notificationsService.error('Error occurred while calling the SavedChatGet API:', error.error.errorMessage);
247
- return throwError(() => error);
248
- }));
249
- }
250
- updateSavedChat(id, name, messages) {
251
- const data = {
252
- action: "SavedChatUpdate",
253
- instanceId: this.chatInstanceId,
254
- savedChatId: id,
255
- debug: this.assistantConfig$.value.defaultValues.debug
256
- };
257
- if (name)
258
- data["title"] = name;
259
- if (messages)
260
- data["history"] = messages;
261
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
262
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
263
- return acc;
264
- }, {}));
265
- // Request the Chat endpoint
266
- const paramsObject = Object.fromEntries(searchParams.entries());
267
- return from(post(`plugin/${this.REQUEST_URL}`, paramsObject))
268
- .pipe(catchError((error) => {
269
- console.error('Error occurred while calling the SavedChatUpdate API:', error.error.errorMessage);
270
- this.notificationsService.error('Error occurred while calling the SavedChatUpdate API:', error.error.errorMessage);
271
- return throwError(() => error);
272
- }));
273
- }
274
- deleteSavedChat(ids) {
275
- const data = {
276
- action: "SavedChatDelete",
277
- instanceId: this.chatInstanceId,
278
- savedChatIds: ids,
279
- debug: this.assistantConfig$.value.defaultValues.debug
280
- };
281
- const searchParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
282
- acc[key] = typeof value === 'string' ? value : JSON.stringify(value);
283
- return acc;
284
- }, {}));
285
- // Request the Chat endpoint
286
- const paramsObject = Object.fromEntries(searchParams.entries());
287
- return from(post(`plugin/${this.REQUEST_URL}`, paramsObject))
288
- .pipe(catchError((error) => {
289
- console.error('Error occurred while calling the SavedChatDelete API:', error.error.errorMessage);
290
- this.notificationsService.error('Error occurred while calling the SavedChatDelete API:', error.error.errorMessage);
291
- return throwError(() => error);
292
- }));
293
- }
294
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RestChatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
295
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RestChatService }); }
296
- }
297
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RestChatService, decorators: [{
298
- type: Injectable
299
- }], ctorParameters: () => [] });
300
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1jaGF0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9yZXN0LWNoYXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbEosT0FBTyxFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFTLE1BQU0saUJBQWlCLENBQUM7QUFFcEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQUk3QyxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxXQUFXO0lBRTlDO1FBQ0UsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQUk7UUFFRixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQ3JCLFNBQVMsQ0FBQyxRQUFRLEVBQUUsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFDbEYsRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUN0RSxDQUFDO1FBRUYsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUNuQixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FB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LENBQUMsRUFBRSxFQUE0QixDQUFDLENBQUMsQ0FBQztRQUVsQyw0QkFBNEI7UUFDNUIsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUVoRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQTBCLFVBQVUsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO2FBQ25GLElBQUksQ0FDSCxVQUFVLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLHVEQUF1RCxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDakcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyx1REFBdUQsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25ILE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDTixDQUFDOytHQS9WVSxlQUFlO21IQUFmLGVBQWU7OzRGQUFmLGVBQWU7a0JBRDNCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaW5hbGl6ZSwgZm9ya0pvaW4sIGZyb20sIGZyb21FdmVudCwgbWFwLCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YsIHNoYXJlUmVwbGF5LCBzd2l0Y2hNYXAsIHRha2UsIHRhcCwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBnZXQsIGlzQXV0aGVudGljYXRlZCwgcG9zdCwgUXVlcnkgfSBmcm9tIFwiQHNpbmVxdWEvYXRvbWljXCI7XG5cbmltcG9ydCB7IENoYXRTZXJ2aWNlIH0gZnJvbSAnLi9jaGF0LnNlcnZpY2UnO1xuaW1wb3J0IHsgQWN0aW9uTWVzc2FnZSwgQ2hhdE1lc3NhZ2UsIENoYXRQYXlsb2FkLCBDaGF0UHJvZ3Jlc3MsIENoYXRSZXNwb25zZSwgRGVsZXRlU2F2ZWRDaGF0UmVzcG9uc2UsIEdsbG1GdW5jdGlvbiwgR2xsbU1vZGVsRGVzY3JpcHRpb24sIEh0dHBDaGF0UmVzcG9uc2UsIFNhdmVkQ2hhdCwgU2F2ZWRDaGF0SGlzdG9yeSwgU2F2ZWRDaGF0UmVzcG9uc2UgfSBmcm9tICcuL3R5cGVzJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlc3RDaGF0U2VydmljZSBleHRlbmRzIENoYXRTZXJ2aWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGNoYXQgcHJvY2VzcyBhZnRlciB0aGUgbG9naW4gaXMgY29tcGxldGUuXG4gICAqIEl0IGxpc3RlbnMgZm9yIHRoZSAnbG9naW4tY29tcGxldGUnIGV2ZW50LCBpbml0aWFsaXplcyBuZWNlc3NhcnkgVVJMLCBhbmQgcGVyZm9ybXMgcGFyYWxsZWwgcmVxdWVzdHMgZm9yIG1vZGVscywgZnVuY3Rpb25zIGFuZCBxdW90YSBkYXRhLlxuICAgKiBAcmV0dXJucyBBbiBPYnNlcnZhYmxlPGJvb2xlYW4+IGluZGljYXRpbmcgdGhlIHN1Y2Nlc3Mgb2YgdGhlIGluaXRpYWxpemF0aW9uIHByb2Nlc3MuXG4gICAqL1xuICBpbml0KCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuXG4gICAgY29uc3QgYWxsRXZlbnQkID0gbWVyZ2UoXG4gICAgICBmcm9tRXZlbnQoZG9jdW1lbnQsICdhdXRoZW50aWNhdGVkJykucGlwZSh0YXAoKCkgPT4gY29uc29sZS5sb2coXCJhdXRoZW50aWNhdGVkXCIpKSksXG4gICAgICBvZihpc0F1dGhlbnRpY2F0ZWQoKSkucGlwZSh0YXAoKCkgPT4gY29uc29sZS5sb2coXCJpc0F1dGhlbnRpY2F0ZWRcIikpKVxuICAgICk7XG5cbiAgICByZXR1cm4gYWxsRXZlbnQkLnBpcGUoXG4gICAgICB0YXAoKCkgPT4gdGhpcy5nZXRSZXF1ZXN0c1VybCgpKSxcbiAgICAgIC8vIEV4ZWN1dGUgcGFyYWxsZWwgcmVxdWVzdHMgZm9yIG1vZGVscyBhbmQgZnVuY3Rpb25zXG4gICAgICBzd2l0Y2hNYXAoKCkgPT5cbiAgICAgICAgZm9ya0pvaW4oW1xuICAgICAgICAgIHRoaXMubGlzdE1vZGVscygpLFxuICAgICAgICAgIHRoaXMubGlzdEZ1bmN0aW9ucygpXG4gICAgICAgIF0pXG4gICAgICApLFxuICAgICAgLy8gTWFwIHRoZSByZXN1bHRzIG9mIHBhcmFsbGVsIHJlcXVlc3RzIHRvIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHN1Y2Nlc3NcbiAgICAgIG1hcCgoW21vZGVscywgZnVuY3Rpb25zXSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSAhIW1vZGVscyAmJiAhIWZ1bmN0aW9ucztcbiAgICAgICAgdGhpcy5pbml0UHJvY2VzcyQubmV4dChyZXN1bHQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSksXG4gICAgICAvLyBBbnkgZXJyb3JzIGR1cmluZyB0aGUgcHJvY2VzcyBhcmUgY2F1Z2h0LCBsb2dnZWQsIGFuZCByZS10aHJvd24gdG8gcHJvcGFnYXRlIHRoZSBlcnJvciBmdXJ0aGVyXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cnJlZDonLCBlcnJvcik7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgIH0pLFxuICAgICAgLy8gY2FjaGUgYW5kIHJlcGxheSB0aGUgZW1pdHRlZCB2YWx1ZSBmb3Igc3Vic2VxdWVudCBzdWJzY3JpYmVycywgZW5zdXJpbmcgdGhlIGluaXRpYWxpemF0aW9uIGxvZ2ljIGlzIG9ubHkgZXhlY3V0ZWQgb25jZSBldmVuIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBzdWJzY3JpYmVyc1xuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERlZmluZSB0aGUgR0xMTSBwbHVnaW4gdG8gdXNlIGZvciB0aGUgaHR0cCByZXF1ZXN0c1xuICAgKiBJdCBjYW4gYmUgb3ZlcnJpZGRlbiBieSB0aGUgYXBwIGNvbmZpZ1xuICAgKi9cbiAgZ2V0UmVxdWVzdHNVcmwoKSB7XG4gICAgaWYgKHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLnJlc3RFbmRwb2ludCkge1xuICAgICAgdGhpcy5SRVFVRVNUX1VSTCA9IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLnJlc3RFbmRwb2ludDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgcHJvcGVydHkgJ3Jlc3RFbmRwb2ludCcgbXVzdCBiZSBwcm92aWRlZCB3aGVuIGF0dGVtcHRpbmcgdG8gdXNlICdSRVNUJyBpbiBhc3Npc3RhbnQgaW5zdGFuY2VgKTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZSBvdmVycmlkZVVzZXIoKTogdm9pZCB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoJ092ZXJyaWRlIHVzZXIgaXMgbm90IHN1cHBvcnRlZCBpbiBSRVNUJyk7XG4gICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gIH1cbiAgbGlzdE1vZGVscygpOiBPYnNlcnZhYmxlPEdsbG1Nb2RlbERlc2NyaXB0aW9uW10gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBkYXRhID0ge1xuICAgICAgYWN0aW9uOiBcImxpc3Rtb2RlbHNcIixcbiAgICAgIGRlYnVnOiB0aGlzLmFzc2lzdGFudENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWcudG9TdHJpbmcoKVxuICAgIH07XG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhPYmplY3QuZW50cmllcyhkYXRhKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2Nba2V5XSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPikpO1xuXG4gICAgcmV0dXJuIGZyb20oXG4gICAgICBnZXQ8eyBtb2RlbHM6IEdsbG1Nb2RlbERlc2NyaXB0aW9uW10gfCB1bmRlZmluZWQgfT4oYHBsdWdpbi8ke3RoaXMuUkVRVUVTVF9VUkx9YCwgc2VhcmNoUGFyYW1zKSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcy5tb2RlbHMpLFxuICAgICAgICB0YXAobW9kZWxzID0+IHRoaXMubW9kZWxzID0gbW9kZWxzPy5maWx0ZXIobW9kZWwgPT4gISFtb2RlbC5lbmFibGUpKSxcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbnZva2luZyBsaXN0bW9kZWxzOicsIGVycm9yKTtcbiAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG5cbiAgbGlzdEZ1bmN0aW9ucygpOiBPYnNlcnZhYmxlPEdsbG1GdW5jdGlvbltdIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGFjdGlvbjogXCJsaXN0ZnVuY3Rpb25zXCIsXG4gICAgICBkZWJ1ZzogdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmRlYnVnLnRvU3RyaW5nKClcbiAgICB9O1xuXG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhPYmplY3QuZW50cmllcyhkYXRhKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2Nba2V5XSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPikpO1xuXG4gICAgcmV0dXJuIGZyb20oXG4gICAgICBnZXQ8eyBmdW5jdGlvbnM6IEdsbG1GdW5jdGlvbltdIHwgdW5kZWZpbmVkIH0+KGBwbHVnaW4vJHt0aGlzLlJFUVVFU1RfVVJMfWAsIHNlYXJjaFBhcmFtcykpXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKHJlcyA9PiByZXMuZnVuY3Rpb25zKSxcbiAgICAgICAgdGFwKChmdW5jdGlvbnM6IEdsbG1GdW5jdGlvbltdIHwgdW5kZWZpbmVkKSA9PiB0aGlzLmZ1bmN0aW9ucyA9IGZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkICYmICEhdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucy5maW5kKGZuID0+IGZuLm5hbWUgPT09IGZ1bmMuZnVuY3Rpb25OYW1lKSkpLFxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIGxpc3RmdW5jdGlvbnM6JywgZXJyb3IpO1xuICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSwgcXVlcnk6IFF1ZXJ5KTogT2JzZXJ2YWJsZTxDaGF0UmVzcG9uc2U+IHtcbiAgICAvLyBTdGFydCBzdHJlYW1pbmcgYnkgaW52b2tpbmcgdGhlIENoYXQgbWV0aG9kXG4gICAgdGhpcy5zdHJlYW1pbmckLm5leHQodHJ1ZSk7XG5cbiAgICAvLyBQcmVwYXJlIHRoZSBwYXlsb2FkIHRvIHNlbmQgdG8gdGhlIENoYXQgbWV0aG9kXG4gICAgY29uc3QgZGF0YTogQ2hhdFBheWxvYWQgJiB7IGFjdGlvbjogXCJjaGF0XCIgfSA9IHtcbiAgICAgIGFjdGlvbjogXCJjaGF0XCIsXG4gICAgICBoaXN0b3J5OiBtZXNzYWdlcyxcbiAgICAgIGZ1bmN0aW9uczogdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkKS5tYXAoZnVuYyA9PiBmdW5jLm5hbWUpLFxuICAgICAgZGVidWc6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1ZyxcbiAgICAgIHNlcnZpY2VTZXR0aW5nczoge1xuICAgICAgICBzZXJ2aWNlX2lkOiB0aGlzLmFzc2lzdGFudENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuc2VydmljZV9pZCxcbiAgICAgICAgbW9kZWxfaWQ6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5tb2RlbF9pZCxcbiAgICAgICAgdG9wX3A6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy50b3BfcCxcbiAgICAgICAgdGVtcGVyYXR1cmU6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy50ZW1wZXJhdHVyZSxcbiAgICAgICAgbWF4X3Rva2VuczogdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLm1heF90b2tlbnMsXG4gICAgICAgIC4uLnRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuYWRkaXRpb25hbFNlcnZpY2VTZXR0aW5nc1xuICAgICAgfSxcbiAgICAgIGFwcFF1ZXJ5OiB7XG4gICAgICAgIGFwcDogdGhpcy5hcHBTZXJ2aWNlLmFwcE5hbWUsXG4gICAgICAgIHF1ZXJ5XG4gICAgICB9LFxuICAgICAgZ2VuZXJpY0NoYXRFcnJvck1lc3NhZ2U6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZ2xvYmFsU2V0dGluZ3MuZ2VuZXJpY0NoYXRFcnJvck1lc3NhZ2VcbiAgICB9XG4gICAgaWYgKHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgZGF0YS5pbnN0YW5jZUlkID0gdGhpcy5jaGF0SW5zdGFuY2VJZDtcbiAgICAgIGRhdGEuc2F2ZWRDaGF0SWQgPSB0aGlzLnNhdmVkQ2hhdElkO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoT2JqZWN0LmVudHJpZXMoZGF0YSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgYWNjW2tleV0gPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pKTtcblxuICAgIC8vIFJlcXVlc3QgdGhlIENoYXQgZW5kcG9pbnRcblxuICAgIGNvbnN0IHBhcmFtc09iamVjdCA9IE9iamVjdC5mcm9tRW50cmllcyhzZWFyY2hQYXJhbXMuZW50cmllcygpKTtcblxuICAgIHJldHVybiBmcm9tKHBvc3Q8SHR0cENoYXRSZXNwb25zZT4oYHBsdWdpbi8ke3RoaXMuUkVRVUVTVF9VUkx9YCwgcGFyYW1zT2JqZWN0KSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKHJlczogSHR0cENoYXRSZXNwb25zZSkgPT4gdGhpcy51cGRhdGVRdW90YShyZXMucXVvdGEsIHRydWUpKSxcbiAgICAgICAgbWFwKChyZXM6IEh0dHBDaGF0UmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAvLyBEZWZpbmUgJHByb2dyZXNzIGZyb20gdGhlIGFjdGlvbnMgcHJvcGVydHkgb2YgdGhlIHJlc3BvbnNlXG4gICAgICAgICAgbGV0ICRwcm9ncmVzczogQ2hhdFByb2dyZXNzW10gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKHJlcy5hY3Rpb25zPy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25zOiBBY3Rpb25NZXNzYWdlW10gPSBPYmplY3QudmFsdWVzKHJlcy5hY3Rpb25zLnJlZHVjZSgoYWNjLCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgIGFjY1tpdGVtLmd1aWRdID0geyAuLi4oYWNjW2l0ZW0uZ3VpZF0gfHwge30pLCAuLi5pdGVtIH07XG4gICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9LCB7fSkpO1xuICAgICAgICAgICAgJHByb2dyZXNzID0gYWN0aW9ucy5tYXAoKGEpID0+ICh7XG4gICAgICAgICAgICAgIHRpdGxlOiBhLmRpc3BsYXlOYW1lID8/IFwiXCIsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6IGEuZGlzcGxheVZhbHVlID8/IFwiXCIsXG4gICAgICAgICAgICAgIGRvbmU6IGEuZXhlY3V0aW9uVGltZSAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB0aW1lOiBhLmV4ZWN1dGlvblRpbWUsXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUmUtYXR0YWNoIHRoZSAkcHJvZ3Jlc3MgYW5kICRhdHRhY2htZW50IG9mIHRoZSBsYXN0IHJlc3BvbnNlIHRvIHRoZSBsYXN0IGFzc2lzdGFudCdzIHJlc3BvbnNlIGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgLi4uKHJlcy5oaXN0b3J5IGFzIEFycmF5PENoYXRNZXNzYWdlPikuYXQoLTEpIH0gYXMgQ2hhdE1lc3NhZ2U7XG4gICAgICAgICAgaWYgKCRwcm9ncmVzcykgcmVzcG9uc2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzID0gJHByb2dyZXNzO1xuICAgICAgICAgIGlmIChyZXMuY29udGV4dCkgcmVzcG9uc2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgPSByZXMuY29udGV4dC5tYXAoKGN0eCkgPT4gY3R4LmFkZGl0aW9uYWxQcm9wZXJ0aWVzKTtcbiAgICAgICAgICBpZiAocmVzLnN1Z2dlc3RlZEFjdGlvbnMpIHJlc3BvbnNlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gPSByZXMuc3VnZ2VzdGVkQWN0aW9ucztcbiAgICAgICAgICAvLyBFbWl0IHRoZSB1cGRhdGVkIGNoYXQgdXNhZ2UgbWV0cmljcyBvbmNlIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgaXMgY29tcGxldGVkXG4gICAgICAgICAgaWYgKCEhcmVzcG9uc2UuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoYXRVc2FnZU1ldHJpY3MocmVzcG9uc2UuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzISk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgY2hhdCBoaXN0b3J5IHdpdGggdGhlIGluY29taW5nIGhpc3RvcnkgcHJvcGVydHkgb2YgdGhlIHJlcyBBTkQgdGhlIHByb2Nlc3NlZCByZXNwb25zZSBtZXNzYWdlXG4gICAgICAgICAgdGhpcy5jaGF0SGlzdG9yeSA9IHJlcy5oaXN0b3J5O1xuICAgICAgICAgIHRoaXMuY2hhdEhpc3RvcnlbdGhpcy5jaGF0SGlzdG9yeS5sZW5ndGggLSAxXSA9IHJlc3BvbnNlO1xuICAgICAgICAgIC8vIFNhdmUvdXBkYXRlIHRoZSBjaGF0IGlmIHNhdmVkQ2hhdCBlbmFibGVkXG4gICAgICAgICAgaWYgKHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCAmJiB0aGlzLmNoYXRIaXN0b3J5LnNvbWUoKG1zZykgPT4gbXNnLmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy5pc1VzZXJJbnB1dCA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9ICF0aGlzLnNhdmVkQ2hhdElkID8gdGhpcy5hZGRTYXZlZENoYXQodGhpcy5jaGF0SGlzdG9yeSkgOiB0aGlzLnVwZGF0ZVNhdmVkQ2hhdCh0aGlzLnNhdmVkQ2hhdElkLCB1bmRlZmluZWQsIHRoaXMuY2hhdEhpc3RvcnkpO1xuICAgICAgICAgICAgYWN0aW9uLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEdlbmVyYXRlIGF1ZGl0IGV2ZW50XG4gICAgICAgICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICAgICAgICdkdXJhdGlvbic6IHJlcy5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIHx8IHJlcy5leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgJ3JvbGUnOiByZXNwb25zZS5yb2xlLCAvLyAnYXNzaXN0YW50J1xuICAgICAgICAgICAgJ3JhbmsnOiB0aGlzLmNoYXRIaXN0b3J5Lmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAnZ2VuZXJhdGlvbi10b2tlbmNvdW50JzogcmVzcG9uc2UuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzPy5jb21wbGV0aW9uVG9rZW5Db3VudCxcbiAgICAgICAgICAgICdwcm9tcHQtdG9rZW5jb3VudCc6IHJlc3BvbnNlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcz8ucHJvbXB0VG9rZW5Db3VudCxcbiAgICAgICAgICAgICdhdHRhY2htZW50cyc6IHJlc3BvbnNlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50Py5tYXAoKHsgcmVjb3JkSWQsIGNvbnRleHRJZCwgcGFydHMsIHR5cGUgfSkgPT4gKHtcbiAgICAgICAgICAgICAgcmVjb3JkSWQsXG4gICAgICAgICAgICAgIGNvbnRleHRJZCxcbiAgICAgICAgICAgICAgcGFydHM6IHBhcnRzLm1hcCgoeyBwYXJ0SWQsIHRleHQgfSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZT8uYXVkaXRTZXR0aW5ncz8ubG9nQ29udGVudCkgcmV0dXJuIHsgcGFydElkLCB0ZXh0IH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgcGFydElkIH1cbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHR5cGVcbiAgICAgICAgICAgIH0pKVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAoISF0aGlzLmFzc2lzdGFudENvbmZpZyQudmFsdWU/LmF1ZGl0U2V0dGluZ3M/LmxvZ0NvbnRlbnQpXG4gICAgICAgICAgICBkZXRhaWxzWyd0ZXh0J10gPSByZXNwb25zZS5jb250ZW50O1xuXG4gICAgICAgICAgdGhpcy5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlJywgZGV0YWlscyk7XG4gICAgICAgICAgLy8gUmV0dXJuIHRoZSByZXN1bHRcbiAgICAgICAgICByZXR1cm4geyBoaXN0b3J5OiBbLi4ubWVzc2FnZXMsIHJlc3BvbnNlXSwgZXhlY3V0aW9uVGltZTogcmVzLmV4ZWN1dGlvblRpbWUsIGV4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHM6IHJlcy5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIH07XG4gICAgICAgIH0pLFxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB0aGlzLnN0cmVhbWluZyQubmV4dChmYWxzZSkpXG4gICAgICApO1xuICB9XG5cbiAgc3RvcEdlbmVyYXRpb24oKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBpbiBSRVNUJyk7XG4gICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICB9XG5cbiAgbGlzdFNhdmVkQ2hhdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBhY3Rpb246IFwiU2F2ZWRDaGF0TGlzdFwiLFxuICAgICAgaW5zdGFuY2VJZDogdGhpcy5jaGF0SW5zdGFuY2VJZCxcbiAgICAgIGRlYnVnOiB0aGlzLmFzc2lzdGFudENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhPYmplY3QuZW50cmllcyhkYXRhKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2Nba2V5XSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPikpO1xuXG4gICAgZnJvbShnZXQ8eyBzYXZlZENoYXQ6IFNhdmVkQ2hhdFtdIH0+KGBwbHVnaW4vJHt0aGlzLlJFUVVFU1RfVVJMfWAsIHNlYXJjaFBhcmFtcykpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogcmVzID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmVkQ2hhdHMkLm5leHQocmVzLnNhdmVkQ2hhdCk7XG4gICAgICAgICAgdGhpcy5zYXZlZENoYXRzRXJyb3IkLm5leHQoZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIHdoaWxlIGNhbGxpbmcgdGhlIFNhdmVkQ2hhdExpc3QgQVBJOicsIGVycm9yLmVycm9yLmVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5zYXZlZENoYXRzRXJyb3IkLm5leHQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zU2VydmljZS5lcnJvcignRXJyb3Igb2NjdXJyZWQgd2hpbGUgY2FsbGluZyB0aGUgU2F2ZWRDaGF0TGlzdCBBUEk6JywgZXJyb3IuZXJyb3IuZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBhZGRTYXZlZENoYXQobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pOiBPYnNlcnZhYmxlPFNhdmVkQ2hhdFJlc3BvbnNlPiB7XG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGFjdGlvbjogXCJTYXZlZENoYXRBZGRcIixcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogdGhpcy5jaGF0SWQsXG4gICAgICBoaXN0b3J5OiBtZXNzYWdlcyxcbiAgICAgIGRlYnVnOiB0aGlzLmFzc2lzdGFudENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhPYmplY3QuZW50cmllcyhkYXRhKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2Nba2V5XSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPikpO1xuXG4gICAgLy8gUmVxdWVzdCB0aGUgQ2hhdCBlbmRwb2ludFxuICAgIGNvbnN0IHBhcmFtc09iamVjdCA9IE9iamVjdC5mcm9tRW50cmllcyhzZWFyY2hQYXJhbXMuZW50cmllcygpKTtcblxuICAgIHJldHVybiBmcm9tKHBvc3Q8U2F2ZWRDaGF0UmVzcG9uc2U+KGBwbHVnaW4vJHt0aGlzLlJFUVVFU1RfVVJMfWAsIHBhcmFtc09iamVjdCkpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKHJlcyA9PiB7XG4gICAgICAgICAgdGhpcy5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1zYXZlZC1jaGF0LmFkZCcsIHsgZHVyYXRpb246IHJlcy5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIH0sIHJlcy5zYXZlZENoYXQuaWQpICAvLyBHZW5lcmF0ZSBhdWRpdCBldmVudFxuICAgICAgICAgIHRoaXMuc2V0U2F2ZWRDaGF0SWQocmVzLnNhdmVkQ2hhdC5pZCk7IC8vIFBlcnNpc3QgdGhlIHNhdmVkQ2hhdElkXG4gICAgICAgIH0pLFxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIHdoaWxlIGNhbGxpbmcgdGhlIFNhdmVkQ2hhdEFkZCBBUEk6JywgZXJyb3IuZXJyb3IuZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKCdFcnJvciBvY2N1cnJlZCB3aGlsZSBjYWxsaW5nIHRoZSBTYXZlZENoYXRBZGQgQVBJOicsIGVycm9yLmVycm9yLmVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIGdldFNhdmVkQ2hhdChpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxTYXZlZENoYXRIaXN0b3J5IHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGFjdGlvbjogXCJTYXZlZENoYXRHZXRcIixcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogaWQsXG4gICAgICBkZWJ1ZzogdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmRlYnVnXG4gICAgfTtcblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoT2JqZWN0LmVudHJpZXMoZGF0YSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgYWNjW2tleV0gPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pKTtcblxuICAgIHJldHVybiBmcm9tKGdldDx7IHNhdmVkQ2hhdDogU2F2ZWRDaGF0SGlzdG9yeSwgZXhlY3V0aW9uVGltZU1pbGxpc2Vjb25kczogbnVtYmVyIH0+KGBwbHVnaW4vJHt0aGlzLlJFUVVFU1RfVVJMfWAsIHNlYXJjaFBhcmFtcykpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKHJlcyA9PiB0aGlzLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LXNhdmVkLWNoYXQubG9hZCcsIHsgZHVyYXRpb246IHJlcy5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIH0sIHJlcy5zYXZlZENoYXQuaWQpKSxcbiAgICAgICAgbWFwKHJlcyA9PiByZXMuc2F2ZWRDaGF0KSxcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cnJlZCB3aGlsZSBjYWxsaW5nIHRoZSBTYXZlZENoYXRHZXQgQVBJOicsIGVycm9yLmVycm9yLmVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zU2VydmljZS5lcnJvcignRXJyb3Igb2NjdXJyZWQgd2hpbGUgY2FsbGluZyB0aGUgU2F2ZWRDaGF0R2V0IEFQSTonLCBlcnJvci5lcnJvci5lcnJvck1lc3NhZ2UpO1xuICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICB1cGRhdGVTYXZlZENoYXQoaWQ6IHN0cmluZywgbmFtZT86IHN0cmluZywgbWVzc2FnZXM/OiBDaGF0TWVzc2FnZVtdKTogT2JzZXJ2YWJsZTxTYXZlZENoYXRSZXNwb25zZT4ge1xuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBhY3Rpb246IFwiU2F2ZWRDaGF0VXBkYXRlXCIsXG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgc2F2ZWRDaGF0SWQ6IGlkLFxuICAgICAgZGVidWc6IHRoaXMuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICBpZiAobmFtZSkgZGF0YVtcInRpdGxlXCJdID0gbmFtZTtcbiAgICBpZiAobWVzc2FnZXMpIGRhdGFbXCJoaXN0b3J5XCJdID0gbWVzc2FnZXM7XG5cbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKE9iamVjdC5lbnRyaWVzKGRhdGEpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGFjY1trZXldID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSk7XG5cbiAgICAvLyBSZXF1ZXN0IHRoZSBDaGF0IGVuZHBvaW50XG4gICAgY29uc3QgcGFyYW1zT2JqZWN0ID0gT2JqZWN0LmZyb21FbnRyaWVzKHNlYXJjaFBhcmFtcy5lbnRyaWVzKCkpO1xuXG4gICAgcmV0dXJuIGZyb20ocG9zdDxTYXZlZENoYXRSZXNwb25zZT4oYHBsdWdpbi8ke3RoaXMuUkVRVUVTVF9VUkx9YCwgcGFyYW1zT2JqZWN0KSlcbiAgICAgIC5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIHdoaWxlIGNhbGxpbmcgdGhlIFNhdmVkQ2hhdFVwZGF0ZSBBUEk6JywgZXJyb3IuZXJyb3IuZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKCdFcnJvciBvY2N1cnJlZCB3aGlsZSBjYWxsaW5nIHRoZSBTYXZlZENoYXRVcGRhdGUgQVBJOicsIGVycm9yLmVycm9yLmVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIGRlbGV0ZVNhdmVkQ2hhdChpZHM6IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxEZWxldGVTYXZlZENoYXRSZXNwb25zZT4ge1xuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBhY3Rpb246IFwiU2F2ZWRDaGF0RGVsZXRlXCIsXG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgc2F2ZWRDaGF0SWRzOiBpZHMsXG4gICAgICBkZWJ1ZzogdGhpcy5hc3Npc3RhbnRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmRlYnVnXG4gICAgfTtcblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoT2JqZWN0LmVudHJpZXMoZGF0YSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgYWNjW2tleV0gPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pKTtcblxuICAgIC8vIFJlcXVlc3QgdGhlIENoYXQgZW5kcG9pbnRcbiAgICBjb25zdCBwYXJhbXNPYmplY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoc2VhcmNoUGFyYW1zLmVudHJpZXMoKSk7XG5cbiAgICByZXR1cm4gZnJvbShwb3N0PERlbGV0ZVNhdmVkQ2hhdFJlc3BvbnNlPihgcGx1Z2luLyR7dGhpcy5SRVFVRVNUX1VSTH1gLCBwYXJhbXNPYmplY3QpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb2NjdXJyZWQgd2hpbGUgY2FsbGluZyB0aGUgU2F2ZWRDaGF0RGVsZXRlIEFQSTonLCBlcnJvci5lcnJvci5lcnJvck1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2UuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIHdoaWxlIGNhbGxpbmcgdGhlIFNhdmVkQ2hhdERlbGV0ZSBBUEk6JywgZXJyb3IuZXJyb3IuZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG59XG4iXX0=