@senior-gestao-empresarial/angular-components 4.22.0 → 4.22.2-7ecfc706-3270-4664-9d10-a6918ef49acd

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.
@@ -1,53 +1,63 @@
1
- import { CookieService } from "ngx-cookie-service";
1
+ import { FrameImpl } from "@stomp/stompjs";
2
2
  import { Observable } from "rxjs";
3
3
  export declare class WebsocketService {
4
- private cookieService;
5
4
  private static RECONNECT_TIMER;
6
5
  private static CONNECTION_TIMEOUT;
7
6
  private static BASE_URL_COOKIE;
8
7
  private static TOKEN_COOKIE;
9
8
  private static TOKEN;
10
9
  private static WEBSOCKET_URL;
11
- private baseUrl;
12
- private username;
13
10
  private focused;
14
11
  private _stompClient;
12
+ private wasConnected;
15
13
  private connected;
16
14
  private isConnecting;
17
- private stompSubscriptions;
18
15
  private primitiveManagers;
19
- private disconnectSubject;
20
16
  private connect$;
21
- constructor(cookieService: CookieService);
17
+ private disconnect$;
18
+ private reconnect$;
19
+ private error$;
20
+ constructor();
22
21
  /**
23
- * Observable resposável por emitir uma notificação quando a conexão websocket é estabelecida.
24
- * @return Um `Observable<void>` que emite uma notificação quando a conexão websocket é estabelecida ou já está em andamento.
22
+ * Observable responsável por emitir uma notificação quando a conexão websocket é estabelecida.
23
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão websocket é estabelecida.
25
24
  */
26
25
  onConnect(): Observable<void>;
27
26
  /**
28
- * Observable resposável por emitir uma notificação quando a conexão é finalizada.
29
- * @return Um `Observable<void>` que emite uma notificação quando a conexão é finalizada.
27
+ * Observable responsável por emitir uma notificação quando a conexão é desconectada.
28
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão é desconectada.
30
29
  */
31
30
  onDisconnect(): Observable<void>;
31
+ /**
32
+ * Observable responsável por emitir uma notificação quando a conexão é reconectada.
33
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão é reconectada.
34
+ */
35
+ onReconnect(): Observable<void>;
36
+ /**
37
+ * Observable responsável por emitir uma notificação quando ocorre algum erro.
38
+ * @return Um `Observable<FrameImpl>` que emite uma notificação quando ocorre algum erro.
39
+ */
40
+ onError(): Observable<FrameImpl>;
32
41
  /**
33
42
  * Observable responsável por emitir uma notificação quando um evento é publicado.
34
43
  * @typeParam `<T>` Tipo do objeto que o retorno do `observable` vai devolver.
35
- * @param domain Dominio da primitva.
44
+ * @param domain Dominio da primitiva.
36
45
  * @param service Service da primitiva.
37
46
  * @param primitive Primitiva que será "observada" pelo client.
38
- * @param identifierPath Caminho até a propriedade considerada o indentificador do registro.
47
+ * @param identifierPath Caminho até a propriedade considerada o identificador do registro.
39
48
  * @return Um `observable` que emite notificações toda vez que o respectivo evento é publicado no sistema.
40
49
  */
41
50
  onEvent<T>(domain: string, service: string, primitive: string, identifierPath: string): Observable<T>;
42
51
  /**
43
- * Retorna todos os eventos ouvidos para a respectiva primitiva.
52
+ * Retorna todos os eventos ouvidos pela primitiva com os respectivos identificadores.
44
53
  * @typeParam `<T>` Tipo do evento retornado pela primitiva.
45
54
  * @param primitive Primitiva que será "observada" pelo client.
46
- * @param identifiers Array com os indentificadores interessados.
55
+ * @param identifiers Array com os identificadores interessados.
47
56
  * @return Array contendo o último evento recebido de cada identificador fornecido.
48
57
  */
49
58
  getPublishedEvents<T>(primitive: string, identifiers: string[]): T[];
50
59
  private addPublishedEvent;
60
+ private createStompSubscriptions;
51
61
  private getIdentifierFromEvent;
52
62
  private connect;
53
63
  private publishOnConnect;
@@ -56,9 +66,12 @@ export declare class WebsocketService {
56
66
  disconnect(): void;
57
67
  private isConnected;
58
68
  private setConnected;
59
- private getSubscriptionUserUrl;
69
+ private getSubscriptionUrlWithToken;
70
+ private getSubscriptionUrlWithoutToken;
71
+ private createStompSubscription;
60
72
  private createStompClient;
61
- private getBaseUrl;
62
- private getUserName;
63
- private reconnectWebSocket;
73
+ private reconnect;
74
+ private reconnectPrimitives;
75
+ private getObserversCount;
76
+ private disconnectPrimitiveOnFinalize;
64
77
  }
@@ -3,32 +3,28 @@ import { __decorate } from "tslib";
3
3
  import { Injectable } from "@angular/core";
4
4
  import { Stomp } from "@stomp/stompjs";
5
5
  import * as Cookies from "js-cookie";
6
- import { CookieService } from "ngx-cookie-service";
7
6
  import { Subject } from "rxjs";
8
- import { take } from "rxjs/operators";
7
+ import { first, finalize } from "rxjs/operators";
9
8
  import * as SockJS from "sockjs-client";
10
9
  import * as i0 from "@angular/core";
11
- import * as i1 from "ngx-cookie-service";
12
10
  let WebsocketService = WebsocketService_1 = class WebsocketService {
13
- constructor(cookieService) {
14
- this.cookieService = cookieService;
15
- this.baseUrl = null;
16
- this.username = null;
11
+ constructor() {
17
12
  this.focused = true;
13
+ this.wasConnected = false;
18
14
  this.connected = false;
19
15
  this.isConnecting = false;
20
- this.stompSubscriptions = new Map();
21
- // private primitiveSubjects: Map<string, Subject<any>> = new Map<string, Subject<any>>();
22
16
  this.primitiveManagers = new Map();
23
- this.disconnectSubject = new Subject();
24
17
  this.connect$ = new Subject();
18
+ this.disconnect$ = new Subject();
19
+ this.reconnect$ = new Subject();
20
+ this.error$ = new Subject();
25
21
  window.onfocus = this.onFocus;
26
22
  window.onblur = this.onBlur;
27
23
  this.connect();
28
24
  }
29
25
  /**
30
- * Observable resposável por emitir uma notificação quando a conexão websocket é estabelecida.
31
- * @return Um `Observable<void>` que emite uma notificação quando a conexão websocket é estabelecida ou já está em andamento.
26
+ * Observable responsável por emitir uma notificação quando a conexão websocket é estabelecida.
27
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão websocket é estabelecida.
32
28
  */
33
29
  onConnect() {
34
30
  setTimeout(() => {
@@ -39,66 +35,68 @@ let WebsocketService = WebsocketService_1 = class WebsocketService {
39
35
  return this.connect$.asObservable();
40
36
  }
41
37
  /**
42
- * Observable resposável por emitir uma notificação quando a conexão é finalizada.
43
- * @return Um `Observable<void>` que emite uma notificação quando a conexão é finalizada.
38
+ * Observable responsável por emitir uma notificação quando a conexão é desconectada.
39
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão é desconectada.
44
40
  */
45
41
  onDisconnect() {
46
- return this.disconnectSubject.asObservable();
42
+ return this.disconnect$.asObservable();
43
+ }
44
+ /**
45
+ * Observable responsável por emitir uma notificação quando a conexão é reconectada.
46
+ * @return Um `Observable<void>` que emite uma notificação quando a conexão é reconectada.
47
+ */
48
+ onReconnect() {
49
+ return this.reconnect$.asObservable();
50
+ }
51
+ /**
52
+ * Observable responsável por emitir uma notificação quando ocorre algum erro.
53
+ * @return Um `Observable<FrameImpl>` que emite uma notificação quando ocorre algum erro.
54
+ */
55
+ onError() {
56
+ return this.error$.asObservable();
47
57
  }
48
58
  /**
49
59
  * Observable responsável por emitir uma notificação quando um evento é publicado.
50
60
  * @typeParam `<T>` Tipo do objeto que o retorno do `observable` vai devolver.
51
- * @param domain Dominio da primitva.
61
+ * @param domain Dominio da primitiva.
52
62
  * @param service Service da primitiva.
53
63
  * @param primitive Primitiva que será "observada" pelo client.
54
- * @param identifierPath Caminho até a propriedade considerada o indentificador do registro.
64
+ * @param identifierPath Caminho até a propriedade considerada o identificador do registro.
55
65
  * @return Um `observable` que emite notificações toda vez que o respectivo evento é publicado no sistema.
56
66
  */
57
67
  onEvent(domain, service, primitive, identifierPath) {
58
- let primitiveManager = this.primitiveManagers.get(primitive);
59
- if (primitiveManager) {
60
- return primitiveManager.subject.asObservable();
68
+ if (this.primitiveManagers.has(primitive)) {
69
+ return this.primitiveManagers.get(primitive).subject.asObservable();
61
70
  }
62
- primitiveManager = {
71
+ const primitiveManager = {
72
+ domain: domain,
73
+ service: service,
74
+ primitive: primitive,
75
+ stompSubscriptions: [],
63
76
  subject: new Subject(),
64
77
  identifierPath: identifierPath,
65
78
  publishedEvents: [],
66
79
  };
80
+ this.primitiveManagers.set(primitive, primitiveManager);
67
81
  if (this.isConnected()) {
68
- const url = this.getSubscriptionUserUrl(domain, service, primitive);
69
- this.primitiveManagers.set(primitive, primitiveManager);
70
- const stompSubscription = this._stompClient.subscribe(url, (message) => {
71
- const event = JSON.parse(message.body || "{}");
72
- this.addPublishedEvent(primitiveManager, event);
73
- primitiveManager.subject.next(event);
74
- });
75
- this.stompSubscriptions.set(primitive, stompSubscription);
76
- return primitiveManager.subject.asObservable();
82
+ this.createStompSubscriptions(primitiveManager);
83
+ return primitiveManager.subject.pipe(finalize(() => this.disconnectPrimitiveOnFinalize(primitive)));
77
84
  }
78
85
  else {
79
86
  if (!this.isConnecting) {
80
87
  this.connect();
81
88
  }
82
- this.onConnect()
83
- .pipe(take(1))
84
- .subscribe(() => {
85
- const url = this.getSubscriptionUserUrl(domain, service, primitive);
86
- this.primitiveManagers.set(primitive, primitiveManager);
87
- const stompSubscription = this._stompClient.subscribe(url, (message) => {
88
- const event = JSON.parse(message.body || "{}");
89
- this.addPublishedEvent(primitiveManager, event);
90
- primitiveManager.subject.next(event);
91
- });
92
- this.stompSubscriptions.set(primitive, stompSubscription);
89
+ this.connect$.pipe(first()).subscribe(() => {
90
+ this.createStompSubscriptions(primitiveManager);
93
91
  });
94
- return primitiveManager.subject.asObservable();
92
+ return primitiveManager.subject.pipe(finalize(() => this.disconnectPrimitiveOnFinalize(primitive)));
95
93
  }
96
94
  }
97
95
  /**
98
- * Retorna todos os eventos ouvidos para a respectiva primitiva.
96
+ * Retorna todos os eventos ouvidos pela primitiva com os respectivos identificadores.
99
97
  * @typeParam `<T>` Tipo do evento retornado pela primitiva.
100
98
  * @param primitive Primitiva que será "observada" pelo client.
101
- * @param identifiers Array com os indentificadores interessados.
99
+ * @param identifiers Array com os identificadores interessados.
102
100
  * @return Array contendo o último evento recebido de cada identificador fornecido.
103
101
  */
104
102
  getPublishedEvents(primitive, identifiers) {
@@ -122,6 +120,13 @@ let WebsocketService = WebsocketService_1 = class WebsocketService {
122
120
  primitiveManager.publishedEvents.push(event);
123
121
  }
124
122
  }
123
+ createStompSubscriptions(primitiveManager) {
124
+ const withTokenUrl = this.getSubscriptionUrlWithToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
125
+ const stompSubscriptionWithToken = this.createStompSubscription(withTokenUrl, primitiveManager);
126
+ const withoutTokenUrl = this.getSubscriptionUrlWithoutToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
127
+ const stompSubscriptionWithoutToken = this.createStompSubscription(withoutTokenUrl, primitiveManager);
128
+ primitiveManager.stompSubscriptions = [stompSubscriptionWithToken, stompSubscriptionWithoutToken];
129
+ }
125
130
  getIdentifierFromEvent(identifierPath, event) {
126
131
  const properties = identifierPath.split(".");
127
132
  let identifier = event;
@@ -133,15 +138,22 @@ let WebsocketService = WebsocketService_1 = class WebsocketService {
133
138
  connect() {
134
139
  this.createStompClient();
135
140
  this.isConnecting = true;
141
+ this._stompClient.activate();
136
142
  this._stompClient.connect({}, () => {
137
- this.setConnected(true);
138
- // console.log('setou false isConnecting');
139
143
  this.isConnecting = false;
140
- // console.log('connectou dentro do connect cb');
141
- this.publishOnConnect();
142
- }, () => {
144
+ this.setConnected(true);
145
+ if (this.wasConnected) {
146
+ this.reconnectPrimitives();
147
+ this.reconnect$.next();
148
+ }
149
+ else {
150
+ this.wasConnected = true;
151
+ this.publishOnConnect();
152
+ }
153
+ }, (error) => {
143
154
  this.setConnected(false);
144
- // this.reconnectWebSocket();
155
+ this.error$.next(error);
156
+ this.reconnect();
145
157
  });
146
158
  }
147
159
  publishOnConnect() {
@@ -155,25 +167,23 @@ let WebsocketService = WebsocketService_1 = class WebsocketService {
155
167
  this.focused = false;
156
168
  }
157
169
  disconnect() {
158
- let observersCount = 0;
170
+ const observersCount = this.getObserversCount();
171
+ if (observersCount > 0)
172
+ return;
159
173
  for (const primitiveManager of this.primitiveManagers.values()) {
160
- observersCount += primitiveManager.subject.observers.length;
161
- }
162
- if (observersCount === 0) {
163
- this.stompSubscriptions.forEach(stompSubscription => {
174
+ for (const stompSubscription of primitiveManager.stompSubscriptions) {
164
175
  stompSubscription.unsubscribe();
165
- });
166
- for (const primitiveManager of this.primitiveManagers.values()) {
167
- primitiveManager.subject.complete();
168
176
  }
169
- this.stompSubscriptions.clear();
170
- this.primitiveManagers.clear();
171
- this._stompClient.disconnect();
172
- this._stompClient.deactivate();
173
- this.setConnected(false);
174
- this.isConnecting = false;
175
- this.disconnectSubject.next();
176
177
  }
178
+ for (const primitiveManager of this.primitiveManagers.values()) {
179
+ primitiveManager.subject.complete();
180
+ }
181
+ this.primitiveManagers.clear();
182
+ this._stompClient.disconnect();
183
+ this._stompClient.deactivate();
184
+ this.setConnected(false);
185
+ this.isConnecting = false;
186
+ this.disconnect$.next();
177
187
  }
178
188
  isConnected() {
179
189
  return this.connected;
@@ -181,59 +191,83 @@ let WebsocketService = WebsocketService_1 = class WebsocketService {
181
191
  setConnected(connected) {
182
192
  this.connected = connected;
183
193
  }
184
- getSubscriptionUserUrl(domain, service, primitive) {
194
+ getSubscriptionUrlWithToken(domain, service, primitive) {
185
195
  const tenant = WebsocketService_1.TOKEN ? WebsocketService_1.TOKEN.username.split("@")[1] : null;
186
196
  const token = WebsocketService_1.TOKEN ? WebsocketService_1.TOKEN.access_token : null;
187
197
  return `/topic/${tenant}/${token}/${domain}/${service}/${primitive}`;
188
198
  }
199
+ getSubscriptionUrlWithoutToken(domain, service, primitive) {
200
+ const tenant = WebsocketService_1.TOKEN ? WebsocketService_1.TOKEN.username.split("@")[1] : null;
201
+ return `/topic/${tenant}/${domain}/${service}/${primitive}`;
202
+ }
203
+ createStompSubscription(destination, primitiveManager) {
204
+ return this._stompClient.subscribe(destination, (message) => {
205
+ const event = JSON.parse(message.body || "{}");
206
+ this.addPublishedEvent(primitiveManager, event);
207
+ primitiveManager.subject.next(event);
208
+ });
209
+ }
189
210
  createStompClient() {
190
211
  const ws = new SockJS(`${WebsocketService_1.WEBSOCKET_URL}subscription`, null, { timeout: WebsocketService_1.CONNECTION_TIMEOUT });
191
212
  this._stompClient = Stomp.over(ws);
213
+ // this._stompClient.debug = (str) => console.log(new Date().toISOString(), str);
192
214
  this._stompClient.debug = () => { }; // Para remover os logs.
193
215
  }
194
- getBaseUrl() {
195
- return this.cookieService.get("com.senior.base.url");
196
- }
197
- getUserName() {
198
- const token = this.cookieService.get("com.senior.token");
199
- return token && JSON.parse(token).username;
200
- }
201
- reconnectWebSocket() {
202
- this._stompClient.disconnect();
203
- const baseUrl = this.getBaseUrl();
204
- if (this.baseUrl !== null && baseUrl != this.baseUrl) {
205
- // //console.log('ws disconnected: base url changed', this.baseUrl, ' -> ', baseUrl || 'null');
206
- return;
207
- }
208
- const username = this.getUserName();
209
- if (this.username !== null && username != this.username) {
210
- // //console.log('ws disconnected: username changed', this.username, ' -> ', username || 'null');
211
- return;
212
- }
216
+ reconnect() {
217
+ if (this.connected)
218
+ this._stompClient.disconnect();
213
219
  setTimeout(() => {
220
+ if (this.getObserversCount() === 0)
221
+ return;
214
222
  if (this.focused) {
215
223
  this.connect();
216
224
  }
217
225
  else {
218
- this.reconnectWebSocket();
226
+ this.reconnect();
219
227
  }
220
228
  }, WebsocketService_1.RECONNECT_TIMER);
221
229
  }
230
+ reconnectPrimitives() {
231
+ for (const primitiveManager of this.primitiveManagers.values()) {
232
+ for (const stompSubscription of primitiveManager.stompSubscriptions) {
233
+ stompSubscription.unsubscribe();
234
+ }
235
+ this.createStompSubscriptions(primitiveManager);
236
+ }
237
+ }
238
+ getObserversCount() {
239
+ let observersCount = 0;
240
+ for (const primitiveManager of this.primitiveManagers.values()) {
241
+ observersCount += primitiveManager.subject.observers.length;
242
+ }
243
+ return observersCount;
244
+ }
245
+ disconnectPrimitiveOnFinalize(primitive) {
246
+ const primitiveManager = this.primitiveManagers.get(primitive);
247
+ if (!primitiveManager)
248
+ return;
249
+ // @IMPORTANT: Replace .observers.length with .observed in rxjs 7.0+
250
+ const hasObservers = !(primitiveManager.subject.observers.length === 1);
251
+ if (hasObservers)
252
+ return;
253
+ for (const stompSubscription of primitiveManager.stompSubscriptions) {
254
+ stompSubscription.unsubscribe();
255
+ }
256
+ this.primitiveManagers.delete(primitive);
257
+ this.disconnect();
258
+ }
222
259
  };
223
260
  WebsocketService.RECONNECT_TIMER = 3000;
224
- WebsocketService.CONNECTION_TIMEOUT = 30000;
261
+ WebsocketService.CONNECTION_TIMEOUT = 15000;
225
262
  WebsocketService.BASE_URL_COOKIE = "com.senior.base.url";
226
263
  WebsocketService.TOKEN_COOKIE = "com.senior.token";
227
264
  WebsocketService.TOKEN = JSON.parse(Cookies.get(WebsocketService_1.TOKEN_COOKIE) || "{}");
228
265
  WebsocketService.WEBSOCKET_URL = Cookies.get(WebsocketService_1.BASE_URL_COOKIE) + "/websocket/";
229
- WebsocketService.ctorParameters = () => [
230
- { type: CookieService }
231
- ];
232
- WebsocketService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebsocketService_Factory() { return new WebsocketService(i0.ɵɵinject(i1.CookieService)); }, token: WebsocketService, providedIn: "root" });
266
+ WebsocketService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebsocketService_Factory() { return new WebsocketService(); }, token: WebsocketService, providedIn: "root" });
233
267
  WebsocketService = WebsocketService_1 = __decorate([
234
268
  Injectable({
235
269
  providedIn: "root",
236
270
  })
237
271
  ], WebsocketService);
238
272
  export { WebsocketService };
239
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2VuaW9yLWdlc3Rhby1lbXByZXNhcmlhbC9hbmd1bGFyLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL3dlYnNvY2tldC93ZWJzb2NrZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFnQixLQUFLLEVBQXFCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEUsT0FBTyxLQUFLLE9BQU8sTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ25ELE9BQU8sRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFDOzs7QUFXeEMsSUFBYSxnQkFBZ0Isd0JBQTdCLE1BQWEsZ0JBQWdCO0lBeUJ6QixZQUFvQixhQUE0QjtRQUE1QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQWpCeEMsWUFBTyxHQUFXLElBQUksQ0FBQztRQUN2QixhQUFRLEdBQVcsSUFBSSxDQUFDO1FBQ3hCLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFHZixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLHVCQUFrQixHQUFtQyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztRQUVsRywwRkFBMEY7UUFDbEYsc0JBQWlCLEdBQWtDLElBQUksR0FBRyxFQUE0QixDQUFDO1FBRXZGLHNCQUFpQixHQUFrQixJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRXZELGFBQVEsR0FBa0IsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUdsRCxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFP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QU8sQ0FBQyxHQUFHLENBQUMsa0JBQWdCLENBQUMsZUFBZSxDQUFDLEdBQUcsYUFBYSxDQUFDOztZQW1CMUQsYUFBYTs7O0FBekJ2QyxnQkFBZ0I7SUFINUIsVUFBVSxDQUFDO1FBQ1IsVUFBVSxFQUFFLE1BQU07S0FDckIsQ0FBQztHQUNXLGdCQUFnQixDQWtTNUI7U0FsU1ksZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IENvbXBhdENsaWVudCwgU3RvbXAsIFN0b21wU3Vic2NyaXB0aW9uIH0gZnJvbSBcIkBzdG9tcC9zdG9tcGpzXCI7XHJcbmltcG9ydCAqIGFzIENvb2tpZXMgZnJvbSBcImpzLWNvb2tpZVwiO1xyXG5pbXBvcnQgeyBDb29raWVTZXJ2aWNlIH0gZnJvbSBcIm5neC1jb29raWUtc2VydmljZVwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgdGFrZSB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQgKiBhcyBTb2NrSlMgZnJvbSBcInNvY2tqcy1jbGllbnRcIjtcclxuXHJcbmludGVyZmFjZSBQcmltaXRpdmVNYW5hZ2VyIHtcclxuICAgIHN1YmplY3Q6IFN1YmplY3Q8YW55PjtcclxuICAgIGlkZW50aWZpZXJQYXRoOiBzdHJpbmc7XHJcbiAgICBwdWJsaXNoZWRFdmVudHM6IGFueVtdO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgICBwcm92aWRlZEluOiBcInJvb3RcIixcclxufSlcclxuZXhwb3J0IGNsYXNzIFdlYnNvY2tldFNlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgUkVDT05ORUNUX1RJTUVSID0gMzAwMDtcclxuICAgIHByaXZhdGUgc3RhdGljIENPTk5FQ1RJT05fVElNRU9VVCA9IDMwMDAwO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgQkFTRV9VUkxfQ09PS0lFID0gXCJjb20uc2VuaW9yLmJhc2UudXJsXCI7XHJcbiAgICBwcml2YXRlIHN0YXRpYyBUT0tFTl9DT09LSUUgPSBcImNvbS5zZW5pb3IudG9rZW5cIjtcclxuICAgIHByaXZhdGUgc3RhdGljIFRPS0VOID0gSlNPTi5wYXJzZShDb29raWVzLmdldChXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOX0NPT0tJRSkgfHwgXCJ7fVwiKTtcclxuICAgIHByaXZhdGUgc3RhdGljIFdFQlNPQ0tFVF9VUkwgPSBDb29raWVzLmdldChXZWJzb2NrZXRTZXJ2aWNlLkJBU0VfVVJMX0NPT0tJRSkgKyBcIi93ZWJzb2NrZXQvXCI7XHJcblxyXG4gICAgcHJpdmF0ZSBiYXNlVXJsOiBzdHJpbmcgPSBudWxsO1xyXG4gICAgcHJpdmF0ZSB1c2VybmFtZTogc3RyaW5nID0gbnVsbDtcclxuICAgIHByaXZhdGUgZm9jdXNlZCA9IHRydWU7XHJcbiAgICBwcml2YXRlIF9zdG9tcENsaWVudDogQ29tcGF0Q2xpZW50O1xyXG5cclxuICAgIHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGlzQ29ubmVjdGluZyA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgc3RvbXBTdWJzY3JpcHRpb25zOiBNYXA8c3RyaW5nLCBTdG9tcFN1YnNjcmlwdGlvbj4gPSBuZXcgTWFwPHN0cmluZywgU3RvbXBTdWJzY3JpcHRpb24+KCk7XHJcblxyXG4gICAgLy8gcHJpdmF0ZSBwcmltaXRpdmVTdWJqZWN0czogTWFwPHN0cmluZywgU3ViamVjdDxhbnk+PiA9IG5ldyBNYXA8c3RyaW5nLCBTdWJqZWN0PGFueT4+KCk7XHJcbiAgICBwcml2YXRlIHByaW1pdGl2ZU1hbmFnZXJzOiBNYXA8c3RyaW5nLCBQcmltaXRpdmVNYW5hZ2VyPiA9IG5ldyBNYXA8c3RyaW5nLCBQcmltaXRpdmVNYW5hZ2VyPigpO1xyXG5cclxuICAgIHByaXZhdGUgZGlzY29ubmVjdFN1YmplY3Q6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICAgIHByaXZhdGUgY29ubmVjdCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29va2llU2VydmljZTogQ29va2llU2VydmljZSkge1xyXG4gICAgICAgIHdpbmRvdy5vbmZvY3VzID0gdGhpcy5vbkZvY3VzO1xyXG4gICAgICAgIHdpbmRvdy5vbmJsdXIgPSB0aGlzLm9uQmx1cjtcclxuXHJcbiAgICAgICAgdGhpcy5jb25uZWN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJlc3Bvc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIGEgY29uZXjDo28gd2Vic29ja2V0IMOpIGVzdGFiZWxlY2lkYS5cclxuICAgICAqIEByZXR1cm4gVW0gYE9ic2VydmFibGU8dm9pZD5gIHF1ZSBlbWl0ZSB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyB3ZWJzb2NrZXQgw6kgZXN0YWJlbGVjaWRhIG91IGrDoSBlc3TDoSBlbSBhbmRhbWVudG8uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkNvbm5lY3QoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaE9uQ29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgMCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3QkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByZXNwb3PDoXZlbCBwb3IgZW1pdGlyIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBhIGNvbmV4w6NvIMOpIGZpbmFsaXphZGEuXHJcbiAgICAgKiBAcmV0dXJuIFVtIGBPYnNlcnZhYmxlPHZvaWQ+YCBxdWUgZW1pdGUgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIGEgY29uZXjDo28gw6kgZmluYWxpemFkYS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRGlzY29ubmVjdCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kaXNjb25uZWN0U3ViamVjdC5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIHVtIGV2ZW50byDDqSBwdWJsaWNhZG8uXHJcbiAgICAgKiBAdHlwZVBhcmFtIGA8VD5gIFRpcG8gZG8gb2JqZXRvIHF1ZSBvIHJldG9ybm8gZG8gYG9ic2VydmFibGVgIHZhaSBkZXZvbHZlci5cclxuICAgICAqIEBwYXJhbSBkb21haW4gRG9taW5pbyBkYSBwcmltaXR2YS5cclxuICAgICAqIEBwYXJhbSBzZXJ2aWNlIFNlcnZpY2UgZGEgcHJpbWl0aXZhLlxyXG4gICAgICogQHBhcmFtIHByaW1pdGl2ZSBQcmltaXRpdmEgcXVlIHNlcsOhIFwib2JzZXJ2YWRhXCIgcGVsbyBjbGllbnQuXHJcbiAgICAgKiBAcGFyYW0gaWRlbnRpZmllclBhdGggQ2FtaW5obyBhdMOpIGEgcHJvcHJpZWRhZGUgY29uc2lkZXJhZGEgbyBpbmRlbnRpZmljYWRvciBkbyByZWdpc3Ryby5cclxuICAgICAqIEByZXR1cm4gVW0gYG9ic2VydmFibGVgIHF1ZSBlbWl0ZSBub3RpZmljYcOnw7VlcyB0b2RhIHZleiBxdWUgbyByZXNwZWN0aXZvIGV2ZW50byDDqSBwdWJsaWNhZG8gbm8gc2lzdGVtYS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRXZlbnQ8VD4oZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcsIGlkZW50aWZpZXJQYXRoOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFQ+IHtcclxuICAgICAgICBsZXQgcHJpbWl0aXZlTWFuYWdlciA9IHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZ2V0KHByaW1pdGl2ZSk7XHJcblxyXG4gICAgICAgIGlmIChwcmltaXRpdmVNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVNYW5hZ2VyLnN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwcmltaXRpdmVNYW5hZ2VyID0ge1xyXG4gICAgICAgICAgICBzdWJqZWN0OiBuZXcgU3ViamVjdCgpLFxyXG4gICAgICAgICAgICBpZGVudGlmaWVyUGF0aDogaWRlbnRpZmllclBhdGgsXHJcbiAgICAgICAgICAgIHB1Ymxpc2hlZEV2ZW50czogW10sXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQoKSkge1xyXG4gICAgICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmdldFN1YnNjcmlwdGlvblVzZXJVcmwoZG9tYWluLCBzZXJ2aWNlLCBwcmltaXRpdmUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5zZXQocHJpbWl0aXZlLCBwcmltaXRpdmVNYW5hZ2VyKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uID0gdGhpcy5fc3RvbXBDbGllbnQuc3Vic2NyaWJlKHVybCwgKG1lc3NhZ2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnQ6IFQgPSBKU09OLnBhcnNlKG1lc3NhZ2UuYm9keSB8fCBcInt9XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkUHVibGlzaGVkRXZlbnQocHJpbWl0aXZlTWFuYWdlciwgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc3ViamVjdC5uZXh0KGV2ZW50KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN0b21wU3Vic2NyaXB0aW9ucy5zZXQocHJpbWl0aXZlLCBzdG9tcFN1YnNjcmlwdGlvbik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlTWFuYWdlci5zdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLm9uQ29ubmVjdCgpXHJcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxyXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpcy5nZXRTdWJzY3JpcHRpb25Vc2VyVXJsKGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5zZXQocHJpbWl0aXZlLCBwcmltaXRpdmVNYW5hZ2VyKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RvbXBTdWJzY3JpcHRpb24gPSB0aGlzLl9zdG9tcENsaWVudC5zdWJzY3JpYmUodXJsLCAobWVzc2FnZTogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50OiBUID0gSlNPTi5wYXJzZShtZXNzYWdlLmJvZHkgfHwgXCJ7fVwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkUHVibGlzaGVkRXZlbnQocHJpbWl0aXZlTWFuYWdlciwgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdWJqZWN0Lm5leHQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b21wU3Vic2NyaXB0aW9ucy5zZXQocHJpbWl0aXZlLCBzdG9tcFN1YnNjcmlwdGlvbik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVNYW5hZ2VyLnN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0b3JuYSB0b2RvcyBvcyBldmVudG9zIG91dmlkb3MgcGFyYSBhIHJlc3BlY3RpdmEgcHJpbWl0aXZhLlxyXG4gICAgICogQHR5cGVQYXJhbSBgPFQ+YCBUaXBvIGRvIGV2ZW50byByZXRvcm5hZG8gcGVsYSBwcmltaXRpdmEuXHJcbiAgICAgKiBAcGFyYW0gcHJpbWl0aXZlIFByaW1pdGl2YSBxdWUgc2Vyw6EgXCJvYnNlcnZhZGFcIiBwZWxvIGNsaWVudC5cclxuICAgICAqIEBwYXJhbSBpZGVudGlmaWVycyBBcnJheSBjb20gb3MgaW5kZW50aWZpY2Fkb3JlcyBpbnRlcmVzc2Fkb3MuXHJcbiAgICAgKiBAcmV0dXJuIEFycmF5IGNvbnRlbmRvIG8gw7psdGltbyBldmVudG8gcmVjZWJpZG8gZGUgY2FkYSBpZGVudGlmaWNhZG9yIGZvcm5lY2lkby5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFB1Ymxpc2hlZEV2ZW50czxUPihwcmltaXRpdmU6IHN0cmluZywgaWRlbnRpZmllcnM6IHN0cmluZ1tdKTogVFtdIHtcclxuICAgICAgICBjb25zdCBwdWJsaXNoZWRFdmVudHM6IFRbXSA9IFtdO1xyXG5cclxuICAgICAgICBjb25zdCBwcmltaXRpdmVNYW5hZ2VyID0gdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5nZXQocHJpbWl0aXZlKTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBpZGVudGlmaWVyIG9mIGlkZW50aWZpZXJzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gcHJpbWl0aXZlTWFuYWdlci5wdWJsaXNoZWRFdmVudHMuZmluZChcclxuICAgICAgICAgICAgICAgIHggPT4gdGhpcy5nZXRJZGVudGlmaWVyRnJvbUV2ZW50KHByaW1pdGl2ZU1hbmFnZXIuaWRlbnRpZmllclBhdGgsIHgpID09PSBpZGVudGlmaWVyXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgIHB1Ymxpc2hlZEV2ZW50cy5wdXNoKGV2ZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHB1Ymxpc2hlZEV2ZW50cztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZFB1Ymxpc2hlZEV2ZW50KHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXIsIGV2ZW50OiBhbnkpIHtcclxuICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gdGhpcy5nZXRJZGVudGlmaWVyRnJvbUV2ZW50KHByaW1pdGl2ZU1hbmFnZXIuaWRlbnRpZmllclBhdGgsIGV2ZW50KTtcclxuXHJcbiAgICAgICAgY29uc3QgZXZlbnRJbmRleCA9IHByaW1pdGl2ZU1hbmFnZXIucHVibGlzaGVkRXZlbnRzLmZpbmRJbmRleChcclxuICAgICAgICAgICAgeCA9PlxyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRJZGVudGlmaWVyRnJvbUV2ZW50KHByaW1pdGl2ZU1hbmFnZXIuaWRlbnRpZmllclBhdGgsIHgpID09PSBpZGVudGlmaWVyXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgaWYgKGV2ZW50SW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHVibGlzaGVkRXZlbnRzW2V2ZW50SW5kZXhdID0geyAuLi5wcmltaXRpdmVNYW5hZ2VyLnB1Ymxpc2hlZEV2ZW50c1tldmVudEluZGV4XSwgLi4uZXZlbnQgfTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnB1Ymxpc2hlZEV2ZW50cy5wdXNoKGV2ZW50KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRJZGVudGlmaWVyRnJvbUV2ZW50KGlkZW50aWZpZXJQYXRoOiBzdHJpbmcsIGV2ZW50OiBhbnkpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBpZGVudGlmaWVyUGF0aC5zcGxpdChcIi5cIik7XHJcblxyXG4gICAgICAgIGxldCBpZGVudGlmaWVyID0gZXZlbnQ7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydGllcykge1xyXG4gICAgICAgICAgICBpZGVudGlmaWVyID0gaWRlbnRpZmllcltwcm9wZXJ0eV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaWRlbnRpZmllcjtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNvbm5lY3QoKSB7XHJcbiAgICAgICAgdGhpcy5jcmVhdGVTdG9tcENsaWVudCgpO1xyXG5cclxuICAgICAgICB0aGlzLmlzQ29ubmVjdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b21wQ2xpZW50LmNvbm5lY3QoXHJcbiAgICAgICAgICAgIHt9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldENvbm5lY3RlZCh0cnVlKTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdzZXRvdSBmYWxzZSBpc0Nvbm5lY3RpbmcnKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzQ29ubmVjdGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2Nvbm5lY3RvdSBkZW50cm8gZG8gY29ubmVjdCBjYicpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaE9uQ29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldENvbm5lY3RlZChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzLnJlY29ubmVjdFdlYlNvY2tldCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHB1Ymxpc2hPbkNvbm5lY3QoKSB7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0JC5uZXh0KCk7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0JC5vYnNlcnZlcnMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uRm9jdXMoKSB7XHJcbiAgICAgICAgdGhpcy5mb2N1c2VkID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uQmx1cigpIHtcclxuICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzY29ubmVjdCgpIHtcclxuICAgICAgICBsZXQgb2JzZXJ2ZXJzQ291bnQgPSAwO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBvYnNlcnZlcnNDb3VudCArPSBwcmltaXRpdmVNYW5hZ2VyLnN1YmplY3Qub2JzZXJ2ZXJzLmxlbmd0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvYnNlcnZlcnNDb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLnN0b21wU3Vic2NyaXB0aW9ucy5mb3JFYWNoKHN0b21wU3Vic2NyaXB0aW9uID0+IHtcclxuICAgICAgICAgICAgICAgIHN0b21wU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBwcmltaXRpdmVNYW5hZ2VyIG9mIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMudmFsdWVzKCkpIHtcclxuICAgICAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc3ViamVjdC5jb21wbGV0ZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN0b21wU3Vic2NyaXB0aW9ucy5jbGVhcigpO1xyXG4gICAgICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9zdG9tcENsaWVudC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b21wQ2xpZW50LmRlYWN0aXZhdGUoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc2V0Q29ubmVjdGVkKGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5pc0Nvbm5lY3RpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdFN1YmplY3QubmV4dCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGlzQ29ubmVjdGVkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RlZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldENvbm5lY3RlZChjb25uZWN0ZWQ6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmNvbm5lY3RlZCA9IGNvbm5lY3RlZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFN1YnNjcmlwdGlvblVzZXJVcmwoZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zdCB0ZW5hbnQgPSBXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOID8gV2Vic29ja2V0U2VydmljZS5UT0tFTi51c2VybmFtZS5zcGxpdChcIkBcIilbMV0gOiBudWxsO1xyXG4gICAgICAgIGNvbnN0IHRva2VuID0gV2Vic29ja2V0U2VydmljZS5UT0tFTiA/IFdlYnNvY2tldFNlcnZpY2UuVE9LRU4uYWNjZXNzX3Rva2VuIDogbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGAvdG9waWMvJHt0ZW5hbnR9LyR7dG9rZW59LyR7ZG9tYWlufS8ke3NlcnZpY2V9LyR7cHJpbWl0aXZlfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVTdG9tcENsaWVudCgpIHtcclxuICAgICAgICBjb25zdCB3cyA9IG5ldyBTb2NrSlMoYCR7V2Vic29ja2V0U2VydmljZS5XRUJTT0NLRVRfVVJMfXN1YnNjcmlwdGlvbmAsIG51bGwsIHsgdGltZW91dDogV2Vic29ja2V0U2VydmljZS5DT05ORUNUSU9OX1RJTUVPVVQgfSk7XHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQgPSBTdG9tcC5vdmVyKHdzKTtcclxuICAgICAgICB0aGlzLl9zdG9tcENsaWVudC5kZWJ1ZyA9ICgpID0+IHt9OyAvLyBQYXJhIHJlbW92ZXIgb3MgbG9ncy5cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldEJhc2VVcmwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29va2llU2VydmljZS5nZXQoXCJjb20uc2VuaW9yLmJhc2UudXJsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0VXNlck5hbWUoKSB7XHJcbiAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLmNvb2tpZVNlcnZpY2UuZ2V0KFwiY29tLnNlbmlvci50b2tlblwiKTtcclxuICAgICAgICByZXR1cm4gdG9rZW4gJiYgSlNPTi5wYXJzZSh0b2tlbikudXNlcm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RXZWJTb2NrZXQoKSB7XHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuZGlzY29ubmVjdCgpO1xyXG4gICAgICAgIGNvbnN0IGJhc2VVcmwgPSB0aGlzLmdldEJhc2VVcmwoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuYmFzZVVybCAhPT0gbnVsbCAmJiBiYXNlVXJsICE9IHRoaXMuYmFzZVVybCkge1xyXG4gICAgICAgICAgICAvLyAvL2NvbnNvbGUubG9nKCd3cyBkaXNjb25uZWN0ZWQ6IGJhc2UgdXJsIGNoYW5nZWQnLCB0aGlzLmJhc2VVcmwsICcgLT4gJywgYmFzZVVybCB8fCAnbnVsbCcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB1c2VybmFtZSA9IHRoaXMuZ2V0VXNlck5hbWUoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMudXNlcm5hbWUgIT09IG51bGwgJiYgdXNlcm5hbWUgIT0gdGhpcy51c2VybmFtZSkge1xyXG4gICAgICAgICAgICAvLyAvL2NvbnNvbGUubG9nKCd3cyBkaXNjb25uZWN0ZWQ6IHVzZXJuYW1lIGNoYW5nZWQnLCB0aGlzLnVzZXJuYW1lLCAnIC0+ICcsIHVzZXJuYW1lIHx8ICdudWxsJyk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5mb2N1c2VkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0V2ViU29ja2V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCBXZWJzb2NrZXRTZXJ2aWNlLlJFQ09OTkVDVF9USU1FUik7XHJcbiAgICB9XHJcbn1cclxuIl19
273
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2VuaW9yLWdlc3Rhby1lbXByZXNhcmlhbC9hbmd1bGFyLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL3dlYnNvY2tldC93ZWJzb2NrZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUEyQixLQUFLLEVBQXFCLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkYsT0FBTyxLQUFLLE9BQU8sTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFDOztBQWV4QyxJQUFhLGdCQUFnQix3QkFBN0IsTUFBYSxnQkFBZ0I7SUE0QnpCO1FBcEJRLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFJZixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUVyQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRWxCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLHNCQUFpQixHQUFrQyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztRQUV2RixhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUUvQixnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFbEMsZUFBVSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFakMsV0FBTSxHQUFHLElBQUksT0FBTyxFQUFhLENBQUM7UUFHdEMsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUU1QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7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Q0FBQztBQUMzQixnQ0FBZSxHQUFHLHFCQUFxQixDQUFDO0FBQ3hDLDZCQUFZLEdBQUcsa0JBQWtCLENBQUM7QUFDbEMsc0JBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWdCLENBQUMsWUFBWSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7QUFDdkUsOEJBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFnQixDQUFDLGVBQWUsQ0FBQyxHQUFHLGFBQWEsQ0FBQzs7QUFOcEYsZ0JBQWdCO0lBSDVCLFVBQVUsQ0FBQztRQUNSLFVBQVUsRUFBRSxNQUFNO0tBQ3JCLENBQUM7R0FDVyxnQkFBZ0IsQ0E2VjVCO1NBN1ZZLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBDb21wYXRDbGllbnQsIEZyYW1lSW1wbCwgU3RvbXAsIFN0b21wU3Vic2NyaXB0aW9uIH0gZnJvbSBcIkBzdG9tcC9zdG9tcGpzXCI7XHJcbmltcG9ydCAqIGFzIENvb2tpZXMgZnJvbSBcImpzLWNvb2tpZVwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgZmlyc3QsIGZpbmFsaXplIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XHJcbmltcG9ydCAqIGFzIFNvY2tKUyBmcm9tIFwic29ja2pzLWNsaWVudFwiO1xyXG5cclxuaW50ZXJmYWNlIFByaW1pdGl2ZU1hbmFnZXIge1xyXG4gICAgZG9tYWluOiBzdHJpbmc7XHJcbiAgICBzZXJ2aWNlOiBzdHJpbmc7XHJcbiAgICBwcmltaXRpdmU6IHN0cmluZztcclxuICAgIHN0b21wU3Vic2NyaXB0aW9uczogU3RvbXBTdWJzY3JpcHRpb25bXTtcclxuICAgIHN1YmplY3Q6IFN1YmplY3Q8YW55PjtcclxuICAgIGlkZW50aWZpZXJQYXRoOiBzdHJpbmc7XHJcbiAgICBwdWJsaXNoZWRFdmVudHM6IGFueVtdO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgICBwcm92aWRlZEluOiBcInJvb3RcIixcclxufSlcclxuZXhwb3J0IGNsYXNzIFdlYnNvY2tldFNlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgUkVDT05ORUNUX1RJTUVSID0gMzAwMDtcclxuICAgIHByaXZhdGUgc3RhdGljIENPTk5FQ1RJT05fVElNRU9VVCA9IDE1MDAwO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgQkFTRV9VUkxfQ09PS0lFID0gXCJjb20uc2VuaW9yLmJhc2UudXJsXCI7XHJcbiAgICBwcml2YXRlIHN0YXRpYyBUT0tFTl9DT09LSUUgPSBcImNvbS5zZW5pb3IudG9rZW5cIjtcclxuICAgIHByaXZhdGUgc3RhdGljIFRPS0VOID0gSlNPTi5wYXJzZShDb29raWVzLmdldChXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOX0NPT0tJRSkgfHwgXCJ7fVwiKTtcclxuICAgIHByaXZhdGUgc3RhdGljIFdFQlNPQ0tFVF9VUkwgPSBDb29raWVzLmdldChXZWJzb2NrZXRTZXJ2aWNlLkJBU0VfVVJMX0NPT0tJRSkgKyBcIi93ZWJzb2NrZXQvXCI7XHJcblxyXG4gICAgcHJpdmF0ZSBmb2N1c2VkID0gdHJ1ZTtcclxuXHJcbiAgICBwcml2YXRlIF9zdG9tcENsaWVudDogQ29tcGF0Q2xpZW50O1xyXG5cclxuICAgIHByaXZhdGUgd2FzQ29ubmVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIGlzQ29ubmVjdGluZyA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgcHJpbWl0aXZlTWFuYWdlcnM6IE1hcDxzdHJpbmcsIFByaW1pdGl2ZU1hbmFnZXI+ID0gbmV3IE1hcDxzdHJpbmcsIFByaW1pdGl2ZU1hbmFnZXI+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBjb25uZWN0JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBkaXNjb25uZWN0JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSByZWNvbm5lY3QkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgICBwcml2YXRlIGVycm9yJCA9IG5ldyBTdWJqZWN0PEZyYW1lSW1wbD4oKTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB3aW5kb3cub25mb2N1cyA9IHRoaXMub25Gb2N1cztcclxuICAgICAgICB3aW5kb3cub25ibHVyID0gdGhpcy5vbkJsdXI7XHJcblxyXG4gICAgICAgIHRoaXMuY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByZXNwb25zw6F2ZWwgcG9yIGVtaXRpciB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyB3ZWJzb2NrZXQgw6kgZXN0YWJlbGVjaWRhLlxyXG4gICAgICogQHJldHVybiBVbSBgT2JzZXJ2YWJsZTx2b2lkPmAgcXVlIGVtaXRlIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBhIGNvbmV4w6NvIHdlYnNvY2tldCDDqSBlc3RhYmVsZWNpZGEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkNvbm5lY3QoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaE9uQ29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgMCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3QkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByZXNwb25zw6F2ZWwgcG9yIGVtaXRpciB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyDDqSBkZXNjb25lY3RhZGEuXHJcbiAgICAgKiBAcmV0dXJuIFVtIGBPYnNlcnZhYmxlPHZvaWQ+YCBxdWUgZW1pdGUgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIGEgY29uZXjDo28gw6kgZGVzY29uZWN0YWRhLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25EaXNjb25uZWN0KCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRpc2Nvbm5lY3QkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByZXNwb25zw6F2ZWwgcG9yIGVtaXRpciB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyDDqSByZWNvbmVjdGFkYS5cclxuICAgICAqIEByZXR1cm4gVW0gYE9ic2VydmFibGU8dm9pZD5gIHF1ZSBlbWl0ZSB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyDDqSByZWNvbmVjdGFkYS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uUmVjb25uZWN0KCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlY29ubmVjdCQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwb3IgZW1pdGlyIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBvY29ycmUgYWxndW0gZXJyby5cclxuICAgICAqIEByZXR1cm4gVW0gYE9ic2VydmFibGU8RnJhbWVJbXBsPmAgcXVlIGVtaXRlIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBvY29ycmUgYWxndW0gZXJyby5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRXJyb3IoKTogT2JzZXJ2YWJsZTxGcmFtZUltcGw+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvciQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwb3IgZW1pdGlyIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyB1bSBldmVudG8gw6kgcHVibGljYWRvLlxyXG4gICAgICogQHR5cGVQYXJhbSBgPFQ+YCBUaXBvIGRvIG9iamV0byBxdWUgbyByZXRvcm5vIGRvIGBvYnNlcnZhYmxlYCB2YWkgZGV2b2x2ZXIuXHJcbiAgICAgKiBAcGFyYW0gZG9tYWluIERvbWluaW8gZGEgcHJpbWl0aXZhLlxyXG4gICAgICogQHBhcmFtIHNlcnZpY2UgU2VydmljZSBkYSBwcmltaXRpdmEuXHJcbiAgICAgKiBAcGFyYW0gcHJpbWl0aXZlIFByaW1pdGl2YSBxdWUgc2Vyw6EgXCJvYnNlcnZhZGFcIiBwZWxvIGNsaWVudC5cclxuICAgICAqIEBwYXJhbSBpZGVudGlmaWVyUGF0aCBDYW1pbmhvIGF0w6kgYSBwcm9wcmllZGFkZSBjb25zaWRlcmFkYSBvIGlkZW50aWZpY2Fkb3IgZG8gcmVnaXN0cm8uXHJcbiAgICAgKiBAcmV0dXJuIFVtIGBvYnNlcnZhYmxlYCBxdWUgZW1pdGUgbm90aWZpY2HDp8O1ZXMgdG9kYSB2ZXogcXVlIG8gcmVzcGVjdGl2byBldmVudG8gw6kgcHVibGljYWRvIG5vIHNpc3RlbWEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkV2ZW50PFQ+KGRvbWFpbjogc3RyaW5nLCBzZXJ2aWNlOiBzdHJpbmcsIHByaW1pdGl2ZTogc3RyaW5nLCBpZGVudGlmaWVyUGF0aDogc3RyaW5nKTogT2JzZXJ2YWJsZTxUPiB7XHJcbiAgICAgICAgaWYgKHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuaGFzKHByaW1pdGl2ZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZ2V0KHByaW1pdGl2ZSkuc3ViamVjdC5hc09ic2VydmFibGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXIgPSB7XHJcbiAgICAgICAgICAgIGRvbWFpbjogZG9tYWluLFxyXG4gICAgICAgICAgICBzZXJ2aWNlOiBzZXJ2aWNlLFxyXG4gICAgICAgICAgICBwcmltaXRpdmU6IHByaW1pdGl2ZSxcclxuICAgICAgICAgICAgc3RvbXBTdWJzY3JpcHRpb25zOiBbXSxcclxuICAgICAgICAgICAgc3ViamVjdDogbmV3IFN1YmplY3Q8VD4oKSxcclxuICAgICAgICAgICAgaWRlbnRpZmllclBhdGg6IGlkZW50aWZpZXJQYXRoLFxyXG4gICAgICAgICAgICBwdWJsaXNoZWRFdmVudHM6IFtdLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuc2V0KHByaW1pdGl2ZSwgcHJpbWl0aXZlTWFuYWdlcik7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlTWFuYWdlci5zdWJqZWN0LnBpcGUoZmluYWxpemUoKCkgPT4gdGhpcy5kaXNjb25uZWN0UHJpbWl0aXZlT25GaW5hbGl6ZShwcmltaXRpdmUpKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzQ29ubmVjdGluZykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0KCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdCQucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZU1hbmFnZXIuc3ViamVjdC5waXBlKGZpbmFsaXplKCgpID0+IHRoaXMuZGlzY29ubmVjdFByaW1pdGl2ZU9uRmluYWxpemUocHJpbWl0aXZlKSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldG9ybmEgdG9kb3Mgb3MgZXZlbnRvcyBvdXZpZG9zIHBlbGEgcHJpbWl0aXZhIGNvbSBvcyByZXNwZWN0aXZvcyBpZGVudGlmaWNhZG9yZXMuXHJcbiAgICAgKiBAdHlwZVBhcmFtIGA8VD5gIFRpcG8gZG8gZXZlbnRvIHJldG9ybmFkbyBwZWxhIHByaW1pdGl2YS5cclxuICAgICAqIEBwYXJhbSBwcmltaXRpdmUgUHJpbWl0aXZhIHF1ZSBzZXLDoSBcIm9ic2VydmFkYVwiIHBlbG8gY2xpZW50LlxyXG4gICAgICogQHBhcmFtIGlkZW50aWZpZXJzIEFycmF5IGNvbSBvcyBpZGVudGlmaWNhZG9yZXMgaW50ZXJlc3NhZG9zLlxyXG4gICAgICogQHJldHVybiBBcnJheSBjb250ZW5kbyBvIMO6bHRpbW8gZXZlbnRvIHJlY2ViaWRvIGRlIGNhZGEgaWRlbnRpZmljYWRvciBmb3JuZWNpZG8uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRQdWJsaXNoZWRFdmVudHM8VD4ocHJpbWl0aXZlOiBzdHJpbmcsIGlkZW50aWZpZXJzOiBzdHJpbmdbXSk6IFRbXSB7XHJcbiAgICAgICAgY29uc3QgcHVibGlzaGVkRXZlbnRzOiBUW10gPSBbXTtcclxuXHJcbiAgICAgICAgY29uc3QgcHJpbWl0aXZlTWFuYWdlciA9IHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZ2V0KHByaW1pdGl2ZSk7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBpZGVudGlmaWVycykge1xyXG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHByaW1pdGl2ZU1hbmFnZXIucHVibGlzaGVkRXZlbnRzLmZpbmQoXHJcbiAgICAgICAgICAgICAgICB4ID0+IHRoaXMuZ2V0SWRlbnRpZmllckZyb21FdmVudChwcmltaXRpdmVNYW5hZ2VyLmlkZW50aWZpZXJQYXRoLCB4KSA9PT0gaWRlbnRpZmllclxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBwdWJsaXNoZWRFdmVudHMucHVzaChldmVudCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwdWJsaXNoZWRFdmVudHM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhZGRQdWJsaXNoZWRFdmVudChwcmltaXRpdmVNYW5hZ2VyOiBQcmltaXRpdmVNYW5hZ2VyLCBldmVudDogYW55KSB7XHJcbiAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IHRoaXMuZ2V0SWRlbnRpZmllckZyb21FdmVudChwcmltaXRpdmVNYW5hZ2VyLmlkZW50aWZpZXJQYXRoLCBldmVudCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGV2ZW50SW5kZXggPSBwcmltaXRpdmVNYW5hZ2VyLnB1Ymxpc2hlZEV2ZW50cy5maW5kSW5kZXgoXHJcbiAgICAgICAgICAgIHggPT4gdGhpcy5nZXRJZGVudGlmaWVyRnJvbUV2ZW50KHByaW1pdGl2ZU1hbmFnZXIuaWRlbnRpZmllclBhdGgsIHgpID09PSBpZGVudGlmaWVyXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgaWYgKGV2ZW50SW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHVibGlzaGVkRXZlbnRzW2V2ZW50SW5kZXhdID0geyAuLi5wcmltaXRpdmVNYW5hZ2VyLnB1Ymxpc2hlZEV2ZW50c1tldmVudEluZGV4XSwgLi4uZXZlbnQgfTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnB1Ymxpc2hlZEV2ZW50cy5wdXNoKGV2ZW50KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcjogUHJpbWl0aXZlTWFuYWdlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHdpdGhUb2tlblVybCA9IHRoaXMuZ2V0U3Vic2NyaXB0aW9uVXJsV2l0aFRva2VuKFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLmRvbWFpbixcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zZXJ2aWNlLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnByaW1pdGl2ZVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uV2l0aFRva2VuID0gdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbih3aXRoVG9rZW5VcmwsIHByaW1pdGl2ZU1hbmFnZXIpO1xyXG5cclxuICAgICAgICBjb25zdCB3aXRob3V0VG9rZW5VcmwgPSB0aGlzLmdldFN1YnNjcmlwdGlvblVybFdpdGhvdXRUb2tlbihcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5kb21haW4sXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc2VydmljZSxcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5wcmltaXRpdmVcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBjb25zdCBzdG9tcFN1YnNjcmlwdGlvbldpdGhvdXRUb2tlbiA9IHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb24od2l0aG91dFRva2VuVXJsLCBwcmltaXRpdmVNYW5hZ2VyKTtcclxuXHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdG9tcFN1YnNjcmlwdGlvbnMgPSBbc3RvbXBTdWJzY3JpcHRpb25XaXRoVG9rZW4sIHN0b21wU3Vic2NyaXB0aW9uV2l0aG91dFRva2VuXTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldElkZW50aWZpZXJGcm9tRXZlbnQoaWRlbnRpZmllclBhdGg6IHN0cmluZywgZXZlbnQ6IGFueSk6IHN0cmluZyB7XHJcbiAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IGlkZW50aWZpZXJQYXRoLnNwbGl0KFwiLlwiKTtcclxuXHJcbiAgICAgICAgbGV0IGlkZW50aWZpZXIgPSBldmVudDtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzKSB7XHJcbiAgICAgICAgICAgIGlkZW50aWZpZXIgPSBpZGVudGlmaWVyW3Byb3BlcnR5XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpZGVudGlmaWVyO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY29ubmVjdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNyZWF0ZVN0b21wQ2xpZW50KCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuYWN0aXZhdGUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuY29ubmVjdChcclxuICAgICAgICAgICAge30sXHJcbiAgICAgICAgICAgICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb25uZWN0ZWQodHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMud2FzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3RQcmltaXRpdmVzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0JC5uZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FzQ29ubmVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2hPbkNvbm5lY3QoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgKGVycm9yOiBGcmFtZUltcGwpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q29ubmVjdGVkKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yJC5uZXh0KGVycm9yKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHB1Ymxpc2hPbkNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0JC5uZXh0KCk7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0JC5vYnNlcnZlcnMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uRm9jdXMoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5mb2N1c2VkID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uQmx1cigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzY29ubmVjdCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBvYnNlcnZlcnNDb3VudCA9IHRoaXMuZ2V0T2JzZXJ2ZXJzQ291bnQoKTtcclxuXHJcbiAgICAgICAgaWYgKG9ic2VydmVyc0NvdW50ID4gMCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uIG9mIHByaW1pdGl2ZU1hbmFnZXIuc3RvbXBTdWJzY3JpcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBzdG9tcFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnN1YmplY3QuY29tcGxldGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuZGlzY29ubmVjdCgpO1xyXG4gICAgICAgIHRoaXMuX3N0b21wQ2xpZW50LmRlYWN0aXZhdGUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5zZXRDb25uZWN0ZWQoZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdCQubmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGVkO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0Q29ubmVjdGVkKGNvbm5lY3RlZDogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGVkID0gY29ubmVjdGVkO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0U3Vic2NyaXB0aW9uVXJsV2l0aFRva2VuKGRvbWFpbjogc3RyaW5nLCBzZXJ2aWNlOiBzdHJpbmcsIHByaW1pdGl2ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCB0ZW5hbnQgPSBXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOID8gV2Vic29ja2V0U2VydmljZS5UT0tFTi51c2VybmFtZS5zcGxpdChcIkBcIilbMV0gOiBudWxsO1xyXG4gICAgICAgIGNvbnN0IHRva2VuID0gV2Vic29ja2V0U2VydmljZS5UT0tFTiA/IFdlYnNvY2tldFNlcnZpY2UuVE9LRU4uYWNjZXNzX3Rva2VuIDogbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGAvdG9waWMvJHt0ZW5hbnR9LyR7dG9rZW59LyR7ZG9tYWlufS8ke3NlcnZpY2V9LyR7cHJpbWl0aXZlfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRTdWJzY3JpcHRpb25VcmxXaXRob3V0VG9rZW4oZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IHRlbmFudCA9IFdlYnNvY2tldFNlcnZpY2UuVE9LRU4gPyBXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOLnVzZXJuYW1lLnNwbGl0KFwiQFwiKVsxXSA6IG51bGw7XHJcblxyXG4gICAgICAgIHJldHVybiBgL3RvcGljLyR7dGVuYW50fS8ke2RvbWFpbn0vJHtzZXJ2aWNlfS8ke3ByaW1pdGl2ZX1gO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlU3RvbXBTdWJzY3JpcHRpb24oZGVzdGluYXRpb246IHN0cmluZywgcHJpbWl0aXZlTWFuYWdlcjogUHJpbWl0aXZlTWFuYWdlcik6IFN0b21wU3Vic2NyaXB0aW9uIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvbXBDbGllbnQuc3Vic2NyaWJlKGRlc3RpbmF0aW9uLCAobWVzc2FnZTogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gSlNPTi5wYXJzZShtZXNzYWdlLmJvZHkgfHwgXCJ7fVwiKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuYWRkUHVibGlzaGVkRXZlbnQocHJpbWl0aXZlTWFuYWdlciwgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdWJqZWN0Lm5leHQoZXZlbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlU3RvbXBDbGllbnQoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgd3MgPSBuZXcgU29ja0pTKGAke1dlYnNvY2tldFNlcnZpY2UuV0VCU09DS0VUX1VSTH1zdWJzY3JpcHRpb25gLCBudWxsLCB7IHRpbWVvdXQ6IFdlYnNvY2tldFNlcnZpY2UuQ09OTkVDVElPTl9USU1FT1VUIH0pO1xyXG4gICAgICAgIHRoaXMuX3N0b21wQ2xpZW50ID0gU3RvbXAub3Zlcih3cyk7XHJcbiAgICAgICAgLy8gdGhpcy5fc3RvbXBDbGllbnQuZGVidWcgPSAoc3RyKSA9PiBjb25zb2xlLmxvZyhuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksIHN0cik7XHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuZGVidWcgPSAoKSA9PiB7fTsgLy8gUGFyYSByZW1vdmVyIG9zIGxvZ3MuXHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSB0aGlzLl9zdG9tcENsaWVudC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5nZXRPYnNlcnZlcnNDb3VudCgpID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5mb2N1c2VkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCBXZWJzb2NrZXRTZXJ2aWNlLlJFQ09OTkVDVF9USU1FUik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RQcmltaXRpdmVzKCk6IHZvaWQge1xyXG4gICAgICAgIGZvciAoY29uc3QgcHJpbWl0aXZlTWFuYWdlciBvZiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnZhbHVlcygpKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc3RvbXBTdWJzY3JpcHRpb24gb2YgcHJpbWl0aXZlTWFuYWdlci5zdG9tcFN1YnNjcmlwdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIHN0b21wU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb25zKHByaW1pdGl2ZU1hbmFnZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldE9ic2VydmVyc0NvdW50KCk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IG9ic2VydmVyc0NvdW50ID0gMDtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBwcmltaXRpdmVNYW5hZ2VyIG9mIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMudmFsdWVzKCkpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXJzQ291bnQgKz0gcHJpbWl0aXZlTWFuYWdlci5zdWJqZWN0Lm9ic2VydmVycy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gb2JzZXJ2ZXJzQ291bnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBkaXNjb25uZWN0UHJpbWl0aXZlT25GaW5hbGl6ZShwcmltaXRpdmU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgPSB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmdldChwcmltaXRpdmUpO1xyXG5cclxuICAgICAgICBpZiAoIXByaW1pdGl2ZU1hbmFnZXIpIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQElNUE9SVEFOVDogUmVwbGFjZSAub2JzZXJ2ZXJzLmxlbmd0aCB3aXRoIC5vYnNlcnZlZCBpbiByeGpzIDcuMCtcclxuICAgICAgICBjb25zdCBoYXNPYnNlcnZlcnMgPSAhKHByaW1pdGl2ZU1hbmFnZXIuc3ViamVjdC5vYnNlcnZlcnMubGVuZ3RoID09PSAxKTtcclxuXHJcbiAgICAgICAgaWYgKGhhc09ic2VydmVycykgcmV0dXJuO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uIG9mIHByaW1pdGl2ZU1hbmFnZXIuc3RvbXBTdWJzY3JpcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHN0b21wU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmRlbGV0ZShwcmltaXRpdmUpO1xyXG5cclxuICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcclxuICAgIH1cclxufVxyXG4iXX0=