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