@senior-gestao-empresarial/angular-components 6.11.5-f1ae0f56-eaa0-41bd-bf14-efca8153a452 → 6.12.0-29fe646c-2d98-4822-8690-597195a76ad7

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 (49) hide show
  1. package/bundles/senior-gestao-empresarial-angular-components.umd.js +514 -255
  2. package/bundles/senior-gestao-empresarial-angular-components.umd.js.map +1 -1
  3. package/bundles/senior-gestao-empresarial-angular-components.umd.min.js +2 -2
  4. package/bundles/senior-gestao-empresarial-angular-components.umd.min.js.map +1 -1
  5. package/components/permissions/index.d.ts +1 -0
  6. package/components/permissions/verify-module-permissions-service.d.ts +18 -0
  7. package/components/permissions/verify-module-permissions.d.ts +16 -0
  8. package/components/utils/async-lock.d.ts +6 -0
  9. package/components/websocket/index.d.ts +2 -0
  10. package/components/websocket/models/index.d.ts +1 -0
  11. package/components/websocket/models/primitive-manager.d.ts +19 -0
  12. package/components/websocket/protocols/index.d.ts +2 -0
  13. package/components/websocket/protocols/on-event-options.d.ts +8 -0
  14. package/components/websocket/protocols/primitive-event.d.ts +10 -0
  15. package/components/websocket/user-information.service.d.ts +7 -0
  16. package/components/websocket/websocket.service.d.ts +78 -74
  17. package/esm2015/components/permissions/index.js +2 -1
  18. package/esm2015/components/permissions/verify-module-permissions-service.js +26 -0
  19. package/esm2015/components/permissions/verify-module-permissions.js +51 -0
  20. package/esm2015/components/utils/async-lock.js +34 -0
  21. package/esm2015/components/websocket/index.js +2 -1
  22. package/esm2015/components/websocket/models/index.js +2 -0
  23. package/esm2015/components/websocket/models/primitive-manager.js +39 -0
  24. package/esm2015/components/websocket/protocols/index.js +1 -0
  25. package/esm2015/components/websocket/protocols/on-event-options.js +1 -0
  26. package/esm2015/components/websocket/protocols/primitive-event.js +1 -0
  27. package/esm2015/components/websocket/user-information.service.js +34 -0
  28. package/esm2015/components/websocket/websocket.service.js +260 -195
  29. package/esm2015/senior-gestao-empresarial-angular-components.js +4 -2
  30. package/esm5/components/permissions/index.js +2 -1
  31. package/esm5/components/permissions/verify-module-permissions-service.js +28 -0
  32. package/esm5/components/permissions/verify-module-permissions.js +53 -0
  33. package/esm5/components/utils/async-lock.js +43 -0
  34. package/esm5/components/websocket/index.js +2 -1
  35. package/esm5/components/websocket/models/index.js +2 -0
  36. package/esm5/components/websocket/models/primitive-manager.js +58 -0
  37. package/esm5/components/websocket/protocols/index.js +1 -0
  38. package/esm5/components/websocket/protocols/on-event-options.js +1 -0
  39. package/esm5/components/websocket/protocols/primitive-event.js +1 -0
  40. package/esm5/components/websocket/user-information.service.js +38 -0
  41. package/esm5/components/websocket/websocket.service.js +318 -256
  42. package/esm5/senior-gestao-empresarial-angular-components.js +4 -2
  43. package/fesm2015/senior-gestao-empresarial-angular-components.js +418 -193
  44. package/fesm2015/senior-gestao-empresarial-angular-components.js.map +1 -1
  45. package/fesm5/senior-gestao-empresarial-angular-components.js +510 -255
  46. package/fesm5/senior-gestao-empresarial-angular-components.js.map +1 -1
  47. package/package.json +3 -3
  48. package/senior-gestao-empresarial-angular-components.d.ts +3 -1
  49. package/senior-gestao-empresarial-angular-components.metadata.json +1 -1
@@ -1,325 +1,387 @@
1
- import { __decorate, __values } from "tslib";
1
+ import { __awaiter, __decorate, __generator, __read, __spread, __values } from "tslib";
2
2
  import { Injectable } from '@angular/core';
3
- import { Stomp } from '@stomp/stompjs';
4
- import * as Cookies from 'js-cookie';
5
- import { BehaviorSubject, Subject, fromEvent, iif, of, race, timer } from 'rxjs';
6
- import { filter, finalize, first, map, switchMap, take } from 'rxjs/operators';
3
+ import { filter, finalize, map, switchMap, take } from 'rxjs/operators';
4
+ import { Client } from '@stomp/stompjs';
5
+ import { BehaviorSubject, Subject } from 'rxjs';
7
6
  import * as SockJS from 'sockjs-client';
7
+ import { AsyncLock } from '../utils/async-lock';
8
+ import { UserInformationService } from './user-information.service';
9
+ import { PrimitiveManager } from './models';
8
10
  import * as i0 from "@angular/core";
11
+ import * as i1 from "./user-information.service";
12
+ var RECONNECT_INTERVAL_MILLISECONDS = 3000;
13
+ var CONNECTION_TIMEOUT_MILLISECONDS = 5000;
9
14
  var WebsocketService = /** @class */ (function () {
10
- function WebsocketService() {
11
- /** @private */
12
- this.wasConnected = false;
13
- /** @private */
14
- this.isConnected = false;
15
- /** @private */
16
- this.isConnecting = false;
17
- /** @private */
18
- this.primitiveManagers = new Map();
19
- /** @private */
15
+ function WebsocketService(userInformationService) {
16
+ this.userInformationService = userInformationService;
20
17
  this.connected$ = new BehaviorSubject(false);
21
- /** @private */
22
- this.disconnect$ = new Subject();
23
- /** @private */
24
- this.reconnect$ = new Subject();
25
- /** @private */
18
+ this.disconnected$ = new Subject();
19
+ this.reconnected$ = new Subject();
26
20
  this.error$ = new Subject();
27
21
  this.subscribed$ = new Subject();
22
+ this.primitiveManagers = new Map();
23
+ this.connectionLock = new AsyncLock();
24
+ this.debugEnable = false;
25
+ this.lostConnection = false;
28
26
  }
29
- WebsocketService_1 = WebsocketService;
30
27
  /**
31
- * Observable responsável por emitir uma notificação quando a conexão websocket é estabelecida pela primeira vez.
32
- * @return Um `Observable<void>` que emite uma notificação quando a conexão websocket é estabelecida pela primeira vez.
28
+ * Enables stompjs debug logs and additional info
33
29
  */
34
- WebsocketService.prototype.onConnect = function () {
35
- return this.connected$.asObservable().pipe(filter(Boolean), map(function () { return undefined; }), take(1));
30
+ WebsocketService.prototype.enableDebugLogs = function () {
31
+ this.debugEnable = true;
36
32
  };
37
33
  /**
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.
34
+ * Manually starts the connection
40
35
  */
41
- WebsocketService.prototype.onDisconnect = function () {
42
- return this.disconnect$.asObservable();
36
+ WebsocketService.prototype.connect = function () {
37
+ return __awaiter(this, void 0, void 0, function () {
38
+ var stompConfig;
39
+ var _this = this;
40
+ return __generator(this, function (_a) {
41
+ switch (_a.label) {
42
+ case 0: return [4 /*yield*/, this.connectionLock.acquire()];
43
+ case 1:
44
+ _a.sent();
45
+ _a.label = 2;
46
+ case 2:
47
+ _a.trys.push([2, , 3, 5]);
48
+ if (this.isConnected() || this.isConnecting()) {
49
+ return [2 /*return*/];
50
+ }
51
+ this.lostConnection = false;
52
+ stompConfig = {
53
+ webSocketFactory: function () {
54
+ return new SockJS(_this.getSubscriptionUrl(), null, {
55
+ timeout: CONNECTION_TIMEOUT_MILLISECONDS
56
+ });
57
+ },
58
+ connectionTimeout: CONNECTION_TIMEOUT_MILLISECONDS,
59
+ reconnectDelay: RECONNECT_INTERVAL_MILLISECONDS,
60
+ debug: this.debug.bind(this),
61
+ onConnect: this.handleOnConnected.bind(this),
62
+ onDisconnect: this.handleOnDisconnect.bind(this),
63
+ onWebSocketClose: this.handleOnWebSocketClose.bind(this),
64
+ onStompError: this.handleOnStompError.bind(this),
65
+ onWebSocketError: this.handleOnWebSocketError.bind(this)
66
+ };
67
+ this.debug('Connecting the Webscoket');
68
+ this.stompClient = new Client(stompConfig);
69
+ this.stompClient.activate();
70
+ return [3 /*break*/, 5];
71
+ case 3: return [4 /*yield*/, this.connectionLock.release()];
72
+ case 4:
73
+ _a.sent();
74
+ return [7 /*endfinally*/];
75
+ case 5: return [2 /*return*/];
76
+ }
77
+ });
78
+ });
43
79
  };
44
80
  /**
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.
81
+ * Manually disconnect the websocket. The reconnect loop will be stopped.
47
82
  */
48
- WebsocketService.prototype.onReconnect = function () {
49
- return this.reconnect$.asObservable();
83
+ WebsocketService.prototype.disconnect = function () {
84
+ return __awaiter(this, void 0, void 0, function () {
85
+ var _a, _b, primitiveManager;
86
+ var e_1, _c;
87
+ return __generator(this, function (_d) {
88
+ switch (_d.label) {
89
+ case 0:
90
+ if (!this.isConnected()) {
91
+ return [2 /*return*/];
92
+ }
93
+ return [4 /*yield*/, this.connectionLock.acquire()];
94
+ case 1:
95
+ _d.sent();
96
+ _d.label = 2;
97
+ case 2:
98
+ _d.trys.push([2, , 5, 7]);
99
+ try {
100
+ for (_a = __values(this.primitiveManagers.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
101
+ primitiveManager = _b.value;
102
+ primitiveManager.unsubscribe();
103
+ }
104
+ }
105
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
106
+ finally {
107
+ try {
108
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
109
+ }
110
+ finally { if (e_1) throw e_1.error; }
111
+ }
112
+ this.primitiveManagers.clear();
113
+ this.connected$.next(false);
114
+ if (!this.stompClient) return [3 /*break*/, 4];
115
+ this.stompClient.forceDisconnect();
116
+ return [4 /*yield*/, this.stompClient.deactivate()];
117
+ case 3:
118
+ _d.sent();
119
+ _d.label = 4;
120
+ case 4: return [3 /*break*/, 7];
121
+ case 5: return [4 /*yield*/, this.connectionLock.release()];
122
+ case 6:
123
+ _d.sent();
124
+ return [7 /*endfinally*/];
125
+ case 7: return [2 /*return*/];
126
+ }
127
+ });
128
+ });
50
129
  };
51
130
  /**
52
- * Observable responsável por emitir uma notificação após o subscribe do evento pela primeira vez.
53
- * @return Um `Observable<void>` que emite uma notificação após o subscribe do evento pela primeira vez.
131
+ * Check if the websocket is connected
132
+ * @return `boolean` representing if the websocket is connected
54
133
  */
55
- WebsocketService.prototype.onSubscribe = function (_a) {
56
- var _this = this;
57
- var domain = _a.domain, service = _a.service, primitive = _a.primitive;
58
- var key = this.getPrimitiveManagerKey(domain, service, primitive);
59
- return this.onConnect().pipe(switchMap(function () {
60
- if (_this.primitiveManagers.has(key))
61
- return _this.primitiveManagers
62
- .get(key)
63
- .subscribed$.asObservable()
64
- .pipe(map(function () { return undefined; }), take(1));
65
- return _this.subscribed$.asObservable().pipe(filter(function (primitiveManager) {
66
- return _this.getPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive) === key;
67
- }), map(function () { return undefined; }), take(1));
68
- }));
134
+ WebsocketService.prototype.isConnected = function () {
135
+ if (!this.stompClient) {
136
+ return false;
137
+ }
138
+ return this.stompClient.connected;
139
+ };
140
+ /**
141
+ * Check if the websocket is tring to connect
142
+ * @return `boolean` representing if the websocket status
143
+ */
144
+ WebsocketService.prototype.isConnecting = function () {
145
+ if (!this.stompClient) {
146
+ return false;
147
+ }
148
+ return !this.stompClient.connected && this.stompClient.active;
149
+ };
150
+ /**
151
+ * Event responsable to emit an event when the connection is established.
152
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
153
+ * @return `Observable<boolean>`
154
+ */
155
+ WebsocketService.prototype.onConnect = function () {
156
+ return this.connected$.asObservable()
157
+ .pipe(filter(function (p) { return p === true; }));
158
+ };
159
+ /**
160
+ * Event responsable to emit an event when the connection is closed.
161
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
162
+ * @return `Observable<void>`
163
+ */
164
+ WebsocketService.prototype.onDisconnect = function () {
165
+ return this.disconnected$.asObservable();
69
166
  };
70
167
  /**
71
- * Observable responsável por emitir uma notificação quando ocorre algum erro.
72
- * @return Um `Observable<FrameImpl>` que emite uma notificação quando ocorre algum erro.
168
+ * Event responsable to emit an event when the connection is reestablished.
169
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
170
+ * @return `Observable<void>`
171
+ */
172
+ WebsocketService.prototype.onReconnect = function () {
173
+ return this.reconnected$.asObservable();
174
+ };
175
+ /**
176
+ * Event responsable to emit an event when an error ocurred.
177
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
178
+ * @return `Observable<FrameImpl>`
73
179
  */
74
180
  WebsocketService.prototype.onError = function () {
75
181
  return this.error$.asObservable();
76
182
  };
77
183
  /**
78
- * @typeParam `<T>` Tipo do objeto que o retorno do `observable` vai devolver.
79
- * @param {Object} options Objeto de configuração do evento.
80
- * @param {string} options.domain Domínio da primitiva.
81
- * @param {string} options.service Serviço da primitiva.
82
- * @param {string} options.primitive Primitiva que será "observada".
83
- * @return Um Observable<T> que emite notificações toda vez que o respectivo evento é publicado.
184
+ * Event responsible to emit an event when a primitive is called.
185
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
186
+ * @typeParam `<T>` Object type that will be used in the observable for the `data` property.
187
+ * @param {OnEventOptions} options Configurations for the event.
188
+ * @return `Observable<PrimitiveEvent<T>>` Observable that emits an event when the service calls the primitive.
84
189
  */
85
190
  WebsocketService.prototype.onEvent = function (options) {
86
191
  var _this = this;
87
- this.connect();
88
192
  var domain = options.domain, service = options.service, primitive = options.primitive;
89
- var key = this.getPrimitiveManagerKey(domain, service, primitive);
193
+ var key = this.buildPrimitiveManagerKey(domain, service, primitive);
90
194
  if (this.primitiveManagers.has(key)) {
91
- return this.primitiveManagers.get(key).event$.asObservable();
195
+ return this.primitiveManagers.get(key).getEventObservable();
92
196
  }
93
- var primitiveManager = {
94
- domain: domain,
95
- service: service,
96
- primitive: primitive,
97
- stompSubscriptions: [],
98
- event$: new Subject(),
99
- subscribed$: new BehaviorSubject(false)
100
- };
197
+ var primitiveManager = new PrimitiveManager(domain, service, primitive);
101
198
  this.primitiveManagers.set(key, primitiveManager);
102
- this.onConnect()
103
- .pipe(take(1))
104
- .subscribe(function () {
105
- _this.createStompSubscriptions(primitiveManager);
199
+ this.connect().then(function () {
200
+ _this.onConnect()
201
+ .pipe(take(1))
202
+ .subscribe(function () {
203
+ _this.createStompSubscriptions(primitiveManager);
204
+ });
106
205
  });
107
- return primitiveManager.event$
108
- .asObservable()
109
- .pipe(finalize(function () { return _this.disconnectPrimitiveOnFinalize(primitiveManager); }));
110
- };
111
- /** @private */
112
- WebsocketService.prototype.createStompSubscriptions = function (primitiveManager) {
113
- var withTokenUrl = this.getSubscriptionUrlWithToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
114
- var stompSubscriptionWithToken = this.createStompSubscription(withTokenUrl, primitiveManager);
115
- var withoutTokenUrl = this.getSubscriptionUrlWithoutToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
116
- var stompSubscriptionWithoutToken = this.createStompSubscription(withoutTokenUrl, primitiveManager);
117
- primitiveManager.stompSubscriptions = [
118
- stompSubscriptionWithToken,
119
- stompSubscriptionWithoutToken
120
- ];
121
- primitiveManager.subscribed$.next(true);
122
- this.subscribed$.next(primitiveManager);
206
+ return primitiveManager
207
+ .getEventObservable()
208
+ .pipe(finalize(function () { return _this.unsubscribePrimitiveOnFinalize(primitiveManager); }));
123
209
  };
124
- /** @private */
125
- WebsocketService.prototype.connect = function () {
210
+ /**
211
+ * Event responsible to emit an event when a subscription is created for the primitive.
212
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
213
+ * @param {OnEventOptions} options Configurations for the event.
214
+ * Observable responsável por emitir uma notificação após o subscribe do evento pela primeira vez.
215
+ * @return `Observable<boolean>` Observable that emits an event when the service calls the primitive.
216
+ */
217
+ WebsocketService.prototype.onSubscribe = function (options) {
126
218
  var _this = this;
127
- if (this.isConnected || this.isConnecting)
128
- return;
129
- this.createStompClient();
130
- this.isConnecting = true;
131
- this._stompClient.connect({}, function () {
132
- _this.isConnecting = false;
133
- _this.isConnected = true;
134
- if (_this.wasConnected) {
135
- _this.reconnectPrimitives();
136
- _this.connected$.next(true);
137
- _this.reconnect$.next();
138
- }
139
- else {
140
- _this.wasConnected = true;
141
- _this.connected$.next(true);
219
+ var domain = options.domain, service = options.service, primitive = options.primitive;
220
+ var key = this.buildPrimitiveManagerKey(domain, service, primitive);
221
+ return this.onConnect().pipe(take(1), switchMap(function () {
222
+ if (_this.primitiveManagers.has(key)) {
223
+ return _this.primitiveManagers
224
+ .get(key)
225
+ .getSubscriptionObservable()
226
+ .pipe(take(1));
142
227
  }
143
- }, function (error) {
144
- _this.isConnected = false;
145
- _this.connected$.next(false);
146
- _this.error$.next(error);
147
- race(_this.disconnect$.pipe(take(1), map(function () { return ({ wasDisconnected: true }); })), timer(WebsocketService_1.RECONNECT_INTERVAL).pipe(take(1), switchMap(function () {
148
- return iif(function () { return document.hidden; }, fromEvent(document, 'visibilitychange').pipe(first()), of(void 0));
149
- }), map(function () { return ({ wasDisconnected: false }); })))
150
- .pipe(take(1))
151
- .subscribe({
152
- next: function (_a) {
153
- var wasDisconnected = _a.wasDisconnected;
154
- if (!wasDisconnected &&
155
- !(_this.isConnected || _this.isConnecting)) {
156
- _this.connect();
157
- }
158
- }
159
- });
160
- });
228
+ return _this.subscribed$.asObservable().pipe(filter(function (primitiveManager) {
229
+ return _this.buildPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive) === key;
230
+ }), map(function () { return true; }), take(1));
231
+ }));
161
232
  };
162
- WebsocketService.prototype.disconnect = function () {
163
- var e_1, _a, e_2, _b, e_3, _c;
164
- if (!this.isConnected || this.getObserversCount() > 0) {
165
- return;
233
+ WebsocketService.prototype.debug = function (message) {
234
+ var optionalParams = [];
235
+ for (var _i = 1; _i < arguments.length; _i++) {
236
+ optionalParams[_i - 1] = arguments[_i];
166
237
  }
167
- try {
168
- for (var _d = __values(this.primitiveManagers.values()), _e = _d.next(); !_e.done; _e = _d.next()) {
169
- var primitiveManager = _e.value;
170
- try {
171
- for (var _f = (e_2 = void 0, __values(primitiveManager.stompSubscriptions)), _g = _f.next(); !_g.done; _g = _f.next()) {
172
- var stompSubscription = _g.value;
173
- stompSubscription.unsubscribe();
174
- }
175
- }
176
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
177
- finally {
178
- try {
179
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
180
- }
181
- finally { if (e_2) throw e_2.error; }
182
- }
183
- }
238
+ if (!this.debugEnable) {
239
+ return;
184
240
  }
185
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
186
- finally {
187
- try {
188
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
189
- }
190
- finally { if (e_1) throw e_1.error; }
241
+ console.log.apply(console, __spread(['WS debug: ' + message], optionalParams));
242
+ };
243
+ WebsocketService.prototype.info = function (message) {
244
+ console.info('WS info: ' + message);
245
+ };
246
+ WebsocketService.prototype.handleOnConnected = function () {
247
+ this.info('Webscoket connected');
248
+ this.connected$.next(true);
249
+ if (this.lostConnection) {
250
+ this.info('Webscoket reconnected, recriating subscriptions');
251
+ this.handleReconnection();
191
252
  }
192
- try {
193
- for (var _h = __values(this.primitiveManagers.values()), _j = _h.next(); !_j.done; _j = _h.next()) {
194
- var primitiveManager = _j.value;
195
- primitiveManager.event$.complete();
196
- }
253
+ };
254
+ WebsocketService.prototype.handleOnDisconnect = function () {
255
+ this.info('Webscoket disconnected');
256
+ this.connected$.next(false);
257
+ this.disconnected$.next();
258
+ };
259
+ WebsocketService.prototype.handleOnWebSocketClose = function (data) {
260
+ if (data.wasClean) {
261
+ return;
197
262
  }
198
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
199
- finally {
200
- try {
201
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
202
- }
203
- finally { if (e_3) throw e_3.error; }
263
+ this.lostConnection = true;
264
+ };
265
+ WebsocketService.prototype.handleOnStompError = function (data) {
266
+ this.handleError('StompError', data);
267
+ if (this.isAuthenticationError(data)) {
268
+ this.info('Authentication error, recriating subscriptions');
269
+ this.handleReconnection();
204
270
  }
205
- this.primitiveManagers.clear();
206
- this._stompClient.disconnect();
207
- this._stompClient.deactivate();
208
- this.isConnected = false;
209
- this.isConnecting = false;
210
- this.wasConnected = false;
211
- this.connected$.next(false);
212
- this.disconnect$.next();
213
271
  };
214
- /** @private */
215
- WebsocketService.prototype.getSubscriptionUrlWithToken = function (domain, service, primitive) {
216
- var tenant = WebsocketService_1.TOKEN
217
- ? WebsocketService_1.TOKEN.username.split('@')[1]
218
- : null;
219
- var token = WebsocketService_1.TOKEN
220
- ? WebsocketService_1.TOKEN.access_token
221
- : null;
222
- return "/topic/" + tenant + "/" + token + "/" + domain + "/" + service + "/" + primitive;
272
+ WebsocketService.prototype.isAuthenticationError = function (data) {
273
+ var _a;
274
+ var errorMessage = (_a = data === null || data === void 0 ? void 0 : data.headers) === null || _a === void 0 ? void 0 : _a.message;
275
+ if (!errorMessage) {
276
+ return false;
277
+ }
278
+ return errorMessage.toLowerCase().indexOf('forbiddenexception') !== -1;
223
279
  };
224
- /** @private */
225
- WebsocketService.prototype.getSubscriptionUrlWithoutToken = function (domain, service, primitive) {
226
- var tenant = WebsocketService_1.TOKEN
227
- ? WebsocketService_1.TOKEN.username.split('@')[1]
228
- : null;
229
- return "/topic/" + tenant + "/" + domain + "/" + service + "/" + primitive;
280
+ WebsocketService.prototype.handleOnWebSocketError = function (data) {
281
+ this.handleError('WebSocketError', data);
230
282
  };
231
- /** @private */
232
- WebsocketService.prototype.createStompSubscription = function (destination, primitiveManager) {
233
- return this._stompClient.subscribe(destination, function (message) {
234
- var event = JSON.parse(message.body || '{}');
235
- primitiveManager.event$.next(event);
236
- });
283
+ WebsocketService.prototype.handleError = function (origin, data) {
284
+ console.error(origin, data);
285
+ this.error$.next(data);
237
286
  };
238
- /** @private */
239
- WebsocketService.prototype.createStompClient = function () {
240
- var ws = new SockJS(WebsocketService_1.WEBSOCKET_URL + "subscription", null, { timeout: WebsocketService_1.CONNECTION_TIMEOUT });
241
- this._stompClient = Stomp.over(ws);
242
- this._stompClient.debug = function () { return null; };
287
+ WebsocketService.prototype.handleReconnection = function () {
288
+ this.lostConnection = false;
289
+ this.reconnectPrimitives();
290
+ this.reconnected$.next();
243
291
  };
244
- /** @private */
245
292
  WebsocketService.prototype.reconnectPrimitives = function () {
246
- var e_4, _a;
293
+ var e_2, _a;
247
294
  try {
248
295
  for (var _b = __values(this.primitiveManagers.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
249
296
  var primitiveManager = _c.value;
250
297
  this.createStompSubscriptions(primitiveManager);
251
298
  }
252
299
  }
253
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
300
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
254
301
  finally {
255
302
  try {
256
303
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
257
304
  }
258
- finally { if (e_4) throw e_4.error; }
305
+ finally { if (e_2) throw e_2.error; }
259
306
  }
260
307
  };
261
- /** @private */
308
+ WebsocketService.prototype.buildSubscriptionUrlWithToken = function (domain, service, primitive) {
309
+ var authToken = this.userInformationService.getAuthToken();
310
+ var tenant = this.userInformationService.getTenantDomain();
311
+ return "/topic/" + tenant + "/" + authToken + "/" + domain + "/" + service + "/" + primitive;
312
+ };
313
+ WebsocketService.prototype.getSubscriptionUrlWithoutToken = function (domain, service, primitive) {
314
+ var tenant = this.userInformationService.getTenantDomain();
315
+ return "/topic/" + tenant + "/" + domain + "/" + service + "/" + primitive;
316
+ };
317
+ WebsocketService.prototype.buildPrimitiveManagerKey = function (domain, service, primitive) {
318
+ return domain + "/" + service + "/" + primitive;
319
+ };
320
+ WebsocketService.prototype.unsubscribePrimitiveOnFinalize = function (primitiveManager) {
321
+ return __awaiter(this, void 0, void 0, function () {
322
+ var key;
323
+ return __generator(this, function (_a) {
324
+ switch (_a.label) {
325
+ case 0:
326
+ if (primitiveManager.hasObservers()) {
327
+ return [2 /*return*/];
328
+ }
329
+ primitiveManager.unsubscribe();
330
+ key = this.buildPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
331
+ this.primitiveManagers.delete(key);
332
+ return [4 /*yield*/, this.disconnectIfNoMoreObservables()];
333
+ case 1:
334
+ _a.sent();
335
+ return [2 /*return*/];
336
+ }
337
+ });
338
+ });
339
+ };
340
+ WebsocketService.prototype.disconnectIfNoMoreObservables = function () {
341
+ return __awaiter(this, void 0, void 0, function () {
342
+ return __generator(this, function (_a) {
343
+ switch (_a.label) {
344
+ case 0:
345
+ if (!(this.getObserversCount() === 0)) return [3 /*break*/, 2];
346
+ this.debug('Manually disconnecting because there are no more observers');
347
+ return [4 /*yield*/, this.disconnect()];
348
+ case 1:
349
+ _a.sent();
350
+ _a.label = 2;
351
+ case 2: return [2 /*return*/];
352
+ }
353
+ });
354
+ });
355
+ };
262
356
  WebsocketService.prototype.getObserversCount = function () {
263
- var e_5, _a;
264
357
  var observersCount = 0;
265
- try {
266
- for (var _b = __values(this.primitiveManagers.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
267
- var primitiveManager = _c.value;
268
- observersCount += primitiveManager.event$.observers.length;
269
- }
270
- }
271
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
272
- finally {
273
- try {
274
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
275
- }
276
- finally { if (e_5) throw e_5.error; }
277
- }
358
+ this.primitiveManagers.forEach(function (primitiveManager) {
359
+ observersCount += primitiveManager.getObserversCount();
360
+ });
278
361
  return observersCount;
279
362
  };
280
- /** @private */
281
- WebsocketService.prototype.disconnectPrimitiveOnFinalize = function (primitiveManager) {
282
- var e_6, _a;
283
- // @IMPORTANT: Replace .observers.length === 1 with .observed in rxjs 7.0+
284
- var hasObservers = !(primitiveManager.event$.observers.length === 1);
285
- if (hasObservers)
286
- return;
287
- primitiveManager.event$.complete();
288
- try {
289
- for (var _b = __values(primitiveManager.stompSubscriptions), _c = _b.next(); !_c.done; _c = _b.next()) {
290
- var stompSubscription = _c.value;
291
- stompSubscription.unsubscribe();
292
- }
293
- }
294
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
295
- finally {
296
- try {
297
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
298
- }
299
- finally { if (e_6) throw e_6.error; }
300
- }
301
- primitiveManager.subscribed$.complete();
302
- var key = this.getPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
303
- this.primitiveManagers.delete(key);
304
- this.disconnect();
363
+ WebsocketService.prototype.createStompSubscription = function (destination, primitiveManager) {
364
+ return this.stompClient.subscribe(destination, function (message) {
365
+ var event = JSON.parse(message.body || '{}');
366
+ primitiveManager.fireEvent(event);
367
+ });
305
368
  };
306
- /** @private */
307
- WebsocketService.prototype.getPrimitiveManagerKey = function (domain, service, primitive) {
308
- return domain + "/" + service + "/" + primitive;
369
+ WebsocketService.prototype.createStompSubscriptions = function (primitiveManager) {
370
+ var subscriptionUrlWithToken = this.buildSubscriptionUrlWithToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
371
+ var subscriptionUrlWithoutToken = this.getSubscriptionUrlWithoutToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
372
+ var stompSubscriptionWithToken = this.createStompSubscription(subscriptionUrlWithToken, primitiveManager);
373
+ var stompSubscriptionWithoutToken = this.createStompSubscription(subscriptionUrlWithoutToken, primitiveManager);
374
+ primitiveManager.subscribe(stompSubscriptionWithToken, stompSubscriptionWithoutToken);
375
+ this.subscribed$.next(primitiveManager);
376
+ };
377
+ WebsocketService.prototype.getSubscriptionUrl = function () {
378
+ return this.userInformationService.getWebSocketUrl() + "/subscription";
309
379
  };
310
- var WebsocketService_1;
311
- WebsocketService.RECONNECT_INTERVAL = 3000;
312
- WebsocketService.CONNECTION_TIMEOUT = 15000;
313
- /** @private */
314
- WebsocketService.BASE_URL_COOKIE = 'com.senior.base.url';
315
- /** @private */
316
- WebsocketService.TOKEN_COOKIE = 'com.senior.token';
317
- /** @private */
318
- WebsocketService.TOKEN = JSON.parse(Cookies.get(WebsocketService_1.TOKEN_COOKIE) || '{}');
319
- /** @private */
320
- WebsocketService.WEBSOCKET_URL = Cookies.get(WebsocketService_1.BASE_URL_COOKIE) + '/websocket/';
321
- WebsocketService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebsocketService_Factory() { return new WebsocketService(); }, token: WebsocketService, providedIn: "root" });
322
- WebsocketService = WebsocketService_1 = __decorate([
380
+ WebsocketService.ctorParameters = function () { return [
381
+ { type: UserInformationService }
382
+ ]; };
383
+ WebsocketService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebsocketService_Factory() { return new WebsocketService(i0.ɵɵinject(i1.UserInformationService)); }, token: WebsocketService, providedIn: "root" });
384
+ WebsocketService = __decorate([
323
385
  Injectable({
324
386
  providedIn: 'root'
325
387
  })
@@ -327,4 +389,4 @@ var WebsocketService = /** @class */ (function () {
327
389
  return WebsocketService;
328
390
  }());
329
391
  export { WebsocketService };
330
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2VuaW9yLWdlc3Rhby1lbXByZXNhcmlhbC9hbmd1bGFyLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL3dlYnNvY2tldC93ZWJzb2NrZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBR0gsS0FBSyxFQUVSLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxLQUFLLE9BQU8sTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUNILGVBQWUsRUFFZixPQUFPLEVBQ1AsU0FBUyxFQUNULEdBQUcsRUFDSCxFQUFFLEVBQ0YsSUFBSSxFQUNKLEtBQUssRUFDUixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFDOztBQWV4QztJQUFBO1FBdUJJLGVBQWU7UUFDUCxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUU3QixlQUFlO1FBQ1AsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFNUIsZUFBZTtRQUNQLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRTdCLGVBQWU7UUFDRSxzQkFBaUIsR0FBa0MsSUFBSSxHQUFHLEVBR3hFLENBQUM7UUFFSixlQUFlO1FBQ0UsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBRWxFLGVBQWU7UUFDUCxnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFMUMsZUFBZTtRQUNQLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRXpDLGVBQWU7UUFDUCxXQUFNLEdBQUcsSUFBSSxPQUFPLEVBQWEs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UUFBUSxFQUFFLENBQUM7UUFFeEMsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUNuQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQ3ZCLGdCQUFnQixDQUFDLE9BQU8sRUFDeEIsZ0JBQWdCLENBQUMsU0FBUyxDQUM3QixDQUFDO1FBRUYsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVuQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELGVBQWU7SUFDUCxpREFBc0IsR0FBOUIsVUFDSSxNQUFjLEVBQ2QsT0FBZSxFQUNmLFNBQWlCO1FBRWpCLE9BQVUsTUFBTSxTQUFJLE9BQU8sU0FBSSxTQUFXLENBQUM7SUFDL0MsQ0FBQzs7SUFyWmUsbUNBQWtCLEdBQUcsSUFBSSxDQUFDO0lBRW5DLG1DQUFrQixHQUFHLEtBQUssQ0FBQztJQUVsQyxlQUFlO0lBQ0EsZ0NBQWUsR0FBRyxxQkFBcUIsQ0FBQztJQUV2RCxlQUFlO0lBQ0EsNkJBQVksR0FBRyxrQkFBa0IsQ0FBQztJQUVqRCxlQUFlO0lBQ0Esc0JBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFnQixDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksQ0FDckQsQ0FBQztJQUVGLGVBQWU7SUFDQSw4QkFBYSxHQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFnQixDQUFDLGVBQWUsQ0FBQyxHQUFHLGFBQWEsQ0FBQzs7SUFsQnpELGdCQUFnQjtRQUg1QixVQUFVLENBQUM7WUFDUixVQUFVLEVBQUUsTUFBTTtTQUNyQixDQUFDO09BQ1csZ0JBQWdCLENBdVo1QjsyQkF6YkQ7Q0F5YkMsQUF2WkQsSUF1WkM7U0F2WlksZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gICAgQ29tcGF0Q2xpZW50LFxyXG4gICAgRnJhbWVJbXBsLFxyXG4gICAgU3RvbXAsXHJcbiAgICBTdG9tcFN1YnNjcmlwdGlvblxyXG59IGZyb20gJ0BzdG9tcC9zdG9tcGpzJztcclxuaW1wb3J0ICogYXMgQ29va2llcyBmcm9tICdqcy1jb29raWUnO1xyXG5pbXBvcnQge1xyXG4gICAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gICAgT2JzZXJ2YWJsZSxcclxuICAgIFN1YmplY3QsXHJcbiAgICBmcm9tRXZlbnQsXHJcbiAgICBpaWYsXHJcbiAgICBvZixcclxuICAgIHJhY2UsXHJcbiAgICB0aW1lclxyXG59IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIGZpbmFsaXplLCBmaXJzdCwgbWFwLCBzd2l0Y2hNYXAsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCAqIGFzIFNvY2tKUyBmcm9tICdzb2NranMtY2xpZW50JztcclxuXHJcbi8qKiBAcHJpdmF0ZSAqL1xyXG5pbnRlcmZhY2UgUHJpbWl0aXZlTWFuYWdlciB7XHJcbiAgICBkb21haW46IHN0cmluZztcclxuICAgIHNlcnZpY2U6IHN0cmluZztcclxuICAgIHByaW1pdGl2ZTogc3RyaW5nO1xyXG4gICAgc3RvbXBTdWJzY3JpcHRpb25zOiBTdG9tcFN1YnNjcmlwdGlvbltdO1xyXG4gICAgZXZlbnQkOiBTdWJqZWN0PGFueT47XHJcbiAgICBzdWJzY3JpYmVkJDogQmVoYXZpb3JTdWJqZWN0PEJvb2xlYW4+O1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFdlYnNvY2tldFNlcnZpY2Uge1xyXG4gICAgc3RhdGljIHJlYWRvbmx5IFJFQ09OTkVDVF9JTlRFUlZBTCA9IDMwMDA7XHJcblxyXG4gICAgc3RhdGljIENPTk5FQ1RJT05fVElNRU9VVCA9IDE1MDAwO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgQkFTRV9VUkxfQ09PS0lFID0gJ2NvbS5zZW5pb3IuYmFzZS51cmwnO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgVE9LRU5fQ09PS0lFID0gJ2NvbS5zZW5pb3IudG9rZW4nO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgVE9LRU4gPSBKU09OLnBhcnNlKFxyXG4gICAgICAgIENvb2tpZXMuZ2V0KFdlYnNvY2tldFNlcnZpY2UuVE9LRU5fQ09PS0lFKSB8fCAne30nXHJcbiAgICApO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgV0VCU09DS0VUX1VSTCA9XHJcbiAgICAgICAgQ29va2llcy5nZXQoV2Vic29ja2V0U2VydmljZS5CQVNFX1VSTF9DT09LSUUpICsgJy93ZWJzb2NrZXQvJztcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgX3N0b21wQ2xpZW50OiBDb21wYXRDbGllbnQ7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIHdhc0Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBpc0Nvbm5lY3RpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbWl0aXZlTWFuYWdlcnM6IE1hcDxzdHJpbmcsIFByaW1pdGl2ZU1hbmFnZXI+ID0gbmV3IE1hcDxcclxuICAgICAgICBzdHJpbmcsXHJcbiAgICAgICAgUHJpbWl0aXZlTWFuYWdlclxyXG4gICAgPigpO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0ZWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxCb29sZWFuPihmYWxzZSk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGRpc2Nvbm5lY3QkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgcmVjb25uZWN0JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGVycm9yJCA9IG5ldyBTdWJqZWN0PEZyYW1lSW1wbD4oKTtcclxuXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmliZWQkID0gbmV3IFN1YmplY3Q8UHJpbWl0aXZlTWFuYWdlcj4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIGEgY29uZXjDo28gd2Vic29ja2V0IMOpIGVzdGFiZWxlY2lkYSBwZWxhIHByaW1laXJhIHZlei5cclxuICAgICAqIEByZXR1cm4gVW0gYE9ic2VydmFibGU8dm9pZD5gIHF1ZSBlbWl0ZSB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyB3ZWJzb2NrZXQgw6kgZXN0YWJlbGVjaWRhIHBlbGEgcHJpbWVpcmEgdmV6LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Db25uZWN0KCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RlZCQuYXNPYnNlcnZhYmxlKCkucGlwZShcclxuICAgICAgICAgICAgZmlsdGVyKEJvb2xlYW4pLFxyXG4gICAgICAgICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcclxuICAgICAgICAgICAgdGFrZSgxKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwb3IgZW1pdGlyIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBhIGNvbmV4w6NvIMOpIGRlc2NvbmVjdGFkYS5cclxuICAgICAqIEByZXR1cm4gVW0gYE9ic2VydmFibGU8dm9pZD5gIHF1ZSBlbWl0ZSB1bWEgbm90aWZpY2HDp8OjbyBxdWFuZG8gYSBjb25leMOjbyDDqSBkZXNjb25lY3RhZGEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkRpc2Nvbm5lY3QoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzY29ubmVjdCQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJlc3BvbnPDoXZlbCBwb3IgZW1pdGlyIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBhIGNvbmV4w6NvIMOpIHJlY29uZWN0YWRhLlxyXG4gICAgICogQHJldHVybiBVbSBgT2JzZXJ2YWJsZTx2b2lkPmAgcXVlIGVtaXRlIHVtYSBub3RpZmljYcOnw6NvIHF1YW5kbyBhIGNvbmV4w6NvIMOpIHJlY29uZWN0YWRhLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25SZWNvbm5lY3QoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb25uZWN0JC5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gYXDDs3MgbyBzdWJzY3JpYmUgZG8gZXZlbnRvIHBlbGEgcHJpbWVpcmEgdmV6LlxyXG4gICAgICogQHJldHVybiBVbSBgT2JzZXJ2YWJsZTx2b2lkPmAgcXVlIGVtaXRlIHVtYSBub3RpZmljYcOnw6NvIGFww7NzIG8gc3Vic2NyaWJlIGRvIGV2ZW50byBwZWxhIHByaW1laXJhIHZlei5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uU3Vic2NyaWJlKHtcclxuICAgICAgICBkb21haW4sXHJcbiAgICAgICAgc2VydmljZSxcclxuICAgICAgICBwcmltaXRpdmVcclxuICAgIH06IHtcclxuICAgICAgICBkb21haW46IHN0cmluZztcclxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmc7XHJcbiAgICAgICAgcHJpbWl0aXZlOiBzdHJpbmc7XHJcbiAgICB9KTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRQcmltaXRpdmVNYW5hZ2VyS2V5KGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMub25Db25uZWN0KCkucGlwZShcclxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmhhcyhrZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoa2V5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlZCQuYXNPYnNlcnZhYmxlKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UoMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdWJzY3JpYmVkJC5hc09ic2VydmFibGUoKS5waXBlKFxyXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHByaW1pdGl2ZU1hbmFnZXIpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFByaW1pdGl2ZU1hbmFnZXJLZXkoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5kb21haW4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zZXJ2aWNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHJpbWl0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApID09PSBrZXlcclxuICAgICAgICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRha2UoMSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIG9jb3JyZSBhbGd1bSBlcnJvLlxyXG4gICAgICogQHJldHVybiBVbSBgT2JzZXJ2YWJsZTxGcmFtZUltcGw+YCBxdWUgZW1pdGUgdW1hIG5vdGlmaWNhw6fDo28gcXVhbmRvIG9jb3JyZSBhbGd1bSBlcnJvLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25FcnJvcigpOiBPYnNlcnZhYmxlPEZyYW1lSW1wbD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yJC5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlUGFyYW0gYDxUPmAgVGlwbyBkbyBvYmpldG8gcXVlIG8gcmV0b3JubyBkbyBgb2JzZXJ2YWJsZWAgdmFpIGRldm9sdmVyLlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgT2JqZXRvIGRlIGNvbmZpZ3VyYcOnw6NvIGRvIGV2ZW50by5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmRvbWFpbiBEb23DrW5pbyBkYSBwcmltaXRpdmEuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5zZXJ2aWNlIFNlcnZpw6dvIGRhIHByaW1pdGl2YS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLnByaW1pdGl2ZSAgUHJpbWl0aXZhIHF1ZSBzZXLDoSBcIm9ic2VydmFkYVwiLlxyXG4gICAgICogQHJldHVybiBVbSBPYnNlcnZhYmxlPFQ+IHF1ZSBlbWl0ZSBub3RpZmljYcOnw7VlcyB0b2RhIHZleiBxdWUgbyByZXNwZWN0aXZvIGV2ZW50byDDqSBwdWJsaWNhZG8uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkV2ZW50PFQ+KG9wdGlvbnM6IHtcclxuICAgICAgICBkb21haW46IHN0cmluZztcclxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmc7XHJcbiAgICAgICAgcHJpbWl0aXZlOiBzdHJpbmc7XHJcbiAgICB9KTogT2JzZXJ2YWJsZTxUPiB7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHsgZG9tYWluLCBzZXJ2aWNlLCBwcmltaXRpdmUgfSA9IG9wdGlvbnM7XHJcblxyXG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0UHJpbWl0aXZlTWFuYWdlcktleShkb21haW4sIHNlcnZpY2UsIHByaW1pdGl2ZSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmhhcyhrZXkpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmdldChrZXkpLmV2ZW50JC5hc09ic2VydmFibGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXIgPSB7XHJcbiAgICAgICAgICAgIGRvbWFpbjogZG9tYWluLFxyXG4gICAgICAgICAgICBzZXJ2aWNlOiBzZXJ2aWNlLFxyXG4gICAgICAgICAgICBwcmltaXRpdmU6IHByaW1pdGl2ZSxcclxuICAgICAgICAgICAgc3RvbXBTdWJzY3JpcHRpb25zOiBbXSxcclxuICAgICAgICAgICAgZXZlbnQkOiBuZXcgU3ViamVjdDxUPigpLFxyXG4gICAgICAgICAgICBzdWJzY3JpYmVkJDogbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSlcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnNldChrZXksIHByaW1pdGl2ZU1hbmFnZXIpO1xyXG5cclxuICAgICAgICB0aGlzLm9uQ29ubmVjdCgpXHJcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJpbWl0aXZlTWFuYWdlci5ldmVudCRcclxuICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXHJcbiAgICAgICAgICAgIC5waXBlKGZpbmFsaXplKCgpID0+IHRoaXMuZGlzY29ubmVjdFByaW1pdGl2ZU9uRmluYWxpemUocHJpbWl0aXZlTWFuYWdlcikpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgY3JlYXRlU3RvbXBTdWJzY3JpcHRpb25zKHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXIpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB3aXRoVG9rZW5VcmwgPSB0aGlzLmdldFN1YnNjcmlwdGlvblVybFdpdGhUb2tlbihcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5kb21haW4sXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc2VydmljZSxcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5wcmltaXRpdmVcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBjb25zdCBzdG9tcFN1YnNjcmlwdGlvbldpdGhUb2tlbiA9IHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb24oXHJcbiAgICAgICAgICAgIHdpdGhUb2tlblVybCxcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlclxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGNvbnN0IHdpdGhvdXRUb2tlblVybCA9IHRoaXMuZ2V0U3Vic2NyaXB0aW9uVXJsV2l0aG91dFRva2VuKFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLmRvbWFpbixcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zZXJ2aWNlLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnByaW1pdGl2ZVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uV2l0aG91dFRva2VuID0gdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbihcclxuICAgICAgICAgICAgd2l0aG91dFRva2VuVXJsLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdG9tcFN1YnNjcmlwdGlvbnMgPSBbXHJcbiAgICAgICAgICAgIHN0b21wU3Vic2NyaXB0aW9uV2l0aFRva2VuLFxyXG4gICAgICAgICAgICBzdG9tcFN1YnNjcmlwdGlvbldpdGhvdXRUb2tlblxyXG4gICAgICAgIF07XHJcblxyXG4gICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc3Vic2NyaWJlZCQubmV4dCh0cnVlKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZWQkLm5leHQocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQgfHwgdGhpcy5pc0Nvbm5lY3RpbmcpIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5jcmVhdGVTdG9tcENsaWVudCgpO1xyXG5cclxuICAgICAgICB0aGlzLmlzQ29ubmVjdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b21wQ2xpZW50LmNvbm5lY3QoXHJcbiAgICAgICAgICAgIHt9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzQ29ubmVjdGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuaXNDb25uZWN0ZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLndhc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0UHJpbWl0aXZlcygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RlZCQubmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdCQubmV4dCgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhc0Nvbm5lY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQkLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIChlcnJvcjogRnJhbWVJbXBsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzQ29ubmVjdGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RlZCQubmV4dChmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciQubmV4dChlcnJvcik7XHJcblxyXG4gICAgICAgICAgICAgICAgcmFjZShcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QkLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiAoeyB3YXNEaXNjb25uZWN0ZWQ6IHRydWUgfSkpXHJcbiAgICAgICAgICAgICAgICAgICAgKSxcclxuICAgICAgICAgICAgICAgICAgICB0aW1lcihXZWJzb2NrZXRTZXJ2aWNlLlJFQ09OTkVDVF9JTlRFUlZBTCkucGlwZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpaWYoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCkgPT4gZG9jdW1lbnQuaGlkZGVuLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ3Zpc2liaWxpdHljaGFuZ2UnKS5waXBlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZih2b2lkIDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiAoeyB3YXNEaXNjb25uZWN0ZWQ6IGZhbHNlIH0pKVxyXG4gICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0OiAoeyB3YXNEaXNjb25uZWN0ZWQgfSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICF3YXNEaXNjb25uZWN0ZWQgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKHRoaXMuaXNDb25uZWN0ZWQgfHwgdGhpcy5pc0Nvbm5lY3RpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzY29ubmVjdCgpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQgfHwgdGhpcy5nZXRPYnNlcnZlcnNDb3VudCgpID4gMCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHN0b21wU3Vic2NyaXB0aW9uIG9mIHByaW1pdGl2ZU1hbmFnZXIuc3RvbXBTdWJzY3JpcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBzdG9tcFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLmV2ZW50JC5jb21wbGV0ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5jbGVhcigpO1xyXG5cclxuICAgICAgICB0aGlzLl9zdG9tcENsaWVudC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuZGVhY3RpdmF0ZSgpO1xyXG5cclxuICAgICAgICB0aGlzLmlzQ29ubmVjdGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5pc0Nvbm5lY3RpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLndhc0Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLmNvbm5lY3RlZCQubmV4dChmYWxzZSk7XHJcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0JC5uZXh0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGdldFN1YnNjcmlwdGlvblVybFdpdGhUb2tlbihcclxuICAgICAgICBkb21haW46IHN0cmluZyxcclxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmcsXHJcbiAgICAgICAgcHJpbWl0aXZlOiBzdHJpbmdcclxuICAgICk6IHN0cmluZyB7XHJcbiAgICAgICAgY29uc3QgdGVuYW50ID0gV2Vic29ja2V0U2VydmljZS5UT0tFTlxyXG4gICAgICAgICAgICA/IFdlYnNvY2tldFNlcnZpY2UuVE9LRU4udXNlcm5hbWUuc3BsaXQoJ0AnKVsxXVxyXG4gICAgICAgICAgICA6IG51bGw7XHJcbiAgICAgICAgY29uc3QgdG9rZW4gPSBXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOXHJcbiAgICAgICAgICAgID8gV2Vic29ja2V0U2VydmljZS5UT0tFTi5hY2Nlc3NfdG9rZW5cclxuICAgICAgICAgICAgOiBudWxsO1xyXG5cclxuICAgICAgICByZXR1cm4gYC90b3BpYy8ke3RlbmFudH0vJHt0b2tlbn0vJHtkb21haW59LyR7c2VydmljZX0vJHtwcmltaXRpdmV9YDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgZ2V0U3Vic2NyaXB0aW9uVXJsV2l0aG91dFRva2VuKFxyXG4gICAgICAgIGRvbWFpbjogc3RyaW5nLFxyXG4gICAgICAgIHNlcnZpY2U6IHN0cmluZyxcclxuICAgICAgICBwcmltaXRpdmU6IHN0cmluZ1xyXG4gICAgKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCB0ZW5hbnQgPSBXZWJzb2NrZXRTZXJ2aWNlLlRPS0VOXHJcbiAgICAgICAgICAgID8gV2Vic29ja2V0U2VydmljZS5UT0tFTi51c2VybmFtZS5zcGxpdCgnQCcpWzFdXHJcbiAgICAgICAgICAgIDogbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGAvdG9waWMvJHt0ZW5hbnR9LyR7ZG9tYWlufS8ke3NlcnZpY2V9LyR7cHJpbWl0aXZlfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGNyZWF0ZVN0b21wU3Vic2NyaXB0aW9uKFxyXG4gICAgICAgIGRlc3RpbmF0aW9uOiBzdHJpbmcsXHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlcjogUHJpbWl0aXZlTWFuYWdlclxyXG4gICAgKTogU3RvbXBTdWJzY3JpcHRpb24ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdG9tcENsaWVudC5zdWJzY3JpYmUoZGVzdGluYXRpb24sIChtZXNzYWdlOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBKU09OLnBhcnNlKG1lc3NhZ2UuYm9keSB8fCAne30nKTtcclxuXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuZXZlbnQkLm5leHQoZXZlbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBjcmVhdGVTdG9tcENsaWVudCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB3cyA9IG5ldyBTb2NrSlMoXHJcbiAgICAgICAgICAgIGAke1dlYnNvY2tldFNlcnZpY2UuV0VCU09DS0VUX1VSTH1zdWJzY3JpcHRpb25gLFxyXG4gICAgICAgICAgICBudWxsLFxyXG4gICAgICAgICAgICB7IHRpbWVvdXQ6IFdlYnNvY2tldFNlcnZpY2UuQ09OTkVDVElPTl9USU1FT1VUIH1cclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMuX3N0b21wQ2xpZW50ID0gU3RvbXAub3Zlcih3cyk7XHJcbiAgICAgICAgdGhpcy5fc3RvbXBDbGllbnQuZGVidWcgPSAoKSA9PiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RQcmltaXRpdmVzKCk6IHZvaWQge1xyXG4gICAgICAgIGZvciAoY29uc3QgcHJpbWl0aXZlTWFuYWdlciBvZiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnZhbHVlcygpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb25zKHByaW1pdGl2ZU1hbmFnZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHByaXZhdGUgZ2V0T2JzZXJ2ZXJzQ291bnQoKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgb2JzZXJ2ZXJzQ291bnQgPSAwO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICBvYnNlcnZlcnNDb3VudCArPSBwcmltaXRpdmVNYW5hZ2VyLmV2ZW50JC5vYnNlcnZlcnMubGVuZ3RoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmVyc0NvdW50O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgcHJpdmF0ZSBkaXNjb25uZWN0UHJpbWl0aXZlT25GaW5hbGl6ZShcclxuICAgICAgICBwcmltaXRpdmVNYW5hZ2VyOiBQcmltaXRpdmVNYW5hZ2VyXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICAvLyBASU1QT1JUQU5UOiBSZXBsYWNlIC5vYnNlcnZlcnMubGVuZ3RoID09PSAxIHdpdGggLm9ic2VydmVkIGluIHJ4anMgNy4wK1xyXG4gICAgICAgIGNvbnN0IGhhc09ic2VydmVycyA9ICEocHJpbWl0aXZlTWFuYWdlci5ldmVudCQub2JzZXJ2ZXJzLmxlbmd0aCA9PT0gMSk7XHJcblxyXG4gICAgICAgIGlmIChoYXNPYnNlcnZlcnMpIHJldHVybjtcclxuXHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5ldmVudCQuY29tcGxldGUoKTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBzdG9tcFN1YnNjcmlwdGlvbiBvZiBwcmltaXRpdmVNYW5hZ2VyLnN0b21wU3Vic2NyaXB0aW9ucykge1xyXG4gICAgICAgICAgICBzdG9tcFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdWJzY3JpYmVkJC5jb21wbGV0ZSgpO1xyXG5cclxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldFByaW1pdGl2ZU1hbmFnZXJLZXkoXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuZG9tYWluLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnNlcnZpY2UsXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHJpbWl0aXZlXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5kZWxldGUoa2V5KTtcclxuXHJcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICBwcml2YXRlIGdldFByaW1pdGl2ZU1hbmFnZXJLZXkoXHJcbiAgICAgICAgZG9tYWluOiBzdHJpbmcsXHJcbiAgICAgICAgc2VydmljZTogc3RyaW5nLFxyXG4gICAgICAgIHByaW1pdGl2ZTogc3RyaW5nXHJcbiAgICApOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiBgJHtkb21haW59LyR7c2VydmljZX0vJHtwcmltaXRpdmV9YDtcclxuICAgIH1cclxufVxyXG4iXX0=
392
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2VuaW9yLWdlc3Rhby1lbXByZXNhcmlhbC9hbmd1bGFyLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL3dlYnNvY2tldC93ZWJzb2NrZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxNQUFNLEVBQTZDLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkYsT0FBTyxFQUFFLGVBQWUsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7O0FBRzVDLElBQU0sK0JBQStCLEdBQUcsSUFBSSxDQUFDO0FBQzdDLElBQU0sK0JBQStCLEdBQUcsSUFBSSxDQUFDO0FBSzdDO0lBY0ksMEJBQTZCLHNCQUE4QztRQUE5QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBYjFELGVBQVUsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUNqRCxrQkFBYSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDcEMsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ25DLFdBQU0sR0FBRyxJQUFJLE9BQU8sRUFBYSxDQUFDO1FBQ2xDLGdCQUFXLEdBQUcsSUFBSSxPQUFPLEVBQXlCLENBQUM7UUFFbkQs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VSxJQUFJLENBQUMsc0JBQXNCLENBQUMsZUFBZSxFQUFFLGtCQUFlLENBQUM7SUFDM0UsQ0FBQzs7Z0JBL1ZvRCxzQkFBc0I7OztJQWRsRSxnQkFBZ0I7UUFINUIsVUFBVSxDQUFDO1lBQ1IsVUFBVSxFQUFFLE1BQU07U0FDckIsQ0FBQztPQUNXLGdCQUFnQixDQThXNUI7MkJBOVhEO0NBOFhDLEFBOVdELElBOFdDO1NBOVdZLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZmlsdGVyLCBmaW5hbGl6ZSwgbWFwLCBzd2l0Y2hNYXAsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IENsaWVudCwgRnJhbWVJbXBsLCBTdG9tcENvbmZpZywgU3RvbXBTdWJzY3JpcHRpb24gfSBmcm9tICdAc3RvbXAvc3RvbXBqcyc7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgKiBhcyBTb2NrSlMgZnJvbSAnc29ja2pzLWNsaWVudCc7XHJcbmltcG9ydCB7IEFzeW5jTG9jayB9IGZyb20gJy4uL3V0aWxzL2FzeW5jLWxvY2snO1xyXG5pbXBvcnQgeyBVc2VySW5mb3JtYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi91c2VyLWluZm9ybWF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQcmltaXRpdmVNYW5hZ2VyIH0gZnJvbSAnLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBPbkV2ZW50T3B0aW9ucywgUHJpbWl0aXZlRXZlbnQgfSBmcm9tICcuL3Byb3RvY29scyc7XHJcblxyXG5jb25zdCBSRUNPTk5FQ1RfSU5URVJWQUxfTUlMTElTRUNPTkRTID0gMzAwMDtcclxuY29uc3QgQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EUyA9IDUwMDA7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFdlYnNvY2tldFNlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0ZWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWNvbm5lY3RlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBlcnJvciQgPSBuZXcgU3ViamVjdDxGcmFtZUltcGw+KCk7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmliZWQkID0gbmV3IFN1YmplY3Q8UHJpbWl0aXZlTWFuYWdlcjxhbnk+PigpO1xyXG5cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbWl0aXZlTWFuYWdlcnM6IE1hcDxzdHJpbmcsIFByaW1pdGl2ZU1hbmFnZXI8YW55Pj4gPSBuZXcgTWFwPHN0cmluZywgUHJpbWl0aXZlTWFuYWdlcjxhbnk+PigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0aW9uTG9jayA9IG5ldyBBc3luY0xvY2soKTtcclxuXHJcbiAgICBwcml2YXRlIHN0b21wQ2xpZW50OiBDbGllbnQ7XHJcbiAgICBwcml2YXRlIGRlYnVnRW5hYmxlID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGxvc3RDb25uZWN0aW9uID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB1c2VySW5mb3JtYXRpb25TZXJ2aWNlOiBVc2VySW5mb3JtYXRpb25TZXJ2aWNlKSB7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmFibGVzIHN0b21wanMgZGVidWcgbG9ncyBhbmQgYWRkaXRpb25hbCBpbmZvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVEZWJ1Z0xvZ3MoKSB7XHJcbiAgICAgICAgdGhpcy5kZWJ1Z0VuYWJsZSA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYW51YWxseSBzdGFydHMgdGhlIGNvbm5lY3Rpb25cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFzeW5jIGNvbm5lY3QoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5jb25uZWN0aW9uTG9jay5hY3F1aXJlKCk7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkgfHwgdGhpcy5pc0Nvbm5lY3RpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMubG9zdENvbm5lY3Rpb24gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0b21wQ29uZmlnOiBTdG9tcENvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgIHdlYlNvY2tldEZhY3Rvcnk6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNvY2tKUyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTdWJzY3JpcHRpb25VcmwoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dDogQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EU1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uVGltZW91dDogQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EUyxcclxuICAgICAgICAgICAgICAgIHJlY29ubmVjdERlbGF5OiBSRUNPTk5FQ1RfSU5URVJWQUxfTUlMTElTRUNPTkRTLFxyXG4gICAgICAgICAgICAgICAgZGVidWc6IHRoaXMuZGVidWcuYmluZCh0aGlzKSxcclxuICAgICAgICAgICAgICAgIG9uQ29ubmVjdDogdGhpcy5oYW5kbGVPbkNvbm5lY3RlZC5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgb25EaXNjb25uZWN0OiB0aGlzLmhhbmRsZU9uRGlzY29ubmVjdC5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgb25XZWJTb2NrZXRDbG9zZTogdGhpcy5oYW5kbGVPbldlYlNvY2tldENsb3NlLmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgICBvblN0b21wRXJyb3I6IHRoaXMuaGFuZGxlT25TdG9tcEVycm9yLmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgICBvbldlYlNvY2tldEVycm9yOiB0aGlzLmhhbmRsZU9uV2ViU29ja2V0RXJyb3IuYmluZCh0aGlzKVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5kZWJ1ZygnQ29ubmVjdGluZyB0aGUgV2Vic2Nva2V0Jyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN0b21wQ2xpZW50ID0gbmV3IENsaWVudChzdG9tcENvbmZpZyk7XHJcbiAgICAgICAgICAgIHRoaXMuc3RvbXBDbGllbnQuYWN0aXZhdGUoKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbm5lY3Rpb25Mb2NrLnJlbGVhc2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYW51YWxseSBkaXNjb25uZWN0IHRoZSB3ZWJzb2NrZXQuIFRoZSByZWNvbm5lY3QgbG9vcCB3aWxsIGJlIHN0b3BwZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdGlvbkxvY2suYWNxdWlyZSgpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJpbWl0aXZlTWFuYWdlciBvZiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnZhbHVlcygpKSB7XHJcbiAgICAgICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuY2xlYXIoKTtcclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQkLm5leHQoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuc3RvbXBDbGllbnQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RvbXBDbGllbnQuZm9yY2VEaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnN0b21wQ2xpZW50LmRlYWN0aXZhdGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdGlvbkxvY2sucmVsZWFzZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrIGlmIHRoZSB3ZWJzb2NrZXQgaXMgY29ubmVjdGVkXHJcbiAgICAgKiBAcmV0dXJuIGBib29sZWFuYCByZXByZXNlbnRpbmcgaWYgdGhlIHdlYnNvY2tldCBpcyBjb25uZWN0ZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghdGhpcy5zdG9tcENsaWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9tcENsaWVudC5jb25uZWN0ZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVjayBpZiB0aGUgd2Vic29ja2V0IGlzIHRyaW5nIHRvIGNvbm5lY3RcclxuICAgICAqIEByZXR1cm4gYGJvb2xlYW5gIHJlcHJlc2VudGluZyBpZiB0aGUgd2Vic29ja2V0IHN0YXR1c1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaXNDb25uZWN0aW5nKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghdGhpcy5zdG9tcENsaWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gIXRoaXMuc3RvbXBDbGllbnQuY29ubmVjdGVkICYmIHRoaXMuc3RvbXBDbGllbnQuYWN0aXZlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgcmVzcG9uc2FibGUgdG8gZW1pdCBhbiBldmVudCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkLlxyXG4gICAgICogRG8gbm90IGZvcmdldCB0byB1bnN1YnNjcmliZSB0aGUgb2JzZXJ2YWJsZSB3aGVuIHlvdSBkb24ndCBuZWVkIGl0IGFueW1vcmUuXHJcbiAgICAgKiBAcmV0dXJuIGBPYnNlcnZhYmxlPGJvb2xlYW4+YFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Db25uZWN0KCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RlZCQuYXNPYnNlcnZhYmxlKClcclxuICAgICAgICAgICAgLnBpcGUoZmlsdGVyKHAgPT4gcCA9PT0gdHJ1ZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgcmVzcG9uc2FibGUgdG8gZW1pdCBhbiBldmVudCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGNsb3NlZC5cclxuICAgICAqIERvIG5vdCBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgdGhlIG9ic2VydmFibGUgd2hlbiB5b3UgZG9uJ3QgbmVlZCBpdCBhbnltb3JlLlxyXG4gICAgICogQHJldHVybiBgT2JzZXJ2YWJsZTx2b2lkPmBcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRGlzY29ubmVjdCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kaXNjb25uZWN0ZWQkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgcmVzcG9uc2FibGUgdG8gZW1pdCBhbiBldmVudCB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIHJlZXN0YWJsaXNoZWQuXHJcbiAgICAgKiBEbyBub3QgZm9yZ2V0IHRvIHVuc3Vic2NyaWJlIHRoZSBvYnNlcnZhYmxlIHdoZW4geW91IGRvbid0IG5lZWQgaXQgYW55bW9yZS5cclxuICAgICAqIEByZXR1cm4gYE9ic2VydmFibGU8dm9pZD5gXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvblJlY29ubmVjdCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZWNvbm5lY3RlZCQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCByZXNwb25zYWJsZSB0byBlbWl0IGFuIGV2ZW50IHdoZW4gYW4gZXJyb3Igb2N1cnJlZC5cclxuICAgICAqIERvIG5vdCBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgdGhlIG9ic2VydmFibGUgd2hlbiB5b3UgZG9uJ3QgbmVlZCBpdCBhbnltb3JlLlxyXG4gICAgICogQHJldHVybiBgT2JzZXJ2YWJsZTxGcmFtZUltcGw+YFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25FcnJvcigpOiBPYnNlcnZhYmxlPEZyYW1lSW1wbD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yJC5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEV2ZW50IHJlc3BvbnNpYmxlIHRvIGVtaXQgYW4gZXZlbnQgd2hlbiBhIHByaW1pdGl2ZSBpcyBjYWxsZWQuXHJcbiAgICAgKiBEbyBub3QgZm9yZ2V0IHRvIHVuc3Vic2NyaWJlIHRoZSBvYnNlcnZhYmxlIHdoZW4geW91IGRvbid0IG5lZWQgaXQgYW55bW9yZS5cclxuICAgICAqIEB0eXBlUGFyYW0gYDxUPmAgT2JqZWN0IHR5cGUgdGhhdCB3aWxsIGJlIHVzZWQgaW4gdGhlIG9ic2VydmFibGUgZm9yIHRoZSBgZGF0YWAgcHJvcGVydHkuXHJcbiAgICAgKiBAcGFyYW0ge09uRXZlbnRPcHRpb25zfSBvcHRpb25zIENvbmZpZ3VyYXRpb25zIGZvciB0aGUgZXZlbnQuXHJcbiAgICAgKiBAcmV0dXJuIGBPYnNlcnZhYmxlPFByaW1pdGl2ZUV2ZW50PFQ+PmAgT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIHNlcnZpY2UgY2FsbHMgdGhlIHByaW1pdGl2ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRXZlbnQ8VD4ob3B0aW9uczogT25FdmVudE9wdGlvbnMpOiBPYnNlcnZhYmxlPFByaW1pdGl2ZUV2ZW50PFQ+PiB7XHJcbiAgICAgICAgY29uc3QgeyBkb21haW4sIHNlcnZpY2UsIHByaW1pdGl2ZSB9ID0gb3B0aW9ucztcclxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkUHJpbWl0aXZlTWFuYWdlcktleShkb21haW4sIHNlcnZpY2UsIHByaW1pdGl2ZSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmhhcyhrZXkpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmdldChrZXkpLmdldEV2ZW50T2JzZXJ2YWJsZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJpbWl0aXZlTWFuYWdlciA9IG5ldyBQcmltaXRpdmVNYW5hZ2VyPFQ+KGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlKTtcclxuICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnNldChrZXksIHByaW1pdGl2ZU1hbmFnZXIpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5vbkNvbm5lY3QoKVxyXG4gICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb25zKHByaW1pdGl2ZU1hbmFnZXIpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBwcmltaXRpdmVNYW5hZ2VyXHJcbiAgICAgICAgICAgIC5nZXRFdmVudE9ic2VydmFibGUoKVxyXG4gICAgICAgICAgICAucGlwZShmaW5hbGl6ZSgoKSA9PiB0aGlzLnVuc3Vic2NyaWJlUHJpbWl0aXZlT25GaW5hbGl6ZShwcmltaXRpdmVNYW5hZ2VyKSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgcmVzcG9uc2libGUgdG8gZW1pdCBhbiBldmVudCB3aGVuIGEgc3Vic2NyaXB0aW9uIGlzIGNyZWF0ZWQgZm9yIHRoZSBwcmltaXRpdmUuXHJcbiAgICAgKiBEbyBub3QgZm9yZ2V0IHRvIHVuc3Vic2NyaWJlIHRoZSBvYnNlcnZhYmxlIHdoZW4geW91IGRvbid0IG5lZWQgaXQgYW55bW9yZS5cclxuICAgICAqIEBwYXJhbSB7T25FdmVudE9wdGlvbnN9IG9wdGlvbnMgQ29uZmlndXJhdGlvbnMgZm9yIHRoZSBldmVudC5cclxuICAgICAqIE9ic2VydmFibGUgcmVzcG9uc8OhdmVsIHBvciBlbWl0aXIgdW1hIG5vdGlmaWNhw6fDo28gYXDDs3MgbyBzdWJzY3JpYmUgZG8gZXZlbnRvIHBlbGEgcHJpbWVpcmEgdmV6LlxyXG4gICAgICogQHJldHVybiBgT2JzZXJ2YWJsZTxib29sZWFuPmAgT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIHNlcnZpY2UgY2FsbHMgdGhlIHByaW1pdGl2ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uU3Vic2NyaWJlKG9wdGlvbnM6IE9uRXZlbnRPcHRpb25zKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICAgICAgY29uc3QgeyBkb21haW4sIHNlcnZpY2UsIHByaW1pdGl2ZSB9ID0gb3B0aW9ucztcclxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkUHJpbWl0aXZlTWFuYWdlcktleShkb21haW4sIHNlcnZpY2UsIHByaW1pdGl2ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLm9uQ29ubmVjdCgpLnBpcGUoXHJcbiAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcmltaXRpdmVNYW5hZ2Vycy5oYXMoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoa2V5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U3Vic2NyaXB0aW9uT2JzZXJ2YWJsZSgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YnNjcmliZWQkLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKChwcmltaXRpdmVNYW5hZ2VyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJ1aWxkUHJpbWl0aXZlTWFuYWdlcktleShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuZG9tYWluLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zZXJ2aWNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5wcmltaXRpdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgKSA9PT0ga2V5O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB0cnVlKSxcclxuICAgICAgICAgICAgICAgICAgICB0YWtlKDEpXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcsIC4uLm9wdGlvbmFsUGFyYW1zOiBhbnlbXSkge1xyXG4gICAgICAgIGlmICghdGhpcy5kZWJ1Z0VuYWJsZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnNvbGUubG9nKCdXUyBkZWJ1ZzogJyArIG1lc3NhZ2UsIC4uLm9wdGlvbmFsUGFyYW1zKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGluZm8obWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc29sZS5pbmZvKCdXUyBpbmZvOiAnICsgbWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVPbkNvbm5lY3RlZCgpIHtcclxuICAgICAgICB0aGlzLmluZm8oJ1dlYnNjb2tldCBjb25uZWN0ZWQnKTtcclxuXHJcbiAgICAgICAgdGhpcy5jb25uZWN0ZWQkLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgaWYgKHRoaXMubG9zdENvbm5lY3Rpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5pbmZvKCdXZWJzY29rZXQgcmVjb25uZWN0ZWQsIHJlY3JpYXRpbmcgc3Vic2NyaXB0aW9ucycpO1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJlY29ubmVjdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU9uRGlzY29ubmVjdCgpIHtcclxuICAgICAgICB0aGlzLmluZm8oJ1dlYnNjb2tldCBkaXNjb25uZWN0ZWQnKTtcclxuXHJcbiAgICAgICAgdGhpcy5jb25uZWN0ZWQkLm5leHQoZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGVkJC5uZXh0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVPbldlYlNvY2tldENsb3NlKGRhdGE6IENsb3NlRXZlbnQpIHtcclxuICAgICAgICBpZiAoZGF0YS53YXNDbGVhbikge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubG9zdENvbm5lY3Rpb24gPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlT25TdG9tcEVycm9yKGRhdGE6IEZyYW1lSW1wbCkge1xyXG4gICAgICAgIHRoaXMuaGFuZGxlRXJyb3IoJ1N0b21wRXJyb3InLCBkYXRhKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNBdXRoZW50aWNhdGlvbkVycm9yKGRhdGEpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5mbygnQXV0aGVudGljYXRpb24gZXJyb3IsIHJlY3JpYXRpbmcgc3Vic2NyaXB0aW9ucycpO1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJlY29ubmVjdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGlzQXV0aGVudGljYXRpb25FcnJvcihkYXRhOiBGcmFtZUltcGwpIHtcclxuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBkYXRhPy5oZWFkZXJzPy5tZXNzYWdlO1xyXG4gICAgICAgIGlmICghZXJyb3JNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBlcnJvck1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmb3JiaWRkZW5leGNlcHRpb24nKSAhPT0gLTE7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVPbldlYlNvY2tldEVycm9yKGRhdGE6IGFueSkge1xyXG4gICAgICAgIHRoaXMuaGFuZGxlRXJyb3IoJ1dlYlNvY2tldEVycm9yJywgZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVFcnJvcihvcmlnaW46IHN0cmluZywgZGF0YTogRnJhbWVJbXBsKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihvcmlnaW4sIGRhdGEpO1xyXG4gICAgICAgIHRoaXMuZXJyb3IkLm5leHQoZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVSZWNvbm5lY3Rpb24oKSB7XHJcbiAgICAgICAgdGhpcy5sb3N0Q29ubmVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMucmVjb25uZWN0UHJpbWl0aXZlcygpO1xyXG4gICAgICAgIHRoaXMucmVjb25uZWN0ZWQkLm5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlY29ubmVjdFByaW1pdGl2ZXMoKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBwcmltaXRpdmVNYW5hZ2VyIG9mIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMudmFsdWVzKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYnVpbGRTdWJzY3JpcHRpb25VcmxXaXRoVG9rZW4oZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGF1dGhUb2tlbiA9IHRoaXMudXNlckluZm9ybWF0aW9uU2VydmljZS5nZXRBdXRoVG9rZW4oKTtcclxuICAgICAgICBjb25zdCB0ZW5hbnQgPSB0aGlzLnVzZXJJbmZvcm1hdGlvblNlcnZpY2UuZ2V0VGVuYW50RG9tYWluKCk7XHJcbiAgICAgICAgcmV0dXJuIGAvdG9waWMvJHt0ZW5hbnR9LyR7YXV0aFRva2VufS8ke2RvbWFpbn0vJHtzZXJ2aWNlfS8ke3ByaW1pdGl2ZX1gO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0U3Vic2NyaXB0aW9uVXJsV2l0aG91dFRva2VuKGRvbWFpbjogc3RyaW5nLCBzZXJ2aWNlOiBzdHJpbmcsIHByaW1pdGl2ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCB0ZW5hbnQgPSB0aGlzLnVzZXJJbmZvcm1hdGlvblNlcnZpY2UuZ2V0VGVuYW50RG9tYWluKCk7XHJcbiAgICAgICAgcmV0dXJuIGAvdG9waWMvJHt0ZW5hbnR9LyR7ZG9tYWlufS8ke3NlcnZpY2V9LyR7cHJpbWl0aXZlfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBidWlsZFByaW1pdGl2ZU1hbmFnZXJLZXkoZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiBgJHtkb21haW59LyR7c2VydmljZX0vJHtwcmltaXRpdmV9YDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIHVuc3Vic2NyaWJlUHJpbWl0aXZlT25GaW5hbGl6ZShwcmltaXRpdmVNYW5hZ2VyOiBQcmltaXRpdmVNYW5hZ2VyPGFueT4pIHtcclxuICAgICAgICBpZiAocHJpbWl0aXZlTWFuYWdlci5oYXNPYnNlcnZlcnMoKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnVuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuYnVpbGRQcmltaXRpdmVNYW5hZ2VyS2V5KHByaW1pdGl2ZU1hbmFnZXIuZG9tYWluLCBwcmltaXRpdmVNYW5hZ2VyLnNlcnZpY2UsIHByaW1pdGl2ZU1hbmFnZXIucHJpbWl0aXZlKTtcclxuICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmRlbGV0ZShrZXkpO1xyXG5cclxuICAgICAgICBhd2FpdCB0aGlzLmRpc2Nvbm5lY3RJZk5vTW9yZU9ic2VydmFibGVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBkaXNjb25uZWN0SWZOb01vcmVPYnNlcnZhYmxlcygpIHtcclxuICAgICAgICBpZiAodGhpcy5nZXRPYnNlcnZlcnNDb3VudCgpID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGVidWcoJ01hbnVhbGx5IGRpc2Nvbm5lY3RpbmcgYmVjYXVzZSB0aGVyZSBhcmUgbm8gbW9yZSBvYnNlcnZlcnMnKTtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0T2JzZXJ2ZXJzQ291bnQoKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgb2JzZXJ2ZXJzQ291bnQgPSAwO1xyXG5cclxuICAgICAgICB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmZvckVhY2gocHJpbWl0aXZlTWFuYWdlciA9PiB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyc0NvdW50ICs9IHByaW1pdGl2ZU1hbmFnZXIuZ2V0T2JzZXJ2ZXJzQ291bnQoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmVyc0NvdW50O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlU3RvbXBTdWJzY3JpcHRpb248VD4oZGVzdGluYXRpb246IHN0cmluZywgcHJpbWl0aXZlTWFuYWdlcjogUHJpbWl0aXZlTWFuYWdlcjxUPik6IFN0b21wU3Vic2NyaXB0aW9uIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9tcENsaWVudC5zdWJzY3JpYmUoZGVzdGluYXRpb24sIChtZXNzYWdlOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBKU09OLnBhcnNlKG1lc3NhZ2UuYm9keSB8fCAne30nKTtcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5maXJlRXZlbnQoZXZlbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlU3RvbXBTdWJzY3JpcHRpb25zPFQ+KHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXI8VD4pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb25VcmxXaXRoVG9rZW4gPSB0aGlzLmJ1aWxkU3Vic2NyaXB0aW9uVXJsV2l0aFRva2VuKFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLmRvbWFpbixcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zZXJ2aWNlLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnByaW1pdGl2ZVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uVXJsV2l0aG91dFRva2VuID0gdGhpcy5nZXRTdWJzY3JpcHRpb25VcmxXaXRob3V0VG9rZW4oXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuZG9tYWluLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnNlcnZpY2UsXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHJpbWl0aXZlXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgY29uc3Qgc3RvbXBTdWJzY3JpcHRpb25XaXRoVG9rZW4gPSB0aGlzLmNyZWF0ZVN0b21wU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvblVybFdpdGhUb2tlbiwgcHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgY29uc3Qgc3RvbXBTdWJzY3JpcHRpb25XaXRob3V0VG9rZW4gPSB0aGlzLmNyZWF0ZVN0b21wU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvblVybFdpdGhvdXRUb2tlbiwgcHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5zdWJzY3JpYmUoc3RvbXBTdWJzY3JpcHRpb25XaXRoVG9rZW4sIHN0b21wU3Vic2NyaXB0aW9uV2l0aG91dFRva2VuKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZWQkLm5leHQocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRTdWJzY3JpcHRpb25VcmwoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMudXNlckluZm9ybWF0aW9uU2VydmljZS5nZXRXZWJTb2NrZXRVcmwoKX0vc3Vic2NyaXB0aW9uYDtcclxuICAgIH1cclxufVxyXG4iXX0=