@senior-gestao-empresarial/angular-components 6.11.5 → 6.12.0-67d9099d-c888-4b61-a14e-4c7c373707d6

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 +513 -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 +259 -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 +317 -256
  42. package/esm5/senior-gestao-empresarial-angular-components.js +4 -2
  43. package/fesm2015/senior-gestao-empresarial-angular-components.js +417 -193
  44. package/fesm2015/senior-gestao-empresarial-angular-components.js.map +1 -1
  45. package/fesm5/senior-gestao-empresarial-angular-components.js +509 -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,386 @@
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
+ return [4 /*yield*/, this.stompClient.deactivate()];
116
+ case 3:
117
+ _d.sent();
118
+ _d.label = 4;
119
+ case 4: return [3 /*break*/, 7];
120
+ case 5: return [4 /*yield*/, this.connectionLock.release()];
121
+ case 6:
122
+ _d.sent();
123
+ return [7 /*endfinally*/];
124
+ case 7: return [2 /*return*/];
125
+ }
126
+ });
127
+ });
50
128
  };
51
129
  /**
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.
130
+ * Check if the websocket is connected
131
+ * @return `boolean` representing if the websocket is connected
54
132
  */
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
- }));
133
+ WebsocketService.prototype.isConnected = function () {
134
+ if (!this.stompClient) {
135
+ return false;
136
+ }
137
+ return this.stompClient.connected;
138
+ };
139
+ /**
140
+ * Check if the websocket is tring to connect
141
+ * @return `boolean` representing if the websocket status
142
+ */
143
+ WebsocketService.prototype.isConnecting = function () {
144
+ if (!this.stompClient) {
145
+ return false;
146
+ }
147
+ return !this.stompClient.connected && this.stompClient.active;
148
+ };
149
+ /**
150
+ * Event responsable to emit an event when the connection is established.
151
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
152
+ * @return `Observable<boolean>`
153
+ */
154
+ WebsocketService.prototype.onConnect = function () {
155
+ return this.connected$.asObservable()
156
+ .pipe(filter(function (p) { return p === true; }));
157
+ };
158
+ /**
159
+ * Event responsable to emit an event when the connection is closed.
160
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
161
+ * @return `Observable<void>`
162
+ */
163
+ WebsocketService.prototype.onDisconnect = function () {
164
+ return this.disconnected$.asObservable();
69
165
  };
70
166
  /**
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.
167
+ * Event responsable to emit an event when the connection is reestablished.
168
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
169
+ * @return `Observable<void>`
170
+ */
171
+ WebsocketService.prototype.onReconnect = function () {
172
+ return this.reconnected$.asObservable();
173
+ };
174
+ /**
175
+ * Event responsable to emit an event when an error ocurred.
176
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
177
+ * @return `Observable<FrameImpl>`
73
178
  */
74
179
  WebsocketService.prototype.onError = function () {
75
180
  return this.error$.asObservable();
76
181
  };
77
182
  /**
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.
183
+ * Event responsible to emit an event when a primitive is called.
184
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
185
+ * @typeParam `<T>` Object type that will be used in the observable for the `data` property.
186
+ * @param {OnEventOptions} options Configurations for the event.
187
+ * @return `Observable<PrimitiveEvent<T>>` Observable that emits an event when the service calls the primitive.
84
188
  */
85
189
  WebsocketService.prototype.onEvent = function (options) {
86
190
  var _this = this;
87
- this.connect();
88
191
  var domain = options.domain, service = options.service, primitive = options.primitive;
89
- var key = this.getPrimitiveManagerKey(domain, service, primitive);
192
+ var key = this.buildPrimitiveManagerKey(domain, service, primitive);
90
193
  if (this.primitiveManagers.has(key)) {
91
- return this.primitiveManagers.get(key).event$.asObservable();
194
+ return this.primitiveManagers.get(key).getEventObservable();
92
195
  }
93
- var primitiveManager = {
94
- domain: domain,
95
- service: service,
96
- primitive: primitive,
97
- stompSubscriptions: [],
98
- event$: new Subject(),
99
- subscribed$: new BehaviorSubject(false)
100
- };
196
+ var primitiveManager = new PrimitiveManager(domain, service, primitive);
101
197
  this.primitiveManagers.set(key, primitiveManager);
102
- this.onConnect()
103
- .pipe(take(1))
104
- .subscribe(function () {
105
- _this.createStompSubscriptions(primitiveManager);
198
+ this.connect().then(function () {
199
+ _this.onConnect()
200
+ .pipe(take(1))
201
+ .subscribe(function () {
202
+ _this.createStompSubscriptions(primitiveManager);
203
+ });
106
204
  });
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);
205
+ return primitiveManager
206
+ .getEventObservable()
207
+ .pipe(finalize(function () { return _this.unsubscribePrimitiveOnFinalize(primitiveManager); }));
123
208
  };
124
- /** @private */
125
- WebsocketService.prototype.connect = function () {
209
+ /**
210
+ * Event responsible to emit an event when a subscription is created for the primitive.
211
+ * Do not forget to unsubscribe the observable when you don't need it anymore.
212
+ * @param {OnEventOptions} options Configurations for the event.
213
+ * Observable responsável por emitir uma notificação após o subscribe do evento pela primeira vez.
214
+ * @return `Observable<boolean>` Observable that emits an event when the service calls the primitive.
215
+ */
216
+ WebsocketService.prototype.onSubscribe = function (options) {
126
217
  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);
218
+ var domain = options.domain, service = options.service, primitive = options.primitive;
219
+ var key = this.buildPrimitiveManagerKey(domain, service, primitive);
220
+ return this.onConnect().pipe(take(1), switchMap(function () {
221
+ if (_this.primitiveManagers.has(key)) {
222
+ return _this.primitiveManagers
223
+ .get(key)
224
+ .getSubscriptionObservable()
225
+ .pipe(take(1));
142
226
  }
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
- });
227
+ return _this.subscribed$.asObservable().pipe(filter(function (primitiveManager) {
228
+ return _this.buildPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive) === key;
229
+ }), map(function () { return true; }), take(1));
230
+ }));
161
231
  };
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;
232
+ WebsocketService.prototype.debug = function (message) {
233
+ var optionalParams = [];
234
+ for (var _i = 1; _i < arguments.length; _i++) {
235
+ optionalParams[_i - 1] = arguments[_i];
166
236
  }
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
- }
237
+ if (!this.debugEnable) {
238
+ return;
184
239
  }
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; }
240
+ console.log.apply(console, __spread(['WS debug: ' + message], optionalParams));
241
+ };
242
+ WebsocketService.prototype.info = function (message) {
243
+ console.info('WS info: ' + message);
244
+ };
245
+ WebsocketService.prototype.handleOnConnected = function () {
246
+ this.info('Webscoket connected');
247
+ this.connected$.next(true);
248
+ if (this.lostConnection) {
249
+ this.info('Webscoket reconnected, recriating subscriptions');
250
+ this.handleReconnection();
191
251
  }
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
- }
252
+ };
253
+ WebsocketService.prototype.handleOnDisconnect = function () {
254
+ this.info('Webscoket disconnected');
255
+ this.connected$.next(false);
256
+ this.disconnected$.next();
257
+ };
258
+ WebsocketService.prototype.handleOnWebSocketClose = function (data) {
259
+ if (data.wasClean) {
260
+ return;
197
261
  }
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; }
262
+ this.lostConnection = true;
263
+ };
264
+ WebsocketService.prototype.handleOnStompError = function (data) {
265
+ this.handleError('StompError', data);
266
+ if (this.isAuthenticationError(data)) {
267
+ this.info('Authentication error, recriating subscriptions');
268
+ this.handleReconnection();
204
269
  }
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
270
  };
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;
271
+ WebsocketService.prototype.isAuthenticationError = function (data) {
272
+ var _a;
273
+ var errorMessage = (_a = data === null || data === void 0 ? void 0 : data.headers) === null || _a === void 0 ? void 0 : _a.message;
274
+ if (!errorMessage) {
275
+ return false;
276
+ }
277
+ return errorMessage.toLowerCase().indexOf('forbiddenexception') !== -1;
223
278
  };
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;
279
+ WebsocketService.prototype.handleOnWebSocketError = function (data) {
280
+ this.handleError('WebSocketError', data);
230
281
  };
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
- });
282
+ WebsocketService.prototype.handleError = function (origin, data) {
283
+ console.error(origin, data);
284
+ this.error$.next(data);
237
285
  };
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; };
286
+ WebsocketService.prototype.handleReconnection = function () {
287
+ this.lostConnection = false;
288
+ this.reconnectPrimitives();
289
+ this.reconnected$.next();
243
290
  };
244
- /** @private */
245
291
  WebsocketService.prototype.reconnectPrimitives = function () {
246
- var e_4, _a;
292
+ var e_2, _a;
247
293
  try {
248
294
  for (var _b = __values(this.primitiveManagers.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
249
295
  var primitiveManager = _c.value;
250
296
  this.createStompSubscriptions(primitiveManager);
251
297
  }
252
298
  }
253
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
299
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
254
300
  finally {
255
301
  try {
256
302
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
257
303
  }
258
- finally { if (e_4) throw e_4.error; }
304
+ finally { if (e_2) throw e_2.error; }
259
305
  }
260
306
  };
261
- /** @private */
307
+ WebsocketService.prototype.buildSubscriptionUrlWithToken = function (domain, service, primitive) {
308
+ var authToken = this.userInformationService.getAuthToken();
309
+ var tenant = this.userInformationService.getTenantDomain();
310
+ return "/topic/" + tenant + "/" + authToken + "/" + domain + "/" + service + "/" + primitive;
311
+ };
312
+ WebsocketService.prototype.getSubscriptionUrlWithoutToken = function (domain, service, primitive) {
313
+ var tenant = this.userInformationService.getTenantDomain();
314
+ return "/topic/" + tenant + "/" + domain + "/" + service + "/" + primitive;
315
+ };
316
+ WebsocketService.prototype.buildPrimitiveManagerKey = function (domain, service, primitive) {
317
+ return domain + "/" + service + "/" + primitive;
318
+ };
319
+ WebsocketService.prototype.unsubscribePrimitiveOnFinalize = function (primitiveManager) {
320
+ return __awaiter(this, void 0, void 0, function () {
321
+ var key;
322
+ return __generator(this, function (_a) {
323
+ switch (_a.label) {
324
+ case 0:
325
+ if (primitiveManager.hasObservers()) {
326
+ return [2 /*return*/];
327
+ }
328
+ primitiveManager.unsubscribe();
329
+ key = this.buildPrimitiveManagerKey(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
330
+ this.primitiveManagers.delete(key);
331
+ return [4 /*yield*/, this.disconnectIfNoMoreObservables()];
332
+ case 1:
333
+ _a.sent();
334
+ return [2 /*return*/];
335
+ }
336
+ });
337
+ });
338
+ };
339
+ WebsocketService.prototype.disconnectIfNoMoreObservables = function () {
340
+ return __awaiter(this, void 0, void 0, function () {
341
+ return __generator(this, function (_a) {
342
+ switch (_a.label) {
343
+ case 0:
344
+ if (!(this.getObserversCount() === 0)) return [3 /*break*/, 2];
345
+ this.debug('Manually disconnecting because there are no more observers');
346
+ return [4 /*yield*/, this.disconnect()];
347
+ case 1:
348
+ _a.sent();
349
+ _a.label = 2;
350
+ case 2: return [2 /*return*/];
351
+ }
352
+ });
353
+ });
354
+ };
262
355
  WebsocketService.prototype.getObserversCount = function () {
263
- var e_5, _a;
264
356
  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
- }
357
+ this.primitiveManagers.forEach(function (primitiveManager) {
358
+ observersCount += primitiveManager.getObserversCount();
359
+ });
278
360
  return observersCount;
279
361
  };
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();
362
+ WebsocketService.prototype.createStompSubscription = function (destination, primitiveManager) {
363
+ return this.stompClient.subscribe(destination, function (message) {
364
+ var event = JSON.parse(message.body || '{}');
365
+ primitiveManager.fireEvent(event);
366
+ });
305
367
  };
306
- /** @private */
307
- WebsocketService.prototype.getPrimitiveManagerKey = function (domain, service, primitive) {
308
- return domain + "/" + service + "/" + primitive;
368
+ WebsocketService.prototype.createStompSubscriptions = function (primitiveManager) {
369
+ var subscriptionUrlWithToken = this.buildSubscriptionUrlWithToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
370
+ var subscriptionUrlWithoutToken = this.getSubscriptionUrlWithoutToken(primitiveManager.domain, primitiveManager.service, primitiveManager.primitive);
371
+ var stompSubscriptionWithToken = this.createStompSubscription(subscriptionUrlWithToken, primitiveManager);
372
+ var stompSubscriptionWithoutToken = this.createStompSubscription(subscriptionUrlWithoutToken, primitiveManager);
373
+ primitiveManager.subscribe(stompSubscriptionWithToken, stompSubscriptionWithoutToken);
374
+ this.subscribed$.next(primitiveManager);
375
+ };
376
+ WebsocketService.prototype.getSubscriptionUrl = function () {
377
+ return this.userInformationService.getWebSocketUrl() + "/subscription";
309
378
  };
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([
379
+ WebsocketService.ctorParameters = function () { return [
380
+ { type: UserInformationService }
381
+ ]; };
382
+ WebsocketService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebsocketService_Factory() { return new WebsocketService(i0.ɵɵinject(i1.UserInformationService)); }, token: WebsocketService, providedIn: "root" });
383
+ WebsocketService = __decorate([
323
384
  Injectable({
324
385
  providedIn: 'root'
325
386
  })
@@ -327,4 +388,4 @@ var WebsocketService = /** @class */ (function () {
327
388
  return WebsocketService;
328
389
  }());
329
390
  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=
391
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2VuaW9yLWdlc3Rhby1lbXByZXNhcmlhbC9hbmd1bGFyLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL3dlYnNvY2tldC93ZWJzb2NrZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxNQUFNLEVBQTZDLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkYsT0FBTyxFQUFFLGVBQWUsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7O0FBRzVDLElBQU0sK0JBQStCLEdBQUcsSUFBSSxDQUFDO0FBQzdDLElBQU0sK0JBQStCLEdBQUcsSUFBSSxDQUFDO0FBSzdDO0lBY0ksMEJBQTZCLHNCQUE4QztRQUE5QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBYjFELGVBQVUsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUNqRCxrQkFBYSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDcEMsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ25DLFdBQU0sR0FBRyxJQUFJLE9BQU8sRUFBYSxDQUFDO1FBQ2xDLGdCQUFXLEdBQUcsSUFBSSxPQUFPLEVBQXlCLENBQUM7UUFFbkQs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QUM7SUFDM0UsQ0FBQzs7Z0JBOVZvRCxzQkFBc0I7OztJQWRsRSxnQkFBZ0I7UUFINUIsVUFBVSxDQUFDO1lBQ1IsVUFBVSxFQUFFLE1BQU07U0FDckIsQ0FBQztPQUNXLGdCQUFnQixDQTZXNUI7MkJBN1hEO0NBNlhDLEFBN1dELElBNldDO1NBN1dZLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZmlsdGVyLCBmaW5hbGl6ZSwgbWFwLCBzd2l0Y2hNYXAsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IENsaWVudCwgRnJhbWVJbXBsLCBTdG9tcENvbmZpZywgU3RvbXBTdWJzY3JpcHRpb24gfSBmcm9tICdAc3RvbXAvc3RvbXBqcyc7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgKiBhcyBTb2NrSlMgZnJvbSAnc29ja2pzLWNsaWVudCc7XHJcbmltcG9ydCB7IEFzeW5jTG9jayB9IGZyb20gJy4uL3V0aWxzL2FzeW5jLWxvY2snO1xyXG5pbXBvcnQgeyBVc2VySW5mb3JtYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi91c2VyLWluZm9ybWF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQcmltaXRpdmVNYW5hZ2VyIH0gZnJvbSAnLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBPbkV2ZW50T3B0aW9ucywgUHJpbWl0aXZlRXZlbnQgfSBmcm9tICcuL3Byb3RvY29scyc7XHJcblxyXG5jb25zdCBSRUNPTk5FQ1RfSU5URVJWQUxfTUlMTElTRUNPTkRTID0gMzAwMDtcclxuY29uc3QgQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EUyA9IDUwMDA7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFdlYnNvY2tldFNlcnZpY2Uge1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0ZWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWNvbm5lY3RlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBlcnJvciQgPSBuZXcgU3ViamVjdDxGcmFtZUltcGw+KCk7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmliZWQkID0gbmV3IFN1YmplY3Q8UHJpbWl0aXZlTWFuYWdlcjxhbnk+PigpO1xyXG5cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbWl0aXZlTWFuYWdlcnM6IE1hcDxzdHJpbmcsIFByaW1pdGl2ZU1hbmFnZXI8YW55Pj4gPSBuZXcgTWFwPHN0cmluZywgUHJpbWl0aXZlTWFuYWdlcjxhbnk+PigpO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0aW9uTG9jayA9IG5ldyBBc3luY0xvY2soKTtcclxuXHJcbiAgICBwcml2YXRlIHN0b21wQ2xpZW50OiBDbGllbnQ7XHJcbiAgICBwcml2YXRlIGRlYnVnRW5hYmxlID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGxvc3RDb25uZWN0aW9uID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB1c2VySW5mb3JtYXRpb25TZXJ2aWNlOiBVc2VySW5mb3JtYXRpb25TZXJ2aWNlKSB7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmFibGVzIHN0b21wanMgZGVidWcgbG9ncyBhbmQgYWRkaXRpb25hbCBpbmZvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVEZWJ1Z0xvZ3MoKSB7XHJcbiAgICAgICAgdGhpcy5kZWJ1Z0VuYWJsZSA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYW51YWxseSBzdGFydHMgdGhlIGNvbm5lY3Rpb25cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFzeW5jIGNvbm5lY3QoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5jb25uZWN0aW9uTG9jay5hY3F1aXJlKCk7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkgfHwgdGhpcy5pc0Nvbm5lY3RpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMubG9zdENvbm5lY3Rpb24gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0b21wQ29uZmlnOiBTdG9tcENvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgIHdlYlNvY2tldEZhY3Rvcnk6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNvY2tKUyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTdWJzY3JpcHRpb25VcmwoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dDogQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EU1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uVGltZW91dDogQ09OTkVDVElPTl9USU1FT1VUX01JTExJU0VDT05EUyxcclxuICAgICAgICAgICAgICAgIHJlY29ubmVjdERlbGF5OiBSRUNPTk5FQ1RfSU5URVJWQUxfTUlMTElTRUNPTkRTLFxyXG4gICAgICAgICAgICAgICAgZGVidWc6IHRoaXMuZGVidWcuYmluZCh0aGlzKSxcclxuICAgICAgICAgICAgICAgIG9uQ29ubmVjdDogdGhpcy5oYW5kbGVPbkNvbm5lY3RlZC5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgb25EaXNjb25uZWN0OiB0aGlzLmhhbmRsZU9uRGlzY29ubmVjdC5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgb25XZWJTb2NrZXRDbG9zZTogdGhpcy5oYW5kbGVPbldlYlNvY2tldENsb3NlLmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgICBvblN0b21wRXJyb3I6IHRoaXMuaGFuZGxlT25TdG9tcEVycm9yLmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgICBvbldlYlNvY2tldEVycm9yOiB0aGlzLmhhbmRsZU9uV2ViU29ja2V0RXJyb3IuYmluZCh0aGlzKVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5kZWJ1ZygnQ29ubmVjdGluZyB0aGUgV2Vic2Nva2V0Jyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN0b21wQ2xpZW50ID0gbmV3IENsaWVudChzdG9tcENvbmZpZyk7XHJcbiAgICAgICAgICAgIHRoaXMuc3RvbXBDbGllbnQuYWN0aXZhdGUoKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbm5lY3Rpb25Mb2NrLnJlbGVhc2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYW51YWxseSBkaXNjb25uZWN0IHRoZSB3ZWJzb2NrZXQuIFRoZSByZWNvbm5lY3QgbG9vcCB3aWxsIGJlIHN0b3BwZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdGlvbkxvY2suYWNxdWlyZSgpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJpbWl0aXZlTWFuYWdlciBvZiB0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLnZhbHVlcygpKSB7XHJcbiAgICAgICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuY2xlYXIoKTtcclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQkLm5leHQoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuc3RvbXBDbGllbnQpIHtcclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc3RvbXBDbGllbnQuZGVhY3RpdmF0ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb25uZWN0aW9uTG9jay5yZWxlYXNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2sgaWYgdGhlIHdlYnNvY2tldCBpcyBjb25uZWN0ZWRcclxuICAgICAqIEByZXR1cm4gYGJvb2xlYW5gIHJlcHJlc2VudGluZyBpZiB0aGUgd2Vic29ja2V0IGlzIGNvbm5lY3RlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnN0b21wQ2xpZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnN0b21wQ2xpZW50LmNvbm5lY3RlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrIGlmIHRoZSB3ZWJzb2NrZXQgaXMgdHJpbmcgdG8gY29ubmVjdFxyXG4gICAgICogQHJldHVybiBgYm9vbGVhbmAgcmVwcmVzZW50aW5nIGlmIHRoZSB3ZWJzb2NrZXQgc3RhdHVzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpc0Nvbm5lY3RpbmcoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnN0b21wQ2xpZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiAhdGhpcy5zdG9tcENsaWVudC5jb25uZWN0ZWQgJiYgdGhpcy5zdG9tcENsaWVudC5hY3RpdmU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCByZXNwb25zYWJsZSB0byBlbWl0IGFuIGV2ZW50IHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQuXHJcbiAgICAgKiBEbyBub3QgZm9yZ2V0IHRvIHVuc3Vic2NyaWJlIHRoZSBvYnNlcnZhYmxlIHdoZW4geW91IGRvbid0IG5lZWQgaXQgYW55bW9yZS5cclxuICAgICAqIEByZXR1cm4gYE9ic2VydmFibGU8Ym9vbGVhbj5gXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkNvbm5lY3QoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGVkJC5hc09ic2VydmFibGUoKVxyXG4gICAgICAgICAgICAucGlwZShmaWx0ZXIocCA9PiBwID09PSB0cnVlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCByZXNwb25zYWJsZSB0byBlbWl0IGFuIGV2ZW50IHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkLlxyXG4gICAgICogRG8gbm90IGZvcmdldCB0byB1bnN1YnNjcmliZSB0aGUgb2JzZXJ2YWJsZSB3aGVuIHlvdSBkb24ndCBuZWVkIGl0IGFueW1vcmUuXHJcbiAgICAgKiBAcmV0dXJuIGBPYnNlcnZhYmxlPHZvaWQ+YFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25EaXNjb25uZWN0KCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRpc2Nvbm5lY3RlZCQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCByZXNwb25zYWJsZSB0byBlbWl0IGFuIGV2ZW50IHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgcmVlc3RhYmxpc2hlZC5cclxuICAgICAqIERvIG5vdCBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgdGhlIG9ic2VydmFibGUgd2hlbiB5b3UgZG9uJ3QgbmVlZCBpdCBhbnltb3JlLlxyXG4gICAgICogQHJldHVybiBgT2JzZXJ2YWJsZTx2b2lkPmBcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uUmVjb25uZWN0KCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlY29ubmVjdGVkJC5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEV2ZW50IHJlc3BvbnNhYmxlIHRvIGVtaXQgYW4gZXZlbnQgd2hlbiBhbiBlcnJvciBvY3VycmVkLlxyXG4gICAgICogRG8gbm90IGZvcmdldCB0byB1bnN1YnNjcmliZSB0aGUgb2JzZXJ2YWJsZSB3aGVuIHlvdSBkb24ndCBuZWVkIGl0IGFueW1vcmUuXHJcbiAgICAgKiBAcmV0dXJuIGBPYnNlcnZhYmxlPEZyYW1lSW1wbD5gXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkVycm9yKCk6IE9ic2VydmFibGU8RnJhbWVJbXBsPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3IkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgcmVzcG9uc2libGUgdG8gZW1pdCBhbiBldmVudCB3aGVuIGEgcHJpbWl0aXZlIGlzIGNhbGxlZC5cclxuICAgICAqIERvIG5vdCBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgdGhlIG9ic2VydmFibGUgd2hlbiB5b3UgZG9uJ3QgbmVlZCBpdCBhbnltb3JlLlxyXG4gICAgICogQHR5cGVQYXJhbSBgPFQ+YCBPYmplY3QgdHlwZSB0aGF0IHdpbGwgYmUgdXNlZCBpbiB0aGUgb2JzZXJ2YWJsZSBmb3IgdGhlIGBkYXRhYCBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSB7T25FdmVudE9wdGlvbnN9IG9wdGlvbnMgQ29uZmlndXJhdGlvbnMgZm9yIHRoZSBldmVudC5cclxuICAgICAqIEByZXR1cm4gYE9ic2VydmFibGU8UHJpbWl0aXZlRXZlbnQ8VD4+YCBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgc2VydmljZSBjYWxscyB0aGUgcHJpbWl0aXZlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25FdmVudDxUPihvcHRpb25zOiBPbkV2ZW50T3B0aW9ucyk6IE9ic2VydmFibGU8UHJpbWl0aXZlRXZlbnQ8VD4+IHtcclxuICAgICAgICBjb25zdCB7IGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlIH0gPSBvcHRpb25zO1xyXG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuYnVpbGRQcmltaXRpdmVNYW5hZ2VyS2V5KGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuaGFzKGtleSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZ2V0KGtleSkuZ2V0RXZlbnRPYnNlcnZhYmxlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcmltaXRpdmVNYW5hZ2VyID0gbmV3IFByaW1pdGl2ZU1hbmFnZXI8VD4oZG9tYWluLCBzZXJ2aWNlLCBwcmltaXRpdmUpO1xyXG4gICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuc2V0KGtleSwgcHJpbWl0aXZlTWFuYWdlcik7XHJcblxyXG4gICAgICAgIHRoaXMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ29ubmVjdCgpXHJcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxyXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnMocHJpbWl0aXZlTWFuYWdlcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHByaW1pdGl2ZU1hbmFnZXJcclxuICAgICAgICAgICAgLmdldEV2ZW50T2JzZXJ2YWJsZSgpXHJcbiAgICAgICAgICAgIC5waXBlKGZpbmFsaXplKCgpID0+IHRoaXMudW5zdWJzY3JpYmVQcmltaXRpdmVPbkZpbmFsaXplKHByaW1pdGl2ZU1hbmFnZXIpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCByZXNwb25zaWJsZSB0byBlbWl0IGFuIGV2ZW50IHdoZW4gYSBzdWJzY3JpcHRpb24gaXMgY3JlYXRlZCBmb3IgdGhlIHByaW1pdGl2ZS5cclxuICAgICAqIERvIG5vdCBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgdGhlIG9ic2VydmFibGUgd2hlbiB5b3UgZG9uJ3QgbmVlZCBpdCBhbnltb3JlLlxyXG4gICAgICogQHBhcmFtIHtPbkV2ZW50T3B0aW9uc30gb3B0aW9ucyBDb25maWd1cmF0aW9ucyBmb3IgdGhlIGV2ZW50LlxyXG4gICAgICogT2JzZXJ2YWJsZSByZXNwb25zw6F2ZWwgcG9yIGVtaXRpciB1bWEgbm90aWZpY2HDp8OjbyBhcMOzcyBvIHN1YnNjcmliZSBkbyBldmVudG8gcGVsYSBwcmltZWlyYSB2ZXouXHJcbiAgICAgKiBAcmV0dXJuIGBPYnNlcnZhYmxlPGJvb2xlYW4+YCBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgc2VydmljZSBjYWxscyB0aGUgcHJpbWl0aXZlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25TdWJzY3JpYmUob3B0aW9uczogT25FdmVudE9wdGlvbnMpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcclxuICAgICAgICBjb25zdCB7IGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlIH0gPSBvcHRpb25zO1xyXG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuYnVpbGRQcmltaXRpdmVNYW5hZ2VyS2V5KGRvbWFpbiwgc2VydmljZSwgcHJpbWl0aXZlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMub25Db25uZWN0KCkucGlwZShcclxuICAgICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByaW1pdGl2ZU1hbmFnZXJzLmhhcyhrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWl0aXZlTWFuYWdlcnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmdldChrZXkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTdWJzY3JpcHRpb25PYnNlcnZhYmxlKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3Vic2NyaWJlZCQuYXNPYnNlcnZhYmxlKCkucGlwZShcclxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoKHByaW1pdGl2ZU1hbmFnZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRQcmltaXRpdmVNYW5hZ2VyS2V5KFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5kb21haW4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnByaW1pdGl2ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApID09PSBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHRydWUpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRha2UoMSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGRlYnVnKG1lc3NhZ2U6IHN0cmluZywgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmRlYnVnRW5hYmxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS5sb2coJ1dTIGRlYnVnOiAnICsgbWVzc2FnZSwgLi4ub3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5mbyhtZXNzYWdlOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zb2xlLmluZm8oJ1dTIGluZm86ICcgKyBtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU9uQ29ubmVjdGVkKCkge1xyXG4gICAgICAgIHRoaXMuaW5mbygnV2Vic2Nva2V0IGNvbm5lY3RlZCcpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbm5lY3RlZCQubmV4dCh0cnVlKTtcclxuICAgICAgICBpZiAodGhpcy5sb3N0Q29ubmVjdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLmluZm8oJ1dlYnNjb2tldCByZWNvbm5lY3RlZCwgcmVjcmlhdGluZyBzdWJzY3JpcHRpb25zJyk7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmVjb25uZWN0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlT25EaXNjb25uZWN0KCkge1xyXG4gICAgICAgIHRoaXMuaW5mbygnV2Vic2Nva2V0IGRpc2Nvbm5lY3RlZCcpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbm5lY3RlZCQubmV4dChmYWxzZSk7XHJcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0ZWQkLm5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU9uV2ViU29ja2V0Q2xvc2UoZGF0YTogQ2xvc2VFdmVudCkge1xyXG4gICAgICAgIGlmIChkYXRhLndhc0NsZWFuKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5sb3N0Q29ubmVjdGlvbiA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVPblN0b21wRXJyb3IoZGF0YTogRnJhbWVJbXBsKSB7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVFcnJvcignU3RvbXBFcnJvcicsIGRhdGEpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc0F1dGhlbnRpY2F0aW9uRXJyb3IoZGF0YSkpIHtcclxuICAgICAgICAgICAgdGhpcy5pbmZvKCdBdXRoZW50aWNhdGlvbiBlcnJvciwgcmVjcmlhdGluZyBzdWJzY3JpcHRpb25zJyk7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmVjb25uZWN0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNBdXRoZW50aWNhdGlvbkVycm9yKGRhdGE6IEZyYW1lSW1wbCkge1xyXG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGRhdGE/LmhlYWRlcnM/Lm1lc3NhZ2U7XHJcbiAgICAgICAgaWYgKCFlcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGVycm9yTWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ2ZvcmJpZGRlbmV4Y2VwdGlvbicpICE9PSAtMTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU9uV2ViU29ja2V0RXJyb3IoZGF0YTogYW55KSB7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVFcnJvcignV2ViU29ja2V0RXJyb3InLCBkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZUVycm9yKG9yaWdpbjogc3RyaW5nLCBkYXRhOiBGcmFtZUltcGwpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKG9yaWdpbiwgZGF0YSk7XHJcbiAgICAgICAgdGhpcy5lcnJvciQubmV4dChkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZVJlY29ubmVjdGlvbigpIHtcclxuICAgICAgICB0aGlzLmxvc3RDb25uZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5yZWNvbm5lY3RQcmltaXRpdmVzKCk7XHJcbiAgICAgICAgdGhpcy5yZWNvbm5lY3RlZCQubmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVjb25uZWN0UHJpbWl0aXZlcygpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZU1hbmFnZXIgb2YgdGhpcy5wcmltaXRpdmVNYW5hZ2Vycy52YWx1ZXMoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVN0b21wU3Vic2NyaXB0aW9ucyhwcmltaXRpdmVNYW5hZ2VyKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBidWlsZFN1YnNjcmlwdGlvblVybFdpdGhUb2tlbihkb21haW46IHN0cmluZywgc2VydmljZTogc3RyaW5nLCBwcmltaXRpdmU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgY29uc3QgYXV0aFRva2VuID0gdGhpcy51c2VySW5mb3JtYXRpb25TZXJ2aWNlLmdldEF1dGhUb2tlbigpO1xyXG4gICAgICAgIGNvbnN0IHRlbmFudCA9IHRoaXMudXNlckluZm9ybWF0aW9uU2VydmljZS5nZXRUZW5hbnREb21haW4oKTtcclxuICAgICAgICByZXR1cm4gYC90b3BpYy8ke3RlbmFudH0vJHthdXRoVG9rZW59LyR7ZG9tYWlufS8ke3NlcnZpY2V9LyR7cHJpbWl0aXZlfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRTdWJzY3JpcHRpb25VcmxXaXRob3V0VG9rZW4oZG9tYWluOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcHJpbWl0aXZlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IHRlbmFudCA9IHRoaXMudXNlckluZm9ybWF0aW9uU2VydmljZS5nZXRUZW5hbnREb21haW4oKTtcclxuICAgICAgICByZXR1cm4gYC90b3BpYy8ke3RlbmFudH0vJHtkb21haW59LyR7c2VydmljZX0vJHtwcmltaXRpdmV9YDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGJ1aWxkUHJpbWl0aXZlTWFuYWdlcktleShkb21haW46IHN0cmluZywgc2VydmljZTogc3RyaW5nLCBwcmltaXRpdmU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIGAke2RvbWFpbn0vJHtzZXJ2aWNlfS8ke3ByaW1pdGl2ZX1gO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgdW5zdWJzY3JpYmVQcmltaXRpdmVPbkZpbmFsaXplKHByaW1pdGl2ZU1hbmFnZXI6IFByaW1pdGl2ZU1hbmFnZXI8YW55Pikge1xyXG4gICAgICAgIGlmIChwcmltaXRpdmVNYW5hZ2VyLmhhc09ic2VydmVycygpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByaW1pdGl2ZU1hbmFnZXIudW5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5idWlsZFByaW1pdGl2ZU1hbmFnZXJLZXkocHJpbWl0aXZlTWFuYWdlci5kb21haW4sIHByaW1pdGl2ZU1hbmFnZXIuc2VydmljZSwgcHJpbWl0aXZlTWFuYWdlci5wcmltaXRpdmUpO1xyXG4gICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZGVsZXRlKGtleSk7XHJcblxyXG4gICAgICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdElmTm9Nb3JlT2JzZXJ2YWJsZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGRpc2Nvbm5lY3RJZk5vTW9yZU9ic2VydmFibGVzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmdldE9ic2VydmVyc0NvdW50KCkgPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5kZWJ1ZygnTWFudWFsbHkgZGlzY29ubmVjdGluZyBiZWNhdXNlIHRoZXJlIGFyZSBubyBtb3JlIG9ic2VydmVycycpO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRpc2Nvbm5lY3QoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRPYnNlcnZlcnNDb3VudCgpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBvYnNlcnZlcnNDb3VudCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMucHJpbWl0aXZlTWFuYWdlcnMuZm9yRWFjaChwcmltaXRpdmVNYW5hZ2VyID0+IHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXJzQ291bnQgKz0gcHJpbWl0aXZlTWFuYWdlci5nZXRPYnNlcnZlcnNDb3VudCgpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gb2JzZXJ2ZXJzQ291bnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVTdG9tcFN1YnNjcmlwdGlvbjxUPihkZXN0aW5hdGlvbjogc3RyaW5nLCBwcmltaXRpdmVNYW5hZ2VyOiBQcmltaXRpdmVNYW5hZ2VyPFQ+KTogU3RvbXBTdWJzY3JpcHRpb24ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnN0b21wQ2xpZW50LnN1YnNjcmliZShkZXN0aW5hdGlvbiwgKG1lc3NhZ2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBldmVudCA9IEpTT04ucGFyc2UobWVzc2FnZS5ib2R5IHx8ICd7fScpO1xyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLmZpcmVFdmVudChldmVudCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVTdG9tcFN1YnNjcmlwdGlvbnM8VD4ocHJpbWl0aXZlTWFuYWdlcjogUHJpbWl0aXZlTWFuYWdlcjxUPik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvblVybFdpdGhUb2tlbiA9IHRoaXMuYnVpbGRTdWJzY3JpcHRpb25VcmxXaXRoVG9rZW4oXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuZG9tYWluLFxyXG4gICAgICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnNlcnZpY2UsXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIucHJpbWl0aXZlXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb25VcmxXaXRob3V0VG9rZW4gPSB0aGlzLmdldFN1YnNjcmlwdGlvblVybFdpdGhvdXRUb2tlbihcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5kb21haW4sXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZU1hbmFnZXIuc2VydmljZSxcclxuICAgICAgICAgICAgcHJpbWl0aXZlTWFuYWdlci5wcmltaXRpdmVcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBjb25zdCBzdG9tcFN1YnNjcmlwdGlvbldpdGhUb2tlbiA9IHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uVXJsV2l0aFRva2VuLCBwcmltaXRpdmVNYW5hZ2VyKTtcclxuICAgICAgICBjb25zdCBzdG9tcFN1YnNjcmlwdGlvbldpdGhvdXRUb2tlbiA9IHRoaXMuY3JlYXRlU3RvbXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uVXJsV2l0aG91dFRva2VuLCBwcmltaXRpdmVNYW5hZ2VyKTtcclxuICAgICAgICBwcmltaXRpdmVNYW5hZ2VyLnN1YnNjcmliZShzdG9tcFN1YnNjcmlwdGlvbldpdGhUb2tlbiwgc3RvbXBTdWJzY3JpcHRpb25XaXRob3V0VG9rZW4pO1xyXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlZCQubmV4dChwcmltaXRpdmVNYW5hZ2VyKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFN1YnNjcmlwdGlvblVybCgpIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy51c2VySW5mb3JtYXRpb25TZXJ2aWNlLmdldFdlYlNvY2tldFVybCgpfS9zdWJzY3JpcHRpb25gO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==