@atlasauth/angular 0.7.0 → 0.9.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/CHANGELOG.md +29 -0
- package/dist/esm2022/lib/appearance.mjs +1 -1
- package/dist/esm2022/lib/atlas.service.mjs +45 -4
- package/dist/esm2022/lib/atlas.ui.mjs +3 -1
- package/dist/esm2022/lib/components/attempt-flow.component.mjs +398 -8
- package/dist/esm2022/lib/components/flow-controller.mjs +127 -7
- package/dist/esm2022/lib/components/impersonation-banner.component.mjs +75 -0
- package/dist/esm2022/lib/components/organization-audit-log.component.mjs +115 -0
- package/dist/esm2022/lib/components/organization-audit-log.mjs +40 -0
- package/dist/esm2022/lib/components/organization-profile.component.mjs +602 -27
- package/dist/esm2022/lib/components/recovery-codes.component.mjs +122 -0
- package/dist/esm2022/lib/components/sign-in.component.mjs +85 -4
- package/dist/esm2022/lib/components/sign-up-form.component.mjs +69 -6
- package/dist/esm2022/lib/components/sign-up.component.mjs +83 -7
- package/dist/esm2022/lib/i18n.mjs +60 -1
- package/dist/esm2022/lib/provide-atlas.mjs +3 -2
- package/dist/esm2022/lib/types.mjs +1 -1
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/esm2022/public-api.mjs +4 -1
- package/dist/fesm2022/atlasauth-angular.mjs +1798 -65
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/appearance.d.ts +1 -1
- package/dist/lib/atlas.service.d.ts +24 -2
- package/dist/lib/atlas.ui.d.ts +2 -1
- package/dist/lib/components/attempt-flow.component.d.ts +60 -3
- package/dist/lib/components/flow-controller.d.ts +65 -2
- package/dist/lib/components/impersonation-banner.component.d.ts +27 -0
- package/dist/lib/components/organization-audit-log.component.d.ts +34 -0
- package/dist/lib/components/organization-audit-log.d.ts +25 -0
- package/dist/lib/components/organization-profile.component.d.ts +55 -6
- package/dist/lib/components/recovery-codes.component.d.ts +26 -0
- package/dist/lib/components/sign-in.component.d.ts +11 -1
- package/dist/lib/components/sign-up-form.component.d.ts +11 -1
- package/dist/lib/components/sign-up.component.d.ts +13 -0
- package/dist/lib/provide-atlas.d.ts +2 -1
- package/dist/lib/types.d.ts +6 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/public-api.d.ts +4 -0
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, inject, } from '@angular/core';
|
|
2
|
-
import { localizedErrorMessage, nextStep, } from '@atlasauth/js';
|
|
2
|
+
import { awaitingSignUpLink, enrollmentSubmitKey, groupSetupKey, localizedErrorMessage, nextStep, } from '@atlasauth/js';
|
|
3
3
|
import { AtlasService } from '../atlas.service';
|
|
4
4
|
import { AtlasCaptchaSlotDirective } from '../directives/captcha-slot.directive';
|
|
5
5
|
import { classFor } from '../appearance';
|
|
@@ -20,6 +20,8 @@ export class AttemptFlowComponent {
|
|
|
20
20
|
attempt = null;
|
|
21
21
|
busy = false;
|
|
22
22
|
errors = [];
|
|
23
|
+
/** `FlowState.sessionKept`: whether this browser kept the session the sign-in created. */
|
|
24
|
+
sessionKept = undefined;
|
|
23
25
|
titleKey = 'signIn.title';
|
|
24
26
|
/**
|
|
25
27
|
* The sign-in captcha, drawn above the submit button on the identifier step
|
|
@@ -39,6 +41,38 @@ export class AttemptFlowComponent {
|
|
|
39
41
|
submitFlow = new EventEmitter();
|
|
40
42
|
/** Emits when the user picks a first factor the server must send first (an emailed code). */
|
|
41
43
|
chooseFactor = new EventEmitter();
|
|
44
|
+
/**
|
|
45
|
+
* Offer "Email me a code instead" at the second factor (the instance's
|
|
46
|
+
* `account.emailSecondFactor`); `emailSecondFactor` asks for it and
|
|
47
|
+
* `emailedSecondFactor` reports how it went.
|
|
48
|
+
*/
|
|
49
|
+
offerEmailSecondFactor = false;
|
|
50
|
+
/** `AtlasFlowController.emailSecondFactor()`: in flight, where it went, or why not. */
|
|
51
|
+
emailedSecondFactor = null;
|
|
52
|
+
emailSecondFactor = new EventEmitter();
|
|
53
|
+
/**
|
|
54
|
+
* Offer "Text me a code instead" at the second factor (where the app offers
|
|
55
|
+
* texted codes, `AtlasFlowController.mfaChoices().sms`); `smsSecondFactor`
|
|
56
|
+
* asks for it and `textedSecondFactor` reports how it went.
|
|
57
|
+
*/
|
|
58
|
+
offerSmsSecondFactor = false;
|
|
59
|
+
/** `AtlasFlowController.smsSecondFactor()`: in flight, where it went, or why not. */
|
|
60
|
+
textedSecondFactor = null;
|
|
61
|
+
smsSecondFactor = new EventEmitter();
|
|
62
|
+
/**
|
|
63
|
+
* The MFA enrolment step (`AtlasFlowController.enrollment` and
|
|
64
|
+
* `enrollmentState()`): the authenticator app's QR code and setup key, or a
|
|
65
|
+
* texted code. Null: the step asks for two authenticator codes only.
|
|
66
|
+
*/
|
|
67
|
+
enrollment = null;
|
|
68
|
+
enrollmentState = null;
|
|
69
|
+
/**
|
|
70
|
+
* The instance's `account.emailVerification`. On `link` a sign-up's
|
|
71
|
+
* verification step has nothing to type: it says to open the emailed link
|
|
72
|
+
* while the flow polls, and offers a resend (`resend`).
|
|
73
|
+
*/
|
|
74
|
+
emailVerification = 'code';
|
|
75
|
+
resend = new EventEmitter();
|
|
42
76
|
values = {};
|
|
43
77
|
t(key, vars) {
|
|
44
78
|
return translate(this.atlas.localization, key, vars);
|
|
@@ -57,8 +91,45 @@ export class AttemptFlowComponent {
|
|
|
57
91
|
}
|
|
58
92
|
onSubmit(event) {
|
|
59
93
|
event.preventDefault();
|
|
94
|
+
// Enrolment: text the code to the typed number, or confirm the factor.
|
|
95
|
+
if (this.enrolling() && this.enrollment) {
|
|
96
|
+
void this.enrollment.submit(this.values).then((next) => {
|
|
97
|
+
if (next)
|
|
98
|
+
this.submitFlow.emit(next);
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
60
102
|
this.submitFlow.emit(this.values);
|
|
61
103
|
}
|
|
104
|
+
/** The shared enrolment step is drawn (a controller was passed and the flow is enrolling). */
|
|
105
|
+
enrolling() {
|
|
106
|
+
return this.step().kind === 'enroll_second_factor' && !!this.enrollment && !!this.enrollmentState;
|
|
107
|
+
}
|
|
108
|
+
chooseMethod(method) {
|
|
109
|
+
this.values = {};
|
|
110
|
+
void this.enrollment?.choose(method);
|
|
111
|
+
}
|
|
112
|
+
resendEnrollment() {
|
|
113
|
+
void this.enrollment?.resend();
|
|
114
|
+
}
|
|
115
|
+
otherMethods(state) {
|
|
116
|
+
return state.options.filter((m) => m !== state.method);
|
|
117
|
+
}
|
|
118
|
+
setupKey(secret) {
|
|
119
|
+
return groupSetupKey(secret);
|
|
120
|
+
}
|
|
121
|
+
/** The submit button's label key (enrolment: "Text me a code" before the number is sent). */
|
|
122
|
+
submitKey() {
|
|
123
|
+
return (this.enrolling() && this.enrollmentState && enrollmentSubmitKey(this.enrollmentState)) || 'signIn.submit';
|
|
124
|
+
}
|
|
125
|
+
showSmsSecondFactor() {
|
|
126
|
+
return this.offerSmsSecondFactor && this.step().kind === 'collect_second_factor';
|
|
127
|
+
}
|
|
128
|
+
/** Where the texted second-factor code went (masked), once it was sent. */
|
|
129
|
+
smsSecondFactorSentTo() {
|
|
130
|
+
const sent = this.textedSecondFactor?.sentTo;
|
|
131
|
+
return typeof sent === 'string' ? sent || ' ' : null;
|
|
132
|
+
}
|
|
62
133
|
formErrors() {
|
|
63
134
|
return this.errors.filter((error) => !error.param);
|
|
64
135
|
}
|
|
@@ -79,6 +150,17 @@ export class AttemptFlowComponent {
|
|
|
79
150
|
return [];
|
|
80
151
|
return this.firstFactors ?? step.strategies;
|
|
81
152
|
}
|
|
153
|
+
linkOnly() {
|
|
154
|
+
return awaitingSignUpLink(this.attempt, this.emailVerification);
|
|
155
|
+
}
|
|
156
|
+
showEmailSecondFactor() {
|
|
157
|
+
return this.offerEmailSecondFactor && this.step().kind === 'collect_second_factor';
|
|
158
|
+
}
|
|
159
|
+
/** Where the emailed second-factor code went (masked), once it was sent. */
|
|
160
|
+
emailSecondFactorSentTo() {
|
|
161
|
+
const sent = this.emailedSecondFactor?.sentTo;
|
|
162
|
+
return typeof sent === 'string' ? sent || ' ' : null;
|
|
163
|
+
}
|
|
82
164
|
showEmailCodeOption() {
|
|
83
165
|
// Before the code is sent: the choice (or the retry of a failed automatic
|
|
84
166
|
// send). After: "Resend code".
|
|
@@ -96,6 +178,11 @@ export class AttemptFlowComponent {
|
|
|
96
178
|
// until that code is sent.
|
|
97
179
|
if (kind === 'collect_first_factor')
|
|
98
180
|
return this.fields().length > 0;
|
|
181
|
+
if (this.linkOnly())
|
|
182
|
+
return false;
|
|
183
|
+
// Enrolment: nothing to submit while choosing a method or fetching the setup.
|
|
184
|
+
if (this.enrolling() && this.enrollmentState && !enrollmentSubmitKey(this.enrollmentState))
|
|
185
|
+
return false;
|
|
99
186
|
return kind !== 'done' && kind !== 'await_oauth';
|
|
100
187
|
}
|
|
101
188
|
fields() {
|
|
@@ -117,6 +204,9 @@ export class AttemptFlowComponent {
|
|
|
117
204
|
case 'collect_second_factor':
|
|
118
205
|
return [{ kind: 'input', name: 'code', labelKey: 'mfa.codeLabel', type: 'text' }];
|
|
119
206
|
case 'enroll_second_factor':
|
|
207
|
+
// The shared enrolment step draws its own fields (above).
|
|
208
|
+
if (this.enrolling())
|
|
209
|
+
return [];
|
|
120
210
|
// Two consecutive codes (§5.6): a phone with a fast clock fails here
|
|
121
211
|
// rather than on every sign-in afterwards.
|
|
122
212
|
return [
|
|
@@ -124,7 +214,7 @@ export class AttemptFlowComponent {
|
|
|
124
214
|
{ kind: 'input', name: 'secondCode', labelKey: 'mfa.enrollSecondCodeLabel', type: 'text' },
|
|
125
215
|
];
|
|
126
216
|
case 'collect_email_code':
|
|
127
|
-
return [{ kind: 'input', name: 'code', labelKey: 'signIn.emailCodeLabel', type: 'text' }];
|
|
217
|
+
return this.linkOnly() ? [] : [{ kind: 'input', name: 'code', labelKey: 'signIn.emailCodeLabel', type: 'text' }];
|
|
128
218
|
case 'collect_new_password':
|
|
129
219
|
return [{ kind: 'input', name: 'password', labelKey: 'reset.newPasswordLabel', type: 'password' }];
|
|
130
220
|
case 'collect_captcha':
|
|
@@ -134,6 +224,12 @@ export class AttemptFlowComponent {
|
|
|
134
224
|
case 'await_oauth':
|
|
135
225
|
return [msg('signIn.magicLinkSent')];
|
|
136
226
|
case 'done':
|
|
227
|
+
// Signed in only when this browser holds the session; a blocked cookie is said
|
|
228
|
+
// plainly. "Check the other tab" is for a sign-in completed on another device.
|
|
229
|
+
if (this.sessionKept === true)
|
|
230
|
+
return [msg('signIn.signedIn')];
|
|
231
|
+
if (this.sessionKept === false)
|
|
232
|
+
return [{ kind: 'alert', name: '', labelKey: 'signIn.sessionNotKept', type: 'text' }];
|
|
137
233
|
return [msg('signIn.checkOtherTab')];
|
|
138
234
|
case 'restart':
|
|
139
235
|
return [msg('error.generic')];
|
|
@@ -144,7 +240,7 @@ export class AttemptFlowComponent {
|
|
|
144
240
|
}
|
|
145
241
|
}
|
|
146
242
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
147
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AttemptFlowComponent, isStandalone: true, selector: "atlas-attempt-flow", inputs: { attempt: "attempt", busy: "busy", errors: "errors", titleKey: "titleKey", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor" }, ngImport: i0, template: `
|
|
243
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AttemptFlowComponent, isStandalone: true, selector: "atlas-attempt-flow", inputs: { attempt: "attempt", busy: "busy", errors: "errors", sessionKept: "sessionKept", titleKey: "titleKey", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor", offerEmailSecondFactor: "offerEmailSecondFactor", emailedSecondFactor: "emailedSecondFactor", offerSmsSecondFactor: "offerSmsSecondFactor", textedSecondFactor: "textedSecondFactor", enrollment: "enrollment", enrollmentState: "enrollmentState", emailVerification: "emailVerification" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor", emailSecondFactor: "emailSecondFactor", smsSecondFactor: "smsSecondFactor", resend: "resend" }, ngImport: i0, template: `
|
|
148
244
|
<div [class]="cls('card', 'atlas-card')">
|
|
149
245
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
150
246
|
|
|
@@ -156,6 +252,98 @@ export class AttemptFlowComponent {
|
|
|
156
252
|
@if (codeSentText(); as sentText) {
|
|
157
253
|
<p class="atlas-text" data-atlas-code-sent="">{{ sentText }}</p>
|
|
158
254
|
}
|
|
255
|
+
@if (linkOnly()) {
|
|
256
|
+
<!-- Nothing to type: the flow polls until the emailed link is opened (anywhere). -->
|
|
257
|
+
<p class="atlas-text" data-atlas-link-sent="" aria-live="polite">
|
|
258
|
+
{{ t('signUp.linkSentTo', { email: attempt?.identifier ?? '' }) }}
|
|
259
|
+
</p>
|
|
260
|
+
<button
|
|
261
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
262
|
+
type="button"
|
|
263
|
+
data-atlas-resend=""
|
|
264
|
+
[disabled]="busy"
|
|
265
|
+
(click)="resend.emit()"
|
|
266
|
+
>
|
|
267
|
+
{{ t('signIn.resendLink') }}
|
|
268
|
+
</button>
|
|
269
|
+
}
|
|
270
|
+
@if (enrolling() && enrollmentState; as enrol) {
|
|
271
|
+
@if (enrol.method === null) {
|
|
272
|
+
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
273
|
+
@for (m of enrol.options; track m) {
|
|
274
|
+
<button
|
|
275
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
276
|
+
type="button"
|
|
277
|
+
[attr.data-atlas-mfa-method]="m"
|
|
278
|
+
[disabled]="busy || enrol.busy"
|
|
279
|
+
(click)="chooseMethod(m)"
|
|
280
|
+
>
|
|
281
|
+
{{ t(m === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
282
|
+
</button>
|
|
283
|
+
}
|
|
284
|
+
} @else if (enrol.method === 'totp') {
|
|
285
|
+
@if (enrol.enrollment; as setup) {
|
|
286
|
+
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
287
|
+
@if (setup.qrCode) {
|
|
288
|
+
<img class="atlas-mfa-qr" data-atlas="mfa-qr" [src]="setup.qrCode" [alt]="t('mfa.enrollQrAlt')" width="180" height="180" />
|
|
289
|
+
}
|
|
290
|
+
@if (setup.secret) {
|
|
291
|
+
<p class="atlas-text" data-atlas="mfa-setup-key">{{ t('mfa.enrollSetupKey') }}: <code>{{ setupKey(setup.secret) }}</code></p>
|
|
292
|
+
}
|
|
293
|
+
<label class="atlas-field">
|
|
294
|
+
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
295
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
296
|
+
</label>
|
|
297
|
+
@if (enrol.totpCodes >= 2) {
|
|
298
|
+
<label class="atlas-field">
|
|
299
|
+
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
300
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="secondCode" autocomplete="one-time-code" inputmode="numeric" [value]="values['secondCode'] ?? ''" (input)="setValue('secondCode', $any($event.target).value)" />
|
|
301
|
+
</label>
|
|
302
|
+
}
|
|
303
|
+
} @else {
|
|
304
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
305
|
+
}
|
|
306
|
+
} @else {
|
|
307
|
+
@if (enrol.enrollment; as texted) {
|
|
308
|
+
<p class="atlas-text" data-atlas="mfa-code-texted" aria-live="polite">{{ t('mfa.codeTextedTo', { phone: texted.phone ?? '' }) }}</p>
|
|
309
|
+
<label class="atlas-field">
|
|
310
|
+
<span>{{ t('mfa.codeLabel') }}</span>
|
|
311
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
312
|
+
</label>
|
|
313
|
+
<button
|
|
314
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
315
|
+
type="button"
|
|
316
|
+
data-atlas-resend=""
|
|
317
|
+
[disabled]="busy || enrol.busy"
|
|
318
|
+
(click)="resendEnrollment()"
|
|
319
|
+
>
|
|
320
|
+
{{ t('signIn.resendCode') }}
|
|
321
|
+
</button>
|
|
322
|
+
} @else {
|
|
323
|
+
<label class="atlas-field">
|
|
324
|
+
<span>{{ t('mfa.phoneLabel') }}</span>
|
|
325
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="tel" name="phone" autocomplete="tel" [value]="values['phone'] ?? ''" (input)="setValue('phone', $any($event.target).value)" />
|
|
326
|
+
</label>
|
|
327
|
+
<p class="atlas-text">{{ t('mfa.phoneHint') }}</p>
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
@for (error of enrol.errors; track $index) {
|
|
331
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ error.message }}</p>
|
|
332
|
+
}
|
|
333
|
+
@if (enrol.method !== null && enrol.options.length > 1) {
|
|
334
|
+
@for (other of otherMethods(enrol); track other) {
|
|
335
|
+
<button
|
|
336
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
337
|
+
type="button"
|
|
338
|
+
[attr.data-atlas-mfa-method]="other"
|
|
339
|
+
[disabled]="busy || enrol.busy"
|
|
340
|
+
(click)="chooseMethod(other)"
|
|
341
|
+
>
|
|
342
|
+
{{ t(other === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
343
|
+
</button>
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
159
347
|
@for (f of fields(); track $index) {
|
|
160
348
|
@if (f.kind === 'input') {
|
|
161
349
|
<label class="atlas-field">
|
|
@@ -171,6 +359,8 @@ export class AttemptFlowComponent {
|
|
|
171
359
|
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
172
360
|
}
|
|
173
361
|
</label>
|
|
362
|
+
} @else if (f.kind === 'alert') {
|
|
363
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ t(f.labelKey) }}</p>
|
|
174
364
|
} @else {
|
|
175
365
|
<p>{{ t(f.labelKey) }}</p>
|
|
176
366
|
}
|
|
@@ -181,11 +371,53 @@ export class AttemptFlowComponent {
|
|
|
181
371
|
}
|
|
182
372
|
|
|
183
373
|
@if (showSubmit()) {
|
|
184
|
-
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy" type="submit">
|
|
185
|
-
{{ t(
|
|
374
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy || (enrolling() && !!enrollmentState?.busy)" type="submit">
|
|
375
|
+
{{ t(submitKey()) }}
|
|
186
376
|
</button>
|
|
187
377
|
}
|
|
188
378
|
|
|
379
|
+
@if (showSmsSecondFactor()) {
|
|
380
|
+
@if (smsSecondFactorSentTo(); as sentTo) {
|
|
381
|
+
<p class="atlas-text" data-atlas="sms-second-factor-sent" aria-live="polite">
|
|
382
|
+
{{ t('mfa.codeTextedTo', { phone: sentTo }) }}
|
|
383
|
+
</p>
|
|
384
|
+
} @else {
|
|
385
|
+
<button
|
|
386
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
387
|
+
type="button"
|
|
388
|
+
data-atlas="sms-second-factor"
|
|
389
|
+
[disabled]="busy || !!textedSecondFactor?.busy"
|
|
390
|
+
(click)="smsSecondFactor.emit()"
|
|
391
|
+
>
|
|
392
|
+
{{ textedSecondFactor?.busy ? t('signIn.sending') : t('mfa.smsCodeOption') }}
|
|
393
|
+
</button>
|
|
394
|
+
@if (textedSecondFactor?.error; as message) {
|
|
395
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
@if (showEmailSecondFactor()) {
|
|
401
|
+
@if (emailSecondFactorSentTo(); as sentTo) {
|
|
402
|
+
<p class="atlas-text" data-atlas="email-second-factor-sent" aria-live="polite">
|
|
403
|
+
{{ t('signIn.codeSentTo', { email: sentTo }) }}
|
|
404
|
+
</p>
|
|
405
|
+
} @else {
|
|
406
|
+
<button
|
|
407
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
408
|
+
type="button"
|
|
409
|
+
data-atlas="email-second-factor"
|
|
410
|
+
[disabled]="busy || !!emailedSecondFactor?.busy"
|
|
411
|
+
(click)="emailSecondFactor.emit()"
|
|
412
|
+
>
|
|
413
|
+
{{ emailedSecondFactor?.busy ? t('signIn.sending') : t('signIn.emailCodeOption') }}
|
|
414
|
+
</button>
|
|
415
|
+
@if (emailedSecondFactor?.error; as message) {
|
|
416
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
189
421
|
@if (showEmailCodeOption()) {
|
|
190
422
|
<button
|
|
191
423
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -221,6 +453,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
221
453
|
@if (codeSentText(); as sentText) {
|
|
222
454
|
<p class="atlas-text" data-atlas-code-sent="">{{ sentText }}</p>
|
|
223
455
|
}
|
|
456
|
+
@if (linkOnly()) {
|
|
457
|
+
<!-- Nothing to type: the flow polls until the emailed link is opened (anywhere). -->
|
|
458
|
+
<p class="atlas-text" data-atlas-link-sent="" aria-live="polite">
|
|
459
|
+
{{ t('signUp.linkSentTo', { email: attempt?.identifier ?? '' }) }}
|
|
460
|
+
</p>
|
|
461
|
+
<button
|
|
462
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
463
|
+
type="button"
|
|
464
|
+
data-atlas-resend=""
|
|
465
|
+
[disabled]="busy"
|
|
466
|
+
(click)="resend.emit()"
|
|
467
|
+
>
|
|
468
|
+
{{ t('signIn.resendLink') }}
|
|
469
|
+
</button>
|
|
470
|
+
}
|
|
471
|
+
@if (enrolling() && enrollmentState; as enrol) {
|
|
472
|
+
@if (enrol.method === null) {
|
|
473
|
+
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
474
|
+
@for (m of enrol.options; track m) {
|
|
475
|
+
<button
|
|
476
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
477
|
+
type="button"
|
|
478
|
+
[attr.data-atlas-mfa-method]="m"
|
|
479
|
+
[disabled]="busy || enrol.busy"
|
|
480
|
+
(click)="chooseMethod(m)"
|
|
481
|
+
>
|
|
482
|
+
{{ t(m === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
483
|
+
</button>
|
|
484
|
+
}
|
|
485
|
+
} @else if (enrol.method === 'totp') {
|
|
486
|
+
@if (enrol.enrollment; as setup) {
|
|
487
|
+
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
488
|
+
@if (setup.qrCode) {
|
|
489
|
+
<img class="atlas-mfa-qr" data-atlas="mfa-qr" [src]="setup.qrCode" [alt]="t('mfa.enrollQrAlt')" width="180" height="180" />
|
|
490
|
+
}
|
|
491
|
+
@if (setup.secret) {
|
|
492
|
+
<p class="atlas-text" data-atlas="mfa-setup-key">{{ t('mfa.enrollSetupKey') }}: <code>{{ setupKey(setup.secret) }}</code></p>
|
|
493
|
+
}
|
|
494
|
+
<label class="atlas-field">
|
|
495
|
+
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
496
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
497
|
+
</label>
|
|
498
|
+
@if (enrol.totpCodes >= 2) {
|
|
499
|
+
<label class="atlas-field">
|
|
500
|
+
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
501
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="secondCode" autocomplete="one-time-code" inputmode="numeric" [value]="values['secondCode'] ?? ''" (input)="setValue('secondCode', $any($event.target).value)" />
|
|
502
|
+
</label>
|
|
503
|
+
}
|
|
504
|
+
} @else {
|
|
505
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
506
|
+
}
|
|
507
|
+
} @else {
|
|
508
|
+
@if (enrol.enrollment; as texted) {
|
|
509
|
+
<p class="atlas-text" data-atlas="mfa-code-texted" aria-live="polite">{{ t('mfa.codeTextedTo', { phone: texted.phone ?? '' }) }}</p>
|
|
510
|
+
<label class="atlas-field">
|
|
511
|
+
<span>{{ t('mfa.codeLabel') }}</span>
|
|
512
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
513
|
+
</label>
|
|
514
|
+
<button
|
|
515
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
516
|
+
type="button"
|
|
517
|
+
data-atlas-resend=""
|
|
518
|
+
[disabled]="busy || enrol.busy"
|
|
519
|
+
(click)="resendEnrollment()"
|
|
520
|
+
>
|
|
521
|
+
{{ t('signIn.resendCode') }}
|
|
522
|
+
</button>
|
|
523
|
+
} @else {
|
|
524
|
+
<label class="atlas-field">
|
|
525
|
+
<span>{{ t('mfa.phoneLabel') }}</span>
|
|
526
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="tel" name="phone" autocomplete="tel" [value]="values['phone'] ?? ''" (input)="setValue('phone', $any($event.target).value)" />
|
|
527
|
+
</label>
|
|
528
|
+
<p class="atlas-text">{{ t('mfa.phoneHint') }}</p>
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
@for (error of enrol.errors; track $index) {
|
|
532
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ error.message }}</p>
|
|
533
|
+
}
|
|
534
|
+
@if (enrol.method !== null && enrol.options.length > 1) {
|
|
535
|
+
@for (other of otherMethods(enrol); track other) {
|
|
536
|
+
<button
|
|
537
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
538
|
+
type="button"
|
|
539
|
+
[attr.data-atlas-mfa-method]="other"
|
|
540
|
+
[disabled]="busy || enrol.busy"
|
|
541
|
+
(click)="chooseMethod(other)"
|
|
542
|
+
>
|
|
543
|
+
{{ t(other === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
544
|
+
</button>
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
224
548
|
@for (f of fields(); track $index) {
|
|
225
549
|
@if (f.kind === 'input') {
|
|
226
550
|
<label class="atlas-field">
|
|
@@ -236,6 +560,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
236
560
|
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
237
561
|
}
|
|
238
562
|
</label>
|
|
563
|
+
} @else if (f.kind === 'alert') {
|
|
564
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ t(f.labelKey) }}</p>
|
|
239
565
|
} @else {
|
|
240
566
|
<p>{{ t(f.labelKey) }}</p>
|
|
241
567
|
}
|
|
@@ -246,11 +572,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
246
572
|
}
|
|
247
573
|
|
|
248
574
|
@if (showSubmit()) {
|
|
249
|
-
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy" type="submit">
|
|
250
|
-
{{ t(
|
|
575
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy || (enrolling() && !!enrollmentState?.busy)" type="submit">
|
|
576
|
+
{{ t(submitKey()) }}
|
|
251
577
|
</button>
|
|
252
578
|
}
|
|
253
579
|
|
|
580
|
+
@if (showSmsSecondFactor()) {
|
|
581
|
+
@if (smsSecondFactorSentTo(); as sentTo) {
|
|
582
|
+
<p class="atlas-text" data-atlas="sms-second-factor-sent" aria-live="polite">
|
|
583
|
+
{{ t('mfa.codeTextedTo', { phone: sentTo }) }}
|
|
584
|
+
</p>
|
|
585
|
+
} @else {
|
|
586
|
+
<button
|
|
587
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
588
|
+
type="button"
|
|
589
|
+
data-atlas="sms-second-factor"
|
|
590
|
+
[disabled]="busy || !!textedSecondFactor?.busy"
|
|
591
|
+
(click)="smsSecondFactor.emit()"
|
|
592
|
+
>
|
|
593
|
+
{{ textedSecondFactor?.busy ? t('signIn.sending') : t('mfa.smsCodeOption') }}
|
|
594
|
+
</button>
|
|
595
|
+
@if (textedSecondFactor?.error; as message) {
|
|
596
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
@if (showEmailSecondFactor()) {
|
|
602
|
+
@if (emailSecondFactorSentTo(); as sentTo) {
|
|
603
|
+
<p class="atlas-text" data-atlas="email-second-factor-sent" aria-live="polite">
|
|
604
|
+
{{ t('signIn.codeSentTo', { email: sentTo }) }}
|
|
605
|
+
</p>
|
|
606
|
+
} @else {
|
|
607
|
+
<button
|
|
608
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
609
|
+
type="button"
|
|
610
|
+
data-atlas="email-second-factor"
|
|
611
|
+
[disabled]="busy || !!emailedSecondFactor?.busy"
|
|
612
|
+
(click)="emailSecondFactor.emit()"
|
|
613
|
+
>
|
|
614
|
+
{{ emailedSecondFactor?.busy ? t('signIn.sending') : t('signIn.emailCodeOption') }}
|
|
615
|
+
</button>
|
|
616
|
+
@if (emailedSecondFactor?.error; as message) {
|
|
617
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
254
622
|
@if (showEmailCodeOption()) {
|
|
255
623
|
<button
|
|
256
624
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -273,6 +641,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
273
641
|
type: Input
|
|
274
642
|
}], errors: [{
|
|
275
643
|
type: Input
|
|
644
|
+
}], sessionKept: [{
|
|
645
|
+
type: Input
|
|
276
646
|
}], titleKey: [{
|
|
277
647
|
type: Input
|
|
278
648
|
}], captcha: [{
|
|
@@ -285,9 +655,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
285
655
|
type: Output
|
|
286
656
|
}], chooseFactor: [{
|
|
287
657
|
type: Output
|
|
658
|
+
}], offerEmailSecondFactor: [{
|
|
659
|
+
type: Input
|
|
660
|
+
}], emailedSecondFactor: [{
|
|
661
|
+
type: Input
|
|
662
|
+
}], emailSecondFactor: [{
|
|
663
|
+
type: Output
|
|
664
|
+
}], offerSmsSecondFactor: [{
|
|
665
|
+
type: Input
|
|
666
|
+
}], textedSecondFactor: [{
|
|
667
|
+
type: Input
|
|
668
|
+
}], smsSecondFactor: [{
|
|
669
|
+
type: Output
|
|
670
|
+
}], enrollment: [{
|
|
671
|
+
type: Input
|
|
672
|
+
}], enrollmentState: [{
|
|
673
|
+
type: Input
|
|
674
|
+
}], emailVerification: [{
|
|
675
|
+
type: Input
|
|
676
|
+
}], resend: [{
|
|
677
|
+
type: Output
|
|
288
678
|
}] } });
|
|
289
679
|
/** A read-only message row: `labelKey` holds the i18n key of the text to show. */
|
|
290
680
|
function msg(labelKey) {
|
|
291
681
|
return { kind: 'message', name: '', labelKey, type: 'text' };
|
|
292
682
|
}
|
|
293
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdC1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hdHRlbXB0LWZsb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLFFBQVEsR0FJVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDakYsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFlcEM7Ozs7Ozs7OztHQVNHO0FBZ0VILE1BQU0sT0FBTyxvQkFBb0I7SUFDZCxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJDLE9BQU8sR0FBdUIsSUFBSSxDQUFDO0lBQ25DLElBQUksR0FBRyxLQUFLLENBQUM7SUFDYixNQUFNLEdBQWlCLEVBQUUsQ0FBQztJQUMxQixRQUFRLEdBQUcsY0FBYyxDQUFDO0lBQ25DOzs7O09BSUc7SUFDTSxPQUFPLEdBQTZCLElBQUksQ0FBQztJQUNsRDs7OztPQUlHO0lBQ00sWUFBWSxHQUFvQixJQUFJLENBQUM7SUFDOUMscUdBQXFHO0lBQzVGLGNBQWMsR0FBa0IsSUFBSSxDQUFDO0lBRTlDLG1FQUFtRTtJQUN6RCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQTBCLENBQUM7SUFDbEUsNkZBQTZGO0lBQ25GLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBZ0IsQ0FBQztJQUVoRCxNQUFNLEdBQTJC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LEVBQUUsQ0FBQztBQUMvRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgbG9jYWxpemVkRXJyb3JNZXNzYWdlLFxuICBuZXh0U3RlcCxcbiAgdHlwZSBBdHRlbXB0VmlldyxcbiAgdHlwZSBDYXB0Y2hhQ29udHJvbGxlcixcbiAgdHlwZSBGaWVsZEVycm9yLFxufSBmcm9tICdAYXRsYXNhdXRoL2pzJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXRsYXNDYXB0Y2hhU2xvdERpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvY2FwdGNoYS1zbG90LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBjbGFzc0ZvciwgdHlwZSBFbGVtZW50S2V5IH0gZnJvbSAnLi4vYXBwZWFyYW5jZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcblxuLyoqXG4gKiBPbmUgcmVuZGVyZWQgcm93IG9mIHRoZSBmbG93LiBBIHVuaWZvcm0gc2hhcGUgKHJhdGhlciB0aGFuIGEgZGlzY3JpbWluYXRlZFxuICogdW5pb24pIHNvIHRoZSB0ZW1wbGF0ZSBhY2Nlc3NlcyBvbmx5IGZpZWxkcyB0aGF0IGFsd2F5cyBleGlzdCDigJQgbm8gcmVsaWFuY2Ugb25cbiAqIHRlbXBsYXRlIGNvbnRyb2wtZmxvdyBuYXJyb3dpbmcgb2YgYSBsb29wIHZhcmlhYmxlLCB3aGljaCB2YXJpZXMgYnkgQW5ndWxhclxuICogbWlub3IuIEZvciBhIGBtZXNzYWdlYCByb3csIGBsYWJlbEtleWAgY2FycmllcyB0aGUgbWVzc2FnZSdzIGkxOG4ga2V5LlxuICovXG5pbnRlcmZhY2UgU3RlcEZpZWxkIHtcbiAga2luZDogJ2lucHV0JyB8ICdtZXNzYWdlJztcbiAgbmFtZTogc3RyaW5nO1xuICBsYWJlbEtleTogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHNlcnZlci1kcml2ZW4gZmxvdyBzaGVsbCwgc2hhcmVkIGJ5IGA8YXRsYXMtc2lnbi1pbj5gIGFuZFxuICogYDxhdGxhcy1zaWduLXVwPmAuIFRoZSBBbmd1bGFyIHBlZXIgb2YgUmVhY3QncyBpbnRlcm5hbCBgQXR0ZW1wdEZsb3dgLlxuICpcbiAqIEl0IGNvbnRhaW5zIE5PIGRlY2lzaW9uIGFib3V0IHdoYXQgY29tZXMgbmV4dDogaXQgcmVuZGVycyB3aGF0ZXZlciBgc3RhdHVzYFxuICogdGhlIHNlcnZlciByZXR1cm5lZCwgbWFwcGVkIHRocm91Z2ggYG5leHRTdGVwYCBmcm9tIGBAYXRsYXNhdXRoL2pzYCAodGhlIHNhbWVcbiAqIGV4aGF1c3RpdmUgbWFwcGluZyB0aGUgUmVhY3QgU0RLIHVzZXMpLCBzbyBhZGRpbmcgYSBzdGVwIGlzIGEgc2VydmVyIGNoYW5nZVxuICogYW5kIGFuIG91dC1vZi1kYXRlIGNsaWVudCBkZWdyYWRlcyB0byBhIHZpc2libGUgXCJwbGVhc2UgdXBkYXRlXCIgbWVzc2FnZSByYXRoZXJcbiAqIHRoYW4gYSBibGFuayBzY3JlZW4uXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLWF0dGVtcHQtZmxvdycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQXRsYXNDYXB0Y2hhU2xvdERpcmVjdGl2ZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY2xzKCdjYXJkJywgJ2F0bGFzLWNhcmQnKVwiPlxuICAgICAgPGgxIFtjbGFzc109XCJjbHMoJ2hlYWRlclRpdGxlJywgJ2F0bGFzLXRpdGxlJylcIj57eyB0KHRpdGxlS2V5KSB9fTwvaDE+XG5cbiAgICAgIEBmb3IgKGVycm9yIG9mIGZvcm1FcnJvcnMoKTsgdHJhY2sgZXJyb3IuY29kZSkge1xuICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgZXJyb3JUZXh0KGVycm9yKSB9fTwvcD5cbiAgICAgIH1cblxuICAgICAgPGZvcm0gKHN1Ym1pdCk9XCJvblN1Ym1pdCgkZXZlbnQpXCI+XG4gICAgICAgIEBpZiAoY29kZVNlbnRUZXh0KCk7IGFzIHNlbnRUZXh0KSB7XG4gICAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCIgZGF0YS1hdGxhcy1jb2RlLXNlbnQ9XCJcIj57eyBzZW50VGV4dCB9fTwvcD5cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChmIG9mIGZpZWxkcygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICBAaWYgKGYua2luZCA9PT0gJ2lucHV0Jykge1xuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYXRsYXMtZmllbGRcIj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgdChmLmxhYmVsS2V5KSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkSW5wdXQnLCAnYXRsYXMtaW5wdXQnKVwiXG4gICAgICAgICAgICAgICAgW3R5cGVdPVwiZi50eXBlXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5uYW1lXT1cImYubmFtZVwiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cInZhbHVlc1tmLm5hbWVdID8/ICcnXCJcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwic2V0VmFsdWUoZi5uYW1lLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGZpZWxkRXJyb3JzRm9yKGYubmFtZSk7IHRyYWNrIGVycm9yLmNvZGUpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCI+e3sgZXJyb3JUZXh0KGVycm9yKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxwPnt7IHQoZi5sYWJlbEtleSkgfX08L3A+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93Q2FwdGNoYSgpKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImF0bGFzLWNhcHRjaGFcIiBkYXRhLWF0bGFzLWNhcHRjaGE9XCJcIiBbYXRsYXNDYXB0Y2hhU2xvdF09XCJjYXB0Y2hhXCI+PC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dTdWJtaXQoKSkge1xuICAgICAgICAgIDxidXR0b24gW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblByaW1hcnknLCAnYXRsYXMtYnV0dG9uJylcIiBbZGlzYWJsZWRdPVwiYnVzeVwiIHR5cGU9XCJzdWJtaXRcIj5cbiAgICAgICAgICAgIHt7IHQoJ3NpZ25Jbi5zdWJtaXQnKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93RW1haWxDb2RlT3B0aW9uKCkpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtc3RyYXRlZ3ldPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/IG51bGwgOiAnZW1haWxfY29kZSdcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1hdGxhcy1yZXNlbmRdPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/ICcnIDogbnVsbFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlRmFjdG9yLmVtaXQoJ2VtYWlsX2NvZGUnKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgdChwcmVwYXJlZEZhY3RvciA9PT0gJ2VtYWlsX2NvZGUnID8gJ3NpZ25Jbi5yZXNlbmRDb2RlJyA6ICdzaWduSW4udXNlRW1haWxDb2RlJykgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBBdHRlbXB0Rmxvd0NvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXRsYXMgPSBpbmplY3QoQXRsYXNTZXJ2aWNlKTtcblxuICBASW5wdXQoKSBhdHRlbXB0OiBBdHRlbXB0VmlldyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBidXN5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVycm9yczogRmllbGRFcnJvcltdID0gW107XG4gIEBJbnB1dCgpIHRpdGxlS2V5ID0gJ3NpZ25Jbi50aXRsZSc7XG4gIC8qKlxuICAgKiBUaGUgc2lnbi1pbiBjYXB0Y2hhLCBkcmF3biBhYm92ZSB0aGUgc3VibWl0IGJ1dHRvbiBvbiB0aGUgaWRlbnRpZmllciBzdGVwXG4gICAqIChhbiBhbHdheXMtb24gc2lnbi1pbiBjYXB0Y2hhKSBhbmQgb24gdGhlIGNoYWxsZW5nZSBzdGVwIHRoZSBzZXJ2ZXIgZGVtYW5kc1xuICAgKiB3aXRoIGBuZWVkc19jYXB0Y2hhYC4gTnVsbCB3aGVuIHRoZSBmbG93IGRyYXdzIG5vbmUuXG4gICAqL1xuICBASW5wdXQoKSBjYXB0Y2hhOiBDYXB0Y2hhQ29udHJvbGxlciB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogVGhlIGZpcnN0IGZhY3RvcnMgdG8gb2ZmZXIgb24gdGhlIGBuZWVkc19maXJzdF9mYWN0b3JgIHN0ZXAg4oCUIHBhc3NcbiAgICogYEF0bGFzRmxvd0NvbnRyb2xsZXIuZmlyc3RGYWN0b3JzKClgLCB3aGljaCBkcm9wcyBlbWFpbCBjb2RlIC8gbGluayB3aGlsZSB0aGVcbiAgICogYXBwIGNhbm5vdCBkZWxpdmVyIGVtYWlsLiBOdWxsIHVzZXMgdGhlIHNlcnZlcidzIGxpc3QgYXMtaXMuXG4gICAqL1xuICBASW5wdXQoKSBmaXJzdEZhY3RvcnM6IHN0cmluZ1tdIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgZmlyc3QgZmFjdG9yIGFscmVhZHkgc2VudCAoYEF0bGFzRmxvd0NvbnRyb2xsZXIucHJlcGFyZWRGYWN0b3IoKWApOiBpdHMgY29kZSBpcyBjb2xsZWN0ZWQuICovXG4gIEBJbnB1dCgpIHByZXBhcmVkRmFjdG9yOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogRW1pdHMgdGhlIGNvbGxlY3RlZCBmaWVsZCB2YWx1ZXMgd2hlbiB0aGUgZm9ybSBpcyBzdWJtaXR0ZWQuICovXG4gIEBPdXRwdXQoKSBzdWJtaXRGbG93ID0gbmV3IEV2ZW50RW1pdHRlcjxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PigpO1xuICAvKiogRW1pdHMgd2hlbiB0aGUgdXNlciBwaWNrcyBhIGZpcnN0IGZhY3RvciB0aGUgc2VydmVyIG11c3Qgc2VuZCBmaXJzdCAoYW4gZW1haWxlZCBjb2RlKS4gKi9cbiAgQE91dHB1dCgpIGNob29zZUZhY3RvciA9IG5ldyBFdmVudEVtaXR0ZXI8J2VtYWlsX2NvZGUnPigpO1xuXG4gIHByb3RlY3RlZCB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBwcm90ZWN0ZWQgdChrZXk6IHN0cmluZywgdmFycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBzdHJpbmcge1xuICAgIHJldHVybiB0cmFuc2xhdGUodGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIGtleSwgdmFycyk7XG4gIH1cblxuICAvKiogQSBzZXJ2ZXIgZXJyb3IgaW4gdGhlIGFwcCdzIGxhbmd1YWdlIChgZXJyb3IuPHJlYXNvbj5gLCBlbHNlIHRoZSBzZXJ2ZXIncyBtZXNzYWdlKS4gKi9cbiAgcHJvdGVjdGVkIGVycm9yVGV4dChlcnJvcjogRmllbGRFcnJvcik6IHN0cmluZyB7XG4gICAgLy8gYGVycm9yTG9jYWxpemF0aW9uYCBpcyByZWFkIGRlZmVuc2l2ZWx5OiBhIHN0YW5kLWluIHNlcnZpY2UgbWF5IGxhY2sgaXQuXG4gICAgY29uc3QgbGF5ZXIgPSAodGhpcy5hdGxhcyBhcyB7IGVycm9yTG9jYWxpemF0aW9uPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB9KS5lcnJvckxvY2FsaXphdGlvbjtcbiAgICByZXR1cm4gbG9jYWxpemVkRXJyb3JNZXNzYWdlKGVycm9yLCBsYXllciA/PyB0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwgdGhpcy5hdGxhcy5sb2NhbGl6YXRpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNscyhrZXk6IEVsZW1lbnRLZXksIGJhc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNsYXNzRm9yKGtleSwgdGhpcy5hdGxhcy5hcHBlYXJhbmNlLCBiYXNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRWYWx1ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlcyA9IHsgLi4udGhpcy52YWx1ZXMsIFtuYW1lXTogdmFsdWUgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblN1Ym1pdChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuc3VibWl0Rmxvdy5lbWl0KHRoaXMudmFsdWVzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtRXJyb3JzKCk6IEZpZWxkRXJyb3JbXSB7XG4gICAgcmV0dXJuIHRoaXMuZXJyb3JzLmZpbHRlcigoZXJyb3IpID0+ICFlcnJvci5wYXJhbSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmllbGRFcnJvcnNGb3IobmFtZTogc3RyaW5nKTogRmllbGRFcnJvcltdIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcnMuZmlsdGVyKChlcnJvcikgPT4gZXJyb3IucGFyYW0gPT09IG5hbWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLmF0dGVtcHQgPyBuZXh0U3RlcCh0aGlzLmF0dGVtcHQpIDogKHsga2luZDogJ2NvbGxlY3RfaWRlbnRpZmllcicgfSBhcyBjb25zdCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0NhcHRjaGEoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2luZCA9IHRoaXMuc3RlcCgpLmtpbmQ7XG4gICAgcmV0dXJuICEhdGhpcy5jYXB0Y2hhICYmIChraW5kID09PSAnY29sbGVjdF9pZGVudGlmaWVyJyB8fCBraW5kID09PSAnY29sbGVjdF9jYXB0Y2hhJyk7XG4gIH1cblxuICAvKiogVGhlIGZpcnN0IGZhY3RvcnMgb24gb2ZmZXIgYXQgYSBgbmVlZHNfZmlyc3RfZmFjdG9yYCBzdGVwIChlbXB0eSBvbiBhbnkgb3RoZXIpLiAqL1xuICBwcml2YXRlIG9mZmVyZWQoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHN0ZXAgPSB0aGlzLnN0ZXAoKTtcbiAgICBpZiAoc3RlcC5raW5kICE9PSAnY29sbGVjdF9maXJzdF9mYWN0b3InKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHRoaXMuZmlyc3RGYWN0b3JzID8/IHN0ZXAuc3RyYXRlZ2llcztcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93RW1haWxDb2RlT3B0aW9uKCk6IGJvb2xlYW4ge1xuICAgIC8vIEJlZm9yZSB0aGUgY29kZSBpcyBzZW50OiB0aGUgY2hvaWNlIChvciB0aGUgcmV0cnkgb2YgYSBmYWlsZWQgYXV0b21hdGljXG4gICAgLy8gc2VuZCkuIEFmdGVyOiBcIlJlc2VuZCBjb2RlXCIuXG4gICAgcmV0dXJuIHRoaXMub2ZmZXJlZCgpLmluY2x1ZGVzKCdlbWFpbF9jb2RlJyk7XG4gIH1cblxuICAvKiogVGhlIFwid2Ugc2VudCBhIGNvZGUgdG8g4oCmXCIgbGluZSBvbiB0aGUgY29kZSBzdGVwLiAqL1xuICBwcm90ZWN0ZWQgY29kZVNlbnRUZXh0KCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLnN0ZXAoKS5raW5kICE9PSAnY29sbGVjdF9maXJzdF9mYWN0b3InIHx8IHRoaXMucHJlcGFyZWRGYWN0b3IgIT09ICdlbWFpbF9jb2RlJykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMudCgnc2lnbkluLmNvZGVTZW50VG8nLCB7IGVtYWlsOiB0aGlzLmF0dGVtcHQ/LmlkZW50aWZpZXIgPz8gJycgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd1N1Ym1pdCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBraW5kID0gdGhpcy5zdGVwKCkua2luZDtcbiAgICAvLyBOb3RoaW5nIHRvIHN1Ym1pdCBvbiBhIGZpcnN0LWZhY3RvciBzdGVwIHRoYXQgb25seSBvZmZlcnMgYW4gZW1haWxlZCBjb2RlXG4gICAgLy8gdW50aWwgdGhhdCBjb2RlIGlzIHNlbnQuXG4gICAgaWYgKGtpbmQgPT09ICdjb2xsZWN0X2ZpcnN0X2ZhY3RvcicpIHJldHVybiB0aGlzLmZpZWxkcygpLmxlbmd0aCA+IDA7XG4gICAgcmV0dXJuIGtpbmQgIT09ICdkb25lJyAmJiBraW5kICE9PSAnYXdhaXRfb2F1dGgnO1xuICB9XG5cbiAgcHJvdGVjdGVkIGZpZWxkcygpOiBTdGVwRmllbGRbXSB7XG4gICAgY29uc3Qgc3RlcCA9IHRoaXMuc3RlcCgpO1xuICAgIHN3aXRjaCAoc3RlcC5raW5kKSB7XG4gICAgICBjYXNlICdjb2xsZWN0X2lkZW50aWZpZXInOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2lkZW50aWZpZXInLCBsYWJlbEtleTogJ3NpZ25Jbi5pZGVudGlmaWVyTGFiZWwnLCB0eXBlOiAnZW1haWwnIH1dO1xuICAgICAgY2FzZSAnY29sbGVjdF9maXJzdF9mYWN0b3InOiB7XG4gICAgICAgIGlmICh0aGlzLnByZXBhcmVkRmFjdG9yID09PSAnZW1haWxfY29kZScpIHtcbiAgICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ3NpZ25Jbi5lbWFpbENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgcGFzc3dvcmQgZmllbGQgdW5sZXNzIHRoZSBvbmx5IG9mZmVyIGlzIGFuIGVtYWlsZWQgY29kZSAoY2hvc2VuXG4gICAgICAgIC8vIHdpdGggdGhlIGJ1dHRvbiBiZWxvdyB0aGUgZm9ybSkuXG4gICAgICAgIGNvbnN0IG9mZmVyZWQgPSB0aGlzLm9mZmVyZWQoKTtcbiAgICAgICAgcmV0dXJuIG9mZmVyZWQuaW5jbHVkZXMoJ2VtYWlsX2NvZGUnKSAmJiAhb2ZmZXJlZC5pbmNsdWRlcygncGFzc3dvcmQnKVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFt7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdwYXNzd29yZCcsIGxhYmVsS2V5OiAnc2lnbkluLnBhc3N3b3JkTGFiZWwnLCB0eXBlOiAncGFzc3dvcmQnIH1dO1xuICAgICAgfVxuICAgICAgY2FzZSAnY29sbGVjdF9zZWNvbmRfZmFjdG9yJzpcbiAgICAgICAgcmV0dXJuIFt7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdjb2RlJywgbGFiZWxLZXk6ICdtZmEuY29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgY2FzZSAnZW5yb2xsX3NlY29uZF9mYWN0b3InOlxuICAgICAgICAvLyBUd28gY29uc2VjdXRpdmUgY29kZXMgKMKnNS42KTogYSBwaG9uZSB3aXRoIGEgZmFzdCBjbG9jayBmYWlscyBoZXJlXG4gICAgICAgIC8vIHJhdGhlciB0aGFuIG9uIGV2ZXJ5IHNpZ24taW4gYWZ0ZXJ3YXJkcy5cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICB7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdjb2RlJywgbGFiZWxLZXk6ICdtZmEuZW5yb2xsRmlyc3RDb2RlTGFiZWwnLCB0eXBlOiAndGV4dCcgfSxcbiAgICAgICAgICB7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdzZWNvbmRDb2RlJywgbGFiZWxLZXk6ICdtZmEuZW5yb2xsU2Vjb25kQ29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH0sXG4gICAgICAgIF07XG4gICAgICBjYXNlICdjb2xsZWN0X2VtYWlsX2NvZGUnOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ3NpZ25Jbi5lbWFpbENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfbmV3X3Bhc3N3b3JkJzpcbiAgICAgICAgcmV0dXJuIFt7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdwYXNzd29yZCcsIGxhYmVsS2V5OiAncmVzZXQubmV3UGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICBjYXNlICdjb2xsZWN0X2NhcHRjaGEnOlxuICAgICAgICAvLyDCpzUgdGhlIHNlcnZlciB3aXRoaGVsZCB0aGUgYXR0ZW1wdCB1bnRpbCBhIGNhcHRjaGEgY2xlYXJzLiBTb2x2aW5nIHRoZVxuICAgICAgICAvLyB3aWRnZXQgcmVzdWJtaXRzIHRoZSBpZGVudGlmaWVyIG9uIGl0cyBvd247IHRoZSBidXR0b24gcmV0cmllcy5cbiAgICAgICAgcmV0dXJuIFttc2coJ2NhcHRjaGEucHJvbXB0JyldO1xuICAgICAgY2FzZSAnYXdhaXRfb2F1dGgnOlxuICAgICAgICByZXR1cm4gW21zZygnc2lnbkluLm1hZ2ljTGlua1NlbnQnKV07XG4gICAgICBjYXNlICdkb25lJzpcbiAgICAgICAgcmV0dXJuIFttc2coJ3NpZ25Jbi5jaGVja090aGVyVGFiJyldO1xuICAgICAgY2FzZSAncmVzdGFydCc6XG4gICAgICAgIHJldHVybiBbbXNnKCdlcnJvci5nZW5lcmljJyldO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gQSBzdGF0dXMgdGhpcyBTREsgdmVyc2lvbiBkb2VzIG5vdCBrbm93LiBBbiBob25lc3QgbWVzc2FnZSBiZWF0cyBhXG4gICAgICAgIC8vIGJsYW5rIGxvZ2luIGJveCB0aGUgdXNlciBjYW5ub3QgYWN0IG9uLlxuICAgICAgICByZXR1cm4gW21zZygnZXJyb3IuZ2VuZXJpYycpXTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIEEgcmVhZC1vbmx5IG1lc3NhZ2Ugcm93OiBgbGFiZWxLZXlgIGhvbGRzIHRoZSBpMThuIGtleSBvZiB0aGUgdGV4dCB0byBzaG93LiAqL1xuZnVuY3Rpb24gbXNnKGxhYmVsS2V5OiBzdHJpbmcpOiBTdGVwRmllbGQge1xuICByZXR1cm4geyBraW5kOiAnbWVzc2FnZScsIG5hbWU6ICcnLCBsYWJlbEtleSwgdHlwZTogJ3RleHQnIH07XG59XG4iXX0=
|
|
683
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdC1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hdHRlbXB0LWZsb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQixhQUFhLEVBQ2IscUJBQXFCLEVBQ3JCLFFBQVEsR0FPVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDakYsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFlcEM7Ozs7Ozs7OztHQVNHO0FBd01ILE1BQU0sT0FBTyxvQkFBb0I7SUFDZCxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJDLE9BQU8sR0FBdUIsSUFBSSxDQUFDO0lBQ25DLElBQUksR0FBRyxLQUFLLENBQUM7SUFDYixNQUFNLEdBQWlCLEVBQUUsQ0FBQztJQUNuQywwRkFBMEY7SUFDakYsV0FBVyxHQUF3QixTQUFTLENBQUM7SUFDN0MsUUFBUSxHQUFHLGNBQWMsQ0FBQztJQUNuQzs7OztPQUlHO0lBQ00sT0FBTyxHQUE2QixJQUFJLENBQUM7SUFDbEQ7Ozs7T0FJRztJQUNNLFlBQVksR0FBb0IsSUFBSSxDQUFDO0lBQzlDLHFHQUFxRztJQUM1RixjQUFjLEdBQWtCLElBQUksQ0FBQztJQUU5QyxtRUFBbUU7SUFDekQsVUFBVSxHQUFHLElBQUksWUFBWSxF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Z0JBTUcsT0FBTztzQkFBZixLQUFLO2dCQU1HLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUcsY0FBYztzQkFBdEIsS0FBSztnQkFHSSxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLFlBQVk7c0JBQXJCLE1BQU07Z0JBTUUsc0JBQXNCO3NCQUE5QixLQUFLO2dCQUVHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBTUUsb0JBQW9CO3NCQUE1QixLQUFLO2dCQUVHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDSSxlQUFlO3NCQUF4QixNQUFNO2dCQU1FLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFNRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0ksTUFBTTtzQkFBZixNQUFNOztBQTBMVCxrRkFBa0Y7QUFDbEYsU0FBUyxHQUFHLENBQUMsUUFBZ0I7SUFDM0IsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBhd2FpdGluZ1NpZ25VcExpbmssXG4gIGVucm9sbG1lbnRTdWJtaXRLZXksXG4gIGdyb3VwU2V0dXBLZXksXG4gIGxvY2FsaXplZEVycm9yTWVzc2FnZSxcbiAgbmV4dFN0ZXAsXG4gIHR5cGUgQXR0ZW1wdFZpZXcsXG4gIHR5cGUgQ2FwdGNoYUNvbnRyb2xsZXIsXG4gIHR5cGUgRmllbGRFcnJvcixcbiAgdHlwZSBNZmFFbnJvbGxtZW50Q29udHJvbGxlcixcbiAgdHlwZSBNZmFFbnJvbGxtZW50U3RhdGUsXG4gIHR5cGUgTWZhRW5yb2xsbWVudFN0cmF0ZWd5LFxufSBmcm9tICdAYXRsYXNhdXRoL2pzJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXRsYXNDYXB0Y2hhU2xvdERpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvY2FwdGNoYS1zbG90LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBjbGFzc0ZvciwgdHlwZSBFbGVtZW50S2V5IH0gZnJvbSAnLi4vYXBwZWFyYW5jZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcblxuLyoqXG4gKiBPbmUgcmVuZGVyZWQgcm93IG9mIHRoZSBmbG93LiBBIHVuaWZvcm0gc2hhcGUgKHJhdGhlciB0aGFuIGEgZGlzY3JpbWluYXRlZFxuICogdW5pb24pIHNvIHRoZSB0ZW1wbGF0ZSBhY2Nlc3NlcyBvbmx5IGZpZWxkcyB0aGF0IGFsd2F5cyBleGlzdCDigJQgbm8gcmVsaWFuY2Ugb25cbiAqIHRlbXBsYXRlIGNvbnRyb2wtZmxvdyBuYXJyb3dpbmcgb2YgYSBsb29wIHZhcmlhYmxlLCB3aGljaCB2YXJpZXMgYnkgQW5ndWxhclxuICogbWlub3IuIEZvciBhIGBtZXNzYWdlYCByb3csIGBsYWJlbEtleWAgY2FycmllcyB0aGUgbWVzc2FnZSdzIGkxOG4ga2V5LlxuICovXG5pbnRlcmZhY2UgU3RlcEZpZWxkIHtcbiAga2luZDogJ2lucHV0JyB8ICdtZXNzYWdlJyB8ICdhbGVydCc7XG4gIG5hbWU6IHN0cmluZztcbiAgbGFiZWxLZXk6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBzZXJ2ZXItZHJpdmVuIGZsb3cgc2hlbGwsIHNoYXJlZCBieSBgPGF0bGFzLXNpZ24taW4+YCBhbmRcbiAqIGA8YXRsYXMtc2lnbi11cD5gLiBUaGUgQW5ndWxhciBwZWVyIG9mIFJlYWN0J3MgaW50ZXJuYWwgYEF0dGVtcHRGbG93YC5cbiAqXG4gKiBJdCBjb250YWlucyBOTyBkZWNpc2lvbiBhYm91dCB3aGF0IGNvbWVzIG5leHQ6IGl0IHJlbmRlcnMgd2hhdGV2ZXIgYHN0YXR1c2BcbiAqIHRoZSBzZXJ2ZXIgcmV0dXJuZWQsIG1hcHBlZCB0aHJvdWdoIGBuZXh0U3RlcGAgZnJvbSBgQGF0bGFzYXV0aC9qc2AgKHRoZSBzYW1lXG4gKiBleGhhdXN0aXZlIG1hcHBpbmcgdGhlIFJlYWN0IFNESyB1c2VzKSwgc28gYWRkaW5nIGEgc3RlcCBpcyBhIHNlcnZlciBjaGFuZ2VcbiAqIGFuZCBhbiBvdXQtb2YtZGF0ZSBjbGllbnQgZGVncmFkZXMgdG8gYSB2aXNpYmxlIFwicGxlYXNlIHVwZGF0ZVwiIG1lc3NhZ2UgcmF0aGVyXG4gKiB0aGFuIGEgYmxhbmsgc2NyZWVuLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1hdHRlbXB0LWZsb3cnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0bGFzQ2FwdGNoYVNsb3REaXJlY3RpdmVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNscygnY2FyZCcsICdhdGxhcy1jYXJkJylcIj5cbiAgICAgIDxoMSBbY2xhc3NdPVwiY2xzKCdoZWFkZXJUaXRsZScsICdhdGxhcy10aXRsZScpXCI+e3sgdCh0aXRsZUtleSkgfX08L2gxPlxuXG4gICAgICBAZm9yIChlcnJvciBvZiBmb3JtRXJyb3JzKCk7IHRyYWNrIGVycm9yLmNvZGUpIHtcbiAgICAgICAgPHAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiIHJvbGU9XCJhbGVydFwiPnt7IGVycm9yVGV4dChlcnJvcikgfX08L3A+XG4gICAgICB9XG5cbiAgICAgIDxmb3JtIChzdWJtaXQpPVwib25TdWJtaXQoJGV2ZW50KVwiPlxuICAgICAgICBAaWYgKGNvZGVTZW50VGV4dCgpOyBhcyBzZW50VGV4dCkge1xuICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXMtY29kZS1zZW50PVwiXCI+e3sgc2VudFRleHQgfX08L3A+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChsaW5rT25seSgpKSB7XG4gICAgICAgICAgPCEtLSBOb3RoaW5nIHRvIHR5cGU6IHRoZSBmbG93IHBvbGxzIHVudGlsIHRoZSBlbWFpbGVkIGxpbmsgaXMgb3BlbmVkIChhbnl3aGVyZSkuIC0tPlxuICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXMtbGluay1zZW50PVwiXCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgICAgICB7eyB0KCdzaWduVXAubGlua1NlbnRUbycsIHsgZW1haWw6IGF0dGVtcHQ/LmlkZW50aWZpZXIgPz8gJycgfSkgfX1cbiAgICAgICAgICA8L3A+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblNlY29uZGFyeScsICdhdGxhcy1idXR0b24tc2Vjb25kYXJ5JylcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBkYXRhLWF0bGFzLXJlc2VuZD1cIlwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeVwiXG4gICAgICAgICAgICAoY2xpY2spPVwicmVzZW5kLmVtaXQoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgdCgnc2lnbkluLnJlc2VuZExpbmsnKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICAgIEBpZiAoZW5yb2xsaW5nKCkgJiYgZW5yb2xsbWVudFN0YXRlOyBhcyBlbnJvbCkge1xuICAgICAgICAgIEBpZiAoZW5yb2wubWV0aG9kID09PSBudWxsKSB7XG4gICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIj57eyB0KCdtZmEuZW5yb2xsQ2hvb3NlJykgfX08L3A+XG4gICAgICAgICAgICBAZm9yIChtIG9mIGVucm9sLm9wdGlvbnM7IHRyYWNrIG0pIHtcbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLWF0bGFzLW1mYS1tZXRob2RdPVwibVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3kgfHwgZW5yb2wuYnVzeVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImNob29zZU1ldGhvZChtKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyB0KG0gPT09ICd0b3RwJyA/ICdtZmEuZW5yb2xsVG90cE9wdGlvbicgOiAnbWZhLmVucm9sbFNtc09wdGlvbicpIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gQGVsc2UgaWYgKGVucm9sLm1ldGhvZCA9PT0gJ3RvdHAnKSB7XG4gICAgICAgICAgICBAaWYgKGVucm9sLmVucm9sbG1lbnQ7IGFzIHNldHVwKSB7XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiPnt7IHQoJ21mYS5lbnJvbGxTY2FuJykgfX08L3A+XG4gICAgICAgICAgICAgIEBpZiAoc2V0dXAucXJDb2RlKSB7XG4gICAgICAgICAgICAgICAgPGltZyBjbGFzcz1cImF0bGFzLW1mYS1xclwiIGRhdGEtYXRsYXM9XCJtZmEtcXJcIiBbc3JjXT1cInNldHVwLnFyQ29kZVwiIFthbHRdPVwidCgnbWZhLmVucm9sbFFyQWx0JylcIiB3aWR0aD1cIjE4MFwiIGhlaWdodD1cIjE4MFwiIC8+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGlmIChzZXR1cC5zZWNyZXQpIHtcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIiBkYXRhLWF0bGFzPVwibWZhLXNldHVwLWtleVwiPnt7IHQoJ21mYS5lbnJvbGxTZXR1cEtleScpIH19OiA8Y29kZT57eyBzZXR1cEtleShzZXR1cC5zZWNyZXQpIH19PC9jb2RlPjwvcD5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJhdGxhcy1maWVsZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IHQoJ21mYS5lbnJvbGxGaXJzdENvZGVMYWJlbCcpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRJbnB1dCcsICdhdGxhcy1pbnB1dCcpXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiY29kZVwiIGF1dG9jb21wbGV0ZT1cIm9uZS10aW1lLWNvZGVcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgW3ZhbHVlXT1cInZhbHVlc1snY29kZSddID8/ICcnXCIgKGlucHV0KT1cInNldFZhbHVlKCdjb2RlJywgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIiAvPlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICBAaWYgKGVucm9sLnRvdHBDb2RlcyA+PSAyKSB7XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYXRsYXMtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHQoJ21mYS5lbnJvbGxTZWNvbmRDb2RlTGFiZWwnKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRJbnB1dCcsICdhdGxhcy1pbnB1dCcpXCIgdHlwZT1cInRleHRcIiBuYW1lPVwic2Vjb25kQ29kZVwiIGF1dG9jb21wbGV0ZT1cIm9uZS10aW1lLWNvZGVcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgW3ZhbHVlXT1cInZhbHVlc1snc2Vjb25kQ29kZSddID8/ICcnXCIgKGlucHV0KT1cInNldFZhbHVlKCdzZWNvbmRDb2RlJywgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIiAvPlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj57eyBlbnJvbC5idXN5ID8gdCgnbWZhLmVucm9sbFByZXBhcmluZycpIDogJycgfX08L3A+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICBAaWYgKGVucm9sLmVucm9sbG1lbnQ7IGFzIHRleHRlZCkge1xuICAgICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIiBkYXRhLWF0bGFzPVwibWZhLWNvZGUtdGV4dGVkXCIgYXJpYS1saXZlPVwicG9saXRlXCI+e3sgdCgnbWZhLmNvZGVUZXh0ZWRUbycsIHsgcGhvbmU6IHRleHRlZC5waG9uZSA/PyAnJyB9KSB9fTwvcD5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYXRsYXMtZmllbGRcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyB0KCdtZmEuY29kZUxhYmVsJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJjb2RlXCIgYXV0b2NvbXBsZXRlPVwib25lLXRpbWUtY29kZVwiIGlucHV0bW9kZT1cIm51bWVyaWNcIiBbdmFsdWVdPVwidmFsdWVzWydjb2RlJ10gPz8gJydcIiAoaW5wdXQpPVwic2V0VmFsdWUoJ2NvZGUnLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiIC8+XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgZGF0YS1hdGxhcy1yZXNlbmQ9XCJcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJidXN5IHx8IGVucm9sLmJ1c3lcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNlbmRFbnJvbGxtZW50KClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge3sgdCgnc2lnbkluLnJlc2VuZENvZGUnKSB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJhdGxhcy1maWVsZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IHQoJ21mYS5waG9uZUxhYmVsJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIiB0eXBlPVwidGVsXCIgbmFtZT1cInBob25lXCIgYXV0b2NvbXBsZXRlPVwidGVsXCIgW3ZhbHVlXT1cInZhbHVlc1sncGhvbmUnXSA/PyAnJ1wiIChpbnB1dCk9XCJzZXRWYWx1ZSgncGhvbmUnLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiIC8+XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiPnt7IHQoJ21mYS5waG9uZUhpbnQnKSB9fTwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgQGZvciAoZXJyb3Igb2YgZW5yb2wuZXJyb3JzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxwIFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZEVycm9yJywgJ2F0bGFzLWVycm9yJylcIiByb2xlPVwiYWxlcnRcIj57eyBlcnJvci5tZXNzYWdlIH19PC9wPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKGVucm9sLm1ldGhvZCAhPT0gbnVsbCAmJiBlbnJvbC5vcHRpb25zLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIEBmb3IgKG90aGVyIG9mIG90aGVyTWV0aG9kcyhlbnJvbCk7IHRyYWNrIG90aGVyKSB7XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZGF0YS1hdGxhcy1tZmEtbWV0aG9kXT1cIm90aGVyXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeSB8fCBlbnJvbC5idXN5XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlTWV0aG9kKG90aGVyKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyB0KG90aGVyID09PSAndG90cCcgPyAnbWZhLmVucm9sbFRvdHBPcHRpb24nIDogJ21mYS5lbnJvbGxTbXNPcHRpb24nKSB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoZiBvZiBmaWVsZHMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgQGlmIChmLmtpbmQgPT09ICdpbnB1dCcpIHtcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImF0bGFzLWZpZWxkXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IHQoZi5sYWJlbEtleSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIlxuICAgICAgICAgICAgICAgIFt0eXBlXT1cImYudHlwZVwiXG4gICAgICAgICAgICAgICAgW2F0dHIubmFtZV09XCJmLm5hbWVcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJ2YWx1ZXNbZi5uYW1lXSA/PyAnJ1wiXG4gICAgICAgICAgICAgICAgKGlucHV0KT1cInNldFZhbHVlKGYubmFtZSwgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICBAZm9yIChlcnJvciBvZiBmaWVsZEVycm9yc0ZvcihmLm5hbWUpOyB0cmFjayBlcnJvci5jb2RlKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiPnt7IGVycm9yVGV4dChlcnJvcikgfX08L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgfSBAZWxzZSBpZiAoZi5raW5kID09PSAnYWxlcnQnKSB7XG4gICAgICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgdChmLmxhYmVsS2V5KSB9fTwvcD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxwPnt7IHQoZi5sYWJlbEtleSkgfX08L3A+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93Q2FwdGNoYSgpKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImF0bGFzLWNhcHRjaGFcIiBkYXRhLWF0bGFzLWNhcHRjaGE9XCJcIiBbYXRsYXNDYXB0Y2hhU2xvdF09XCJjYXB0Y2hhXCI+PC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dTdWJtaXQoKSkge1xuICAgICAgICAgIDxidXR0b24gW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblByaW1hcnknLCAnYXRsYXMtYnV0dG9uJylcIiBbZGlzYWJsZWRdPVwiYnVzeSB8fCAoZW5yb2xsaW5nKCkgJiYgISFlbnJvbGxtZW50U3RhdGU/LmJ1c3kpXCIgdHlwZT1cInN1Ym1pdFwiPlxuICAgICAgICAgICAge3sgdChzdWJtaXRLZXkoKSkgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuXG4gICAgICAgIEBpZiAoc2hvd1Ntc1NlY29uZEZhY3RvcigpKSB7XG4gICAgICAgICAgQGlmIChzbXNTZWNvbmRGYWN0b3JTZW50VG8oKTsgYXMgc2VudFRvKSB7XG4gICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIiBkYXRhLWF0bGFzPVwic21zLXNlY29uZC1mYWN0b3Itc2VudFwiIGFyaWEtbGl2ZT1cInBvbGl0ZVwiPlxuICAgICAgICAgICAgICB7eyB0KCdtZmEuY29kZVRleHRlZFRvJywgeyBwaG9uZTogc2VudFRvIH0pIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGRhdGEtYXRsYXM9XCJzbXMtc2Vjb25kLWZhY3RvclwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJidXN5IHx8ICEhdGV4dGVkU2Vjb25kRmFjdG9yPy5idXN5XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNtc1NlY29uZEZhY3Rvci5lbWl0KClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyB0ZXh0ZWRTZWNvbmRGYWN0b3I/LmJ1c3kgPyB0KCdzaWduSW4uc2VuZGluZycpIDogdCgnbWZhLnNtc0NvZGVPcHRpb24nKSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICBAaWYgKHRleHRlZFNlY29uZEZhY3Rvcj8uZXJyb3I7IGFzIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgPHAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiIHJvbGU9XCJhbGVydFwiPnt7IG1lc3NhZ2UgfX08L3A+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93RW1haWxTZWNvbmRGYWN0b3IoKSkge1xuICAgICAgICAgIEBpZiAoZW1haWxTZWNvbmRGYWN0b3JTZW50VG8oKTsgYXMgc2VudFRvKSB7XG4gICAgICAgICAgICA8cCBjbGFzcz1cImF0bGFzLXRleHRcIiBkYXRhLWF0bGFzPVwiZW1haWwtc2Vjb25kLWZhY3Rvci1zZW50XCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgICAgICAgIHt7IHQoJ3NpZ25Jbi5jb2RlU2VudFRvJywgeyBlbWFpbDogc2VudFRvIH0pIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGRhdGEtYXRsYXM9XCJlbWFpbC1zZWNvbmQtZmFjdG9yXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3kgfHwgISFlbWFpbGVkU2Vjb25kRmFjdG9yPy5idXN5XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImVtYWlsU2Vjb25kRmFjdG9yLmVtaXQoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IGVtYWlsZWRTZWNvbmRGYWN0b3I/LmJ1c3kgPyB0KCdzaWduSW4uc2VuZGluZycpIDogdCgnc2lnbkluLmVtYWlsQ29kZU9wdGlvbicpIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIEBpZiAoZW1haWxlZFNlY29uZEZhY3Rvcj8uZXJyb3I7IGFzIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgPHAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiIHJvbGU9XCJhbGVydFwiPnt7IG1lc3NhZ2UgfX08L3A+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93RW1haWxDb2RlT3B0aW9uKCkpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtc3RyYXRlZ3ldPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/IG51bGwgOiAnZW1haWxfY29kZSdcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1hdGxhcy1yZXNlbmRdPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/ICcnIDogbnVsbFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlRmFjdG9yLmVtaXQoJ2VtYWlsX2NvZGUnKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgdChwcmVwYXJlZEZhY3RvciA9PT0gJ2VtYWlsX2NvZGUnID8gJ3NpZ25Jbi5yZXNlbmRDb2RlJyA6ICdzaWduSW4udXNlRW1haWxDb2RlJykgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBBdHRlbXB0Rmxvd0NvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXRsYXMgPSBpbmplY3QoQXRsYXNTZXJ2aWNlKTtcblxuICBASW5wdXQoKSBhdHRlbXB0OiBBdHRlbXB0VmlldyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBidXN5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVycm9yczogRmllbGRFcnJvcltdID0gW107XG4gIC8qKiBgRmxvd1N0YXRlLnNlc3Npb25LZXB0YDogd2hldGhlciB0aGlzIGJyb3dzZXIga2VwdCB0aGUgc2Vzc2lvbiB0aGUgc2lnbi1pbiBjcmVhdGVkLiAqL1xuICBASW5wdXQoKSBzZXNzaW9uS2VwdDogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgdGl0bGVLZXkgPSAnc2lnbkluLnRpdGxlJztcbiAgLyoqXG4gICAqIFRoZSBzaWduLWluIGNhcHRjaGEsIGRyYXduIGFib3ZlIHRoZSBzdWJtaXQgYnV0dG9uIG9uIHRoZSBpZGVudGlmaWVyIHN0ZXBcbiAgICogKGFuIGFsd2F5cy1vbiBzaWduLWluIGNhcHRjaGEpIGFuZCBvbiB0aGUgY2hhbGxlbmdlIHN0ZXAgdGhlIHNlcnZlciBkZW1hbmRzXG4gICAqIHdpdGggYG5lZWRzX2NhcHRjaGFgLiBOdWxsIHdoZW4gdGhlIGZsb3cgZHJhd3Mgbm9uZS5cbiAgICovXG4gIEBJbnB1dCgpIGNhcHRjaGE6IENhcHRjaGFDb250cm9sbGVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBUaGUgZmlyc3QgZmFjdG9ycyB0byBvZmZlciBvbiB0aGUgYG5lZWRzX2ZpcnN0X2ZhY3RvcmAgc3RlcCDigJQgcGFzc1xuICAgKiBgQXRsYXNGbG93Q29udHJvbGxlci5maXJzdEZhY3RvcnMoKWAsIHdoaWNoIGRyb3BzIGVtYWlsIGNvZGUgLyBsaW5rIHdoaWxlIHRoZVxuICAgKiBhcHAgY2Fubm90IGRlbGl2ZXIgZW1haWwuIE51bGwgdXNlcyB0aGUgc2VydmVyJ3MgbGlzdCBhcy1pcy5cbiAgICovXG4gIEBJbnB1dCgpIGZpcnN0RmFjdG9yczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSBmaXJzdCBmYWN0b3IgYWxyZWFkeSBzZW50IChgQXRsYXNGbG93Q29udHJvbGxlci5wcmVwYXJlZEZhY3RvcigpYCk6IGl0cyBjb2RlIGlzIGNvbGxlY3RlZC4gKi9cbiAgQElucHV0KCkgcHJlcGFyZWRGYWN0b3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBFbWl0cyB0aGUgY29sbGVjdGVkIGZpZWxkIHZhbHVlcyB3aGVuIHRoZSBmb3JtIGlzIHN1Ym1pdHRlZC4gKi9cbiAgQE91dHB1dCgpIHN1Ym1pdEZsb3cgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KCk7XG4gIC8qKiBFbWl0cyB3aGVuIHRoZSB1c2VyIHBpY2tzIGEgZmlyc3QgZmFjdG9yIHRoZSBzZXJ2ZXIgbXVzdCBzZW5kIGZpcnN0IChhbiBlbWFpbGVkIGNvZGUpLiAqL1xuICBAT3V0cHV0KCkgY2hvb3NlRmFjdG9yID0gbmV3IEV2ZW50RW1pdHRlcjwnZW1haWxfY29kZSc+KCk7XG4gIC8qKlxuICAgKiBPZmZlciBcIkVtYWlsIG1lIGEgY29kZSBpbnN0ZWFkXCIgYXQgdGhlIHNlY29uZCBmYWN0b3IgKHRoZSBpbnN0YW5jZSdzXG4gICAqIGBhY2NvdW50LmVtYWlsU2Vjb25kRmFjdG9yYCk7IGBlbWFpbFNlY29uZEZhY3RvcmAgYXNrcyBmb3IgaXQgYW5kXG4gICAqIGBlbWFpbGVkU2Vjb25kRmFjdG9yYCByZXBvcnRzIGhvdyBpdCB3ZW50LlxuICAgKi9cbiAgQElucHV0KCkgb2ZmZXJFbWFpbFNlY29uZEZhY3RvciA9IGZhbHNlO1xuICAvKiogYEF0bGFzRmxvd0NvbnRyb2xsZXIuZW1haWxTZWNvbmRGYWN0b3IoKWA6IGluIGZsaWdodCwgd2hlcmUgaXQgd2VudCwgb3Igd2h5IG5vdC4gKi9cbiAgQElucHV0KCkgZW1haWxlZFNlY29uZEZhY3RvcjogeyBidXN5PzogYm9vbGVhbjsgc2VudFRvPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9IHwgbnVsbCA9IG51bGw7XG4gIEBPdXRwdXQoKSBlbWFpbFNlY29uZEZhY3RvciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqXG4gICAqIE9mZmVyIFwiVGV4dCBtZSBhIGNvZGUgaW5zdGVhZFwiIGF0IHRoZSBzZWNvbmQgZmFjdG9yICh3aGVyZSB0aGUgYXBwIG9mZmVyc1xuICAgKiB0ZXh0ZWQgY29kZXMsIGBBdGxhc0Zsb3dDb250cm9sbGVyLm1mYUNob2ljZXMoKS5zbXNgKTsgYHNtc1NlY29uZEZhY3RvcmBcbiAgICogYXNrcyBmb3IgaXQgYW5kIGB0ZXh0ZWRTZWNvbmRGYWN0b3JgIHJlcG9ydHMgaG93IGl0IHdlbnQuXG4gICAqL1xuICBASW5wdXQoKSBvZmZlclNtc1NlY29uZEZhY3RvciA9IGZhbHNlO1xuICAvKiogYEF0bGFzRmxvd0NvbnRyb2xsZXIuc21zU2Vjb25kRmFjdG9yKClgOiBpbiBmbGlnaHQsIHdoZXJlIGl0IHdlbnQsIG9yIHdoeSBub3QuICovXG4gIEBJbnB1dCgpIHRleHRlZFNlY29uZEZhY3RvcjogeyBidXN5PzogYm9vbGVhbjsgc2VudFRvPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9IHwgbnVsbCA9IG51bGw7XG4gIEBPdXRwdXQoKSBzbXNTZWNvbmRGYWN0b3IgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKlxuICAgKiBUaGUgTUZBIGVucm9sbWVudCBzdGVwIChgQXRsYXNGbG93Q29udHJvbGxlci5lbnJvbGxtZW50YCBhbmRcbiAgICogYGVucm9sbG1lbnRTdGF0ZSgpYCk6IHRoZSBhdXRoZW50aWNhdG9yIGFwcCdzIFFSIGNvZGUgYW5kIHNldHVwIGtleSwgb3IgYVxuICAgKiB0ZXh0ZWQgY29kZS4gTnVsbDogdGhlIHN0ZXAgYXNrcyBmb3IgdHdvIGF1dGhlbnRpY2F0b3IgY29kZXMgb25seS5cbiAgICovXG4gIEBJbnB1dCgpIGVucm9sbG1lbnQ6IE1mYUVucm9sbG1lbnRDb250cm9sbGVyIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGVucm9sbG1lbnRTdGF0ZTogTWZhRW5yb2xsbWVudFN0YXRlIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBUaGUgaW5zdGFuY2UncyBgYWNjb3VudC5lbWFpbFZlcmlmaWNhdGlvbmAuIE9uIGBsaW5rYCBhIHNpZ24tdXAnc1xuICAgKiB2ZXJpZmljYXRpb24gc3RlcCBoYXMgbm90aGluZyB0byB0eXBlOiBpdCBzYXlzIHRvIG9wZW4gdGhlIGVtYWlsZWQgbGlua1xuICAgKiB3aGlsZSB0aGUgZmxvdyBwb2xscywgYW5kIG9mZmVycyBhIHJlc2VuZCAoYHJlc2VuZGApLlxuICAgKi9cbiAgQElucHV0KCkgZW1haWxWZXJpZmljYXRpb246IHN0cmluZyA9ICdjb2RlJztcbiAgQE91dHB1dCgpIHJlc2VuZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcm90ZWN0ZWQgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgcHJvdGVjdGVkIHQoa2V5OiBzdHJpbmcsIHZhcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKHRoaXMuYXRsYXMubG9jYWxpemF0aW9uLCBrZXksIHZhcnMpO1xuICB9XG5cbiAgLyoqIEEgc2VydmVyIGVycm9yIGluIHRoZSBhcHAncyBsYW5ndWFnZSAoYGVycm9yLjxyZWFzb24+YCwgZWxzZSB0aGUgc2VydmVyJ3MgbWVzc2FnZSkuICovXG4gIHByb3RlY3RlZCBlcnJvclRleHQoZXJyb3I6IEZpZWxkRXJyb3IpOiBzdHJpbmcge1xuICAgIC8vIGBlcnJvckxvY2FsaXphdGlvbmAgaXMgcmVhZCBkZWZlbnNpdmVseTogYSBzdGFuZC1pbiBzZXJ2aWNlIG1heSBsYWNrIGl0LlxuICAgIGNvbnN0IGxheWVyID0gKHRoaXMuYXRsYXMgYXMgeyBlcnJvckxvY2FsaXphdGlvbj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSkuZXJyb3JMb2NhbGl6YXRpb247XG4gICAgcmV0dXJuIGxvY2FsaXplZEVycm9yTWVzc2FnZShlcnJvciwgbGF5ZXIgPz8gdGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIHRoaXMuYXRsYXMubG9jYWxpemF0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbHMoa2V5OiBFbGVtZW50S2V5LCBiYXNlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBjbGFzc0ZvcihrZXksIHRoaXMuYXRsYXMuYXBwZWFyYW5jZSwgYmFzZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmFsdWUobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZXMgPSB7IC4uLnRoaXMudmFsdWVzLCBbbmFtZV06IHZhbHVlIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TdWJtaXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAvLyBFbnJvbG1lbnQ6IHRleHQgdGhlIGNvZGUgdG8gdGhlIHR5cGVkIG51bWJlciwgb3IgY29uZmlybSB0aGUgZmFjdG9yLlxuICAgIGlmICh0aGlzLmVucm9sbGluZygpICYmIHRoaXMuZW5yb2xsbWVudCkge1xuICAgICAgdm9pZCB0aGlzLmVucm9sbG1lbnQuc3VibWl0KHRoaXMudmFsdWVzKS50aGVuKChuZXh0KSA9PiB7XG4gICAgICAgIGlmIChuZXh0KSB0aGlzLnN1Ym1pdEZsb3cuZW1pdChuZXh0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnN1Ym1pdEZsb3cuZW1pdCh0aGlzLnZhbHVlcyk7XG4gIH1cblxuICAvKiogVGhlIHNoYXJlZCBlbnJvbG1lbnQgc3RlcCBpcyBkcmF3biAoYSBjb250cm9sbGVyIHdhcyBwYXNzZWQgYW5kIHRoZSBmbG93IGlzIGVucm9sbGluZykuICovXG4gIHByb3RlY3RlZCBlbnJvbGxpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RlcCgpLmtpbmQgPT09ICdlbnJvbGxfc2Vjb25kX2ZhY3RvcicgJiYgISF0aGlzLmVucm9sbG1lbnQgJiYgISF0aGlzLmVucm9sbG1lbnRTdGF0ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjaG9vc2VNZXRob2QobWV0aG9kOiBNZmFFbnJvbGxtZW50U3RyYXRlZ3kpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlcyA9IHt9O1xuICAgIHZvaWQgdGhpcy5lbnJvbGxtZW50Py5jaG9vc2UobWV0aG9kKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXNlbmRFbnJvbGxtZW50KCk6IHZvaWQge1xuICAgIHZvaWQgdGhpcy5lbnJvbGxtZW50Py5yZXNlbmQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdGhlck1ldGhvZHMoc3RhdGU6IE1mYUVucm9sbG1lbnRTdGF0ZSk6IE1mYUVucm9sbG1lbnRTdHJhdGVneVtdIHtcbiAgICByZXR1cm4gc3RhdGUub3B0aW9ucy5maWx0ZXIoKG0pID0+IG0gIT09IHN0YXRlLm1ldGhvZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0dXBLZXkoc2VjcmV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBncm91cFNldHVwS2V5KHNlY3JldCk7XG4gIH1cblxuICAvKiogVGhlIHN1Ym1pdCBidXR0b24ncyBsYWJlbCBrZXkgKGVucm9sbWVudDogXCJUZXh0IG1lIGEgY29kZVwiIGJlZm9yZSB0aGUgbnVtYmVyIGlzIHNlbnQpLiAqL1xuICBwcm90ZWN0ZWQgc3VibWl0S2V5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICh0aGlzLmVucm9sbGluZygpICYmIHRoaXMuZW5yb2xsbWVudFN0YXRlICYmIGVucm9sbG1lbnRTdWJtaXRLZXkodGhpcy5lbnJvbGxtZW50U3RhdGUpKSB8fCAnc2lnbkluLnN1Ym1pdCc7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd1Ntc1NlY29uZEZhY3RvcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vZmZlclNtc1NlY29uZEZhY3RvciAmJiB0aGlzLnN0ZXAoKS5raW5kID09PSAnY29sbGVjdF9zZWNvbmRfZmFjdG9yJztcbiAgfVxuXG4gIC8qKiBXaGVyZSB0aGUgdGV4dGVkIHNlY29uZC1mYWN0b3IgY29kZSB3ZW50IChtYXNrZWQpLCBvbmNlIGl0IHdhcyBzZW50LiAqL1xuICBwcm90ZWN0ZWQgc21zU2Vjb25kRmFjdG9yU2VudFRvKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHNlbnQgPSB0aGlzLnRleHRlZFNlY29uZEZhY3Rvcj8uc2VudFRvO1xuICAgIHJldHVybiB0eXBlb2Ygc2VudCA9PT0gJ3N0cmluZycgPyBzZW50IHx8ICcgJyA6IG51bGw7XG4gIH1cblxuICBwcm90ZWN0ZWQgZm9ybUVycm9ycygpOiBGaWVsZEVycm9yW10ge1xuICAgIHJldHVybiB0aGlzLmVycm9ycy5maWx0ZXIoKGVycm9yKSA9PiAhZXJyb3IucGFyYW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGZpZWxkRXJyb3JzRm9yKG5hbWU6IHN0cmluZyk6IEZpZWxkRXJyb3JbXSB7XG4gICAgcmV0dXJuIHRoaXMuZXJyb3JzLmZpbHRlcigoZXJyb3IpID0+IGVycm9yLnBhcmFtID09PSBuYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5hdHRlbXB0ID8gbmV4dFN0ZXAodGhpcy5hdHRlbXB0KSA6ICh7IGtpbmQ6ICdjb2xsZWN0X2lkZW50aWZpZXInIH0gYXMgY29uc3QpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dDYXB0Y2hhKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGtpbmQgPSB0aGlzLnN0ZXAoKS5raW5kO1xuICAgIHJldHVybiAhIXRoaXMuY2FwdGNoYSAmJiAoa2luZCA9PT0gJ2NvbGxlY3RfaWRlbnRpZmllcicgfHwga2luZCA9PT0gJ2NvbGxlY3RfY2FwdGNoYScpO1xuICB9XG5cbiAgLyoqIFRoZSBmaXJzdCBmYWN0b3JzIG9uIG9mZmVyIGF0IGEgYG5lZWRzX2ZpcnN0X2ZhY3RvcmAgc3RlcCAoZW1wdHkgb24gYW55IG90aGVyKS4gKi9cbiAgcHJpdmF0ZSBvZmZlcmVkKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwKCk7XG4gICAgaWYgKHN0ZXAua2luZCAhPT0gJ2NvbGxlY3RfZmlyc3RfZmFjdG9yJykgcmV0dXJuIFtdO1xuICAgIHJldHVybiB0aGlzLmZpcnN0RmFjdG9ycyA/PyBzdGVwLnN0cmF0ZWdpZXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgbGlua09ubHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGF3YWl0aW5nU2lnblVwTGluayh0aGlzLmF0dGVtcHQsIHRoaXMuZW1haWxWZXJpZmljYXRpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dFbWFpbFNlY29uZEZhY3RvcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vZmZlckVtYWlsU2Vjb25kRmFjdG9yICYmIHRoaXMuc3RlcCgpLmtpbmQgPT09ICdjb2xsZWN0X3NlY29uZF9mYWN0b3InO1xuICB9XG5cbiAgLyoqIFdoZXJlIHRoZSBlbWFpbGVkIHNlY29uZC1mYWN0b3IgY29kZSB3ZW50IChtYXNrZWQpLCBvbmNlIGl0IHdhcyBzZW50LiAqL1xuICBwcm90ZWN0ZWQgZW1haWxTZWNvbmRGYWN0b3JTZW50VG8oKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3Qgc2VudCA9IHRoaXMuZW1haWxlZFNlY29uZEZhY3Rvcj8uc2VudFRvO1xuICAgIHJldHVybiB0eXBlb2Ygc2VudCA9PT0gJ3N0cmluZycgPyBzZW50IHx8ICcgJyA6IG51bGw7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0VtYWlsQ29kZU9wdGlvbigpOiBib29sZWFuIHtcbiAgICAvLyBCZWZvcmUgdGhlIGNvZGUgaXMgc2VudDogdGhlIGNob2ljZSAob3IgdGhlIHJldHJ5IG9mIGEgZmFpbGVkIGF1dG9tYXRpY1xuICAgIC8vIHNlbmQpLiBBZnRlcjogXCJSZXNlbmQgY29kZVwiLlxuICAgIHJldHVybiB0aGlzLm9mZmVyZWQoKS5pbmNsdWRlcygnZW1haWxfY29kZScpO1xuICB9XG5cbiAgLyoqIFRoZSBcIndlIHNlbnQgYSBjb2RlIHRvIOKAplwiIGxpbmUgb24gdGhlIGNvZGUgc3RlcC4gKi9cbiAgcHJvdGVjdGVkIGNvZGVTZW50VGV4dCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAodGhpcy5zdGVwKCkua2luZCAhPT0gJ2NvbGxlY3RfZmlyc3RfZmFjdG9yJyB8fCB0aGlzLnByZXBhcmVkRmFjdG9yICE9PSAnZW1haWxfY29kZScpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB0aGlzLnQoJ3NpZ25Jbi5jb2RlU2VudFRvJywgeyBlbWFpbDogdGhpcy5hdHRlbXB0Py5pZGVudGlmaWVyID8/ICcnIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dTdWJtaXQoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2luZCA9IHRoaXMuc3RlcCgpLmtpbmQ7XG4gICAgLy8gTm90aGluZyB0byBzdWJtaXQgb24gYSBmaXJzdC1mYWN0b3Igc3RlcCB0aGF0IG9ubHkgb2ZmZXJzIGFuIGVtYWlsZWQgY29kZVxuICAgIC8vIHVudGlsIHRoYXQgY29kZSBpcyBzZW50LlxuICAgIGlmIChraW5kID09PSAnY29sbGVjdF9maXJzdF9mYWN0b3InKSByZXR1cm4gdGhpcy5maWVsZHMoKS5sZW5ndGggPiAwO1xuICAgIGlmICh0aGlzLmxpbmtPbmx5KCkpIHJldHVybiBmYWxzZTtcbiAgICAvLyBFbnJvbG1lbnQ6IG5vdGhpbmcgdG8gc3VibWl0IHdoaWxlIGNob29zaW5nIGEgbWV0aG9kIG9yIGZldGNoaW5nIHRoZSBzZXR1cC5cbiAgICBpZiAodGhpcy5lbnJvbGxpbmcoKSAmJiB0aGlzLmVucm9sbG1lbnRTdGF0ZSAmJiAhZW5yb2xsbWVudFN1Ym1pdEtleSh0aGlzLmVucm9sbG1lbnRTdGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4ga2luZCAhPT0gJ2RvbmUnICYmIGtpbmQgIT09ICdhd2FpdF9vYXV0aCc7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmllbGRzKCk6IFN0ZXBGaWVsZFtdIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwKCk7XG4gICAgc3dpdGNoIChzdGVwLmtpbmQpIHtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfaWRlbnRpZmllcic6XG4gICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnaWRlbnRpZmllcicsIGxhYmVsS2V5OiAnc2lnbkluLmlkZW50aWZpZXJMYWJlbCcsIHR5cGU6ICdlbWFpbCcgfV07XG4gICAgICBjYXNlICdjb2xsZWN0X2ZpcnN0X2ZhY3Rvcic6IHtcbiAgICAgICAgaWYgKHRoaXMucHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJykge1xuICAgICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnc2lnbkluLmVtYWlsQ29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBwYXNzd29yZCBmaWVsZCB1bmxlc3MgdGhlIG9ubHkgb2ZmZXIgaXMgYW4gZW1haWxlZCBjb2RlIChjaG9zZW5cbiAgICAgICAgLy8gd2l0aCB0aGUgYnV0dG9uIGJlbG93IHRoZSBmb3JtKS5cbiAgICAgICAgY29uc3Qgb2ZmZXJlZCA9IHRoaXMub2ZmZXJlZCgpO1xuICAgICAgICByZXR1cm4gb2ZmZXJlZC5pbmNsdWRlcygnZW1haWxfY29kZScpICYmICFvZmZlcmVkLmluY2x1ZGVzKCdwYXNzd29yZCcpXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogW3sga2luZDogJ2lucHV0JywgbmFtZTogJ3Bhc3N3b3JkJywgbGFiZWxLZXk6ICdzaWduSW4ucGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICB9XG4gICAgICBjYXNlICdjb2xsZWN0X3NlY29uZF9mYWN0b3InOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ21mYS5jb2RlTGFiZWwnLCB0eXBlOiAndGV4dCcgfV07XG4gICAgICBjYXNlICdlbnJvbGxfc2Vjb25kX2ZhY3Rvcic6XG4gICAgICAgIC8vIFRoZSBzaGFyZWQgZW5yb2xtZW50IHN0ZXAgZHJhd3MgaXRzIG93biBmaWVsZHMgKGFib3ZlKS5cbiAgICAgICAgaWYgKHRoaXMuZW5yb2xsaW5nKCkpIHJldHVybiBbXTtcbiAgICAgICAgLy8gVHdvIGNvbnNlY3V0aXZlIGNvZGVzICjCpzUuNik6IGEgcGhvbmUgd2l0aCBhIGZhc3QgY2xvY2sgZmFpbHMgaGVyZVxuICAgICAgICAvLyByYXRoZXIgdGhhbiBvbiBldmVyeSBzaWduLWluIGFmdGVyd2FyZHMuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnbWZhLmVucm9sbEZpcnN0Q29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH0sXG4gICAgICAgICAgeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnc2Vjb25kQ29kZScsIGxhYmVsS2V5OiAnbWZhLmVucm9sbFNlY29uZENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9LFxuICAgICAgICBdO1xuICAgICAgY2FzZSAnY29sbGVjdF9lbWFpbF9jb2RlJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlua09ubHkoKSA/IFtdIDogW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ3NpZ25Jbi5lbWFpbENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfbmV3X3Bhc3N3b3JkJzpcbiAgICAgICAgcmV0dXJuIFt7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdwYXNzd29yZCcsIGxhYmVsS2V5OiAncmVzZXQubmV3UGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICBjYXNlICdjb2xsZWN0X2NhcHRjaGEnOlxuICAgICAgICAvLyDCpzUgdGhlIHNlcnZlciB3aXRoaGVsZCB0aGUgYXR0ZW1wdCB1bnRpbCBhIGNhcHRjaGEgY2xlYXJzLiBTb2x2aW5nIHRoZVxuICAgICAgICAvLyB3aWRnZXQgcmVzdWJtaXRzIHRoZSBpZGVudGlmaWVyIG9uIGl0cyBvd247IHRoZSBidXR0b24gcmV0cmllcy5cbiAgICAgICAgcmV0dXJuIFttc2coJ2NhcHRjaGEucHJvbXB0JyldO1xuICAgICAgY2FzZSAnYXdhaXRfb2F1dGgnOlxuICAgICAgICByZXR1cm4gW21zZygnc2lnbkluLm1hZ2ljTGlua1NlbnQnKV07XG4gICAgICBjYXNlICdkb25lJzpcbiAgICAgICAgLy8gU2lnbmVkIGluIG9ubHkgd2hlbiB0aGlzIGJyb3dzZXIgaG9sZHMgdGhlIHNlc3Npb247IGEgYmxvY2tlZCBjb29raWUgaXMgc2FpZFxuICAgICAgICAvLyBwbGFpbmx5LiBcIkNoZWNrIHRoZSBvdGhlciB0YWJcIiBpcyBmb3IgYSBzaWduLWluIGNvbXBsZXRlZCBvbiBhbm90aGVyIGRldmljZS5cbiAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbktlcHQgPT09IHRydWUpIHJldHVybiBbbXNnKCdzaWduSW4uc2lnbmVkSW4nKV07XG4gICAgICAgIGlmICh0aGlzLnNlc3Npb25LZXB0ID09PSBmYWxzZSkgcmV0dXJuIFt7IGtpbmQ6ICdhbGVydCcsIG5hbWU6ICcnLCBsYWJlbEtleTogJ3NpZ25Jbi5zZXNzaW9uTm90S2VwdCcsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICAgICAgcmV0dXJuIFttc2coJ3NpZ25Jbi5jaGVja090aGVyVGFiJyldO1xuICAgICAgY2FzZSAncmVzdGFydCc6XG4gICAgICAgIHJldHVybiBbbXNnKCdlcnJvci5nZW5lcmljJyldO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gQSBzdGF0dXMgdGhpcyBTREsgdmVyc2lvbiBkb2VzIG5vdCBrbm93LiBBbiBob25lc3QgbWVzc2FnZSBiZWF0cyBhXG4gICAgICAgIC8vIGJsYW5rIGxvZ2luIGJveCB0aGUgdXNlciBjYW5ub3QgYWN0IG9uLlxuICAgICAgICByZXR1cm4gW21zZygnZXJyb3IuZ2VuZXJpYycpXTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIEEgcmVhZC1vbmx5IG1lc3NhZ2Ugcm93OiBgbGFiZWxLZXlgIGhvbGRzIHRoZSBpMThuIGtleSBvZiB0aGUgdGV4dCB0byBzaG93LiAqL1xuZnVuY3Rpb24gbXNnKGxhYmVsS2V5OiBzdHJpbmcpOiBTdGVwRmllbGQge1xuICByZXR1cm4geyBraW5kOiAnbWVzc2FnZScsIG5hbWU6ICcnLCBsYWJlbEtleSwgdHlwZTogJ3RleHQnIH07XG59XG4iXX0=
|