@atlasauth/angular 0.8.0 → 0.10.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 +23 -0
- package/dist/esm2022/lib/appearance.mjs +1 -1
- package/dist/esm2022/lib/atlas.service.mjs +40 -3
- package/dist/esm2022/lib/atlas.ui.mjs +7 -1
- package/dist/esm2022/lib/components/attempt-flow.component.mjs +419 -11
- package/dist/esm2022/lib/components/flow-controller.mjs +132 -2
- 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/policy-host.mjs +254 -0
- package/dist/esm2022/lib/components/recovery-codes.component.mjs +122 -0
- package/dist/esm2022/lib/components/sign-in.component.mjs +47 -4
- package/dist/esm2022/lib/components/sign-up-form.component.mjs +136 -10
- package/dist/esm2022/lib/components/sign-up.component.mjs +86 -8
- package/dist/esm2022/lib/i18n.mjs +61 -1
- package/dist/esm2022/lib/provide-atlas.mjs +4 -2
- package/dist/esm2022/lib/types.mjs +1 -1
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/esm2022/public-api.mjs +6 -1
- package/dist/fesm2022/atlasauth-angular.mjs +2129 -95
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/appearance.d.ts +1 -1
- package/dist/lib/atlas.service.d.ts +23 -1
- package/dist/lib/atlas.ui.d.ts +3 -1
- package/dist/lib/components/attempt-flow.component.d.ts +61 -2
- package/dist/lib/components/flow-controller.d.ts +73 -1
- 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/policy-host.d.ts +88 -0
- package/dist/lib/components/recovery-codes.component.d.ts +26 -0
- package/dist/lib/components/sign-in.component.d.ts +2 -0
- package/dist/lib/components/sign-up-form.component.d.ts +22 -4
- package/dist/lib/components/sign-up.component.d.ts +13 -0
- package/dist/lib/provide-atlas.d.ts +3 -1
- package/dist/lib/types.d.ts +6 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/public-api.d.ts +5 -0
- package/package.json +3 -3
|
@@ -1,7 +1,8 @@
|
|
|
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
|
+
import { PolicyAcceptStepComponent } from './policy-host';
|
|
5
6
|
import { classFor } from '../appearance';
|
|
6
7
|
import { translate } from '../i18n';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
@@ -41,6 +42,40 @@ export class AttemptFlowComponent {
|
|
|
41
42
|
submitFlow = new EventEmitter();
|
|
42
43
|
/** Emits when the user picks a first factor the server must send first (an emailed code). */
|
|
43
44
|
chooseFactor = new EventEmitter();
|
|
45
|
+
/**
|
|
46
|
+
* Offer "Email me a code instead" at the second factor (the instance's
|
|
47
|
+
* `account.emailSecondFactor`); `emailSecondFactor` asks for it and
|
|
48
|
+
* `emailedSecondFactor` reports how it went.
|
|
49
|
+
*/
|
|
50
|
+
offerEmailSecondFactor = false;
|
|
51
|
+
/** `AtlasFlowController.emailSecondFactor()`: in flight, where it went, or why not. */
|
|
52
|
+
emailedSecondFactor = null;
|
|
53
|
+
emailSecondFactor = new EventEmitter();
|
|
54
|
+
/**
|
|
55
|
+
* Offer "Text me a code instead" at the second factor (where the app offers
|
|
56
|
+
* texted codes, `AtlasFlowController.mfaChoices().sms`); `smsSecondFactor`
|
|
57
|
+
* asks for it and `textedSecondFactor` reports how it went.
|
|
58
|
+
*/
|
|
59
|
+
offerSmsSecondFactor = false;
|
|
60
|
+
/** `AtlasFlowController.smsSecondFactor()`: in flight, where it went, or why not. */
|
|
61
|
+
textedSecondFactor = null;
|
|
62
|
+
smsSecondFactor = new EventEmitter();
|
|
63
|
+
/**
|
|
64
|
+
* The MFA enrolment step (`AtlasFlowController.enrollment` and
|
|
65
|
+
* `enrollmentState()`): the authenticator app's QR code and setup key, or a
|
|
66
|
+
* texted code. Null: the step asks for two authenticator codes only.
|
|
67
|
+
*/
|
|
68
|
+
enrollment = null;
|
|
69
|
+
enrollmentState = null;
|
|
70
|
+
/**
|
|
71
|
+
* The instance's `account.emailVerification`. On `link` a sign-up's
|
|
72
|
+
* verification step has nothing to type: it says to open the emailed link
|
|
73
|
+
* while the flow polls, and offers a resend (`resend`).
|
|
74
|
+
*/
|
|
75
|
+
emailVerification = 'code';
|
|
76
|
+
resend = new EventEmitter();
|
|
77
|
+
/** The user declined a policy the sign-in was waiting on (`needs_policy_acceptance`): cancel the attempt. */
|
|
78
|
+
policyDeclined = new EventEmitter();
|
|
44
79
|
values = {};
|
|
45
80
|
t(key, vars) {
|
|
46
81
|
return translate(this.atlas.localization, key, vars);
|
|
@@ -59,8 +94,45 @@ export class AttemptFlowComponent {
|
|
|
59
94
|
}
|
|
60
95
|
onSubmit(event) {
|
|
61
96
|
event.preventDefault();
|
|
97
|
+
// Enrolment: text the code to the typed number, or confirm the factor.
|
|
98
|
+
if (this.enrolling() && this.enrollment) {
|
|
99
|
+
void this.enrollment.submit(this.values).then((next) => {
|
|
100
|
+
if (next)
|
|
101
|
+
this.submitFlow.emit(next);
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
62
105
|
this.submitFlow.emit(this.values);
|
|
63
106
|
}
|
|
107
|
+
/** The shared enrolment step is drawn (a controller was passed and the flow is enrolling). */
|
|
108
|
+
enrolling() {
|
|
109
|
+
return this.step().kind === 'enroll_second_factor' && !!this.enrollment && !!this.enrollmentState;
|
|
110
|
+
}
|
|
111
|
+
chooseMethod(method) {
|
|
112
|
+
this.values = {};
|
|
113
|
+
void this.enrollment?.choose(method);
|
|
114
|
+
}
|
|
115
|
+
resendEnrollment() {
|
|
116
|
+
void this.enrollment?.resend();
|
|
117
|
+
}
|
|
118
|
+
otherMethods(state) {
|
|
119
|
+
return state.options.filter((m) => m !== state.method);
|
|
120
|
+
}
|
|
121
|
+
setupKey(secret) {
|
|
122
|
+
return groupSetupKey(secret);
|
|
123
|
+
}
|
|
124
|
+
/** The submit button's label key (enrolment: "Text me a code" before the number is sent). */
|
|
125
|
+
submitKey() {
|
|
126
|
+
return (this.enrolling() && this.enrollmentState && enrollmentSubmitKey(this.enrollmentState)) || 'signIn.submit';
|
|
127
|
+
}
|
|
128
|
+
showSmsSecondFactor() {
|
|
129
|
+
return this.offerSmsSecondFactor && this.step().kind === 'collect_second_factor';
|
|
130
|
+
}
|
|
131
|
+
/** Where the texted second-factor code went (masked), once it was sent. */
|
|
132
|
+
smsSecondFactorSentTo() {
|
|
133
|
+
const sent = this.textedSecondFactor?.sentTo;
|
|
134
|
+
return typeof sent === 'string' ? sent || ' ' : null;
|
|
135
|
+
}
|
|
64
136
|
formErrors() {
|
|
65
137
|
return this.errors.filter((error) => !error.param);
|
|
66
138
|
}
|
|
@@ -81,6 +153,17 @@ export class AttemptFlowComponent {
|
|
|
81
153
|
return [];
|
|
82
154
|
return this.firstFactors ?? step.strategies;
|
|
83
155
|
}
|
|
156
|
+
linkOnly() {
|
|
157
|
+
return awaitingSignUpLink(this.attempt, this.emailVerification);
|
|
158
|
+
}
|
|
159
|
+
showEmailSecondFactor() {
|
|
160
|
+
return this.offerEmailSecondFactor && this.step().kind === 'collect_second_factor';
|
|
161
|
+
}
|
|
162
|
+
/** Where the emailed second-factor code went (masked), once it was sent. */
|
|
163
|
+
emailSecondFactorSentTo() {
|
|
164
|
+
const sent = this.emailedSecondFactor?.sentTo;
|
|
165
|
+
return typeof sent === 'string' ? sent || ' ' : null;
|
|
166
|
+
}
|
|
84
167
|
showEmailCodeOption() {
|
|
85
168
|
// Before the code is sent: the choice (or the retry of a failed automatic
|
|
86
169
|
// send). After: "Resend code".
|
|
@@ -92,13 +175,22 @@ export class AttemptFlowComponent {
|
|
|
92
175
|
return null;
|
|
93
176
|
return this.t('signIn.codeSentTo', { email: this.attempt?.identifier ?? '' });
|
|
94
177
|
}
|
|
178
|
+
/** The attempt is `needs_policy_acceptance`. */
|
|
179
|
+
awaitingPolicies() {
|
|
180
|
+
return this.step().kind === 'accept_policies';
|
|
181
|
+
}
|
|
95
182
|
showSubmit() {
|
|
96
183
|
const kind = this.step().kind;
|
|
97
184
|
// Nothing to submit on a first-factor step that only offers an emailed code
|
|
98
185
|
// until that code is sent.
|
|
99
186
|
if (kind === 'collect_first_factor')
|
|
100
187
|
return this.fields().length > 0;
|
|
101
|
-
|
|
188
|
+
if (this.linkOnly())
|
|
189
|
+
return false;
|
|
190
|
+
// Enrolment: nothing to submit while choosing a method or fetching the setup.
|
|
191
|
+
if (this.enrolling() && this.enrollmentState && !enrollmentSubmitKey(this.enrollmentState))
|
|
192
|
+
return false;
|
|
193
|
+
return kind !== 'done' && kind !== 'await_oauth' && kind !== 'accept_policies';
|
|
102
194
|
}
|
|
103
195
|
fields() {
|
|
104
196
|
const step = this.step();
|
|
@@ -119,6 +211,9 @@ export class AttemptFlowComponent {
|
|
|
119
211
|
case 'collect_second_factor':
|
|
120
212
|
return [{ kind: 'input', name: 'code', labelKey: 'mfa.codeLabel', type: 'text' }];
|
|
121
213
|
case 'enroll_second_factor':
|
|
214
|
+
// The shared enrolment step draws its own fields (above).
|
|
215
|
+
if (this.enrolling())
|
|
216
|
+
return [];
|
|
122
217
|
// Two consecutive codes (§5.6): a phone with a fast clock fails here
|
|
123
218
|
// rather than on every sign-in afterwards.
|
|
124
219
|
return [
|
|
@@ -126,9 +221,12 @@ export class AttemptFlowComponent {
|
|
|
126
221
|
{ kind: 'input', name: 'secondCode', labelKey: 'mfa.enrollSecondCodeLabel', type: 'text' },
|
|
127
222
|
];
|
|
128
223
|
case 'collect_email_code':
|
|
129
|
-
return [{ kind: 'input', name: 'code', labelKey: 'signIn.emailCodeLabel', type: 'text' }];
|
|
224
|
+
return this.linkOnly() ? [] : [{ kind: 'input', name: 'code', labelKey: 'signIn.emailCodeLabel', type: 'text' }];
|
|
130
225
|
case 'collect_new_password':
|
|
131
226
|
return [{ kind: 'input', name: 'password', labelKey: 'reset.newPasswordLabel', type: 'password' }];
|
|
227
|
+
case 'accept_policies':
|
|
228
|
+
// Drawn by <atlas-policy-accept-step> above.
|
|
229
|
+
return [];
|
|
132
230
|
case 'collect_captcha':
|
|
133
231
|
// §5 the server withheld the attempt until a captcha clears. Solving the
|
|
134
232
|
// widget resubmits the identifier on its own; the button retries.
|
|
@@ -152,7 +250,7 @@ export class AttemptFlowComponent {
|
|
|
152
250
|
}
|
|
153
251
|
}
|
|
154
252
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
155
|
-
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" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor" }, ngImport: i0, template: `
|
|
253
|
+
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", policyDeclined: "policyDeclined" }, ngImport: i0, template: `
|
|
156
254
|
<div [class]="cls('card', 'atlas-card')">
|
|
157
255
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
158
256
|
|
|
@@ -164,6 +262,98 @@ export class AttemptFlowComponent {
|
|
|
164
262
|
@if (codeSentText(); as sentText) {
|
|
165
263
|
<p class="atlas-text" data-atlas-code-sent="">{{ sentText }}</p>
|
|
166
264
|
}
|
|
265
|
+
@if (linkOnly()) {
|
|
266
|
+
<!-- Nothing to type: the flow polls until the emailed link is opened (anywhere). -->
|
|
267
|
+
<p class="atlas-text" data-atlas-link-sent="" aria-live="polite">
|
|
268
|
+
{{ t('signUp.linkSentTo', { email: attempt?.identifier ?? '' }) }}
|
|
269
|
+
</p>
|
|
270
|
+
<button
|
|
271
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
272
|
+
type="button"
|
|
273
|
+
data-atlas-resend=""
|
|
274
|
+
[disabled]="busy"
|
|
275
|
+
(click)="resend.emit()"
|
|
276
|
+
>
|
|
277
|
+
{{ t('signIn.resendLink') }}
|
|
278
|
+
</button>
|
|
279
|
+
}
|
|
280
|
+
@if (enrolling() && enrollmentState; as enrol) {
|
|
281
|
+
@if (enrol.method === null) {
|
|
282
|
+
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
283
|
+
@for (m of enrol.options; track m) {
|
|
284
|
+
<button
|
|
285
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
286
|
+
type="button"
|
|
287
|
+
[attr.data-atlas-mfa-method]="m"
|
|
288
|
+
[disabled]="busy || enrol.busy"
|
|
289
|
+
(click)="chooseMethod(m)"
|
|
290
|
+
>
|
|
291
|
+
{{ t(m === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
292
|
+
</button>
|
|
293
|
+
}
|
|
294
|
+
} @else if (enrol.method === 'totp') {
|
|
295
|
+
@if (enrol.enrollment; as setup) {
|
|
296
|
+
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
297
|
+
@if (setup.qrCode) {
|
|
298
|
+
<img class="atlas-mfa-qr" data-atlas="mfa-qr" [src]="setup.qrCode" [alt]="t('mfa.enrollQrAlt')" width="180" height="180" />
|
|
299
|
+
}
|
|
300
|
+
@if (setup.secret) {
|
|
301
|
+
<p class="atlas-text" data-atlas="mfa-setup-key">{{ t('mfa.enrollSetupKey') }}: <code>{{ setupKey(setup.secret) }}</code></p>
|
|
302
|
+
}
|
|
303
|
+
<label class="atlas-field">
|
|
304
|
+
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
305
|
+
<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)" />
|
|
306
|
+
</label>
|
|
307
|
+
@if (enrol.totpCodes >= 2) {
|
|
308
|
+
<label class="atlas-field">
|
|
309
|
+
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
310
|
+
<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)" />
|
|
311
|
+
</label>
|
|
312
|
+
}
|
|
313
|
+
} @else {
|
|
314
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
315
|
+
}
|
|
316
|
+
} @else {
|
|
317
|
+
@if (enrol.enrollment; as texted) {
|
|
318
|
+
<p class="atlas-text" data-atlas="mfa-code-texted" aria-live="polite">{{ t('mfa.codeTextedTo', { phone: texted.phone ?? '' }) }}</p>
|
|
319
|
+
<label class="atlas-field">
|
|
320
|
+
<span>{{ t('mfa.codeLabel') }}</span>
|
|
321
|
+
<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)" />
|
|
322
|
+
</label>
|
|
323
|
+
<button
|
|
324
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
325
|
+
type="button"
|
|
326
|
+
data-atlas-resend=""
|
|
327
|
+
[disabled]="busy || enrol.busy"
|
|
328
|
+
(click)="resendEnrollment()"
|
|
329
|
+
>
|
|
330
|
+
{{ t('signIn.resendCode') }}
|
|
331
|
+
</button>
|
|
332
|
+
} @else {
|
|
333
|
+
<label class="atlas-field">
|
|
334
|
+
<span>{{ t('mfa.phoneLabel') }}</span>
|
|
335
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="tel" name="phone" autocomplete="tel" [value]="values['phone'] ?? ''" (input)="setValue('phone', $any($event.target).value)" />
|
|
336
|
+
</label>
|
|
337
|
+
<p class="atlas-text">{{ t('mfa.phoneHint') }}</p>
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
@for (error of enrol.errors; track $index) {
|
|
341
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ error.message }}</p>
|
|
342
|
+
}
|
|
343
|
+
@if (enrol.method !== null && enrol.options.length > 1) {
|
|
344
|
+
@for (other of otherMethods(enrol); track other) {
|
|
345
|
+
<button
|
|
346
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
347
|
+
type="button"
|
|
348
|
+
[attr.data-atlas-mfa-method]="other"
|
|
349
|
+
[disabled]="busy || enrol.busy"
|
|
350
|
+
(click)="chooseMethod(other)"
|
|
351
|
+
>
|
|
352
|
+
{{ t(other === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
353
|
+
</button>
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
167
357
|
@for (f of fields(); track $index) {
|
|
168
358
|
@if (f.kind === 'input') {
|
|
169
359
|
<label class="atlas-field">
|
|
@@ -186,16 +376,68 @@ export class AttemptFlowComponent {
|
|
|
186
376
|
}
|
|
187
377
|
}
|
|
188
378
|
|
|
379
|
+
@if (awaitingPolicies()) {
|
|
380
|
+
<!-- A required policy changed: scroll-mode ones in their dialog, the rest as checkboxes. -->
|
|
381
|
+
<atlas-policy-accept-step
|
|
382
|
+
[attempt]="attempt"
|
|
383
|
+
[busy]="busy"
|
|
384
|
+
(submitFlow)="submitFlow.emit($event)"
|
|
385
|
+
(declined)="policyDeclined.emit($event)"
|
|
386
|
+
></atlas-policy-accept-step>
|
|
387
|
+
}
|
|
388
|
+
|
|
189
389
|
@if (showCaptcha()) {
|
|
190
390
|
<div class="atlas-captcha" data-atlas-captcha="" [atlasCaptchaSlot]="captcha"></div>
|
|
191
391
|
}
|
|
192
392
|
|
|
193
393
|
@if (showSubmit()) {
|
|
194
|
-
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy" type="submit">
|
|
195
|
-
{{ t(
|
|
394
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy || (enrolling() && !!enrollmentState?.busy)" type="submit">
|
|
395
|
+
{{ t(submitKey()) }}
|
|
196
396
|
</button>
|
|
197
397
|
}
|
|
198
398
|
|
|
399
|
+
@if (showSmsSecondFactor()) {
|
|
400
|
+
@if (smsSecondFactorSentTo(); as sentTo) {
|
|
401
|
+
<p class="atlas-text" data-atlas="sms-second-factor-sent" aria-live="polite">
|
|
402
|
+
{{ t('mfa.codeTextedTo', { phone: sentTo }) }}
|
|
403
|
+
</p>
|
|
404
|
+
} @else {
|
|
405
|
+
<button
|
|
406
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
407
|
+
type="button"
|
|
408
|
+
data-atlas="sms-second-factor"
|
|
409
|
+
[disabled]="busy || !!textedSecondFactor?.busy"
|
|
410
|
+
(click)="smsSecondFactor.emit()"
|
|
411
|
+
>
|
|
412
|
+
{{ textedSecondFactor?.busy ? t('signIn.sending') : t('mfa.smsCodeOption') }}
|
|
413
|
+
</button>
|
|
414
|
+
@if (textedSecondFactor?.error; as message) {
|
|
415
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
@if (showEmailSecondFactor()) {
|
|
421
|
+
@if (emailSecondFactorSentTo(); as sentTo) {
|
|
422
|
+
<p class="atlas-text" data-atlas="email-second-factor-sent" aria-live="polite">
|
|
423
|
+
{{ t('signIn.codeSentTo', { email: sentTo }) }}
|
|
424
|
+
</p>
|
|
425
|
+
} @else {
|
|
426
|
+
<button
|
|
427
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
428
|
+
type="button"
|
|
429
|
+
data-atlas="email-second-factor"
|
|
430
|
+
[disabled]="busy || !!emailedSecondFactor?.busy"
|
|
431
|
+
(click)="emailSecondFactor.emit()"
|
|
432
|
+
>
|
|
433
|
+
{{ emailedSecondFactor?.busy ? t('signIn.sending') : t('signIn.emailCodeOption') }}
|
|
434
|
+
</button>
|
|
435
|
+
@if (emailedSecondFactor?.error; as message) {
|
|
436
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
199
441
|
@if (showEmailCodeOption()) {
|
|
200
442
|
<button
|
|
201
443
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -210,7 +452,7 @@ export class AttemptFlowComponent {
|
|
|
210
452
|
}
|
|
211
453
|
</form>
|
|
212
454
|
</div>
|
|
213
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: AtlasCaptchaSlotDirective, selector: "[atlasCaptchaSlot]", inputs: ["atlasCaptchaSlot"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
455
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: AtlasCaptchaSlotDirective, selector: "[atlasCaptchaSlot]", inputs: ["atlasCaptchaSlot"] }, { kind: "component", type: PolicyAcceptStepComponent, selector: "atlas-policy-accept-step", inputs: ["attempt", "busy"], outputs: ["submitFlow", "declined"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
214
456
|
}
|
|
215
457
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, decorators: [{
|
|
216
458
|
type: Component,
|
|
@@ -218,7 +460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
218
460
|
selector: 'atlas-attempt-flow',
|
|
219
461
|
standalone: true,
|
|
220
462
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
221
|
-
imports: [AtlasCaptchaSlotDirective],
|
|
463
|
+
imports: [AtlasCaptchaSlotDirective, PolicyAcceptStepComponent],
|
|
222
464
|
template: `
|
|
223
465
|
<div [class]="cls('card', 'atlas-card')">
|
|
224
466
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
@@ -231,6 +473,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
231
473
|
@if (codeSentText(); as sentText) {
|
|
232
474
|
<p class="atlas-text" data-atlas-code-sent="">{{ sentText }}</p>
|
|
233
475
|
}
|
|
476
|
+
@if (linkOnly()) {
|
|
477
|
+
<!-- Nothing to type: the flow polls until the emailed link is opened (anywhere). -->
|
|
478
|
+
<p class="atlas-text" data-atlas-link-sent="" aria-live="polite">
|
|
479
|
+
{{ t('signUp.linkSentTo', { email: attempt?.identifier ?? '' }) }}
|
|
480
|
+
</p>
|
|
481
|
+
<button
|
|
482
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
483
|
+
type="button"
|
|
484
|
+
data-atlas-resend=""
|
|
485
|
+
[disabled]="busy"
|
|
486
|
+
(click)="resend.emit()"
|
|
487
|
+
>
|
|
488
|
+
{{ t('signIn.resendLink') }}
|
|
489
|
+
</button>
|
|
490
|
+
}
|
|
491
|
+
@if (enrolling() && enrollmentState; as enrol) {
|
|
492
|
+
@if (enrol.method === null) {
|
|
493
|
+
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
494
|
+
@for (m of enrol.options; track m) {
|
|
495
|
+
<button
|
|
496
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
497
|
+
type="button"
|
|
498
|
+
[attr.data-atlas-mfa-method]="m"
|
|
499
|
+
[disabled]="busy || enrol.busy"
|
|
500
|
+
(click)="chooseMethod(m)"
|
|
501
|
+
>
|
|
502
|
+
{{ t(m === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
503
|
+
</button>
|
|
504
|
+
}
|
|
505
|
+
} @else if (enrol.method === 'totp') {
|
|
506
|
+
@if (enrol.enrollment; as setup) {
|
|
507
|
+
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
508
|
+
@if (setup.qrCode) {
|
|
509
|
+
<img class="atlas-mfa-qr" data-atlas="mfa-qr" [src]="setup.qrCode" [alt]="t('mfa.enrollQrAlt')" width="180" height="180" />
|
|
510
|
+
}
|
|
511
|
+
@if (setup.secret) {
|
|
512
|
+
<p class="atlas-text" data-atlas="mfa-setup-key">{{ t('mfa.enrollSetupKey') }}: <code>{{ setupKey(setup.secret) }}</code></p>
|
|
513
|
+
}
|
|
514
|
+
<label class="atlas-field">
|
|
515
|
+
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
516
|
+
<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)" />
|
|
517
|
+
</label>
|
|
518
|
+
@if (enrol.totpCodes >= 2) {
|
|
519
|
+
<label class="atlas-field">
|
|
520
|
+
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
521
|
+
<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)" />
|
|
522
|
+
</label>
|
|
523
|
+
}
|
|
524
|
+
} @else {
|
|
525
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
526
|
+
}
|
|
527
|
+
} @else {
|
|
528
|
+
@if (enrol.enrollment; as texted) {
|
|
529
|
+
<p class="atlas-text" data-atlas="mfa-code-texted" aria-live="polite">{{ t('mfa.codeTextedTo', { phone: texted.phone ?? '' }) }}</p>
|
|
530
|
+
<label class="atlas-field">
|
|
531
|
+
<span>{{ t('mfa.codeLabel') }}</span>
|
|
532
|
+
<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)" />
|
|
533
|
+
</label>
|
|
534
|
+
<button
|
|
535
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
536
|
+
type="button"
|
|
537
|
+
data-atlas-resend=""
|
|
538
|
+
[disabled]="busy || enrol.busy"
|
|
539
|
+
(click)="resendEnrollment()"
|
|
540
|
+
>
|
|
541
|
+
{{ t('signIn.resendCode') }}
|
|
542
|
+
</button>
|
|
543
|
+
} @else {
|
|
544
|
+
<label class="atlas-field">
|
|
545
|
+
<span>{{ t('mfa.phoneLabel') }}</span>
|
|
546
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="tel" name="phone" autocomplete="tel" [value]="values['phone'] ?? ''" (input)="setValue('phone', $any($event.target).value)" />
|
|
547
|
+
</label>
|
|
548
|
+
<p class="atlas-text">{{ t('mfa.phoneHint') }}</p>
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
@for (error of enrol.errors; track $index) {
|
|
552
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ error.message }}</p>
|
|
553
|
+
}
|
|
554
|
+
@if (enrol.method !== null && enrol.options.length > 1) {
|
|
555
|
+
@for (other of otherMethods(enrol); track other) {
|
|
556
|
+
<button
|
|
557
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
558
|
+
type="button"
|
|
559
|
+
[attr.data-atlas-mfa-method]="other"
|
|
560
|
+
[disabled]="busy || enrol.busy"
|
|
561
|
+
(click)="chooseMethod(other)"
|
|
562
|
+
>
|
|
563
|
+
{{ t(other === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }}
|
|
564
|
+
</button>
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
234
568
|
@for (f of fields(); track $index) {
|
|
235
569
|
@if (f.kind === 'input') {
|
|
236
570
|
<label class="atlas-field">
|
|
@@ -253,16 +587,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
253
587
|
}
|
|
254
588
|
}
|
|
255
589
|
|
|
590
|
+
@if (awaitingPolicies()) {
|
|
591
|
+
<!-- A required policy changed: scroll-mode ones in their dialog, the rest as checkboxes. -->
|
|
592
|
+
<atlas-policy-accept-step
|
|
593
|
+
[attempt]="attempt"
|
|
594
|
+
[busy]="busy"
|
|
595
|
+
(submitFlow)="submitFlow.emit($event)"
|
|
596
|
+
(declined)="policyDeclined.emit($event)"
|
|
597
|
+
></atlas-policy-accept-step>
|
|
598
|
+
}
|
|
599
|
+
|
|
256
600
|
@if (showCaptcha()) {
|
|
257
601
|
<div class="atlas-captcha" data-atlas-captcha="" [atlasCaptchaSlot]="captcha"></div>
|
|
258
602
|
}
|
|
259
603
|
|
|
260
604
|
@if (showSubmit()) {
|
|
261
|
-
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy" type="submit">
|
|
262
|
-
{{ t(
|
|
605
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" [disabled]="busy || (enrolling() && !!enrollmentState?.busy)" type="submit">
|
|
606
|
+
{{ t(submitKey()) }}
|
|
263
607
|
</button>
|
|
264
608
|
}
|
|
265
609
|
|
|
610
|
+
@if (showSmsSecondFactor()) {
|
|
611
|
+
@if (smsSecondFactorSentTo(); as sentTo) {
|
|
612
|
+
<p class="atlas-text" data-atlas="sms-second-factor-sent" aria-live="polite">
|
|
613
|
+
{{ t('mfa.codeTextedTo', { phone: sentTo }) }}
|
|
614
|
+
</p>
|
|
615
|
+
} @else {
|
|
616
|
+
<button
|
|
617
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
618
|
+
type="button"
|
|
619
|
+
data-atlas="sms-second-factor"
|
|
620
|
+
[disabled]="busy || !!textedSecondFactor?.busy"
|
|
621
|
+
(click)="smsSecondFactor.emit()"
|
|
622
|
+
>
|
|
623
|
+
{{ textedSecondFactor?.busy ? t('signIn.sending') : t('mfa.smsCodeOption') }}
|
|
624
|
+
</button>
|
|
625
|
+
@if (textedSecondFactor?.error; as message) {
|
|
626
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@if (showEmailSecondFactor()) {
|
|
632
|
+
@if (emailSecondFactorSentTo(); as sentTo) {
|
|
633
|
+
<p class="atlas-text" data-atlas="email-second-factor-sent" aria-live="polite">
|
|
634
|
+
{{ t('signIn.codeSentTo', { email: sentTo }) }}
|
|
635
|
+
</p>
|
|
636
|
+
} @else {
|
|
637
|
+
<button
|
|
638
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
639
|
+
type="button"
|
|
640
|
+
data-atlas="email-second-factor"
|
|
641
|
+
[disabled]="busy || !!emailedSecondFactor?.busy"
|
|
642
|
+
(click)="emailSecondFactor.emit()"
|
|
643
|
+
>
|
|
644
|
+
{{ emailedSecondFactor?.busy ? t('signIn.sending') : t('signIn.emailCodeOption') }}
|
|
645
|
+
</button>
|
|
646
|
+
@if (emailedSecondFactor?.error; as message) {
|
|
647
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ message }}</p>
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
266
652
|
@if (showEmailCodeOption()) {
|
|
267
653
|
<button
|
|
268
654
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -299,9 +685,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
299
685
|
type: Output
|
|
300
686
|
}], chooseFactor: [{
|
|
301
687
|
type: Output
|
|
688
|
+
}], offerEmailSecondFactor: [{
|
|
689
|
+
type: Input
|
|
690
|
+
}], emailedSecondFactor: [{
|
|
691
|
+
type: Input
|
|
692
|
+
}], emailSecondFactor: [{
|
|
693
|
+
type: Output
|
|
694
|
+
}], offerSmsSecondFactor: [{
|
|
695
|
+
type: Input
|
|
696
|
+
}], textedSecondFactor: [{
|
|
697
|
+
type: Input
|
|
698
|
+
}], smsSecondFactor: [{
|
|
699
|
+
type: Output
|
|
700
|
+
}], enrollment: [{
|
|
701
|
+
type: Input
|
|
702
|
+
}], enrollmentState: [{
|
|
703
|
+
type: Input
|
|
704
|
+
}], emailVerification: [{
|
|
705
|
+
type: Input
|
|
706
|
+
}], resend: [{
|
|
707
|
+
type: Output
|
|
708
|
+
}], policyDeclined: [{
|
|
709
|
+
type: Output
|
|
302
710
|
}] } });
|
|
303
711
|
/** A read-only message row: `labelKey` holds the i18n key of the text to show. */
|
|
304
712
|
function msg(labelKey) {
|
|
305
713
|
return { kind: 'message', name: '', labelKey, type: 'text' };
|
|
306
714
|
}
|
|
307
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdC1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hdHRlbXB0LWZsb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLFFBQVEsR0FJVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDakYsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFlcEM7Ozs7Ozs7OztHQVNHO0FBa0VILE1BQU0sT0FBTyxvQkFBb0I7SUFDZCxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJDLE9BQU8sR0FBdUIsSUFBSSxDQUFDO0lBQ25DLElBQUksR0FBRyxLQUFLLENBQUM7SUFDYixNQUFNLEdBQWlCLEVBQUUsQ0FBQztJQUNuQywwRkFBMEY7SUFDakYsV0FBVyxHQUF3QixTQUFTLENBQUM7SUFDN0MsUUFBUSxHQUFHLGNBQWMsQ0FBQztJQUNuQzs7OztPQUlHO0lBQ00sT0FBTyxHQUE2QixJQUFJLENBQUM7SUFDbEQ7Ozs7T0FJRztJQUNNLFlBQVksR0FBb0IsSUFBSSxDQUFDO0lBQzlDLHFHQUFxRztJQUM1RixjQUFjLEdBQWtCLElBQUksQ0FBQztJQUU5QyxtRUFBbUU7SUFDekQsVUFBVSxHQUFHLElBQUksWUFBWSxFQUEwQixDQUFDO0lBQ2xFLDZGQUE2RjtJQUNuRixZQUFZLEdB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S0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFNRyxPQUFPO3NCQUFmLEtBQUs7Z0JBTUcsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUdJLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsWUFBWTtzQkFBckIsTUFBTTs7QUEySFQsa0ZBQWtGO0FBQ2xGLFNBQVMsR0FBRyxDQUFDLFFBQWdCO0lBQzNCLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUMvRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgbG9jYWxpemVkRXJyb3JNZXNzYWdlLFxuICBuZXh0U3RlcCxcbiAgdHlwZSBBdHRlbXB0VmlldyxcbiAgdHlwZSBDYXB0Y2hhQ29udHJvbGxlcixcbiAgdHlwZSBGaWVsZEVycm9yLFxufSBmcm9tICdAYXRsYXNhdXRoL2pzJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXRsYXNDYXB0Y2hhU2xvdERpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvY2FwdGNoYS1zbG90LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBjbGFzc0ZvciwgdHlwZSBFbGVtZW50S2V5IH0gZnJvbSAnLi4vYXBwZWFyYW5jZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcblxuLyoqXG4gKiBPbmUgcmVuZGVyZWQgcm93IG9mIHRoZSBmbG93LiBBIHVuaWZvcm0gc2hhcGUgKHJhdGhlciB0aGFuIGEgZGlzY3JpbWluYXRlZFxuICogdW5pb24pIHNvIHRoZSB0ZW1wbGF0ZSBhY2Nlc3NlcyBvbmx5IGZpZWxkcyB0aGF0IGFsd2F5cyBleGlzdCDigJQgbm8gcmVsaWFuY2Ugb25cbiAqIHRlbXBsYXRlIGNvbnRyb2wtZmxvdyBuYXJyb3dpbmcgb2YgYSBsb29wIHZhcmlhYmxlLCB3aGljaCB2YXJpZXMgYnkgQW5ndWxhclxuICogbWlub3IuIEZvciBhIGBtZXNzYWdlYCByb3csIGBsYWJlbEtleWAgY2FycmllcyB0aGUgbWVzc2FnZSdzIGkxOG4ga2V5LlxuICovXG5pbnRlcmZhY2UgU3RlcEZpZWxkIHtcbiAga2luZDogJ2lucHV0JyB8ICdtZXNzYWdlJyB8ICdhbGVydCc7XG4gIG5hbWU6IHN0cmluZztcbiAgbGFiZWxLZXk6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBzZXJ2ZXItZHJpdmVuIGZsb3cgc2hlbGwsIHNoYXJlZCBieSBgPGF0bGFzLXNpZ24taW4+YCBhbmRcbiAqIGA8YXRsYXMtc2lnbi11cD5gLiBUaGUgQW5ndWxhciBwZWVyIG9mIFJlYWN0J3MgaW50ZXJuYWwgYEF0dGVtcHRGbG93YC5cbiAqXG4gKiBJdCBjb250YWlucyBOTyBkZWNpc2lvbiBhYm91dCB3aGF0IGNvbWVzIG5leHQ6IGl0IHJlbmRlcnMgd2hhdGV2ZXIgYHN0YXR1c2BcbiAqIHRoZSBzZXJ2ZXIgcmV0dXJuZWQsIG1hcHBlZCB0aHJvdWdoIGBuZXh0U3RlcGAgZnJvbSBgQGF0bGFzYXV0aC9qc2AgKHRoZSBzYW1lXG4gKiBleGhhdXN0aXZlIG1hcHBpbmcgdGhlIFJlYWN0IFNESyB1c2VzKSwgc28gYWRkaW5nIGEgc3RlcCBpcyBhIHNlcnZlciBjaGFuZ2VcbiAqIGFuZCBhbiBvdXQtb2YtZGF0ZSBjbGllbnQgZGVncmFkZXMgdG8gYSB2aXNpYmxlIFwicGxlYXNlIHVwZGF0ZVwiIG1lc3NhZ2UgcmF0aGVyXG4gKiB0aGFuIGEgYmxhbmsgc2NyZWVuLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1hdHRlbXB0LWZsb3cnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0bGFzQ2FwdGNoYVNsb3REaXJlY3RpdmVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNscygnY2FyZCcsICdhdGxhcy1jYXJkJylcIj5cbiAgICAgIDxoMSBbY2xhc3NdPVwiY2xzKCdoZWFkZXJUaXRsZScsICdhdGxhcy10aXRsZScpXCI+e3sgdCh0aXRsZUtleSkgfX08L2gxPlxuXG4gICAgICBAZm9yIChlcnJvciBvZiBmb3JtRXJyb3JzKCk7IHRyYWNrIGVycm9yLmNvZGUpIHtcbiAgICAgICAgPHAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiIHJvbGU9XCJhbGVydFwiPnt7IGVycm9yVGV4dChlcnJvcikgfX08L3A+XG4gICAgICB9XG5cbiAgICAgIDxmb3JtIChzdWJtaXQpPVwib25TdWJtaXQoJGV2ZW50KVwiPlxuICAgICAgICBAaWYgKGNvZGVTZW50VGV4dCgpOyBhcyBzZW50VGV4dCkge1xuICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXMtY29kZS1zZW50PVwiXCI+e3sgc2VudFRleHQgfX08L3A+XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoZiBvZiBmaWVsZHMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgQGlmIChmLmtpbmQgPT09ICdpbnB1dCcpIHtcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImF0bGFzLWZpZWxkXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IHQoZi5sYWJlbEtleSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIlxuICAgICAgICAgICAgICAgIFt0eXBlXT1cImYudHlwZVwiXG4gICAgICAgICAgICAgICAgW2F0dHIubmFtZV09XCJmLm5hbWVcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJ2YWx1ZXNbZi5uYW1lXSA/PyAnJ1wiXG4gICAgICAgICAgICAgICAgKGlucHV0KT1cInNldFZhbHVlKGYubmFtZSwgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICBAZm9yIChlcnJvciBvZiBmaWVsZEVycm9yc0ZvcihmLm5hbWUpOyB0cmFjayBlcnJvci5jb2RlKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiPnt7IGVycm9yVGV4dChlcnJvcikgfX08L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgfSBAZWxzZSBpZiAoZi5raW5kID09PSAnYWxlcnQnKSB7XG4gICAgICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgdChmLmxhYmVsS2V5KSB9fTwvcD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxwPnt7IHQoZi5sYWJlbEtleSkgfX08L3A+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93Q2FwdGNoYSgpKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImF0bGFzLWNhcHRjaGFcIiBkYXRhLWF0bGFzLWNhcHRjaGE9XCJcIiBbYXRsYXNDYXB0Y2hhU2xvdF09XCJjYXB0Y2hhXCI+PC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dTdWJtaXQoKSkge1xuICAgICAgICAgIDxidXR0b24gW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblByaW1hcnknLCAnYXRsYXMtYnV0dG9uJylcIiBbZGlzYWJsZWRdPVwiYnVzeVwiIHR5cGU9XCJzdWJtaXRcIj5cbiAgICAgICAgICAgIHt7IHQoJ3NpZ25Jbi5zdWJtaXQnKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93RW1haWxDb2RlT3B0aW9uKCkpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtc3RyYXRlZ3ldPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/IG51bGwgOiAnZW1haWxfY29kZSdcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1hdGxhcy1yZXNlbmRdPVwicHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJyA/ICcnIDogbnVsbFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlRmFjdG9yLmVtaXQoJ2VtYWlsX2NvZGUnKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgdChwcmVwYXJlZEZhY3RvciA9PT0gJ2VtYWlsX2NvZGUnID8gJ3NpZ25Jbi5yZXNlbmRDb2RlJyA6ICdzaWduSW4udXNlRW1haWxDb2RlJykgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBBdHRlbXB0Rmxvd0NvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXRsYXMgPSBpbmplY3QoQXRsYXNTZXJ2aWNlKTtcblxuICBASW5wdXQoKSBhdHRlbXB0OiBBdHRlbXB0VmlldyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBidXN5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVycm9yczogRmllbGRFcnJvcltdID0gW107XG4gIC8qKiBgRmxvd1N0YXRlLnNlc3Npb25LZXB0YDogd2hldGhlciB0aGlzIGJyb3dzZXIga2VwdCB0aGUgc2Vzc2lvbiB0aGUgc2lnbi1pbiBjcmVhdGVkLiAqL1xuICBASW5wdXQoKSBzZXNzaW9uS2VwdDogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgdGl0bGVLZXkgPSAnc2lnbkluLnRpdGxlJztcbiAgLyoqXG4gICAqIFRoZSBzaWduLWluIGNhcHRjaGEsIGRyYXduIGFib3ZlIHRoZSBzdWJtaXQgYnV0dG9uIG9uIHRoZSBpZGVudGlmaWVyIHN0ZXBcbiAgICogKGFuIGFsd2F5cy1vbiBzaWduLWluIGNhcHRjaGEpIGFuZCBvbiB0aGUgY2hhbGxlbmdlIHN0ZXAgdGhlIHNlcnZlciBkZW1hbmRzXG4gICAqIHdpdGggYG5lZWRzX2NhcHRjaGFgLiBOdWxsIHdoZW4gdGhlIGZsb3cgZHJhd3Mgbm9uZS5cbiAgICovXG4gIEBJbnB1dCgpIGNhcHRjaGE6IENhcHRjaGFDb250cm9sbGVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBUaGUgZmlyc3QgZmFjdG9ycyB0byBvZmZlciBvbiB0aGUgYG5lZWRzX2ZpcnN0X2ZhY3RvcmAgc3RlcCDigJQgcGFzc1xuICAgKiBgQXRsYXNGbG93Q29udHJvbGxlci5maXJzdEZhY3RvcnMoKWAsIHdoaWNoIGRyb3BzIGVtYWlsIGNvZGUgLyBsaW5rIHdoaWxlIHRoZVxuICAgKiBhcHAgY2Fubm90IGRlbGl2ZXIgZW1haWwuIE51bGwgdXNlcyB0aGUgc2VydmVyJ3MgbGlzdCBhcy1pcy5cbiAgICovXG4gIEBJbnB1dCgpIGZpcnN0RmFjdG9yczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSBmaXJzdCBmYWN0b3IgYWxyZWFkeSBzZW50IChgQXRsYXNGbG93Q29udHJvbGxlci5wcmVwYXJlZEZhY3RvcigpYCk6IGl0cyBjb2RlIGlzIGNvbGxlY3RlZC4gKi9cbiAgQElucHV0KCkgcHJlcGFyZWRGYWN0b3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBFbWl0cyB0aGUgY29sbGVjdGVkIGZpZWxkIHZhbHVlcyB3aGVuIHRoZSBmb3JtIGlzIHN1Ym1pdHRlZC4gKi9cbiAgQE91dHB1dCgpIHN1Ym1pdEZsb3cgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KCk7XG4gIC8qKiBFbWl0cyB3aGVuIHRoZSB1c2VyIHBpY2tzIGEgZmlyc3QgZmFjdG9yIHRoZSBzZXJ2ZXIgbXVzdCBzZW5kIGZpcnN0IChhbiBlbWFpbGVkIGNvZGUpLiAqL1xuICBAT3V0cHV0KCkgY2hvb3NlRmFjdG9yID0gbmV3IEV2ZW50RW1pdHRlcjwnZW1haWxfY29kZSc+KCk7XG5cbiAgcHJvdGVjdGVkIHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gIHByb3RlY3RlZCB0KGtleTogc3RyaW5nLCB2YXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRyYW5zbGF0ZSh0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwga2V5LCB2YXJzKTtcbiAgfVxuXG4gIC8qKiBBIHNlcnZlciBlcnJvciBpbiB0aGUgYXBwJ3MgbGFuZ3VhZ2UgKGBlcnJvci48cmVhc29uPmAsIGVsc2UgdGhlIHNlcnZlcidzIG1lc3NhZ2UpLiAqL1xuICBwcm90ZWN0ZWQgZXJyb3JUZXh0KGVycm9yOiBGaWVsZEVycm9yKTogc3RyaW5nIHtcbiAgICAvLyBgZXJyb3JMb2NhbGl6YXRpb25gIGlzIHJlYWQgZGVmZW5zaXZlbHk6IGEgc3RhbmQtaW4gc2VydmljZSBtYXkgbGFjayBpdC5cbiAgICBjb25zdCBsYXllciA9ICh0aGlzLmF0bGFzIGFzIHsgZXJyb3JMb2NhbGl6YXRpb24/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IH0pLmVycm9yTG9jYWxpemF0aW9uO1xuICAgIHJldHVybiBsb2NhbGl6ZWRFcnJvck1lc3NhZ2UoZXJyb3IsIGxheWVyID8/IHRoaXMuYXRsYXMubG9jYWxpemF0aW9uLCB0aGlzLmF0bGFzLmxvY2FsaXphdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xzKGtleTogRWxlbWVudEtleSwgYmFzZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY2xhc3NGb3Ioa2V5LCB0aGlzLmF0bGFzLmFwcGVhcmFuY2UsIGJhc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldFZhbHVlKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudmFsdWVzID0geyAuLi50aGlzLnZhbHVlcywgW25hbWVdOiB2YWx1ZSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uU3VibWl0KGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zdWJtaXRGbG93LmVtaXQodGhpcy52YWx1ZXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGZvcm1FcnJvcnMoKTogRmllbGRFcnJvcltdIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcnMuZmlsdGVyKChlcnJvcikgPT4gIWVycm9yLnBhcmFtKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBmaWVsZEVycm9yc0ZvcihuYW1lOiBzdHJpbmcpOiBGaWVsZEVycm9yW10ge1xuICAgIHJldHVybiB0aGlzLmVycm9ycy5maWx0ZXIoKGVycm9yKSA9PiBlcnJvci5wYXJhbSA9PT0gbmFtZSk7XG4gIH1cblxuICBwcml2YXRlIHN0ZXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXR0ZW1wdCA/IG5leHRTdGVwKHRoaXMuYXR0ZW1wdCkgOiAoeyBraW5kOiAnY29sbGVjdF9pZGVudGlmaWVyJyB9IGFzIGNvbnN0KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93Q2FwdGNoYSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBraW5kID0gdGhpcy5zdGVwKCkua2luZDtcbiAgICByZXR1cm4gISF0aGlzLmNhcHRjaGEgJiYgKGtpbmQgPT09ICdjb2xsZWN0X2lkZW50aWZpZXInIHx8IGtpbmQgPT09ICdjb2xsZWN0X2NhcHRjaGEnKTtcbiAgfVxuXG4gIC8qKiBUaGUgZmlyc3QgZmFjdG9ycyBvbiBvZmZlciBhdCBhIGBuZWVkc19maXJzdF9mYWN0b3JgIHN0ZXAgKGVtcHR5IG9uIGFueSBvdGhlcikuICovXG4gIHByaXZhdGUgb2ZmZXJlZCgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgc3RlcCA9IHRoaXMuc3RlcCgpO1xuICAgIGlmIChzdGVwLmtpbmQgIT09ICdjb2xsZWN0X2ZpcnN0X2ZhY3RvcicpIHJldHVybiBbXTtcbiAgICByZXR1cm4gdGhpcy5maXJzdEZhY3RvcnMgPz8gc3RlcC5zdHJhdGVnaWVzO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dFbWFpbENvZGVPcHRpb24oKTogYm9vbGVhbiB7XG4gICAgLy8gQmVmb3JlIHRoZSBjb2RlIGlzIHNlbnQ6IHRoZSBjaG9pY2UgKG9yIHRoZSByZXRyeSBvZiBhIGZhaWxlZCBhdXRvbWF0aWNcbiAgICAvLyBzZW5kKS4gQWZ0ZXI6IFwiUmVzZW5kIGNvZGVcIi5cbiAgICByZXR1cm4gdGhpcy5vZmZlcmVkKCkuaW5jbHVkZXMoJ2VtYWlsX2NvZGUnKTtcbiAgfVxuXG4gIC8qKiBUaGUgXCJ3ZSBzZW50IGEgY29kZSB0byDigKZcIiBsaW5lIG9uIHRoZSBjb2RlIHN0ZXAuICovXG4gIHByb3RlY3RlZCBjb2RlU2VudFRleHQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuc3RlcCgpLmtpbmQgIT09ICdjb2xsZWN0X2ZpcnN0X2ZhY3RvcicgfHwgdGhpcy5wcmVwYXJlZEZhY3RvciAhPT0gJ2VtYWlsX2NvZGUnKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gdGhpcy50KCdzaWduSW4uY29kZVNlbnRUbycsIHsgZW1haWw6IHRoaXMuYXR0ZW1wdD8uaWRlbnRpZmllciA/PyAnJyB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93U3VibWl0KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGtpbmQgPSB0aGlzLnN0ZXAoKS5raW5kO1xuICAgIC8vIE5vdGhpbmcgdG8gc3VibWl0IG9uIGEgZmlyc3QtZmFjdG9yIHN0ZXAgdGhhdCBvbmx5IG9mZmVycyBhbiBlbWFpbGVkIGNvZGVcbiAgICAvLyB1bnRpbCB0aGF0IGNvZGUgaXMgc2VudC5cbiAgICBpZiAoa2luZCA9PT0gJ2NvbGxlY3RfZmlyc3RfZmFjdG9yJykgcmV0dXJuIHRoaXMuZmllbGRzKCkubGVuZ3RoID4gMDtcbiAgICByZXR1cm4ga2luZCAhPT0gJ2RvbmUnICYmIGtpbmQgIT09ICdhd2FpdF9vYXV0aCc7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmllbGRzKCk6IFN0ZXBGaWVsZFtdIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwKCk7XG4gICAgc3dpdGNoIChzdGVwLmtpbmQpIHtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfaWRlbnRpZmllcic6XG4gICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnaWRlbnRpZmllcicsIGxhYmVsS2V5OiAnc2lnbkluLmlkZW50aWZpZXJMYWJlbCcsIHR5cGU6ICdlbWFpbCcgfV07XG4gICAgICBjYXNlICdjb2xsZWN0X2ZpcnN0X2ZhY3Rvcic6IHtcbiAgICAgICAgaWYgKHRoaXMucHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJykge1xuICAgICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnc2lnbkluLmVtYWlsQ29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBwYXNzd29yZCBmaWVsZCB1bmxlc3MgdGhlIG9ubHkgb2ZmZXIgaXMgYW4gZW1haWxlZCBjb2RlIChjaG9zZW5cbiAgICAgICAgLy8gd2l0aCB0aGUgYnV0dG9uIGJlbG93IHRoZSBmb3JtKS5cbiAgICAgICAgY29uc3Qgb2ZmZXJlZCA9IHRoaXMub2ZmZXJlZCgpO1xuICAgICAgICByZXR1cm4gb2ZmZXJlZC5pbmNsdWRlcygnZW1haWxfY29kZScpICYmICFvZmZlcmVkLmluY2x1ZGVzKCdwYXNzd29yZCcpXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogW3sga2luZDogJ2lucHV0JywgbmFtZTogJ3Bhc3N3b3JkJywgbGFiZWxLZXk6ICdzaWduSW4ucGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICB9XG4gICAgICBjYXNlICdjb2xsZWN0X3NlY29uZF9mYWN0b3InOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ21mYS5jb2RlTGFiZWwnLCB0eXBlOiAndGV4dCcgfV07XG4gICAgICBjYXNlICdlbnJvbGxfc2Vjb25kX2ZhY3Rvcic6XG4gICAgICAgIC8vIFR3byBjb25zZWN1dGl2ZSBjb2RlcyAowqc1LjYpOiBhIHBob25lIHdpdGggYSBmYXN0IGNsb2NrIGZhaWxzIGhlcmVcbiAgICAgICAgLy8gcmF0aGVyIHRoYW4gb24gZXZlcnkgc2lnbi1pbiBhZnRlcndhcmRzLlxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHsga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ21mYS5lbnJvbGxGaXJzdENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9LFxuICAgICAgICAgIHsga2luZDogJ2lucHV0JywgbmFtZTogJ3NlY29uZENvZGUnLCBsYWJlbEtleTogJ21mYS5lbnJvbGxTZWNvbmRDb2RlTGFiZWwnLCB0eXBlOiAndGV4dCcgfSxcbiAgICAgICAgXTtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfZW1haWxfY29kZSc6XG4gICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnc2lnbkluLmVtYWlsQ29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgY2FzZSAnY29sbGVjdF9uZXdfcGFzc3dvcmQnOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ3Bhc3N3b3JkJywgbGFiZWxLZXk6ICdyZXNldC5uZXdQYXNzd29yZExhYmVsJywgdHlwZTogJ3Bhc3N3b3JkJyB9XTtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfY2FwdGNoYSc6XG4gICAgICAgIC8vIMKnNSB0aGUgc2VydmVyIHdpdGhoZWxkIHRoZSBhdHRlbXB0IHVudGlsIGEgY2FwdGNoYSBjbGVhcnMuIFNvbHZpbmcgdGhlXG4gICAgICAgIC8vIHdpZGdldCByZXN1Ym1pdHMgdGhlIGlkZW50aWZpZXIgb24gaXRzIG93bjsgdGhlIGJ1dHRvbiByZXRyaWVzLlxuICAgICAgICByZXR1cm4gW21zZygnY2FwdGNoYS5wcm9tcHQnKV07XG4gICAgICBjYXNlICdhd2FpdF9vYXV0aCc6XG4gICAgICAgIHJldHVybiBbbXNnKCdzaWduSW4ubWFnaWNMaW5rU2VudCcpXTtcbiAgICAgIGNhc2UgJ2RvbmUnOlxuICAgICAgICAvLyBTaWduZWQgaW4gb25seSB3aGVuIHRoaXMgYnJvd3NlciBob2xkcyB0aGUgc2Vzc2lvbjsgYSBibG9ja2VkIGNvb2tpZSBpcyBzYWlkXG4gICAgICAgIC8vIHBsYWlubHkuIFwiQ2hlY2sgdGhlIG90aGVyIHRhYlwiIGlzIGZvciBhIHNpZ24taW4gY29tcGxldGVkIG9uIGFub3RoZXIgZGV2aWNlLlxuICAgICAgICBpZiAodGhpcy5zZXNzaW9uS2VwdCA9PT0gdHJ1ZSkgcmV0dXJuIFttc2coJ3NpZ25Jbi5zaWduZWRJbicpXTtcbiAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbktlcHQgPT09IGZhbHNlKSByZXR1cm4gW3sga2luZDogJ2FsZXJ0JywgbmFtZTogJycsIGxhYmVsS2V5OiAnc2lnbkluLnNlc3Npb25Ob3RLZXB0JywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgICByZXR1cm4gW21zZygnc2lnbkluLmNoZWNrT3RoZXJUYWInKV07XG4gICAgICBjYXNlICdyZXN0YXJ0JzpcbiAgICAgICAgcmV0dXJuIFttc2coJ2Vycm9yLmdlbmVyaWMnKV07XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBBIHN0YXR1cyB0aGlzIFNESyB2ZXJzaW9uIGRvZXMgbm90IGtub3cuIEFuIGhvbmVzdCBtZXNzYWdlIGJlYXRzIGFcbiAgICAgICAgLy8gYmxhbmsgbG9naW4gYm94IHRoZSB1c2VyIGNhbm5vdCBhY3Qgb24uXG4gICAgICAgIHJldHVybiBbbXNnKCdlcnJvci5nZW5lcmljJyldO1xuICAgIH1cbiAgfVxufVxuXG4vKiogQSByZWFkLW9ubHkgbWVzc2FnZSByb3c6IGBsYWJlbEtleWAgaG9sZHMgdGhlIGkxOG4ga2V5IG9mIHRoZSB0ZXh0IHRvIHNob3cuICovXG5mdW5jdGlvbiBtc2cobGFiZWxLZXk6IHN0cmluZyk6IFN0ZXBGaWVsZCB7XG4gIHJldHVybiB7IGtpbmQ6ICdtZXNzYWdlJywgbmFtZTogJycsIGxhYmVsS2V5LCB0eXBlOiAndGV4dCcgfTtcbn1cbiJdfQ==
|
|
715
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdC1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hdHRlbXB0LWZsb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQixhQUFhLEVBQ2IscUJBQXFCLEVBQ3JCLFFBQVEsR0FPVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDakYsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxRQUFRLEVBQW1CLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7O0FBZXBDOzs7Ozs7Ozs7R0FTRztBQWtOSCxNQUFNLE9BQU8sb0JBQW9CO0lBQ2QsS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUVyQyxPQUFPLEdBQXVCLElBQUksQ0FBQztJQUNuQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0lBQ2IsTUFBTSxHQUFpQixFQUFFLENBQUM7SUFDbkMsMEZBQTBGO0lBQ2pGLFdBQVcsR0FBd0IsU0FBUyxDQUFDO0lBQzdDLFFBQVEsR0FBRyxjQUFjLENBQUM7SUFDbkM7Ozs7T0FJRztJQUNNLE9BQU8sR0FBNkIsSUFBSSxDQUFDO0lBQ2xEOzs7O09BSUc7SUFDTSxZQUFZLEdBQW9CLElBQUksQ0FBQztJQUM5QyxxR0FBcUc7SUFDNUYsY0FBYyxHQUFrQixJQUFJLENB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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBNVDtpQkFDRjs4QkFJVSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsT0FBTztzQkFBZixLQUFLO2dCQU1HLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUcsY0FBYztzQkFBdEIsS0FBSztnQkFHSSxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLFlBQVk7c0JBQXJCLE1BQU07Z0JBTUUsc0JBQXNCO3NCQUE5QixLQUFLO2dCQUVHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBTUUsb0JBQW9CO3NCQUE1QixLQUFLO2dCQUVHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDSSxlQUFlO3NCQUF4QixNQUFNO2dCQU1FLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFNRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0ksTUFBTTtzQkFBZixNQUFNO2dCQUVHLGNBQWM7c0JBQXZCLE1BQU07O0FBa01ULGtGQUFrRjtBQUNsRixTQUFTLEdBQUcsQ0FBQyxRQUFnQjtJQUMzQixPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDL0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIGF3YWl0aW5nU2lnblVwTGluayxcbiAgZW5yb2xsbWVudFN1Ym1pdEtleSxcbiAgZ3JvdXBTZXR1cEtleSxcbiAgbG9jYWxpemVkRXJyb3JNZXNzYWdlLFxuICBuZXh0U3RlcCxcbiAgdHlwZSBBdHRlbXB0VmlldyxcbiAgdHlwZSBDYXB0Y2hhQ29udHJvbGxlcixcbiAgdHlwZSBGaWVsZEVycm9yLFxuICB0eXBlIE1mYUVucm9sbG1lbnRDb250cm9sbGVyLFxuICB0eXBlIE1mYUVucm9sbG1lbnRTdGF0ZSxcbiAgdHlwZSBNZmFFbnJvbGxtZW50U3RyYXRlZ3ksXG59IGZyb20gJ0BhdGxhc2F1dGgvanMnO1xuaW1wb3J0IHsgQXRsYXNTZXJ2aWNlIH0gZnJvbSAnLi4vYXRsYXMuc2VydmljZSc7XG5pbXBvcnQgeyBBdGxhc0NhcHRjaGFTbG90RGlyZWN0aXZlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9jYXB0Y2hhLXNsb3QuZGlyZWN0aXZlJztcbmltcG9ydCB7IFBvbGljeUFjY2VwdFN0ZXBDb21wb25lbnQgfSBmcm9tICcuL3BvbGljeS1ob3N0JztcbmltcG9ydCB7IGNsYXNzRm9yLCB0eXBlIEVsZW1lbnRLZXkgfSBmcm9tICcuLi9hcHBlYXJhbmNlJztcbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uL2kxOG4nO1xuXG4vKipcbiAqIE9uZSByZW5kZXJlZCByb3cgb2YgdGhlIGZsb3cuIEEgdW5pZm9ybSBzaGFwZSAocmF0aGVyIHRoYW4gYSBkaXNjcmltaW5hdGVkXG4gKiB1bmlvbikgc28gdGhlIHRlbXBsYXRlIGFjY2Vzc2VzIG9ubHkgZmllbGRzIHRoYXQgYWx3YXlzIGV4aXN0IOKAlCBubyByZWxpYW5jZSBvblxuICogdGVtcGxhdGUgY29udHJvbC1mbG93IG5hcnJvd2luZyBvZiBhIGxvb3AgdmFyaWFibGUsIHdoaWNoIHZhcmllcyBieSBBbmd1bGFyXG4gKiBtaW5vci4gRm9yIGEgYG1lc3NhZ2VgIHJvdywgYGxhYmVsS2V5YCBjYXJyaWVzIHRoZSBtZXNzYWdlJ3MgaTE4biBrZXkuXG4gKi9cbmludGVyZmFjZSBTdGVwRmllbGQge1xuICBraW5kOiAnaW5wdXQnIHwgJ21lc3NhZ2UnIHwgJ2FsZXJ0JztcbiAgbmFtZTogc3RyaW5nO1xuICBsYWJlbEtleTogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHNlcnZlci1kcml2ZW4gZmxvdyBzaGVsbCwgc2hhcmVkIGJ5IGA8YXRsYXMtc2lnbi1pbj5gIGFuZFxuICogYDxhdGxhcy1zaWduLXVwPmAuIFRoZSBBbmd1bGFyIHBlZXIgb2YgUmVhY3QncyBpbnRlcm5hbCBgQXR0ZW1wdEZsb3dgLlxuICpcbiAqIEl0IGNvbnRhaW5zIE5PIGRlY2lzaW9uIGFib3V0IHdoYXQgY29tZXMgbmV4dDogaXQgcmVuZGVycyB3aGF0ZXZlciBgc3RhdHVzYFxuICogdGhlIHNlcnZlciByZXR1cm5lZCwgbWFwcGVkIHRocm91Z2ggYG5leHRTdGVwYCBmcm9tIGBAYXRsYXNhdXRoL2pzYCAodGhlIHNhbWVcbiAqIGV4aGF1c3RpdmUgbWFwcGluZyB0aGUgUmVhY3QgU0RLIHVzZXMpLCBzbyBhZGRpbmcgYSBzdGVwIGlzIGEgc2VydmVyIGNoYW5nZVxuICogYW5kIGFuIG91dC1vZi1kYXRlIGNsaWVudCBkZWdyYWRlcyB0byBhIHZpc2libGUgXCJwbGVhc2UgdXBkYXRlXCIgbWVzc2FnZSByYXRoZXJcbiAqIHRoYW4gYSBibGFuayBzY3JlZW4uXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLWF0dGVtcHQtZmxvdycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQXRsYXNDYXB0Y2hhU2xvdERpcmVjdGl2ZSwgUG9saWN5QWNjZXB0U3RlcENvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY2xzKCdjYXJkJywgJ2F0bGFzLWNhcmQnKVwiPlxuICAgICAgPGgxIFtjbGFzc109XCJjbHMoJ2hlYWRlclRpdGxlJywgJ2F0bGFzLXRpdGxlJylcIj57eyB0KHRpdGxlS2V5KSB9fTwvaDE+XG5cbiAgICAgIEBmb3IgKGVycm9yIG9mIGZvcm1FcnJvcnMoKTsgdHJhY2sgZXJyb3IuY29kZSkge1xuICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgZXJyb3JUZXh0KGVycm9yKSB9fTwvcD5cbiAgICAgIH1cblxuICAgICAgPGZvcm0gKHN1Ym1pdCk9XCJvblN1Ym1pdCgkZXZlbnQpXCI+XG4gICAgICAgIEBpZiAoY29kZVNlbnRUZXh0KCk7IGFzIHNlbnRUZXh0KSB7XG4gICAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCIgZGF0YS1hdGxhcy1jb2RlLXNlbnQ9XCJcIj57eyBzZW50VGV4dCB9fTwvcD5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGxpbmtPbmx5KCkpIHtcbiAgICAgICAgICA8IS0tIE5vdGhpbmcgdG8gdHlwZTogdGhlIGZsb3cgcG9sbHMgdW50aWwgdGhlIGVtYWlsZWQgbGluayBpcyBvcGVuZWQgKGFueXdoZXJlKS4gLS0+XG4gICAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCIgZGF0YS1hdGxhcy1saW5rLXNlbnQ9XCJcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj5cbiAgICAgICAgICAgIHt7IHQoJ3NpZ25VcC5saW5rU2VudFRvJywgeyBlbWFpbDogYXR0ZW1wdD8uaWRlbnRpZmllciA/PyAnJyB9KSB9fVxuICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGRhdGEtYXRsYXMtcmVzZW5kPVwiXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJidXN5XCJcbiAgICAgICAgICAgIChjbGljayk9XCJyZXNlbmQuZW1pdCgpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyB0KCdzaWduSW4ucmVzZW5kTGluaycpIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChlbnJvbGxpbmcoKSAmJiBlbnJvbGxtZW50U3RhdGU7IGFzIGVucm9sKSB7XG4gICAgICAgICAgQGlmIChlbnJvbC5tZXRob2QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiPnt7IHQoJ21mYS5lbnJvbGxDaG9vc2UnKSB9fTwvcD5cbiAgICAgICAgICAgIEBmb3IgKG0gb2YgZW5yb2wub3B0aW9uczsgdHJhY2sgbSkge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblNlY29uZGFyeScsICdhdGxhcy1idXR0b24tc2Vjb25kYXJ5JylcIlxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtYXRsYXMtbWZhLW1ldGhvZF09XCJtXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeSB8fCBlbnJvbC5idXN5XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlTWV0aG9kKG0pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IHQobSA9PT0gJ3RvdHAnID8gJ21mYS5lbnJvbGxUb3RwT3B0aW9uJyA6ICdtZmEuZW5yb2xsU21zT3B0aW9uJykgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBAZWxzZSBpZiAoZW5yb2wubWV0aG9kID09PSAndG90cCcpIHtcbiAgICAgICAgICAgIEBpZiAoZW5yb2wuZW5yb2xsbWVudDsgYXMgc2V0dXApIHtcbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCI+e3sgdCgnbWZhLmVucm9sbFNjYW4nKSB9fTwvcD5cbiAgICAgICAgICAgICAgQGlmIChzZXR1cC5xckNvZGUpIHtcbiAgICAgICAgICAgICAgICA8aW1nIGNsYXNzPVwiYXRsYXMtbWZhLXFyXCIgZGF0YS1hdGxhcz1cIm1mYS1xclwiIFtzcmNdPVwic2V0dXAucXJDb2RlXCIgW2FsdF09XCJ0KCdtZmEuZW5yb2xsUXJBbHQnKVwiIHdpZHRoPVwiMTgwXCIgaGVpZ2h0PVwiMTgwXCIgLz5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBAaWYgKHNldHVwLnNlY3JldCkge1xuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXM9XCJtZmEtc2V0dXAta2V5XCI+e3sgdCgnbWZhLmVucm9sbFNldHVwS2V5JykgfX06IDxjb2RlPnt7IHNldHVwS2V5KHNldHVwLnNlY3JldCkgfX08L2NvZGU+PC9wPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImF0bGFzLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgdCgnbWZhLmVucm9sbEZpcnN0Q29kZUxhYmVsJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJjb2RlXCIgYXV0b2NvbXBsZXRlPVwib25lLXRpbWUtY29kZVwiIGlucHV0bW9kZT1cIm51bWVyaWNcIiBbdmFsdWVdPVwidmFsdWVzWydjb2RlJ10gPz8gJydcIiAoaW5wdXQpPVwic2V0VmFsdWUoJ2NvZGUnLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiIC8+XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIEBpZiAoZW5yb2wudG90cENvZGVzID49IDIpIHtcbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJhdGxhcy1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgdCgnbWZhLmVucm9sbFNlY29uZENvZGVMYWJlbCcpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZElucHV0JywgJ2F0bGFzLWlucHV0JylcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJzZWNvbmRDb2RlXCIgYXV0b2NvbXBsZXRlPVwib25lLXRpbWUtY29kZVwiIGlucHV0bW9kZT1cIm51bWVyaWNcIiBbdmFsdWVdPVwidmFsdWVzWydzZWNvbmRDb2RlJ10gPz8gJydcIiAoaW5wdXQpPVwic2V0VmFsdWUoJ3NlY29uZENvZGUnLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiIC8+XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGFyaWEtbGl2ZT1cInBvbGl0ZVwiPnt7IGVucm9sLmJ1c3kgPyB0KCdtZmEuZW5yb2xsUHJlcGFyaW5nJykgOiAnJyB9fTwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIEBpZiAoZW5yb2wuZW5yb2xsbWVudDsgYXMgdGV4dGVkKSB7XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXM9XCJtZmEtY29kZS10ZXh0ZWRcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj57eyB0KCdtZmEuY29kZVRleHRlZFRvJywgeyBwaG9uZTogdGV4dGVkLnBob25lID8/ICcnIH0pIH19PC9wPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJhdGxhcy1maWVsZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IHQoJ21mYS5jb2RlTGFiZWwnKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkSW5wdXQnLCAnYXRsYXMtaW5wdXQnKVwiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cImNvZGVcIiBhdXRvY29tcGxldGU9XCJvbmUtdGltZS1jb2RlXCIgaW5wdXRtb2RlPVwibnVtZXJpY1wiIFt2YWx1ZV09XCJ2YWx1ZXNbJ2NvZGUnXSA/PyAnJ1wiIChpbnB1dCk9XCJzZXRWYWx1ZSgnY29kZScsICRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCIgLz5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBkYXRhLWF0bGFzLXJlc2VuZD1cIlwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3kgfHwgZW5yb2wuYnVzeVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlc2VuZEVucm9sbG1lbnQoKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyB0KCdzaWduSW4ucmVzZW5kQ29kZScpIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImF0bGFzLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgdCgnbWZhLnBob25lTGFiZWwnKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkSW5wdXQnLCAnYXRsYXMtaW5wdXQnKVwiIHR5cGU9XCJ0ZWxcIiBuYW1lPVwicGhvbmVcIiBhdXRvY29tcGxldGU9XCJ0ZWxcIiBbdmFsdWVdPVwidmFsdWVzWydwaG9uZSddID8/ICcnXCIgKGlucHV0KT1cInNldFZhbHVlKCdwaG9uZScsICRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCIgLz5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCI+e3sgdCgnbWZhLnBob25lSGludCcpIH19PC9wPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBAZm9yIChlcnJvciBvZiBlbnJvbC5lcnJvcnM7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgPHAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkRXJyb3InLCAnYXRsYXMtZXJyb3InKVwiIHJvbGU9XCJhbGVydFwiPnt7IGVycm9yLm1lc3NhZ2UgfX08L3A+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBpZiAoZW5yb2wubWV0aG9kICE9PSBudWxsICYmIGVucm9sLm9wdGlvbnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgQGZvciAob3RoZXIgb2Ygb3RoZXJNZXRob2RzKGVucm9sKTsgdHJhY2sgb3RoZXIpIHtcbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLWF0bGFzLW1mYS1tZXRob2RdPVwib3RoZXJcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJidXN5IHx8IGVucm9sLmJ1c3lcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJjaG9vc2VNZXRob2Qob3RoZXIpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IHQob3RoZXIgPT09ICd0b3RwJyA/ICdtZmEuZW5yb2xsVG90cE9wdGlvbicgOiAnbWZhLmVucm9sbFNtc09wdGlvbicpIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChmIG9mIGZpZWxkcygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICBAaWYgKGYua2luZCA9PT0gJ2lucHV0Jykge1xuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYXRsYXMtZmllbGRcIj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgdChmLmxhYmVsS2V5KSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUZpZWxkSW5wdXQnLCAnYXRsYXMtaW5wdXQnKVwiXG4gICAgICAgICAgICAgICAgW3R5cGVdPVwiZi50eXBlXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5uYW1lXT1cImYubmFtZVwiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cInZhbHVlc1tmLm5hbWVdID8/ICcnXCJcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwic2V0VmFsdWUoZi5uYW1lLCAkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIEBmb3IgKGVycm9yIG9mIGZpZWxkRXJyb3JzRm9yKGYubmFtZSk7IHRyYWNrIGVycm9yLmNvZGUpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCI+e3sgZXJyb3JUZXh0KGVycm9yKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICB9IEBlbHNlIGlmIChmLmtpbmQgPT09ICdhbGVydCcpIHtcbiAgICAgICAgICAgIDxwIFtjbGFzc109XCJjbHMoJ2Zvcm1GaWVsZEVycm9yJywgJ2F0bGFzLWVycm9yJylcIiByb2xlPVwiYWxlcnRcIj57eyB0KGYubGFiZWxLZXkpIH19PC9wPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPHA+e3sgdChmLmxhYmVsS2V5KSB9fTwvcD5cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKGF3YWl0aW5nUG9saWNpZXMoKSkge1xuICAgICAgICAgIDwhLS0gQSByZXF1aXJlZCBwb2xpY3kgY2hhbmdlZDogc2Nyb2xsLW1vZGUgb25lcyBpbiB0aGVpciBkaWFsb2csIHRoZSByZXN0IGFzIGNoZWNrYm94ZXMuIC0tPlxuICAgICAgICAgIDxhdGxhcy1wb2xpY3ktYWNjZXB0LXN0ZXBcbiAgICAgICAgICAgIFthdHRlbXB0XT1cImF0dGVtcHRcIlxuICAgICAgICAgICAgW2J1c3ldPVwiYnVzeVwiXG4gICAgICAgICAgICAoc3VibWl0Rmxvdyk9XCJzdWJtaXRGbG93LmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAoZGVjbGluZWQpPVwicG9saWN5RGVjbGluZWQuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICA+PC9hdGxhcy1wb2xpY3ktYWNjZXB0LXN0ZXA+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dDYXB0Y2hhKCkpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXRsYXMtY2FwdGNoYVwiIGRhdGEtYXRsYXMtY2FwdGNoYT1cIlwiIFthdGxhc0NhcHRjaGFTbG90XT1cImNhcHRjaGFcIj48L2Rpdj5cbiAgICAgICAgfVxuXG4gICAgICAgIEBpZiAoc2hvd1N1Ym1pdCgpKSB7XG4gICAgICAgICAgPGJ1dHRvbiBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uUHJpbWFyeScsICdhdGxhcy1idXR0b24nKVwiIFtkaXNhYmxlZF09XCJidXN5IHx8IChlbnJvbGxpbmcoKSAmJiAhIWVucm9sbG1lbnRTdGF0ZT8uYnVzeSlcIiB0eXBlPVwic3VibWl0XCI+XG4gICAgICAgICAgICB7eyB0KHN1Ym1pdEtleSgpKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChzaG93U21zU2Vjb25kRmFjdG9yKCkpIHtcbiAgICAgICAgICBAaWYgKHNtc1NlY29uZEZhY3RvclNlbnRUbygpOyBhcyBzZW50VG8pIHtcbiAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXM9XCJzbXMtc2Vjb25kLWZhY3Rvci1zZW50XCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgICAgICAgIHt7IHQoJ21mYS5jb2RlVGV4dGVkVG8nLCB7IHBob25lOiBzZW50VG8gfSkgfX1cbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblNlY29uZGFyeScsICdhdGxhcy1idXR0b24tc2Vjb25kYXJ5JylcIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgZGF0YS1hdGxhcz1cInNtcy1zZWNvbmQtZmFjdG9yXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3kgfHwgISF0ZXh0ZWRTZWNvbmRGYWN0b3I/LmJ1c3lcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic21zU2Vjb25kRmFjdG9yLmVtaXQoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IHRleHRlZFNlY29uZEZhY3Rvcj8uYnVzeSA/IHQoJ3NpZ25Jbi5zZW5kaW5nJykgOiB0KCdtZmEuc21zQ29kZU9wdGlvbicpIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIEBpZiAodGV4dGVkU2Vjb25kRmFjdG9yPy5lcnJvcjsgYXMgbWVzc2FnZSkge1xuICAgICAgICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgbWVzc2FnZSB9fTwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dFbWFpbFNlY29uZEZhY3RvcigpKSB7XG4gICAgICAgICAgQGlmIChlbWFpbFNlY29uZEZhY3RvclNlbnRUbygpOyBhcyBzZW50VG8pIHtcbiAgICAgICAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiIGRhdGEtYXRsYXM9XCJlbWFpbC1zZWNvbmQtZmFjdG9yLXNlbnRcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj5cbiAgICAgICAgICAgICAge3sgdCgnc2lnbkluLmNvZGVTZW50VG8nLCB7IGVtYWlsOiBzZW50VG8gfSkgfX1cbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgW2NsYXNzXT1cImNscygnZm9ybUJ1dHRvblNlY29uZGFyeScsICdhdGxhcy1idXR0b24tc2Vjb25kYXJ5JylcIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgZGF0YS1hdGxhcz1cImVtYWlsLXNlY29uZC1mYWN0b3JcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiYnVzeSB8fCAhIWVtYWlsZWRTZWNvbmRGYWN0b3I/LmJ1c3lcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZW1haWxTZWNvbmRGYWN0b3IuZW1pdCgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgZW1haWxlZFNlY29uZEZhY3Rvcj8uYnVzeSA/IHQoJ3NpZ25Jbi5zZW5kaW5nJykgOiB0KCdzaWduSW4uZW1haWxDb2RlT3B0aW9uJykgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgQGlmIChlbWFpbGVkU2Vjb25kRmFjdG9yPy5lcnJvcjsgYXMgbWVzc2FnZSkge1xuICAgICAgICAgICAgICA8cCBbY2xhc3NdPVwiY2xzKCdmb3JtRmllbGRFcnJvcicsICdhdGxhcy1lcnJvcicpXCIgcm9sZT1cImFsZXJ0XCI+e3sgbWVzc2FnZSB9fTwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKHNob3dFbWFpbENvZGVPcHRpb24oKSkge1xuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJidXN5XCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1zdHJhdGVneV09XCJwcmVwYXJlZEZhY3RvciA9PT0gJ2VtYWlsX2NvZGUnID8gbnVsbCA6ICdlbWFpbF9jb2RlJ1wiXG4gICAgICAgICAgICBbYXR0ci5kYXRhLWF0bGFzLXJlc2VuZF09XCJwcmVwYXJlZEZhY3RvciA9PT0gJ2VtYWlsX2NvZGUnID8gJycgOiBudWxsXCJcbiAgICAgICAgICAgIChjbGljayk9XCJjaG9vc2VGYWN0b3IuZW1pdCgnZW1haWxfY29kZScpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyB0KHByZXBhcmVkRmFjdG9yID09PSAnZW1haWxfY29kZScgPyAnc2lnbkluLnJlc2VuZENvZGUnIDogJ3NpZ25Jbi51c2VFbWFpbENvZGUnKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEF0dGVtcHRGbG93Q29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuXG4gIEBJbnB1dCgpIGF0dGVtcHQ6IEF0dGVtcHRWaWV3IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGJ1c3kgPSBmYWxzZTtcbiAgQElucHV0KCkgZXJyb3JzOiBGaWVsZEVycm9yW10gPSBbXTtcbiAgLyoqIGBGbG93U3RhdGUuc2Vzc2lvbktlcHRgOiB3aGV0aGVyIHRoaXMgYnJvd3NlciBrZXB0IHRoZSBzZXNzaW9uIHRoZSBzaWduLWluIGNyZWF0ZWQuICovXG4gIEBJbnB1dCgpIHNlc3Npb25LZXB0OiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSB0aXRsZUtleSA9ICdzaWduSW4udGl0bGUnO1xuICAvKipcbiAgICogVGhlIHNpZ24taW4gY2FwdGNoYSwgZHJhd24gYWJvdmUgdGhlIHN1Ym1pdCBidXR0b24gb24gdGhlIGlkZW50aWZpZXIgc3RlcFxuICAgKiAoYW4gYWx3YXlzLW9uIHNpZ24taW4gY2FwdGNoYSkgYW5kIG9uIHRoZSBjaGFsbGVuZ2Ugc3RlcCB0aGUgc2VydmVyIGRlbWFuZHNcbiAgICogd2l0aCBgbmVlZHNfY2FwdGNoYWAuIE51bGwgd2hlbiB0aGUgZmxvdyBkcmF3cyBub25lLlxuICAgKi9cbiAgQElucHV0KCkgY2FwdGNoYTogQ2FwdGNoYUNvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIFRoZSBmaXJzdCBmYWN0b3JzIHRvIG9mZmVyIG9uIHRoZSBgbmVlZHNfZmlyc3RfZmFjdG9yYCBzdGVwIOKAlCBwYXNzXG4gICAqIGBBdGxhc0Zsb3dDb250cm9sbGVyLmZpcnN0RmFjdG9ycygpYCwgd2hpY2ggZHJvcHMgZW1haWwgY29kZSAvIGxpbmsgd2hpbGUgdGhlXG4gICAqIGFwcCBjYW5ub3QgZGVsaXZlciBlbWFpbC4gTnVsbCB1c2VzIHRoZSBzZXJ2ZXIncyBsaXN0IGFzLWlzLlxuICAgKi9cbiAgQElucHV0KCkgZmlyc3RGYWN0b3JzOiBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGZpcnN0IGZhY3RvciBhbHJlYWR5IHNlbnQgKGBBdGxhc0Zsb3dDb250cm9sbGVyLnByZXBhcmVkRmFjdG9yKClgKTogaXRzIGNvZGUgaXMgY29sbGVjdGVkLiAqL1xuICBASW5wdXQoKSBwcmVwYXJlZEZhY3Rvcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIEVtaXRzIHRoZSBjb2xsZWN0ZWQgZmllbGQgdmFsdWVzIHdoZW4gdGhlIGZvcm0gaXMgc3VibWl0dGVkLiAqL1xuICBAT3V0cHV0KCkgc3VibWl0RmxvdyA9IG5ldyBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4oKTtcbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgcGlja3MgYSBmaXJzdCBmYWN0b3IgdGhlIHNlcnZlciBtdXN0IHNlbmQgZmlyc3QgKGFuIGVtYWlsZWQgY29kZSkuICovXG4gIEBPdXRwdXQoKSBjaG9vc2VGYWN0b3IgPSBuZXcgRXZlbnRFbWl0dGVyPCdlbWFpbF9jb2RlJz4oKTtcbiAgLyoqXG4gICAqIE9mZmVyIFwiRW1haWwgbWUgYSBjb2RlIGluc3RlYWRcIiBhdCB0aGUgc2Vjb25kIGZhY3RvciAodGhlIGluc3RhbmNlJ3NcbiAgICogYGFjY291bnQuZW1haWxTZWNvbmRGYWN0b3JgKTsgYGVtYWlsU2Vjb25kRmFjdG9yYCBhc2tzIGZvciBpdCBhbmRcbiAgICogYGVtYWlsZWRTZWNvbmRGYWN0b3JgIHJlcG9ydHMgaG93IGl0IHdlbnQuXG4gICAqL1xuICBASW5wdXQoKSBvZmZlckVtYWlsU2Vjb25kRmFjdG9yID0gZmFsc2U7XG4gIC8qKiBgQXRsYXNGbG93Q29udHJvbGxlci5lbWFpbFNlY29uZEZhY3RvcigpYDogaW4gZmxpZ2h0LCB3aGVyZSBpdCB3ZW50LCBvciB3aHkgbm90LiAqL1xuICBASW5wdXQoKSBlbWFpbGVkU2Vjb25kRmFjdG9yOiB7IGJ1c3k/OiBib29sZWFuOyBzZW50VG8/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0gfCBudWxsID0gbnVsbDtcbiAgQE91dHB1dCgpIGVtYWlsU2Vjb25kRmFjdG9yID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKipcbiAgICogT2ZmZXIgXCJUZXh0IG1lIGEgY29kZSBpbnN0ZWFkXCIgYXQgdGhlIHNlY29uZCBmYWN0b3IgKHdoZXJlIHRoZSBhcHAgb2ZmZXJzXG4gICAqIHRleHRlZCBjb2RlcywgYEF0bGFzRmxvd0NvbnRyb2xsZXIubWZhQ2hvaWNlcygpLnNtc2ApOyBgc21zU2Vjb25kRmFjdG9yYFxuICAgKiBhc2tzIGZvciBpdCBhbmQgYHRleHRlZFNlY29uZEZhY3RvcmAgcmVwb3J0cyBob3cgaXQgd2VudC5cbiAgICovXG4gIEBJbnB1dCgpIG9mZmVyU21zU2Vjb25kRmFjdG9yID0gZmFsc2U7XG4gIC8qKiBgQXRsYXNGbG93Q29udHJvbGxlci5zbXNTZWNvbmRGYWN0b3IoKWA6IGluIGZsaWdodCwgd2hlcmUgaXQgd2VudCwgb3Igd2h5IG5vdC4gKi9cbiAgQElucHV0KCkgdGV4dGVkU2Vjb25kRmFjdG9yOiB7IGJ1c3k/OiBib29sZWFuOyBzZW50VG8/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0gfCBudWxsID0gbnVsbDtcbiAgQE91dHB1dCgpIHNtc1NlY29uZEZhY3RvciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqXG4gICAqIFRoZSBNRkEgZW5yb2xtZW50IHN0ZXAgKGBBdGxhc0Zsb3dDb250cm9sbGVyLmVucm9sbG1lbnRgIGFuZFxuICAgKiBgZW5yb2xsbWVudFN0YXRlKClgKTogdGhlIGF1dGhlbnRpY2F0b3IgYXBwJ3MgUVIgY29kZSBhbmQgc2V0dXAga2V5LCBvciBhXG4gICAqIHRleHRlZCBjb2RlLiBOdWxsOiB0aGUgc3RlcCBhc2tzIGZvciB0d28gYXV0aGVudGljYXRvciBjb2RlcyBvbmx5LlxuICAgKi9cbiAgQElucHV0KCkgZW5yb2xsbWVudDogTWZhRW5yb2xsbWVudENvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZW5yb2xsbWVudFN0YXRlOiBNZmFFbnJvbGxtZW50U3RhdGUgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSdzIGBhY2NvdW50LmVtYWlsVmVyaWZpY2F0aW9uYC4gT24gYGxpbmtgIGEgc2lnbi11cCdzXG4gICAqIHZlcmlmaWNhdGlvbiBzdGVwIGhhcyBub3RoaW5nIHRvIHR5cGU6IGl0IHNheXMgdG8gb3BlbiB0aGUgZW1haWxlZCBsaW5rXG4gICAqIHdoaWxlIHRoZSBmbG93IHBvbGxzLCBhbmQgb2ZmZXJzIGEgcmVzZW5kIChgcmVzZW5kYCkuXG4gICAqL1xuICBASW5wdXQoKSBlbWFpbFZlcmlmaWNhdGlvbjogc3RyaW5nID0gJ2NvZGUnO1xuICBAT3V0cHV0KCkgcmVzZW5kID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVGhlIHVzZXIgZGVjbGluZWQgYSBwb2xpY3kgdGhlIHNpZ24taW4gd2FzIHdhaXRpbmcgb24gKGBuZWVkc19wb2xpY3lfYWNjZXB0YW5jZWApOiBjYW5jZWwgdGhlIGF0dGVtcHQuICovXG4gIEBPdXRwdXQoKSBwb2xpY3lEZWNsaW5lZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIHByb3RlY3RlZCB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBwcm90ZWN0ZWQgdChrZXk6IHN0cmluZywgdmFycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBzdHJpbmcge1xuICAgIHJldHVybiB0cmFuc2xhdGUodGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIGtleSwgdmFycyk7XG4gIH1cblxuICAvKiogQSBzZXJ2ZXIgZXJyb3IgaW4gdGhlIGFwcCdzIGxhbmd1YWdlIChgZXJyb3IuPHJlYXNvbj5gLCBlbHNlIHRoZSBzZXJ2ZXIncyBtZXNzYWdlKS4gKi9cbiAgcHJvdGVjdGVkIGVycm9yVGV4dChlcnJvcjogRmllbGRFcnJvcik6IHN0cmluZyB7XG4gICAgLy8gYGVycm9yTG9jYWxpemF0aW9uYCBpcyByZWFkIGRlZmVuc2l2ZWx5OiBhIHN0YW5kLWluIHNlcnZpY2UgbWF5IGxhY2sgaXQuXG4gICAgY29uc3QgbGF5ZXIgPSAodGhpcy5hdGxhcyBhcyB7IGVycm9yTG9jYWxpemF0aW9uPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB9KS5lcnJvckxvY2FsaXphdGlvbjtcbiAgICByZXR1cm4gbG9jYWxpemVkRXJyb3JNZXNzYWdlKGVycm9yLCBsYXllciA/PyB0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwgdGhpcy5hdGxhcy5sb2NhbGl6YXRpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNscyhrZXk6IEVsZW1lbnRLZXksIGJhc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNsYXNzRm9yKGtleSwgdGhpcy5hdGxhcy5hcHBlYXJhbmNlLCBiYXNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRWYWx1ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlcyA9IHsgLi4udGhpcy52YWx1ZXMsIFtuYW1lXTogdmFsdWUgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblN1Ym1pdChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIEVucm9sbWVudDogdGV4dCB0aGUgY29kZSB0byB0aGUgdHlwZWQgbnVtYmVyLCBvciBjb25maXJtIHRoZSBmYWN0b3IuXG4gICAgaWYgKHRoaXMuZW5yb2xsaW5nKCkgJiYgdGhpcy5lbnJvbGxtZW50KSB7XG4gICAgICB2b2lkIHRoaXMuZW5yb2xsbWVudC5zdWJtaXQodGhpcy52YWx1ZXMpLnRoZW4oKG5leHQpID0+IHtcbiAgICAgICAgaWYgKG5leHQpIHRoaXMuc3VibWl0Rmxvdy5lbWl0KG5leHQpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc3VibWl0Rmxvdy5lbWl0KHRoaXMudmFsdWVzKTtcbiAgfVxuXG4gIC8qKiBUaGUgc2hhcmVkIGVucm9sbWVudCBzdGVwIGlzIGRyYXduIChhIGNvbnRyb2xsZXIgd2FzIHBhc3NlZCBhbmQgdGhlIGZsb3cgaXMgZW5yb2xsaW5nKS4gKi9cbiAgcHJvdGVjdGVkIGVucm9sbGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwKCkua2luZCA9PT0gJ2Vucm9sbF9zZWNvbmRfZmFjdG9yJyAmJiAhIXRoaXMuZW5yb2xsbWVudCAmJiAhIXRoaXMuZW5yb2xsbWVudFN0YXRlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNob29zZU1ldGhvZChtZXRob2Q6IE1mYUVucm9sbG1lbnRTdHJhdGVneSk6IHZvaWQge1xuICAgIHRoaXMudmFsdWVzID0ge307XG4gICAgdm9pZCB0aGlzLmVucm9sbG1lbnQ/LmNob29zZShtZXRob2QpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlc2VuZEVucm9sbG1lbnQoKTogdm9pZCB7XG4gICAgdm9pZCB0aGlzLmVucm9sbG1lbnQ/LnJlc2VuZCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG90aGVyTWV0aG9kcyhzdGF0ZTogTWZhRW5yb2xsbWVudFN0YXRlKTogTWZhRW5yb2xsbWVudFN0cmF0ZWd5W10ge1xuICAgIHJldHVybiBzdGF0ZS5vcHRpb25zLmZpbHRlcigobSkgPT4gbSAhPT0gc3RhdGUubWV0aG9kKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXR1cEtleShzZWNyZXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdyb3VwU2V0dXBLZXkoc2VjcmV0KTtcbiAgfVxuXG4gIC8qKiBUaGUgc3VibWl0IGJ1dHRvbidzIGxhYmVsIGtleSAoZW5yb2xtZW50OiBcIlRleHQgbWUgYSBjb2RlXCIgYmVmb3JlIHRoZSBudW1iZXIgaXMgc2VudCkuICovXG4gIHByb3RlY3RlZCBzdWJtaXRLZXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKHRoaXMuZW5yb2xsaW5nKCkgJiYgdGhpcy5lbnJvbGxtZW50U3RhdGUgJiYgZW5yb2xsbWVudFN1Ym1pdEtleSh0aGlzLmVucm9sbG1lbnRTdGF0ZSkpIHx8ICdzaWduSW4uc3VibWl0JztcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93U21zU2Vjb25kRmFjdG9yKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm9mZmVyU21zU2Vjb25kRmFjdG9yICYmIHRoaXMuc3RlcCgpLmtpbmQgPT09ICdjb2xsZWN0X3NlY29uZF9mYWN0b3InO1xuICB9XG5cbiAgLyoqIFdoZXJlIHRoZSB0ZXh0ZWQgc2Vjb25kLWZhY3RvciBjb2RlIHdlbnQgKG1hc2tlZCksIG9uY2UgaXQgd2FzIHNlbnQuICovXG4gIHByb3RlY3RlZCBzbXNTZWNvbmRGYWN0b3JTZW50VG8oKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3Qgc2VudCA9IHRoaXMudGV4dGVkU2Vjb25kRmFjdG9yPy5zZW50VG87XG4gICAgcmV0dXJuIHR5cGVvZiBzZW50ID09PSAnc3RyaW5nJyA/IHNlbnQgfHwgJyAnIDogbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtRXJyb3JzKCk6IEZpZWxkRXJyb3JbXSB7XG4gICAgcmV0dXJuIHRoaXMuZXJyb3JzLmZpbHRlcigoZXJyb3IpID0+ICFlcnJvci5wYXJhbSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmllbGRFcnJvcnNGb3IobmFtZTogc3RyaW5nKTogRmllbGRFcnJvcltdIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcnMuZmlsdGVyKChlcnJvcikgPT4gZXJyb3IucGFyYW0gPT09IG5hbWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLmF0dGVtcHQgPyBuZXh0U3RlcCh0aGlzLmF0dGVtcHQpIDogKHsga2luZDogJ2NvbGxlY3RfaWRlbnRpZmllcicgfSBhcyBjb25zdCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0NhcHRjaGEoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2luZCA9IHRoaXMuc3RlcCgpLmtpbmQ7XG4gICAgcmV0dXJuICEhdGhpcy5jYXB0Y2hhICYmIChraW5kID09PSAnY29sbGVjdF9pZGVudGlmaWVyJyB8fCBraW5kID09PSAnY29sbGVjdF9jYXB0Y2hhJyk7XG4gIH1cblxuICAvKiogVGhlIGZpcnN0IGZhY3RvcnMgb24gb2ZmZXIgYXQgYSBgbmVlZHNfZmlyc3RfZmFjdG9yYCBzdGVwIChlbXB0eSBvbiBhbnkgb3RoZXIpLiAqL1xuICBwcml2YXRlIG9mZmVyZWQoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHN0ZXAgPSB0aGlzLnN0ZXAoKTtcbiAgICBpZiAoc3RlcC5raW5kICE9PSAnY29sbGVjdF9maXJzdF9mYWN0b3InKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHRoaXMuZmlyc3RGYWN0b3JzID8/IHN0ZXAuc3RyYXRlZ2llcztcbiAgfVxuXG4gIHByb3RlY3RlZCBsaW5rT25seSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYXdhaXRpbmdTaWduVXBMaW5rKHRoaXMuYXR0ZW1wdCwgdGhpcy5lbWFpbFZlcmlmaWNhdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0VtYWlsU2Vjb25kRmFjdG9yKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm9mZmVyRW1haWxTZWNvbmRGYWN0b3IgJiYgdGhpcy5zdGVwKCkua2luZCA9PT0gJ2NvbGxlY3Rfc2Vjb25kX2ZhY3Rvcic7XG4gIH1cblxuICAvKiogV2hlcmUgdGhlIGVtYWlsZWQgc2Vjb25kLWZhY3RvciBjb2RlIHdlbnQgKG1hc2tlZCksIG9uY2UgaXQgd2FzIHNlbnQuICovXG4gIHByb3RlY3RlZCBlbWFpbFNlY29uZEZhY3RvclNlbnRUbygpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBzZW50ID0gdGhpcy5lbWFpbGVkU2Vjb25kRmFjdG9yPy5zZW50VG87XG4gICAgcmV0dXJuIHR5cGVvZiBzZW50ID09PSAnc3RyaW5nJyA/IHNlbnQgfHwgJyAnIDogbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93RW1haWxDb2RlT3B0aW9uKCk6IGJvb2xlYW4ge1xuICAgIC8vIEJlZm9yZSB0aGUgY29kZSBpcyBzZW50OiB0aGUgY2hvaWNlIChvciB0aGUgcmV0cnkgb2YgYSBmYWlsZWQgYXV0b21hdGljXG4gICAgLy8gc2VuZCkuIEFmdGVyOiBcIlJlc2VuZCBjb2RlXCIuXG4gICAgcmV0dXJuIHRoaXMub2ZmZXJlZCgpLmluY2x1ZGVzKCdlbWFpbF9jb2RlJyk7XG4gIH1cblxuICAvKiogVGhlIFwid2Ugc2VudCBhIGNvZGUgdG8g4oCmXCIgbGluZSBvbiB0aGUgY29kZSBzdGVwLiAqL1xuICBwcm90ZWN0ZWQgY29kZVNlbnRUZXh0KCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLnN0ZXAoKS5raW5kICE9PSAnY29sbGVjdF9maXJzdF9mYWN0b3InIHx8IHRoaXMucHJlcGFyZWRGYWN0b3IgIT09ICdlbWFpbF9jb2RlJykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMudCgnc2lnbkluLmNvZGVTZW50VG8nLCB7IGVtYWlsOiB0aGlzLmF0dGVtcHQ/LmlkZW50aWZpZXIgPz8gJycgfSk7XG4gIH1cblxuICAvKiogVGhlIGF0dGVtcHQgaXMgYG5lZWRzX3BvbGljeV9hY2NlcHRhbmNlYC4gKi9cbiAgcHJvdGVjdGVkIGF3YWl0aW5nUG9saWNpZXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RlcCgpLmtpbmQgPT09ICdhY2NlcHRfcG9saWNpZXMnO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dTdWJtaXQoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2luZCA9IHRoaXMuc3RlcCgpLmtpbmQ7XG4gICAgLy8gTm90aGluZyB0byBzdWJtaXQgb24gYSBmaXJzdC1mYWN0b3Igc3RlcCB0aGF0IG9ubHkgb2ZmZXJzIGFuIGVtYWlsZWQgY29kZVxuICAgIC8vIHVudGlsIHRoYXQgY29kZSBpcyBzZW50LlxuICAgIGlmIChraW5kID09PSAnY29sbGVjdF9maXJzdF9mYWN0b3InKSByZXR1cm4gdGhpcy5maWVsZHMoKS5sZW5ndGggPiAwO1xuICAgIGlmICh0aGlzLmxpbmtPbmx5KCkpIHJldHVybiBmYWxzZTtcbiAgICAvLyBFbnJvbG1lbnQ6IG5vdGhpbmcgdG8gc3VibWl0IHdoaWxlIGNob29zaW5nIGEgbWV0aG9kIG9yIGZldGNoaW5nIHRoZSBzZXR1cC5cbiAgICBpZiAodGhpcy5lbnJvbGxpbmcoKSAmJiB0aGlzLmVucm9sbG1lbnRTdGF0ZSAmJiAhZW5yb2xsbWVudFN1Ym1pdEtleSh0aGlzLmVucm9sbG1lbnRTdGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4ga2luZCAhPT0gJ2RvbmUnICYmIGtpbmQgIT09ICdhd2FpdF9vYXV0aCcgJiYga2luZCAhPT0gJ2FjY2VwdF9wb2xpY2llcyc7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmllbGRzKCk6IFN0ZXBGaWVsZFtdIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwKCk7XG4gICAgc3dpdGNoIChzdGVwLmtpbmQpIHtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfaWRlbnRpZmllcic6XG4gICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnaWRlbnRpZmllcicsIGxhYmVsS2V5OiAnc2lnbkluLmlkZW50aWZpZXJMYWJlbCcsIHR5cGU6ICdlbWFpbCcgfV07XG4gICAgICBjYXNlICdjb2xsZWN0X2ZpcnN0X2ZhY3Rvcic6IHtcbiAgICAgICAgaWYgKHRoaXMucHJlcGFyZWRGYWN0b3IgPT09ICdlbWFpbF9jb2RlJykge1xuICAgICAgICAgIHJldHVybiBbeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnc2lnbkluLmVtYWlsQ29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH1dO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBwYXNzd29yZCBmaWVsZCB1bmxlc3MgdGhlIG9ubHkgb2ZmZXIgaXMgYW4gZW1haWxlZCBjb2RlIChjaG9zZW5cbiAgICAgICAgLy8gd2l0aCB0aGUgYnV0dG9uIGJlbG93IHRoZSBmb3JtKS5cbiAgICAgICAgY29uc3Qgb2ZmZXJlZCA9IHRoaXMub2ZmZXJlZCgpO1xuICAgICAgICByZXR1cm4gb2ZmZXJlZC5pbmNsdWRlcygnZW1haWxfY29kZScpICYmICFvZmZlcmVkLmluY2x1ZGVzKCdwYXNzd29yZCcpXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogW3sga2luZDogJ2lucHV0JywgbmFtZTogJ3Bhc3N3b3JkJywgbGFiZWxLZXk6ICdzaWduSW4ucGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICB9XG4gICAgICBjYXNlICdjb2xsZWN0X3NlY29uZF9mYWN0b3InOlxuICAgICAgICByZXR1cm4gW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ21mYS5jb2RlTGFiZWwnLCB0eXBlOiAndGV4dCcgfV07XG4gICAgICBjYXNlICdlbnJvbGxfc2Vjb25kX2ZhY3Rvcic6XG4gICAgICAgIC8vIFRoZSBzaGFyZWQgZW5yb2xtZW50IHN0ZXAgZHJhd3MgaXRzIG93biBmaWVsZHMgKGFib3ZlKS5cbiAgICAgICAgaWYgKHRoaXMuZW5yb2xsaW5nKCkpIHJldHVybiBbXTtcbiAgICAgICAgLy8gVHdvIGNvbnNlY3V0aXZlIGNvZGVzICjCpzUuNik6IGEgcGhvbmUgd2l0aCBhIGZhc3QgY2xvY2sgZmFpbHMgaGVyZVxuICAgICAgICAvLyByYXRoZXIgdGhhbiBvbiBldmVyeSBzaWduLWluIGFmdGVyd2FyZHMuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnY29kZScsIGxhYmVsS2V5OiAnbWZhLmVucm9sbEZpcnN0Q29kZUxhYmVsJywgdHlwZTogJ3RleHQnIH0sXG4gICAgICAgICAgeyBraW5kOiAnaW5wdXQnLCBuYW1lOiAnc2Vjb25kQ29kZScsIGxhYmVsS2V5OiAnbWZhLmVucm9sbFNlY29uZENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9LFxuICAgICAgICBdO1xuICAgICAgY2FzZSAnY29sbGVjdF9lbWFpbF9jb2RlJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlua09ubHkoKSA/IFtdIDogW3sga2luZDogJ2lucHV0JywgbmFtZTogJ2NvZGUnLCBsYWJlbEtleTogJ3NpZ25Jbi5lbWFpbENvZGVMYWJlbCcsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICAgIGNhc2UgJ2NvbGxlY3RfbmV3X3Bhc3N3b3JkJzpcbiAgICAgICAgcmV0dXJuIFt7IGtpbmQ6ICdpbnB1dCcsIG5hbWU6ICdwYXNzd29yZCcsIGxhYmVsS2V5OiAncmVzZXQubmV3UGFzc3dvcmRMYWJlbCcsIHR5cGU6ICdwYXNzd29yZCcgfV07XG4gICAgICBjYXNlICdhY2NlcHRfcG9saWNpZXMnOlxuICAgICAgICAvLyBEcmF3biBieSA8YXRsYXMtcG9saWN5LWFjY2VwdC1zdGVwPiBhYm92ZS5cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgY2FzZSAnY29sbGVjdF9jYXB0Y2hhJzpcbiAgICAgICAgLy8gwqc1IHRoZSBzZXJ2ZXIgd2l0aGhlbGQgdGhlIGF0dGVtcHQgdW50aWwgYSBjYXB0Y2hhIGNsZWFycy4gU29sdmluZyB0aGVcbiAgICAgICAgLy8gd2lkZ2V0IHJlc3VibWl0cyB0aGUgaWRlbnRpZmllciBvbiBpdHMgb3duOyB0aGUgYnV0dG9uIHJldHJpZXMuXG4gICAgICAgIHJldHVybiBbbXNnKCdjYXB0Y2hhLnByb21wdCcpXTtcbiAgICAgIGNhc2UgJ2F3YWl0X29hdXRoJzpcbiAgICAgICAgcmV0dXJuIFttc2coJ3NpZ25Jbi5tYWdpY0xpbmtTZW50JyldO1xuICAgICAgY2FzZSAnZG9uZSc6XG4gICAgICAgIC8vIFNpZ25lZCBpbiBvbmx5IHdoZW4gdGhpcyBicm93c2VyIGhvbGRzIHRoZSBzZXNzaW9uOyBhIGJsb2NrZWQgY29va2llIGlzIHNhaWRcbiAgICAgICAgLy8gcGxhaW5seS4gXCJDaGVjayB0aGUgb3RoZXIgdGFiXCIgaXMgZm9yIGEgc2lnbi1pbiBjb21wbGV0ZWQgb24gYW5vdGhlciBkZXZpY2UuXG4gICAgICAgIGlmICh0aGlzLnNlc3Npb25LZXB0ID09PSB0cnVlKSByZXR1cm4gW21zZygnc2lnbkluLnNpZ25lZEluJyldO1xuICAgICAgICBpZiAodGhpcy5zZXNzaW9uS2VwdCA9PT0gZmFsc2UpIHJldHVybiBbeyBraW5kOiAnYWxlcnQnLCBuYW1lOiAnJywgbGFiZWxLZXk6ICdzaWduSW4uc2Vzc2lvbk5vdEtlcHQnLCB0eXBlOiAndGV4dCcgfV07XG4gICAgICAgIHJldHVybiBbbXNnKCdzaWduSW4uY2hlY2tPdGhlclRhYicpXTtcbiAgICAgIGNhc2UgJ3Jlc3RhcnQnOlxuICAgICAgICByZXR1cm4gW21zZygnZXJyb3IuZ2VuZXJpYycpXTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIEEgc3RhdHVzIHRoaXMgU0RLIHZlcnNpb24gZG9lcyBub3Qga25vdy4gQW4gaG9uZXN0IG1lc3NhZ2UgYmVhdHMgYVxuICAgICAgICAvLyBibGFuayBsb2dpbiBib3ggdGhlIHVzZXIgY2Fubm90IGFjdCBvbi5cbiAgICAgICAgcmV0dXJuIFttc2coJ2Vycm9yLmdlbmVyaWMnKV07XG4gICAgfVxuICB9XG59XG5cbi8qKiBBIHJlYWQtb25seSBtZXNzYWdlIHJvdzogYGxhYmVsS2V5YCBob2xkcyB0aGUgaTE4biBrZXkgb2YgdGhlIHRleHQgdG8gc2hvdy4gKi9cbmZ1bmN0aW9uIG1zZyhsYWJlbEtleTogc3RyaW5nKTogU3RlcEZpZWxkIHtcbiAgcmV0dXJuIHsga2luZDogJ21lc3NhZ2UnLCBuYW1lOiAnJywgbGFiZWxLZXksIHR5cGU6ICd0ZXh0JyB9O1xufVxuIl19
|