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 { of } from 'rxjs';
|
7 | import { fromPromise } from 'rxjs/internal/observable/fromPromise';
|
8 | import { map, switchMap, 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 | }
|
58 | /**
|
59 | * @return {?}
|
60 | */
|
61 | getUser() {
|
62 | if (null !== this.user) {
|
63 | return of(this.user);
|
64 | }
|
65 | return fromPromise(this.storage.get('user')).pipe(switchMap((user) => {
|
66 | if (null !== user) {
|
67 | return of(user);
|
68 | }
|
69 | const /** @type {?} */ uri = this.config.endpoint + '/api/' + this.VERSION + '/users/me';
|
70 | return fromPromise(this.getSignature()).pipe(switchMap((signature) => {
|
71 | if (null === signature) {
|
72 | return of(null);
|
73 | }
|
74 | const /** @type {?} */ options = {
|
75 | headers: {
|
76 | Authorization: `${signature.type} ${signature.token}`,
|
77 | },
|
78 | };
|
79 | return this.http.get(uri, options).pipe(map((res) => {
|
80 | if (res.data) {
|
81 | return res.data;
|
82 | }
|
83 | throw new Error('There are no body to be transformed');
|
84 | }), map((data) => {
|
85 | const /** @type {?} */ authUser = plainToClass(User, data);
|
86 | this.storage.set('user', authUser);
|
87 | return authUser;
|
88 | }));
|
89 | }));
|
90 | }));
|
91 | }
|
92 | /**
|
93 | * @return {?}
|
94 | */
|
95 | getSignature() {
|
96 | if (null !== this.signature) {
|
97 | return Promise.resolve(this.signature);
|
98 | }
|
99 | return this.storage.get('signature');
|
100 | }
|
101 | /**
|
102 | * @param {?} signature
|
103 | * @return {?}
|
104 | */
|
105 | setSignature(signature) {
|
106 | this.signature = signature;
|
107 | this.storage.set('signature', signature);
|
108 | }
|
109 | /**
|
110 | * @param {?} scopes
|
111 | * @param {?=} redirectUri
|
112 | * @return {?}
|
113 | */
|
114 | login(scopes, redirectUri) {
|
115 | if (!redirectUri) {
|
116 | redirectUri = this.router.url;
|
117 | }
|
118 | const /** @type {?} */ state = this.generateState();
|
119 | this.storage.set('state', state);
|
120 | const /** @type {?} */ query = this.buildQueryString({
|
121 | 'response_type': 'token',
|
122 | 'scopes': scopes,
|
123 | 'client': this.config.clientId,
|
124 | 'state': state,
|
125 | 'continue': redirectUri,
|
126 | });
|
127 | return this.config.endpoint + '/auth?' + query;
|
128 | }
|
129 | /**
|
130 | * @param {?=} redirectUri
|
131 | * @return {?}
|
132 | */
|
133 | logout(redirectUri) {
|
134 | this.signature = null;
|
135 | this.user = null;
|
136 | return new Promise(resolve => {
|
137 | Promise.all([
|
138 | this.storage.remove('signature'),
|
139 | this.storage.remove('user'),
|
140 | ]).then(() => {
|
141 | let /** @type {?} */ endpoint = this.config.endpoint + '/auth/logout';
|
142 | if (redirectUri) {
|
143 | endpoint += '?continue=' + redirectUri;
|
144 | }
|
145 | resolve(endpoint);
|
146 | });
|
147 | });
|
148 | }
|
149 | /**
|
150 | * @return {?}
|
151 | */
|
152 | getState() {
|
153 | return this.storage.get('state');
|
154 | }
|
155 | /**
|
156 | * @param {?} route
|
157 | * @return {?}
|
158 | */
|
159 | buildNestedUri(route) {
|
160 | let /** @type {?} */ uri = '';
|
161 | if (route.routeConfig && route.routeConfig.path) {
|
162 | uri += '/' + route.routeConfig.path;
|
163 | }
|
164 | if (route.children) {
|
165 | route.children.forEach((item) => {
|
166 | uri += this.buildNestedUri(item);
|
167 | });
|
168 | }
|
169 | return uri;
|
170 | }
|
171 | /**
|
172 | * @return {?}
|
173 | */
|
174 | generateState() {
|
175 | const /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
176 | let /** @type {?} */ text = '';
|
177 | for (let /** @type {?} */ i = 0; i < 5; i++) {
|
178 | text += possible.charAt(Math.floor(Math.random() * possible.length));
|
179 | }
|
180 | return text;
|
181 | }
|
182 | /**
|
183 | * @param {?} params
|
184 | * @return {?}
|
185 | */
|
186 | buildQueryString(params) {
|
187 | const /** @type {?} */ queryParams = Object.keys(params).map((key) => {
|
188 | return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
|
189 | });
|
190 | return queryParams.join('&');
|
191 | }
|
192 | }
|
193 | NacoService.decorators = [
|
194 | { type: Injectable },
|
195 | ];
|
196 | /** @nocollapse */
|
197 | NacoService.ctorParameters = () => [
|
198 | { type: Config },
|
199 | { type: Router },
|
200 | { type: Storage },
|
201 | { type: HttpClient }
|
202 | ];
|
203 |
|
204 | /**
|
205 | * @fileoverview added by tsickle
|
206 | * @suppress {checkTypes} checked by tsc
|
207 | */
|
208 | class Signature {
|
209 | }
|
210 |
|
211 | /**
|
212 | * @fileoverview added by tsickle
|
213 | * @suppress {checkTypes} checked by tsc
|
214 | */
|
215 | class AuthenticatedGuard {
|
216 | /**
|
217 | * @param {?} naco
|
218 | * @param {?} storage
|
219 | * @param {?} platformLocation
|
220 | */
|
221 | constructor(naco, storage, platformLocation) {
|
222 | this.naco = naco;
|
223 | this.storage = storage;
|
224 | this.platformLocation = platformLocation;
|
225 | }
|
226 | /**
|
227 | * @param {?} route
|
228 | * @return {?}
|
229 | */
|
230 | canActivate(route) {
|
231 | return this.naco.getUser().pipe(first(), map((user) => {
|
232 | if (null === user) {
|
233 | const /** @type {?} */ base = this.rtrim((/** @type {?} */ (this.platformLocation)).location.href);
|
234 | const /** @type {?} */ uri = this.naco.buildNestedUri(route.root);
|
235 | const /** @type {?} */ next = base.replace(uri, '') + '/' + this.ltrim(uri);
|
236 | const /** @type {?} */ origin = (/** @type {?} */ (this.platformLocation)).location.origin;
|
237 | this.storage.set('naco_intended_url', next).then(() => {
|
238 | window.location.href = this.naco.login('basic email', origin + '/auth');
|
239 | });
|
240 | }
|
241 | return !!user;
|
242 | }));
|
243 | }
|
244 | /**
|
245 | * @param {?} route
|
246 | * @return {?}
|
247 | */
|
248 | canActivateChild(route) {
|
249 | return this.canActivate(route);
|
250 | }
|
251 | /**
|
252 | * @param {?} text
|
253 | * @return {?}
|
254 | */
|
255 | ltrim(text) {
|
256 | return text.replace(/^\/+/, '');
|
257 | }
|
258 | /**
|
259 | * @param {?} text
|
260 | * @return {?}
|
261 | */
|
262 | rtrim(text) {
|
263 | return text.replace(/\/+$/, '');
|
264 | }
|
265 | }
|
266 | AuthenticatedGuard.decorators = [
|
267 | { type: Injectable },
|
268 | ];
|
269 | /** @nocollapse */
|
270 | AuthenticatedGuard.ctorParameters = () => [
|
271 | { type: NacoService },
|
272 | { type: Storage },
|
273 | { type: PlatformLocation }
|
274 | ];
|
275 |
|
276 | /**
|
277 | * @fileoverview added by tsickle
|
278 | * @suppress {checkTypes} checked by tsc
|
279 | */
|
280 | class AuthInterceptor {
|
281 | /**
|
282 | * @param {?} naco
|
283 | */
|
284 | constructor(naco) {
|
285 | this.naco = naco;
|
286 | }
|
287 | /**
|
288 | * @param {?} req
|
289 | * @param {?} next
|
290 | * @return {?}
|
291 | */
|
292 | intercept(req, next) {
|
293 | return fromPromise(this.naco.getSignature()).pipe(switchMap((signature) => {
|
294 | if (!signature) {
|
295 | return next.handle(req);
|
296 | }
|
297 | return next
|
298 | .handle(req.clone({
|
299 | setHeaders: {
|
300 | Authorization: `${signature.type} ${signature.token}`,
|
301 | },
|
302 | }))
|
303 | .pipe(catchError((error) => {
|
304 | if (error.status === 401) ;
|
305 | return ErrorObservable.create(error);
|
306 | }));
|
307 | }));
|
308 | }
|
309 | }
|
310 | AuthInterceptor.decorators = [
|
311 | { type: Injectable },
|
312 | ];
|
313 | /** @nocollapse */
|
314 | AuthInterceptor.ctorParameters = () => [
|
315 | { type: NacoService }
|
316 | ];
|
317 |
|
318 | /**
|
319 | * @fileoverview added by tsickle
|
320 | * @suppress {checkTypes} checked by tsc
|
321 | */
|
322 | /**
|
323 | * @param {?} config
|
324 | * @param {?} router
|
325 | * @param {?} storage
|
326 | * @param {?} http
|
327 | * @return {?}
|
328 | */
|
329 | function nacoFactory(config, router, storage, http) {
|
330 | return new NacoService(new Config(Object.assign({}, config)), router, storage, http);
|
331 | }
|
332 | const /** @type {?} */ NACO_CONFIG = new InjectionToken('NACO_CONFIG');
|
333 |
|
334 | /**
|
335 | * @fileoverview added by tsickle
|
336 | * @suppress {checkTypes} checked by tsc
|
337 | */
|
338 | class AuthPage {
|
339 | /**
|
340 | * @param {?} route
|
341 | * @param {?} naco
|
342 | * @param {?} storage
|
343 | */
|
344 | constructor(route, naco, storage) {
|
345 | this.route = route;
|
346 | this.naco = naco;
|
347 | this.storage = storage;
|
348 | this.message = 'Authenticating...';
|
349 | this.route.queryParams.subscribe((params) => this.handle(params));
|
350 | }
|
351 | /**
|
352 | * @param {?} params
|
353 | * @return {?}
|
354 | */
|
355 | handle(params) {
|
356 | if (params["state"]) {
|
357 | this.naco.getState().then((state) => {
|
358 | if (state !== params["state"]) {
|
359 | this.message = 'Invalid CSRF';
|
360 | return;
|
361 | }
|
362 | this.authenticate(params);
|
363 | });
|
364 | }
|
365 | else {
|
366 | this.authenticate(params);
|
367 | }
|
368 | }
|
369 | /**
|
370 | * @param {?} params
|
371 | * @return {?}
|
372 | */
|
373 | authenticate(params) {
|
374 | const /** @type {?} */ signature = {
|
375 | expiresIn: params["expires_in"],
|
376 | type: params["token_type"],
|
377 | token: params["access_token"],
|
378 | };
|
379 | this.naco.setSignature(signature);
|
380 | this.naco.getUser().subscribe((user) => {
|
381 | if (null !== user) {
|
382 | this.storage.get('naco_intended_url').then((url) => {
|
383 | this.storage.remove('naco_intended_url').then(() => {
|
384 | window.location.href = url ? url : '/';
|
385 | });
|
386 | });
|
387 | return;
|
388 | }
|
389 | this.message = 'Unauthenticated!';
|
390 | });
|
391 | }
|
392 | }
|
393 | AuthPage.decorators = [
|
394 | { type: Component, args: [{
|
395 | selector: 'naker-auth-page',
|
396 | template: '{{ message }}',
|
397 | },] },
|
398 | ];
|
399 | /** @nocollapse */
|
400 | AuthPage.ctorParameters = () => [
|
401 | { type: ActivatedRoute },
|
402 | { type: NacoService },
|
403 | { type: Storage }
|
404 | ];
|
405 |
|
406 | /**
|
407 | * @fileoverview added by tsickle
|
408 | * @suppress {checkTypes} checked by tsc
|
409 | */
|
410 | const /** @type {?} */ routes = [
|
411 | {
|
412 | path: 'auth',
|
413 | component: AuthPage
|
414 | },
|
415 | ];
|
416 | const /** @type {?} */ AUTH_ROUTING = RouterModule.forChild(routes);
|
417 |
|
418 | /**
|
419 | * @fileoverview added by tsickle
|
420 | * @suppress {checkTypes} checked by tsc
|
421 | */
|
422 | class NacoViewModule {
|
423 | }
|
424 | NacoViewModule.decorators = [
|
425 | { type: NgModule, args: [{
|
426 | imports: [
|
427 | AUTH_ROUTING,
|
428 | ],
|
429 | declarations: [
|
430 | AuthPage,
|
431 | ],
|
432 | },] },
|
433 | ];
|
434 |
|
435 | /**
|
436 | * @fileoverview added by tsickle
|
437 | * @suppress {checkTypes} checked by tsc
|
438 | */
|
439 | class NacoModule {
|
440 | /**
|
441 | * @param {?} config
|
442 | * @return {?}
|
443 | */
|
444 | static forRoot(config) {
|
445 | return {
|
446 | ngModule: NacoModule,
|
447 | providers: [
|
448 | {
|
449 | provide: NACO_CONFIG,
|
450 | useValue: config,
|
451 | },
|
452 | {
|
453 | provide: NacoService,
|
454 | useFactory: nacoFactory,
|
455 | deps: [NACO_CONFIG, Router, Storage, HttpClient],
|
456 | },
|
457 | AuthenticatedGuard,
|
458 | ],
|
459 | };
|
460 | }
|
461 | }
|
462 | NacoModule.decorators = [
|
463 | { type: NgModule, args: [{
|
464 | imports: [
|
465 | UbudStorageModule,
|
466 | NacoViewModule,
|
467 | ],
|
468 | },] },
|
469 | ];
|
470 |
|
471 | /**
|
472 | * @fileoverview added by tsickle
|
473 | * @suppress {checkTypes} checked by tsc
|
474 | */
|
475 |
|
476 | /**
|
477 | * @fileoverview added by tsickle
|
478 | * @suppress {checkTypes} checked by tsc
|
479 | */
|
480 |
|
481 | 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 };
|
482 |
|
483 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFrZXItbmFjby5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvY29uZmlnLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL21vZGVscy91c2VyLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvc2lnbmF0dXJlLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZC50cyIsIm5nOi8vQG5ha2VyL25hY28vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiLCJuZzovL0BuYWtlci9uYWNvL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnkudHMiLCJuZzovL0BuYWtlci9uYWNvL3ZpZXdzL3BhZ2VzL2F1dGgucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3Mvcm91dGVzLnRzIiwibmc6Ly9AbmFrZXIvbmFjby92aWV3cy9tb2R1bGUudHMiLCJuZzovL0BuYWtlci9uYWNvL25hY28ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHB1YmxpYyBlbmRwb2ludDogc3RyaW5nID0gJ2h0dHBzOi8vYWNjb3VudC5rZW1uYWtlci5nby5pZCc7XG4gICAgcHVibGljIGNsaWVudElkOiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZGF0YT86IFBhcnRpYWw8Q29uZmlnPikge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRhdGEpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IGZvcndhcmRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5cbmV4cG9ydCBjbGFzcyBVc2VyIHtcbiAgICBwdWJsaWMgaWQ6IHN0cmluZztcbiAgICBwdWJsaWMgdXNlcm5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgZW1haWw/OiBzdHJpbmc7XG4gICAgcHVibGljIG5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgc3RhdHVzOiBudW1iZXI7XG5cbiAgICBAVHlwZShmb3J3YXJkUmVmKCgpID0+IERhdGUpIGFzIGFueSlcbiAgICBwdWJsaWMgdXBkYXRlZEF0OiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL3ZhbHVlcy9jb25maWcnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL21vZGVscy91c2VyJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTaWduYXR1cmUgfSBmcm9tICcuLi92YWx1ZXMvc2lnbmF0dXJlJztcbmltcG9ydCB7IGZyb21Qcm9taXNlIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgcGxhaW5Ub0NsYXNzIH0gZnJvbSAnY2xhc3MtdHJhbnNmb3JtZXInO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgVkVSU0lPTiA9ICd2MSc7XG5cbiAgICBwcml2YXRlIHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB1c2VyOiBVc2VyIHwgbnVsbCA9IG51bGw7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWc6IENvbmZpZywgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlciwgcHJpdmF0ZSBzdG9yYWdlOiBTdG9yYWdlLCBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQpIHtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VXNlcigpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnVzZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih0aGlzLnVzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHRoaXMuc3RvcmFnZS5nZXQoJ3VzZXInKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgodXNlcjogVXNlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobnVsbCAhPT0gdXNlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YodXNlcik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdXJpID0gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2FwaS8nICsgdGhpcy5WRVJTSU9OICsgJy91c2Vycy9tZSc7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbVByb21pc2UodGhpcy5nZXRTaWduYXR1cmUoKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKChzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChudWxsID09PSBzaWduYXR1cmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgJHtzaWduYXR1cmUudHlwZX0gJHtzaWduYXR1cmUudG9rZW59YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55Pih1cmksIG9wdGlvbnMpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgYXJlIG5vIGJvZHkgdG8gYmUgdHJhbnNmb3JtZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhdXRoVXNlciA9IHBsYWluVG9DbGFzcyhVc2VyLCBkYXRhKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCd1c2VyJywgYXV0aFVzZXIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdXRoVXNlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2lnbmF0dXJlKCk6IFByb21pc2U8U2lnbmF0dXJlIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy5zaWduYXR1cmUpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5zaWduYXR1cmUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3NpZ25hdHVyZScpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRTaWduYXR1cmUoc2lnbmF0dXJlOiBTaWduYXR1cmUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zaWduYXR1cmUgPSBzaWduYXR1cmU7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3NpZ25hdHVyZScsIHNpZ25hdHVyZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ2luKHNjb3Blczogc3RyaW5nLCByZWRpcmVjdFVyaT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICghcmVkaXJlY3RVcmkpIHtcbiAgICAgICAgICAgIHJlZGlyZWN0VXJpID0gdGhpcy5yb3V0ZXIudXJsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdlbmVyYXRlU3RhdGUoKTtcblxuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdzdGF0ZScsIHN0YXRlKTtcblxuICAgICAgICBjb25zdCBxdWVyeTogc3RyaW5nID0gdGhpcy5idWlsZFF1ZXJ5U3RyaW5nKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICdyZXNwb25zZV90eXBlJzogJ3Rva2VuJyxcbiAgICAgICAgICAgICAgICAnc2NvcGVzJzogc2NvcGVzLFxuICAgICAgICAgICAgICAgICdjbGllbnQnOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgICAgICAnc3RhdGUnOiBzdGF0ZSxcbiAgICAgICAgICAgICAgICAnY29udGludWUnOiByZWRpcmVjdFVyaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmVuZHBvaW50ICsgJy9hdXRoPycgKyBxdWVyeTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbG9nb3V0KHJlZGlyZWN0VXJpPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgdGhpcy5zaWduYXR1cmUgPSBudWxsO1xuICAgICAgICB0aGlzLnVzZXIgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCdzaWduYXR1cmUnKSxcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCd1c2VyJyksXG4gICAgICAgICAgICBdKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZW5kcG9pbnQgPSB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXV0aC9sb2dvdXQnO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZGlyZWN0VXJpKSB7XG4gICAgICAgICAgICAgICAgICAgIGVuZHBvaW50ICs9ICc/Y29udGludWU9JyArIHJlZGlyZWN0VXJpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc29sdmUoZW5kcG9pbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3N0YXRlJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkTmVzdGVkVXJpKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHVyaSA9ICcnO1xuXG4gICAgICAgIGlmIChyb3V0ZS5yb3V0ZUNvbmZpZyAmJiByb3V0ZS5yb3V0ZUNvbmZpZy5wYXRoKSB7XG4gICAgICAgICAgICB1cmkgKz0gJy8nICsgcm91dGUucm91dGVDb25maWcucGF0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyb3V0ZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgcm91dGUuY2hpbGRyZW4uZm9yRWFjaCgoaXRlbTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCkgPT4ge1xuICAgICAgICAgICAgICAgIHVyaSArPSB0aGlzLmJ1aWxkTmVzdGVkVXJpKGl0ZW0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXJpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVTdGF0ZSgpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBwb3NzaWJsZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG4gICAgICAgIGxldCB0ZXh0ID0gJyc7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICAgICAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFF1ZXJ5U3RyaW5nKHBhcmFtczogb2JqZWN0KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBPYmplY3Qua2V5cyhwYXJhbXMpLm1hcCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChwYXJhbXNba2V5XSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBxdWVyeVBhcmFtcy5qb2luKCcmJyk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIFNpZ25hdHVyZSB7XG4gICAgcHVibGljIGV4cGlyZXNJbjogbnVtYmVyO1xuICAgIHB1YmxpYyB0b2tlbjogc3RyaW5nO1xuICAgIHB1YmxpYyB0eXBlOiBzdHJpbmc7XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IGZpcnN0LCBtYXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vZG9tYWlucy9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90IH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyL3NyYy9yb3V0ZXJfc3RhdGUnO1xuaW1wb3J0IHsgUGxhdGZvcm1Mb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGVkR3VhcmQgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSwgcHJpdmF0ZSBwbGF0Zm9ybUxvY2F0aW9uOiBQbGF0Zm9ybUxvY2F0aW9uKSB7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbkFjdGl2YXRlKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hY28uZ2V0VXNlcigpLnBpcGUoXG4gICAgICAgICAgICBmaXJzdCgpLFxuICAgICAgICAgICAgbWFwKCh1c2VyOiBVc2VyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChudWxsID09PSB1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLnJ0cmltKCh0aGlzLnBsYXRmb3JtTG9jYXRpb24gYXMgYW55KS5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXJpID0gdGhpcy5uYWNvLmJ1aWxkTmVzdGVkVXJpKHJvdXRlLnJvb3QpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0ID0gYmFzZS5yZXBsYWNlKHVyaSwgJycpICsgJy8nICsgdGhpcy5sdHJpbSh1cmkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW4gPSAodGhpcy5wbGF0Zm9ybUxvY2F0aW9uIGFzIGFueSkubG9jYXRpb24ub3JpZ2luO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ25hY29faW50ZW5kZWRfdXJsJywgbmV4dCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHRoaXMubmFjby5sb2dpbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFzaWMgZW1haWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiArICcvYXV0aCcsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gISF1c2VyO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbkFjdGl2YXRlQ2hpbGQocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWN0aXZhdGUocm91dGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbHRyaW0odGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSgvXlxcLysvLCcnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJ0cmltKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcLyskLywnJyk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSHR0cEVycm9yUmVzcG9uc2UsIEh0dHBFdmVudCwgSHR0cEhhbmRsZXIsIEh0dHBJbnRlcmNlcHRvciwgSHR0cFJlcXVlc3QgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IGZyb21Qcm9taXNlIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBFcnJvck9ic2VydmFibGUgfSBmcm9tICdyeGpzLWNvbXBhdC9vYnNlcnZhYmxlL0Vycm9yT2JzZXJ2YWJsZSc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIG5hY286IE5hY29TZXJ2aWNlKSB7XG4gICAgfVxuXG4gICAgcHVibGljIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgICAgICByZXR1cm4gZnJvbVByb21pc2UodGhpcy5uYWNvLmdldFNpZ25hdHVyZSgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dFxuICAgICAgICAgICAgICAgICAgICAuaGFuZGxlKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxLmNsb25lKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRIZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhvcml6YXRpb246IGAke3NpZ25hdHVyZS50eXBlfSAke3NpZ25hdHVyZS50b2tlbn1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBSZWZyZXNoIHRva2VuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycm9yT2JzZXJ2YWJsZS5jcmVhdGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL2NvbmZpZyc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgU3RvcmFnZSB9IGZyb20gJ0B1YnVkL3N0b3JhZ2UnO1xuaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBuYWNvRmFjdG9yeShjb25maWc6IG9iamVjdCwgcm91dGVyOiBSb3V0ZXIsIHN0b3JhZ2U6IFN0b3JhZ2UsIGh0dHA6IEh0dHBDbGllbnQpIHtcbiAgICByZXR1cm4gbmV3IE5hY29TZXJ2aWNlKFxuICAgICAgICBuZXcgQ29uZmlnKHsgLi4uY29uZmlnIH0pLFxuICAgICAgICByb3V0ZXIsXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIGh0dHBcbiAgICApO1xufVxuXG5leHBvcnQgY29uc3QgTkFDT19DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW48b2JqZWN0PignTkFDT19DT05GSUcnKTtcbiIsImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uLy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uLy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vLi4vZG9tYWlucy9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmFrZXItYXV0aC1wYWdlJyxcbiAgICB0ZW1wbGF0ZTogJ3t7IG1lc3NhZ2UgfX0nLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoUGFnZSB7XG4gICAgcHVibGljIG1lc3NhZ2U6IHN0cmluZyA9ICdBdXRoZW50aWNhdGluZy4uLic7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSkge1xuICAgICAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnN1YnNjcmliZSgocGFyYW1zOiBQYXJhbXMpID0+IHRoaXMuaGFuZGxlKHBhcmFtcykpO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGUocGFyYW1zOiBQYXJhbXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKHBhcmFtcy5zdGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5uYWNvLmdldFN0YXRlKCkudGhlbigoc3RhdGU6IHN0cmluZyB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgIT09IHBhcmFtcy5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSAnSW52YWxpZCBDU1JGJztcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5hdXRoZW50aWNhdGUocGFyYW1zKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hdXRoZW50aWNhdGUocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXV0aGVudGljYXRlKHBhcmFtczogUGFyYW1zKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZTogU2lnbmF0dXJlID0ge1xuICAgICAgICAgICAgZXhwaXJlc0luOiBwYXJhbXMuZXhwaXJlc19pbixcbiAgICAgICAgICAgIHR5cGU6IHBhcmFtcy50b2tlbl90eXBlLFxuICAgICAgICAgICAgdG9rZW46IHBhcmFtcy5hY2Nlc3NfdG9rZW4sXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5uYWNvLnNldFNpZ25hdHVyZShzaWduYXR1cmUpO1xuXG4gICAgICAgIHRoaXMubmFjby5nZXRVc2VyKCkuc3Vic2NyaWJlKCh1c2VyOiBVc2VyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgaWYgKG51bGwgIT09IHVzZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuZ2V0KCduYWNvX2ludGVuZGVkX3VybCcpLnRoZW4oKHVybDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoJ25hY29faW50ZW5kZWRfdXJsJykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybCA/IHVybCA6ICcvJztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9ICdVbmF1dGhlbnRpY2F0ZWQhJztcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG4iLCJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXJNb2R1bGUsIFJvdXRlcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBBdXRoUGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC5wYWdlJztcblxuY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gICAge1xuICAgICAgICBwYXRoOiAnYXV0aCcsXG4gICAgICAgIGNvbXBvbmVudDogQXV0aFBhZ2VcbiAgICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEFVVEhfUk9VVElORzogTW9kdWxlV2l0aFByb3ZpZGVycyA9IFJvdXRlck1vZHVsZS5mb3JDaGlsZChyb3V0ZXMpO1xuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFVVEhfUk9VVElORyB9IGZyb20gJy4vcm91dGVzJztcbmltcG9ydCB7IEF1dGhQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLnBhZ2UnO1xuXG5ATmdNb2R1bGUoe1xuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQVVUSF9ST1VUSU5HLFxuICAgIF0sXG4gICAgZGVjbGFyYXRpb25zOiBbXG4gICAgICAgIEF1dGhQYWdlLFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5hY29WaWV3TW9kdWxlIHtcbn1cbiIsImltcG9ydCB7IE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZEd1YXJkIH0gZnJvbSAnLi9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZCc7XG5pbXBvcnQgeyBOQUNPX0NPTkZJRywgbmFjb0ZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnknO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UsIFVidWRTdG9yYWdlTW9kdWxlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBOYWNvVmlld01vZHVsZSB9IGZyb20gJy4vdmlld3MvbW9kdWxlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBVYnVkU3RvcmFnZU1vZHVsZSxcbiAgICAgICAgTmFjb1ZpZXdNb2R1bGUsXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTmFjb01vZHVsZSB7XG4gICAgcHVibGljIHN0YXRpYyBmb3JSb290KGNvbmZpZzogeyBjbGllbnRJZDogc3RyaW5nLCBlbmRwb2ludD86IHN0cmluZyB9KTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZ01vZHVsZTogTmFjb01vZHVsZSxcbiAgICAgICAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZTogTkFDT19DT05GSUcsXG4gICAgICAgICAgICAgICAgICAgIHVzZVZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGU6IE5hY29TZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICB1c2VGYWN0b3J5OiBuYWNvRmFjdG9yeSxcbiAgICAgICAgICAgICAgICAgICAgZGVwczogW05BQ09fQ09ORklHLCBSb3V0ZXIsIFN0b3JhZ2UsIEh0dHBDbGllbnRdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgQXV0aGVudGljYXRlZEd1YXJkLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6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 |
\ | No newline at end of file |