1 | import { __extends, __decorate, __metadata, __awaiter, __generator, __values } from 'tslib';
|
2 | import { forwardRef, Injectable, Inject, Component, NgModule, InjectionToken } from '@angular/core';
|
3 | import { Type, plainToClass } from 'class-transformer';
|
4 | import { Router, ActivatedRoute, RouterModule } from '@angular/router';
|
5 | import { Storage } from '@ubud/storage';
|
6 | import { forkJoin, from, Observable, of, throwError, concat } from 'rxjs';
|
7 | import { catchError, map, switchMap, tap, retryWhen } from 'rxjs/operators';
|
8 | import { HttpClient } from '@angular/common/http';
|
9 | import { Location, CommonModule } from '@angular/common';
|
10 | import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
|
11 | import { first, map as map$1 } from 'rxjs/internal/operators';
|
12 |
|
13 | /**
|
14 | * @fileoverview added by tsickle
|
15 | * @suppress {checkTypes} checked by tsc
|
16 | */
|
17 | var Config = /** @class */ (function () {
|
18 | function Config(data) {
|
19 | this.endpoint = 'https://account.kemnaker.go.id';
|
20 | this.scopes = 'basic email';
|
21 | Object.assign(this, data);
|
22 | }
|
23 | return Config;
|
24 | }());
|
25 |
|
26 | /**
|
27 | * @fileoverview added by tsickle
|
28 | * @suppress {checkTypes} checked by tsc
|
29 | */
|
30 | var User = /** @class */ (function () {
|
31 | function User() {
|
32 | }
|
33 | __decorate([
|
34 | Type(/** @type {?} */ (forwardRef(function () { return Date; }))),
|
35 | __metadata("design:type", Date)
|
36 | ], User.prototype, "updatedAt", void 0);
|
37 | return User;
|
38 | }());
|
39 |
|
40 | /**
|
41 | * @fileoverview added by tsickle
|
42 | * @suppress {checkTypes} checked by tsc
|
43 | */
|
44 | var NacoService = /** @class */ (function () {
|
45 | function NacoService(config, router, storage, http, location) {
|
46 | this.config = config;
|
47 | this.router = router;
|
48 | this.storage = storage;
|
49 | this.http = http;
|
50 | this.location = location;
|
51 | this.VERSION = 'v1';
|
52 | this.signature = null;
|
53 | this.user = null;
|
54 | this.refreshToken = null;
|
55 | this.clientSecret = null;
|
56 | }
|
57 | /**
|
58 | * @param {?} user
|
59 | * @return {?}
|
60 | */
|
61 | NacoService.prototype.setUser = /**
|
62 | * @param {?} user
|
63 | * @return {?}
|
64 | */
|
65 | function (user) {
|
66 | this.user = user;
|
67 | };
|
68 | /**
|
69 | * @return {?}
|
70 | */
|
71 | NacoService.prototype.getUser = /**
|
72 | * @return {?}
|
73 | */
|
74 | function () {
|
75 | var _this = this;
|
76 | if (null !== this.user) {
|
77 | return of(this.user);
|
78 | }
|
79 | var /** @type {?} */ uri = this.getUri('/users/me');
|
80 | return from(this.getSignature()).pipe(switchMap(function (signature) {
|
81 | if (!signature) {
|
82 | return _this.refreshUser(_this.config.scopes);
|
83 | }
|
84 | var /** @type {?} */ options = {
|
85 | headers: {
|
86 | Authorization: signature.type + " " + signature.token,
|
87 | },
|
88 | };
|
89 | return _this.http.get(uri, options).pipe(map(function (res) {
|
90 | if (res.data) {
|
91 | return res.data;
|
92 | }
|
93 | throw new Error('There are no body to be transformed');
|
94 | }), map(function (data) {
|
95 | var /** @type {?} */ authUser = plainToClass(User, data);
|
96 | _this.setUser(authUser);
|
97 | return authUser;
|
98 | }), catchError(function (e) {
|
99 | if (401 === e.status) {
|
100 | return _this.refreshUser(signature.scopes);
|
101 | }
|
102 | return of(null);
|
103 | }));
|
104 | }));
|
105 | };
|
106 | /**
|
107 | * @param {?} user
|
108 | * @return {?}
|
109 | */
|
110 | NacoService.prototype.getProfilePicture = /**
|
111 | * @param {?} user
|
112 | * @return {?}
|
113 | */
|
114 | function (user) {
|
115 | return this.config.endpoint + '/users/' + user + '/picture';
|
116 | };
|
117 | /**
|
118 | * @return {?}
|
119 | */
|
120 | NacoService.prototype.getSignature = /**
|
121 | * @return {?}
|
122 | */
|
123 | function () {
|
124 | if (this.signature) {
|
125 | return Promise.resolve(this.signature);
|
126 | }
|
127 | return this.storage.get('signature');
|
128 | };
|
129 | /**
|
130 | * @param {?} signature
|
131 | * @return {?}
|
132 | */
|
133 | NacoService.prototype.setSignature = /**
|
134 | * @param {?} signature
|
135 | * @return {?}
|
136 | */
|
137 | function (signature) {
|
138 | this.signature = signature;
|
139 | this.storage.set('signature', signature);
|
140 | };
|
141 | /**
|
142 | * @param {?} secret
|
143 | * @return {?}
|
144 | */
|
145 | NacoService.prototype.setClientSecret = /**
|
146 | * @param {?} secret
|
147 | * @return {?}
|
148 | */
|
149 | function (secret) {
|
150 | this.clientSecret = secret;
|
151 | this.storage.set('client_secret', secret);
|
152 | };
|
153 | /**
|
154 | * @param {?} refreshToken
|
155 | * @return {?}
|
156 | */
|
157 | NacoService.prototype.setRefreshToken = /**
|
158 | * @param {?} refreshToken
|
159 | * @return {?}
|
160 | */
|
161 | function (refreshToken) {
|
162 | this.refreshToken = refreshToken;
|
163 | this.storage.set('refresh_token', refreshToken);
|
164 | };
|
165 | /**
|
166 | * @param {?=} scopes
|
167 | * @return {?}
|
168 | */
|
169 | NacoService.prototype.refreshUser = /**
|
170 | * @param {?=} scopes
|
171 | * @return {?}
|
172 | */
|
173 | function (scopes) {
|
174 | var _this = this;
|
175 | this.setUser(null);
|
176 | this.setSignature(null);
|
177 | return forkJoin(this.getRefreshToken(), this.getClientSecret()).pipe(switchMap(function (results) {
|
178 | var /** @type {?} */ refreshToken = results[0];
|
179 | var /** @type {?} */ clientSecret = results[1];
|
180 | if (refreshToken && clientSecret) {
|
181 | return _this.refreshWithRefreshToken(clientSecret, refreshToken.token, scopes);
|
182 | }
|
183 | return _this.refreshWithSilentAuth(scopes);
|
184 | }));
|
185 | };
|
186 | /**
|
187 | * @param {?} clientSecret
|
188 | * @param {?} refreshToken
|
189 | * @param {?=} scopes
|
190 | * @return {?}
|
191 | */
|
192 | NacoService.prototype.refreshWithRefreshToken = /**
|
193 | * @param {?} clientSecret
|
194 | * @param {?} refreshToken
|
195 | * @param {?=} scopes
|
196 | * @return {?}
|
197 | */
|
198 | function (clientSecret, refreshToken, scopes) {
|
199 | var _this = this;
|
200 | var /** @type {?} */ request = this.http.post(this.getUri('/tokens'), {
|
201 | grant_type: 'refresh_token',
|
202 | scopes: scopes || this.config.scopes,
|
203 | client_id: this.config.clientId,
|
204 | client_secret: clientSecret,
|
205 | refresh_token: refreshToken,
|
206 | });
|
207 | return request.pipe(tap(function (tokens) {
|
208 | if (tokens && tokens.data) {
|
209 | _this.setSignature({
|
210 | expiresIn: tokens.data.expires_in,
|
211 | type: tokens.data.token_type,
|
212 | token: tokens.data.access_token,
|
213 | scopes: decodeURIComponent(tokens.data.scopes || _this.config.scopes),
|
214 | });
|
215 | _this.setRefreshToken({
|
216 | type: tokens.data.token_type,
|
217 | token: tokens.data.refresh_token,
|
218 | });
|
219 | }
|
220 | }), map(function (tokens) { return tokens && tokens.data; }), switchMap(function (hasToken) {
|
221 | if (hasToken) {
|
222 | return _this.getUser();
|
223 | }
|
224 | return of(null);
|
225 | }));
|
226 | };
|
227 | /**
|
228 | * @param {?=} scopes
|
229 | * @return {?}
|
230 | */
|
231 | NacoService.prototype.refreshWithSilentAuth = /**
|
232 | * @param {?=} scopes
|
233 | * @return {?}
|
234 | */
|
235 | function (scopes) {
|
236 | var _this = this;
|
237 | return new Observable(function (observer) {
|
238 | var /** @type {?} */ redirectUri = _this.getCurrentOrigin('auth/silent');
|
239 | var /** @type {?} */ uri = _this.login(scopes || _this.config.scopes, redirectUri, false);
|
240 | var /** @type {?} */ iframe = document.createElement('iframe');
|
241 | iframe.setAttribute('src', uri);
|
242 | iframe.style.display = 'none';
|
243 | iframe.addEventListener('load', function () { return __awaiter(_this, void 0, void 0, function () {
|
244 | var e_1, _a, queryString, queryParts, params, queryParts_1, queryParts_1_1, item, itemParts, user, e_2;
|
245 | return __generator(this, function (_b) {
|
246 | switch (_b.label) {
|
247 | case 0:
|
248 | _b.trys.push([0, 5, , 6]);
|
249 | queryString = iframe.contentWindow.location.search.substring(1);
|
250 | iframe.parentNode.removeChild(iframe);
|
251 | if (!queryString) return [3 /*break*/, 4];
|
252 | queryParts = queryString.split('&');
|
253 | params = {};
|
254 | try {
|
255 | for (queryParts_1 = __values(queryParts), queryParts_1_1 = queryParts_1.next(); !queryParts_1_1.done; queryParts_1_1 = queryParts_1.next()) {
|
256 | item = queryParts_1_1.value;
|
257 | itemParts = item.split('=');
|
258 | params[itemParts[0]] = itemParts[1];
|
259 | }
|
260 | }
|
261 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
262 | finally {
|
263 | try {
|
264 | if (queryParts_1_1 && !queryParts_1_1.done && (_a = queryParts_1.return)) _a.call(queryParts_1);
|
265 | }
|
266 | finally { if (e_1) throw e_1.error; }
|
267 | }
|
268 | if (!params.hasOwnProperty('access_token')) return [3 /*break*/, 2];
|
269 | this.setSignature({
|
270 | token: params['access_token'],
|
271 | type: params['token_type'],
|
272 | expiresIn: params['expires_in'],
|
273 | scopes: decodeURIComponent(params['scopes'] || this.config.scopes),
|
274 | });
|
275 | return [4 /*yield*/, this.getUser().toPromise()];
|
276 | case 1:
|
277 | user = _b.sent();
|
278 | if (user) {
|
279 | this.setUser(user);
|
280 | }
|
281 | observer.next(user);
|
282 | return [3 /*break*/, 3];
|
283 | case 2:
|
284 | observer.next(null);
|
285 | _b.label = 3;
|
286 | case 3: return [2 /*return*/];
|
287 | case 4:
|
288 | observer.next(null);
|
289 | return [3 /*break*/, 6];
|
290 | case 5:
|
291 | e_2 = _b.sent();
|
292 | observer.next(null);
|
293 | return [3 /*break*/, 6];
|
294 | case 6: return [2 /*return*/];
|
295 | }
|
296 | });
|
297 | }); }, false);
|
298 | document.body.appendChild(iframe);
|
299 | });
|
300 | };
|
301 | /**
|
302 | * @param {?} scopes
|
303 | * @param {?=} redirectUri
|
304 | * @param {?=} needState
|
305 | * @return {?}
|
306 | */
|
307 | NacoService.prototype.login = /**
|
308 | * @param {?} scopes
|
309 | * @param {?=} redirectUri
|
310 | * @param {?=} needState
|
311 | * @return {?}
|
312 | */
|
313 | function (scopes, redirectUri, needState) {
|
314 | if (needState === void 0) { needState = true; }
|
315 | if (!redirectUri) {
|
316 | redirectUri = this.router.url;
|
317 | }
|
318 | var /** @type {?} */ params = {
|
319 | response_type: 'token',
|
320 | scopes: scopes,
|
321 | client: this.config.clientId,
|
322 | silent: true,
|
323 | continue: encodeURIComponent(redirectUri),
|
324 | };
|
325 | if (needState) {
|
326 | var /** @type {?} */ state = this.generateState();
|
327 | this.storage.set('state', state);
|
328 | params.state = state;
|
329 | }
|
330 | var /** @type {?} */ query = this.buildQueryString(params);
|
331 | return this.config.endpoint + '/auth?' + query;
|
332 | };
|
333 | /**
|
334 | * @param {?=} redirectUri
|
335 | * @return {?}
|
336 | */
|
337 | NacoService.prototype.logout = /**
|
338 | * @param {?=} redirectUri
|
339 | * @return {?}
|
340 | */
|
341 | function (redirectUri) {
|
342 | var _this = this;
|
343 | this.signature = null;
|
344 | this.user = null;
|
345 | this.clientSecret = null;
|
346 | this.refreshToken = null;
|
347 | return new Promise(function (resolve) {
|
348 | var /** @type {?} */ clear = [
|
349 | _this.storage.remove('signature'),
|
350 | _this.storage.remove('user'),
|
351 | _this.storage.remove('refresh_token'),
|
352 | _this.storage.remove('client_secret'),
|
353 | ];
|
354 | Promise.all(clear).then(function () {
|
355 | var /** @type {?} */ endpoint = _this.config.endpoint + '/auth/logout';
|
356 | if (redirectUri) {
|
357 | endpoint += '?continue=' + encodeURIComponent(redirectUri);
|
358 | }
|
359 | resolve(endpoint);
|
360 | });
|
361 | });
|
362 | };
|
363 | /**
|
364 | * @return {?}
|
365 | */
|
366 | NacoService.prototype.getState = /**
|
367 | * @return {?}
|
368 | */
|
369 | function () {
|
370 | return this.storage.get('state');
|
371 | };
|
372 | /**
|
373 | * @param {?} route
|
374 | * @return {?}
|
375 | */
|
376 | NacoService.prototype.buildNestedUri = /**
|
377 | * @param {?} route
|
378 | * @return {?}
|
379 | */
|
380 | function (route) {
|
381 | var _this = this;
|
382 | var /** @type {?} */ uri = '';
|
383 | if (route.routeConfig && route.routeConfig.path) {
|
384 | var /** @type {?} */ routePath = route.routeConfig.path;
|
385 | for (var /** @type {?} */ key in route.params) {
|
386 | if (key) {
|
387 | var /** @type {?} */ re = new RegExp(':' + key);
|
388 | routePath = routePath.replace(re, route.params[key]);
|
389 | }
|
390 | }
|
391 | uri += '/' + routePath;
|
392 | }
|
393 | if (route.children) {
|
394 | route.children.forEach(function (item) {
|
395 | uri += _this.buildNestedUri(item);
|
396 | });
|
397 | }
|
398 | return uri;
|
399 | };
|
400 | /**
|
401 | * @return {?}
|
402 | */
|
403 | NacoService.prototype.getRefreshToken = /**
|
404 | * @return {?}
|
405 | */
|
406 | function () {
|
407 | if (null !== this.refreshToken) {
|
408 | return Promise.resolve(this.refreshToken);
|
409 | }
|
410 | return this.storage.get('refresh_token');
|
411 | };
|
412 | /**
|
413 | * @return {?}
|
414 | */
|
415 | NacoService.prototype.getClientSecret = /**
|
416 | * @return {?}
|
417 | */
|
418 | function () {
|
419 | if (null !== this.clientSecret) {
|
420 | return Promise.resolve(this.clientSecret);
|
421 | }
|
422 | return this.storage.get('client_secret');
|
423 | };
|
424 | /**
|
425 | * @param {?} path
|
426 | * @return {?}
|
427 | */
|
428 | NacoService.prototype.getUri = /**
|
429 | * @param {?} path
|
430 | * @return {?}
|
431 | */
|
432 | function (path) {
|
433 | return this.config.endpoint + '/api/' + this.VERSION + path;
|
434 | };
|
435 | /**
|
436 | * @param {?=} path
|
437 | * @return {?}
|
438 | */
|
439 | NacoService.prototype.getCurrentOrigin = /**
|
440 | * @param {?=} path
|
441 | * @return {?}
|
442 | */
|
443 | function (path) {
|
444 | return window.location.origin + this.location.prepareExternalUrl(path || '');
|
445 | };
|
446 | /**
|
447 | * @return {?}
|
448 | */
|
449 | NacoService.prototype.generateState = /**
|
450 | * @return {?}
|
451 | */
|
452 | function () {
|
453 | var /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
454 | var /** @type {?} */ text = '';
|
455 | for (var /** @type {?} */ i = 0; i < 5; i++) {
|
456 | text += possible.charAt(Math.floor(Math.random() * possible.length));
|
457 | }
|
458 | return text;
|
459 | };
|
460 | /**
|
461 | * @param {?} params
|
462 | * @return {?}
|
463 | */
|
464 | NacoService.prototype.buildQueryString = /**
|
465 | * @param {?} params
|
466 | * @return {?}
|
467 | */
|
468 | function (params) {
|
469 | var /** @type {?} */ queryParams = Object.keys(params).map(function (key) {
|
470 | return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
|
471 | });
|
472 | return queryParams.join('&');
|
473 | };
|
474 | /**
|
475 | * @param {?} route
|
476 | * @return {?}
|
477 | */
|
478 | NacoService.prototype.goToAccountEndpoint = /**
|
479 | * @param {?} route
|
480 | * @return {?}
|
481 | */
|
482 | function (route) {
|
483 | var _this = this;
|
484 | var /** @type {?} */ ltrim = function (text) { return text.replace(/^\/+/, ''); };
|
485 | var /** @type {?} */ next = this.getCurrentOrigin('/' + ltrim(this.buildNestedUri(route.root)));
|
486 | this.storage.set('naco_intended_url', next).then(function () {
|
487 | _this.redirect(_this.login(_this.config.scopes, _this.getCurrentOrigin('/auth')));
|
488 | });
|
489 | };
|
490 | /**
|
491 | * @return {?}
|
492 | */
|
493 | NacoService.prototype.goToIntendedUrl = /**
|
494 | * @return {?}
|
495 | */
|
496 | function () {
|
497 | var _this = this;
|
498 | this.storage.get('naco_intended_url').then(function (url) {
|
499 | _this.storage.remove('naco_intended_url');
|
500 | _this.redirect(url || '/');
|
501 | });
|
502 | };
|
503 | /**
|
504 | * @param {?} url
|
505 | * @return {?}
|
506 | */
|
507 | NacoService.prototype.redirect = /**
|
508 | * @param {?} url
|
509 | * @return {?}
|
510 | */
|
511 | function (url) {
|
512 | window.location.href = url;
|
513 | };
|
514 | NacoService.decorators = [
|
515 | { type: Injectable },
|
516 | ];
|
517 | /** @nocollapse */
|
518 | NacoService.ctorParameters = function () { return [
|
519 | { type: Config },
|
520 | { type: Router },
|
521 | { type: Storage },
|
522 | { type: HttpClient },
|
523 | { type: Location }
|
524 | ]; };
|
525 | return NacoService;
|
526 | }());
|
527 |
|
528 | /**
|
529 | * @fileoverview added by tsickle
|
530 | * @suppress {checkTypes} checked by tsc
|
531 | */
|
532 | var NacoExpressService = /** @class */ (function (_super) {
|
533 | __extends(NacoExpressService, _super);
|
534 | function NacoExpressService(config, router, storage, http, location, request, response) {
|
535 | var _this = _super.call(this, config, router, storage, http, location) || this;
|
536 | _this.request = request;
|
537 | _this.response = response;
|
538 | return _this;
|
539 | }
|
540 | /**
|
541 | * @return {?}
|
542 | */
|
543 | NacoExpressService.prototype.refreshWithSilentAuth = /**
|
544 | * @return {?}
|
545 | */
|
546 | function () {
|
547 | return of(null);
|
548 | };
|
549 | /**
|
550 | * @param {?=} path
|
551 | * @return {?}
|
552 | */
|
553 | NacoExpressService.prototype.getCurrentOrigin = /**
|
554 | * @param {?=} path
|
555 | * @return {?}
|
556 | */
|
557 | function (path) {
|
558 | if (path === void 0) { path = ''; }
|
559 | return this.request.protocol + "://" + this.request.headers.host + this.location.prepareExternalUrl(path || '');
|
560 | };
|
561 | /**
|
562 | * @param {?} url
|
563 | * @return {?}
|
564 | */
|
565 | NacoExpressService.prototype.redirect = /**
|
566 | * @param {?} url
|
567 | * @return {?}
|
568 | */
|
569 | function (url) {
|
570 | this.response.redirect(302, url);
|
571 | this.response.end();
|
572 | };
|
573 | NacoExpressService.decorators = [
|
574 | { type: Injectable },
|
575 | ];
|
576 | /** @nocollapse */
|
577 | NacoExpressService.ctorParameters = function () { return [
|
578 | { type: Config },
|
579 | { type: Router },
|
580 | { type: Storage },
|
581 | { type: HttpClient },
|
582 | { type: Location },
|
583 | { type: undefined, decorators: [{ type: Inject, args: [REQUEST,] }] },
|
584 | { type: undefined, decorators: [{ type: Inject, args: [RESPONSE,] }] }
|
585 | ]; };
|
586 | return NacoExpressService;
|
587 | }(NacoService));
|
588 |
|
589 | /**
|
590 | * @fileoverview added by tsickle
|
591 | * @suppress {checkTypes} checked by tsc
|
592 | */
|
593 | var Signature = /** @class */ (function () {
|
594 | function Signature() {
|
595 | }
|
596 | return Signature;
|
597 | }());
|
598 |
|
599 | /**
|
600 | * @fileoverview added by tsickle
|
601 | * @suppress {checkTypes} checked by tsc
|
602 | */
|
603 | var AuthenticatedGuard = /** @class */ (function () {
|
604 | function AuthenticatedGuard(naco, storage, location) {
|
605 | this.naco = naco;
|
606 | this.storage = storage;
|
607 | this.location = location;
|
608 | }
|
609 | /**
|
610 | * @param {?} route
|
611 | * @return {?}
|
612 | */
|
613 | AuthenticatedGuard.prototype.canActivate = /**
|
614 | * @param {?} route
|
615 | * @return {?}
|
616 | */
|
617 | function (route) {
|
618 | var _this = this;
|
619 | return this.naco.getUser().pipe(first(), map$1(function (user) {
|
620 | if (null === user) {
|
621 | _this.naco.goToAccountEndpoint(route.root);
|
622 | }
|
623 | return !!user;
|
624 | }));
|
625 | };
|
626 | /**
|
627 | * @param {?} route
|
628 | * @return {?}
|
629 | */
|
630 | AuthenticatedGuard.prototype.canActivateChild = /**
|
631 | * @param {?} route
|
632 | * @return {?}
|
633 | */
|
634 | function (route) {
|
635 | return this.canActivate(route);
|
636 | };
|
637 | AuthenticatedGuard.decorators = [
|
638 | { type: Injectable },
|
639 | ];
|
640 | /** @nocollapse */
|
641 | AuthenticatedGuard.ctorParameters = function () { return [
|
642 | { type: NacoService },
|
643 | { type: Storage },
|
644 | { type: Location }
|
645 | ]; };
|
646 | return AuthenticatedGuard;
|
647 | }());
|
648 |
|
649 | /**
|
650 | * @fileoverview added by tsickle
|
651 | * @suppress {checkTypes} checked by tsc
|
652 | */
|
653 | var AuthInterceptor = /** @class */ (function () {
|
654 | function AuthInterceptor(naco) {
|
655 | this.naco = naco;
|
656 | }
|
657 | /**
|
658 | * @param {?} req
|
659 | * @param {?} next
|
660 | * @return {?}
|
661 | */
|
662 | AuthInterceptor.prototype.intercept = /**
|
663 | * @param {?} req
|
664 | * @param {?} next
|
665 | * @return {?}
|
666 | */
|
667 | function (req, next) {
|
668 | var _this = this;
|
669 | var /** @type {?} */ needRetry = true;
|
670 | return from(this.naco.getSignature()).pipe(switchMap(function (signature) {
|
671 | if (!signature) {
|
672 | needRetry = false;
|
673 | return next.handle(req);
|
674 | }
|
675 | return next.handle(req.clone({
|
676 | setHeaders: {
|
677 | Authorization: signature.type + " " + signature.token,
|
678 | },
|
679 | }));
|
680 | }), retryWhen(function (error) {
|
681 | return error.pipe(switchMap(function (error) {
|
682 | if (error.status !== 401 || !needRetry) {
|
683 | return throwError(error);
|
684 | }
|
685 | needRetry = false;
|
686 | return _this.naco.refreshUser().pipe(switchMap(function (user) {
|
687 | if (!user) {
|
688 | return of(null);
|
689 | }
|
690 | return throwError(error);
|
691 | }));
|
692 | }));
|
693 | }));
|
694 | };
|
695 | AuthInterceptor.decorators = [
|
696 | { type: Injectable },
|
697 | ];
|
698 | /** @nocollapse */
|
699 | AuthInterceptor.ctorParameters = function () { return [
|
700 | { type: NacoService }
|
701 | ]; };
|
702 | return AuthInterceptor;
|
703 | }());
|
704 |
|
705 | /**
|
706 | * @fileoverview added by tsickle
|
707 | * @suppress {checkTypes} checked by tsc
|
708 | */
|
709 | var AuthPage = /** @class */ (function () {
|
710 | function AuthPage(route, naco, storage, location) {
|
711 | this.route = route;
|
712 | this.naco = naco;
|
713 | this.storage = storage;
|
714 | this.location = location;
|
715 | this.message$ = concat(of('Authenticating...'), this.handle());
|
716 | }
|
717 | /**
|
718 | * @return {?}
|
719 | */
|
720 | AuthPage.prototype.handle = /**
|
721 | * @return {?}
|
722 | */
|
723 | function () {
|
724 | var _this = this;
|
725 | return from(this.naco.getState()).pipe(switchMap(function (state) {
|
726 | return _this.route.queryParams.pipe(switchMap(function (params) {
|
727 | if (state && params["state"] !== state) {
|
728 | return throwError('Invalid CSRF Token');
|
729 | }
|
730 | return of(params);
|
731 | }));
|
732 | }), switchMap(function (params) {
|
733 | _this.naco.setUser(null);
|
734 | _this.naco.setSignature({
|
735 | expiresIn: params["expires_in"],
|
736 | type: params["token_type"],
|
737 | token: params["access_token"],
|
738 | });
|
739 | return _this.naco.getUser();
|
740 | }), switchMap(function (user) {
|
741 | if (null === user) {
|
742 | return throwError(new Error('Unauthenticated!'));
|
743 | }
|
744 | _this.naco.goToIntendedUrl();
|
745 | return 'Success';
|
746 | }), catchError(function (e) {
|
747 | return of(e.message);
|
748 | }));
|
749 | };
|
750 | AuthPage.decorators = [
|
751 | { type: Component, args: [{
|
752 | selector: 'naker-auth-page',
|
753 | template: '{{ message$ | async }}',
|
754 | },] },
|
755 | ];
|
756 | /** @nocollapse */
|
757 | AuthPage.ctorParameters = function () { return [
|
758 | { type: ActivatedRoute },
|
759 | { type: NacoService },
|
760 | { type: Storage },
|
761 | { type: Location }
|
762 | ]; };
|
763 | return AuthPage;
|
764 | }());
|
765 |
|
766 | /**
|
767 | * @fileoverview added by tsickle
|
768 | * @suppress {checkTypes} checked by tsc
|
769 | */
|
770 | var AuthSilentPage = /** @class */ (function () {
|
771 | function AuthSilentPage(naco) {
|
772 | this.naco = naco;
|
773 | }
|
774 | /**
|
775 | * @return {?}
|
776 | */
|
777 | AuthSilentPage.prototype.ngOnInit = /**
|
778 | * @return {?}
|
779 | */
|
780 | function () {
|
781 | var _this = this;
|
782 | var /** @type {?} */ timeout = setTimeout(function () {
|
783 | clearTimeout(timeout);
|
784 | _this.naco.redirect('/');
|
785 | }, 2000);
|
786 | };
|
787 | AuthSilentPage.decorators = [
|
788 | { type: Component, args: [{
|
789 | selector: 'naker-auth-silent',
|
790 | template: 'Please wait...',
|
791 | },] },
|
792 | ];
|
793 | /** @nocollapse */
|
794 | AuthSilentPage.ctorParameters = function () { return [
|
795 | { type: NacoService }
|
796 | ]; };
|
797 | return AuthSilentPage;
|
798 | }());
|
799 |
|
800 | /**
|
801 | * @fileoverview added by tsickle
|
802 | * @suppress {checkTypes} checked by tsc
|
803 | */
|
804 | var /** @type {?} */ routes = [
|
805 | {
|
806 | path: 'auth',
|
807 | component: AuthPage
|
808 | },
|
809 | {
|
810 | path: 'auth/silent',
|
811 | component: AuthSilentPage
|
812 | },
|
813 | ];
|
814 | var /** @type {?} */ AUTH_ROUTING = RouterModule.forChild(routes);
|
815 |
|
816 | /**
|
817 | * @fileoverview added by tsickle
|
818 | * @suppress {checkTypes} checked by tsc
|
819 | */
|
820 | var NacoViewModule = /** @class */ (function () {
|
821 | function NacoViewModule() {
|
822 | }
|
823 | NacoViewModule.decorators = [
|
824 | { type: NgModule, args: [{
|
825 | imports: [CommonModule, AUTH_ROUTING],
|
826 | declarations: [AuthPage, AuthSilentPage],
|
827 | },] },
|
828 | ];
|
829 | return NacoViewModule;
|
830 | }());
|
831 |
|
832 | /**
|
833 | * @fileoverview added by tsickle
|
834 | * @suppress {checkTypes} checked by tsc
|
835 | */
|
836 | var /** @type {?} */ NACO_ROOT_CONFIG = new InjectionToken('NACO_ROOT_CONFIG');
|
837 | /**
|
838 | * @param {?} config
|
839 | * @return {?}
|
840 | */
|
841 | function nacoConfigFactory(config) {
|
842 | return new Config(config);
|
843 | }
|
844 | var NacoModule = /** @class */ (function () {
|
845 | function NacoModule() {
|
846 | }
|
847 | /**
|
848 | * @param {?} config
|
849 | * @return {?}
|
850 | */
|
851 | NacoModule.forRoot = /**
|
852 | * @param {?} config
|
853 | * @return {?}
|
854 | */
|
855 | function (config) {
|
856 | return {
|
857 | ngModule: NacoModule,
|
858 | providers: [
|
859 | {
|
860 | provide: NACO_ROOT_CONFIG,
|
861 | useValue: config,
|
862 | },
|
863 | {
|
864 | provide: Config,
|
865 | useFactory: nacoConfigFactory,
|
866 | deps: [NACO_ROOT_CONFIG],
|
867 | },
|
868 | NacoService,
|
869 | AuthenticatedGuard,
|
870 | ],
|
871 | };
|
872 | };
|
873 | NacoModule.decorators = [
|
874 | { type: NgModule, args: [{
|
875 | imports: [NacoViewModule],
|
876 | },] },
|
877 | ];
|
878 | return NacoModule;
|
879 | }());
|
880 |
|
881 | /**
|
882 | * @fileoverview added by tsickle
|
883 | * @suppress {checkTypes} checked by tsc
|
884 | */
|
885 |
|
886 | /**
|
887 | * @fileoverview added by tsickle
|
888 | * @suppress {checkTypes} checked by tsc
|
889 | */
|
890 |
|
891 | export { NacoService, NacoExpressService, User, Signature, Config, AuthenticatedGuard, AuthInterceptor, nacoConfigFactory, NacoModule, NacoViewModule as ɵa, AuthSilentPage as ɵd, AuthPage as ɵc, AUTH_ROUTING as ɵb };
|
892 |
|
893 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFrZXItbmFjby5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvY29uZmlnLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL21vZGVscy91c2VyLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLmV4cHJlc3Muc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvc2lnbmF0dXJlLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZC50cyIsIm5nOi8vQG5ha2VyL25hY28vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiLCJuZzovL0BuYWtlci9uYWNvL3ZpZXdzL3BhZ2VzL2F1dGgucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3MvcGFnZXMvYXV0aC1zaWxlbnQucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3Mvcm91dGVzLnRzIiwibmc6Ly9AbmFrZXIvbmFjby92aWV3cy9tb2R1bGUudHMiLCJuZzovL0BuYWtlci9uYWNvL25hY28ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHB1YmxpYyBlbmRwb2ludD86IHN0cmluZyA9ICdodHRwczovL2FjY291bnQua2VtbmFrZXIuZ28uaWQnO1xuICAgIHB1YmxpYyBjbGllbnRJZD86IHN0cmluZztcbiAgICBwdWJsaWMgc2NvcGVzPzogc3RyaW5nID0gJ2Jhc2ljIGVtYWlsJztcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihkYXRhPzogUGFydGlhbDxDb25maWc+KSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgZGF0YSk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJ2NsYXNzLXRyYW5zZm9ybWVyJztcblxuZXhwb3J0IGNsYXNzIFVzZXIge1xuICAgIHB1YmxpYyBpZDogc3RyaW5nO1xuICAgIHB1YmxpYyB1c2VybmFtZTogc3RyaW5nO1xuICAgIHB1YmxpYyBlbWFpbD86IHN0cmluZztcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuICAgIHB1YmxpYyBzdGF0dXM6IG51bWJlcjtcblxuICAgIEBUeXBlKGZvcndhcmRSZWYoKCkgPT4gRGF0ZSkgYXMgYW55KVxuICAgIHB1YmxpYyB1cGRhdGVkQXQ6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgU3RvcmFnZSB9IGZyb20gJ0B1YnVkL3N0b3JhZ2UnO1xuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi4vdmFsdWVzL2NvbmZpZyc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vbW9kZWxzL3VzZXInO1xuaW1wb3J0IHsgZm9ya0pvaW4sIGZyb20sIE9ic2VydmFibGUsIE9ic2VydmVyLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgU2lnbmF0dXJlIH0gZnJvbSAnLi4vdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgcGxhaW5Ub0NsYXNzIH0gZnJvbSAnY2xhc3MtdHJhbnNmb3JtZXInO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOYWNvU2VydmljZSB7XG4gICAgcHVibGljIHJlYWRvbmx5IFZFUlNJT04gPSAndjEnO1xuXG4gICAgcHJpdmF0ZSBzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgdXNlcjogVXNlciB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgcmVmcmVzaFRva2VuOiBTaWduYXR1cmUgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGNsaWVudFNlY3JldDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIHByb3RlY3RlZCBjb25maWc6IENvbmZpZyxcbiAgICAgICAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyLFxuICAgICAgICBwcm90ZWN0ZWQgc3RvcmFnZTogU3RvcmFnZSxcbiAgICAgICAgcHJvdGVjdGVkIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgIHByb3RlY3RlZCBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgKSB7fVxuXG4gICAgcHVibGljIHNldFVzZXIodXNlcjogVXNlciB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51c2VyID0gdXNlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VXNlcigpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnVzZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih0aGlzLnVzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdXJpID0gdGhpcy5nZXRVcmkoJy91c2Vycy9tZScpO1xuXG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMuZ2V0U2lnbmF0dXJlKCkpLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghc2lnbmF0dXJlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hVc2VyKHRoaXMuY29uZmlnLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYCR7c2lnbmF0dXJlLnR5cGV9ICR7c2lnbmF0dXJlLnRva2VufWAsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4odXJpLCBvcHRpb25zKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICBtYXAoKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmRhdGE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgYXJlIG5vIGJvZHkgdG8gYmUgdHJhbnNmb3JtZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIG1hcCgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhdXRoVXNlcjogYW55ID0gcGxhaW5Ub0NsYXNzKFVzZXIsIGRhdGEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFVzZXIoYXV0aFVzZXIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXV0aFVzZXI7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChlOiBIdHRwRXJyb3JSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDQwMSA9PT0gZS5zdGF0dXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoVXNlcihzaWduYXR1cmUuc2NvcGVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFByb2ZpbGVQaWN0dXJlKHVzZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvdXNlcnMvJyArIHVzZXIgKyAnL3BpY3R1cmUnO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTaWduYXR1cmUoKTogUHJvbWlzZTxTaWduYXR1cmUgfCBudWxsPiB7XG4gICAgICAgIGlmICh0aGlzLnNpZ25hdHVyZSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnNpZ25hdHVyZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgnc2lnbmF0dXJlJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFNpZ25hdHVyZShzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zaWduYXR1cmUgPSBzaWduYXR1cmU7XG5cbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnc2lnbmF0dXJlJywgc2lnbmF0dXJlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Q2xpZW50U2VjcmV0KHNlY3JldDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xpZW50U2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdjbGllbnRfc2VjcmV0Jywgc2VjcmV0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UmVmcmVzaFRva2VuKHJlZnJlc2hUb2tlbjogU2lnbmF0dXJlKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2VuO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyZWZyZXNoX3Rva2VuJywgcmVmcmVzaFRva2VuKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFVzZXIoc2NvcGVzPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICB0aGlzLnNldFVzZXIobnVsbCk7XG4gICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKG51bGwpO1xuXG4gICAgICAgIHJldHVybiBmb3JrSm9pbih0aGlzLmdldFJlZnJlc2hUb2tlbigpLCB0aGlzLmdldENsaWVudFNlY3JldCgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChyZXN1bHRzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50U2VjcmV0OiBzdHJpbmcgPSByZXN1bHRzWzFdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hUb2tlbiAmJiBjbGllbnRTZWNyZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0LCByZWZyZXNoVG9rZW4udG9rZW4sIHNjb3Blcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhTaWxlbnRBdXRoKHNjb3Blcyk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0OiBzdHJpbmcsIHJlZnJlc2hUb2tlbjogc3RyaW5nLCBzY29wZXM/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmh0dHAucG9zdCh0aGlzLmdldFVyaSgnL3Rva2VucycpLCB7XG4gICAgICAgICAgICBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsXG4gICAgICAgICAgICBzY29wZXM6IHNjb3BlcyB8fCB0aGlzLmNvbmZpZy5zY29wZXMsXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY29uZmlnLmNsaWVudElkLFxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogY2xpZW50U2VjcmV0LFxuICAgICAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVxdWVzdC5waXBlKFxuICAgICAgICAgICAgdGFwKCh0b2tlbnM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduYXR1cmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0luOiB0b2tlbnMuZGF0YS5leHBpcmVzX2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogdG9rZW5zLmRhdGEudG9rZW5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlbnMuZGF0YS5hY2Nlc3NfdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXM6IGRlY29kZVVSSUNvbXBvbmVudCh0b2tlbnMuZGF0YS5zY29wZXMgfHwgdGhpcy5jb25maWcuc2NvcGVzKSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSZWZyZXNoVG9rZW4oe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogdG9rZW5zLmRhdGEudG9rZW5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlbnMuZGF0YS5yZWZyZXNoX3Rva2VuLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1hcCgodG9rZW5zOiBhbnkpID0+IHRva2VucyAmJiB0b2tlbnMuZGF0YSksXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKGhhc1Rva2VuOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc1Rva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFVzZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFdpdGhTaWxlbnRBdXRoKHNjb3Blcz86IHN0cmluZyk6IE9ic2VydmFibGU8VXNlciB8IG51bGw+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPigob2JzZXJ2ZXI6IE9ic2VydmVyPFVzZXIgfCBudWxsPikgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RVcmkgPSB0aGlzLmdldEN1cnJlbnRPcmlnaW4oJ2F1dGgvc2lsZW50Jyk7XG4gICAgICAgICAgICBjb25zdCB1cmkgPSB0aGlzLmxvZ2luKHNjb3BlcyB8fCB0aGlzLmNvbmZpZy5zY29wZXMsIHJlZGlyZWN0VXJpLCBmYWxzZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgICAgICAgICAgaWZyYW1lLnNldEF0dHJpYnV0ZSgnc3JjJywgdXJpKTtcbiAgICAgICAgICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgICAgICAgICBpZnJhbWUuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAnbG9hZCcsXG4gICAgICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVlcnlTdHJpbmcgPSBpZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZnJhbWUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChpZnJhbWUpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWVyeVBhcnRzID0gcXVlcnlTdHJpbmcuc3BsaXQoJyYnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBxdWVyeVBhcnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1QYXJ0cyA9IGl0ZW0uc3BsaXQoJz0nKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXNbaXRlbVBhcnRzWzBdXSA9IGl0ZW1QYXJ0c1sxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1zLmhhc093blByb3BlcnR5KCdhY2Nlc3NfdG9rZW4nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFNpZ25hdHVyZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogcGFyYW1zWydhY2Nlc3NfdG9rZW4nXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHBhcmFtc1sndG9rZW5fdHlwZSddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0luOiBwYXJhbXNbJ2V4cGlyZXNfaW4nXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlczogZGVjb2RlVVJJQ29tcG9uZW50KHBhcmFtc1snc2NvcGVzJ10gfHwgdGhpcy5jb25maWcuc2NvcGVzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMuZ2V0VXNlcigpLnRvUHJvbWlzZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFVzZXIodXNlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ2luKHNjb3Blczogc3RyaW5nLCByZWRpcmVjdFVyaT86IHN0cmluZywgbmVlZFN0YXRlOiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgICAgIGlmICghcmVkaXJlY3RVcmkpIHtcbiAgICAgICAgICAgIHJlZGlyZWN0VXJpID0gdGhpcy5yb3V0ZXIudXJsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFyYW1zOiBhbnkgPSB7XG4gICAgICAgICAgICByZXNwb25zZV90eXBlOiAndG9rZW4nLFxuICAgICAgICAgICAgc2NvcGVzOiBzY29wZXMsXG4gICAgICAgICAgICBjbGllbnQ6IHRoaXMuY29uZmlnLmNsaWVudElkLFxuICAgICAgICAgICAgc2lsZW50OiB0cnVlLFxuICAgICAgICAgICAgY29udGludWU6IGVuY29kZVVSSUNvbXBvbmVudChyZWRpcmVjdFVyaSksXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG5lZWRTdGF0ZSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdlbmVyYXRlU3RhdGUoKTtcblxuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnc3RhdGUnLCBzdGF0ZSk7XG4gICAgICAgICAgICBwYXJhbXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHF1ZXJ5OiBzdHJpbmcgPSB0aGlzLmJ1aWxkUXVlcnlTdHJpbmcocGFyYW1zKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2F1dGg/JyArIHF1ZXJ5O1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dvdXQocmVkaXJlY3RVcmk/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICB0aGlzLnNpZ25hdHVyZSA9IG51bGw7XG4gICAgICAgIHRoaXMudXNlciA9IG51bGw7XG4gICAgICAgIHRoaXMuY2xpZW50U2VjcmV0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5yZWZyZXNoVG9rZW4gPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNsZWFyID0gW1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoJ3NpZ25hdHVyZScpLFxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoJ3VzZXInKSxcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCdyZWZyZXNoX3Rva2VuJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnY2xpZW50X3NlY3JldCcpLFxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgUHJvbWlzZS5hbGwoY2xlYXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBlbmRwb2ludCA9IHRoaXMuY29uZmlnLmVuZHBvaW50ICsgJy9hdXRoL2xvZ291dCc7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RVcmkpIHtcbiAgICAgICAgICAgICAgICAgICAgZW5kcG9pbnQgKz0gJz9jb250aW51ZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlZGlyZWN0VXJpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXNvbHZlKGVuZHBvaW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U3RhdGUoKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdzdGF0ZScpO1xuICAgIH1cblxuICAgIHB1YmxpYyBidWlsZE5lc3RlZFVyaShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IHN0cmluZyB7XG4gICAgICAgIGxldCB1cmkgPSAnJztcblxuICAgICAgICBpZiAocm91dGUucm91dGVDb25maWcgJiYgcm91dGUucm91dGVDb25maWcucGF0aCkge1xuICAgICAgICAgICAgbGV0IHJvdXRlUGF0aCA9IHJvdXRlLnJvdXRlQ29uZmlnLnBhdGg7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJvdXRlLnBhcmFtcykge1xuICAgICAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKCc6JyArIGtleSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcm91dGVQYXRoID0gcm91dGVQYXRoLnJlcGxhY2UocmUsIHJvdXRlLnBhcmFtc1trZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHVyaSArPSAnLycgKyByb3V0ZVBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm91dGUuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goKGl0ZW06IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpID0+IHtcbiAgICAgICAgICAgICAgICB1cmkgKz0gdGhpcy5idWlsZE5lc3RlZFVyaShpdGVtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVyaTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlZnJlc2hUb2tlbigpOiBQcm9taXNlPFNpZ25hdHVyZSB8IG51bGw+IHtcbiAgICAgICAgaWYgKG51bGwgIT09IHRoaXMucmVmcmVzaFRva2VuKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMucmVmcmVzaFRva2VuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdyZWZyZXNoX3Rva2VuJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbGllbnRTZWNyZXQoKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLmNsaWVudFNlY3JldCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLmNsaWVudFNlY3JldCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgnY2xpZW50X3NlY3JldCcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VXJpKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXBpLycgKyB0aGlzLlZFUlNJT04gKyBwYXRoO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRDdXJyZW50T3JpZ2luKHBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gd2luZG93LmxvY2F0aW9uLm9yaWdpbiArIHRoaXMubG9jYXRpb24ucHJlcGFyZUV4dGVybmFsVXJsKHBhdGggfHwgJycpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVTdGF0ZSgpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBwb3NzaWJsZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG4gICAgICAgIGxldCB0ZXh0ID0gJyc7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICAgICAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFF1ZXJ5U3RyaW5nKHBhcmFtczogb2JqZWN0KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBPYmplY3Qua2V5cyhwYXJhbXMpLm1hcCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChwYXJhbXNba2V5XSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBxdWVyeVBhcmFtcy5qb2luKCcmJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGdvVG9BY2NvdW50RW5kcG9pbnQocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbHRyaW0gPSB0ZXh0ID0+IHRleHQucmVwbGFjZSgvXlxcLysvLCAnJyk7XG5cbiAgICAgICAgY29uc3QgbmV4dCA9IHRoaXMuZ2V0Q3VycmVudE9yaWdpbignLycgKyBsdHJpbSh0aGlzLmJ1aWxkTmVzdGVkVXJpKHJvdXRlLnJvb3QpKSk7XG5cbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnbmFjb19pbnRlbmRlZF91cmwnLCBuZXh0KS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVkaXJlY3QodGhpcy5sb2dpbih0aGlzLmNvbmZpZy5zY29wZXMsIHRoaXMuZ2V0Q3VycmVudE9yaWdpbignL2F1dGgnKSkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ29Ub0ludGVuZGVkVXJsKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0b3JhZ2UuZ2V0PHN0cmluZz4oJ25hY29faW50ZW5kZWRfdXJsJykudGhlbih1cmwgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnbmFjb19pbnRlbmRlZF91cmwnKTtcbiAgICAgICAgICAgIHRoaXMucmVkaXJlY3QodXJsIHx8ICcvJyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWRpcmVjdCh1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi92YWx1ZXMvY29uZmlnJztcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuLi9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJFUVVFU1QsIFJFU1BPTlNFIH0gZnJvbSAnQG5ndW5pdmVyc2FsL2V4cHJlc3MtZW5naW5lL3Rva2Vucyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vbmFjby5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29FeHByZXNzU2VydmljZSBleHRlbmRzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZzogQ29uZmlnLFxuICAgICAgICByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZSxcbiAgICAgICAgaHR0cDogSHR0cENsaWVudCxcbiAgICAgICAgbG9jYXRpb246IExvY2F0aW9uLFxuICAgICAgICBASW5qZWN0KFJFUVVFU1QpIHByaXZhdGUgcmVxdWVzdDogYW55LFxuICAgICAgICBASW5qZWN0KFJFU1BPTlNFKSBwcml2YXRlIHJlc3BvbnNlOiBhbnksXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGNvbmZpZywgcm91dGVyLCBzdG9yYWdlLCBodHRwLCBsb2NhdGlvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hXaXRoU2lsZW50QXV0aCgpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Q3VycmVudE9yaWdpbihwYXRoOiBzdHJpbmcgPSAnJyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLnJlcXVlc3QucHJvdG9jb2x9Oi8vJHt0aGlzLnJlcXVlc3QuaGVhZGVycy5ob3N0fSR7dGhpcy5sb2NhdGlvbi5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCB8fCAnJyl9YDtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVkaXJlY3QodXJsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZWRpcmVjdCgzMDIsIHVybCk7XG4gICAgICAgIHRoaXMucmVzcG9uc2UuZW5kKCk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIFNpZ25hdHVyZSB7XG4gICAgcHVibGljIGV4cGlyZXNJbj86IG51bWJlcjtcbiAgICBwdWJsaWMgdG9rZW46IHN0cmluZztcbiAgICBwdWJsaWMgdHlwZTogc3RyaW5nO1xuICAgIHB1YmxpYyBzY29wZXM/OiBzdHJpbmc7XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IGZpcnN0LCBtYXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vZG9tYWlucy9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGVkR3VhcmQgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSwgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24pIHt9XG5cbiAgICBwdWJsaWMgY2FuQWN0aXZhdGUocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFjby5nZXRVc2VyKCkucGlwZShcbiAgICAgICAgICAgIGZpcnN0KCksXG4gICAgICAgICAgICBtYXAoKHVzZXI6IFVzZXIgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IHVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYWNvLmdvVG9BY2NvdW50RW5kcG9pbnQocm91dGUucm9vdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuICEhdXNlcjtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZUNoaWxkKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbkFjdGl2YXRlKHJvdXRlKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEV2ZW50LCBIdHRwSGFuZGxlciwgSHR0cEludGVyY2VwdG9yLCBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IGZyb20sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyByZXRyeVdoZW4sIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEF1dGhJbnRlcmNlcHRvciBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UpIHt9XG5cbiAgICBwdWJsaWMgaW50ZXJjZXB0KHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XG4gICAgICAgIGxldCBuZWVkUmV0cnk6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMubmFjby5nZXRTaWduYXR1cmUoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFzaWduYXR1cmUpIHtcbiAgICAgICAgICAgICAgICAgICAgbmVlZFJldHJ5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShcbiAgICAgICAgICAgICAgICAgICAgcmVxLmNsb25lKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgJHtzaWduYXR1cmUudHlwZX0gJHtzaWduYXR1cmUudG9rZW59YCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHJldHJ5V2hlbigoZXJyb3I6IE9ic2VydmFibGU8SHR0cEVycm9yUmVzcG9uc2U+KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzICE9PSA0MDEgfHwgIW5lZWRSZXRyeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFJldHJ5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYWNvLnJlZnJlc2hVc2VyKCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHVzZXI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi8uLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBjb25jYXQsIGZyb20sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmFrZXItYXV0aC1wYWdlJyxcbiAgICB0ZW1wbGF0ZTogJ3t7IG1lc3NhZ2UkIHwgYXN5bmMgfX0nLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoUGFnZSB7XG4gICAgcHVibGljIG1lc3NhZ2UkOiBPYnNlcnZhYmxlPHN0cmluZz47XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSwgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24pIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlJCA9IGNvbmNhdChvZignQXV0aGVudGljYXRpbmcuLi4nKSwgdGhpcy5oYW5kbGUoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGhhbmRsZSgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gZnJvbSh0aGlzLm5hY28uZ2V0U3RhdGUoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcChzdGF0ZSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucm91dGUucXVlcnlQYXJhbXMucGlwZShcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKHBhcmFtcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUgJiYgcGFyYW1zLnN0YXRlICE9PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCdJbnZhbGlkIENTUkYgVG9rZW4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgocGFyYW1zOiBQYXJhbXMpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm5hY28uc2V0VXNlcihudWxsKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5hY28uc2V0U2lnbmF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0luOiBwYXJhbXMuZXhwaXJlc19pbixcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogcGFyYW1zLnRva2VuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgIHRva2VuOiBwYXJhbXMuYWNjZXNzX3Rva2VuLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmFjby5nZXRVc2VyKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCh1c2VyID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gdXNlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgRXJyb3IoJ1VuYXV0aGVudGljYXRlZCEnKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5uYWNvLmdvVG9JbnRlbmRlZFVybCgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuICdTdWNjZXNzJztcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgY2F0Y2hFcnJvcihlID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2YoZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uLy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduYWtlci1hdXRoLXNpbGVudCcsXG4gICAgdGVtcGxhdGU6ICdQbGVhc2Ugd2FpdC4uLicsXG59KVxuZXhwb3J0IGNsYXNzIEF1dGhTaWxlbnRQYWdlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSBuYWNvOiBOYWNvU2VydmljZSkge31cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5uYWNvLnJlZGlyZWN0KCcvJyk7XG4gICAgICAgIH0sIDIwMDApO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlck1vZHVsZSwgUm91dGVzIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IEF1dGhQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLnBhZ2UnO1xuaW1wb3J0IHsgQXV0aFNpbGVudFBhZ2UgfSBmcm9tICcuL3BhZ2VzL2F1dGgtc2lsZW50LnBhZ2UnO1xuXG5jb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAgICB7XG4gICAgICAgIHBhdGg6ICdhdXRoJyxcbiAgICAgICAgY29tcG9uZW50OiBBdXRoUGFnZVxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXRoOiAnYXV0aC9zaWxlbnQnLFxuICAgICAgICBjb21wb25lbnQ6IEF1dGhTaWxlbnRQYWdlXG4gICAgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBBVVRIX1JPVVRJTkc6IE1vZHVsZVdpdGhQcm92aWRlcnMgPSBSb3V0ZXJNb2R1bGUuZm9yQ2hpbGQocm91dGVzKTtcbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBVVRIX1JPVVRJTkcgfSBmcm9tICcuL3JvdXRlcyc7XG5pbXBvcnQgeyBBdXRoUGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC5wYWdlJztcbmltcG9ydCB7IEF1dGhTaWxlbnRQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLXNpbGVudC5wYWdlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgQVVUSF9ST1VUSU5HXSxcbiAgICBkZWNsYXJhdGlvbnM6IFtBdXRoUGFnZSwgQXV0aFNpbGVudFBhZ2VdLFxufSlcbmV4cG9ydCBjbGFzcyBOYWNvVmlld01vZHVsZSB7fVxuIiwiaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4sIE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZEd1YXJkIH0gZnJvbSAnLi9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZCc7XG5pbXBvcnQgeyBOYWNvVmlld01vZHVsZSB9IGZyb20gJy4vdmlld3MvbW9kdWxlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vZG9tYWlucy92YWx1ZXMvY29uZmlnJztcblxuY29uc3QgTkFDT19ST09UX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbignTkFDT19ST09UX0NPTkZJRycpO1xuXG5leHBvcnQgZnVuY3Rpb24gbmFjb0NvbmZpZ0ZhY3RvcnkoY29uZmlnOiBDb25maWcpIHtcbiAgICByZXR1cm4gbmV3IENvbmZpZyhjb25maWcpO1xufVxuXG5ATmdNb2R1bGUoe1xuICAgIGltcG9ydHM6IFtOYWNvVmlld01vZHVsZV0sXG59KVxuZXhwb3J0IGNsYXNzIE5hY29Nb2R1bGUge1xuICAgIHB1YmxpYyBzdGF0aWMgZm9yUm9vdChjb25maWc6IENvbmZpZyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmdNb2R1bGU6IE5hY29Nb2R1bGUsXG4gICAgICAgICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGU6IE5BQ09fUk9PVF9DT05GSUcsXG4gICAgICAgICAgICAgICAgICAgIHVzZVZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGU6IENvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAgdXNlRmFjdG9yeTogbmFjb0NvbmZpZ0ZhY3RvcnksXG4gICAgICAgICAgICAgICAgICAgIGRlcHM6IFtOQUNPX1JPT1RfQ09ORklHXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIE5hY29TZXJ2aWNlLFxuICAgICAgICAgICAgICAgIEF1dGhlbnRpY2F0ZWRHdWFyZCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbInRzbGliXzEuX192YWx1ZXMiLCJ0c2xpYl8xLl9fZXh0ZW5kcyIsIm1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBQUE7b0JBS3VCLElBQXNCO3dCQUpkLGdDQUFnQztzQkFFbEMsYUFBYTtRQUdsQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQzs7aUJBTmxDO0lBUUM7Ozs7Ozs7Ozs7UUNFSSxJQUFJLG1CQUFDLFVBQVUsQ0FBQyxjQUFNLE9BQUEsSUFBSSxHQUFBLENBQVEsRUFBQztrQ0FDbEIsSUFBSTs7ZUFYMUI7Ozs7Ozs7O3lCQ3NCa0IsTUFBYyxFQUNkLE1BQWMsRUFDZCxPQUFnQixFQUNoQixJQUFnQixFQUNoQixRQUFrQjtRQUpsQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFDaEIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNoQixhQUFRLEdBQVIsUUFBUSxDQUFVO3VCQVpOLElBQUk7eUJBRVEsSUFBSTtvQkFDZCxJQUFJOzRCQUNTLElBQUk7NEJBQ1AsSUFBSTs7Ozs7O0lBVW5DLDZCQUFPOzs7O2NBQUMsSUFBaUI7UUFDNUIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Ozs7O0lBR2QsNkJBQU87Ozs7O1FBQ1YsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRTtZQUNwQixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDeEI7UUFFRCxxQkFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVyQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQ2pDLFNBQVMsQ0FB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 |
\ | No newline at end of file |