UNPKG

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