ssi-security-commons 0.16.23 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ssi-security-commons.mjs +80 -52
- package/fesm2022/ssi-security-commons.mjs.map +1 -1
- package/lib/services/user-event.service.d.ts +11 -0
- package/package.json +6 -8
- package/public-api.d.ts +1 -0
- package/esm2022/lib/alert/alert.component.mjs +0 -29
- package/esm2022/lib/services/auth-interceptor.service.mjs +0 -165
- package/esm2022/lib/services/crypto.service.mjs +0 -41
- package/esm2022/lib/services/jwt.service.mjs +0 -29
- package/esm2022/lib/services/messages.service.mjs +0 -248
- package/esm2022/lib/services/session.service.mjs +0 -413
- package/esm2022/lib/services/web-authn.service.mjs +0 -249
- package/esm2022/lib/shared/constants.mjs +0 -5
- package/esm2022/lib/ssi-security-commons.component.mjs +0 -13
- package/esm2022/lib/ssi-security-commons.module.mjs +0 -60
- package/esm2022/lib/ssi-security-commons.service.mjs +0 -13
- package/esm2022/lib/user.model.mjs +0 -2
- package/esm2022/public-api.mjs +0 -15
- package/esm2022/ssi-security-commons.mjs +0 -5
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-lines-per-function */
|
|
2
|
-
/* eslint-disable arrow-body-style */
|
|
3
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
4
|
-
import { Inject, Injectable } from '@angular/core';
|
|
5
|
-
import { HttpHeaders } from '@angular/common/http';
|
|
6
|
-
import { map } from 'rxjs/operators';
|
|
7
|
-
import { REFRESH_TOKEN, TOKEN, USERDATA } from '../shared/constants';
|
|
8
|
-
import * as i0 from "@angular/core";
|
|
9
|
-
import * as i1 from "@angular/common/http";
|
|
10
|
-
import * as i2 from "./crypto.service";
|
|
11
|
-
import * as i3 from "./jwt.service";
|
|
12
|
-
export class SessionService {
|
|
13
|
-
constructor(http, environment, cryptoService, jwtService) {
|
|
14
|
-
this.http = http;
|
|
15
|
-
this.cryptoService = cryptoService;
|
|
16
|
-
this.jwtService = jwtService;
|
|
17
|
-
this.loginUrl = 'http://localhost:4200/login';
|
|
18
|
-
this.endPoint = environment.endPointCore;
|
|
19
|
-
this.applicationId = environment.applicationId;
|
|
20
|
-
this.environment = environment;
|
|
21
|
-
}
|
|
22
|
-
buildUserdataFromToken(token) {
|
|
23
|
-
const tokenData = this.jwtService.decodeToken(token);
|
|
24
|
-
const userData = {
|
|
25
|
-
givenName: tokenData.given_name,
|
|
26
|
-
familyName: tokenData.family_name,
|
|
27
|
-
name: tokenData.name,
|
|
28
|
-
roles: tokenData.realm_access.roles,
|
|
29
|
-
userId: tokenData.sub,
|
|
30
|
-
username: tokenData.preferred_username,
|
|
31
|
-
email: tokenData.email,
|
|
32
|
-
emailVerified: tokenData.email_verified,
|
|
33
|
-
countryCode: tokenData.country_code
|
|
34
|
-
};
|
|
35
|
-
return userData;
|
|
36
|
-
}
|
|
37
|
-
async reviewSessionData() {
|
|
38
|
-
const value = await this.checkSessionData();
|
|
39
|
-
console.log(`async result: ${value}`);
|
|
40
|
-
return value;
|
|
41
|
-
}
|
|
42
|
-
setUserdata(userdata) {
|
|
43
|
-
this.userdata = userdata;
|
|
44
|
-
}
|
|
45
|
-
setTokens(token, refreshToken) {
|
|
46
|
-
this.token = token;
|
|
47
|
-
this.refreshToken = refreshToken;
|
|
48
|
-
}
|
|
49
|
-
getUserdata() {
|
|
50
|
-
return this.userdata;
|
|
51
|
-
}
|
|
52
|
-
setRefreshToken(refreshToken) {
|
|
53
|
-
this.refreshToken = refreshToken;
|
|
54
|
-
this.saveStorageData(REFRESH_TOKEN, refreshToken);
|
|
55
|
-
}
|
|
56
|
-
getRefreshToken() {
|
|
57
|
-
return this.refreshToken;
|
|
58
|
-
}
|
|
59
|
-
setToken(token) {
|
|
60
|
-
this.token = token;
|
|
61
|
-
this.saveStorageData(TOKEN, token);
|
|
62
|
-
}
|
|
63
|
-
getToken() {
|
|
64
|
-
return this.token;
|
|
65
|
-
}
|
|
66
|
-
destroyCredentials() {
|
|
67
|
-
this.token = undefined;
|
|
68
|
-
this.refreshToken = undefined;
|
|
69
|
-
this.deleteStorageData(TOKEN);
|
|
70
|
-
this.deleteStorageData(REFRESH_TOKEN);
|
|
71
|
-
}
|
|
72
|
-
destroyUserData() {
|
|
73
|
-
this.userdata = undefined;
|
|
74
|
-
this.deleteStorageData(USERDATA);
|
|
75
|
-
}
|
|
76
|
-
saveCredentials(token, refreshToken) {
|
|
77
|
-
this.token = token;
|
|
78
|
-
this.refreshToken = refreshToken;
|
|
79
|
-
this.saveStorageData(TOKEN, token);
|
|
80
|
-
this.saveStorageData(REFRESH_TOKEN, refreshToken);
|
|
81
|
-
this.saveUserData(this.buildUserdataFromToken(token));
|
|
82
|
-
}
|
|
83
|
-
saveUserData(userData) {
|
|
84
|
-
this.userdata = userData;
|
|
85
|
-
this.saveStorageData(USERDATA, JSON.stringify(userData));
|
|
86
|
-
}
|
|
87
|
-
isLoggedIn() {
|
|
88
|
-
return !!this.userdata;
|
|
89
|
-
}
|
|
90
|
-
logout() {
|
|
91
|
-
let clientId = this.environment.authClient;
|
|
92
|
-
if (this.refreshToken) {
|
|
93
|
-
const decoded = this.jwtService.decodeToken(this.refreshToken);
|
|
94
|
-
clientId = decoded.azp;
|
|
95
|
-
}
|
|
96
|
-
return new Promise((resolve, reject) => {
|
|
97
|
-
this.logoutApiClient(clientId).subscribe(res => {
|
|
98
|
-
console.log(res);
|
|
99
|
-
this.destroyCredentials();
|
|
100
|
-
this.destroyUserData();
|
|
101
|
-
this.goToLogin();
|
|
102
|
-
resolve(null);
|
|
103
|
-
}, (err) => {
|
|
104
|
-
this.destroyCredentials();
|
|
105
|
-
this.destroyUserData();
|
|
106
|
-
console.error(err);
|
|
107
|
-
reject(err);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
getNewToken(refreshToken) {
|
|
112
|
-
console.log('getNewToken');
|
|
113
|
-
const body = 'grant_type=refresh_token' + '&refresh_token=' + refreshToken + '&client_id=' + this.environment.authClient;
|
|
114
|
-
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
|
|
115
|
-
return this.http.post(`${this.environment.authEndPoint}/realms/${this.environment.authRealm}/protocol/openid-connect/token`, body, { headers })
|
|
116
|
-
.pipe(map(res => res));
|
|
117
|
-
}
|
|
118
|
-
getNewTokenClient(refreshToken, clientId) {
|
|
119
|
-
console.log('getNewToken');
|
|
120
|
-
const body = 'grant_type=refresh_token' + '&refresh_token=' + refreshToken + '&client_id=' + clientId;
|
|
121
|
-
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
|
|
122
|
-
return this.http.post(`${this.environment.authEndPoint}/realms/${this.environment.authRealm}/protocol/openid-connect/token`, body, { headers })
|
|
123
|
-
.pipe(map(res => res));
|
|
124
|
-
}
|
|
125
|
-
getTokenClientCode(refreshToken, clientId) {
|
|
126
|
-
console.log('getNewToken');
|
|
127
|
-
const body = 'grant_type=refresh_token' + '&refresh_token=' + refreshToken + '&client_id=' + clientId;
|
|
128
|
-
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
|
|
129
|
-
return this.http.post(`${this.environment.authEndPoint}/realms/${this.environment.authRealm}/protocol/openid-connect/token`, body, { headers })
|
|
130
|
-
.pipe(map(res => res));
|
|
131
|
-
}
|
|
132
|
-
getLoginUrl() {
|
|
133
|
-
return this.http.get(this.endPoint + '/auth/login/url/' + this.environment.authClient)
|
|
134
|
-
.pipe(map(res => res));
|
|
135
|
-
}
|
|
136
|
-
getHomeUrl() {
|
|
137
|
-
return this.http.get(this.endPoint + '/auth/home/url/' + this.environment.authClient)
|
|
138
|
-
.pipe(map(res => res));
|
|
139
|
-
}
|
|
140
|
-
logoutApi() {
|
|
141
|
-
const body = 'refresh_token=' + this.refreshToken + '&client_id=' + this.environment.authClient;
|
|
142
|
-
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
|
|
143
|
-
return this.http.post(`${this.environment.authEndPoint}/realms/${this.environment.authRealm}/protocol/openid-connect/logout`, body, { headers })
|
|
144
|
-
.pipe(map(res => res));
|
|
145
|
-
}
|
|
146
|
-
logoutApiClient(clientId) {
|
|
147
|
-
const body = 'refresh_token=' + this.refreshToken + '&client_id=' + clientId;
|
|
148
|
-
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
|
|
149
|
-
return this.http.post(`${this.environment.authEndPoint}/realms/${this.environment.authRealm}/protocol/openid-connect/logout`, body, { headers })
|
|
150
|
-
.pipe(map(res => res));
|
|
151
|
-
}
|
|
152
|
-
goToLogin() {
|
|
153
|
-
this.getLoginUrl().subscribe(res => {
|
|
154
|
-
console.log(res);
|
|
155
|
-
const loginUrl = res.data;
|
|
156
|
-
window.location.href = loginUrl;
|
|
157
|
-
}, (err) => {
|
|
158
|
-
console.error(err);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
loadSessionData() {
|
|
162
|
-
let data;
|
|
163
|
-
let token;
|
|
164
|
-
let refreshToken;
|
|
165
|
-
if (this.environment.production) {
|
|
166
|
-
const u = this.cryptoService.encrypt(USERDATA);
|
|
167
|
-
const t = this.cryptoService.encrypt(TOKEN);
|
|
168
|
-
const r = this.cryptoService.encrypt(REFRESH_TOKEN);
|
|
169
|
-
data = window.localStorage.getItem(u);
|
|
170
|
-
token = window.localStorage.getItem(t);
|
|
171
|
-
refreshToken = window.localStorage.getItem(r);
|
|
172
|
-
if (data && token && refreshToken) {
|
|
173
|
-
data = this.cryptoService.decrypt(data);
|
|
174
|
-
token = this.cryptoService.decrypt(token);
|
|
175
|
-
refreshToken = this.cryptoService.decrypt(refreshToken);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
data = window.localStorage.getItem(USERDATA);
|
|
180
|
-
token = window.localStorage.getItem(TOKEN);
|
|
181
|
-
refreshToken = window.localStorage.getItem(REFRESH_TOKEN);
|
|
182
|
-
}
|
|
183
|
-
if (data && token && refreshToken) {
|
|
184
|
-
const user = JSON.parse(data);
|
|
185
|
-
this.setTokens(token, refreshToken);
|
|
186
|
-
this.setUserdata(user);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
userHasOptionsInApp(userId, applicationId) {
|
|
190
|
-
return this.http.get(this.endPoint + `/security/option/${applicationId}/${userId}`)
|
|
191
|
-
.pipe(map(res => res));
|
|
192
|
-
}
|
|
193
|
-
checkAppPermissions() {
|
|
194
|
-
const promise = new Promise((resolve, reject) => {
|
|
195
|
-
console.log(this.userdata?.userId, this.applicationId);
|
|
196
|
-
if (this.applicationId) {
|
|
197
|
-
this.userHasOptionsInApp(this.userdata?.userId, this.applicationId).subscribe(res => {
|
|
198
|
-
console.log(res);
|
|
199
|
-
if (res.data) {
|
|
200
|
-
resolve('ok');
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
this.getHomeUrl().subscribe(res1 => {
|
|
204
|
-
console.log(res1);
|
|
205
|
-
const homeUrl = res1.data;
|
|
206
|
-
window.location.href = homeUrl;
|
|
207
|
-
reject('nok');
|
|
208
|
-
}, (err) => {
|
|
209
|
-
console.error(err);
|
|
210
|
-
reject('nok');
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}, (err) => {
|
|
214
|
-
console.error(err);
|
|
215
|
-
reject('nok');
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
resolve('ok');
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
return promise;
|
|
223
|
-
}
|
|
224
|
-
// eslint-disable-next-line max-len
|
|
225
|
-
getOptionsUser(applicationId, type, language, entityCode, parentOptionId, includeData) {
|
|
226
|
-
const param = {
|
|
227
|
-
userId: this.userdata?.userId,
|
|
228
|
-
applicationId,
|
|
229
|
-
type,
|
|
230
|
-
language,
|
|
231
|
-
entityCode,
|
|
232
|
-
parentOptionId,
|
|
233
|
-
includeData
|
|
234
|
-
};
|
|
235
|
-
return this.http.post(this.endPoint + '/security/option/user', param)
|
|
236
|
-
.pipe(map(res => res));
|
|
237
|
-
}
|
|
238
|
-
registerException(param) {
|
|
239
|
-
const headers = new HttpHeaders().set('skipError', 'true');
|
|
240
|
-
return this.http.post(this.endPoint + '/auth/exception/log', param, { headers })
|
|
241
|
-
.pipe(map(res => res));
|
|
242
|
-
}
|
|
243
|
-
saveStorageData(key, value) {
|
|
244
|
-
if (this.environment.production) {
|
|
245
|
-
const k = this.cryptoService.encrypt(key);
|
|
246
|
-
const v = this.cryptoService.encrypt(value);
|
|
247
|
-
window.localStorage.setItem(k, v);
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
window.localStorage.setItem(key, value);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
deleteStorageData(key) {
|
|
254
|
-
if (this.environment.production) {
|
|
255
|
-
const k = this.cryptoService.encrypt(key);
|
|
256
|
-
window.localStorage.removeItem(k);
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
window.localStorage.removeItem(key);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
getStorageData(key) {
|
|
263
|
-
let res;
|
|
264
|
-
if (this.environment.production) {
|
|
265
|
-
const k = this.cryptoService.encrypt(key);
|
|
266
|
-
const v = window.localStorage.getItem(k);
|
|
267
|
-
if (v) {
|
|
268
|
-
res = this.cryptoService.decrypt(v);
|
|
269
|
-
return res;
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
res = null;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
res = window.localStorage.getItem(key);
|
|
277
|
-
}
|
|
278
|
-
return res;
|
|
279
|
-
}
|
|
280
|
-
removeUrlData() {
|
|
281
|
-
const url = new URL(window.location.href);
|
|
282
|
-
const queryParams = url.searchParams;
|
|
283
|
-
queryParams.delete('code');
|
|
284
|
-
const newUrl = url.origin + url.pathname + '?' + queryParams.toString();
|
|
285
|
-
window.history.replaceState({}, document.title, newUrl);
|
|
286
|
-
}
|
|
287
|
-
checkSessionData() {
|
|
288
|
-
const promise = new Promise((resolve, reject) => {
|
|
289
|
-
let data;
|
|
290
|
-
let token;
|
|
291
|
-
let refreshToken;
|
|
292
|
-
const currentUrl = new URL(window.location.href);
|
|
293
|
-
const code = currentUrl.searchParams.get('code');
|
|
294
|
-
console.log('code', code);
|
|
295
|
-
if (code) {
|
|
296
|
-
const codeDecoded = this.getDecodedAuthCode(code);
|
|
297
|
-
// console.log('code', codeDecoded);
|
|
298
|
-
const decoded = this.jwtService.decodeToken(codeDecoded);
|
|
299
|
-
this.getTokenClientCode(codeDecoded, decoded.azp).subscribe({
|
|
300
|
-
next: (res) => {
|
|
301
|
-
console.log(res);
|
|
302
|
-
token = res.access_token;
|
|
303
|
-
refreshToken = res.refresh_token;
|
|
304
|
-
this.saveCredentials(token, refreshToken);
|
|
305
|
-
this.checkAppPermissions().then((res1) => {
|
|
306
|
-
console.log(res1);
|
|
307
|
-
this.removeUrlData();
|
|
308
|
-
resolve('OK');
|
|
309
|
-
}, (err) => {
|
|
310
|
-
console.error(err);
|
|
311
|
-
reject(err);
|
|
312
|
-
});
|
|
313
|
-
},
|
|
314
|
-
error: (err) => {
|
|
315
|
-
console.error(err);
|
|
316
|
-
reject(err);
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
else {
|
|
321
|
-
data = this.getStorageData(USERDATA);
|
|
322
|
-
token = this.getStorageData(TOKEN);
|
|
323
|
-
refreshToken = this.getStorageData(REFRESH_TOKEN);
|
|
324
|
-
if (data && token && refreshToken) {
|
|
325
|
-
this.saveCredentials(token, refreshToken);
|
|
326
|
-
this.checkAppPermissions().then((res1) => {
|
|
327
|
-
console.log(res1);
|
|
328
|
-
resolve('OK');
|
|
329
|
-
}, (err) => {
|
|
330
|
-
console.error(err);
|
|
331
|
-
reject(err);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
const url = window.location.href;
|
|
336
|
-
if (url.indexOf('/redirect') > -1) {
|
|
337
|
-
resolve('OK');
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
this.destroyCredentials();
|
|
341
|
-
this.destroyUserData();
|
|
342
|
-
this.getLoginUrl().subscribe(res1 => {
|
|
343
|
-
console.log(res1);
|
|
344
|
-
this.loginUrl = res1.data;
|
|
345
|
-
if (url.indexOf('/login') < 0 && url.indexOf('/forgot') < 0 &&
|
|
346
|
-
url.indexOf('/reset') < 0 && url.indexOf('/verify') < 0 &&
|
|
347
|
-
url.indexOf('/sign_up') < 0) {
|
|
348
|
-
window.location.href = this.loginUrl + '?continue=' + encodeURIComponent(url);
|
|
349
|
-
}
|
|
350
|
-
resolve('NOK');
|
|
351
|
-
}, (err) => {
|
|
352
|
-
console.error(err);
|
|
353
|
-
reject(err);
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
return promise;
|
|
360
|
-
}
|
|
361
|
-
checkSessionDataMicrofront() {
|
|
362
|
-
const promise = new Promise((resolve, reject) => {
|
|
363
|
-
let data;
|
|
364
|
-
let token;
|
|
365
|
-
let refreshToken;
|
|
366
|
-
if (this.environment.production) {
|
|
367
|
-
const u = this.cryptoService.encrypt(USERDATA);
|
|
368
|
-
const t = this.cryptoService.encrypt(TOKEN);
|
|
369
|
-
const r = this.cryptoService.encrypt(REFRESH_TOKEN);
|
|
370
|
-
const d1 = window.localStorage.getItem(u);
|
|
371
|
-
const d2 = window.localStorage.getItem(t);
|
|
372
|
-
const d3 = window.localStorage.getItem(r);
|
|
373
|
-
if (d1 && d2 && d3) {
|
|
374
|
-
data = this.cryptoService.decrypt(d1);
|
|
375
|
-
token = this.cryptoService.decrypt(d2);
|
|
376
|
-
refreshToken = this.cryptoService.decrypt(d3);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
data = window.localStorage.getItem(USERDATA);
|
|
381
|
-
token = window.localStorage.getItem(TOKEN);
|
|
382
|
-
refreshToken = window.localStorage.getItem(REFRESH_TOKEN);
|
|
383
|
-
}
|
|
384
|
-
if (data && token && refreshToken) {
|
|
385
|
-
console.log('local session ok');
|
|
386
|
-
this.saveCredentials(token, refreshToken);
|
|
387
|
-
resolve('OK');
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
console.error('local session nok');
|
|
391
|
-
reject('NOK');
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
return promise;
|
|
395
|
-
}
|
|
396
|
-
getAuthCode() {
|
|
397
|
-
const enc = this.cryptoService.encrypt(this.refreshToken ? this.refreshToken : '');
|
|
398
|
-
return encodeURIComponent(enc);
|
|
399
|
-
}
|
|
400
|
-
getDecodedAuthCode(code) {
|
|
401
|
-
const dec = decodeURIComponent(code);
|
|
402
|
-
return this.cryptoService.decrypt(dec);
|
|
403
|
-
}
|
|
404
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SessionService, deps: [{ token: i1.HttpClient }, { token: 'environment' }, { token: i2.CryptoService }, { token: i3.JwtService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
405
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SessionService }); }
|
|
406
|
-
}
|
|
407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SessionService, decorators: [{
|
|
408
|
-
type: Injectable
|
|
409
|
-
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
410
|
-
type: Inject,
|
|
411
|
-
args: ['environment']
|
|
412
|
-
}] }, { type: i2.CryptoService }, { type: i3.JwtService }]; } });
|
|
413
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3NpLXNlY3VyaXR5LWNvbW1vbnMvc3JjL2xpYi9zZXJ2aWNlcy9zZXNzaW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMkNBQTJDO0FBQzNDLHFDQUFxQztBQUNyQyx5REFBeUQ7QUFDekQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRy9ELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdyQyxPQUFPLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7QUFJckUsTUFBTSxPQUFPLGNBQWM7SUFVekIsWUFBb0IsSUFBZ0IsRUFDWCxXQUFnQixFQUNyQixhQUE0QixFQUM1QixVQUFzQjtRQUh0QixTQUFJLEdBQUosSUFBSSxDQUFZO1FBRWhCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFQMUMsYUFBUSxHQUFHLDZCQUE2QixDQUFDO1FBUXZDLElBQUksQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDLFlBQVksQ0FBQztRQUN6QyxJQUFJLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUM7UUFDL0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDakMsQ0FBQztJQUVNLHNCQUFzQixDQUFDLEtBQWE7UUFDekMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckQsTUFBTSxRQUFRLEdBQWE7WUFDekIsU0FBUyxFQUFFLFNBQVMsQ0FBQyxVQUFVO1lBQy9CLFVBQVUsRUFBRSxTQUFTLENB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QkFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztnQkFDMUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2Y7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUNuQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDZjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVNLFdBQVc7UUFDaEIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQSxDQUFDLENBQUEsSUFBSSxDQUFDLFlBQVksQ0FBQSxDQUFDLENBQUEsRUFBRSxDQUFDLENBQUM7UUFDL0UsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRU8sa0JBQWtCLENBQUMsSUFBWTtRQUNyQyxNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7OEdBL2JVLGNBQWMsNENBV2YsYUFBYTtrSEFYWixjQUFjOzsyRkFBZCxjQUFjO2tCQUQxQixVQUFVOzswQkFZTixNQUFNOzJCQUFDLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGluZXMtcGVyLWZ1bmN0aW9uICovXG4vKiBlc2xpbnQtZGlzYWJsZSBhcnJvdy1ib2R5LXN0eWxlICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEhlYWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBGcm9udEVuZEV4Y2VwdGlvbiwgVXNlckRhdGEgfSBmcm9tICcuLi91c2VyLm1vZGVsJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEp3dFNlcnZpY2UgfSBmcm9tICcuL2p3dC5zZXJ2aWNlJztcbmltcG9ydCB7IENyeXB0b1NlcnZpY2UgfSBmcm9tICcuL2NyeXB0by5zZXJ2aWNlJztcbmltcG9ydCB7IFJFRlJFU0hfVE9LRU4sIFRPS0VOLCBVU0VSREFUQSB9IGZyb20gJy4uL3NoYXJlZC9jb25zdGFudHMnO1xuXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBTZXNzaW9uU2VydmljZSB7XG5cbiAgdXNlcmRhdGE6IFVzZXJEYXRhIHwgdW5kZWZpbmVkO1xuICB0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICByZWZyZXNoVG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgZW5kUG9pbnQ6IHN0cmluZztcbiAgbG9naW5VcmwgPSAnaHR0cDovL2xvY2FsaG9zdDo0MjAwL2xvZ2luJztcbiAgYXBwbGljYXRpb25JZDogYW55O1xuICBlbnZpcm9ubWVudDogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICBASW5qZWN0KCdlbnZpcm9ubWVudCcpIGVudmlyb25tZW50OiBhbnksXG4gICAgICAgICAgICAgIHByaXZhdGUgY3J5cHRvU2VydmljZTogQ3J5cHRvU2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBqd3RTZXJ2aWNlOiBKd3RTZXJ2aWNlKSB7XG4gICAgdGhpcy5lbmRQb2ludCA9IGVudmlyb25tZW50LmVuZFBvaW50Q29yZTtcbiAgICB0aGlzLmFwcGxpY2F0aW9uSWQgPSBlbnZpcm9ubWVudC5hcHBsaWNhdGlvbklkO1xuICAgIHRoaXMuZW52aXJvbm1lbnQgPSBlbnZpcm9ubWVudDtcbiAgfVxuXG4gIHB1YmxpYyBidWlsZFVzZXJkYXRhRnJvbVRva2VuKHRva2VuOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IHRva2VuRGF0YSA9IHRoaXMuand0U2VydmljZS5kZWNvZGVUb2tlbih0b2tlbik7XG4gICAgY29uc3QgdXNlckRhdGE6IFVzZXJEYXRhID0ge1xuICAgICAgZ2l2ZW5OYW1lOiB0b2tlbkRhdGEuZ2l2ZW5fbmFtZSxcbiAgICAgIGZhbWlseU5hbWU6IHRva2VuRGF0YS5mYW1pbHlfbmFtZSxcbiAgICAgIG5hbWU6IHRva2VuRGF0YS5uYW1lLFxuICAgICAgcm9sZXM6IHRva2VuRGF0YS5yZWFsbV9hY2Nlc3Mucm9sZXMsXG4gICAgICB1c2VySWQ6IHRva2VuRGF0YS5zdWIsXG4gICAgICB1c2VybmFtZTogdG9rZW5EYXRhLnByZWZlcnJlZF91c2VybmFtZSxcbiAgICAgIGVtYWlsOiB0b2tlbkRhdGEuZW1haWwsXG4gICAgICBlbWFpbFZlcmlmaWVkOiB0b2tlbkRhdGEuZW1haWxfdmVyaWZpZWQsXG4gICAgICBjb3VudHJ5Q29kZTogdG9rZW5EYXRhLmNvdW50cnlfY29kZVxuICAgIH07XG4gICAgcmV0dXJuIHVzZXJEYXRhO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJldmlld1Nlc3Npb25EYXRhKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgdmFsdWUgPSBhd2FpdCB0aGlzLmNoZWNrU2Vzc2lvbkRhdGEoKSBhcyBhbnk7XG4gICAgY29uc29sZS5sb2coYGFzeW5jIHJlc3VsdDogJHt2YWx1ZX1gKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgc2V0VXNlcmRhdGEodXNlcmRhdGE6IGFueSk6IHZvaWQge1xuICAgIHRoaXMudXNlcmRhdGEgPSB1c2VyZGF0YTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRUb2tlbnModG9rZW46IGFueSwgcmVmcmVzaFRva2VuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgdGhpcy5yZWZyZXNoVG9rZW4gPSByZWZyZXNoVG9rZW47XG4gIH1cblxuICBwdWJsaWMgZ2V0VXNlcmRhdGEoKTogVXNlckRhdGEgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnVzZXJkYXRhO1xuICB9XG5cbiAgcHVibGljIHNldFJlZnJlc2hUb2tlbihyZWZyZXNoVG9rZW46IGFueSk6IHZvaWQge1xuICAgIHRoaXMucmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2VuO1xuICAgIHRoaXMuc2F2ZVN0b3JhZ2VEYXRhKFJFRlJFU0hfVE9LRU4sIHJlZnJlc2hUb2tlbik7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmVmcmVzaFRva2VuKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaFRva2VuO1xuICB9XG5cbiAgcHVibGljIHNldFRva2VuKHRva2VuOiBhbnkpOiBhbnkge1xuICAgIHRoaXMudG9rZW4gPSB0b2tlbjtcbiAgICB0aGlzLnNhdmVTdG9yYWdlRGF0YShUT0tFTiwgdG9rZW4pO1xuICB9XG5cbiAgcHVibGljIGdldFRva2VuKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW47XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveUNyZWRlbnRpYWxzKCk6IHZvaWQge1xuICAgIHRoaXMudG9rZW4gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yZWZyZXNoVG9rZW4gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5kZWxldGVTdG9yYWdlRGF0YShUT0tFTik7XG4gICAgdGhpcy5kZWxldGVTdG9yYWdlRGF0YShSRUZSRVNIX1RPS0VOKTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95VXNlckRhdGEoKTogdm9pZCB7XG4gICAgdGhpcy51c2VyZGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRlbGV0ZVN0b3JhZ2VEYXRhKFVTRVJEQVRBKTtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlQ3JlZGVudGlhbHModG9rZW46IGFueSwgcmVmcmVzaFRva2VuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgdGhpcy5yZWZyZXNoVG9rZW4gPSByZWZyZXNoVG9rZW47XG4gICAgdGhpcy5zYXZlU3RvcmFnZURhdGEoVE9LRU4sIHRva2VuKTtcbiAgICB0aGlzLnNhdmVTdG9yYWdlRGF0YShSRUZSRVNIX1RPS0VOLCByZWZyZXNoVG9rZW4pO1xuICAgIHRoaXMuc2F2ZVVzZXJEYXRhKHRoaXMuYnVpbGRVc2VyZGF0YUZyb21Ub2tlbih0b2tlbikpO1xuICB9XG5cbiAgcHVibGljIHNhdmVVc2VyRGF0YSh1c2VyRGF0YTogYW55KTogdm9pZCB7XG4gICAgdGhpcy51c2VyZGF0YSA9IHVzZXJEYXRhO1xuICAgIHRoaXMuc2F2ZVN0b3JhZ2VEYXRhKFVTRVJEQVRBLCBKU09OLnN0cmluZ2lmeSh1c2VyRGF0YSkpO1xuICB9XG5cbiAgcHVibGljIGlzTG9nZ2VkSW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy51c2VyZGF0YTtcbiAgfVxuXG4gIGxvZ291dCgpOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBjbGllbnRJZCA9IHRoaXMuZW52aXJvbm1lbnQuYXV0aENsaWVudDtcbiAgICBpZiAodGhpcy5yZWZyZXNoVG9rZW4pIHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSB0aGlzLmp3dFNlcnZpY2UuZGVjb2RlVG9rZW4odGhpcy5yZWZyZXNoVG9rZW4pO1xuICAgICAgY2xpZW50SWQgPSBkZWNvZGVkLmF6cDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMubG9nb3V0QXBpQ2xpZW50KGNsaWVudElkKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzKTtcbiAgICAgICAgdGhpcy5kZXN0cm95Q3JlZGVudGlhbHMoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95VXNlckRhdGEoKTtcbiAgICAgICAgdGhpcy5nb1RvTG9naW4oKTtcbiAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgdGhpcy5kZXN0cm95Q3JlZGVudGlhbHMoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95VXNlckRhdGEoKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0TmV3VG9rZW4ocmVmcmVzaFRva2VuOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnNvbGUubG9nKCdnZXROZXdUb2tlbicpO1xuICAgIGNvbnN0IGJvZHkgPSAnZ3JhbnRfdHlwZT1yZWZyZXNoX3Rva2VuJyArICcmcmVmcmVzaF90b2tlbj0nICsgcmVmcmVzaFRva2VuICsgJyZjbGllbnRfaWQ9JyArIHRoaXMuZW52aXJvbm1lbnQuYXV0aENsaWVudDtcblxuICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoKS5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55PihgJHt0aGlzLmVudmlyb25tZW50LmF1dGhFbmRQb2ludH0vcmVhbG1zLyR7dGhpcy5lbnZpcm9ubWVudC5hdXRoUmVhbG19L3Byb3RvY29sL29wZW5pZC1jb25uZWN0L3Rva2VuYCxcbiAgICAgIGJvZHksIHtoZWFkZXJzfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcykpO1xuICB9XG5cbiAgZ2V0TmV3VG9rZW5DbGllbnQocmVmcmVzaFRva2VuOiBzdHJpbmcsIGNsaWVudElkOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnNvbGUubG9nKCdnZXROZXdUb2tlbicpO1xuICAgIGNvbnN0IGJvZHkgPSAnZ3JhbnRfdHlwZT1yZWZyZXNoX3Rva2VuJyArICcmcmVmcmVzaF90b2tlbj0nICsgcmVmcmVzaFRva2VuICsgJyZjbGllbnRfaWQ9JyArIGNsaWVudElkO1xuXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KGAke3RoaXMuZW52aXJvbm1lbnQuYXV0aEVuZFBvaW50fS9yZWFsbXMvJHt0aGlzLmVudmlyb25tZW50LmF1dGhSZWFsbX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdG9rZW5gLFxuICAgICAgYm9keSwge2hlYWRlcnN9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChyZXMgPT4gcmVzKSk7XG4gIH1cblxuICBnZXRUb2tlbkNsaWVudENvZGUocmVmcmVzaFRva2VuOiBzdHJpbmcsIGNsaWVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnNvbGUubG9nKCdnZXROZXdUb2tlbicpO1xuICAgIGNvbnN0IGJvZHkgPSAnZ3JhbnRfdHlwZT1yZWZyZXNoX3Rva2VuJyArICcmcmVmcmVzaF90b2tlbj0nICsgcmVmcmVzaFRva2VuICsgJyZjbGllbnRfaWQ9JyArIGNsaWVudElkO1xuXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KGAke3RoaXMuZW52aXJvbm1lbnQuYXV0aEVuZFBvaW50fS9yZWFsbXMvJHt0aGlzLmVudmlyb25tZW50LmF1dGhSZWFsbX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdG9rZW5gLFxuICAgICAgYm9keSwge2hlYWRlcnN9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChyZXMgPT4gcmVzKSk7XG4gIH1cblxuXG4gIGdldExvZ2luVXJsKCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55Pih0aGlzLmVuZFBvaW50ICsgJy9hdXRoL2xvZ2luL3VybC8nK3RoaXMuZW52aXJvbm1lbnQuYXV0aENsaWVudClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcykpO1xuICB9XG5cbiAgZ2V0SG9tZVVybCgpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4odGhpcy5lbmRQb2ludCArICcvYXV0aC9ob21lL3VybC8nK3RoaXMuZW52aXJvbm1lbnQuYXV0aENsaWVudClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcykpO1xuICB9XG5cbiAgbG9nb3V0QXBpKCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgY29uc3QgYm9keSA9ICdyZWZyZXNoX3Rva2VuPScgKyB0aGlzLnJlZnJlc2hUb2tlbiArICcmY2xpZW50X2lkPScgKyB0aGlzLmVudmlyb25tZW50LmF1dGhDbGllbnQ7XG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KGAke3RoaXMuZW52aXJvbm1lbnQuYXV0aEVuZFBvaW50fS9yZWFsbXMvJHt0aGlzLmVudmlyb25tZW50LmF1dGhSZWFsbX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvbG9nb3V0YCxcbiAgICAgIGJvZHksIHtoZWFkZXJzfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcykpO1xuICB9XG5cbiAgbG9nb3V0QXBpQ2xpZW50KGNsaWVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnN0IGJvZHkgPSAncmVmcmVzaF90b2tlbj0nICsgdGhpcy5yZWZyZXNoVG9rZW4gKyAnJmNsaWVudF9pZD0nICsgY2xpZW50SWQ7XG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KGAke3RoaXMuZW52aXJvbm1lbnQuYXV0aEVuZFBvaW50fS9yZWFsbXMvJHt0aGlzLmVudmlyb25tZW50LmF1dGhSZWFsbX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvbG9nb3V0YCxcbiAgICAgIGJvZHksIHtoZWFkZXJzfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzID0+IHJlcykpO1xuICB9XG5cbiAgZ29Ub0xvZ2luKCk6IHZvaWQge1xuICAgIHRoaXMuZ2V0TG9naW5VcmwoKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKHJlcyk7XG4gICAgICBjb25zdCBsb2dpblVybCA9IHJlcy5kYXRhO1xuICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSBsb2dpblVybDtcbiAgICB9LCAoZXJyKSA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbG9hZFNlc3Npb25EYXRhKCk6IHZvaWQge1xuICAgIGxldCBkYXRhO1xuICAgIGxldCB0b2tlbjtcbiAgICBsZXQgcmVmcmVzaFRva2VuO1xuICAgIGlmICh0aGlzLmVudmlyb25tZW50LnByb2R1Y3Rpb24pIHtcbiAgICAgIGNvbnN0IHUgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdChVU0VSREFUQSk7XG4gICAgICBjb25zdCB0ID0gdGhpcy5jcnlwdG9TZXJ2aWNlLmVuY3J5cHQoVE9LRU4pO1xuICAgICAgY29uc3QgciA9IHRoaXMuY3J5cHRvU2VydmljZS5lbmNyeXB0KFJFRlJFU0hfVE9LRU4pO1xuICAgICAgZGF0YSA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSh1KTtcbiAgICAgIHRva2VuID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHQpO1xuICAgICAgcmVmcmVzaFRva2VuID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHIpO1xuICAgICAgaWYgKGRhdGEgJiYgdG9rZW4gJiYgcmVmcmVzaFRva2VuKSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZGVjcnlwdChkYXRhKTtcbiAgICAgICAgdG9rZW4gPSB0aGlzLmNyeXB0b1NlcnZpY2UuZGVjcnlwdCh0b2tlbik7XG4gICAgICAgIHJlZnJlc2hUb2tlbiA9IHRoaXMuY3J5cHRvU2VydmljZS5kZWNyeXB0KHJlZnJlc2hUb2tlbik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oVVNFUkRBVEEpO1xuICAgICAgdG9rZW4gPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oVE9LRU4pO1xuICAgICAgcmVmcmVzaFRva2VuID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKFJFRlJFU0hfVE9LRU4pO1xuICAgIH1cbiAgICBpZiAoZGF0YSAmJiB0b2tlbiAmJiByZWZyZXNoVG9rZW4pIHtcbiAgICAgIGNvbnN0IHVzZXIgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgdGhpcy5zZXRUb2tlbnModG9rZW4sIHJlZnJlc2hUb2tlbik7XG4gICAgICB0aGlzLnNldFVzZXJkYXRhKHVzZXIpO1xuICAgIH1cbiAgfVxuXG4gIHVzZXJIYXNPcHRpb25zSW5BcHAodXNlcklkOiBhbnksIGFwcGxpY2F0aW9uSWQ6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55Pih0aGlzLmVuZFBvaW50ICsgYC9zZWN1cml0eS9vcHRpb24vJHthcHBsaWNhdGlvbklkfS8ke3VzZXJJZH1gKVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChyZXMgPT4gcmVzKSk7XG4gIH1cblxuICBjaGVja0FwcFBlcm1pc3Npb25zKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKHRoaXMudXNlcmRhdGE/LnVzZXJJZCwgdGhpcy5hcHBsaWNhdGlvbklkKTtcbiAgICAgIGlmICh0aGlzLmFwcGxpY2F0aW9uSWQpIHtcbiAgICAgICAgdGhpcy51c2VySGFzT3B0aW9uc0luQXBwKHRoaXMudXNlcmRhdGE/LnVzZXJJZCwgdGhpcy5hcHBsaWNhdGlvbklkKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhyZXMpO1xuICAgICAgICAgIGlmIChyZXMuZGF0YSkge1xuICAgICAgICAgICAgcmVzb2x2ZSgnb2snKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRIb21lVXJsKCkuc3Vic2NyaWJlKHJlczEgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXMxKTtcbiAgICAgICAgICAgICAgY29uc3QgaG9tZVVybCA9IHJlczEuZGF0YTtcbiAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSBob21lVXJsO1xuICAgICAgICAgICAgICByZWplY3QoJ25vaycpO1xuICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgIHJlamVjdCgnbm9rJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgcmVqZWN0KCdub2snKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKCdvaycpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICBwdWJsaWMgZ2V0T3B0aW9uc1VzZXIoYXBwbGljYXRpb25JZDogbnVtYmVyIHwgbnVsbCwgdHlwZTogc3RyaW5nIHwgbnVsbCwgbGFuZ3VhZ2U6IHN0cmluZyB8IG51bGwsIGVudGl0eUNvZGU6IHN0cmluZyB8IG51bGwsIHBhcmVudE9wdGlvbklkOiBudW1iZXIgfCBudWxsLCBpbmNsdWRlRGF0YTogYm9vbGVhbiB8IG51bGwpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnN0IHBhcmFtID0ge1xuICAgICAgdXNlcklkOiB0aGlzLnVzZXJkYXRhPy51c2VySWQsXG4gICAgICBhcHBsaWNhdGlvbklkLFxuICAgICAgdHlwZSxcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgZW50aXR5Q29kZSxcbiAgICAgIHBhcmVudE9wdGlvbklkLFxuICAgICAgaW5jbHVkZURhdGFcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KHRoaXMuZW5kUG9pbnQgKyAnL3NlY3VyaXR5L29wdGlvbi91c2VyJywgcGFyYW0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKHJlcyA9PiByZXMpKTtcbiAgfVxuXG4gIHJlZ2lzdGVyRXhjZXB0aW9uKHBhcmFtOiBGcm9udEVuZEV4Y2VwdGlvbik6IE9ic2VydmFibGU8YW55PiB7XG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldCgnc2tpcEVycm9yJywgJ3RydWUnKTtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55Pih0aGlzLmVuZFBvaW50ICsgJy9hdXRoL2V4Y2VwdGlvbi9sb2cnLCBwYXJhbSwge2hlYWRlcnN9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChyZXMgPT4gcmVzKSk7XG4gIH1cblxuICBzYXZlU3RvcmFnZURhdGEoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbnZpcm9ubWVudC5wcm9kdWN0aW9uKSB7XG4gICAgICBjb25zdCBrID0gdGhpcy5jcnlwdG9TZXJ2aWNlLmVuY3J5cHQoa2V5KTtcbiAgICAgIGNvbnN0IHYgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdCh2YWx1ZSk7XG4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oaywgdik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBkZWxldGVTdG9yYWdlRGF0YShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVudmlyb25tZW50LnByb2R1Y3Rpb24pIHtcbiAgICAgIGNvbnN0IGsgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdChrZXkpO1xuICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGspO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KTtcbiAgICB9XG4gIH1cblxuICBnZXRTdG9yYWdlRGF0YShrZXk6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIGxldCByZXM6IHN0cmluZyB8IG51bGw7XG4gICAgaWYgKHRoaXMuZW52aXJvbm1lbnQucHJvZHVjdGlvbikge1xuICAgICAgY29uc3QgayA9IHRoaXMuY3J5cHRvU2VydmljZS5lbmNyeXB0KGtleSk7XG4gICAgICBjb25zdCB2ID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKGspO1xuICAgICAgaWYgKHYpIHtcbiAgICAgICAgcmVzID0gdGhpcy5jcnlwdG9TZXJ2aWNlLmRlY3J5cHQodik7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXMgPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG5cbiAgcHVibGljIHJlbW92ZVVybERhdGEoKTogdm9pZCB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTCh3aW5kb3cubG9jYXRpb24uaHJlZik7XG4gICAgY29uc3QgcXVlcnlQYXJhbXMgPSB1cmwuc2VhcmNoUGFyYW1zO1xuICAgIHF1ZXJ5UGFyYW1zLmRlbGV0ZSgnY29kZScpO1xuICAgIGNvbnN0IG5ld1VybCA9IHVybC5vcmlnaW4gKyB1cmwucGF0aG5hbWUgKyAnPycgKyBxdWVyeVBhcmFtcy50b1N0cmluZygpO1xuICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwgZG9jdW1lbnQudGl0bGUsIG5ld1VybCk7XG4gIH1cblxuICBwdWJsaWMgY2hlY2tTZXNzaW9uRGF0YSgpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgZGF0YTtcbiAgICAgIGxldCB0b2tlbjtcbiAgICAgIGxldCByZWZyZXNoVG9rZW47XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRVcmwgPSBuZXcgVVJMKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgIGNvbnN0IGNvZGUgPSBjdXJyZW50VXJsLnNlYXJjaFBhcmFtcy5nZXQoJ2NvZGUnKTtcbiAgICAgIGNvbnNvbGUubG9nKCdjb2RlJywgY29kZSk7XG4gICAgICBpZiAoY29kZSkge1xuICAgICAgICBjb25zdCBjb2RlRGVjb2RlZCA9IHRoaXMuZ2V0RGVjb2RlZEF1dGhDb2RlKGNvZGUpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZygnY29kZScsIGNvZGVEZWNvZGVkKTtcbiAgICAgICAgY29uc3QgZGVjb2RlZCA9IHRoaXMuand0U2VydmljZS5kZWNvZGVUb2tlbihjb2RlRGVjb2RlZCk7XG4gICAgICAgIHRoaXMuZ2V0VG9rZW5DbGllbnRDb2RlKGNvZGVEZWNvZGVkLCBkZWNvZGVkLmF6cCkuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAocmVzKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhyZXMpO1xuICAgICAgICAgICAgdG9rZW4gPSByZXMuYWNjZXNzX3Rva2VuO1xuICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gcmVzLnJlZnJlc2hfdG9rZW47XG4gICAgICAgICAgICB0aGlzLnNhdmVDcmVkZW50aWFscyh0b2tlbiwgcmVmcmVzaFRva2VuKTtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tBcHBQZXJtaXNzaW9ucygpLnRoZW4oKHJlczEpID0+IHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2cocmVzMSk7XG4gICAgICAgICAgICAgIHRoaXMucmVtb3ZlVXJsRGF0YSgpO1xuICAgICAgICAgICAgICByZXNvbHZlKCdPSycpO1xuICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLmdldFN0b3JhZ2VEYXRhKFVTRVJEQVRBKTtcbiAgICAgICAgdG9rZW4gPSB0aGlzLmdldFN0b3JhZ2VEYXRhKFRPS0VOKTtcbiAgICAgICAgcmVmcmVzaFRva2VuID0gdGhpcy5nZXRTdG9yYWdlRGF0YShSRUZSRVNIX1RPS0VOKTtcbiAgICAgICAgaWYgKGRhdGEgJiYgdG9rZW4gJiYgcmVmcmVzaFRva2VuKSB7XG4gICAgICAgICAgdGhpcy5zYXZlQ3JlZGVudGlhbHModG9rZW4sIHJlZnJlc2hUb2tlbik7XG4gICAgICAgICAgdGhpcy5jaGVja0FwcFBlcm1pc3Npb25zKCkudGhlbigocmVzMSkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2cocmVzMSk7XG4gICAgICAgICAgICByZXNvbHZlKCdPSycpO1xuICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICAgIGlmICh1cmwuaW5kZXhPZignL3JlZGlyZWN0Jyk+LTEpIHtcbiAgICAgICAgICAgIHJlc29sdmUoJ09LJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveUNyZWRlbnRpYWxzKCk7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lVc2VyRGF0YSgpO1xuICAgICAgICAgICAgdGhpcy5nZXRMb2dpblVybCgpLnN1YnNjcmliZShyZXMxID0+IHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2cocmVzMSk7XG4gICAgICAgICAgICAgIHRoaXMubG9naW5VcmwgPSByZXMxLmRhdGE7XG4gICAgICAgICAgICAgIGlmICh1cmwuaW5kZXhPZignL2xvZ2luJyk8MCAmJiB1cmwuaW5kZXhPZignL2ZvcmdvdCcpPDAgJiZcbiAgICAgICAgICAgICAgICAgIHVybC5pbmRleE9mKCcvcmVzZXQnKTwwICYmIHVybC5pbmRleE9mKCcvdmVyaWZ5Jyk8MCAmJlxuICAgICAgICAgICAgICAgICAgdXJsLmluZGV4T2YoJy9zaWduX3VwJyk8MCkge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdGhpcy5sb2dpblVybCArICc/Y29udGludWU9JytlbmNvZGVVUklDb21wb25lbnQodXJsKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXNvbHZlKCdOT0snKTtcbiAgICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cblxuXG4gIHB1YmxpYyBjaGVja1Nlc3Npb25EYXRhTWljcm9mcm9udCgpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgZGF0YTtcbiAgICAgIGxldCB0b2tlbjtcbiAgICAgIGxldCByZWZyZXNoVG9rZW47XG4gICAgICBpZiAodGhpcy5lbnZpcm9ubWVudC5wcm9kdWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IHUgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdChVU0VSREFUQSk7XG4gICAgICAgIGNvbnN0IHQgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdChUT0tFTik7XG4gICAgICAgIGNvbnN0IHIgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdChSRUZSRVNIX1RPS0VOKTtcbiAgICAgICAgY29uc3QgZDEgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0odSk7XG4gICAgICAgIGNvbnN0IGQyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHQpO1xuICAgICAgICBjb25zdCBkMyA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShyKTtcbiAgICAgICAgaWYgKGQxICYmIGQyICYmIGQzKSB7XG4gICAgICAgICAgZGF0YSA9IHRoaXMuY3J5cHRvU2VydmljZS5kZWNyeXB0KGQxKTtcbiAgICAgICAgICB0b2tlbiA9IHRoaXMuY3J5cHRvU2VydmljZS5kZWNyeXB0KGQyKTtcbiAgICAgICAgICByZWZyZXNoVG9rZW4gPSB0aGlzLmNyeXB0b1NlcnZpY2UuZGVjcnlwdChkMyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGEgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oVVNFUkRBVEEpO1xuICAgICAgICB0b2tlbiA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShUT0tFTik7XG4gICAgICAgIHJlZnJlc2hUb2tlbiA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShSRUZSRVNIX1RPS0VOKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhICYmIHRva2VuICYmIHJlZnJlc2hUb2tlbikge1xuICAgICAgICBjb25zb2xlLmxvZygnbG9jYWwgc2Vzc2lvbiBvaycpO1xuICAgICAgICB0aGlzLnNhdmVDcmVkZW50aWFscyh0b2tlbiwgcmVmcmVzaFRva2VuKTtcbiAgICAgICAgcmVzb2x2ZSgnT0snKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2xvY2FsIHNlc3Npb24gbm9rJyk7XG4gICAgICAgIHJlamVjdCgnTk9LJyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBwdWJsaWMgZ2V0QXV0aENvZGUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBlbmMgPSB0aGlzLmNyeXB0b1NlcnZpY2UuZW5jcnlwdCh0aGlzLnJlZnJlc2hUb2tlbj90aGlzLnJlZnJlc2hUb2tlbjonJyk7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChlbmMpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWNvZGVkQXV0aENvZGUoY29kZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkZWMgPSBkZWNvZGVVUklDb21wb25lbnQoY29kZSk7XG4gICAgcmV0dXJuIHRoaXMuY3J5cHRvU2VydmljZS5kZWNyeXB0KGRlYyk7XG4gIH1cblxufVxuXG4iXX0=
|