@openziti/ziti-console-lib 0.6.0 → 0.6.1
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/assets/styles/global.scss +212 -3
- package/esm2022/lib/features/data-table/cells/table-cell-name/table-cell-name.component.mjs +12 -3
- package/esm2022/lib/features/dynamic-widgets/text-list/text-list-input.component.mjs +2 -2
- package/esm2022/lib/features/list-page-features/list-page-header/list-page-header.component.mjs +22 -3
- package/esm2022/lib/features/projectable-forms/auth-policy/auth-policy-form.component.mjs +342 -0
- package/esm2022/lib/features/projectable-forms/auth-policy/auth-policy-form.service.mjs +127 -0
- package/esm2022/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.mjs +78 -20
- package/esm2022/lib/features/projectable-forms/jwt-signer/jwt-signer-form.service.mjs +2 -2
- package/esm2022/lib/features/projectable-forms/service/service-form.component.mjs +3 -3
- package/esm2022/lib/features/tag-selector/tag-selector.component.mjs +2 -2
- package/esm2022/lib/models/auth-policy.mjs +31 -0
- package/esm2022/lib/models/jwt-signer.mjs +4 -2
- package/esm2022/lib/pages/auth-policies/auth-policies-page.component.mjs +115 -0
- package/esm2022/lib/pages/auth-policies/auth-policies-page.service.mjs +207 -0
- package/esm2022/lib/pages/jwt-signers/jwt-signers-page.component.mjs +3 -3
- package/esm2022/lib/pages/terminators/terminators-page.component.mjs +2 -2
- package/esm2022/lib/services/node-data.service.mjs +18 -1
- package/esm2022/lib/services/validation.service.mjs +10 -1
- package/esm2022/lib/services/ziti-controller-data.service.mjs +16 -1
- package/esm2022/lib/services/ziti-data.service.mjs +1 -1
- package/esm2022/lib/ziti-console-lib.module.mjs +19 -5
- package/esm2022/public-api.mjs +5 -1
- package/fesm2022/openziti-ziti-console-lib.mjs +1080 -189
- package/fesm2022/openziti-ziti-console-lib.mjs.map +1 -1
- package/lib/features/data-table/cells/table-cell-name/table-cell-name.component.d.ts.map +1 -1
- package/lib/features/list-page-features/list-page-header/list-page-header.component.d.ts +1 -0
- package/lib/features/list-page-features/list-page-header/list-page-header.component.d.ts.map +1 -1
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.component.d.ts +75 -0
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.component.d.ts.map +1 -0
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.service.d.ts +38 -0
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.service.d.ts.map +1 -0
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.d.ts +4 -0
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.d.ts.map +1 -1
- package/lib/models/auth-policy.d.ts +8 -0
- package/lib/models/auth-policy.d.ts.map +1 -0
- package/lib/models/jwt-signer.d.ts +3 -1
- package/lib/models/jwt-signer.d.ts.map +1 -1
- package/lib/pages/auth-policies/auth-policies-page.component.d.ts +29 -0
- package/lib/pages/auth-policies/auth-policies-page.component.d.ts.map +1 -0
- package/lib/pages/auth-policies/auth-policies-page.service.d.ts +34 -0
- package/lib/pages/auth-policies/auth-policies-page.service.d.ts.map +1 -0
- package/lib/pages/jwt-signers/jwt-signers-page.component.d.ts +1 -1
- package/lib/services/node-data.service.d.ts +1 -0
- package/lib/services/node-data.service.d.ts.map +1 -1
- package/lib/services/validation.service.d.ts +1 -0
- package/lib/services/validation.service.d.ts.map +1 -1
- package/lib/services/ziti-controller-data.service.d.ts +1 -0
- package/lib/services/ziti-controller-data.service.d.ts.map +1 -1
- package/lib/services/ziti-data.service.d.ts +1 -0
- package/lib/services/ziti-data.service.d.ts.map +1 -1
- package/lib/ziti-console-lib.module.d.ts +20 -17
- package/lib/ziti-console-lib.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +4 -0
- package/public-api.d.ts.map +1 -1
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright NetFoundry Inc.
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { Component, EventEmitter, Inject, Input, Output, ViewChild, } from '@angular/core';
|
|
17
|
+
import { KEY_CODES, ProjectableForm } from "../projectable-form.class";
|
|
18
|
+
import { SHAREDZ_EXTENSION } from "../../extendable/extensions-noop.service";
|
|
19
|
+
import { cloneDeep, delay, forOwn, invert, isEmpty, unset, debounce } from 'lodash';
|
|
20
|
+
import { GrowlerModel } from "../../messaging/growler.model";
|
|
21
|
+
import { SETTINGS_SERVICE } from "../../../services/settings.service";
|
|
22
|
+
import { ZITI_DATA_SERVICE } from "../../../services/ziti-data.service";
|
|
23
|
+
import { AuthPolicy } from "../../../models/auth-policy";
|
|
24
|
+
import * as i0 from "@angular/core";
|
|
25
|
+
import * as i1 from "./auth-policy-form.service";
|
|
26
|
+
import * as i2 from "../../../services/schema.service";
|
|
27
|
+
import * as i3 from "../../messaging/growler.service";
|
|
28
|
+
import * as i4 from "@angular/router";
|
|
29
|
+
import * as i5 from "@angular/common";
|
|
30
|
+
import * as i6 from "../../../services/validation.service";
|
|
31
|
+
import * as i7 from "@angular/forms";
|
|
32
|
+
import * as i8 from "primeng/inputtext";
|
|
33
|
+
import * as i9 from "primeng/api";
|
|
34
|
+
import * as i10 from "primeng/button";
|
|
35
|
+
import * as i11 from "@angular/material/tooltip";
|
|
36
|
+
import * as i12 from "primeng/dropdown";
|
|
37
|
+
import * as i13 from "../form-header/form-header.component";
|
|
38
|
+
import * as i14 from "../form-field-container/form-field-container.component";
|
|
39
|
+
import * as i15 from "../../loading-indicator/loading-indicator.component";
|
|
40
|
+
import * as i16 from "../form-field-toggle/form-field-toggle.component";
|
|
41
|
+
import * as i17 from "../../json-view/json-view.component";
|
|
42
|
+
import * as i18 from "../../tag-selector/tag-selector.component";
|
|
43
|
+
import * as i19 from "../../custom-tags/custom-tags.component";
|
|
44
|
+
import * as i20 from "../../../services/settings.service";
|
|
45
|
+
import * as i21 from "../../../services/ziti-data.service";
|
|
46
|
+
class AuthPolicyFormComponent extends ProjectableForm {
|
|
47
|
+
constructor(svc, schemaSvc, growlerService, extService, settingsService, zitiService, router, route, location, validationService) {
|
|
48
|
+
super(growlerService, extService, zitiService, router, route, location);
|
|
49
|
+
this.svc = svc;
|
|
50
|
+
this.schemaSvc = schemaSvc;
|
|
51
|
+
this.settingsService = settingsService;
|
|
52
|
+
this.zitiService = zitiService;
|
|
53
|
+
this.router = router;
|
|
54
|
+
this.route = route;
|
|
55
|
+
this.validationService = validationService;
|
|
56
|
+
this.formData = new AuthPolicy();
|
|
57
|
+
this.errors = {};
|
|
58
|
+
this.close = new EventEmitter();
|
|
59
|
+
this.allowedJwtSignerAttributes = [];
|
|
60
|
+
this.formView = 'simple';
|
|
61
|
+
this.options = [];
|
|
62
|
+
this.isEditing = !isEmpty(this.formData.id);
|
|
63
|
+
this.formDataInvalid = false;
|
|
64
|
+
this.editMode = false;
|
|
65
|
+
this.items = [];
|
|
66
|
+
this.settings = {};
|
|
67
|
+
this.fileSelectOpening = false;
|
|
68
|
+
this.entityType = 'auth-policies';
|
|
69
|
+
this.entityClass = AuthPolicy;
|
|
70
|
+
this.jwtSignersFilterChangedDebounced = debounce(this.jwtSignerFilterChanged.bind(this), 200);
|
|
71
|
+
this._apiData = {};
|
|
72
|
+
}
|
|
73
|
+
ngOnInit() {
|
|
74
|
+
super.ngOnInit();
|
|
75
|
+
this.svc.getJwtSigners();
|
|
76
|
+
this.svc.getJwtSignerNamedAttributes().then(() => {
|
|
77
|
+
this.initSelectedAttributes();
|
|
78
|
+
});
|
|
79
|
+
this.settingsService.settingsChange.subscribe((results) => {
|
|
80
|
+
this.settings = results;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
entityUpdated() {
|
|
84
|
+
super.entityUpdated();
|
|
85
|
+
}
|
|
86
|
+
ngOnDestroy() {
|
|
87
|
+
this.clearForm();
|
|
88
|
+
}
|
|
89
|
+
headerActionRequested(event) {
|
|
90
|
+
switch (event.name) {
|
|
91
|
+
case 'save':
|
|
92
|
+
this.save(event);
|
|
93
|
+
break;
|
|
94
|
+
case 'close':
|
|
95
|
+
this.returnToListPage();
|
|
96
|
+
break;
|
|
97
|
+
case 'toggle-view':
|
|
98
|
+
this.formView = event.data;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
clear() {
|
|
103
|
+
this.formData.configTypeId = '';
|
|
104
|
+
this.clearForm();
|
|
105
|
+
}
|
|
106
|
+
clearForm() {
|
|
107
|
+
this.items.forEach((item) => {
|
|
108
|
+
if (item?.component)
|
|
109
|
+
item.component.destroy();
|
|
110
|
+
});
|
|
111
|
+
this.errors = {};
|
|
112
|
+
this.items = [];
|
|
113
|
+
this.formData = new AuthPolicy();
|
|
114
|
+
if (this.subscription)
|
|
115
|
+
this.subscription.unsubscribe();
|
|
116
|
+
}
|
|
117
|
+
allowedJwtSignersChanged(event) {
|
|
118
|
+
this.formData.primary.extJwt.allowedSigners = this.getSelectedAttributes(this.allowedJwtSignerAttributes, this.svc.jwtSignerNamedAttributesMap);
|
|
119
|
+
}
|
|
120
|
+
getSelectedAttributes(namedAttributes, namedAttributeMap) {
|
|
121
|
+
const prependedNamedAttributes = namedAttributes.map((attr) => {
|
|
122
|
+
return namedAttributeMap[attr];
|
|
123
|
+
});
|
|
124
|
+
return [...prependedNamedAttributes];
|
|
125
|
+
}
|
|
126
|
+
initSelectedAttributes() {
|
|
127
|
+
const jwtSignerNamedAttributesMap = invert(this.svc.jwtSignerNamedAttributesMap);
|
|
128
|
+
this.formData.primary?.extJwt?.allowedSigners?.forEach(attr => {
|
|
129
|
+
this.allowedJwtSignerAttributes.push(jwtSignerNamedAttributesMap[attr]);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async save(event) {
|
|
133
|
+
if (!this.validate()) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const tagVals = this.getTagValues();
|
|
137
|
+
if (!isEmpty(tagVals)) {
|
|
138
|
+
forOwn(tagVals, (value, key) => {
|
|
139
|
+
this.formData.tags[key] = value;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const apiData = this.apiData;
|
|
143
|
+
apiData.id = this.formData.id;
|
|
144
|
+
this.isLoading = true;
|
|
145
|
+
this.svc.save(apiData).then((result) => {
|
|
146
|
+
if (this.isModal) {
|
|
147
|
+
this.closeModal(true, true);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.initData = this.formData;
|
|
151
|
+
this._dataChange = false;
|
|
152
|
+
this.returnToListPage();
|
|
153
|
+
}).finally(() => {
|
|
154
|
+
this.isLoading = false;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
validate() {
|
|
158
|
+
this.errors = {};
|
|
159
|
+
const labels = [];
|
|
160
|
+
const growlers = [];
|
|
161
|
+
if (isEmpty(this.formData.name)) {
|
|
162
|
+
this.errors.name = true;
|
|
163
|
+
labels.push('Name');
|
|
164
|
+
}
|
|
165
|
+
if (!isEmpty(this.errors)) {
|
|
166
|
+
let missingFields = labels.join(', ');
|
|
167
|
+
growlers.push(new GrowlerModel('error', 'Invalid', `Missing Form Data`, `Please enter a value for the highlighted fields: ${missingFields}`));
|
|
168
|
+
}
|
|
169
|
+
if (!isEmpty(growlers)) {
|
|
170
|
+
growlers.forEach((growlerData) => {
|
|
171
|
+
this.growlerService.show(growlerData);
|
|
172
|
+
});
|
|
173
|
+
return isEmpty(this.errors);
|
|
174
|
+
}
|
|
175
|
+
growlers.forEach((growlerData) => {
|
|
176
|
+
this.growlerService.show(growlerData);
|
|
177
|
+
});
|
|
178
|
+
return isEmpty(this.errors);
|
|
179
|
+
}
|
|
180
|
+
get apiCallURL() {
|
|
181
|
+
return this.settings.selectedEdgeController + '/edge/management/v1/auth-policies' + (this.formData.id ? `/${this.formData.id}` : '');
|
|
182
|
+
}
|
|
183
|
+
get apiData() {
|
|
184
|
+
const data = {
|
|
185
|
+
name: this.formData.name || '',
|
|
186
|
+
primary: this.formData.primary || {},
|
|
187
|
+
secondary: this.formData.secondary || {},
|
|
188
|
+
tags: this.formData.tags || {}
|
|
189
|
+
};
|
|
190
|
+
this._apiData = data;
|
|
191
|
+
return this._apiData;
|
|
192
|
+
}
|
|
193
|
+
set apiData(data) {
|
|
194
|
+
this._apiData = data;
|
|
195
|
+
}
|
|
196
|
+
dataChanged(event) {
|
|
197
|
+
this._apiData = cloneDeep(this.apiData);
|
|
198
|
+
}
|
|
199
|
+
toggleCertAllowed() {
|
|
200
|
+
this.formData.primary.cert.allowed = !this.formData.primary.cert.allowed;
|
|
201
|
+
if (!this.formData.primary.cert.allowed) {
|
|
202
|
+
this.formData.primary.cert.allowExpiredCerts = false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
toggleExtJwtAllowed() {
|
|
206
|
+
this.formData.primary.extJwt.allowed = !this.formData.primary.extJwt.allowed;
|
|
207
|
+
}
|
|
208
|
+
toggleUpdbAllowed() {
|
|
209
|
+
this.formData.primary.updb.allowed = !this.formData.primary.updb.allowed;
|
|
210
|
+
}
|
|
211
|
+
toggleAllowExpiredCerts() {
|
|
212
|
+
this.formData.primary.cert.allowExpiredCerts = !this.formData.primary.cert.allowExpiredCerts;
|
|
213
|
+
}
|
|
214
|
+
toggleUpdbMixed() {
|
|
215
|
+
this.formData.primary.updb.requireMixedCase = !this.formData.primary.updb.requireMixedCase;
|
|
216
|
+
}
|
|
217
|
+
toggleUpdbNumeric() {
|
|
218
|
+
this.formData.primary.updb.requireNumericChar = !this.formData.primary.updb.requireNumericChar;
|
|
219
|
+
}
|
|
220
|
+
toggleUpdbSpecial() {
|
|
221
|
+
this.formData.primary.updb.requireSpecialChar = !this.formData.primary.updb.requireSpecialChar;
|
|
222
|
+
}
|
|
223
|
+
toggleRequireTotp() {
|
|
224
|
+
this.formData.secondary.requireTotp = !this.formData.secondary.requireTotp;
|
|
225
|
+
}
|
|
226
|
+
openFileSelect(event) {
|
|
227
|
+
this.filterInput.nativeElement.click();
|
|
228
|
+
this.fileSelectOpening = true;
|
|
229
|
+
delay(() => {
|
|
230
|
+
this.fileSelectOpening = false;
|
|
231
|
+
}, 1000);
|
|
232
|
+
}
|
|
233
|
+
selectPemFile(event) {
|
|
234
|
+
console.log(event);
|
|
235
|
+
const file = event?.target?.files[0];
|
|
236
|
+
if (file) {
|
|
237
|
+
const fileReader = new FileReader();
|
|
238
|
+
fileReader.onload = (fileLoadedEvent) => {
|
|
239
|
+
const textFromSelectedFile = fileLoadedEvent.target?.result;
|
|
240
|
+
if (!this.validationService.isValidPEM(textFromSelectedFile?.trim())) {
|
|
241
|
+
this.errors.certPem = true;
|
|
242
|
+
const growlerData = new GrowlerModel('error', 'Invalid', `Cert PEM Invalid`, `The file selected for the Cert PEM field is invalid. Please check your input and try again.`);
|
|
243
|
+
this.growlerService.show(growlerData);
|
|
244
|
+
this.formData.certPem = 'Invalid PEM. Please select or enter a valid PEM certificate.';
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
unset(this.errors, 'certPem');
|
|
248
|
+
this.formData.certPem = textFromSelectedFile;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
fileReader.readAsText(file, "UTF-8");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
apiActionRequested(action) {
|
|
255
|
+
switch (action.id) {
|
|
256
|
+
case 'cli':
|
|
257
|
+
this.copyCLICommand();
|
|
258
|
+
break;
|
|
259
|
+
case 'curl':
|
|
260
|
+
this.copyCURLCommand();
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
copyCLICommand() {
|
|
265
|
+
const command = `ziti edge ${this.formData.id ? 'update' : 'create'} auth-policy ${this.formData.id ? `'${this.formData.id}'` : ''} ${this.formData.id ? '--name' : ''} '${this.formData.name}' --primary-cert-allowed '${this.formData.primary.cert.allowed}' --primary-cert-expired-allowed '${this.formData.primary.cert.allowExpiredCerts}' --primary-ext-jwt-allowed '${this.formData.primary.extJwt.allowed}' --primary-ext-jwt-allowed-signers ${this.formData.primary.extJwt.allowedSigners.join(',') || ''} --primary-updb-allowed '${this.formData.primary.updb.allowed}' --primary-updb-lockout-min ${this.formData.primary.updb.lockoutDurationMinutes} --primary-updb-max-attempts ${this.formData.primary.updb.maxAttempts} --primary-updb-min-length ${this.formData.primary.updb.minPasswordLength} --primary-updb-req-mixed-case '${this.formData.primary.updb.requireMixedCase}' --primary-updb-req-numbers '${this.formData.primary.updb.requireNumberChar}' --primary-updb-req-special '${this.formData.primary.updb.requireSpecialChar}' --secondary-req-ext-jwt-signer '${this.formData.secondary.requireExtJwtSigner}' --secondary-req-totp '${this.formData.secondary.requireTotp}' --tags-json '${JSON.stringify(this.formData.tags)}'`;
|
|
266
|
+
navigator.clipboard.writeText(command);
|
|
267
|
+
const growlerData = new GrowlerModel('success', 'Success', `Text Copied`, `CLI command copied to clipboard`);
|
|
268
|
+
this.growlerService.show(growlerData);
|
|
269
|
+
}
|
|
270
|
+
copyCURLCommand() {
|
|
271
|
+
const command = `curl '${this.apiCallURL}' \\
|
|
272
|
+
${this.formData.id ? '--request PATCH \\' : '\\'}
|
|
273
|
+
-H 'accept: application/json' \\
|
|
274
|
+
-H 'content-type: application/json' \\
|
|
275
|
+
-H 'zt-session: ${this.settings.session.id}' \\
|
|
276
|
+
--data-raw '${JSON.stringify(this.apiData)}'`;
|
|
277
|
+
navigator.clipboard.writeText(command);
|
|
278
|
+
const growlerData = new GrowlerModel('success', 'Success', `Text Copied`, `CURL command copied to clipboard`);
|
|
279
|
+
this.growlerService.show(growlerData);
|
|
280
|
+
}
|
|
281
|
+
scopesOnKeyup(event) {
|
|
282
|
+
const key = event.key?.toLowerCase();
|
|
283
|
+
if (key === " " || key === 'enter') {
|
|
284
|
+
event.preventDefault();
|
|
285
|
+
event.stopPropagation();
|
|
286
|
+
const element = event.target;
|
|
287
|
+
element.blur();
|
|
288
|
+
element.focus();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
jwtSignerFilterChanged(event) {
|
|
292
|
+
if (event?.keyCode === KEY_CODES.LEFT_ARROW || event?.keyCode === KEY_CODES.RIGHT_ARROW || event?.keyCode === KEY_CODES.UP_ARROW || event?.keyCode === KEY_CODES.DOWN_ARROW) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
let filters = [];
|
|
296
|
+
if (event?.target?.value) {
|
|
297
|
+
filters.push({
|
|
298
|
+
columnId: 'name',
|
|
299
|
+
value: event.target.value,
|
|
300
|
+
label: event.target.value,
|
|
301
|
+
filterName: 'Name',
|
|
302
|
+
type: 'TEXTINPUT',
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
this.svc.getJwtSigners(filters, 1);
|
|
306
|
+
}
|
|
307
|
+
secondaryJwtSignerChanged(event) {
|
|
308
|
+
this.svc.filteredJwtSigners = this.svc.jwtSigners.filter((jwtSigner) => {
|
|
309
|
+
return jwtSigner.id === this.formData.secondary.requireExtJwtSigner;
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
clearJwtSignerFilter(event) {
|
|
313
|
+
const filters = [];
|
|
314
|
+
this.svc.getJwtSigners(filters, 1);
|
|
315
|
+
}
|
|
316
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthPolicyFormComponent, deps: [{ token: i1.AuthPolicyFormService }, { token: i2.SchemaService }, { token: i3.GrowlerService }, { token: SHAREDZ_EXTENSION }, { token: SETTINGS_SERVICE }, { token: ZITI_DATA_SERVICE }, { token: i4.Router }, { token: i4.ActivatedRoute }, { token: i5.Location }, { token: i6.ValidationService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
317
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthPolicyFormComponent, selector: "lib-configuration", inputs: { formData: "formData", errors: "errors" }, outputs: { close: "close" }, viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["fileSelect"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"projectable-form-wrapper\"\n (keyup.enter)=\"save($event)\"\n (keyup.escape)=\"closeModal(false)\"\n tabindex=\"0\"\n>\n <lib-form-header\n [data]=\"formData\"\n [title]=\"(formData.id ? 'Auth Policy Details' : 'Create Auth Policy')\"\n [moreActions]=\"formData.moreActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n [(formView)]=\"formView\"\n [saveDisabled]=\"svc.saveDisabled || formDataInvalid\"\n ></lib-form-header>\n <div class=\"jwt-signer-form-container projectable-form-container\">\n <div class=\"projectable-form-main-column form-group-row\" [hidden]=\"formView !== 'simple'\">\n <div class=\"form-group-column three-fifths\">\n <lib-form-field-container\n [title]=\"'Name'\"\n [label]=\"'Required'\"\n >\n <input class=\"form-field-input read-only\" [(ngModel)]=\"formData.name\" [ngClass]=\"{error: errors['name']}\" placeholder=\"Name this JWT Signer\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Primary Authentication'\"\n [layout]=\"'row'\"\n >\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Cert</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow x509 certificate based authentication\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleCertAllowed()\"\n [ngClass]=\"{ on: formData.primary.cert.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.cert.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.cert.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Ext JWT</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow externally signed JWT bearer tokens\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleExtJwtAllowed()\"\n [ngClass]=\"{ on: formData.primary.extJwt.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.extJwt.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.extJwt.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">UPDB</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow authentication via a traditional "Username Password Database"\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbAllowed()\"\n [ngClass]=\"{ on: formData.primary.updb.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.cert.allowed\"\n [title]=\"'Cert Options'\"\n [layout]=\"'row'\"\n >\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Allow Expired Certificates</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow expired client certificates to authenticate\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleAllowExpiredCerts()\"\n [ngClass]=\"{ on: formData.primary.cert.allowExpiredCerts }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.cert.allowExpiredCerts\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.cert.allowExpiredCerts\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.extJwt.allowed\"\n [title]=\"'Ext JWT Options'\"\n [layout]=\"'column'\"\n >\n <div class=\"form-field-label-container allowed-signers-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Allowed JWT Signers</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Choose which External JWT Signers may be used for authentication\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"allowedJwtSignerAttributes\"\n [availableNamedAttributes]=\"svc.jwtSignerNamedAttributes\"\n [placeholder]=\"'Select which External JWT Signers to allow'\"\n (selectedNamedAttributesChange)=\"allowedJwtSignersChanged($event)\"\n ></lib-tag-selector>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.updb.allowed\"\n [title]=\"'UPDB Options'\"\n [layout]=\"'column'\"\n >\n <div class=\"form-field-row updb-input-options\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Minimum Length</span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter a numeric value\" type=\"number\" [(ngModel)]=\"formData.primary.updb.minPasswordLength\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Max Attempts</span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter a numeric value\" type=\"number\" [(ngModel)]=\"formData.primary.updb.maxAttempts\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Lockout Duration <div class=\"form-sub-text\">(min)</div></span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter time in min\" type=\"number\" [(ngModel)]=\"formData.primary.updb.lockoutDurationMinutes\"/>\n </div>\n </div>\n <div class=\"form-field-row\">\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Mixed Case</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require upper and lower case charachters\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbMixed()\"\n [ngClass]=\"{ on: formData.primary.updb.requireMixedCase }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireMixedCase\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireMixedCase\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Numeric</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require numerical charachters 0-9\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbNumeric()\"\n [ngClass]=\"{ on: formData.primary.updb.requireNumericChar }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireNumericChar\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireNumericChar\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Special</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require special (non-alpha numeric) charachters. ie. !%$@*\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbSpecial()\"\n [ngClass]=\"{ on: formData.primary.updb.requireSpecialChar }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireSpecialChar\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireSpecialChar\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-toggle [(toggleOn)]=\"showMore\" (toggleOnChange)=\"showMoreChanged($event)\" style=\"margin: 0px 10px\"></lib-form-field-toggle>\n <div [hidden]=\"!showMore\" class=\"form-group-column\">\n <lib-form-field-container\n [title]=\"'Custom Tags'\"\n [label]=\"'OPTIONAL'\"\n class=\"form-field-advanced\"\n >\n <lib-custom-tags [(tags)]=\"formData.tags\"></lib-custom-tags>\n </lib-form-field-container>\n </div>\n </div>\n <div class=\"form-group-column two-fifths\">\n <lib-form-field-container\n [title]=\"'Secondary Authentication'\"\n [label]=\"'OPTIONAL'\"\n [layout]=\"'column'\"\n [contentStyle]=\"'z-index: 1000001'\"\n >\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">TOTP MFA</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require authenticating clients to have TOTP MFA enabled (Time-based, One-Time Password)\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Require TOTP</div>\n </div>\n <div\n (click)=\"toggleRequireTotp()\"\n [ngClass]=\"{ on: formData.secondary.requireTotp }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.secondary.requireTotp\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.secondary.requireTotp\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">JWT Signer</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require every client request to have a JWT from the specified External JTW Signer in the HTTP Authentication header\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <p-dropdown\n placeholder=\"Select JWT Signer...\"\n optionLabel=\"name\"\n optionValue=\"id\"\n filterBy=\"name\"\n [options]=\"svc.jwtSigners\"\n [filter]=\"true\"\n [showClear]=\"true\"\n (change)=\"secondaryJwtSignerChanged($event)\"\n [(ngModel)]=\"formData.secondary.requireExtJwtSigner\"\n >\n <ng-template pTemplate=\"filter\" let-options=\"options\">\n <div class=\"dropdown-filter-container\">\n <div class=\"p-inputgroup\" (click)=\"$event.stopPropagation()\">\n <span class=\"p-inputgroup-addon\"><i class=\"pi pi-search\"></i></span>\n <input\n type=\"text\"\n pInputText\n placeholder=\"Filter\"\n (keyup)=\"jwtSignersFilterChangedDebounced($event)\" />\n </div>\n <button pButton\n icon=\"pi pi-times\"\n [ngClass]=\"{'configs-loading': svc.jwtSignersLoading}\"\n (click)=\"clearJwtSignerFilter($event)\"\n severity=\"secondary\">\n </button>\n <div class=\"spinner\" *ngIf=\"svc.jwtSignersLoading\"></div>\n </div>\n </ng-template>\n </p-dropdown>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'API Calls'\"\n [headerActions]=\"apiOptions\"\n (actionRequested)=\"apiActionRequested($event)\"\n [class]=\"'api-data-no-wrap'\"\n >\n <div class=\"form-row\">\n <input class=\"form-field-input\" [value]=\"apiCallURL\"/>\n <div class=\"icon-copy copy\" (click)=\"copyToClipboard(apiCallURL)\"></div>\n </div>\n <lib-json-view *ngIf=\"formData\" [(data)]=\"apiData\" [readOnly]=\"true\" [showCopy]=\"true\"></lib-json-view>\n </lib-form-field-container>\n </div>\n </div>\n <div class=\"form-group-column\" *ngIf=\"formView === 'raw'\">\n <lib-json-view *ngIf=\"formData\" [(data)]=\"formData\"></lib-json-view>\n </div>\n </div>\n</div>\n<lib-loading-indicator *ngIf=\"isLoading\" [isLoading]=\"isLoading\"></lib-loading-indicator>\n", styles: ["@charset \"UTF-8\";.form-group-column.three-fifths{min-width:500px}.jwt-signer-form-container{display:flex;flex-direction:column;height:100%;width:100%;align-items:center;gap:var(--gapXL)}.jwt-signer-form-container .select-file-button{padding-left:var(--paddingMedium);padding-right:var(--paddingMedium);height:25px;width:-moz-fit-content;width:fit-content;white-space:nowrap;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:14px;background:var(--primary);border-style:solid;border-width:1px;border-color:var(--stroke);color:var(--white);cursor:pointer;border-radius:var(--inputBorderRadius);gap:var(--marginMedium);margin-top:-5px}.jwt-signer-form-container .select-file-button:hover{filter:brightness(.8)}.jwt-signer-form-container .select-file-button:active{filter:grayscale(1);transform:translateY(1px)}.jwt-signer-form-container .select-file-button .spinner{display:inline-block;width:8px;height:8px;border-radius:50%;background:transparent;border-top:2px solid white;border-right:2px solid white;border-bottom:2px solid transparent;border-left:2px solid transparent;animation:loading .5s infinite linear}.jwt-signer-form-container .select-file-label-container{gap:var(--marginMedium)}.jwt-signer-form-container .updb-input-options{margin-top:var(--marginSmall);background-color:var(--formGroup);padding:var(--paddingMedium);border-radius:var(--inputBorderRadius)}.jwt-signer-form-container .updb-input-options .form-field-title{color:var(--offWhite)}::ng-deep .jwt-signer-form-container select:disabled,::ng-deep .jwt-signer-form-container input:disabled{opacity:.75!important;cursor:text;background-color:var(--stroke)!important}::ng-deep .api-data-no-wrap .jse-text-mode{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller .cm-content{width:100%;overflow:auto}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller .cm-content .\\37cr{white-space:nowrap}.radio-group-container{display:flex;gap:var(--marginLarge)}.radio-group-container:focus .radio-button-container .radio-button-circle{border-color:var(--primaryColor)}.radio-group-container .radio-button-container{display:flex;flex-direction:row;align-items:center;background-color:var(--formGroup);border-radius:var(--inputBorderRadius);width:100%;padding-left:var(--paddingMedium);padding-right:var(--paddingMedium);padding-top:var(--paddingLarge);padding-bottom:var(--paddingLarge);cursor:pointer;gap:var(--marginMedium)}.radio-group-container .radio-button-container .radio-button-circle{display:flex;width:21px;height:21px;border-radius:21px;border-width:2px;border-style:solid;border-color:var(--offWhite);align-items:center;justify-content:center;background-color:var(--offWhite)}.radio-group-container .radio-button-container .radio-button-circle .radio-button-inner-circle{display:none;width:15px;height:15px;border-radius:15px;align-items:center;justify-content:center;background-color:var(--primaryColor)}.radio-group-container .radio-button-container.selected .radio-button-circle .radio-button-inner-circle{display:flex}.radio-group-container .radio-button-container:active .radio-button-circle .radio-button-inner-circle{display:flex;background-color:var(--menu)}.radio-group-container .radio-button-container .radio-button-label{color:var(--offWhite);font-size:14px;font-weight:600}.allowed-signers-container{background-color:var(--formGroup);padding:var(--paddingMedium);border-radius:var(--inputBorderRadius)}.allowed-signers-container .form-field-title{color:var(--offWhite)}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]" }, { kind: "directive", type: i9.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i10.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i12.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i13.FormHeaderComponent, selector: "lib-form-header", inputs: ["data", "title", "moreActions", "formView", "saveDisabled", "saveTooltip", "actionButtonText", "moreActionsText"], outputs: ["formViewChange", "actionRequested"] }, { kind: "component", type: i14.FormFieldContainerComponent, selector: "lib-form-field-container", inputs: ["title", "title2", "layout", "helpText", "helpText2", "label", "count", "action", "actionLabel", "class", "contentStyle", "showHeader", "headerActions"], outputs: ["actionRequested"] }, { kind: "component", type: i15.LoadingIndicatorComponent, selector: "lib-loading-indicator", inputs: ["isLoading"] }, { kind: "component", type: i16.FormFieldToggleComponent, selector: "lib-form-field-toggle", inputs: ["label", "orientation", "labelOn", "labelOff", "toggleOn"], outputs: ["toggleOnChange"] }, { kind: "component", type: i17.JsonViewComponent, selector: "lib-json-view", inputs: ["data", "schema", "readOnly", "jsonInvalid", "showCopy"], outputs: ["dataChange", "jsonChange", "jsonInvalidChange"] }, { kind: "component", type: i18.TagSelectorComponent, selector: "lib-tag-selector", inputs: ["placeholder", "disableField", "disableCreate", "hideOption", "isLoading", "errorMessage", "focusOnInit", "selectedRoleAttributes", "selectedNamedAttributes", "hasError", "availableRoleAttributes", "availableNamedAttributes"], outputs: ["addRoleAttribute", "addNamedAttribute", "roleAttributeRemoved", "namedAttributeRemoved", "selectedRoleAttributesChange", "selectedNamedAttributesChange", "filterChange"] }, { kind: "component", type: i19.CustomTagsComponent, selector: "lib-custom-tags", inputs: ["tags"], outputs: ["tagsChange"] }] }); }
|
|
318
|
+
}
|
|
319
|
+
export { AuthPolicyFormComponent };
|
|
320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthPolicyFormComponent, decorators: [{
|
|
321
|
+
type: Component,
|
|
322
|
+
args: [{ selector: 'lib-configuration', template: "<div class=\"projectable-form-wrapper\"\n (keyup.enter)=\"save($event)\"\n (keyup.escape)=\"closeModal(false)\"\n tabindex=\"0\"\n>\n <lib-form-header\n [data]=\"formData\"\n [title]=\"(formData.id ? 'Auth Policy Details' : 'Create Auth Policy')\"\n [moreActions]=\"formData.moreActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n [(formView)]=\"formView\"\n [saveDisabled]=\"svc.saveDisabled || formDataInvalid\"\n ></lib-form-header>\n <div class=\"jwt-signer-form-container projectable-form-container\">\n <div class=\"projectable-form-main-column form-group-row\" [hidden]=\"formView !== 'simple'\">\n <div class=\"form-group-column three-fifths\">\n <lib-form-field-container\n [title]=\"'Name'\"\n [label]=\"'Required'\"\n >\n <input class=\"form-field-input read-only\" [(ngModel)]=\"formData.name\" [ngClass]=\"{error: errors['name']}\" placeholder=\"Name this JWT Signer\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Primary Authentication'\"\n [layout]=\"'row'\"\n >\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Cert</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow x509 certificate based authentication\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleCertAllowed()\"\n [ngClass]=\"{ on: formData.primary.cert.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.cert.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.cert.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Ext JWT</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow externally signed JWT bearer tokens\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleExtJwtAllowed()\"\n [ngClass]=\"{ on: formData.primary.extJwt.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.extJwt.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.extJwt.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">UPDB</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow authentication via a traditional "Username Password Database"\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbAllowed()\"\n [ngClass]=\"{ on: formData.primary.updb.allowed }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.allowed\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.allowed\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.cert.allowed\"\n [title]=\"'Cert Options'\"\n [layout]=\"'row'\"\n >\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Allow Expired Certificates</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allow expired client certificates to authenticate\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleAllowExpiredCerts()\"\n [ngClass]=\"{ on: formData.primary.cert.allowExpiredCerts }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.cert.allowExpiredCerts\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.cert.allowExpiredCerts\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.extJwt.allowed\"\n [title]=\"'Ext JWT Options'\"\n [layout]=\"'column'\"\n >\n <div class=\"form-field-label-container allowed-signers-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Allowed JWT Signers</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Choose which External JWT Signers may be used for authentication\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"allowedJwtSignerAttributes\"\n [availableNamedAttributes]=\"svc.jwtSignerNamedAttributes\"\n [placeholder]=\"'Select which External JWT Signers to allow'\"\n (selectedNamedAttributesChange)=\"allowedJwtSignersChanged($event)\"\n ></lib-tag-selector>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n *ngIf=\"formData.primary.updb.allowed\"\n [title]=\"'UPDB Options'\"\n [layout]=\"'column'\"\n >\n <div class=\"form-field-row updb-input-options\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Minimum Length</span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter a numeric value\" type=\"number\" [(ngModel)]=\"formData.primary.updb.minPasswordLength\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Max Attempts</span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter a numeric value\" type=\"number\" [(ngModel)]=\"formData.primary.updb.maxAttempts\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Lockout Duration <div class=\"form-sub-text\">(min)</div></span>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter time in min\" type=\"number\" [(ngModel)]=\"formData.primary.updb.lockoutDurationMinutes\"/>\n </div>\n </div>\n <div class=\"form-field-row\">\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Mixed Case</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require upper and lower case charachters\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbMixed()\"\n [ngClass]=\"{ on: formData.primary.updb.requireMixedCase }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireMixedCase\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireMixedCase\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Numeric</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require numerical charachters 0-9\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbNumeric()\"\n [ngClass]=\"{ on: formData.primary.updb.requireNumericChar }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireNumericChar\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireNumericChar\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Special</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require special (non-alpha numeric) charachters. ie. !%$@*\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleUpdbSpecial()\"\n [ngClass]=\"{ on: formData.primary.updb.requireSpecialChar }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.primary.updb.requireSpecialChar\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.primary.updb.requireSpecialChar\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-toggle [(toggleOn)]=\"showMore\" (toggleOnChange)=\"showMoreChanged($event)\" style=\"margin: 0px 10px\"></lib-form-field-toggle>\n <div [hidden]=\"!showMore\" class=\"form-group-column\">\n <lib-form-field-container\n [title]=\"'Custom Tags'\"\n [label]=\"'OPTIONAL'\"\n class=\"form-field-advanced\"\n >\n <lib-custom-tags [(tags)]=\"formData.tags\"></lib-custom-tags>\n </lib-form-field-container>\n </div>\n </div>\n <div class=\"form-group-column two-fifths\">\n <lib-form-field-container\n [title]=\"'Secondary Authentication'\"\n [label]=\"'OPTIONAL'\"\n [layout]=\"'column'\"\n [contentStyle]=\"'z-index: 1000001'\"\n >\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">TOTP MFA</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require authenticating clients to have TOTP MFA enabled (Time-based, One-Time Password)\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div class=\"config-item\">\n <div class=\"config-container toggle-container\">\n <div class=\"form-field-title-container\">\n <div class=\"config-container-label\">Require TOTP</div>\n </div>\n <div\n (click)=\"toggleRequireTotp()\"\n [ngClass]=\"{ on: formData.secondary.requireTotp }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.secondary.requireTotp\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.secondary.requireTotp\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">JWT Signer</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Require every client request to have a JWT from the specified External JTW Signer in the HTTP Authentication header\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <p-dropdown\n placeholder=\"Select JWT Signer...\"\n optionLabel=\"name\"\n optionValue=\"id\"\n filterBy=\"name\"\n [options]=\"svc.jwtSigners\"\n [filter]=\"true\"\n [showClear]=\"true\"\n (change)=\"secondaryJwtSignerChanged($event)\"\n [(ngModel)]=\"formData.secondary.requireExtJwtSigner\"\n >\n <ng-template pTemplate=\"filter\" let-options=\"options\">\n <div class=\"dropdown-filter-container\">\n <div class=\"p-inputgroup\" (click)=\"$event.stopPropagation()\">\n <span class=\"p-inputgroup-addon\"><i class=\"pi pi-search\"></i></span>\n <input\n type=\"text\"\n pInputText\n placeholder=\"Filter\"\n (keyup)=\"jwtSignersFilterChangedDebounced($event)\" />\n </div>\n <button pButton\n icon=\"pi pi-times\"\n [ngClass]=\"{'configs-loading': svc.jwtSignersLoading}\"\n (click)=\"clearJwtSignerFilter($event)\"\n severity=\"secondary\">\n </button>\n <div class=\"spinner\" *ngIf=\"svc.jwtSignersLoading\"></div>\n </div>\n </ng-template>\n </p-dropdown>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'API Calls'\"\n [headerActions]=\"apiOptions\"\n (actionRequested)=\"apiActionRequested($event)\"\n [class]=\"'api-data-no-wrap'\"\n >\n <div class=\"form-row\">\n <input class=\"form-field-input\" [value]=\"apiCallURL\"/>\n <div class=\"icon-copy copy\" (click)=\"copyToClipboard(apiCallURL)\"></div>\n </div>\n <lib-json-view *ngIf=\"formData\" [(data)]=\"apiData\" [readOnly]=\"true\" [showCopy]=\"true\"></lib-json-view>\n </lib-form-field-container>\n </div>\n </div>\n <div class=\"form-group-column\" *ngIf=\"formView === 'raw'\">\n <lib-json-view *ngIf=\"formData\" [(data)]=\"formData\"></lib-json-view>\n </div>\n </div>\n</div>\n<lib-loading-indicator *ngIf=\"isLoading\" [isLoading]=\"isLoading\"></lib-loading-indicator>\n", styles: ["@charset \"UTF-8\";.form-group-column.three-fifths{min-width:500px}.jwt-signer-form-container{display:flex;flex-direction:column;height:100%;width:100%;align-items:center;gap:var(--gapXL)}.jwt-signer-form-container .select-file-button{padding-left:var(--paddingMedium);padding-right:var(--paddingMedium);height:25px;width:-moz-fit-content;width:fit-content;white-space:nowrap;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:14px;background:var(--primary);border-style:solid;border-width:1px;border-color:var(--stroke);color:var(--white);cursor:pointer;border-radius:var(--inputBorderRadius);gap:var(--marginMedium);margin-top:-5px}.jwt-signer-form-container .select-file-button:hover{filter:brightness(.8)}.jwt-signer-form-container .select-file-button:active{filter:grayscale(1);transform:translateY(1px)}.jwt-signer-form-container .select-file-button .spinner{display:inline-block;width:8px;height:8px;border-radius:50%;background:transparent;border-top:2px solid white;border-right:2px solid white;border-bottom:2px solid transparent;border-left:2px solid transparent;animation:loading .5s infinite linear}.jwt-signer-form-container .select-file-label-container{gap:var(--marginMedium)}.jwt-signer-form-container .updb-input-options{margin-top:var(--marginSmall);background-color:var(--formGroup);padding:var(--paddingMedium);border-radius:var(--inputBorderRadius)}.jwt-signer-form-container .updb-input-options .form-field-title{color:var(--offWhite)}::ng-deep .jwt-signer-form-container select:disabled,::ng-deep .jwt-signer-form-container input:disabled{opacity:.75!important;cursor:text;background-color:var(--stroke)!important}::ng-deep .api-data-no-wrap .jse-text-mode{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller{width:100%}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller .cm-content{width:100%;overflow:auto}::ng-deep .api-data-no-wrap .jse-text-mode .cm-editor .cm-scroller .cm-content .\\37cr{white-space:nowrap}.radio-group-container{display:flex;gap:var(--marginLarge)}.radio-group-container:focus .radio-button-container .radio-button-circle{border-color:var(--primaryColor)}.radio-group-container .radio-button-container{display:flex;flex-direction:row;align-items:center;background-color:var(--formGroup);border-radius:var(--inputBorderRadius);width:100%;padding-left:var(--paddingMedium);padding-right:var(--paddingMedium);padding-top:var(--paddingLarge);padding-bottom:var(--paddingLarge);cursor:pointer;gap:var(--marginMedium)}.radio-group-container .radio-button-container .radio-button-circle{display:flex;width:21px;height:21px;border-radius:21px;border-width:2px;border-style:solid;border-color:var(--offWhite);align-items:center;justify-content:center;background-color:var(--offWhite)}.radio-group-container .radio-button-container .radio-button-circle .radio-button-inner-circle{display:none;width:15px;height:15px;border-radius:15px;align-items:center;justify-content:center;background-color:var(--primaryColor)}.radio-group-container .radio-button-container.selected .radio-button-circle .radio-button-inner-circle{display:flex}.radio-group-container .radio-button-container:active .radio-button-circle .radio-button-inner-circle{display:flex;background-color:var(--menu)}.radio-group-container .radio-button-container .radio-button-label{color:var(--offWhite);font-size:14px;font-weight:600}.allowed-signers-container{background-color:var(--formGroup);padding:var(--paddingMedium);border-radius:var(--inputBorderRadius)}.allowed-signers-container .form-field-title{color:var(--offWhite)}\n"] }]
|
|
323
|
+
}], ctorParameters: function () { return [{ type: i1.AuthPolicyFormService }, { type: i2.SchemaService }, { type: i3.GrowlerService }, { type: undefined, decorators: [{
|
|
324
|
+
type: Inject,
|
|
325
|
+
args: [SHAREDZ_EXTENSION]
|
|
326
|
+
}] }, { type: i20.SettingsService, decorators: [{
|
|
327
|
+
type: Inject,
|
|
328
|
+
args: [SETTINGS_SERVICE]
|
|
329
|
+
}] }, { type: i21.ZitiDataService, decorators: [{
|
|
330
|
+
type: Inject,
|
|
331
|
+
args: [ZITI_DATA_SERVICE]
|
|
332
|
+
}] }, { type: i4.Router }, { type: i4.ActivatedRoute }, { type: i5.Location }, { type: i6.ValidationService }]; }, propDecorators: { formData: [{
|
|
333
|
+
type: Input
|
|
334
|
+
}], errors: [{
|
|
335
|
+
type: Input
|
|
336
|
+
}], close: [{
|
|
337
|
+
type: Output
|
|
338
|
+
}], filterInput: [{
|
|
339
|
+
type: ViewChild,
|
|
340
|
+
args: ['fileSelect']
|
|
341
|
+
}] } });
|
|
342
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1wb2xpY3ktZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy96aXRpLWNvbnNvbGUtbGliL3NyYy9saWIvZmVhdHVyZXMvcHJvamVjdGFibGUtZm9ybXMvYXV0aC1wb2xpY3kvYXV0aC1wb2xpY3ktZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy96aXRpLWNvbnNvbGUtbGliL3NyYy9saWIvZmVhdHVyZXMvcHJvamVjdGFibGUtZm9ybXMvYXV0aC1wb2xpY3kvYXV0aC1wb2xpY3ktZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7RUFjRTtBQUVGLE9BQU8sRUFDSCxTQUFTLEVBQ1QsWUFBWSxFQUFFLE1BQU0sRUFDcEIsS0FBSyxFQUVHLE1BQU0sRUFDZCxTQUFTLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFDLFNBQVMsRUFBRSxlQUFlLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUVyRSxPQUFPLEVBQW1CLGlCQUFpQixFQUFDLE1BQU0sMENBQTBDLENBQUM7QUFFN0YsT0FBTyxFQUFDLFNBQVMsRUFBUyxLQUFLLEVBQUUsTUFBTSxFQUFRLE1BQU0sRUFBRSxPQUFPLEVBQVMsS0FBSyxFQUFjLFFBQVEsRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUNsSCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFDLGdCQUFnQixFQUFrQixNQUFNLG9DQUFvQyxDQUFDO0FBQ3JGLE9BQU8sRUFBQyxpQkFBaUIsRUFBa0IsTUFBTSxxQ0FBcUMsQ0FBQztBQUl2RixPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sNkJBQTZCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRXZELE1BS2EsdUJBQXdCLFNBQVEsZUFBZTtJ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Yy5cblxuICAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG4gICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qL1xuXG5pbXBvcnQge1xuICAgIENvbXBvbmVudCwgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsIEluamVjdCxcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LCBPdXRwdXQsXG4gICAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QXV0aFBvbGljeUZvcm1TZXJ2aWNlfSBmcm9tIFwiLi9hdXRoLXBvbGljeS1mb3JtLnNlcnZpY2VcIjtcbmltcG9ydCB7U2NoZW1hU2VydmljZX0gZnJvbSBcIi4uLy4uLy4uL3NlcnZpY2VzL3NjaGVtYS5zZXJ2aWNlXCI7XG5pbXBvcnQge0tFWV9DT0RFUywgUHJvamVjdGFibGVGb3JtfSBmcm9tIFwiLi4vcHJvamVjdGFibGUtZm9ybS5jbGFzc1wiO1xuaW1wb3J0IHtHcm93bGVyU2VydmljZX0gZnJvbSBcIi4uLy4uL21lc3NhZ2luZy9ncm93bGVyLnNlcnZpY2VcIjtcbmltcG9ydCB7RXh0ZW5zaW9uU2VydmljZSwgU0hBUkVEWl9FWFRFTlNJT059IGZyb20gXCIuLi8uLi9leHRlbmRhYmxlL2V4dGVuc2lvbnMtbm9vcC5zZXJ2aWNlXCI7XG5cbmltcG9ydCB7Y2xvbmVEZWVwLCBkZWZlciwgZGVsYXksIGZvck93biwga2V5cywgaW52ZXJ0LCBpc0VtcHR5LCBpc05pbCwgdW5zZXQsIHNvcnRlZFVuaXEsIGRlYm91bmNlfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtHcm93bGVyTW9kZWx9IGZyb20gXCIuLi8uLi9tZXNzYWdpbmcvZ3Jvd2xlci5tb2RlbFwiO1xuaW1wb3J0IHtTRVRUSU5HU19TRVJWSUNFLCBTZXR0aW5nc1NlcnZpY2V9IGZyb20gXCIuLi8uLi8uLi9zZXJ2aWNlcy9zZXR0aW5ncy5zZXJ2aWNlXCI7XG5pbXBvcnQge1pJVElfREFUQV9TRVJWSUNFLCBaaXRpRGF0YVNlcnZpY2V9IGZyb20gXCIuLi8uLi8uLi9zZXJ2aWNlcy96aXRpLWRhdGEuc2VydmljZVwiO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XG5pbXBvcnQge0xvY2F0aW9ufSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1ZhbGlkYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vc2VydmljZXMvdmFsaWRhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQge0F1dGhQb2xpY3l9IGZyb20gXCIuLi8uLi8uLi9tb2RlbHMvYXV0aC1wb2xpY3lcIjtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdsaWItY29uZmlndXJhdGlvbicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2F1dGgtcG9saWN5LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2F1dGgtcG9saWN5LWZvcm0uY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBBdXRoUG9saWN5Rm9ybUNvbXBvbmVudCBleHRlbmRzIFByb2plY3RhYmxlRm9ybSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIEBJbnB1dCgpIG92ZXJyaWRlIGZvcm1EYXRhOiBhbnkgPSBuZXcgQXV0aFBvbGljeSgpO1xuICAgIEBJbnB1dCgpIG92ZXJyaWRlIGVycm9yczogYW55ID0ge307XG4gICAgQE91dHB1dCgpIGNsb3NlOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICBhbGxvd2VkSnd0U2lnbmVyQXR0cmlidXRlcyA9IFtdO1xuXG4gICAgZm9ybVZpZXcgPSAnc2ltcGxlJztcbiAgICBvcHRpb25zOiBhbnlbXSA9IFtdO1xuICAgIGlzRWRpdGluZyA9ICFpc0VtcHR5KHRoaXMuZm9ybURhdGEuaWQpO1xuICAgIGZvcm1EYXRhSW52YWxpZCA9IGZhbHNlO1xuICAgIGVkaXRNb2RlID0gZmFsc2U7XG4gICAgaXRlbXM6IGFueSA9IFtdO1xuICAgIHNldHRpbmdzOiBhbnkgPSB7fTtcbiAgICBmaWxlU2VsZWN0T3BlbmluZyA9IGZhbHNlO1xuICAgIG92ZXJyaWRlIGVudGl0eVR5cGUgPSAnYXV0aC1wb2xpY2llcyc7XG4gICAgb3ZlcnJpZGUgZW50aXR5Q2xhc3MgPSBBdXRoUG9saWN5O1xuXG4gICAgand0U2lnbmVyc0ZpbHRlckNoYW5nZWREZWJvdW5jZWQgPSBkZWJvdW5jZSh0aGlzLmp3dFNpZ25lckZpbHRlckNoYW5nZWQuYmluZCh0aGlzKSwgMjAwKTtcblxuICAgIEBWaWV3Q2hpbGQoJ2ZpbGVTZWxlY3QnKSBmaWx0ZXJJbnB1dDogRWxlbWVudFJlZjtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgc3ZjOiBBdXRoUG9saWN5Rm9ybVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgc2NoZW1hU3ZjOiBTY2hlbWFTZXJ2aWNlLFxuICAgICAgICBncm93bGVyU2VydmljZTogR3Jvd2xlclNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoU0hBUkVEWl9FWFRFTlNJT04pIGV4dFNlcnZpY2U6IEV4dGVuc2lvblNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoU0VUVElOR1NfU0VSVklDRSkgcHVibGljIHNldHRpbmdzU2VydmljZTogU2V0dGluZ3NTZXJ2aWNlLFxuICAgICAgICBASW5qZWN0KFpJVElfREFUQV9TRVJWSUNFKSBvdmVycmlkZSB6aXRpU2VydmljZTogWml0aURhdGFTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByb3RlY3RlZCBvdmVycmlkZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICAgICAgcHJpdmF0ZSB2YWxpZGF0aW9uU2VydmljZTogVmFsaWRhdGlvblNlcnZpY2VcbiAgICApIHtcbiAgICAgICAgc3VwZXIoZ3Jvd2xlclNlcnZpY2UsIGV4dFNlcnZpY2UsIHppdGlTZXJ2aWNlLCByb3V0ZXIsIHJvdXRlLCBsb2NhdGlvbik7XG4gICAgfVxuXG4gICAgb3ZlcnJpZGUgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgICAgIHRoaXMuc3ZjLmdldEp3dFNpZ25lcnMoKTtcbiAgICAgICAgdGhpcy5zdmMuZ2V0Snd0U2lnbmVyTmFtZWRBdHRyaWJ1dGVzKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmluaXRTZWxlY3RlZEF0dHJpYnV0ZXMoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzQ2hhbmdlLnN1YnNjcmliZSgocmVzdWx0czphbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MgPSByZXN1bHRzO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZW50aXR5VXBkYXRlZCgpIHtcbiAgICAgICAgc3VwZXIuZW50aXR5VXBkYXRlZCgpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsZWFyRm9ybSgpO1xuICAgIH1cblxuICAgIGhlYWRlckFjdGlvblJlcXVlc3RlZChldmVudCkge1xuICAgICAgICBzd2l0Y2goZXZlbnQubmFtZSkge1xuICAgICAgICAgICAgY2FzZSAnc2F2ZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2Nsb3NlJzpcbiAgICAgICAgICAgICAgICB0aGlzLnJldHVyblRvTGlzdFBhZ2UoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3RvZ2dsZS12aWV3JzpcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1WaWV3ID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG92ZXJyaWRlIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmZvcm1EYXRhLmNvbmZpZ1R5cGVJZCA9ICcnO1xuICAgICAgICB0aGlzLmNsZWFyRm9ybSgpO1xuICAgIH1cblxuICAgIGNsZWFyRm9ybSgpIHtcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKChpdGVtOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtPy5jb21wb25lbnQpIGl0ZW0uY29tcG9uZW50LmRlc3Ryb3koKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXJyb3JzID0ge307XG4gICAgICAgIHRoaXMuaXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy5mb3JtRGF0YSA9IG5ldyBBdXRoUG9saWN5KCk7XG4gICAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbikgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBhbGxvd2VkSnd0U2lnbmVyc0NoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5mb3JtRGF0YS5wcmltYXJ5LmV4dEp3dC5hbGxvd2VkU2lnbmVycyA9IHRoaXMuZ2V0U2VsZWN0ZWRBdHRyaWJ1dGVzKHRoaXMuYWxsb3dlZEp3dFNpZ25lckF0dHJpYnV0ZXMsIHRoaXMuc3ZjLmp3dFNpZ25lck5hbWVkQXR0cmlidXRlc01hcCk7XG4gICAgfVxuXG4gICAgZ2V0U2VsZWN0ZWRBdHRyaWJ1dGVzKG5hbWVkQXR0cmlidXRlcywgbmFtZWRBdHRyaWJ1dGVNYXApIHtcbiAgICAgICAgY29uc3QgcHJlcGVuZGVkTmFtZWRBdHRyaWJ1dGVzID0gbmFtZWRBdHRyaWJ1dGVzLm1hcCgoYXR0cikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5hbWVkQXR0cmlidXRlTWFwW2F0dHJdO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFsuLi5wcmVwZW5kZWROYW1lZEF0dHJpYnV0ZXNdO1xuICAgIH1cblxuICAgIGluaXRTZWxlY3RlZEF0dHJpYnV0ZXMoKSB7XG4gICAgICAgIGNvbnN0IGp3dFNpZ25lck5hbWVkQXR0cmlidXRlc01hcCA9IGludmVydCh0aGlzLnN2Yy5qd3RTaWduZXJOYW1lZEF0dHJpYnV0ZXNNYXApO1xuICAgICAgICB0aGlzLmZvcm1EYXRhLnByaW1hcnk/LmV4dEp3dD8uYWxsb3dlZFNpZ25lcnM/LmZvckVhY2goYXR0ciA9PiB7XG4gICAgICAgICAgICB0aGlzLmFsbG93ZWRKd3RTaWduZXJBdHRyaWJ1dGVzLnB1c2goand0U2lnbmVyTmFtZWRBdHRyaWJ1dGVzTWFwW2F0dHJdKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2F2ZShldmVudD86IGFueSkge1xuICAgICAgICBpZighdGhpcy52YWxpZGF0ZSgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFnVmFscyA9IHRoaXMuZ2V0VGFnVmFsdWVzKCk7XG4gICAgICAgIGlmICghaXNFbXB0eSh0YWdWYWxzKSkge1xuICAgICAgICAgICAgZm9yT3duKHRhZ1ZhbHMsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRGF0YS50YWdzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaURhdGEgPSB0aGlzLmFwaURhdGE7XG4gICAgICAgIGFwaURhdGEuaWQgPSB0aGlzLmZvcm1EYXRhLmlkO1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuc3ZjLnNhdmUoYXBpRGF0YSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc01vZGFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZU1vZGFsKHRydWUsIHRydWUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaW5pdERhdGEgPSB0aGlzLmZvcm1EYXRhO1xuICAgICAgICAgICAgdGhpcy5fZGF0YUNoYW5nZSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5yZXR1cm5Ub0xpc3RQYWdlKCk7XG4gICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFsaWRhdGUoKSB7XG4gICAgICAgIHRoaXMuZXJyb3JzID0ge307XG4gICAgICAgIGNvbnN0IGxhYmVscyA9IFtdO1xuICAgICAgICBjb25zdCBncm93bGVycyA9IFtdO1xuICAgICAgICBpZiAoaXNFbXB0eSh0aGlzLmZvcm1EYXRhLm5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9ycy5uYW1lID0gdHJ1ZTtcbiAgICAgICAgICAgIGxhYmVscy5wdXNoKCdOYW1lJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0VtcHR5KHRoaXMuZXJyb3JzKSkge1xuICAgICAgICAgICAgbGV0IG1pc3NpbmdGaWVsZHMgPSBsYWJlbHMuam9pbignLCAnKTtcbiAgICAgICAgICAgIGdyb3dsZXJzLnB1c2gobmV3IEdyb3dsZXJNb2RlbChcbiAgICAgICAgICAgICAgICAnZXJyb3InLFxuICAgICAgICAgICAgICAgICdJbnZhbGlkJyxcbiAgICAgICAgICAgICAgICBgTWlzc2luZyBGb3JtIERhdGFgLFxuICAgICAgICAgICAgICAgIGBQbGVhc2UgZW50ZXIgYSB2YWx1ZSBmb3IgdGhlIGhpZ2hsaWdodGVkIGZpZWxkczogJHttaXNzaW5nRmllbGRzfWAsXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRW1wdHkoZ3Jvd2xlcnMpKSB7XG4gICAgICAgICAgICBncm93bGVycy5mb3JFYWNoKChncm93bGVyRGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ3Jvd2xlclNlcnZpY2Uuc2hvdyhncm93bGVyRGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBpc0VtcHR5KHRoaXMuZXJyb3JzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGdyb3dsZXJzLmZvckVhY2goKGdyb3dsZXJEYXRhKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdyb3dsZXJTZXJ2aWNlLnNob3coZ3Jvd2xlckRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGlzRW1wdHkodGhpcy5lcnJvcnMpO1xuICAgIH1cblxuICAgIGdldCBhcGlDYWxsVVJMKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5ncy5zZWxlY3RlZEVkZ2VDb250cm9sbGVyICsgJy9lZGdlL21hbmFnZW1lbnQvdjEvYXV0aC1wb2xpY2llcycgKyAodGhpcy5mb3JtRGF0YS5pZCA/IGAvJHt0aGlzLmZvcm1EYXRhLmlkfWAgOiAnJyk7XG4gICAgfVxuXG4gICAgZ2V0IGFwaURhdGEoKTogYW55IHtcbiAgICAgICAgY29uc3QgZGF0YTogYW55ID0ge1xuICAgICAgICAgICAgbmFtZTogdGhpcy5mb3JtRGF0YS5uYW1lIHx8ICcnLFxuICAgICAgICAgICAgcHJpbWFyeTogdGhpcy5mb3JtRGF0YS5wcmltYXJ5IHx8IHt9LFxuICAgICAgICAgICAgc2Vjb25kYXJ5OiB0aGlzLmZvcm1EYXRhLnNlY29uZGFyeSB8fCB7fSxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMuZm9ybURhdGEudGFncyB8fCB7fVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9hcGlEYXRhID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwaURhdGE7XG4gICAgfVxuXG4gICAgX2FwaURhdGE6IGFueSA9IHt9O1xuICAgIHNldCBhcGlEYXRhKGRhdGEpIHtcbiAgICAgICAgdGhpcy5fYXBpRGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgZGF0YUNoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5fYXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLmFwaURhdGEpO1xuICAgIH1cblxuICAgIHRvZ2dsZUNlcnRBbGxvd2VkKCkge1xuICAgICAgICB0aGlzLmZvcm1EYXRhLnByaW1hcnkuY2VydC5hbGxvd2VkID0gIXRoaXMuZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93ZWQ7XG4gICAgICAgIGlmICghdGhpcy5mb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dlZCkge1xuICAgICAgICAgICAgdGhpcy5mb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dFeHBpcmVkQ2VydHMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvZ2dsZUV4dEp3dEFsbG93ZWQoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEucHJpbWFyeS5leHRKd3QuYWxsb3dlZCA9ICF0aGlzLmZvcm1EYXRhLnByaW1hcnkuZXh0Snd0LmFsbG93ZWQ7XG4gICAgfVxuXG4gICAgdG9nZ2xlVXBkYkFsbG93ZWQoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEucHJpbWFyeS51cGRiLmFsbG93ZWQgPSAhdGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIuYWxsb3dlZDtcbiAgICB9XG5cbiAgICB0b2dnbGVBbGxvd0V4cGlyZWRDZXJ0cygpIHtcbiAgICAgICAgdGhpcy5mb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dFeHBpcmVkQ2VydHMgPSAhdGhpcy5mb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dFeHBpcmVkQ2VydHM7XG4gICAgfVxuXG4gICAgdG9nZ2xlVXBkYk1peGVkKCkge1xuICAgICAgICB0aGlzLmZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlTWl4ZWRDYXNlID0gIXRoaXMuZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVNaXhlZENhc2U7XG4gICAgfVxuXG4gICAgdG9nZ2xlVXBkYk51bWVyaWMoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVOdW1lcmljQ2hhciA9ICF0aGlzLmZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlTnVtZXJpY0NoYXI7XG4gICAgfVxuXG4gICAgdG9nZ2xlVXBkYlNwZWNpYWwoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVTcGVjaWFsQ2hhciA9ICF0aGlzLmZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlU3BlY2lhbENoYXI7XG4gICAgfVxuXG4gICAgdG9nZ2xlUmVxdWlyZVRvdHAoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEuc2Vjb25kYXJ5LnJlcXVpcmVUb3RwID0gIXRoaXMuZm9ybURhdGEuc2Vjb25kYXJ5LnJlcXVpcmVUb3RwO1xuICAgIH1cblxuICAgIG9wZW5GaWxlU2VsZWN0KGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5maWx0ZXJJbnB1dC5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgIHRoaXMuZmlsZVNlbGVjdE9wZW5pbmcgPSB0cnVlO1xuICAgICAgICBkZWxheSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbGVTZWxlY3RPcGVuaW5nID0gZmFsc2U7XG4gICAgICAgIH0sIDEwMDApO1xuICAgIH1cblxuICAgIHNlbGVjdFBlbUZpbGUoZXZlbnQ6IGFueSkge1xuICAgICAgICBjb25zb2xlLmxvZyhldmVudCk7XG4gICAgICAgIGNvbnN0IGZpbGU6IEZpbGUgPSBldmVudD8udGFyZ2V0Py5maWxlc1swXTtcblxuICAgICAgICBpZiAoZmlsZSkge1xuICAgICAgICAgICAgY29uc3QgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IChmaWxlTG9hZGVkRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0RnJvbVNlbGVjdGVkRmlsZTogYW55ID0gZmlsZUxvYWRlZEV2ZW50LnRhcmdldD8ucmVzdWx0O1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy52YWxpZGF0aW9uU2VydmljZS5pc1ZhbGlkUEVNKHRleHRGcm9tU2VsZWN0ZWRGaWxlPy50cmltKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JzLmNlcnRQZW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBncm93bGVyRGF0YSA9IG5ldyBHcm93bGVyTW9kZWwoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ludmFsaWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYENlcnQgUEVNIEludmFsaWRgLFxuICAgICAgICAgICAgICAgICAgICAgICAgYFRoZSBmaWxlIHNlbGVjdGVkIGZvciB0aGUgQ2VydCBQRU0gZmllbGQgaXMgaW52YWxpZC4gUGxlYXNlIGNoZWNrIHlvdXIgaW5wdXQgYW5kIHRyeSBhZ2Fpbi5gLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdyb3dsZXJTZXJ2aWNlLnNob3coZ3Jvd2xlckRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1EYXRhLmNlcnRQZW0gPSAnSW52YWxpZCBQRU0uIFBsZWFzZSBzZWxlY3Qgb3IgZW50ZXIgYSB2YWxpZCBQRU0gY2VydGlmaWNhdGUuJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1bnNldCh0aGlzLmVycm9ycywgJ2NlcnRQZW0nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtRGF0YS5jZXJ0UGVtID0gdGV4dEZyb21TZWxlY3RlZEZpbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzVGV4dChmaWxlLCBcIlVURi04XCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXBpQWN0aW9uUmVxdWVzdGVkKGFjdGlvbikge1xuICAgICAgICBzd2l0Y2ggKGFjdGlvbi5pZCkge1xuICAgICAgICAgICAgY2FzZSAnY2xpJzpcbiAgICAgICAgICAgICAgICB0aGlzLmNvcHlDTElDb21tYW5kKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdjdXJsJzpcbiAgICAgICAgICAgICAgICB0aGlzLmNvcHlDVVJMQ29tbWFuZCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29weUNMSUNvbW1hbmQoKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBgeml0aSBlZGdlICR7dGhpcy5mb3JtRGF0YS5pZCA/ICd1cGRhdGUnIDogJ2NyZWF0ZSd9IGF1dGgtcG9saWN5ICR7dGhpcy5mb3JtRGF0YS5pZCA/IGAnJHt0aGlzLmZvcm1EYXRhLmlkfSdgIDogJyd9ICR7dGhpcy5mb3JtRGF0YS5pZCA/ICctLW5hbWUnIDogJyd9ICcke3RoaXMuZm9ybURhdGEubmFtZX0nIC0tcHJpbWFyeS1jZXJ0LWFsbG93ZWQgJyR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dlZH0nIC0tcHJpbWFyeS1jZXJ0LWV4cGlyZWQtYWxsb3dlZCAnJHt0aGlzLmZvcm1EYXRhLnByaW1hcnkuY2VydC5hbGxvd0V4cGlyZWRDZXJ0c30nIC0tcHJpbWFyeS1leHQtand0LWFsbG93ZWQgJyR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LmV4dEp3dC5hbGxvd2VkfScgLS1wcmltYXJ5LWV4dC1qd3QtYWxsb3dlZC1zaWduZXJzICR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LmV4dEp3dC5hbGxvd2VkU2lnbmVycy5qb2luKCcsJykgfHwgJyd9IC0tcHJpbWFyeS11cGRiLWFsbG93ZWQgJyR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIuYWxsb3dlZH0nIC0tcHJpbWFyeS11cGRiLWxvY2tvdXQtbWluICR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIubG9ja291dER1cmF0aW9uTWludXRlc30gLS1wcmltYXJ5LXVwZGItbWF4LWF0dGVtcHRzICR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIubWF4QXR0ZW1wdHN9IC0tcHJpbWFyeS11cGRiLW1pbi1sZW5ndGggJHt0aGlzLmZvcm1EYXRhLnByaW1hcnkudXBkYi5taW5QYXNzd29yZExlbmd0aH0gLS1wcmltYXJ5LXVwZGItcmVxLW1peGVkLWNhc2UgJyR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIucmVxdWlyZU1peGVkQ2FzZX0nIC0tcHJpbWFyeS11cGRiLXJlcS1udW1iZXJzICcke3RoaXMuZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVOdW1iZXJDaGFyfScgLS1wcmltYXJ5LXVwZGItcmVxLXNwZWNpYWwgJyR7dGhpcy5mb3JtRGF0YS5wcmltYXJ5LnVwZGIucmVxdWlyZVNwZWNpYWxDaGFyfScgLS1zZWNvbmRhcnktcmVxLWV4dC1qd3Qtc2lnbmVyICcke3RoaXMuZm9ybURhdGEuc2Vjb25kYXJ5LnJlcXVpcmVFeHRKd3RTaWduZXJ9JyAtLXNlY29uZGFyeS1yZXEtdG90cCAnJHt0aGlzLmZvcm1EYXRhLnNlY29uZGFyeS5yZXF1aXJlVG90cH0nIC0tdGFncy1qc29uICcke0pTT04uc3RyaW5naWZ5KHRoaXMuZm9ybURhdGEudGFncyl9J2A7XG5cbiAgICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoY29tbWFuZCk7XG4gICAgICAgIGNvbnN0IGdyb3dsZXJEYXRhID0gbmV3IEdyb3dsZXJNb2RlbChcbiAgICAgICAgICAgICdzdWNjZXNzJyxcbiAgICAgICAgICAgICdTdWNjZXNzJyxcbiAgICAgICAgICAgIGBUZXh0IENvcGllZGAsXG4gICAgICAgICAgICBgQ0xJIGNvbW1hbmQgY29waWVkIHRvIGNsaXBib2FyZGAsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuZ3Jvd2xlclNlcnZpY2Uuc2hvdyhncm93bGVyRGF0YSk7XG4gICAgfVxuXG4gICAgY29weUNVUkxDb21tYW5kKCkge1xuICAgICAgICBjb25zdCBjb21tYW5kID0gYGN1cmwgJyR7dGhpcy5hcGlDYWxsVVJMfScgXFxcXFxuICAgICR7dGhpcy5mb3JtRGF0YS5pZCA/ICctLXJlcXVlc3QgUEFUQ0ggXFxcXCcgOiAnXFxcXCd9XG4gICAgLUggJ2FjY2VwdDogYXBwbGljYXRpb24vanNvbicgXFxcXFxuICAgIC1IICdjb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL2pzb24nIFxcXFxcbiAgICAtSCAnenQtc2Vzc2lvbjogJHt0aGlzLnNldHRpbmdzLnNlc3Npb24uaWR9JyBcXFxcXG4gICAgLS1kYXRhLXJhdyAnJHtKU09OLnN0cmluZ2lmeSh0aGlzLmFwaURhdGEpfSdgO1xuXG4gICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KGNvbW1hbmQpO1xuICAgICAgICBjb25zdCBncm93bGVyRGF0YSA9IG5ldyBHcm93bGVyTW9kZWwoXG4gICAgICAgICAgICAnc3VjY2VzcycsXG4gICAgICAgICAgICAnU3VjY2VzcycsXG4gICAgICAgICAgICBgVGV4dCBDb3BpZWRgLFxuICAgICAgICAgICAgYENVUkwgY29tbWFuZCBjb3BpZWQgdG8gY2xpcGJvYXJkYCxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5ncm93bGVyU2VydmljZS5zaG93KGdyb3dsZXJEYXRhKTtcbiAgICB9XG5cbiAgICBzY29wZXNPbktleXVwKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gZXZlbnQua2V5Py50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoa2V5ID09PSBcIiBcIiB8fCBrZXkgPT09ICdlbnRlcicpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgICBlbGVtZW50LmJsdXIoKTtcbiAgICAgICAgICAgIGVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGp3dFNpZ25lckZpbHRlckNoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50Py5rZXlDb2RlID09PSBLRVlfQ09ERVMuTEVGVF9BUlJPVyB8fCBldmVudD8ua2V5Q29kZSA9PT0gS0VZX0NPREVTLlJJR0hUX0FSUk9XIHx8IGV2ZW50Py5rZXlDb2RlID09PSBLRVlfQ09ERVMuVVBfQVJST1cgfHwgZXZlbnQ/LmtleUNvZGUgPT09IEtFWV9DT0RFUy5ET1dOX0FSUk9XKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGZpbHRlcnMgPSBbXTtcbiAgICAgICAgaWYgKGV2ZW50Py50YXJnZXQ/LnZhbHVlKSB7XG4gICAgICAgICAgICBmaWx0ZXJzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvbHVtbklkOiAnbmFtZScsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZSxcbiAgICAgICAgICAgICAgICBsYWJlbDogZXZlbnQudGFyZ2V0LnZhbHVlLFxuICAgICAgICAgICAgICAgIGZpbHRlck5hbWU6ICdOYW1lJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnVEVYVElOUFVUJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3ZjLmdldEp3dFNpZ25lcnMoZmlsdGVycywxKTtcbiAgICB9XG5cbiAgICBzZWNvbmRhcnlKd3RTaWduZXJDaGFuZ2VkKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc3ZjLmZpbHRlcmVkSnd0U2lnbmVycyA9IHRoaXMuc3ZjLmp3dFNpZ25lcnMuZmlsdGVyKChqd3RTaWduZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqd3RTaWduZXIuaWQgPT09IHRoaXMuZm9ybURhdGEuc2Vjb25kYXJ5LnJlcXVpcmVFeHRKd3RTaWduZXI7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNsZWFySnd0U2lnbmVyRmlsdGVyKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5zdmMuZ2V0Snd0U2lnbmVycyhmaWx0ZXJzLDEpO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwcm9qZWN0YWJsZS1mb3JtLXdyYXBwZXJcIlxuICAgICAoa2V5dXAuZW50ZXIpPVwic2F2ZSgkZXZlbnQpXCJcbiAgICAgKGtleXVwLmVzY2FwZSk9XCJjbG9zZU1vZGFsKGZhbHNlKVwiXG4gICAgIHRhYmluZGV4PVwiMFwiXG4+XG4gICAgPGxpYi1mb3JtLWhlYWRlclxuICAgICAgICAgICAgW2RhdGFdPVwiZm9ybURhdGFcIlxuICAgICAgICAgICAgW3RpdGxlXT1cIihmb3JtRGF0YS5pZCA/ICdBdXRoIFBvbGljeSBEZXRhaWxzJyA6ICdDcmVhdGUgQXV0aCBQb2xpY3knKVwiXG4gICAgICAgICAgICBbbW9yZUFjdGlvbnNdPVwiZm9ybURhdGEubW9yZUFjdGlvbnNcIlxuICAgICAgICAgICAgKGFjdGlvblJlcXVlc3RlZCk9XCJoZWFkZXJBY3Rpb25SZXF1ZXN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICBbKGZvcm1WaWV3KV09XCJmb3JtVmlld1wiXG4gICAgICAgICAgICBbc2F2ZURpc2FibGVkXT1cInN2Yy5zYXZlRGlzYWJsZWQgfHwgZm9ybURhdGFJbnZhbGlkXCJcbiAgICA+PC9saWItZm9ybS1oZWFkZXI+XG4gICAgPGRpdiBjbGFzcz1cImp3dC1zaWduZXItZm9ybS1jb250YWluZXIgcHJvamVjdGFibGUtZm9ybS1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInByb2plY3RhYmxlLWZvcm0tbWFpbi1jb2x1bW4gZm9ybS1ncm91cC1yb3dcIiBbaGlkZGVuXT1cImZvcm1WaWV3ICE9PSAnc2ltcGxlJ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAtY29sdW1uIHRocmVlLWZpZnRoc1wiPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInTmFtZSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidSZXF1aXJlZCdcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1maWVsZC1pbnB1dCByZWFkLW9ubHlcIiBbKG5nTW9kZWwpXT1cImZvcm1EYXRhLm5hbWVcIiBbbmdDbGFzc109XCJ7ZXJyb3I6IGVycm9yc1snbmFtZSddfVwiIHBsYWNlaG9sZGVyPVwiTmFtZSB0aGlzIEpXVCBTaWduZXJcIi8+XG4gICAgICAgICAgICAgICAgPC9saWItZm9ybS1maWVsZC1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidQcmltYXJ5IEF1dGhlbnRpY2F0aW9uJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGF5b3V0XT1cIidyb3cnXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lci1sYWJlbFwiPkNlcnQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiQWxsb3cgeDUwOSBjZXJ0aWZpY2F0ZSBiYXNlZCBhdXRoZW50aWNhdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNlcnRBbGxvd2VkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBvbjogZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93ZWQgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRvZ2dsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cIiFmb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dlZFwiIGNsYXNzPVwib24tbGFiZWxcIj5ZRVM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93ZWRcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lci1sYWJlbFwiPkV4dCBKV1Q8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiQWxsb3cgZXh0ZXJuYWxseSBzaWduZWQgSldUIGJlYXJlciB0b2tlbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVFeHRKd3RBbGxvd2VkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBvbjogZm9ybURhdGEucHJpbWFyeS5leHRKd3QuYWxsb3dlZCB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidG9nZ2xlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiIWZvcm1EYXRhLnByaW1hcnkuZXh0Snd0LmFsbG93ZWRcIiBjbGFzcz1cIm9uLWxhYmVsXCI+WUVTPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cImZvcm1EYXRhLnByaW1hcnkuZXh0Snd0LmFsbG93ZWRcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lci1sYWJlbFwiPlVQREI8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiQWxsb3cgYXV0aGVudGljYXRpb24gdmlhIGEgdHJhZGl0aW9uYWwgJnF1b3Q7VXNlcm5hbWUgUGFzc3dvcmQgRGF0YWJhc2UmcXVvdDtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVVcGRiQWxsb3dlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgb246IGZvcm1EYXRhLnByaW1hcnkudXBkYi5hbGxvd2VkIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhZm9ybURhdGEucHJpbWFyeS51cGRiLmFsbG93ZWRcIiBjbGFzcz1cIm9uLWxhYmVsXCI+WUVTPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cImZvcm1EYXRhLnByaW1hcnkudXBkYi5hbGxvd2VkXCIgY2xhc3M9XCJvZmYtbGFiZWxcIj5OTzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN3aXRjaFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93ZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidDZXJ0IE9wdGlvbnMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsYXlvdXRdPVwiJ3JvdydcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lciB0b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctY29udGFpbmVyLWxhYmVsXCI+QWxsb3cgRXhwaXJlZCBDZXJ0aWZpY2F0ZXM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiQWxsb3cgZXhwaXJlZCBjbGllbnQgY2VydGlmaWNhdGVzIHRvIGF1dGhlbnRpY2F0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUFsbG93RXhwaXJlZENlcnRzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBvbjogZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93RXhwaXJlZENlcnRzIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhZm9ybURhdGEucHJpbWFyeS5jZXJ0LmFsbG93RXhwaXJlZENlcnRzXCIgY2xhc3M9XCJvbi1sYWJlbFwiPllFUzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCJmb3JtRGF0YS5wcmltYXJ5LmNlcnQuYWxsb3dFeHBpcmVkQ2VydHNcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9saWItZm9ybS1maWVsZC1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJmb3JtRGF0YS5wcmltYXJ5LmV4dEp3dC5hbGxvd2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInRXh0IEpXVCBPcHRpb25zJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGF5b3V0XT1cIidjb2x1bW4nXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWxhYmVsLWNvbnRhaW5lciBhbGxvd2VkLXNpZ25lcnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5BbGxvd2VkIEpXVCBTaWduZXJzPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJDaG9vc2Ugd2hpY2ggRXh0ZXJuYWwgSldUIFNpZ25lcnMgbWF5IGJlIHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItdGFnLXNlbGVjdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsoc2VsZWN0ZWROYW1lZEF0dHJpYnV0ZXMpXT1cImFsbG93ZWRKd3RTaWduZXJBdHRyaWJ1dGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F2YWlsYWJsZU5hbWVkQXR0cmlidXRlc109XCJzdmMuand0U2lnbmVyTmFtZWRBdHRyaWJ1dGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidTZWxlY3Qgd2hpY2ggRXh0ZXJuYWwgSldUIFNpZ25lcnMgdG8gYWxsb3cnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkTmFtZWRBdHRyaWJ1dGVzQ2hhbmdlKT1cImFsbG93ZWRKd3RTaWduZXJzQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L2xpYi10YWctc2VsZWN0b3I+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZm9ybURhdGEucHJpbWFyeS51cGRiLmFsbG93ZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidVUERCIE9wdGlvbnMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsYXlvdXRdPVwiJ2NvbHVtbidcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtcm93IHVwZGItaW5wdXQtb3B0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtbGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPk1pbmltdW0gTGVuZ3RoPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXRcIiBwbGFjZWhvbGRlcj1cIkVudGVyIGEgbnVtZXJpYyB2YWx1ZVwiIHR5cGU9XCJudW1iZXJcIiBbKG5nTW9kZWwpXT1cImZvcm1EYXRhLnByaW1hcnkudXBkYi5taW5QYXNzd29yZExlbmd0aFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtbGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPk1heCBBdHRlbXB0czwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJFbnRlciBhIG51bWVyaWMgdmFsdWVcIiB0eXBlPVwibnVtYmVyXCIgWyhuZ01vZGVsKV09XCJmb3JtRGF0YS5wcmltYXJ5LnVwZGIubWF4QXR0ZW1wdHNcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWxhYmVsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5Mb2Nrb3V0IER1cmF0aW9uIDxkaXYgY2xhc3M9XCJmb3JtLXN1Yi10ZXh0XCI+KG1pbik8L2Rpdj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1maWVsZC1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiRW50ZXIgdGltZSBpbiBtaW5cIiB0eXBlPVwibnVtYmVyXCIgWyhuZ01vZGVsKV09XCJmb3JtRGF0YS5wcmltYXJ5LnVwZGIubG9ja291dER1cmF0aW9uTWludXRlc1wiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lciB0b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXItbGFiZWxcIj5NaXhlZCBDYXNlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlJlcXVpcmUgdXBwZXIgYW5kIGxvd2VyIGNhc2UgY2hhcmFjaHRlcnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJiZWxvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVVwZGJNaXhlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7IG9uOiBmb3JtRGF0YS5wcmltYXJ5LnVwZGIucmVxdWlyZU1peGVkQ2FzZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRvZ2dsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiIWZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlTWl4ZWRDYXNlXCIgY2xhc3M9XCJvbi1sYWJlbFwiPllFUzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVNaXhlZENhc2VcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN3aXRjaFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctY29udGFpbmVyLWxhYmVsXCI+TnVtZXJpYzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJSZXF1aXJlIG51bWVyaWNhbCBjaGFyYWNodGVycyAwLTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJiZWxvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVVwZGJOdW1lcmljKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgb246IGZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlTnVtZXJpY0NoYXIgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cIiFmb3JtRGF0YS5wcmltYXJ5LnVwZGIucmVxdWlyZU51bWVyaWNDaGFyXCIgY2xhc3M9XCJvbi1sYWJlbFwiPllFUzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVOdW1lcmljQ2hhclwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lciB0b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXItbGFiZWxcIj5TcGVjaWFsPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlJlcXVpcmUgc3BlY2lhbCAobm9uLWFscGhhIG51bWVyaWMpIGNoYXJhY2h0ZXJzLiBpZS4gISUkQCpcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJiZWxvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVVwZGJTcGVjaWFsKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgb246IGZvcm1EYXRhLnByaW1hcnkudXBkYi5yZXF1aXJlU3BlY2lhbENoYXIgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cIiFmb3JtRGF0YS5wcmltYXJ5LnVwZGIucmVxdWlyZVNwZWNpYWxDaGFyXCIgY2xhc3M9XCJvbi1sYWJlbFwiPllFUzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEucHJpbWFyeS51cGRiLnJlcXVpcmVTcGVjaWFsQ2hhclwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC10b2dnbGUgWyh0b2dnbGVPbildPVwic2hvd01vcmVcIiAodG9nZ2xlT25DaGFuZ2UpPVwic2hvd01vcmVDaGFuZ2VkKCRldmVudClcIiBzdHlsZT1cIm1hcmdpbjogMHB4IDEwcHhcIj48L2xpYi1mb3JtLWZpZWxkLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICA8ZGl2IFtoaWRkZW5dPVwiIXNob3dNb3JlXCIgY2xhc3M9XCJmb3JtLWdyb3VwLWNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidDdXN0b20gVGFncydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCInT1BUSU9OQUwnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtYWR2YW5jZWRcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWN1c3RvbS10YWdzIFsodGFncyldPVwiZm9ybURhdGEudGFnc1wiPjwvbGliLWN1c3RvbS10YWdzPlxuICAgICAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAtY29sdW1uIHR3by1maWZ0aHNcIj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1NlY29uZGFyeSBBdXRoZW50aWNhdGlvbidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidPUFRJT05BTCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xheW91dF09XCInY29sdW1uJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGVudFN0eWxlXT1cIid6LWluZGV4OiAxMDAwMDAxJ1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1sYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPlRPVFAgTUZBPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJSZXF1aXJlIGF1dGhlbnRpY2F0aW5nIGNsaWVudHMgdG8gaGF2ZSBUT1RQIE1GQSBlbmFibGVkIChUaW1lLWJhc2VkLCBPbmUtVGltZSBQYXNzd29yZClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctY29udGFpbmVyLWxhYmVsXCI+UmVxdWlyZSBUT1RQPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVJlcXVpcmVUb3RwKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgb246IGZvcm1EYXRhLnNlY29uZGFyeS5yZXF1aXJlVG90cCB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRvZ2dsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiIWZvcm1EYXRhLnNlY29uZGFyeS5yZXF1aXJlVG90cFwiIGNsYXNzPVwib24tbGFiZWxcIj5ZRVM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cImZvcm1EYXRhLnNlY29uZGFyeS5yZXF1aXJlVG90cFwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1sYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPkpXVCBTaWduZXI8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWZpZWxkLWluZm8gaW5mb2ljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlJlcXVpcmUgZXZlcnkgY2xpZW50IHJlcXVlc3QgdG8gaGF2ZSBhIEpXVCBmcm9tIHRoZSBzcGVjaWZpZWQgRXh0ZXJuYWwgSlRXIFNpZ25lciBpbiB0aGUgSFRUUCBBdXRoZW50aWNhdGlvbiBoZWFkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtZHJvcGRvd25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgSldUIFNpZ25lci4uLlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbkxhYmVsPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvblZhbHVlPVwiaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJCeT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJzdmMuand0U2lnbmVyc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWx0ZXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2Vjb25kYXJ5Snd0U2lnbmVyQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJmb3JtRGF0YS5zZWNvbmRhcnkucmVxdWlyZUV4dEp3dFNpZ25lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImZpbHRlclwiIGxldC1vcHRpb25zPVwib3B0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tZmlsdGVyLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtaW5wdXRncm91cFwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInAtaW5wdXRncm91cC1hZGRvblwiPjxpIGNsYXNzPVwicGkgcGktc2VhcmNoXCI+PC9pPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXl1cCk9XCJqd3RTaWduZXJzRmlsdGVyQ2hhbmdlZERlYm91bmNlZCgkZXZlbnQpXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS10aW1lc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnY29uZmlncy1sb2FkaW5nJzogc3ZjLmp3dFNpZ25lcnNMb2FkaW5nfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhckp3dFNpZ25lckZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk9XCJzZWNvbmRhcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXJcIiAqbmdJZj1cInN2Yy5qd3RTaWduZXJzTG9hZGluZ1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWRyb3Bkb3duPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0FQSSBDYWxscydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2hlYWRlckFjdGlvbnNdPVwiYXBpT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoYWN0aW9uUmVxdWVzdGVkKT1cImFwaUFjdGlvblJlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCInYXBpLWRhdGEtbm8td3JhcCdcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0XCIgW3ZhbHVlXT1cImFwaUNhbGxVUkxcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1jb3B5IGNvcHlcIiAoY2xpY2spPVwiY29weVRvQ2xpcGJvYXJkKGFwaUNhbGxVUkwpXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8bGliLWpzb24tdmlldyAqbmdJZj1cImZvcm1EYXRhXCIgWyhkYXRhKV09XCJhcGlEYXRhXCIgW3JlYWRPbmx5XT1cInRydWVcIiBbc2hvd0NvcHldPVwidHJ1ZVwiPjwvbGliLWpzb24tdmlldz5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAtY29sdW1uXCIgKm5nSWY9XCJmb3JtVmlldyA9PT0gJ3JhdydcIj5cbiAgICAgICAgICAgIDxsaWItanNvbi12aWV3ICpuZ0lmPVwiZm9ybURhdGFcIiBbKGRhdGEpXT1cImZvcm1EYXRhXCI+PC9saWItanNvbi12aWV3PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuPGxpYi1sb2FkaW5nLWluZGljYXRvciAqbmdJZj1cImlzTG9hZGluZ1wiIFtpc0xvYWRpbmddPVwiaXNMb2FkaW5nXCI+PC9saWItbG9hZGluZy1pbmRpY2F0b3I+XG4iXX0=
|