1 | /**
|
2 | * @fileoverview added by tsickle
|
3 | * @suppress {checkTypes} checked by tsc
|
4 | */
|
5 | import * as tslib_1 from "tslib";
|
6 | import { Injectable } from '@angular/core';
|
7 | import { Router } from '@angular/router';
|
8 | import { Storage } from '@ubud/storage';
|
9 | import { Config } from '../values/config';
|
10 | import { User } from '../models/user';
|
11 | import { forkJoin, Observable, of } from 'rxjs';
|
12 | import { fromPromise } from 'rxjs/internal/observable/fromPromise';
|
13 | import { catchError, map, switchMap, tap } from 'rxjs/internal/operators';
|
14 | import { plainToClass } from 'class-transformer';
|
15 | import { HttpClient } from '@angular/common/http';
|
16 | import { Location } from '@angular/common';
|
17 | var NacoService = /** @class */ (function () {
|
18 | function NacoService(config, router, storage, http, location) {
|
19 | this.config = config;
|
20 | this.router = router;
|
21 | this.storage = storage;
|
22 | this.http = http;
|
23 | this.location = location;
|
24 | this.VERSION = 'v1';
|
25 | this.signature = null;
|
26 | this.user = null;
|
27 | this.refreshToken = null;
|
28 | this.clientSecret = null;
|
29 | }
|
30 | /**
|
31 | * @param {?} user
|
32 | * @return {?}
|
33 | */
|
34 | NacoService.prototype.setUser = /**
|
35 | * @param {?} user
|
36 | * @return {?}
|
37 | */
|
38 | function (user) {
|
39 | this.user = user;
|
40 | };
|
41 | /**
|
42 | * @return {?}
|
43 | */
|
44 | NacoService.prototype.getUser = /**
|
45 | * @return {?}
|
46 | */
|
47 | function () {
|
48 | var _this = this;
|
49 | if (null !== this.user) {
|
50 | return of(this.user);
|
51 | }
|
52 | var /** @type {?} */ uri = this.getUri('/users/me');
|
53 | return fromPromise(this.getSignature()).pipe(switchMap(function (signature) {
|
54 | if (null === signature) {
|
55 | return _this.refreshUser();
|
56 | }
|
57 | var /** @type {?} */ options = {
|
58 | headers: {
|
59 | Authorization: signature.type + " " + signature.token,
|
60 | },
|
61 | };
|
62 | return _this.http.get(uri, options).pipe(map(function (res) {
|
63 | if (res.data) {
|
64 | return res.data;
|
65 | }
|
66 | throw new Error('There are no body to be transformed');
|
67 | }), map(function (data) {
|
68 | var /** @type {?} */ authUser = plainToClass(User, data);
|
69 | _this.setUser(authUser);
|
70 | return authUser;
|
71 | }), catchError(function (e) {
|
72 | if (401 === e.status) {
|
73 | return _this.refreshUser().pipe(switchMap(function (refreshUser) {
|
74 | if (refreshUser) {
|
75 | return of(refreshUser);
|
76 | }
|
77 | return of(null);
|
78 | }));
|
79 | }
|
80 | return of(null);
|
81 | }));
|
82 | }));
|
83 | };
|
84 | /**
|
85 | * @param {?} user
|
86 | * @return {?}
|
87 | */
|
88 | NacoService.prototype.getProfilePicture = /**
|
89 | * @param {?} user
|
90 | * @return {?}
|
91 | */
|
92 | function (user) {
|
93 | return this.config.endpoint + '/users/' + user + '/picture';
|
94 | };
|
95 | /**
|
96 | * @return {?}
|
97 | */
|
98 | NacoService.prototype.getSignature = /**
|
99 | * @return {?}
|
100 | */
|
101 | function () {
|
102 | if (this.signature) {
|
103 | return Promise.resolve(this.signature);
|
104 | }
|
105 | return this.storage.get('signature');
|
106 | };
|
107 | /**
|
108 | * @param {?} signature
|
109 | * @return {?}
|
110 | */
|
111 | NacoService.prototype.setSignature = /**
|
112 | * @param {?} signature
|
113 | * @return {?}
|
114 | */
|
115 | function (signature) {
|
116 | this.signature = signature;
|
117 | if (null === signature) {
|
118 | this.storage.remove('signature');
|
119 | }
|
120 | else {
|
121 | this.storage.set('signature', signature);
|
122 | }
|
123 | };
|
124 | /**
|
125 | * @param {?} secret
|
126 | * @return {?}
|
127 | */
|
128 | NacoService.prototype.setClientSecret = /**
|
129 | * @param {?} secret
|
130 | * @return {?}
|
131 | */
|
132 | function (secret) {
|
133 | this.clientSecret = secret;
|
134 | this.storage.set('client_secret', secret);
|
135 | };
|
136 | /**
|
137 | * @param {?} refreshToken
|
138 | * @return {?}
|
139 | */
|
140 | NacoService.prototype.setRefreshToken = /**
|
141 | * @param {?} refreshToken
|
142 | * @return {?}
|
143 | */
|
144 | function (refreshToken) {
|
145 | this.refreshToken = refreshToken;
|
146 | this.storage.set('refresh_token', refreshToken);
|
147 | };
|
148 | /**
|
149 | * @param {?=} scopes
|
150 | * @return {?}
|
151 | */
|
152 | NacoService.prototype.refreshUser = /**
|
153 | * @param {?=} scopes
|
154 | * @return {?}
|
155 | */
|
156 | function (scopes) {
|
157 | var _this = this;
|
158 | this.setUser(null);
|
159 | this.setSignature(null);
|
160 | return forkJoin(this.getRefreshToken(), this.getClientSecret()).pipe(switchMap(function (results) {
|
161 | var /** @type {?} */ refreshToken = results[0];
|
162 | var /** @type {?} */ clientSecret = results[1];
|
163 | if (refreshToken && clientSecret) {
|
164 | return _this.refreshWithRefreshToken(clientSecret, refreshToken.token, scopes);
|
165 | }
|
166 | return _this.refreshWithSilentAuth();
|
167 | }));
|
168 | };
|
169 | /**
|
170 | * @param {?} clientSecret
|
171 | * @param {?} refreshToken
|
172 | * @param {?=} scopes
|
173 | * @return {?}
|
174 | */
|
175 | NacoService.prototype.refreshWithRefreshToken = /**
|
176 | * @param {?} clientSecret
|
177 | * @param {?} refreshToken
|
178 | * @param {?=} scopes
|
179 | * @return {?}
|
180 | */
|
181 | function (clientSecret, refreshToken, scopes) {
|
182 | var _this = this;
|
183 | var /** @type {?} */ request = this.http.post(this.getUri('/tokens'), {
|
184 | grant_type: 'refresh_token',
|
185 | scopes: scopes || 'basic email',
|
186 | client_id: this.config.clientId,
|
187 | client_secret: clientSecret,
|
188 | refresh_token: refreshToken,
|
189 | });
|
190 | return request.pipe(tap(function (tokens) {
|
191 | if (tokens && tokens.data) {
|
192 | _this.setSignature({
|
193 | expiresIn: tokens.data.expires_in,
|
194 | type: tokens.data.token_type,
|
195 | token: tokens.data.access_token,
|
196 | });
|
197 | _this.setRefreshToken({
|
198 | type: tokens.data.token_type,
|
199 | token: tokens.data.refresh_token,
|
200 | });
|
201 | }
|
202 | }), map(function (tokens) { return tokens && tokens.data; }), switchMap(function (hasToken) {
|
203 | if (hasToken) {
|
204 | return _this.getUser();
|
205 | }
|
206 | return of(null);
|
207 | }));
|
208 | };
|
209 | /**
|
210 | * @return {?}
|
211 | */
|
212 | NacoService.prototype.refreshWithSilentAuth = /**
|
213 | * @return {?}
|
214 | */
|
215 | function () {
|
216 | var _this = this;
|
217 | return new Observable(function (observer) {
|
218 | var /** @type {?} */ redirectUri = _this.getCurrentOrigin('auth/silent');
|
219 | var /** @type {?} */ uri = _this.login('basic email', redirectUri, false);
|
220 | var /** @type {?} */ iframe = document.createElement('iframe');
|
221 | iframe.setAttribute('src', uri);
|
222 | iframe.style.display = 'none';
|
223 | iframe.addEventListener('load', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
224 | var e_1, _a, queryString, queryParts, params, queryParts_1, queryParts_1_1, item, itemParts, user, e_2;
|
225 | return tslib_1.__generator(this, function (_b) {
|
226 | switch (_b.label) {
|
227 | case 0:
|
228 | _b.trys.push([0, 5, , 6]);
|
229 | queryString = iframe.contentWindow.location.search.substring(1);
|
230 | iframe.parentNode.removeChild(iframe);
|
231 | if (!queryString) return [3 /*break*/, 4];
|
232 | queryParts = queryString.split('&');
|
233 | params = {};
|
234 | try {
|
235 | for (queryParts_1 = tslib_1.__values(queryParts), queryParts_1_1 = queryParts_1.next(); !queryParts_1_1.done; queryParts_1_1 = queryParts_1.next()) {
|
236 | item = queryParts_1_1.value;
|
237 | itemParts = item.split('=');
|
238 | params[itemParts[0]] = itemParts[1];
|
239 | }
|
240 | }
|
241 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
242 | finally {
|
243 | try {
|
244 | if (queryParts_1_1 && !queryParts_1_1.done && (_a = queryParts_1.return)) _a.call(queryParts_1);
|
245 | }
|
246 | finally { if (e_1) throw e_1.error; }
|
247 | }
|
248 | if (!params.hasOwnProperty('access_token')) return [3 /*break*/, 2];
|
249 | this.setSignature({
|
250 | token: params['access_token'],
|
251 | type: params['token_type'],
|
252 | expiresIn: params['ttl'],
|
253 | });
|
254 | return [4 /*yield*/, this.getUser().toPromise()];
|
255 | case 1:
|
256 | user = _b.sent();
|
257 | if (user) {
|
258 | this.setUser(user);
|
259 | }
|
260 | observer.next(user);
|
261 | return [3 /*break*/, 3];
|
262 | case 2:
|
263 | observer.next(null);
|
264 | _b.label = 3;
|
265 | case 3: return [2 /*return*/];
|
266 | case 4:
|
267 | observer.next(null);
|
268 | return [3 /*break*/, 6];
|
269 | case 5:
|
270 | e_2 = _b.sent();
|
271 | observer.next(null);
|
272 | return [3 /*break*/, 6];
|
273 | case 6: return [2 /*return*/];
|
274 | }
|
275 | });
|
276 | }); }, false);
|
277 | document.body.appendChild(iframe);
|
278 | });
|
279 | };
|
280 | /**
|
281 | * @param {?} scopes
|
282 | * @param {?=} redirectUri
|
283 | * @param {?=} needState
|
284 | * @return {?}
|
285 | */
|
286 | NacoService.prototype.login = /**
|
287 | * @param {?} scopes
|
288 | * @param {?=} redirectUri
|
289 | * @param {?=} needState
|
290 | * @return {?}
|
291 | */
|
292 | function (scopes, redirectUri, needState) {
|
293 | if (needState === void 0) { needState = true; }
|
294 | if (!redirectUri) {
|
295 | redirectUri = this.router.url;
|
296 | }
|
297 | var /** @type {?} */ params = {
|
298 | response_type: 'token',
|
299 | scopes: scopes,
|
300 | client: this.config.clientId,
|
301 | silent: true,
|
302 | continue: encodeURIComponent(redirectUri),
|
303 | };
|
304 | if (needState) {
|
305 | var /** @type {?} */ state = this.generateState();
|
306 | this.storage.set('state', state);
|
307 | params.state = state;
|
308 | }
|
309 | var /** @type {?} */ query = this.buildQueryString(params);
|
310 | return this.config.endpoint + '/auth?' + query;
|
311 | };
|
312 | /**
|
313 | * @param {?=} redirectUri
|
314 | * @return {?}
|
315 | */
|
316 | NacoService.prototype.logout = /**
|
317 | * @param {?=} redirectUri
|
318 | * @return {?}
|
319 | */
|
320 | function (redirectUri) {
|
321 | var _this = this;
|
322 | this.signature = null;
|
323 | this.user = null;
|
324 | this.clientSecret = null;
|
325 | this.refreshToken = null;
|
326 | return new Promise(function (resolve) {
|
327 | var /** @type {?} */ clear = [
|
328 | _this.storage.remove('signature'),
|
329 | _this.storage.remove('user'),
|
330 | _this.storage.remove('refresh_token'),
|
331 | _this.storage.remove('client_secret'),
|
332 | ];
|
333 | Promise.all(clear).then(function () {
|
334 | var /** @type {?} */ endpoint = _this.config.endpoint + '/auth/logout';
|
335 | if (redirectUri) {
|
336 | endpoint += '?continue=' + encodeURIComponent(redirectUri);
|
337 | }
|
338 | resolve(endpoint);
|
339 | });
|
340 | });
|
341 | };
|
342 | /**
|
343 | * @return {?}
|
344 | */
|
345 | NacoService.prototype.getState = /**
|
346 | * @return {?}
|
347 | */
|
348 | function () {
|
349 | return this.storage.get('state');
|
350 | };
|
351 | /**
|
352 | * @param {?} route
|
353 | * @return {?}
|
354 | */
|
355 | NacoService.prototype.buildNestedUri = /**
|
356 | * @param {?} route
|
357 | * @return {?}
|
358 | */
|
359 | function (route) {
|
360 | var _this = this;
|
361 | var /** @type {?} */ uri = '';
|
362 | if (route.routeConfig && route.routeConfig.path) {
|
363 | var /** @type {?} */ routePath = route.routeConfig.path;
|
364 | for (var /** @type {?} */ key in route.params) {
|
365 | if (key) {
|
366 | var /** @type {?} */ re = new RegExp(':' + key);
|
367 | routePath = routePath.replace(re, route.params[key]);
|
368 | }
|
369 | }
|
370 | uri += '/' + routePath;
|
371 | }
|
372 | if (route.children) {
|
373 | route.children.forEach(function (item) {
|
374 | uri += _this.buildNestedUri(item);
|
375 | });
|
376 | }
|
377 | return uri;
|
378 | };
|
379 | /**
|
380 | * @return {?}
|
381 | */
|
382 | NacoService.prototype.getRefreshToken = /**
|
383 | * @return {?}
|
384 | */
|
385 | function () {
|
386 | if (null !== this.refreshToken) {
|
387 | return Promise.resolve(this.refreshToken);
|
388 | }
|
389 | return this.storage.get('refresh_token');
|
390 | };
|
391 | /**
|
392 | * @return {?}
|
393 | */
|
394 | NacoService.prototype.getClientSecret = /**
|
395 | * @return {?}
|
396 | */
|
397 | function () {
|
398 | if (null !== this.clientSecret) {
|
399 | return Promise.resolve(this.clientSecret);
|
400 | }
|
401 | return this.storage.get('client_secret');
|
402 | };
|
403 | /**
|
404 | * @param {?} path
|
405 | * @return {?}
|
406 | */
|
407 | NacoService.prototype.getUri = /**
|
408 | * @param {?} path
|
409 | * @return {?}
|
410 | */
|
411 | function (path) {
|
412 | return this.config.endpoint + '/api/' + this.VERSION + path;
|
413 | };
|
414 | /**
|
415 | * @param {?=} path
|
416 | * @return {?}
|
417 | */
|
418 | NacoService.prototype.getCurrentOrigin = /**
|
419 | * @param {?=} path
|
420 | * @return {?}
|
421 | */
|
422 | function (path) {
|
423 | return window.location.origin + this.location.prepareExternalUrl(path || '');
|
424 | };
|
425 | /**
|
426 | * @return {?}
|
427 | */
|
428 | NacoService.prototype.generateState = /**
|
429 | * @return {?}
|
430 | */
|
431 | function () {
|
432 | var /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
433 | var /** @type {?} */ text = '';
|
434 | for (var /** @type {?} */ i = 0; i < 5; i++) {
|
435 | text += possible.charAt(Math.floor(Math.random() * possible.length));
|
436 | }
|
437 | return text;
|
438 | };
|
439 | /**
|
440 | * @param {?} params
|
441 | * @return {?}
|
442 | */
|
443 | NacoService.prototype.buildQueryString = /**
|
444 | * @param {?} params
|
445 | * @return {?}
|
446 | */
|
447 | function (params) {
|
448 | var /** @type {?} */ queryParams = Object.keys(params).map(function (key) {
|
449 | return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
|
450 | });
|
451 | return queryParams.join('&');
|
452 | };
|
453 | NacoService.decorators = [
|
454 | { type: Injectable },
|
455 | ];
|
456 | /** @nocollapse */
|
457 | NacoService.ctorParameters = function () { return [
|
458 | { type: Config },
|
459 | { type: Router },
|
460 | { type: Storage },
|
461 | { type: HttpClient },
|
462 | { type: Location }
|
463 | ]; };
|
464 | return NacoService;
|
465 | }());
|
466 | export { NacoService };
|
467 | function NacoService_tsickle_Closure_declarations() {
|
468 | /** @type {?} */
|
469 | NacoService.prototype.VERSION;
|
470 | /** @type {?} */
|
471 | NacoService.prototype.signature;
|
472 | /** @type {?} */
|
473 | NacoService.prototype.user;
|
474 | /** @type {?} */
|
475 | NacoService.prototype.refreshToken;
|
476 | /** @type {?} */
|
477 | NacoService.prototype.clientSecret;
|
478 | /** @type {?} */
|
479 | NacoService.prototype.config;
|
480 | /** @type {?} */
|
481 | NacoService.prototype.router;
|
482 | /** @type {?} */
|
483 | NacoService.prototype.storage;
|
484 | /** @type {?} */
|
485 | NacoService.prototype.http;
|
486 | /** @type {?} */
|
487 | NacoService.prototype.location;
|
488 | }
|
489 |
|
490 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFjby5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5ha2VyL25hY28vIiwic291cmNlcyI6WyJkb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUEwQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQVksRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTFELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxVQUFVLEVBQXFCLE1BQU0sc0JBQXNCLENBQUM7QUFDckUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDOzt5QkFZM0IsUUFDQSxRQUNBLFNBQ0EsTUFDQTtRQUpBLFdBQU0sR0FBTixNQUFNO1FBQ04sV0FBTSxHQUFOLE1BQU07UUFDTixZQUFPLEdBQVAsT0FBTztRQUNQLFNBQUksR0FBSixJQUFJO1FBQ0osYUFBUSxHQUFSLFFBQVE7dUJBWk0sSUFBSTt5QkFFUSxJQUFJO29CQUNkLElBQUk7NEJBQ1MsSUFBSTs0QkFDUCxJQUFJOzs7Ozs7SUFXbkMsNkJBQU87Ozs7Y0FBQyxJQUFpQjtRQUM1QixJQUFJLENBQUMsSUFBSSxH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QUMsT0FBTyxHQUFHLElBQUksQ0FBQzs7Ozs7O0lBR3pELHNDQUFnQjs7OztjQUFDLElBQWE7UUFDakMsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQzs7Ozs7SUFHekUsbUNBQWE7Ozs7UUFDakIscUJBQU0sUUFBUSxHQUFHLGdFQUFnRSxDQUFDO1FBQ2xGLHFCQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFFZCxLQUFLLHFCQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN4QixJQUFJLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztTQUN4RTtRQUVELE9BQU8sSUFBSSxDQUFDOzs7Ozs7SUFHUixzQ0FBZ0I7Ozs7Y0FBQyxNQUFjO1FBQ25DLHFCQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFDLEdBQVc7WUFDcEQsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDMUUsQ0FBQyxDQUFDO1FBRUgsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7Z0JBdFZwQyxVQUFVOzs7O2dCQVZGLE1BQU07Z0JBRmtCLE1BQU07Z0JBQzlCLE9BQU87Z0JBUVAsVUFBVTtnQkFDVixRQUFROztzQkFYakI7O1NBY2EsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi92YWx1ZXMvY29uZmlnJztcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuLi9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTaWduYXR1cmUgfSBmcm9tICcuLi92YWx1ZXMvc2lnbmF0dXJlJztcbmltcG9ydCB7IGZyb21Qcm9taXNlIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBwbGFpblRvQ2xhc3MgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5pbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgVkVSU0lPTiA9ICd2MSc7XG5cbiAgICBwcml2YXRlIHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB1c2VyOiBVc2VyIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgY2xpZW50U2VjcmV0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBjb25maWc6IENvbmZpZyxcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgcHJpdmF0ZSBzdG9yYWdlOiBTdG9yYWdlLFxuICAgICAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLFxuICAgICkge1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRVc2VyKHVzZXI6IFVzZXIgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXNlciA9IHVzZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFVzZXIoKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy51c2VyKSB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy51c2VyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVyaSA9IHRoaXMuZ2V0VXJpKCcvdXNlcnMvbWUnKTtcblxuICAgICAgICByZXR1cm4gZnJvbVByb21pc2UodGhpcy5nZXRTaWduYXR1cmUoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IHNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoVXNlcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhvcml6YXRpb246IGAke3NpZ25hdHVyZS50eXBlfSAke3NpZ25hdHVyZS50b2tlbn1gLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxhbnk+KHVyaSwgb3B0aW9ucykucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGFyZSBubyBib2R5IHRvIGJlIHRyYW5zZm9ybWVkJyk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aFVzZXI6IGFueSA9IHBsYWluVG9DbGFzcyhVc2VyLCBkYXRhKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRVc2VyKGF1dGhVc2VyKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhVc2VyO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZTogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICg0MDEgPT09IGUuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFVzZXIoKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHJlZnJlc2hVc2VyOiBVc2VyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hVc2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKHJlZnJlc2hVc2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0UHJvZmlsZVBpY3R1cmUodXNlcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmVuZHBvaW50ICsgJy91c2Vycy8nICsgdXNlciArICcvcGljdHVyZSc7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNpZ25hdHVyZSgpOiBQcm9taXNlPFNpZ25hdHVyZSB8IG51bGw+IHtcbiAgICAgICAgaWYgKHRoaXMuc2lnbmF0dXJlKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuc2lnbmF0dXJlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdzaWduYXR1cmUnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0U2lnbmF0dXJlKHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNpZ25hdHVyZSA9IHNpZ25hdHVyZTtcblxuICAgICAgICBpZiAobnVsbCA9PT0gc2lnbmF0dXJlKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCdzaWduYXR1cmUnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3NpZ25hdHVyZScsIHNpZ25hdHVyZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Q2xpZW50U2VjcmV0KHNlY3JldDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xpZW50U2VjcmV0ID0gc2VjcmV0O1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdjbGllbnRfc2VjcmV0Jywgc2VjcmV0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UmVmcmVzaFRva2VuKHJlZnJlc2hUb2tlbjogU2lnbmF0dXJlKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2VuO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyZWZyZXNoX3Rva2VuJywgcmVmcmVzaFRva2VuKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFVzZXIoc2NvcGVzPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICB0aGlzLnNldFVzZXIobnVsbCk7XG4gICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKG51bGwpO1xuXG4gICAgICAgIHJldHVybiBmb3JrSm9pbih0aGlzLmdldFJlZnJlc2hUb2tlbigpLCB0aGlzLmdldENsaWVudFNlY3JldCgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChyZXN1bHRzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50U2VjcmV0OiBzdHJpbmcgPSByZXN1bHRzWzFdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hUb2tlbiAmJiBjbGllbnRTZWNyZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0LCByZWZyZXNoVG9rZW4udG9rZW4sIHNjb3Blcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhTaWxlbnRBdXRoKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0OiBzdHJpbmcsIHJlZnJlc2hUb2tlbjogc3RyaW5nLCBzY29wZXM/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmh0dHAucG9zdCh0aGlzLmdldFVyaSgnL3Rva2VucycpLCB7XG4gICAgICAgICAgICBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsXG4gICAgICAgICAgICBzY29wZXM6IHNjb3BlcyB8fCAnYmFzaWMgZW1haWwnLFxuICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IGNsaWVudFNlY3JldCxcbiAgICAgICAgICAgIHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcXVlc3QucGlwZShcbiAgICAgICAgICAgIHRhcCgodG9rZW5zOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodG9rZW5zICYmIHRva2Vucy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXNJbjogdG9rZW5zLmRhdGEuZXhwaXJlc19pbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRva2Vucy5kYXRhLnRva2VuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW5zLmRhdGEuYWNjZXNzX3Rva2VuLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJlZnJlc2hUb2tlbih7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0b2tlbnMuZGF0YS50b2tlbl90eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHRva2Vucy5kYXRhLnJlZnJlc2hfdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKCh0b2tlbnM6IGFueSkgPT4gdG9rZW5zICYmIHRva2Vucy5kYXRhKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoaGFzVG9rZW46IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzVG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWZyZXNoV2l0aFNpbGVudEF1dGgoKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8VXNlciB8IG51bGw+KChvYnNlcnZlcjogT2JzZXJ2ZXI8VXNlciB8IG51bGw+KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWRpcmVjdFVyaSA9IHRoaXMuZ2V0Q3VycmVudE9yaWdpbignYXV0aC9zaWxlbnQnKTtcbiAgICAgICAgICAgIGNvbnN0IHVyaSA9IHRoaXMubG9naW4oJ2Jhc2ljIGVtYWlsJywgcmVkaXJlY3RVcmksIGZhbHNlKTtcblxuICAgICAgICAgICAgY29uc3QgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICAgICAgICBpZnJhbWUuc2V0QXR0cmlidXRlKCdzcmMnLCB1cmkpO1xuICAgICAgICAgICAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICAgICAgICAgIGlmcmFtZS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICdsb2FkJyxcbiAgICAgICAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWVyeVN0cmluZyA9IGlmcmFtZS5jb250ZW50V2luZG93LmxvY2F0aW9uLnNlYXJjaC5zdWJzdHJpbmcoMSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmcmFtZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGlmcmFtZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdWVyeVN0cmluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1ZXJ5UGFydHMgPSBxdWVyeVN0cmluZy5zcGxpdCgnJicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHF1ZXJ5UGFydHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbVBhcnRzID0gaXRlbS5zcGxpdCgnPScpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtc1tpdGVtUGFydHNbMF1dID0gaXRlbVBhcnRzWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXMuaGFzT3duUHJvcGVydHkoJ2FjY2Vzc190b2tlbicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiBwYXJhbXNbJ2FjY2Vzc190b2tlbiddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogcGFyYW1zWyd0b2tlbl90eXBlJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzSW46IHBhcmFtc1sndHRsJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXIoKS50b1Byb21pc2UoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRVc2VyKHVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh1c2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dpbihzY29wZXM6IHN0cmluZywgcmVkaXJlY3RVcmk/OiBzdHJpbmcsIG5lZWRTdGF0ZTogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIXJlZGlyZWN0VXJpKSB7XG4gICAgICAgICAgICByZWRpcmVjdFVyaSA9IHRoaXMucm91dGVyLnVybDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgICAgICAgcmVzcG9uc2VfdHlwZTogJ3Rva2VuJyxcbiAgICAgICAgICAgIHNjb3Blczogc2NvcGVzLFxuICAgICAgICAgICAgY2xpZW50OiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgIHNpbGVudDogdHJ1ZSxcbiAgICAgICAgICAgIGNvbnRpbnVlOiBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmkpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChuZWVkU3RhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5nZW5lcmF0ZVN0YXRlKCk7XG5cbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3N0YXRlJywgc3RhdGUpO1xuICAgICAgICAgICAgcGFyYW1zLnN0YXRlID0gc3RhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWVyeTogc3RyaW5nID0gdGhpcy5idWlsZFF1ZXJ5U3RyaW5nKHBhcmFtcyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmVuZHBvaW50ICsgJy9hdXRoPycgKyBxdWVyeTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbG9nb3V0KHJlZGlyZWN0VXJpPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgdGhpcy5zaWduYXR1cmUgPSBudWxsO1xuICAgICAgICB0aGlzLnVzZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmNsaWVudFNlY3JldCA9IG51bGw7XG4gICAgICAgIHRoaXMucmVmcmVzaFRva2VuID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjbGVhciA9IFtcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCdzaWduYXR1cmUnKSxcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlKCd1c2VyJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgncmVmcmVzaF90b2tlbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5yZW1vdmUoJ2NsaWVudF9zZWNyZXQnKSxcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIFByb21pc2UuYWxsKGNsZWFyKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZW5kcG9pbnQgPSB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXV0aC9sb2dvdXQnO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZGlyZWN0VXJpKSB7XG4gICAgICAgICAgICAgICAgICAgIGVuZHBvaW50ICs9ICc/Y29udGludWU9JyArIGVuY29kZVVSSUNvbXBvbmVudChyZWRpcmVjdFVyaSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShlbmRwb2ludCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFN0YXRlKCk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgnc3RhdGUnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYnVpbGROZXN0ZWRVcmkocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdXJpID0gJyc7XG5cbiAgICAgICAgaWYgKHJvdXRlLnJvdXRlQ29uZmlnICYmIHJvdXRlLnJvdXRlQ29uZmlnLnBhdGgpIHtcbiAgICAgICAgICAgIGxldCByb3V0ZVBhdGggPSByb3V0ZS5yb3V0ZUNvbmZpZy5wYXRoO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiByb3V0ZS5wYXJhbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cCgnOicgKyBrZXkpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJvdXRlUGF0aCA9IHJvdXRlUGF0aC5yZXBsYWNlKHJlLCByb3V0ZS5wYXJhbXNba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1cmkgKz0gJy8nICsgcm91dGVQYXRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICByb3V0ZS5jaGlsZHJlbi5mb3JFYWNoKChpdGVtOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KSA9PiB7XG4gICAgICAgICAgICAgICAgdXJpICs9IHRoaXMuYnVpbGROZXN0ZWRVcmkoaXRlbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1cmk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZWZyZXNoVG9rZW4oKTogUHJvbWlzZTxTaWduYXR1cmUgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnJlZnJlc2hUb2tlbikge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnJlZnJlc2hUb2tlbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgncmVmcmVzaF90b2tlbicpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q2xpZW50U2VjcmV0KCk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy5jbGllbnRTZWNyZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5jbGllbnRTZWNyZXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ2NsaWVudF9zZWNyZXQnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFVyaShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2FwaS8nICsgdGhpcy5WRVJTSU9OICsgcGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Q3VycmVudE9yaWdpbihwYXRoPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gKyB0aGlzLmxvY2F0aW9uLnByZXBhcmVFeHRlcm5hbFVybChwYXRoIHx8ICcnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdlbmVyYXRlU3RhdGUoKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcG9zc2libGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknO1xuICAgICAgICBsZXQgdGV4dCA9ICcnO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgICAgICB0ZXh0ICs9IHBvc3NpYmxlLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBwb3NzaWJsZS5sZW5ndGgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIHByaXZhdGUgYnVpbGRRdWVyeVN0cmluZyhwYXJhbXM6IG9iamVjdCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gT2JqZWN0LmtleXMocGFyYW1zKS5tYXAoKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1zW2tleV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcXVlcnlQYXJhbXMuam9pbignJicpO1xuICAgIH1cbn1cbiJdfQ== |
\ | No newline at end of file |