1 | import { __decorate, __metadata } from 'tslib';
|
2 | import { forwardRef, Injectable, InjectionToken, Component, NgModule } from '@angular/core';
|
3 | import { Type, plainToClass } from 'class-transformer';
|
4 | import { Router, ActivatedRoute, RouterModule } from '@angular/router';
|
5 | import { Storage, UbudStorageModule } from '@ubud/storage';
|
6 | import { forkJoin, of } from 'rxjs';
|
7 | import { fromPromise } from 'rxjs/internal/observable/fromPromise';
|
8 | import { map, switchMap, tap, first, catchError } from 'rxjs/internal/operators';
|
9 | import { HttpClient } from '@angular/common/http';
|
10 | import { PlatformLocation } from '@angular/common';
|
11 | import { ErrorObservable } from 'rxjs-compat/observable/ErrorObservable';
|
12 |
|
13 | /**
|
14 | * @fileoverview added by tsickle
|
15 | * @suppress {checkTypes} checked by tsc
|
16 | */
|
17 | class Config {
|
18 | /**
|
19 | * @param {?=} data
|
20 | */
|
21 | constructor(data) {
|
22 | this.endpoint = 'https://account.kemnaker.go.id';
|
23 | Object.assign(this, data);
|
24 | }
|
25 | }
|
26 |
|
27 | /**
|
28 | * @fileoverview added by tsickle
|
29 | * @suppress {checkTypes} checked by tsc
|
30 | */
|
31 | class User {
|
32 | }
|
33 | __decorate([
|
34 | Type(/** @type {?} */ (forwardRef(() => Date))),
|
35 | __metadata("design:type", Date)
|
36 | ], User.prototype, "updatedAt", void 0);
|
37 |
|
38 | /**
|
39 | * @fileoverview added by tsickle
|
40 | * @suppress {checkTypes} checked by tsc
|
41 | */
|
42 | class NacoService {
|
43 | /**
|
44 | * @param {?} config
|
45 | * @param {?} router
|
46 | * @param {?} storage
|
47 | * @param {?} http
|
48 | */
|
49 | constructor(config, router, storage, http) {
|
50 | this.config = config;
|
51 | this.router = router;
|
52 | this.storage = storage;
|
53 | this.http = http;
|
54 | this.VERSION = 'v1';
|
55 | this.signature = null;
|
56 | this.user = null;
|
57 | this.refreshToken = null;
|
58 | this.clientSecret = null;
|
59 | }
|
60 | /**
|
61 | * @param {?} user
|
62 | * @return {?}
|
63 | */
|
64 | setUser(user) {
|
65 | this.user = user;
|
66 | this.storage.set('user', user);
|
67 | }
|
68 | /**
|
69 | * @return {?}
|
70 | */
|
71 | getUser() {
|
72 | if (null !== this.user) {
|
73 | return of(this.user);
|
74 | }
|
75 | return fromPromise(this.storage.get('user')).pipe(switchMap((user) => {
|
76 | if (null !== user) {
|
77 | return of(user);
|
78 | }
|
79 | const /** @type {?} */ uri = this.getUri('/users/me');
|
80 | return fromPromise(this.getSignature()).pipe(switchMap((signature) => {
|
81 | if (null === signature) {
|
82 | return of(null);
|
83 | }
|
84 | const /** @type {?} */ options = {
|
85 | headers: {
|
86 | Authorization: `${signature.type} ${signature.token}`,
|
87 | },
|
88 | };
|
89 | return this.http.get(uri, options).pipe(map((res) => {
|
90 | if (res.data) {
|
91 | return res.data;
|
92 | }
|
93 | throw new Error('There are no body to be transformed');
|
94 | }), map((data) => {
|
95 | const /** @type {?} */ authUser = plainToClass(User, data);
|
96 | this.setUser(authUser);
|
97 | return authUser;
|
98 | }));
|
99 | }));
|
100 | }));
|
101 | }
|
102 | /**
|
103 | * @return {?}
|
104 | */
|
105 | getSignature() {
|
106 | if (null !== this.signature) {
|
107 | return Promise.resolve(this.signature);
|
108 | }
|
109 | return this.storage.get('signature');
|
110 | }
|
111 | /**
|
112 | * @param {?} signature
|
113 | * @return {?}
|
114 | */
|
115 | setSignature(signature) {
|
116 | this.signature = signature;
|
117 | this.storage.set('signature', signature);
|
118 | }
|
119 | /**
|
120 | * @param {?} secret
|
121 | * @return {?}
|
122 | */
|
123 | setClientSecret(secret) {
|
124 | this.clientSecret = secret;
|
125 | this.storage.set('client_secret', secret);
|
126 | }
|
127 | /**
|
128 | * @param {?} refreshToken
|
129 | * @return {?}
|
130 | */
|
131 | setRefreshToken(refreshToken) {
|
132 | this.refreshToken = refreshToken;
|
133 | this.storage.set('refresh_token', refreshToken);
|
134 | }
|
135 | /**
|
136 | * @param {?=} scopes
|
137 | * @return {?}
|
138 | */
|
139 | refreshUser(scopes) {
|
140 | this.setUser(null);
|
141 | this.setSignature(null);
|
142 | return forkJoin(this.getRefreshToken(), this.getClientSecret()).pipe(switchMap((results) => {
|
143 | const /** @type {?} */ refreshToken = results[0];
|
144 | const /** @type {?} */ clientSecret = results[1];
|
145 | if (refreshToken && clientSecret) {
|
146 | const /** @type {?} */ request = this.http.post(this.getUri('/tokens'), {
|
147 | grant_type: 'refresh_token',
|
148 | scopes: scopes || 'basic email',
|
149 | client_id: this.config.clientId,
|
150 | client_secret: clientSecret,
|
151 | refresh_token: refreshToken.token,
|
152 | });
|
153 | return request.pipe(tap((tokens) => {
|
154 | if (tokens && tokens.data) {
|
155 | this.setSignature({
|
156 | expiresIn: tokens.data.expires_in,
|
157 | type: tokens.data.token_type,
|
158 | token: tokens.data.access_token,
|
159 | });
|
160 | this.setRefreshToken({
|
161 | type: tokens.data.token_type,
|
162 | token: tokens.data.refresh_token,
|
163 | });
|
164 | }
|
165 | }), map((tokens) => tokens && tokens.data), switchMap((hasToken) => {
|
166 | if (hasToken) {
|
167 | return this.getUser();
|
168 | }
|
169 | return of(null);
|
170 | }));
|
171 | }
|
172 | return of(null);
|
173 | }));
|
174 | }
|
175 | /**
|
176 | * @param {?} scopes
|
177 | * @param {?=} redirectUri
|
178 | * @return {?}
|
179 | */
|
180 | login(scopes, redirectUri) {
|
181 | if (!redirectUri) {
|
182 | redirectUri = this.router.url;
|
183 | }
|
184 | const /** @type {?} */ state = this.generateState();
|
185 | this.storage.set('state', state);
|
186 | const /** @type {?} */ query = this.buildQueryString({
|
187 | 'response_type': 'token',
|
188 | 'scopes': scopes,
|
189 | 'client': this.config.clientId,
|
190 | 'state': state,
|
191 | 'continue': redirectUri,
|
192 | });
|
193 | return this.config.endpoint + '/auth?' + query;
|
194 | }
|
195 | /**
|
196 | * @param {?=} redirectUri
|
197 | * @return {?}
|
198 | */
|
199 | logout(redirectUri) {
|
200 | this.signature = null;
|
201 | this.user = null;
|
202 | return new Promise(resolve => {
|
203 | Promise.all([
|
204 | this.storage.remove('signature'),
|
205 | this.storage.remove('user'),
|
206 | ]).then(() => {
|
207 | let /** @type {?} */ endpoint = this.config.endpoint + '/auth/logout';
|
208 | if (redirectUri) {
|
209 | endpoint += '?continue=' + redirectUri;
|
210 | }
|
211 | resolve(endpoint);
|
212 | });
|
213 | });
|
214 | }
|
215 | /**
|
216 | * @return {?}
|
217 | */
|
218 | getState() {
|
219 | return this.storage.get('state');
|
220 | }
|
221 | /**
|
222 | * @param {?} route
|
223 | * @return {?}
|
224 | */
|
225 | buildNestedUri(route) {
|
226 | let /** @type {?} */ uri = '';
|
227 | if (route.routeConfig && route.routeConfig.path) {
|
228 | uri += '/' + route.routeConfig.path;
|
229 | }
|
230 | if (route.children) {
|
231 | route.children.forEach((item) => {
|
232 | uri += this.buildNestedUri(item);
|
233 | });
|
234 | }
|
235 | return uri;
|
236 | }
|
237 | /**
|
238 | * @return {?}
|
239 | */
|
240 | getRefreshToken() {
|
241 | if (null !== this.refreshToken) {
|
242 | return Promise.resolve(this.refreshToken);
|
243 | }
|
244 | return this.storage.get('refresh_token');
|
245 | }
|
246 | /**
|
247 | * @return {?}
|
248 | */
|
249 | getClientSecret() {
|
250 | if (null !== this.clientSecret) {
|
251 | return Promise.resolve(this.clientSecret);
|
252 | }
|
253 | return this.storage.get('client_secret');
|
254 | }
|
255 | /**
|
256 | * @param {?} path
|
257 | * @return {?}
|
258 | */
|
259 | getUri(path) {
|
260 | return this.config.endpoint + '/api/' + this.VERSION + path;
|
261 | }
|
262 | /**
|
263 | * @return {?}
|
264 | */
|
265 | generateState() {
|
266 | const /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
267 | let /** @type {?} */ text = '';
|
268 | for (let /** @type {?} */ i = 0; i < 5; i++) {
|
269 | text += possible.charAt(Math.floor(Math.random() * possible.length));
|
270 | }
|
271 | return text;
|
272 | }
|
273 | /**
|
274 | * @param {?} params
|
275 | * @return {?}
|
276 | */
|
277 | buildQueryString(params) {
|
278 | const /** @type {?} */ queryParams = Object.keys(params).map((key) => {
|
279 | return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
|
280 | });
|
281 | return queryParams.join('&');
|
282 | }
|
283 | }
|
284 | NacoService.decorators = [
|
285 | { type: Injectable },
|
286 | ];
|
287 | /** @nocollapse */
|
288 | NacoService.ctorParameters = () => [
|
289 | { type: Config },
|
290 | { type: Router },
|
291 | { type: Storage },
|
292 | { type: HttpClient }
|
293 | ];
|
294 |
|
295 | /**
|
296 | * @fileoverview added by tsickle
|
297 | * @suppress {checkTypes} checked by tsc
|
298 | */
|
299 | class Signature {
|
300 | }
|
301 |
|
302 | /**
|
303 | * @fileoverview added by tsickle
|
304 | * @suppress {checkTypes} checked by tsc
|
305 | */
|
306 | class AuthenticatedGuard {
|
307 | /**
|
308 | * @param {?} naco
|
309 | * @param {?} storage
|
310 | * @param {?} platformLocation
|
311 | */
|
312 | constructor(naco, storage, platformLocation) {
|
313 | this.naco = naco;
|
314 | this.storage = storage;
|
315 | this.platformLocation = platformLocation;
|
316 | }
|
317 | /**
|
318 | * @param {?} route
|
319 | * @return {?}
|
320 | */
|
321 | canActivate(route) {
|
322 | return this.naco.getUser().pipe(first(), map((user) => {
|
323 | if (null === user) {
|
324 | const /** @type {?} */ base = this.rtrim((/** @type {?} */ (this.platformLocation)).location.href);
|
325 | const /** @type {?} */ uri = this.naco.buildNestedUri(route.root);
|
326 | const /** @type {?} */ next = base.replace(uri, '') + '/' + this.ltrim(uri);
|
327 | const /** @type {?} */ origin = base.replace(uri, '');
|
328 | this.storage.set('naco_intended_url', next).then(() => {
|
329 | window.location.href = this.naco.login('basic email', origin + '/auth');
|
330 | });
|
331 | }
|
332 | return !!user;
|
333 | }));
|
334 | }
|
335 | /**
|
336 | * @param {?} route
|
337 | * @return {?}
|
338 | */
|
339 | canActivateChild(route) {
|
340 | return this.canActivate(route);
|
341 | }
|
342 | /**
|
343 | * @param {?} text
|
344 | * @return {?}
|
345 | */
|
346 | ltrim(text) {
|
347 | return text.replace(/^\/+/, '');
|
348 | }
|
349 | /**
|
350 | * @param {?} text
|
351 | * @return {?}
|
352 | */
|
353 | rtrim(text) {
|
354 | return text.replace(/\/+$/, '');
|
355 | }
|
356 | }
|
357 | AuthenticatedGuard.decorators = [
|
358 | { type: Injectable },
|
359 | ];
|
360 | /** @nocollapse */
|
361 | AuthenticatedGuard.ctorParameters = () => [
|
362 | { type: NacoService },
|
363 | { type: Storage },
|
364 | { type: PlatformLocation }
|
365 | ];
|
366 |
|
367 | /**
|
368 | * @fileoverview added by tsickle
|
369 | * @suppress {checkTypes} checked by tsc
|
370 | */
|
371 | class AuthInterceptor {
|
372 | /**
|
373 | * @param {?} naco
|
374 | */
|
375 | constructor(naco) {
|
376 | this.naco = naco;
|
377 | }
|
378 | /**
|
379 | * @param {?} req
|
380 | * @param {?} next
|
381 | * @return {?}
|
382 | */
|
383 | intercept(req, next) {
|
384 | return fromPromise(this.naco.getSignature()).pipe(switchMap((signature) => {
|
385 | if (!signature) {
|
386 | return next.handle(req);
|
387 | }
|
388 | return next
|
389 | .handle(req.clone({
|
390 | setHeaders: {
|
391 | Authorization: `${signature.type} ${signature.token}`,
|
392 | },
|
393 | }))
|
394 | .pipe(catchError((error) => {
|
395 | if (error.status === 401) {
|
396 | return this.naco.refreshUser().pipe(switchMap(() => fromPromise(this.naco.getSignature())), switchMap((newSignature) => {
|
397 | return next.handle(req.clone({
|
398 | setHeaders: {
|
399 | Authorization: `${newSignature.type} ${newSignature.token}`,
|
400 | },
|
401 | }));
|
402 | }));
|
403 | }
|
404 | return ErrorObservable.create(error);
|
405 | }));
|
406 | }));
|
407 | }
|
408 | }
|
409 | AuthInterceptor.decorators = [
|
410 | { type: Injectable },
|
411 | ];
|
412 | /** @nocollapse */
|
413 | AuthInterceptor.ctorParameters = () => [
|
414 | { type: NacoService }
|
415 | ];
|
416 |
|
417 | /**
|
418 | * @fileoverview added by tsickle
|
419 | * @suppress {checkTypes} checked by tsc
|
420 | */
|
421 | /**
|
422 | * @param {?} config
|
423 | * @param {?} router
|
424 | * @param {?} storage
|
425 | * @param {?} http
|
426 | * @return {?}
|
427 | */
|
428 | function nacoFactory(config, router, storage, http) {
|
429 | return new NacoService(new Config(Object.assign({}, config)), router, storage, http);
|
430 | }
|
431 | const /** @type {?} */ NACO_CONFIG = new InjectionToken('NACO_CONFIG');
|
432 |
|
433 | /**
|
434 | * @fileoverview added by tsickle
|
435 | * @suppress {checkTypes} checked by tsc
|
436 | */
|
437 | class AuthPage {
|
438 | /**
|
439 | * @param {?} route
|
440 | * @param {?} naco
|
441 | * @param {?} storage
|
442 | */
|
443 | constructor(route, naco, storage) {
|
444 | this.route = route;
|
445 | this.naco = naco;
|
446 | this.storage = storage;
|
447 | this.message = 'Authenticating...';
|
448 | this.route.queryParams.subscribe((params) => this.handle(params));
|
449 | }
|
450 | /**
|
451 | * @param {?} params
|
452 | * @return {?}
|
453 | */
|
454 | handle(params) {
|
455 | if (params["state"]) {
|
456 | this.naco.getState().then((state) => {
|
457 | if (state !== params["state"]) {
|
458 | this.message = 'Invalid CSRF';
|
459 | return;
|
460 | }
|
461 | this.authenticate(params);
|
462 | });
|
463 | }
|
464 | else {
|
465 | this.authenticate(params);
|
466 | }
|
467 | }
|
468 | /**
|
469 | * @param {?} params
|
470 | * @return {?}
|
471 | */
|
472 | authenticate(params) {
|
473 | const /** @type {?} */ signature = {
|
474 | expiresIn: params["expires_in"],
|
475 | type: params["token_type"],
|
476 | token: params["access_token"],
|
477 | };
|
478 | this.naco.setSignature(signature);
|
479 | this.naco.getUser().subscribe((user) => {
|
480 | if (null !== user) {
|
481 | this.storage.get('naco_intended_url').then((url) => {
|
482 | this.storage.remove('naco_intended_url').then(() => {
|
483 | window.location.href = url ? url : '/';
|
484 | });
|
485 | });
|
486 | return;
|
487 | }
|
488 | this.message = 'Unauthenticated!';
|
489 | });
|
490 | }
|
491 | }
|
492 | AuthPage.decorators = [
|
493 | { type: Component, args: [{
|
494 | selector: 'naker-auth-page',
|
495 | template: '{{ message }}',
|
496 | },] },
|
497 | ];
|
498 | /** @nocollapse */
|
499 | AuthPage.ctorParameters = () => [
|
500 | { type: ActivatedRoute },
|
501 | { type: NacoService },
|
502 | { type: Storage }
|
503 | ];
|
504 |
|
505 | /**
|
506 | * @fileoverview added by tsickle
|
507 | * @suppress {checkTypes} checked by tsc
|
508 | */
|
509 | const /** @type {?} */ routes = [
|
510 | {
|
511 | path: 'auth',
|
512 | component: AuthPage
|
513 | },
|
514 | ];
|
515 | const /** @type {?} */ AUTH_ROUTING = RouterModule.forChild(routes);
|
516 |
|
517 | /**
|
518 | * @fileoverview added by tsickle
|
519 | * @suppress {checkTypes} checked by tsc
|
520 | */
|
521 | class NacoViewModule {
|
522 | }
|
523 | NacoViewModule.decorators = [
|
524 | { type: NgModule, args: [{
|
525 | imports: [
|
526 | AUTH_ROUTING,
|
527 | ],
|
528 | declarations: [
|
529 | AuthPage,
|
530 | ],
|
531 | },] },
|
532 | ];
|
533 |
|
534 | /**
|
535 | * @fileoverview added by tsickle
|
536 | * @suppress {checkTypes} checked by tsc
|
537 | */
|
538 | class NacoModule {
|
539 | /**
|
540 | * @param {?} config
|
541 | * @return {?}
|
542 | */
|
543 | static forRoot(config) {
|
544 | return {
|
545 | ngModule: NacoModule,
|
546 | providers: [
|
547 | {
|
548 | provide: NACO_CONFIG,
|
549 | useValue: config,
|
550 | },
|
551 | {
|
552 | provide: NacoService,
|
553 | useFactory: nacoFactory,
|
554 | deps: [NACO_CONFIG, Router, Storage, HttpClient],
|
555 | },
|
556 | AuthenticatedGuard,
|
557 | ],
|
558 | };
|
559 | }
|
560 | }
|
561 | NacoModule.decorators = [
|
562 | { type: NgModule, args: [{
|
563 | imports: [
|
564 | UbudStorageModule,
|
565 | NacoViewModule,
|
566 | ],
|
567 | },] },
|
568 | ];
|
569 |
|
570 | /**
|
571 | * @fileoverview added by tsickle
|
572 | * @suppress {checkTypes} checked by tsc
|
573 | */
|
574 |
|
575 | /**
|
576 | * @fileoverview added by tsickle
|
577 | * @suppress {checkTypes} checked by tsc
|
578 | */
|
579 |
|
580 | export { NacoService, User, Signature, Config, AuthenticatedGuard, AuthInterceptor, NacoModule, NACO_CONFIG as ɵe, nacoFactory as ɵd, NacoViewModule as ɵa, AuthPage as ɵc, AUTH_ROUTING as ɵb };
|
581 |
|
582 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFrZXItbmFjby5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvY29uZmlnLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL21vZGVscy91c2VyLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvc2lnbmF0dXJlLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZC50cyIsIm5nOi8vQG5ha2VyL25hY28vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiLCJuZzovL0BuYWtlci9uYWNvL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnkudHMiLCJuZzovL0BuYWtlci9uYWNvL3ZpZXdzL3BhZ2VzL2F1dGgucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3Mvcm91dGVzLnRzIiwibmc6Ly9AbmFrZXIvbmFjby92aWV3cy9tb2R1bGUudHMiLCJuZzovL0BuYWtlci9uYWNvL25hY28ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHB1YmxpYyBlbmRwb2ludDogc3RyaW5nID0gJ2h0dHBzOi8vYWNjb3VudC5rZW1uYWtlci5nby5pZCc7XG4gICAgcHVibGljIGNsaWVudElkOiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZGF0YT86IFBhcnRpYWw8Q29uZmlnPikge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRhdGEpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IGZvcndhcmRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5cbmV4cG9ydCBjbGFzcyBVc2VyIHtcbiAgICBwdWJsaWMgaWQ6IHN0cmluZztcbiAgICBwdWJsaWMgdXNlcm5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgZW1haWw/OiBzdHJpbmc7XG4gICAgcHVibGljIG5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgc3RhdHVzOiBudW1iZXI7XG5cbiAgICBAVHlwZShmb3J3YXJkUmVmKCgpID0+IERhdGUpIGFzIGFueSlcbiAgICBwdWJsaWMgdXBkYXRlZEF0OiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL3ZhbHVlcy9jb25maWcnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL21vZGVscy91c2VyJztcbmltcG9ydCB7IGZvcmtKb2luLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgU2lnbmF0dXJlIH0gZnJvbSAnLi4vdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSB9IGZyb20gJ3J4anMvaW50ZXJuYWwvb2JzZXJ2YWJsZS9mcm9tUHJvbWlzZSc7XG5pbXBvcnQgeyBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgcGxhaW5Ub0NsYXNzIH0gZnJvbSAnY2xhc3MtdHJhbnNmb3JtZXInO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgVkVSU0lPTiA9ICd2MSc7XG5cbiAgICBwcml2YXRlIHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB1c2VyOiBVc2VyIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgY2xpZW50U2VjcmV0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogQ29uZmlnLCBwcml2YXRlIHJvdXRlcjogUm91dGVyLCBwcml2YXRlIHN0b3JhZ2U6IFN0b3JhZ2UsIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCkge1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRVc2VyKHVzZXI6IFVzZXIgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXNlciA9IHVzZXI7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3VzZXInLCB1c2VyKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VXNlcigpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnVzZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih0aGlzLnVzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHRoaXMuc3RvcmFnZS5nZXQoJ3VzZXInKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgodXNlcjogVXNlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gdXNlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YodXNlcik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdXJpID0gdGhpcy5nZXRVcmkoJy91c2Vycy9tZScpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHRoaXMuZ2V0U2lnbmF0dXJlKCkpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gc2lnbmF0dXJlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYCR7c2lnbmF0dXJlLnR5cGV9ICR7c2lnbmF0dXJlLnRva2VufWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4odXJpLCBvcHRpb25zKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmRhdGE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGFyZSBubyBib2R5IHRvIGJlIHRyYW5zZm9ybWVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aFVzZXI6IGFueSA9IHBsYWluVG9DbGFzcyhVc2VyLCBkYXRhKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFVzZXIoYXV0aFVzZXIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdXRoVXNlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2lnbmF0dXJlKCk6IFByb21pc2U8U2lnbmF0dXJlIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy5zaWduYXR1cmUpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5zaWduYXR1cmUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3NpZ25hdHVyZScpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRTaWduYXR1cmUoc2lnbmF0dXJlOiBTaWduYXR1cmUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zaWduYXR1cmUgPSBzaWduYXR1cmU7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3NpZ25hdHVyZScsIHNpZ25hdHVyZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldENsaWVudFNlY3JldChzZWNyZXQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsaWVudFNlY3JldCA9IHNlY3JldDtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnY2xpZW50X3NlY3JldCcsIHNlY3JldCk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFJlZnJlc2hUb2tlbihyZWZyZXNoVG9rZW46IFNpZ25hdHVyZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlZnJlc2hUb2tlbiA9IHJlZnJlc2hUb2tlbjtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmVmcmVzaF90b2tlbicsIHJlZnJlc2hUb2tlbik7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hVc2VyKHNjb3Blcz86IHN0cmluZyk6IE9ic2VydmFibGU8VXNlciB8IG51bGw+IHtcbiAgICAgICAgdGhpcy5zZXRVc2VyKG51bGwpO1xuICAgICAgICB0aGlzLnNldFNpZ25hdHVyZShudWxsKTtcblxuICAgICAgICByZXR1cm4gZm9ya0pvaW4odGhpcy5nZXRSZWZyZXNoVG9rZW4oKSwgdGhpcy5nZXRDbGllbnRTZWNyZXQoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgocmVzdWx0czogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmcmVzaFRva2VuOiBTaWduYXR1cmUgPSByZXN1bHRzWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFNlY3JldDogc3RyaW5nID0gcmVzdWx0c1sxXTtcblxuICAgICAgICAgICAgICAgIGlmIChyZWZyZXNoVG9rZW4gJiYgY2xpZW50U2VjcmV0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmh0dHAucG9zdCh0aGlzLmdldFVyaSgnL3Rva2VucycpLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXM6IHNjb3BlcyB8fCAnYmFzaWMgZW1haWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IGNsaWVudFNlY3JldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbi50b2tlbixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcCgodG9rZW5zOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW5zICYmIHRva2Vucy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXNJbjogdG9rZW5zLmRhdGEuZXhwaXJlc19pbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRva2Vucy5kYXRhLnRva2VuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW5zLmRhdGEuYWNjZXNzX3Rva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJlZnJlc2hUb2tlbih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0b2tlbnMuZGF0YS50b2tlbl90eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHRva2Vucy5kYXRhLnJlZnJlc2hfdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFwKCh0b2tlbnM6IGFueSkgPT4gdG9rZW5zICYmIHRva2Vucy5kYXRhKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoaGFzVG9rZW46IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzVG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dpbihzY29wZXM6IHN0cmluZywgcmVkaXJlY3RVcmk/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIXJlZGlyZWN0VXJpKSB7XG4gICAgICAgICAgICByZWRpcmVjdFVyaSA9IHRoaXMucm91dGVyLnVybDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5nZW5lcmF0ZVN0YXRlKCk7XG5cbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnc3RhdGUnLCBzdGF0ZSk7XG5cbiAgICAgICAgY29uc3QgcXVlcnk6IHN0cmluZyA9IHRoaXMuYnVpbGRRdWVyeVN0cmluZyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAncmVzcG9uc2VfdHlwZSc6ICd0b2tlbicsXG4gICAgICAgICAgICAgICAgJ3Njb3Blcyc6IHNjb3BlcyxcbiAgICAgICAgICAgICAgICAnY2xpZW50JzogdGhpcy5jb25maWcuY2xpZW50SWQsXG4gICAgICAgICAgICAgICAgJ3N0YXRlJzogc3RhdGUsXG4gICAgICAgICAgICAgICAgJ2NvbnRpbnVlJzogcmVkaXJlY3RVcmksXG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXV0aD8nICsgcXVlcnk7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ291dChyZWRpcmVjdFVyaT86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlID0gbnVsbDtcbiAgICAgICAgdGhpcy51c2VyID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnc2lnbmF0dXJlJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgndXNlcicpLFxuICAgICAgICAgICAgXSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGVuZHBvaW50ID0gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2F1dGgvbG9nb3V0JztcblxuICAgICAgICAgICAgICAgIGlmIChyZWRpcmVjdFVyaSkge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludCArPSAnP2NvbnRpbnVlPScgKyByZWRpcmVjdFVyaTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXNvbHZlKGVuZHBvaW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdzdGF0ZScpO1xuICAgIH1cblxuICAgIHB1YmxpYyBidWlsZE5lc3RlZFVyaShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IHN0cmluZyB7XG4gICAgICAgIGxldCB1cmkgPSAnJztcblxuICAgICAgICBpZiAocm91dGUucm91dGVDb25maWcgJiYgcm91dGUucm91dGVDb25maWcucGF0aCkge1xuICAgICAgICAgICAgdXJpICs9ICcvJyArIHJvdXRlLnJvdXRlQ29uZmlnLnBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm91dGUuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goKGl0ZW06IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpID0+IHtcbiAgICAgICAgICAgICAgICB1cmkgKz0gdGhpcy5idWlsZE5lc3RlZFVyaShpdGVtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVyaTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlZnJlc2hUb2tlbigpOiBQcm9taXNlPFNpZ25hdHVyZSB8IG51bGw+IHtcbiAgICAgICAgaWYgKG51bGwgIT09IHRoaXMucmVmcmVzaFRva2VuKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMucmVmcmVzaFRva2VuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdyZWZyZXNoX3Rva2VuJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbGllbnRTZWNyZXQoKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLmNsaWVudFNlY3JldCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLmNsaWVudFNlY3JldCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgnY2xpZW50X3NlY3JldCcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VXJpKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXBpLycgKyB0aGlzLlZFUlNJT04gKyBwYXRoO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVTdGF0ZSgpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBwb3NzaWJsZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG4gICAgICAgIGxldCB0ZXh0ID0gJyc7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICAgICAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFF1ZXJ5U3RyaW5nKHBhcmFtczogb2JqZWN0KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBPYmplY3Qua2V5cyhwYXJhbXMpLm1hcCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChwYXJhbXNba2V5XSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBxdWVyeVBhcmFtcy5qb2luKCcmJyk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIFNpZ25hdHVyZSB7XG4gICAgcHVibGljIGV4cGlyZXNJbj86IG51bWJlcjtcbiAgICBwdWJsaWMgdG9rZW46IHN0cmluZztcbiAgICBwdWJsaWMgdHlwZTogc3RyaW5nO1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2FuQWN0aXZhdGUsIENhbkFjdGl2YXRlQ2hpbGQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBmaXJzdCwgbWFwIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL2RvbWFpbnMvbW9kZWxzL3VzZXInO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgU3RvcmFnZSB9IGZyb20gJ0B1YnVkL3N0b3JhZ2UnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlci9zcmMvcm91dGVyX3N0YXRlJztcbmltcG9ydCB7IFBsYXRmb3JtTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQXV0aGVudGljYXRlZEd1YXJkIGltcGxlbWVudHMgQ2FuQWN0aXZhdGUsIENhbkFjdGl2YXRlQ2hpbGQge1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIG5hY286IE5hY29TZXJ2aWNlLCBwcml2YXRlIHN0b3JhZ2U6IFN0b3JhZ2UsIHByaXZhdGUgcGxhdGZvcm1Mb2NhdGlvbjogUGxhdGZvcm1Mb2NhdGlvbikge1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5uYWNvLmdldFVzZXIoKS5waXBlKFxuICAgICAgICAgICAgZmlyc3QoKSxcbiAgICAgICAgICAgIG1hcCgodXNlcjogVXNlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gdXNlcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBiYXNlID0gdGhpcy5ydHJpbSgodGhpcy5wbGF0Zm9ybUxvY2F0aW9uIGFzIGFueSkubG9jYXRpb24uaHJlZik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVyaSA9IHRoaXMubmFjby5idWlsZE5lc3RlZFVyaShyb3V0ZS5yb290KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IGJhc2UucmVwbGFjZSh1cmksICcnKSArICcvJyArIHRoaXMubHRyaW0odXJpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gYmFzZS5yZXBsYWNlKHVyaSwgJycpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ25hY29faW50ZW5kZWRfdXJsJywgbmV4dCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHRoaXMubmFjby5sb2dpbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFzaWMgZW1haWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiArICcvYXV0aCcsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gISF1c2VyO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbkFjdGl2YXRlQ2hpbGQocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWN0aXZhdGUocm91dGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbHRyaW0odGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSgvXlxcLysvLCcnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJ0cmltKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcLyskLywnJyk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSHR0cEVycm9yUmVzcG9uc2UsIEh0dHBFdmVudCwgSHR0cEhhbmRsZXIsIEh0dHBJbnRlcmNlcHRvciwgSHR0cFJlcXVlc3QgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IGZyb21Qcm9taXNlIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBFcnJvck9ic2VydmFibGUgfSBmcm9tICdyeGpzLWNvbXBhdC9vYnNlcnZhYmxlL0Vycm9yT2JzZXJ2YWJsZSc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIG5hY286IE5hY29TZXJ2aWNlKSB7XG4gICAgfVxuXG4gICAgcHVibGljIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgICAgICByZXR1cm4gZnJvbVByb21pc2UodGhpcy5uYWNvLmdldFNpZ25hdHVyZSgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dFxuICAgICAgICAgICAgICAgICAgICAuaGFuZGxlKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxLmNsb25lKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRIZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhvcml6YXRpb246IGAke3NpZ25hdHVyZS50eXBlfSAke3NpZ25hdHVyZS50b2tlbn1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYWNvLnJlZnJlc2hVc2VyKCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiBmcm9tUHJvbWlzZSh0aGlzLm5hY28uZ2V0U2lnbmF0dXJlKCkpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgobmV3U2lnbmF0dXJlOiBTaWduYXR1cmUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5oYW5kbGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5jbG9uZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRIZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYCR7bmV3U2lnbmF0dXJlLnR5cGV9ICR7bmV3U2lnbmF0dXJlLnRva2VufWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycm9yT2JzZXJ2YWJsZS5jcmVhdGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL2NvbmZpZyc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgU3RvcmFnZSB9IGZyb20gJ0B1YnVkL3N0b3JhZ2UnO1xuaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBuYWNvRmFjdG9yeShjb25maWc6IG9iamVjdCwgcm91dGVyOiBSb3V0ZXIsIHN0b3JhZ2U6IFN0b3JhZ2UsIGh0dHA6IEh0dHBDbGllbnQpIHtcbiAgICByZXR1cm4gbmV3IE5hY29TZXJ2aWNlKFxuICAgICAgICBuZXcgQ29uZmlnKHsgLi4uY29uZmlnIH0pLFxuICAgICAgICByb3V0ZXIsXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIGh0dHBcbiAgICApO1xufVxuXG5leHBvcnQgY29uc3QgTkFDT19DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW48b2JqZWN0PignTkFDT19DT05GSUcnKTtcbiIsImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uLy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uLy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vLi4vZG9tYWlucy9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmFrZXItYXV0aC1wYWdlJyxcbiAgICB0ZW1wbGF0ZTogJ3t7IG1lc3NhZ2UgfX0nLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoUGFnZSB7XG4gICAgcHVibGljIG1lc3NhZ2U6IHN0cmluZyA9ICdBdXRoZW50aWNhdGluZy4uLic7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSkge1xuICAgICAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnN1YnNjcmliZSgocGFyYW1zOiBQYXJhbXMpID0+IHRoaXMuaGFuZGxlKHBhcmFtcykpO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGUocGFyYW1zOiBQYXJhbXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBhcmFtcy5zdGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5uYWNvLmdldFN0YXRlKCkudGhlbigoc3RhdGU6IHN0cmluZyB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgIT09IHBhcmFtcy5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSAnSW52YWxpZCBDU1JGJztcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5hdXRoZW50aWNhdGUocGFyYW1zKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hdXRoZW50aWNhdGUocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXV0aGVudGljYXRlKHBhcmFtczogUGFyYW1zKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZTogU2lnbmF0dXJlID0ge1xuICAgICAgICAgICAgZXhwaXJlc0luOiBwYXJhbXMuZXhwaXJlc19pbixcbiAgICAgICAgICAgIHR5cGU6IHBhcmFtcy50b2tlbl90eXBlLFxuICAgICAgICAgICAgdG9rZW46IHBhcmFtcy5hY2Nlc3NfdG9rZW4sXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5uYWNvLnNldFNpZ25hdHVyZShzaWduYXR1cmUpO1xuXG4gICAgICAgIHRoaXMubmFjby5nZXRVc2VyKCkuc3Vic2NyaWJlKCh1c2VyOiBVc2VyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgaWYgKG51bGwgIT09IHVzZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuZ2V0KCduYWNvX2ludGVuZGVkX3VybCcpLnRoZW4oKHVybDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoJ25hY29faW50ZW5kZWRfdXJsJykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybCA/IHVybCA6ICcvJztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9ICdVbmF1dGhlbnRpY2F0ZWQhJztcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG4iLCJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXJNb2R1bGUsIFJvdXRlcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBBdXRoUGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC5wYWdlJztcblxuY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gICAge1xuICAgICAgICBwYXRoOiAnYXV0aCcsXG4gICAgICAgIGNvbXBvbmVudDogQXV0aFBhZ2VcbiAgICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEFVVEhfUk9VVElORzogTW9kdWxlV2l0aFByb3ZpZGVycyA9IFJvdXRlck1vZHVsZS5mb3JDaGlsZChyb3V0ZXMpO1xuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFVVEhfUk9VVElORyB9IGZyb20gJy4vcm91dGVzJztcbmltcG9ydCB7IEF1dGhQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLnBhZ2UnO1xuXG5ATmdNb2R1bGUoe1xuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQVVUSF9ST1VUSU5HLFxuICAgIF0sXG4gICAgZGVjbGFyYXRpb25zOiBbXG4gICAgICAgIEF1dGhQYWdlLFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5hY29WaWV3TW9kdWxlIHtcbn1cbiIsImltcG9ydCB7IE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZEd1YXJkIH0gZnJvbSAnLi9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZCc7XG5pbXBvcnQgeyBOQUNPX0NPTkZJRywgbmFjb0ZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnknO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UsIFVidWRTdG9yYWdlTW9kdWxlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBOYWNvVmlld01vZHVsZSB9IGZyb20gJy4vdmlld3MvbW9kdWxlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBVYnVkU3RvcmFnZU1vZHVsZSxcbiAgICAgICAgTmFjb1ZpZXdNb2R1bGUsXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTmFjb01vZHVsZSB7XG4gICAgcHVibGljIHN0YXRpYyBmb3JSb290KGNvbmZpZzogeyBjbGllbnRJZDogc3RyaW5nLCBlbmRwb2ludD86IHN0cmluZyB9KTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZ01vZHVsZTogTmFjb01vZHVsZSxcbiAgICAgICAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZTogTkFDT19DT05GSUcsXG4gICAgICAgICAgICAgICAgICAgIHVzZVZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGU6IE5hY29TZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICB1c2VGYWN0b3J5OiBuYWNvRmFjdG9yeSxcbiAgICAgICAgICAgICAgICAgICAgZGVwczogW05BQ09fQ09ORklHLCBSb3V0ZXIsIFN0b3JhZ2UsIEh0dHBDbGllbnRdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgQXV0aGVudGljYXRlZEd1YXJkLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7O2dCQUl1QixJQUFzQjt3QkFIZixnQ0FBZ0M7UUFJdEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7O0NBRWpDOzs7Ozs7O0NDS0E7O0lBRkksSUFBSSxtQkFBQyxVQUFVLENBQUMsTUFBTSxJQUFJLENBQVEsRUFBQzs4QkFDbEIsSUFBSTs7Ozs7OztBQ1gxQjs7Ozs7OztnQkFxQitCLE1BQWMsRUFBVSxNQUFjLEVBQVUsT0FBZ0IsRUFBVSxJQUFnQjtRQUExRixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFVLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFZO3VCQVAzRixJQUFJO3lCQUVRLElBQUk7b0JBQ2QsSUFBSTs0QkFDUyxJQUFJOzRCQUNQLElBQUk7Ozs7OztJQUtuQyxPQUFPLENBQUMsSUFBaUI7UUFDNUIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDOzs7OztJQUc1QixPQUFPO1FBQ1YsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRTtZQUNwQixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDeEI7UUFFRCxPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUks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 |
\ | No newline at end of file |