@openziti/ziti-console-lib 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fonts/icomoon.eot +0 -0
- package/assets/fonts/icomoon.svg +118 -0
- package/assets/fonts/icomoon.ttf +0 -0
- package/assets/fonts/icomoon.woff +0 -0
- package/assets/fonts/icomoon.woff2 +0 -0
- package/assets/styles/dark.css +10 -0
- package/assets/styles/global.scss +182 -9
- package/assets/styles/icons.css +13 -0
- package/assets/styles/ziti.css +8 -2
- package/esm2022/lib/features/creation-summary-dialog/creation-summary-dialog.component.mjs +1 -1
- package/esm2022/lib/features/dynamic-widgets/password/password-input.component.mjs +9 -7
- package/esm2022/lib/features/dynamic-widgets/string/string-input.component.mjs +9 -7
- package/esm2022/lib/features/messaging/growler.component.mjs +2 -2
- package/esm2022/lib/features/preview-selections/preview-selections.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/auth-policy/auth-policy-form.component.mjs +3 -3
- package/esm2022/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.mjs +403 -0
- package/esm2022/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.mjs +108 -0
- package/esm2022/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.mjs +222 -0
- package/esm2022/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.mjs +55 -0
- package/esm2022/lib/features/projectable-forms/configuration/configuration-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/edge-router/edge-router-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/form-field-container/form-field-container.component.mjs +24 -3
- package/esm2022/lib/features/projectable-forms/form-header/form-header.component.mjs +15 -3
- package/esm2022/lib/features/projectable-forms/identity/identity-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/service/service-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/service/simple-service/simple-service.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/service-policy/service-policy-form.component.mjs +1 -1
- package/esm2022/lib/features/projectable-forms/terminator/terminator-form.component.mjs +1 -1
- package/esm2022/lib/features/sidebars/side-banner/side-banner.component.mjs +2 -2
- package/esm2022/lib/features/sidebars/side-toolbar/side-toolbar.component.mjs +2 -2
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.component.mjs +13 -9
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.helper.mjs +6 -6
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.treenodeprocessor.mjs +12 -12
- package/esm2022/lib/models/certificate-authority.mjs +16 -0
- package/esm2022/lib/pages/auth-policies/auth-policies-page.component.mjs +3 -3
- package/esm2022/lib/pages/certificate-authorities/certificate-authorities-page.component.mjs +120 -0
- package/esm2022/lib/pages/certificate-authorities/certificate-authorities-page.service.mjs +237 -0
- package/esm2022/lib/pages/configurations/configurations-page.component.mjs +36 -3
- package/esm2022/lib/services/validation.service.mjs +3 -12
- package/esm2022/lib/services/ziti-controller-data.service.mjs +23 -5
- package/esm2022/lib/services/ziti-data.service.mjs +20 -1
- package/esm2022/lib/shared/list-page-component.class.mjs +1 -1
- package/esm2022/lib/shared/list-page-service.class.mjs +22 -1
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/lib/ziti-console-lib.module.mjs +12 -3
- package/esm2022/public-api.mjs +6 -1
- package/fesm2022/openziti-ziti-console-lib.mjs +1409 -219
- package/fesm2022/openziti-ziti-console-lib.mjs.map +1 -1
- package/lib/features/dynamic-widgets/password/password-input.component.d.ts +2 -0
- package/lib/features/dynamic-widgets/password/password-input.component.d.ts.map +1 -1
- package/lib/features/dynamic-widgets/string/string-input.component.d.ts +2 -0
- package/lib/features/dynamic-widgets/string/string-input.component.d.ts.map +1 -1
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.d.ts +81 -0
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.d.ts.map +1 -0
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.d.ts +37 -0
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.d.ts.map +1 -0
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.d.ts +63 -0
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.d.ts.map +1 -0
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.d.ts +28 -0
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.d.ts.map +1 -0
- package/lib/features/projectable-forms/form-field-container/form-field-container.component.d.ts +5 -1
- package/lib/features/projectable-forms/form-field-container/form-field-container.component.d.ts.map +1 -1
- package/lib/features/projectable-forms/form-header/form-header.component.d.ts +5 -1
- package/lib/features/projectable-forms/form-header/form-header.component.d.ts.map +1 -1
- package/lib/features/visualizer/network-visualizer/network-visualizer.component.d.ts.map +1 -1
- package/lib/models/certificate-authority.d.ts +14 -0
- package/lib/models/certificate-authority.d.ts.map +1 -0
- package/lib/pages/certificate-authorities/certificate-authorities-page.component.d.ts +30 -0
- package/lib/pages/certificate-authorities/certificate-authorities-page.component.d.ts.map +1 -0
- package/lib/pages/certificate-authorities/certificate-authorities-page.service.d.ts +35 -0
- package/lib/pages/certificate-authorities/certificate-authorities-page.service.d.ts.map +1 -0
- package/lib/pages/configurations/configurations-page.component.d.ts +1 -0
- package/lib/pages/configurations/configurations-page.component.d.ts.map +1 -1
- package/lib/services/validation.service.d.ts.map +1 -1
- package/lib/services/ziti-controller-data.service.d.ts +2 -2
- package/lib/services/ziti-controller-data.service.d.ts.map +1 -1
- package/lib/services/ziti-data.service.d.ts +3 -2
- package/lib/services/ziti-data.service.d.ts.map +1 -1
- package/lib/shared/list-page-component.class.d.ts.map +1 -1
- package/lib/shared/list-page-service.class.d.ts +2 -0
- package/lib/shared/list-page-service.class.d.ts.map +1 -1
- package/lib/ziti-console-lib.module.d.ts +21 -18
- package/lib/ziti-console-lib.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +5 -0
- package/public-api.d.ts.map +1 -1
|
@@ -0,0 +1,403 @@
|
|
|
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 { ProjectableForm } from "../projectable-form.class";
|
|
18
|
+
import { SHAREDZ_EXTENSION } from "../../extendable/extensions-noop.service";
|
|
19
|
+
import { cloneDeep, delay, forOwn, isEmpty, unset } 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 { CertificateAuthority } from "../../../models/certificate-authority";
|
|
24
|
+
import * as i0 from "@angular/core";
|
|
25
|
+
import * as i1 from "./certificate-authority-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 "@angular/material/tooltip";
|
|
33
|
+
import * as i9 from "../form-header/form-header.component";
|
|
34
|
+
import * as i10 from "../form-field-container/form-field-container.component";
|
|
35
|
+
import * as i11 from "../../loading-indicator/loading-indicator.component";
|
|
36
|
+
import * as i12 from "../form-field-toggle/form-field-toggle.component";
|
|
37
|
+
import * as i13 from "../../json-view/json-view.component";
|
|
38
|
+
import * as i14 from "../../tag-selector/tag-selector.component";
|
|
39
|
+
import * as i15 from "../../custom-tags/custom-tags.component";
|
|
40
|
+
import * as i16 from "../../../services/settings.service";
|
|
41
|
+
import * as i17 from "../../../services/ziti-data.service";
|
|
42
|
+
class CertificateAuthorityFormComponent extends ProjectableForm {
|
|
43
|
+
constructor(svc, schemaSvc, growlerService, extService, settingsService, zitiService, router, route, location, validationService) {
|
|
44
|
+
super(growlerService, extService, zitiService, router, route, location);
|
|
45
|
+
this.svc = svc;
|
|
46
|
+
this.schemaSvc = schemaSvc;
|
|
47
|
+
this.settingsService = settingsService;
|
|
48
|
+
this.zitiService = zitiService;
|
|
49
|
+
this.router = router;
|
|
50
|
+
this.route = route;
|
|
51
|
+
this.validationService = validationService;
|
|
52
|
+
this.formData = new CertificateAuthority();
|
|
53
|
+
this.errors = {};
|
|
54
|
+
this.close = new EventEmitter();
|
|
55
|
+
this._externalIdClaim = false;
|
|
56
|
+
this.formView = 'simple';
|
|
57
|
+
this.options = [];
|
|
58
|
+
this.isEditing = !isEmpty(this.formData.id);
|
|
59
|
+
this.formDataInvalid = false;
|
|
60
|
+
this.editMode = false;
|
|
61
|
+
this.items = [];
|
|
62
|
+
this.settings = {};
|
|
63
|
+
this.fileSelectOpening = false;
|
|
64
|
+
this.identityRoleAttributes = [];
|
|
65
|
+
this.badges = [];
|
|
66
|
+
this.entityType = 'cas';
|
|
67
|
+
this.entityClass = CertificateAuthority;
|
|
68
|
+
this.locations = ['COMMON_NAME', 'SAN_URI', 'SAN_EMAIL'];
|
|
69
|
+
this.matchers = ['ALL', 'PREFIX', 'SUFFIX', 'SCHEME'];
|
|
70
|
+
this.parsers = ['NONE', 'SPLIT'];
|
|
71
|
+
this._apiData = {};
|
|
72
|
+
}
|
|
73
|
+
ngOnInit() {
|
|
74
|
+
super.ngOnInit();
|
|
75
|
+
this.svc.getIdentityRoleAttributes().then((results) => {
|
|
76
|
+
this.identityRoleAttributes = results?.data || [];
|
|
77
|
+
});
|
|
78
|
+
this.settingsService.settingsChange.subscribe((results) => {
|
|
79
|
+
this.settings = results;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
entityUpdated() {
|
|
83
|
+
if (this.formData.id && this.formData.isVerified) {
|
|
84
|
+
this.badges.push({ label: 'Verified', class: 'verified', circle: 'verified' });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.badges.push({ label: 'Unverified', class: 'unreg' });
|
|
88
|
+
}
|
|
89
|
+
super.entityUpdated();
|
|
90
|
+
}
|
|
91
|
+
ngOnDestroy() {
|
|
92
|
+
this.clearForm();
|
|
93
|
+
}
|
|
94
|
+
headerActionRequested(event) {
|
|
95
|
+
switch (event.name) {
|
|
96
|
+
case 'save':
|
|
97
|
+
this.save(event);
|
|
98
|
+
break;
|
|
99
|
+
case 'close':
|
|
100
|
+
this.returnToListPage();
|
|
101
|
+
break;
|
|
102
|
+
case 'toggle-view':
|
|
103
|
+
this.formView = event.data;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
externalIdClaimChanged() {
|
|
108
|
+
if (this.externalIdClaim && !this.formData.externalIdClaim) {
|
|
109
|
+
this.formData.externalIdClaim = {
|
|
110
|
+
location: '',
|
|
111
|
+
matcher: '',
|
|
112
|
+
parser: '',
|
|
113
|
+
index: 0,
|
|
114
|
+
matcherCriteria: '',
|
|
115
|
+
parserCriteria: ''
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
clear() {
|
|
120
|
+
this.formData.configTypeId = '';
|
|
121
|
+
this.clearForm();
|
|
122
|
+
}
|
|
123
|
+
clearForm() {
|
|
124
|
+
this.items.forEach((item) => {
|
|
125
|
+
if (item?.component)
|
|
126
|
+
item.component.destroy();
|
|
127
|
+
});
|
|
128
|
+
this.errors = {};
|
|
129
|
+
this.items = [];
|
|
130
|
+
this.formData = new CertificateAuthority();
|
|
131
|
+
if (this.subscription)
|
|
132
|
+
this.subscription.unsubscribe();
|
|
133
|
+
}
|
|
134
|
+
async save(event) {
|
|
135
|
+
if (!this.validate()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const tagVals = this.getTagValues();
|
|
139
|
+
if (!isEmpty(tagVals)) {
|
|
140
|
+
forOwn(tagVals, (value, key) => {
|
|
141
|
+
this.formData.tags[key] = value;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const apiData = this.apiData;
|
|
145
|
+
apiData.id = this.formData.id;
|
|
146
|
+
this.isLoading = true;
|
|
147
|
+
this.svc.save(apiData).then((result) => {
|
|
148
|
+
if (this.isModal) {
|
|
149
|
+
this.closeModal(true, true);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this.initData = this.formData;
|
|
153
|
+
this._dataChange = false;
|
|
154
|
+
this.returnToListPage();
|
|
155
|
+
}).finally(() => {
|
|
156
|
+
this.isLoading = false;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
validate() {
|
|
160
|
+
this.errors = {};
|
|
161
|
+
const labels = [];
|
|
162
|
+
const growlers = [];
|
|
163
|
+
if (isEmpty(this.formData.name)) {
|
|
164
|
+
this.errors.name = true;
|
|
165
|
+
labels.push('Name');
|
|
166
|
+
}
|
|
167
|
+
if (this.externalIdClaim) {
|
|
168
|
+
if (isEmpty(this.claimLocation)) {
|
|
169
|
+
this.errors.claimLocation = true;
|
|
170
|
+
labels.push('Location');
|
|
171
|
+
}
|
|
172
|
+
if (isEmpty(this.parser)) {
|
|
173
|
+
this.errors.parser = true;
|
|
174
|
+
labels.push('Parser');
|
|
175
|
+
}
|
|
176
|
+
if (isEmpty(this.matcher)) {
|
|
177
|
+
this.errors.matcher = true;
|
|
178
|
+
labels.push('Matcher');
|
|
179
|
+
}
|
|
180
|
+
if (isEmpty(this.parserCriteria)) {
|
|
181
|
+
this.errors.parserCriteria = true;
|
|
182
|
+
labels.push('Parser Criteria');
|
|
183
|
+
}
|
|
184
|
+
if (isEmpty(this.matcherCriteria)) {
|
|
185
|
+
this.errors.matcherCriteria = true;
|
|
186
|
+
labels.push('Matcher Criteria');
|
|
187
|
+
}
|
|
188
|
+
if (isNaN(this.index) || this.index < 0) {
|
|
189
|
+
this.errors.index = true;
|
|
190
|
+
labels.push('Index');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!this.validationService.isValidPEM(this.formData.certPem)) {
|
|
194
|
+
this.errors.certPem = true;
|
|
195
|
+
labels.push('Cert PEM');
|
|
196
|
+
}
|
|
197
|
+
if (!isEmpty(this.errors)) {
|
|
198
|
+
let errorLabels = '';
|
|
199
|
+
labels.forEach((label, index) => {
|
|
200
|
+
errorLabels += `<li>${label}</li>`;
|
|
201
|
+
});
|
|
202
|
+
errorLabels = `<ul>${errorLabels}</ul>`;
|
|
203
|
+
growlers.push(new GrowlerModel('error', 'Invalid', `Missing Form Data`, `Please enter a value for the highlighted fields: ${errorLabels}`));
|
|
204
|
+
}
|
|
205
|
+
if (!isEmpty(growlers)) {
|
|
206
|
+
growlers.forEach((growlerData) => {
|
|
207
|
+
this.growlerService.show(growlerData);
|
|
208
|
+
});
|
|
209
|
+
return isEmpty(this.errors);
|
|
210
|
+
}
|
|
211
|
+
growlers.forEach((growlerData) => {
|
|
212
|
+
this.growlerService.show(growlerData);
|
|
213
|
+
});
|
|
214
|
+
return isEmpty(this.errors);
|
|
215
|
+
}
|
|
216
|
+
get apiCallURL() {
|
|
217
|
+
return this.settings.selectedEdgeController + '/edge/management/v1/cas' + (this.formData.id ? `/${this.formData.id}` : '');
|
|
218
|
+
}
|
|
219
|
+
get apiData() {
|
|
220
|
+
const data = {
|
|
221
|
+
name: this.formData.name || '',
|
|
222
|
+
isAutoCaEnrollmentEnabled: this.formData.isAutoCaEnrollmentEnabled,
|
|
223
|
+
isOttCaEnrollmentEnabled: this.formData.isOttCaEnrollmentEnabled,
|
|
224
|
+
identityRoles: this.formData.identityRoles || [],
|
|
225
|
+
identityNameFormat: this.formData.identityNameFormat,
|
|
226
|
+
isAuthEnabled: this.formData.isAuthEnabled,
|
|
227
|
+
certPem: this.formData.certPem,
|
|
228
|
+
tags: this.formData.tags || {}
|
|
229
|
+
};
|
|
230
|
+
if (this.externalIdClaim) {
|
|
231
|
+
data.externalIdClaim = this.formData.externalIdClaim;
|
|
232
|
+
}
|
|
233
|
+
this._apiData = data;
|
|
234
|
+
return this._apiData;
|
|
235
|
+
}
|
|
236
|
+
set apiData(data) {
|
|
237
|
+
this._apiData = data;
|
|
238
|
+
}
|
|
239
|
+
dataChanged(event) {
|
|
240
|
+
this._apiData = cloneDeep(this.apiData);
|
|
241
|
+
}
|
|
242
|
+
get externalIdClaim() {
|
|
243
|
+
if (this.formData.externalIdClaim) {
|
|
244
|
+
this._externalIdClaim = true;
|
|
245
|
+
}
|
|
246
|
+
return this._externalIdClaim;
|
|
247
|
+
}
|
|
248
|
+
set externalIdClaim(val) {
|
|
249
|
+
if (!val) {
|
|
250
|
+
this.formData.externalIdClaim = undefined;
|
|
251
|
+
}
|
|
252
|
+
this._externalIdClaim = val;
|
|
253
|
+
}
|
|
254
|
+
toggleSwitch(prop) {
|
|
255
|
+
if (prop === 'externalIdClaim') {
|
|
256
|
+
this.externalIdClaim = !this.externalIdClaim;
|
|
257
|
+
}
|
|
258
|
+
this.formData[prop] = !this.formData[prop];
|
|
259
|
+
}
|
|
260
|
+
openFileSelect(event) {
|
|
261
|
+
this.filterInput.nativeElement.click();
|
|
262
|
+
this.fileSelectOpening = true;
|
|
263
|
+
delay(() => {
|
|
264
|
+
this.fileSelectOpening = false;
|
|
265
|
+
}, 1000);
|
|
266
|
+
}
|
|
267
|
+
selectPemFile(event) {
|
|
268
|
+
console.log(event);
|
|
269
|
+
const file = event?.target?.files[0];
|
|
270
|
+
if (file) {
|
|
271
|
+
const fileReader = new FileReader();
|
|
272
|
+
fileReader.onload = (fileLoadedEvent) => {
|
|
273
|
+
const textFromSelectedFile = fileLoadedEvent.target?.result;
|
|
274
|
+
if (!this.validationService.isValidPEM(textFromSelectedFile?.trim())) {
|
|
275
|
+
this.errors.certPem = true;
|
|
276
|
+
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.`);
|
|
277
|
+
this.growlerService.show(growlerData);
|
|
278
|
+
this.formData.certPem = 'Invalid PEM. Please select or enter a valid PEM certificate.';
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
unset(this.errors, 'certPem');
|
|
282
|
+
this.formData.certPem = textFromSelectedFile;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
fileReader.readAsText(file, "UTF-8");
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
apiActionRequested(action) {
|
|
289
|
+
switch (action.id) {
|
|
290
|
+
case 'cli':
|
|
291
|
+
this.copyCLICommand();
|
|
292
|
+
break;
|
|
293
|
+
case 'curl':
|
|
294
|
+
this.copyCURLCommand();
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
copyCLICommand() {
|
|
299
|
+
let command = `ziti edge ${this.formData.id ? 'update' : 'create'} ca ${this.formData.id ? `'${this.formData.id}'` : ''} ${this.formData.id ? '--name' : ''} '${this.formData.name}' ${this.formData.id ? '' : this.formData.certPem} --identity-name-format '${this.formData.identityNameFormat}' --auth '${this.formData.isAuthEnabled}' --auth '${this.formData.isAuthEnabled}' --autoca '${this.formData.isAutoCaEnrollmentEnabled}' --ottca '${this.formData.isOttCaEnrollmentEnabled}'`;
|
|
300
|
+
if (this.externalIdClaim) {
|
|
301
|
+
command += ` --location '${this.formData.externalIdClaim.location}' --matcher '${this.formData.externalIdClaim.matcher}' --parser '${this.formData.externalIdClaim.parser}' --index '${this.formData.externalIdClaim.index}' --matcher-criteria '${this.formData.externalIdClaim.matcherCriteria}' --parser-criteria '${this.formData.externalIdClaim.parserCriteria}'`;
|
|
302
|
+
}
|
|
303
|
+
navigator.clipboard.writeText(command);
|
|
304
|
+
const growlerData = new GrowlerModel('success', 'Success', `Text Copied`, `CLI command copied to clipboard`);
|
|
305
|
+
this.growlerService.show(growlerData);
|
|
306
|
+
}
|
|
307
|
+
copyCURLCommand() {
|
|
308
|
+
const command = `curl '${this.apiCallURL}' \\
|
|
309
|
+
${this.formData.id ? '--request PATCH \\' : '\\'}
|
|
310
|
+
-H 'accept: application/json' \\
|
|
311
|
+
-H 'content-type: application/json' \\
|
|
312
|
+
-H 'zt-session: ${this.settings.session.id}' \\
|
|
313
|
+
--data-raw '${JSON.stringify(this.apiData)}'`;
|
|
314
|
+
navigator.clipboard.writeText(command);
|
|
315
|
+
const growlerData = new GrowlerModel('success', 'Success', `Text Copied`, `CURL command copied to clipboard`);
|
|
316
|
+
this.growlerService.show(growlerData);
|
|
317
|
+
}
|
|
318
|
+
verifyCertificate(event) {
|
|
319
|
+
event.stopPropagation();
|
|
320
|
+
event.preventDefault();
|
|
321
|
+
this.router?.navigateByUrl(`${this.basePath}/${this.formData.id}/verify`);
|
|
322
|
+
}
|
|
323
|
+
get claimLocation() {
|
|
324
|
+
return this.formData.externalIdClaim?.location;
|
|
325
|
+
}
|
|
326
|
+
set claimLocation(loc) {
|
|
327
|
+
if (!this.formData.externalIdClaim) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
this.formData.externalIdClaim.location = loc;
|
|
331
|
+
}
|
|
332
|
+
get matcher() {
|
|
333
|
+
return this.formData.externalIdClaim?.matcher;
|
|
334
|
+
}
|
|
335
|
+
set matcher(matcher) {
|
|
336
|
+
if (!this.formData.externalIdClaim) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
this.formData.externalIdClaim.matcher = matcher;
|
|
340
|
+
}
|
|
341
|
+
get parser() {
|
|
342
|
+
return this.formData.externalIdClaim?.parser;
|
|
343
|
+
}
|
|
344
|
+
set parser(parser) {
|
|
345
|
+
if (!this.formData.externalIdClaim) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
this.formData.externalIdClaim.parser = parser;
|
|
349
|
+
}
|
|
350
|
+
get index() {
|
|
351
|
+
return this.formData.externalIdClaim?.index;
|
|
352
|
+
}
|
|
353
|
+
set index(index) {
|
|
354
|
+
if (!this.formData.externalIdClaim) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
this.formData.externalIdClaim.index = index;
|
|
358
|
+
}
|
|
359
|
+
get matcherCriteria() {
|
|
360
|
+
return this.formData.externalIdClaim?.matcherCriteria;
|
|
361
|
+
}
|
|
362
|
+
set matcherCriteria(matcherCriteria) {
|
|
363
|
+
if (!this.formData.externalIdClaim) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
this.formData.externalIdClaim.matcherCriteria = matcherCriteria;
|
|
367
|
+
}
|
|
368
|
+
get parserCriteria() {
|
|
369
|
+
return this.formData.externalIdClaim?.parserCriteria;
|
|
370
|
+
}
|
|
371
|
+
set parserCriteria(parserCriteria) {
|
|
372
|
+
if (!this.formData.externalIdClaim) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
this.formData.externalIdClaim.parserCriteria = parserCriteria;
|
|
376
|
+
}
|
|
377
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CertificateAuthorityFormComponent, deps: [{ token: i1.CertificateAuthorityFormService }, { 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 }); }
|
|
378
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CertificateAuthorityFormComponent, selector: "lib-certificate-authority", 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 ? 'Certificate Authority Details' : 'Create Certificate Authority')\"\n [moreActions]=\"formData.moreActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n [(formView)]=\"formView\"\n [saveDisabled]=\"svc.saveDisabled || formDataInvalid\"\n [badges]=\"badges\"\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 Certificate Authority\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Identity Name Format'\"\n [contentStyle]=\"'z-index: 99999999'\"\n [label]=\"'OPTIONAL'\"\n [helpText]=\"'The identity name format used to name automatically enrolling identities. Defaults to [caName]-[commonName]'\"\n >\n <input class=\"form-field-input read-only\" [(ngModel)]=\"formData.identityNameFormat\" [ngClass]=\"{error: errors['identityNameFormat']}\" placeholder=\"Defaults to [caName]-[commonName]\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Identity Roles'\"\n [contentStyle]=\"'z-index: 99999999'\"\n [label]=\"'OPTIONAL'\"\n [helpText]=\"'The identity roles to give to automatically enrolling identities'\"\n >\n <lib-tag-selector\n [(selectedRoleAttributes)]=\"formData.identityRoles\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Type to filter and enter to assign'\"\n [hasError]=\"errors.dialIdentities\"\n ></lib-tag-selector>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Enrollment 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\">Auto Enroll</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to automatically enroll when encountered\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isAutoCaEnrollmentEnabled')\"\n [ngClass]=\"{ on: formData.isAutoCaEnrollmentEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isAutoCaEnrollmentEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isAutoCaEnrollmentEnabled\" 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\">OTT Enroll</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to enroll if an identity with an ottca enrollment was created\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isOttCaEnrollmentEnabled')\"\n [ngClass]=\"{ on: formData.isOttCaEnrollmentEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isOttCaEnrollmentEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isOttCaEnrollmentEnabled\" 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\">Auth Enabled</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to attempt to enroll\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isAuthEnabled')\"\n [ngClass]=\"{ on: formData.isAuthEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isAuthEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isAuthEnabled\" 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 [title]=\"'External ID Claim'\"\n [layout]=\"'column'\"\n [helpText]=\"'Configuration used to pull values out of the x509 client certificate used to match identity externalId'\"\n [showToggle]=\"true\"\n [(headerToggle)]=\"externalIdClaim\"\n (headerToggleChange)=\"externalIdClaimChanged()\"\n >\n <div class=\"form-field-input-group\" [ngClass]=\"{disabled: !externalIdClaim}\">\n <div class=\"form-field-row\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Location</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines which value(s) in an x509 certificate will be processed\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"claimLocation\" id=\"ClaimLocation\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['claimLocation']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let loc of locations\" [value]=\"loc\">\n {{ loc }}\n </option>\n </select>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Matcher</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines how values from location will be filtered\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"matcher\" id=\"ClaimMatcher\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['matcher']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let matcher of matchers\" [value]=\"matcher\">\n {{ matcher }}\n </option>\n </select>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Parser</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines how values from location filtered by matcher will be parsed\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"parser\" id=\"ClaimParser\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['parser']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let parser of parsers\" [value]=\"parser\">\n {{ parser }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"form-field-row\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Index</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Should multiple values still be available after location, matcher, and parser processing the integer value here will be used from the set\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" type=\"number\" placeholder=\"Enter a number\" [(ngModel)]=\"index\" [ngClass]=\"{error: errors['index']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Match Criteria</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines the PREFIX, SUFFIX, or SCHEME to look for based on matcher\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter matcher criteria\" [(ngModel)]=\"matcherCriteria\" [ngClass]=\"{error: errors['matcherCriteria']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Parser Criteria</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines the criteria to provide to parser\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter parser criteria\" [(ngModel)]=\"parserCriteria\" [ngClass]=\"{error: errors['parserCriteria']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'PEM'\"\n [label]=\"'REQUIRED'\"\n >\n <div class=\"form-field-input-group\">\n <div class=\"form-field-label-container select-file-label-container\">\n <div class=\"form-field-header\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Enter PEM</span>\n </div>\n <span class=\"select-file-button\" (click)=\"openFileSelect($event)\">\n Select File\n <div class=\"spinner\" *ngIf=\"fileSelectOpening\"></div>\n </span>\n <input #fileSelect type=\"file\" style=\"display:none\" (change)=\"selectPemFile($event)\">\n </div>\n <textarea placeholder=\"Paste pem contents or select file\" [(ngModel)]=\"formData.certPem\" [ngClass]=\"{error: errors['certPem']}\"></textarea>\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 *ngIf=\"formData.id && !this.formData.isVerified\"\n [showHeader]=\"false\"\n >\n <a class=\"download-button\" href=\"./{{this.basePath}}/{{this.formData.id}}/verify\" (click)=\"verifyCertificate($event)\">\n <div class=\"verify-certificate\"></div>\n <span>Verify Certificate</span>\n <div class=\"tap-to-download\"></div>\n </a>\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:31.25rem}.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:1.5625rem;width:-moz-fit-content;width:fit-content;white-space:nowrap;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:.875rem;background:var(--primary);border-style:solid;border-width:.0625rem;border-color:var(--stroke);color:var(--white);cursor:pointer;border-radius:var(--inputBorderRadius);gap:var(--marginMedium);margin-top:-.3125rem}.jwt-signer-form-container .select-file-button:hover{filter:brightness(.8)}.jwt-signer-form-container .select-file-button:active{filter:grayscale(1);transform:translateY(.0625rem)}.jwt-signer-form-container .select-file-button .spinner{display:inline-block;width:.5rem;height:.5rem;border-radius:50%;background:transparent;border-top:.125rem solid white;border-right:.125rem solid white;border-bottom:.125rem solid transparent;border-left:.125rem 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:1.3125rem;height:1.3125rem;border-radius:1.3125rem;border-width:.125rem;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:.9375rem;height:.9375rem;border-radius:.9375rem;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:.875rem;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)}.toggle-container .config-container-label{font-size:.8rem}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i9.FormHeaderComponent, selector: "lib-form-header", inputs: ["data", "badges", "title", "moreActions", "formView", "saveDisabled", "saveTooltip", "actionButtonText", "moreActionsText", "showHeaderToggle", "showHeaderButton"], outputs: ["formViewChange", "actionRequested"] }, { kind: "component", type: i10.FormFieldContainerComponent, selector: "lib-form-field-container", inputs: ["title", "title2", "titleIcon", "layout", "helpText", "helpText2", "label", "count", "action", "actionLabel", "class", "contentStyle", "showHeader", "showToggle", "headerActions", "headerToggle"], outputs: ["actionRequested", "headerToggleChange"] }, { kind: "component", type: i11.LoadingIndicatorComponent, selector: "lib-loading-indicator", inputs: ["isLoading"] }, { kind: "component", type: i12.FormFieldToggleComponent, selector: "lib-form-field-toggle", inputs: ["label", "orientation", "labelOn", "labelOff", "toggleOn"], outputs: ["toggleOnChange"] }, { kind: "component", type: i13.JsonViewComponent, selector: "lib-json-view", inputs: ["data", "schema", "readOnly", "jsonInvalid", "showCopy"], outputs: ["dataChange", "jsonChange", "jsonInvalidChange"] }, { kind: "component", type: i14.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: i15.CustomTagsComponent, selector: "lib-custom-tags", inputs: ["tags"], outputs: ["tagsChange"] }] }); }
|
|
379
|
+
}
|
|
380
|
+
export { CertificateAuthorityFormComponent };
|
|
381
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CertificateAuthorityFormComponent, decorators: [{
|
|
382
|
+
type: Component,
|
|
383
|
+
args: [{ selector: 'lib-certificate-authority', 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 ? 'Certificate Authority Details' : 'Create Certificate Authority')\"\n [moreActions]=\"formData.moreActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n [(formView)]=\"formView\"\n [saveDisabled]=\"svc.saveDisabled || formDataInvalid\"\n [badges]=\"badges\"\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 Certificate Authority\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Identity Name Format'\"\n [contentStyle]=\"'z-index: 99999999'\"\n [label]=\"'OPTIONAL'\"\n [helpText]=\"'The identity name format used to name automatically enrolling identities. Defaults to [caName]-[commonName]'\"\n >\n <input class=\"form-field-input read-only\" [(ngModel)]=\"formData.identityNameFormat\" [ngClass]=\"{error: errors['identityNameFormat']}\" placeholder=\"Defaults to [caName]-[commonName]\"/>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Identity Roles'\"\n [contentStyle]=\"'z-index: 99999999'\"\n [label]=\"'OPTIONAL'\"\n [helpText]=\"'The identity roles to give to automatically enrolling identities'\"\n >\n <lib-tag-selector\n [(selectedRoleAttributes)]=\"formData.identityRoles\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Type to filter and enter to assign'\"\n [hasError]=\"errors.dialIdentities\"\n ></lib-tag-selector>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'Enrollment 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\">Auto Enroll</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to automatically enroll when encountered\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isAutoCaEnrollmentEnabled')\"\n [ngClass]=\"{ on: formData.isAutoCaEnrollmentEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isAutoCaEnrollmentEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isAutoCaEnrollmentEnabled\" 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\">OTT Enroll</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to enroll if an identity with an ottca enrollment was created\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isOttCaEnrollmentEnabled')\"\n [ngClass]=\"{ on: formData.isOttCaEnrollmentEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isOttCaEnrollmentEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isOttCaEnrollmentEnabled\" 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\">Auth Enabled</div>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Allows client certificates of the CA to attempt to enroll\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <div\n (click)=\"toggleSwitch('isAuthEnabled')\"\n [ngClass]=\"{ on: formData.isAuthEnabled }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!formData.isAuthEnabled\" class=\"on-label\">YES</span>\n <span [hidden]=\"formData.isAuthEnabled\" 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 [title]=\"'External ID Claim'\"\n [layout]=\"'column'\"\n [helpText]=\"'Configuration used to pull values out of the x509 client certificate used to match identity externalId'\"\n [showToggle]=\"true\"\n [(headerToggle)]=\"externalIdClaim\"\n (headerToggleChange)=\"externalIdClaimChanged()\"\n >\n <div class=\"form-field-input-group\" [ngClass]=\"{disabled: !externalIdClaim}\">\n <div class=\"form-field-row\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Location</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines which value(s) in an x509 certificate will be processed\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"claimLocation\" id=\"ClaimLocation\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['claimLocation']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let loc of locations\" [value]=\"loc\">\n {{ loc }}\n </option>\n </select>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Matcher</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines how values from location will be filtered\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"matcher\" id=\"ClaimMatcher\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['matcher']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let matcher of matchers\" [value]=\"matcher\">\n {{ matcher }}\n </option>\n </select>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Parser</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines how values from location filtered by matcher will be parsed\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <select [(ngModel)]=\"parser\" id=\"ClaimParser\" class=\"form-field-dropdown\" [disabled]=\"!externalIdClaim\" [ngClass]=\"{error: errors['parser']}\">\n <option value=\"\">Select an option</option>\n <option *ngFor=\"let parser of parsers\" [value]=\"parser\">\n {{ parser }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"form-field-row\">\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Index</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Should multiple values still be available after location, matcher, and parser processing the integer value here will be used from the set\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" type=\"number\" placeholder=\"Enter a number\" [(ngModel)]=\"index\" [ngClass]=\"{error: errors['index']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Match Criteria</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines the PREFIX, SUFFIX, or SCHEME to look for based on matcher\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter matcher criteria\" [(ngModel)]=\"matcherCriteria\" [ngClass]=\"{error: errors['matcherCriteria']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n <div class=\"form-field-label-container\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Parser Criteria</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Defines the criteria to provide to parser\"\n matTooltipPosition=\"below\"\n ></div>\n </div>\n <input class=\"form-field-input\" placeholder=\"Enter parser criteria\" [(ngModel)]=\"parserCriteria\" [ngClass]=\"{error: errors['parserCriteria']}\" [disabled]=\"!externalIdClaim\"/>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'PEM'\"\n [label]=\"'REQUIRED'\"\n >\n <div class=\"form-field-input-group\">\n <div class=\"form-field-label-container select-file-label-container\">\n <div class=\"form-field-header\">\n <div class=\"form-field-title-container\">\n <span class=\"form-field-title\">Enter PEM</span>\n </div>\n <span class=\"select-file-button\" (click)=\"openFileSelect($event)\">\n Select File\n <div class=\"spinner\" *ngIf=\"fileSelectOpening\"></div>\n </span>\n <input #fileSelect type=\"file\" style=\"display:none\" (change)=\"selectPemFile($event)\">\n </div>\n <textarea placeholder=\"Paste pem contents or select file\" [(ngModel)]=\"formData.certPem\" [ngClass]=\"{error: errors['certPem']}\"></textarea>\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 *ngIf=\"formData.id && !this.formData.isVerified\"\n [showHeader]=\"false\"\n >\n <a class=\"download-button\" href=\"./{{this.basePath}}/{{this.formData.id}}/verify\" (click)=\"verifyCertificate($event)\">\n <div class=\"verify-certificate\"></div>\n <span>Verify Certificate</span>\n <div class=\"tap-to-download\"></div>\n </a>\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:31.25rem}.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:1.5625rem;width:-moz-fit-content;width:fit-content;white-space:nowrap;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:.875rem;background:var(--primary);border-style:solid;border-width:.0625rem;border-color:var(--stroke);color:var(--white);cursor:pointer;border-radius:var(--inputBorderRadius);gap:var(--marginMedium);margin-top:-.3125rem}.jwt-signer-form-container .select-file-button:hover{filter:brightness(.8)}.jwt-signer-form-container .select-file-button:active{filter:grayscale(1);transform:translateY(.0625rem)}.jwt-signer-form-container .select-file-button .spinner{display:inline-block;width:.5rem;height:.5rem;border-radius:50%;background:transparent;border-top:.125rem solid white;border-right:.125rem solid white;border-bottom:.125rem solid transparent;border-left:.125rem 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:1.3125rem;height:1.3125rem;border-radius:1.3125rem;border-width:.125rem;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:.9375rem;height:.9375rem;border-radius:.9375rem;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:.875rem;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)}.toggle-container .config-container-label{font-size:.8rem}\n"] }]
|
|
384
|
+
}], ctorParameters: function () { return [{ type: i1.CertificateAuthorityFormService }, { type: i2.SchemaService }, { type: i3.GrowlerService }, { type: undefined, decorators: [{
|
|
385
|
+
type: Inject,
|
|
386
|
+
args: [SHAREDZ_EXTENSION]
|
|
387
|
+
}] }, { type: i16.SettingsService, decorators: [{
|
|
388
|
+
type: Inject,
|
|
389
|
+
args: [SETTINGS_SERVICE]
|
|
390
|
+
}] }, { type: i17.ZitiDataService, decorators: [{
|
|
391
|
+
type: Inject,
|
|
392
|
+
args: [ZITI_DATA_SERVICE]
|
|
393
|
+
}] }, { type: i4.Router }, { type: i4.ActivatedRoute }, { type: i5.Location }, { type: i6.ValidationService }]; }, propDecorators: { formData: [{
|
|
394
|
+
type: Input
|
|
395
|
+
}], errors: [{
|
|
396
|
+
type: Input
|
|
397
|
+
}], close: [{
|
|
398
|
+
type: Output
|
|
399
|
+
}], filterInput: [{
|
|
400
|
+
type: ViewChild,
|
|
401
|
+
args: ['fileSelect']
|
|
402
|
+
}] } });
|
|
403
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUtYXV0aG9yaXR5LWZvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMveml0aS1jb25zb2xlLWxpYi9zcmMvbGliL2ZlYXR1cmVzL3Byb2plY3RhYmxlLWZvcm1zL2NlcnRpZmljYXRlLWF1dGhvcml0eS9jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy96aXRpLWNvbnNvbGUtbGliL3NyYy9saWIvZmVhdHVyZXMvcHJvamVjdGFibGUtZm9ybXMvY2VydGlmaWNhdGUtYXV0aG9yaXR5L2NlcnRpZmljYXRlLWF1dGhvcml0eS1mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztFQWNFO0FBRUYsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQUUsTUFBTSxFQUNwQixLQUFLLEVBRUcsTUFBTSxFQUNkLFNBQVMsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQVksZUFBZSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFFckUsT0FBTyxFQUFtQixpQkFBaUIsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBRTdGLE9BQU8sRUFBQyxTQUFTLEVBQVMsS0FBSyxFQUFFLE1BQU0sRUFBZ0IsT0FBTyxFQUFTLEtBQUssRUFBdUIsTUFBTSxRQUFRLENBQUM7QUFDbEgsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sRUFBQyxnQkFBZ0IsRUFBa0IsTUFBTSxvQ0FBb0MsQ0FBQztBQUNyRixPQUFPLEVBQUMsaUJBQWlCLEVBQWtCLE1BQU0scUNBQXFDLENBQUM7QUFJdkYsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sdUNBQXVDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFM0UsTUFL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QkFxQmtCLFdBQVc7c0JBQW5DLFNBQVM7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gICAgQ29weXJpZ2h0IE5ldEZvdW5kcnkgSW5jLlxuXG4gICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cbiAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB7XG4gICAgQ29tcG9uZW50LCBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlciwgSW5qZWN0LFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsIE91dHB1dCxcbiAgICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDZXJ0aWZpY2F0ZUF1dGhvcml0eUZvcm1TZXJ2aWNlfSBmcm9tIFwiLi9jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZm9ybS5zZXJ2aWNlXCI7XG5pbXBvcnQge1NjaGVtYVNlcnZpY2V9IGZyb20gXCIuLi8uLi8uLi9zZXJ2aWNlcy9zY2hlbWEuc2VydmljZVwiO1xuaW1wb3J0IHtLRVlfQ09ERVMsIFByb2plY3RhYmxlRm9ybX0gZnJvbSBcIi4uL3Byb2plY3RhYmxlLWZvcm0uY2xhc3NcIjtcbmltcG9ydCB7R3Jvd2xlclNlcnZpY2V9IGZyb20gXCIuLi8uLi9tZXNzYWdpbmcvZ3Jvd2xlci5zZXJ2aWNlXCI7XG5pbXBvcnQge0V4dGVuc2lvblNlcnZpY2UsIFNIQVJFRFpfRVhURU5TSU9OfSBmcm9tIFwiLi4vLi4vZXh0ZW5kYWJsZS9leHRlbnNpb25zLW5vb3Auc2VydmljZVwiO1xuXG5pbXBvcnQge2Nsb25lRGVlcCwgZGVmZXIsIGRlbGF5LCBmb3JPd24sIGtleXMsIGludmVydCwgaXNFbXB0eSwgaXNOaWwsIHVuc2V0LCBzb3J0ZWRVbmlxLCBkZWJvdW5jZX0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7R3Jvd2xlck1vZGVsfSBmcm9tIFwiLi4vLi4vbWVzc2FnaW5nL2dyb3dsZXIubW9kZWxcIjtcbmltcG9ydCB7U0VUVElOR1NfU0VSVklDRSwgU2V0dGluZ3NTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vc2VydmljZXMvc2V0dGluZ3Muc2VydmljZVwiO1xuaW1wb3J0IHtaSVRJX0RBVEFfU0VSVklDRSwgWml0aURhdGFTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vc2VydmljZXMveml0aS1kYXRhLnNlcnZpY2VcIjtcbmltcG9ydCB7QWN0aXZhdGVkUm91dGUsIFJvdXRlcn0gZnJvbSBcIkBhbmd1bGFyL3JvdXRlclwiO1xuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHtWYWxpZGF0aW9uU2VydmljZX0gZnJvbSBcIi4uLy4uLy4uL3NlcnZpY2VzL3ZhbGlkYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHtDZXJ0aWZpY2F0ZUF1dGhvcml0eX0gZnJvbSBcIi4uLy4uLy4uL21vZGVscy9jZXJ0aWZpY2F0ZS1hdXRob3JpdHlcIjtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdsaWItY2VydGlmaWNhdGUtYXV0aG9yaXR5JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY2VydGlmaWNhdGUtYXV0aG9yaXR5LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2NlcnRpZmljYXRlLWF1dGhvcml0eS1mb3JtLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ2VydGlmaWNhdGVBdXRob3JpdHlGb3JtQ29tcG9uZW50IGV4dGVuZHMgUHJvamVjdGFibGVGb3JtIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgQElucHV0KCkgb3ZlcnJpZGUgZm9ybURhdGE6IGFueSA9IG5ldyBDZXJ0aWZpY2F0ZUF1dGhvcml0eSgpO1xuICAgIEBJbnB1dCgpIG92ZXJyaWRlIGVycm9yczogYW55ID0ge307XG4gICAgQE91dHB1dCgpIGNsb3NlOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICBfZXh0ZXJuYWxJZENsYWltID0gZmFsc2U7XG5cbiAgICBmb3JtVmlldyA9ICdzaW1wbGUnO1xuICAgIG9wdGlvbnM6IGFueVtdID0gW107XG4gICAgaXNFZGl0aW5nID0gIWlzRW1wdHkodGhpcy5mb3JtRGF0YS5pZCk7XG4gICAgZm9ybURhdGFJbnZhbGlkID0gZmFsc2U7XG4gICAgZWRpdE1vZGUgPSBmYWxzZTtcbiAgICBpdGVtczogYW55ID0gW107XG4gICAgc2V0dGluZ3M6IGFueSA9IHt9O1xuICAgIGZpbGVTZWxlY3RPcGVuaW5nID0gZmFsc2U7XG4gICAgaWRlbnRpdHlSb2xlQXR0cmlidXRlcyA9IFtdO1xuICAgIGJhZGdlczogYW55W10gPSBbXTtcbiAgICBvdmVycmlkZSBlbnRpdHlUeXBlID0gJ2Nhcyc7XG4gICAgb3ZlcnJpZGUgZW50aXR5Q2xhc3MgPSBDZXJ0aWZpY2F0ZUF1dGhvcml0eTtcblxuICAgIGxvY2F0aW9ucyA9IFsnQ09NTU9OX05BTUUnLCAnU0FOX1VSSScsICdTQU5fRU1BSUwnXTtcbiAgICBtYXRjaGVycyA9IFsnQUxMJywgJ1BSRUZJWCcsICdTVUZGSVgnLCAnU0NIRU1FJ107XG4gICAgcGFyc2VycyA9IFsnTk9ORScsICdTUExJVCddO1xuXG4gICAgQFZpZXdDaGlsZCgnZmlsZVNlbGVjdCcpIGZpbHRlcklucHV0OiBFbGVtZW50UmVmO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBzdmM6IENlcnRpZmljYXRlQXV0aG9yaXR5Rm9ybVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgc2NoZW1hU3ZjOiBTY2hlbWFTZXJ2aWNlLFxuICAgICAgICBncm93bGVyU2VydmljZTogR3Jvd2xlclNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoU0hBUkVEWl9FWFRFTlNJT04pIGV4dFNlcnZpY2U6IEV4dGVuc2lvblNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoU0VUVElOR1NfU0VSVklDRSkgcHVibGljIHNldHRpbmdzU2VydmljZTogU2V0dGluZ3NTZXJ2aWNlLFxuICAgICAgICBASW5qZWN0KFpJVElfREFUQV9TRVJWSUNFKSBvdmVycmlkZSB6aXRpU2VydmljZTogWml0aURhdGFTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByb3RlY3RlZCBvdmVycmlkZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICAgICAgcHJpdmF0ZSB2YWxpZGF0aW9uU2VydmljZTogVmFsaWRhdGlvblNlcnZpY2VcbiAgICApIHtcbiAgICAgICAgc3VwZXIoZ3Jvd2xlclNlcnZpY2UsIGV4dFNlcnZpY2UsIHppdGlTZXJ2aWNlLCByb3V0ZXIsIHJvdXRlLCBsb2NhdGlvbik7XG4gICAgfVxuXG4gICAgb3ZlcnJpZGUgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgICAgIHRoaXMuc3ZjLmdldElkZW50aXR5Um9sZUF0dHJpYnV0ZXMoKS50aGVuKChyZXN1bHRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlkZW50aXR5Um9sZUF0dHJpYnV0ZXMgPSByZXN1bHRzPy5kYXRhIHx8IFtdO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3NDaGFuZ2Uuc3Vic2NyaWJlKChyZXN1bHRzOmFueSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncyA9IHJlc3VsdHM7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBlbnRpdHlVcGRhdGVkKCkge1xuICAgICAgICBpZiAodGhpcy5mb3JtRGF0YS5pZCAmJiB0aGlzLmZvcm1EYXRhLmlzVmVyaWZpZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYmFkZ2VzLnB1c2goe2xhYmVsOiAnVmVyaWZpZWQnLCBjbGFzczogJ3ZlcmlmaWVkJywgY2lyY2xlOiAndmVyaWZpZWQnfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJhZGdlcy5wdXNoKHtsYWJlbDogJ1VudmVyaWZpZWQnLCBjbGFzczogJ3VucmVnJ30pO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLmVudGl0eVVwZGF0ZWQoKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbGVhckZvcm0oKTtcbiAgICB9XG5cbiAgICBoZWFkZXJBY3Rpb25SZXF1ZXN0ZWQoZXZlbnQpIHtcbiAgICAgICAgc3dpdGNoKGV2ZW50Lm5hbWUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3NhdmUnOlxuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZShldmVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdjbG9zZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5yZXR1cm5Ub0xpc3RQYWdlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0b2dnbGUtdmlldyc6XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtVmlldyA9IGV2ZW50LmRhdGE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBleHRlcm5hbElkQ2xhaW1DaGFuZ2VkKCkge1xuICAgICAgICBpZiAodGhpcy5leHRlcm5hbElkQ2xhaW0gJiYgIXRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbSA9IHtcbiAgICAgICAgICAgICAgICBsb2NhdGlvbjogJycsXG4gICAgICAgICAgICAgICAgbWF0Y2hlcjogJycsXG4gICAgICAgICAgICAgICAgcGFyc2VyOiAnJyxcbiAgICAgICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgICAgICBtYXRjaGVyQ3JpdGVyaWE6ICcnLFxuICAgICAgICAgICAgICAgIHBhcnNlckNyaXRlcmlhOiAnJ1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3ZlcnJpZGUgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuZm9ybURhdGEuY29uZmlnVHlwZUlkID0gJyc7XG4gICAgICAgIHRoaXMuY2xlYXJGb3JtKCk7XG4gICAgfVxuXG4gICAgY2xlYXJGb3JtKCkge1xuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW06IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0/LmNvbXBvbmVudCkgaXRlbS5jb21wb25lbnQuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lcnJvcnMgPSB7fTtcbiAgICAgICAgdGhpcy5pdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLmZvcm1EYXRhID0gbmV3IENlcnRpZmljYXRlQXV0aG9yaXR5KCk7XG4gICAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbikgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBhc3luYyBzYXZlKGV2ZW50PzogYW55KSB7XG4gICAgICAgIGlmKCF0aGlzLnZhbGlkYXRlKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YWdWYWxzID0gdGhpcy5nZXRUYWdWYWx1ZXMoKTtcbiAgICAgICAgaWYgKCFpc0VtcHR5KHRhZ1ZhbHMpKSB7XG4gICAgICAgICAgICBmb3JPd24odGFnVmFscywgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1EYXRhLnRhZ3Nba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpRGF0YSA9IHRoaXMuYXBpRGF0YTtcbiAgICAgICAgYXBpRGF0YS5pZCA9IHRoaXMuZm9ybURhdGEuaWQ7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdmMuc2F2ZShhcGlEYXRhKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTW9kYWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTW9kYWwodHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pbml0RGF0YSA9IHRoaXMuZm9ybURhdGE7XG4gICAgICAgICAgICB0aGlzLl9kYXRhQ2hhbmdlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnJldHVyblRvTGlzdFBhZ2UoKTtcbiAgICAgICAgfSkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZSgpIHtcbiAgICAgICAgdGhpcy5lcnJvcnMgPSB7fTtcbiAgICAgICAgY29uc3QgbGFiZWxzID0gW107XG4gICAgICAgIGNvbnN0IGdyb3dsZXJzID0gW107XG4gICAgICAgIGlmIChpc0VtcHR5KHRoaXMuZm9ybURhdGEubmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JzLm5hbWUgPSB0cnVlO1xuICAgICAgICAgICAgbGFiZWxzLnB1c2goJ05hbWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHRlcm5hbElkQ2xhaW0pIHtcbiAgICAgICAgICAgIGlmIChpc0VtcHR5KHRoaXMuY2xhaW1Mb2NhdGlvbikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ycy5jbGFpbUxvY2F0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsYWJlbHMucHVzaCgnTG9jYXRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0VtcHR5KHRoaXMucGFyc2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JzLnBhcnNlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgbGFiZWxzLnB1c2goJ1BhcnNlcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzRW1wdHkodGhpcy5tYXRjaGVyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JzLm1hdGNoZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxhYmVscy5wdXNoKCdNYXRjaGVyJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNFbXB0eSh0aGlzLnBhcnNlckNyaXRlcmlhKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JzLnBhcnNlckNyaXRlcmlhID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsYWJlbHMucHVzaCgnUGFyc2VyIENyaXRlcmlhJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNFbXB0eSh0aGlzLm1hdGNoZXJDcml0ZXJpYSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ycy5tYXRjaGVyQ3JpdGVyaWEgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxhYmVscy5wdXNoKCdNYXRjaGVyIENyaXRlcmlhJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOYU4odGhpcy5pbmRleCkgfHwgdGhpcy5pbmRleCA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ycy5pbmRleCA9IHRydWU7XG4gICAgICAgICAgICAgICAgbGFiZWxzLnB1c2goJ0luZGV4Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnZhbGlkYXRpb25TZXJ2aWNlLmlzVmFsaWRQRU0odGhpcy5mb3JtRGF0YS5jZXJ0UGVtKSkge1xuICAgICAgICAgICAgdGhpcy5lcnJvcnMuY2VydFBlbSA9IHRydWU7XG4gICAgICAgICAgICBsYWJlbHMucHVzaCgnQ2VydCBQRU0nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRW1wdHkodGhpcy5lcnJvcnMpKSB7XG4gICAgICAgICAgICBsZXQgZXJyb3JMYWJlbHMgPSAnJztcbiAgICAgICAgICAgIGxhYmVscy5mb3JFYWNoKChsYWJlbCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBlcnJvckxhYmVscyArPSBgPGxpPiR7bGFiZWx9PC9saT5gO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBlcnJvckxhYmVscyA9IGA8dWw+JHtlcnJvckxhYmVsc308L3VsPmA7XG4gICAgICAgICAgICBncm93bGVycy5wdXNoKG5ldyBHcm93bGVyTW9kZWwoXG4gICAgICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAnSW52YWxpZCcsXG4gICAgICAgICAgICAgICAgYE1pc3NpbmcgRm9ybSBEYXRhYCxcbiAgICAgICAgICAgICAgICBgUGxlYXNlIGVudGVyIGEgdmFsdWUgZm9yIHRoZSBoaWdobGlnaHRlZCBmaWVsZHM6ICR7ZXJyb3JMYWJlbHN9YCxcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFbXB0eShncm93bGVycykpIHtcbiAgICAgICAgICAgIGdyb3dsZXJzLmZvckVhY2goKGdyb3dsZXJEYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ncm93bGVyU2VydmljZS5zaG93KGdyb3dsZXJEYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGlzRW1wdHkodGhpcy5lcnJvcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3Jvd2xlcnMuZm9yRWFjaCgoZ3Jvd2xlckRhdGEpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3Jvd2xlclNlcnZpY2Uuc2hvdyhncm93bGVyRGF0YSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gaXNFbXB0eSh0aGlzLmVycm9ycyk7XG4gICAgfVxuXG4gICAgZ2V0IGFwaUNhbGxVUkwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnNlbGVjdGVkRWRnZUNvbnRyb2xsZXIgKyAnL2VkZ2UvbWFuYWdlbWVudC92MS9jYXMnICsgKHRoaXMuZm9ybURhdGEuaWQgPyBgLyR7dGhpcy5mb3JtRGF0YS5pZH1gIDogJycpO1xuICAgIH1cblxuICAgIGdldCBhcGlEYXRhKCk6IGFueSB7XG4gICAgICAgIGNvbnN0IGRhdGE6IGFueSA9IHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMuZm9ybURhdGEubmFtZSB8fCAnJyxcbiAgICAgICAgICAgIGlzQXV0b0NhRW5yb2xsbWVudEVuYWJsZWQ6IHRoaXMuZm9ybURhdGEuaXNBdXRvQ2FFbnJvbGxtZW50RW5hYmxlZCxcbiAgICAgICAgICAgIGlzT3R0Q2FFbnJvbGxtZW50RW5hYmxlZDogdGhpcy5mb3JtRGF0YS5pc090dENhRW5yb2xsbWVudEVuYWJsZWQsXG4gICAgICAgICAgICBpZGVudGl0eVJvbGVzOiB0aGlzLmZvcm1EYXRhLmlkZW50aXR5Um9sZXMgfHwgW10sXG4gICAgICAgICAgICBpZGVudGl0eU5hbWVGb3JtYXQ6IHRoaXMuZm9ybURhdGEuaWRlbnRpdHlOYW1lRm9ybWF0LFxuICAgICAgICAgICAgaXNBdXRoRW5hYmxlZDogdGhpcy5mb3JtRGF0YS5pc0F1dGhFbmFibGVkLFxuICAgICAgICAgICAgY2VydFBlbTogdGhpcy5mb3JtRGF0YS5jZXJ0UGVtLFxuXG4gICAgICAgICAgICB0YWdzOiB0aGlzLmZvcm1EYXRhLnRhZ3MgfHwge31cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMuZXh0ZXJuYWxJZENsYWltKSB7XG4gICAgICAgICAgICBkYXRhLmV4dGVybmFsSWRDbGFpbSA9ICB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hcGlEYXRhID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwaURhdGE7XG4gICAgfVxuXG4gICAgX2FwaURhdGE6IGFueSA9IHt9O1xuICAgIHNldCBhcGlEYXRhKGRhdGEpIHtcbiAgICAgICAgdGhpcy5fYXBpRGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgZGF0YUNoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5fYXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLmFwaURhdGEpO1xuICAgIH1cblxuICAgIGdldCBleHRlcm5hbElkQ2xhaW0oKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbSkge1xuICAgICAgICAgICAgdGhpcy5fZXh0ZXJuYWxJZENsYWltID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZXh0ZXJuYWxJZENsYWltO1xuICAgIH1cblxuICAgIHNldCBleHRlcm5hbElkQ2xhaW0odmFsKSB7XG4gICAgICAgIGlmICghdmFsKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9leHRlcm5hbElkQ2xhaW0gPSB2YWw7XG4gICAgfVxuXG4gICAgdG9nZ2xlU3dpdGNoKHByb3ApIHtcbiAgICAgICAgaWYgKHByb3AgPT09ICdleHRlcm5hbElkQ2xhaW0nKSB7XG4gICAgICAgICAgICB0aGlzLmV4dGVybmFsSWRDbGFpbSA9ICF0aGlzLmV4dGVybmFsSWRDbGFpbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1EYXRhW3Byb3BdID0gIXRoaXMuZm9ybURhdGFbcHJvcF07XG4gICAgfVxuXG4gICAgb3BlbkZpbGVTZWxlY3QoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmZpbHRlcklucHV0Lm5hdGl2ZUVsZW1lbnQuY2xpY2soKTtcbiAgICAgICAgdGhpcy5maWxlU2VsZWN0T3BlbmluZyA9IHRydWU7XG4gICAgICAgIGRlbGF5KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZmlsZVNlbGVjdE9wZW5pbmcgPSBmYWxzZTtcbiAgICAgICAgfSwgMTAwMCk7XG4gICAgfVxuXG4gICAgc2VsZWN0UGVtRmlsZShldmVudDogYW55KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGV2ZW50KTtcbiAgICAgICAgY29uc3QgZmlsZTogRmlsZSA9IGV2ZW50Py50YXJnZXQ/LmZpbGVzWzBdO1xuXG4gICAgICAgIGlmIChmaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gKGZpbGVMb2FkZWRFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHRGcm9tU2VsZWN0ZWRGaWxlOiBhbnkgPSBmaWxlTG9hZGVkRXZlbnQudGFyZ2V0Py5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnZhbGlkYXRpb25TZXJ2aWNlLmlzVmFsaWRQRU0odGV4dEZyb21TZWxlY3RlZEZpbGU/LnRyaW0oKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvcnMuY2VydFBlbSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdyb3dsZXJEYXRhID0gbmV3IEdyb3dsZXJNb2RlbChcbiAgICAgICAgICAgICAgICAgICAgICAgICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAnSW52YWxpZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBgQ2VydCBQRU0gSW52YWxpZGAsXG4gICAgICAgICAgICAgICAgICAgICAgICBgVGhlIGZpbGUgc2VsZWN0ZWQgZm9yIHRoZSBDZXJ0IFBFTSBmaWVsZCBpcyBpbnZhbGlkLiBQbGVhc2UgY2hlY2sgeW91ciBpbnB1dCBhbmQgdHJ5IGFnYWluLmAsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ3Jvd2xlclNlcnZpY2Uuc2hvdyhncm93bGVyRGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybURhdGEuY2VydFBlbSA9ICdJbnZhbGlkIFBFTS4gUGxlYXNlIHNlbGVjdCBvciBlbnRlciBhIHZhbGlkIFBFTSBjZXJ0aWZpY2F0ZS4nO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHVuc2V0KHRoaXMuZXJyb3JzLCAnY2VydFBlbScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1EYXRhLmNlcnRQZW0gPSB0ZXh0RnJvbVNlbGVjdGVkRmlsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNUZXh0KGZpbGUsIFwiVVRGLThcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhcGlBY3Rpb25SZXF1ZXN0ZWQoYWN0aW9uKSB7XG4gICAgICAgIHN3aXRjaCAoYWN0aW9uLmlkKSB7XG4gICAgICAgICAgICBjYXNlICdjbGknOlxuICAgICAgICAgICAgICAgIHRoaXMuY29weUNMSUNvbW1hbmQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2N1cmwnOlxuICAgICAgICAgICAgICAgIHRoaXMuY29weUNVUkxDb21tYW5kKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb3B5Q0xJQ29tbWFuZCgpIHtcbiAgICAgICAgbGV0IGNvbW1hbmQgPSBgeml0aSBlZGdlICR7dGhpcy5mb3JtRGF0YS5pZCA/ICd1cGRhdGUnIDogJ2NyZWF0ZSd9IGNhICR7dGhpcy5mb3JtRGF0YS5pZCA/IGAnJHt0aGlzLmZvcm1EYXRhLmlkfSdgIDogJyd9ICR7dGhpcy5mb3JtRGF0YS5pZCA/ICctLW5hbWUnIDogJyd9ICcke3RoaXMuZm9ybURhdGEubmFtZX0nICR7dGhpcy5mb3JtRGF0YS5pZCA/ICcnIDogdGhpcy5mb3JtRGF0YS5jZXJ0UGVtfSAtLWlkZW50aXR5LW5hbWUtZm9ybWF0ICcke3RoaXMuZm9ybURhdGEuaWRlbnRpdHlOYW1lRm9ybWF0fScgLS1hdXRoICcke3RoaXMuZm9ybURhdGEuaXNBdXRoRW5hYmxlZH0nIC0tYXV0aCAnJHt0aGlzLmZvcm1EYXRhLmlzQXV0aEVuYWJsZWR9JyAtLWF1dG9jYSAnJHt0aGlzLmZvcm1EYXRhLmlzQXV0b0NhRW5yb2xsbWVudEVuYWJsZWR9JyAtLW90dGNhICcke3RoaXMuZm9ybURhdGEuaXNPdHRDYUVucm9sbG1lbnRFbmFibGVkfSdgO1xuICAgICAgICBpZiAodGhpcy5leHRlcm5hbElkQ2xhaW0pIHtcbiAgICAgICAgICAgIGNvbW1hbmQgKz0gYCAtLWxvY2F0aW9uICcke3RoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLmxvY2F0aW9ufScgLS1tYXRjaGVyICcke3RoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLm1hdGNoZXJ9JyAtLXBhcnNlciAnJHt0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbS5wYXJzZXJ9JyAtLWluZGV4ICcke3RoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLmluZGV4fScgLS1tYXRjaGVyLWNyaXRlcmlhICcke3RoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLm1hdGNoZXJDcml0ZXJpYX0nIC0tcGFyc2VyLWNyaXRlcmlhICcke3RoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLnBhcnNlckNyaXRlcmlhfSdgXG4gICAgICAgIH1cblxuICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dChjb21tYW5kKTtcbiAgICAgICAgY29uc3QgZ3Jvd2xlckRhdGEgPSBuZXcgR3Jvd2xlck1vZGVsKFxuICAgICAgICAgICAgJ3N1Y2Nlc3MnLFxuICAgICAgICAgICAgJ1N1Y2Nlc3MnLFxuICAgICAgICAgICAgYFRleHQgQ29waWVkYCxcbiAgICAgICAgICAgIGBDTEkgY29tbWFuZCBjb3BpZWQgdG8gY2xpcGJvYXJkYCxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5ncm93bGVyU2VydmljZS5zaG93KGdyb3dsZXJEYXRhKTtcbiAgICB9XG5cbiAgICBjb3B5Q1VSTENvbW1hbmQoKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBgY3VybCAnJHt0aGlzLmFwaUNhbGxVUkx9JyBcXFxcXG4gICAgJHt0aGlzLmZvcm1EYXRhLmlkID8gJy0tcmVxdWVzdCBQQVRDSCBcXFxcJyA6ICdcXFxcJ31cbiAgICAtSCAnYWNjZXB0OiBhcHBsaWNhdGlvbi9qc29uJyBcXFxcXG4gICAgLUggJ2NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXFxcXFxuICAgIC1IICd6dC1zZXNzaW9uOiAke3RoaXMuc2V0dGluZ3Muc2Vzc2lvbi5pZH0nIFxcXFxcbiAgICAtLWRhdGEtcmF3ICcke0pTT04uc3RyaW5naWZ5KHRoaXMuYXBpRGF0YSl9J2A7XG5cbiAgICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoY29tbWFuZCk7XG4gICAgICAgIGNvbnN0IGdyb3dsZXJEYXRhID0gbmV3IEdyb3dsZXJNb2RlbChcbiAgICAgICAgICAgICdzdWNjZXNzJyxcbiAgICAgICAgICAgICdTdWNjZXNzJyxcbiAgICAgICAgICAgIGBUZXh0IENvcGllZGAsXG4gICAgICAgICAgICBgQ1VSTCBjb21tYW5kIGNvcGllZCB0byBjbGlwYm9hcmRgLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmdyb3dsZXJTZXJ2aWNlLnNob3coZ3Jvd2xlckRhdGEpO1xuICAgIH1cblxuICAgIHZlcmlmeUNlcnRpZmljYXRlKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJvdXRlcj8ubmF2aWdhdGVCeVVybChgJHt0aGlzLmJhc2VQYXRofS8ke3RoaXMuZm9ybURhdGEuaWR9L3ZlcmlmeWApO1xuICAgIH1cblxuICAgIGdldCBjbGFpbUxvY2F0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0/LmxvY2F0aW9uO1xuICAgIH1cblxuICAgIHNldCBjbGFpbUxvY2F0aW9uKGxvYykge1xuICAgICAgICBpZiAoIXRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0ubG9jYXRpb24gPSBsb2M7XG4gICAgfVxuXG4gICAgZ2V0IG1hdGNoZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbT8ubWF0Y2hlcjtcbiAgICB9XG5cbiAgICBzZXQgbWF0Y2hlcihtYXRjaGVyKSB7XG4gICAgICAgIGlmICghdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbS5tYXRjaGVyID0gbWF0Y2hlcjtcbiAgICB9XG5cbiAgICBnZXQgcGFyc2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0/LnBhcnNlcjtcbiAgICB9XG5cbiAgICBzZXQgcGFyc2VyKHBhcnNlcikge1xuICAgICAgICBpZiAoIXRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0ucGFyc2VyID0gcGFyc2VyO1xuICAgIH1cblxuICAgIGdldCBpbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltPy5pbmRleDtcbiAgICB9XG5cbiAgICBzZXQgaW5kZXgoaW5kZXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLmluZGV4ID0gaW5kZXg7XG4gICAgfVxuXG4gICAgZ2V0IG1hdGNoZXJDcml0ZXJpYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltPy5tYXRjaGVyQ3JpdGVyaWE7XG4gICAgfVxuXG4gICAgc2V0IG1hdGNoZXJDcml0ZXJpYShtYXRjaGVyQ3JpdGVyaWEpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybURhdGEuZXh0ZXJuYWxJZENsYWltLm1hdGNoZXJDcml0ZXJpYSA9IG1hdGNoZXJDcml0ZXJpYTtcbiAgICB9XG5cbiAgICBnZXQgcGFyc2VyQ3JpdGVyaWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbT8ucGFyc2VyQ3JpdGVyaWE7XG4gICAgfVxuXG4gICAgc2V0IHBhcnNlckNyaXRlcmlhKHBhcnNlckNyaXRlcmlhKSB7XG4gICAgICAgIGlmICghdGhpcy5mb3JtRGF0YS5leHRlcm5hbElkQ2xhaW0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1EYXRhLmV4dGVybmFsSWRDbGFpbS5wYXJzZXJDcml0ZXJpYSA9IHBhcnNlckNyaXRlcmlhO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwcm9qZWN0YWJsZS1mb3JtLXdyYXBwZXJcIlxuICAgICAoa2V5dXAuZW50ZXIpPVwic2F2ZSgkZXZlbnQpXCJcbiAgICAgKGtleXVwLmVzY2FwZSk9XCJjbG9zZU1vZGFsKGZhbHNlKVwiXG4gICAgIHRhYmluZGV4PVwiMFwiXG4+XG4gICAgPGxpYi1mb3JtLWhlYWRlclxuICAgICAgICAgICAgW2RhdGFdPVwiZm9ybURhdGFcIlxuICAgICAgICAgICAgW3RpdGxlXT1cIihmb3JtRGF0YS5pZCA/ICdDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgRGV0YWlscycgOiAnQ3JlYXRlIENlcnRpZmljYXRlIEF1dGhvcml0eScpXCJcbiAgICAgICAgICAgIFttb3JlQWN0aW9uc109XCJmb3JtRGF0YS5tb3JlQWN0aW9uc1wiXG4gICAgICAgICAgICAoYWN0aW9uUmVxdWVzdGVkKT1cImhlYWRlckFjdGlvblJlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIFsoZm9ybVZpZXcpXT1cImZvcm1WaWV3XCJcbiAgICAgICAgICAgIFtzYXZlRGlzYWJsZWRdPVwic3ZjLnNhdmVEaXNhYmxlZCB8fCBmb3JtRGF0YUludmFsaWRcIlxuICAgICAgICAgICAgW2JhZGdlc109XCJiYWRnZXNcIlxuICAgID48L2xpYi1mb3JtLWhlYWRlcj5cbiAgICA8ZGl2IGNsYXNzPVwiand0LXNpZ25lci1mb3JtLWNvbnRhaW5lciBwcm9qZWN0YWJsZS1mb3JtLWNvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvamVjdGFibGUtZm9ybS1tYWluLWNvbHVtbiBmb3JtLWdyb3VwLXJvd1wiIFtoaWRkZW5dPVwiZm9ybVZpZXcgIT09ICdzaW1wbGUnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cC1jb2x1bW4gdGhyZWUtZmlmdGhzXCI+XG4gICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidOYW1lJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiJ1JlcXVpcmVkJ1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0IHJlYWQtb25seVwiIFsobmdNb2RlbCldPVwiZm9ybURhdGEubmFtZVwiIFtuZ0NsYXNzXT1cIntlcnJvcjogZXJyb3JzWyduYW1lJ119XCIgcGxhY2Vob2xkZXI9XCJOYW1lIHRoaXMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5XCIvPlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInSWRlbnRpdHkgTmFtZSBGb3JtYXQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50U3R5bGVdPVwiJ3otaW5kZXg6IDk5OTk5OTk5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiJ09QVElPTkFMJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGVscFRleHRdPVwiJ1RoZSBpZGVudGl0eSBuYW1lIGZvcm1hdCB1c2VkIHRvIG5hbWUgYXV0b21hdGljYWxseSBlbnJvbGxpbmcgaWRlbnRpdGllcy4gRGVmYXVsdHMgdG8gW2NhTmFtZV0tW2NvbW1vbk5hbWVdJ1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0IHJlYWQtb25seVwiIFsobmdNb2RlbCldPVwiZm9ybURhdGEuaWRlbnRpdHlOYW1lRm9ybWF0XCIgW25nQ2xhc3NdPVwie2Vycm9yOiBlcnJvcnNbJ2lkZW50aXR5TmFtZUZvcm1hdCddfVwiIHBsYWNlaG9sZGVyPVwiRGVmYXVsdHMgdG8gW2NhTmFtZV0tW2NvbW1vbk5hbWVdXCIvPlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInSWRlbnRpdHkgUm9sZXMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50U3R5bGVdPVwiJ3otaW5kZXg6IDk5OTk5OTk5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiJ09QVElPTkFMJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGVscFRleHRdPVwiJ1RoZSBpZGVudGl0eSByb2xlcyB0byBnaXZlIHRvIGF1dG9tYXRpY2FsbHkgZW5yb2xsaW5nIGlkZW50aXRpZXMnXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxsaWItdGFnLXNlbGVjdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhzZWxlY3RlZFJvbGVBdHRyaWJ1dGVzKV09XCJmb3JtRGF0YS5pZGVudGl0eVJvbGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXZhaWxhYmxlUm9sZUF0dHJpYnV0ZXNdPVwiaWRlbnRpdHlSb2xlQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidUeXBlIHRvIGZpbHRlciBhbmQgZW50ZXIgdG8gYXNzaWduJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hhc0Vycm9yXT1cImVycm9ycy5kaWFsSWRlbnRpdGllc1wiXG4gICAgICAgICAgICAgICAgICAgID48L2xpYi10YWctc2VsZWN0b3I+XG4gICAgICAgICAgICAgICAgPC9saWItZm9ybS1maWVsZC1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidFbnJvbGxtZW50IE9wdGlvbnMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsYXlvdXRdPVwiJ3JvdydcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lciB0b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctY29udGFpbmVyLWxhYmVsXCI+QXV0byBFbnJvbGw8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiQWxsb3dzIGNsaWVudCBjZXJ0aWZpY2F0ZXMgb2YgdGhlIENBIHRvIGF1dG9tYXRpY2FsbHkgZW5yb2xsIHdoZW4gZW5jb3VudGVyZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTd2l0Y2goJ2lzQXV0b0NhRW5yb2xsbWVudEVuYWJsZWQnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7IG9uOiBmb3JtRGF0YS5pc0F1dG9DYUVucm9sbG1lbnRFbmFibGVkIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhZm9ybURhdGEuaXNBdXRvQ2FFbnJvbGxtZW50RW5hYmxlZFwiIGNsYXNzPVwib24tbGFiZWxcIj5ZRVM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEuaXNBdXRvQ2FFbnJvbGxtZW50RW5hYmxlZFwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzd2l0Y2hcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lciB0b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctY29udGFpbmVyLWxhYmVsXCI+T1RUIEVucm9sbDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWZpZWxkLWluZm8gaW5mb2ljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJBbGxvd3MgY2xpZW50IGNlcnRpZmljYXRlcyBvZiB0aGUgQ0EgdG8gZW5yb2xsIGlmIGFuIGlkZW50aXR5IHdpdGggYW4gb3R0Y2EgZW5yb2xsbWVudCB3YXMgY3JlYXRlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVN3aXRjaCgnaXNPdHRDYUVucm9sbG1lbnRFbmFibGVkJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBvbjogZm9ybURhdGEuaXNPdHRDYUVucm9sbG1lbnRFbmFibGVkIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhZm9ybURhdGEuaXNPdHRDYUVucm9sbG1lbnRFbmFibGVkXCIgY2xhc3M9XCJvbi1sYWJlbFwiPllFUzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCJmb3JtRGF0YS5pc090dENhRW5yb2xsbWVudEVuYWJsZWRcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1jb250YWluZXIgdG9nZ2xlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWNvbnRhaW5lci1sYWJlbFwiPkF1dGggRW5hYmxlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWZpZWxkLWluZm8gaW5mb2ljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJBbGxvd3MgY2xpZW50IGNlcnRpZmljYXRlcyBvZiB0aGUgQ0EgdG8gYXR0ZW1wdCB0byBlbnJvbGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTd2l0Y2goJ2lzQXV0aEVuYWJsZWQnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7IG9uOiBmb3JtRGF0YS5pc0F1dGhFbmFibGVkIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhZm9ybURhdGEuaXNBdXRoRW5hYmxlZFwiIGNsYXNzPVwib24tbGFiZWxcIj5ZRVM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwiZm9ybURhdGEuaXNBdXRoRW5hYmxlZFwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzd2l0Y2hcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0V4dGVybmFsIElEIENsYWltJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGF5b3V0XT1cIidjb2x1bW4nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoZWxwVGV4dF09XCInQ29uZmlndXJhdGlvbiB1c2VkIHRvIHB1bGwgdmFsdWVzIG91dCBvZiB0aGUgeDUwOSBjbGllbnQgY2VydGlmaWNhdGUgdXNlZCB0byBtYXRjaCBpZGVudGl0eSBleHRlcm5hbElkJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1RvZ2dsZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFsoaGVhZGVyVG9nZ2xlKV09XCJleHRlcm5hbElkQ2xhaW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGhlYWRlclRvZ2dsZUNoYW5nZSk9XCJleHRlcm5hbElkQ2xhaW1DaGFuZ2VkKClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXQtZ3JvdXBcIiBbbmdDbGFzc109XCJ7ZGlzYWJsZWQ6ICFleHRlcm5hbElkQ2xhaW19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1sYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5Mb2NhdGlvbjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWZpZWxkLWluZm8gaW5mb2ljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiRGVmaW5lcyB3aGljaCB2YWx1ZShzKSBpbiBhbiB4NTA5IGNlcnRpZmljYXRlIHdpbGwgYmUgcHJvY2Vzc2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImNsYWltTG9jYXRpb25cIiBpZD1cIkNsYWltTG9jYXRpb25cIiBjbGFzcz1cImZvcm0tZmllbGQtZHJvcGRvd25cIiBbZGlzYWJsZWRdPVwiIWV4dGVybmFsSWRDbGFpbVwiIFtuZ0NsYXNzXT1cIntlcnJvcjogZXJyb3JzWydjbGFpbUxvY2F0aW9uJ119XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IGFuIG9wdGlvbjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgbG9jIG9mIGxvY2F0aW9uc1wiIFt2YWx1ZV09XCJsb2NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBsb2MgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1sYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5NYXRjaGVyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEZWZpbmVzIGhvdyB2YWx1ZXMgZnJvbSBsb2NhdGlvbiB3aWxsIGJlIGZpbHRlcmVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cIm1hdGNoZXJcIiBpZD1cIkNsYWltTWF0Y2hlclwiIGNsYXNzPVwiZm9ybS1maWVsZC1kcm9wZG93blwiIFtkaXNhYmxlZF09XCIhZXh0ZXJuYWxJZENsYWltXCIgW25nQ2xhc3NdPVwie2Vycm9yOiBlcnJvcnNbJ21hdGNoZXInXX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgYW4gb3B0aW9uPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBtYXRjaGVyIG9mIG1hdGNoZXJzXCIgW3ZhbHVlXT1cIm1hdGNoZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBtYXRjaGVyIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtbGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+UGFyc2VyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEZWZpbmVzIGhvdyB2YWx1ZXMgZnJvbSBsb2NhdGlvbiBmaWx0ZXJlZCBieSBtYXRjaGVyIHdpbGwgYmUgcGFyc2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cInBhcnNlclwiIGlkPVwiQ2xhaW1QYXJzZXJcIiBjbGFzcz1cImZvcm0tZmllbGQtZHJvcGRvd25cIiBbZGlzYWJsZWRdPVwiIWV4dGVybmFsSWRDbGFpbVwiIFtuZ0NsYXNzXT1cIntlcnJvcjogZXJyb3JzWydwYXJzZXInXX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgYW4gb3B0aW9uPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBwYXJzZXIgb2YgcGFyc2Vyc1wiIFt2YWx1ZV09XCJwYXJzZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBwYXJzZXIgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtbGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+SW5kZXg8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbmZvIGluZm9pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlNob3VsZCBtdWx0aXBsZSB2YWx1ZXMgc3RpbGwgYmUgYXZhaWxhYmxlIGFmdGVyIGxvY2F0aW9uLCBtYXRjaGVyLCBhbmQgcGFyc2VyIHByb2Nlc3NpbmcgdGhlIGludGVnZXIgdmFsdWUgaGVyZSB3aWxsIGJlIHVzZWQgZnJvbSB0aGUgc2V0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYmVsb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1maWVsZC1pbnB1dFwiIHR5cGU9XCJudW1iZXJcIiBwbGFjZWhvbGRlcj1cIkVudGVyIGEgbnVtYmVyXCIgWyhuZ01vZGVsKV09XCJpbmRleFwiIFtuZ0NsYXNzXT1cIntlcnJvcjogZXJyb3JzWydpbmRleCddfVwiIFtkaXNhYmxlZF09XCIhZXh0ZXJuYWxJZENsYWltXCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWxhYmVsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPk1hdGNoIENyaXRlcmlhPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEZWZpbmVzIHRoZSBQUkVGSVgsIFNVRkZJWCwgb3IgU0NIRU1FIHRvIGxvb2sgZm9yIGJhc2VkIG9uIG1hdGNoZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJiZWxvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJFbnRlciBtYXRjaGVyIGNyaXRlcmlhXCIgWyhuZ01vZGVsKV09XCJtYXRjaGVyQ3JpdGVyaWFcIiBbbmdDbGFzc109XCJ7ZXJyb3I6IGVycm9yc1snbWF0Y2hlckNyaXRlcmlhJ119XCIgW2Rpc2FibGVkXT1cIiFleHRlcm5hbElkQ2xhaW1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtbGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+UGFyc2VyIENyaXRlcmlhPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEZWZpbmVzIHRoZSBjcml0ZXJpYSB0byBwcm92aWRlIHRvIHBhcnNlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXRcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHBhcnNlciBjcml0ZXJpYVwiIFsobmdNb2RlbCldPVwicGFyc2VyQ3JpdGVyaWFcIiBbbmdDbGFzc109XCJ7ZXJyb3I6IGVycm9yc1sncGFyc2VyQ3JpdGVyaWEnXX1cIiBbZGlzYWJsZWRdPVwiIWV4dGVybmFsSWRDbGFpbVwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1BFTSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidSRVFVSVJFRCdcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWxhYmVsLWNvbnRhaW5lciBzZWxlY3QtZmlsZS1sYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5FbnRlciBQRU08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNlbGVjdC1maWxlLWJ1dHRvblwiIChjbGljayk9XCJvcGVuRmlsZVNlbGVjdCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0IEZpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lclwiICpuZ0lmPVwiZmlsZVNlbGVjdE9wZW5pbmdcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0ICNmaWxlU2VsZWN0IHR5cGU9XCJmaWxlXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmVcIiAoY2hhbmdlKT1cInNlbGVjdFBlbUZpbGUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBwbGFjZWhvbGRlcj1cIlBhc3RlIHBlbSBjb250ZW50cyBvciBzZWxlY3QgZmlsZVwiIFsobmdNb2RlbCldPVwiZm9ybURhdGEuY2VydFBlbVwiIFtuZ0NsYXNzXT1cIntlcnJvcjogZXJyb3JzWydjZXJ0UGVtJ119XCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtdG9nZ2xlIFsodG9nZ2xlT24pXT1cInNob3dNb3JlXCIgKHRvZ2dsZU9uQ2hhbmdlKT1cInNob3dNb3JlQ2hhbmdlZCgkZXZlbnQpXCIgc3R5bGU9XCJtYXJnaW46IDBweCAxMHB4XCI+PC9saWItZm9ybS1maWVsZC10b2dnbGU+XG4gICAgICAgICAgICAgICAgPGRpdiBbaGlkZGVuXT1cIiFzaG93TW9yZVwiIGNsYXNzPVwiZm9ybS1ncm91cC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQ3VzdG9tIFRhZ3MnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiJ09QVElPTkFMJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWZpZWxkLWFkdmFuY2VkXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxpYi1jdXN0b20tdGFncyBbKHRhZ3MpXT1cImZvcm1EYXRhLnRhZ3NcIj48L2xpYi1jdXN0b20tdGFncz5cbiAgICAgICAgICAgICAgICAgICAgPC9saWItZm9ybS1maWVsZC1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwLWNvbHVtbiB0d28tZmlmdGhzXCI+XG4gICAgICAgICAgICAgICAgPGxpYi1mb3JtLWZpZWxkLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImZvcm1EYXRhLmlkICYmICF0aGlzLmZvcm1EYXRhLmlzVmVyaWZpZWRcIlxuICAgICAgICAgICAgICAgICAgICBbc2hvd0hlYWRlcl09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImRvd25sb2FkLWJ1dHRvblwiIGhyZWY9XCIuL3t7dGhpcy5iYXNlUGF0aH19L3t7dGhpcy5mb3JtRGF0YS5pZH19L3ZlcmlmeVwiIChjbGljayk9XCJ2ZXJpZnlDZXJ0aWZpY2F0ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmVyaWZ5LWNlcnRpZmljYXRlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5WZXJpZnkgQ2VydGlmaWNhdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFwLXRvLWRvd25sb2FkXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQVBJIENhbGxzJ1wiXG4gICAgICAgICAgICAgICAgICAgIFtoZWFkZXJBY3Rpb25zXT1cImFwaU9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAoYWN0aW9uUmVxdWVzdGVkKT1cImFwaUFjdGlvblJlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIidhcGktZGF0YS1uby13cmFwJ1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXRcIiBbdmFsdWVdPVwiYXBpQ2FsbFVSTFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uLWNvcHkgY29weVwiIChjbGljayk9XCJjb3B5VG9DbGlwYm9hcmQoYXBpQ2FsbFVSTClcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxsaWItanNvbi12aWV3ICpuZ0lmPVwiZm9ybURhdGFcIiBbKGRhdGEpXT1cImFwaURhdGFcIiBbcmVhZE9ubHldPVwidHJ1ZVwiIFtzaG93Q29weV09XCJ0cnVlXCI+PC9saWItanNvbi12aWV3PlxuICAgICAgICAgICAgICAgIDwvbGliLWZvcm0tZmllbGQtY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cC1jb2x1bW5cIiAqbmdJZj1cImZvcm1WaWV3ID09PSAncmF3J1wiPlxuICAgICAgICAgICAgPGxpYi1qc29uLXZpZXcgKm5nSWY9XCJmb3JtRGF0YVwiIFsoZGF0YSldPVwiZm9ybURhdGFcIj48L2xpYi1qc29uLXZpZXc+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG48bGliLWxvYWRpbmctaW5kaWNhdG9yICpuZ0lmPVwiaXNMb2FkaW5nXCIgW2lzTG9hZGluZ109XCJpc0xvYWRpbmdcIj48L2xpYi1sb2FkaW5nLWluZGljYXRvcj5cbiJdfQ==
|