@cqa-lib/cqa-ui 1.1.184 → 1.1.186
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/esm2020/lib/execution-screen/main-step-collapse/main-step-collapse.component.mjs +20 -3
- package/esm2020/lib/simulator/simulator.component.mjs +188 -346
- package/esm2020/lib/step-builder/step-builder-api/step-builder-api.component.mjs +510 -0
- package/esm2020/lib/step-builder/step-builder-custom-code/step-builder-custom-code.component.mjs +92 -7
- package/esm2020/lib/test-case-details/create-step-group/create-step-group.component.mjs +114 -0
- package/esm2020/lib/test-case-details/delete-steps/delete-steps.component.mjs +104 -0
- package/esm2020/lib/ui-kit.module.mjs +17 -2
- package/esm2020/public-api.mjs +4 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +1065 -398
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +1014 -356
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/execution-screen/main-step-collapse/main-step-collapse.component.d.ts +6 -3
- package/lib/simulator/simulator.component.d.ts +10 -22
- package/lib/step-builder/step-builder-api/step-builder-api.component.d.ts +115 -0
- package/lib/step-builder/step-builder-custom-code/step-builder-custom-code.component.d.ts +17 -3
- package/lib/test-case-details/create-step-group/create-step-group.component.d.ts +30 -0
- package/lib/test-case-details/delete-steps/delete-steps.component.d.ts +26 -0
- package/lib/ui-kit.module.d.ts +35 -32
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
- package/styles.css +1 -1
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { Validators } from '@angular/forms';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "@angular/forms";
|
|
5
|
+
import * as i2 from "../../dynamic-select/dynamic-select-field.component";
|
|
6
|
+
import * as i3 from "../../custom-input/custom-input.component";
|
|
7
|
+
import * as i4 from "../../button/button.component";
|
|
8
|
+
import * as i5 from "@angular/material/icon";
|
|
9
|
+
import * as i6 from "../../custom-textarea/custom-textarea.component";
|
|
10
|
+
import * as i7 from "@angular/material/checkbox";
|
|
11
|
+
import * as i8 from "@angular/common";
|
|
12
|
+
export class StepBuilderApiComponent {
|
|
13
|
+
constructor(fb) {
|
|
14
|
+
this.fb = fb;
|
|
15
|
+
/** Options for HTTP method dropdown */
|
|
16
|
+
this.httpMethodOptions = [
|
|
17
|
+
{ id: 'GET', value: 'GET', name: 'GET', label: 'GET' },
|
|
18
|
+
{ id: 'POST', value: 'POST', name: 'POST', label: 'POST' },
|
|
19
|
+
{ id: 'PUT', value: 'PUT', name: 'PUT', label: 'PUT' },
|
|
20
|
+
{ id: 'PATCH', value: 'PATCH', name: 'PATCH', label: 'PATCH' },
|
|
21
|
+
{ id: 'DELETE', value: 'DELETE', name: 'DELETE', label: 'DELETE' },
|
|
22
|
+
{ id: 'HEAD', value: 'HEAD', name: 'HEAD', label: 'HEAD' },
|
|
23
|
+
{ id: 'OPTIONS', value: 'OPTIONS', name: 'OPTIONS', label: 'OPTIONS' }
|
|
24
|
+
];
|
|
25
|
+
/** Options for header name dropdown */
|
|
26
|
+
this.headerNameOptions = [];
|
|
27
|
+
/** Current progress step */
|
|
28
|
+
this.currentStep = 'request-details';
|
|
29
|
+
/** Response preview data */
|
|
30
|
+
this.responsePreview = null;
|
|
31
|
+
/** Loading state */
|
|
32
|
+
this.isLoading = false;
|
|
33
|
+
/** Emit when step is created */
|
|
34
|
+
this.createStep = new EventEmitter();
|
|
35
|
+
/** Emit when cancelled */
|
|
36
|
+
this.cancelled = new EventEmitter();
|
|
37
|
+
/** Emit when request is sent */
|
|
38
|
+
this.sendRequest = new EventEmitter();
|
|
39
|
+
/** Emit when cURL is imported */
|
|
40
|
+
this.importCurl = new EventEmitter();
|
|
41
|
+
this.selectedTab = 'headers';
|
|
42
|
+
this.selectedProgressStep = 'request-details';
|
|
43
|
+
// progressSteps: ProgressStep[] = ['request-details', 'store-response', 'validation'];
|
|
44
|
+
// Cache config objects to prevent infinite change detection loops
|
|
45
|
+
this.verificationTypeConfigCache = null;
|
|
46
|
+
this.expectedTypeConfigCache = null;
|
|
47
|
+
this.httpMethodConfigCache = null;
|
|
48
|
+
this.headerNameConfigCache = null;
|
|
49
|
+
this.paramNameConfigCache = null;
|
|
50
|
+
this.hasLoadedInitialData = false;
|
|
51
|
+
this.apiForm = this.fb.group({
|
|
52
|
+
method: ['GET', Validators.required],
|
|
53
|
+
url: ['', Validators.required],
|
|
54
|
+
headers: this.fb.array([]),
|
|
55
|
+
body: [''],
|
|
56
|
+
params: this.fb.array([]),
|
|
57
|
+
scripts: [''],
|
|
58
|
+
variableName: [''],
|
|
59
|
+
validation: this.fb.array([])
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
ngOnInit() {
|
|
63
|
+
// Sync currentStep input with selectedProgressStep
|
|
64
|
+
if (this.currentStep) {
|
|
65
|
+
this.selectedProgressStep = this.currentStep;
|
|
66
|
+
}
|
|
67
|
+
// Load initial data if provided (edit mode)
|
|
68
|
+
if (this.initialData) {
|
|
69
|
+
this.loadInitialData(this.initialData);
|
|
70
|
+
this.hasLoadedInitialData = true;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Add initial header row for new step
|
|
74
|
+
this.addHeader();
|
|
75
|
+
}
|
|
76
|
+
// Initialize validation form array if starting on validation step
|
|
77
|
+
if (this.selectedProgressStep === 'validation' && this.validationFormArray.length === 0) {
|
|
78
|
+
this.addValidationRule();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
loadInitialData(data) {
|
|
82
|
+
console.log('loadInitialData: Loading data', data);
|
|
83
|
+
console.log('loadInitialData: Headers count', data.headers?.length || 0);
|
|
84
|
+
console.log('loadInitialData: Headers data', data.headers);
|
|
85
|
+
// Set basic fields
|
|
86
|
+
this.apiForm.patchValue({
|
|
87
|
+
method: data.method || 'GET',
|
|
88
|
+
url: data.url || '',
|
|
89
|
+
body: data.body || '',
|
|
90
|
+
scripts: data.scripts || '',
|
|
91
|
+
variableName: data.variableName || ''
|
|
92
|
+
});
|
|
93
|
+
// Load headers
|
|
94
|
+
// Clear existing headers first
|
|
95
|
+
while (this.headersFormArray.length !== 0) {
|
|
96
|
+
this.headersFormArray.removeAt(0);
|
|
97
|
+
}
|
|
98
|
+
if (data.headers && data.headers.length > 0) {
|
|
99
|
+
// Add headers from initial data (include all headers, even if empty)
|
|
100
|
+
data.headers.forEach(header => {
|
|
101
|
+
const headerGroup = this.fb.group({
|
|
102
|
+
name: [header.name || '', Validators.required],
|
|
103
|
+
value: [header.value || '', Validators.required]
|
|
104
|
+
});
|
|
105
|
+
this.headersFormArray.push(headerGroup);
|
|
106
|
+
});
|
|
107
|
+
console.log('loadInitialData: Loaded headers into form array, count:', this.headersFormArray.length);
|
|
108
|
+
}
|
|
109
|
+
// Ensure at least one header row exists
|
|
110
|
+
if (this.headersFormArray.length === 0) {
|
|
111
|
+
console.log('loadInitialData: No headers found, adding empty header row');
|
|
112
|
+
this.addHeader();
|
|
113
|
+
}
|
|
114
|
+
// Load params
|
|
115
|
+
// Clear existing params first
|
|
116
|
+
while (this.paramsFormArray.length !== 0) {
|
|
117
|
+
this.paramsFormArray.removeAt(0);
|
|
118
|
+
}
|
|
119
|
+
if (data.params && data.params.length > 0) {
|
|
120
|
+
// Add params from initial data (include all params, even if empty)
|
|
121
|
+
data.params.forEach(param => {
|
|
122
|
+
const paramGroup = this.fb.group({
|
|
123
|
+
name: [param.name || '', Validators.required],
|
|
124
|
+
value: [param.value || '', Validators.required]
|
|
125
|
+
});
|
|
126
|
+
this.paramsFormArray.push(paramGroup);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Load validation rules
|
|
130
|
+
if (data.validation && data.validation.length > 0) {
|
|
131
|
+
// Clear existing validation rules
|
|
132
|
+
while (this.validationFormArray.length !== 0) {
|
|
133
|
+
this.validationFormArray.removeAt(0);
|
|
134
|
+
}
|
|
135
|
+
// Add validation rules from initial data
|
|
136
|
+
data.validation.forEach(rule => {
|
|
137
|
+
const validationGroup = this.fb.group({
|
|
138
|
+
jsonPath: [rule.jsonPath || '', Validators.required],
|
|
139
|
+
verificationType: [rule.verificationType || 'equals', Validators.required],
|
|
140
|
+
expectedType: [rule.expectedType || 'string', Validators.required],
|
|
141
|
+
expectedValue: [rule.expectedValue !== undefined ? rule.expectedValue : '', Validators.required],
|
|
142
|
+
result: [rule.result || 'Not run'],
|
|
143
|
+
checked: [rule.checked || false]
|
|
144
|
+
});
|
|
145
|
+
// Ensure all controls are enabled
|
|
146
|
+
validationGroup.enable({ emitEvent: false });
|
|
147
|
+
this.validationFormArray.push(validationGroup);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
get headersFormArray() {
|
|
152
|
+
return this.apiForm.get('headers');
|
|
153
|
+
}
|
|
154
|
+
get paramsFormArray() {
|
|
155
|
+
return this.apiForm.get('params');
|
|
156
|
+
}
|
|
157
|
+
get validationFormArray() {
|
|
158
|
+
return this.apiForm.get('validation');
|
|
159
|
+
}
|
|
160
|
+
addHeader() {
|
|
161
|
+
const headerGroup = this.fb.group({
|
|
162
|
+
name: ['', Validators.required],
|
|
163
|
+
value: ['', Validators.required]
|
|
164
|
+
});
|
|
165
|
+
this.headersFormArray.push(headerGroup);
|
|
166
|
+
}
|
|
167
|
+
removeHeader(index) {
|
|
168
|
+
this.headersFormArray.removeAt(index);
|
|
169
|
+
}
|
|
170
|
+
addParam() {
|
|
171
|
+
const paramGroup = this.fb.group({
|
|
172
|
+
name: ['', Validators.required],
|
|
173
|
+
value: ['', Validators.required]
|
|
174
|
+
});
|
|
175
|
+
this.paramsFormArray.push(paramGroup);
|
|
176
|
+
}
|
|
177
|
+
removeParam(index) {
|
|
178
|
+
this.paramsFormArray.removeAt(index);
|
|
179
|
+
}
|
|
180
|
+
ngOnChanges(changes) {
|
|
181
|
+
// Reset config caches when inputs change
|
|
182
|
+
if (changes['httpMethodOptions']) {
|
|
183
|
+
this.httpMethodConfigCache = null;
|
|
184
|
+
}
|
|
185
|
+
if (changes['headerNameOptions']) {
|
|
186
|
+
this.headerNameConfigCache = null;
|
|
187
|
+
}
|
|
188
|
+
// Load initial data if it's set after component initialization
|
|
189
|
+
if (changes['initialData'] && !changes['initialData'].firstChange && this.initialData && !this.hasLoadedInitialData) {
|
|
190
|
+
this.loadInitialData(this.initialData);
|
|
191
|
+
this.hasLoadedInitialData = true;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
getHttpMethodConfig() {
|
|
195
|
+
if (!this.httpMethodConfigCache) {
|
|
196
|
+
this.httpMethodConfigCache = {
|
|
197
|
+
key: 'method',
|
|
198
|
+
placeholder: 'Select method',
|
|
199
|
+
multiple: false,
|
|
200
|
+
searchable: false,
|
|
201
|
+
options: this.httpMethodOptions
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return this.httpMethodConfigCache;
|
|
205
|
+
}
|
|
206
|
+
getHeaderNameConfig(index) {
|
|
207
|
+
if (!this.headerNameConfigCache) {
|
|
208
|
+
const defaultOptions = [
|
|
209
|
+
{ id: 'string', value: 'string', name: 'string', label: 'string' },
|
|
210
|
+
{ id: 'Content-Type', value: 'Content-Type', name: 'Content-Type', label: 'Content-Type' },
|
|
211
|
+
{ id: 'Authorization', value: 'Authorization', name: 'Authorization', label: 'Authorization' },
|
|
212
|
+
{ id: 'Accept', value: 'Accept', name: 'Accept', label: 'Accept' }
|
|
213
|
+
];
|
|
214
|
+
this.headerNameConfigCache = {
|
|
215
|
+
key: 'name',
|
|
216
|
+
placeholder: 'Select header',
|
|
217
|
+
multiple: false,
|
|
218
|
+
searchable: true,
|
|
219
|
+
options: this.headerNameOptions.length > 0 ? this.headerNameOptions : defaultOptions
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return this.headerNameConfigCache;
|
|
223
|
+
}
|
|
224
|
+
getParamNameConfig(index) {
|
|
225
|
+
if (!this.paramNameConfigCache) {
|
|
226
|
+
this.paramNameConfigCache = {
|
|
227
|
+
key: 'name',
|
|
228
|
+
placeholder: 'Parameter name',
|
|
229
|
+
multiple: false,
|
|
230
|
+
searchable: false,
|
|
231
|
+
options: []
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return this.paramNameConfigCache;
|
|
235
|
+
}
|
|
236
|
+
getHeaderFormGroup(index) {
|
|
237
|
+
return this.headersFormArray.at(index);
|
|
238
|
+
}
|
|
239
|
+
getParamFormGroup(index) {
|
|
240
|
+
return this.paramsFormArray.at(index);
|
|
241
|
+
}
|
|
242
|
+
onTabChange(tab) {
|
|
243
|
+
this.selectedTab = tab;
|
|
244
|
+
}
|
|
245
|
+
onSendRequest() {
|
|
246
|
+
if (this.apiForm.valid) {
|
|
247
|
+
const formValue = this.apiForm.value;
|
|
248
|
+
const headers = formValue.headers.map((h) => ({
|
|
249
|
+
name: h.name,
|
|
250
|
+
value: h.value
|
|
251
|
+
}));
|
|
252
|
+
const params = formValue.params ? formValue.params.map((p) => ({
|
|
253
|
+
name: p.name,
|
|
254
|
+
value: p.value
|
|
255
|
+
})) : [];
|
|
256
|
+
this.sendRequest.emit({
|
|
257
|
+
method: formValue.method,
|
|
258
|
+
url: formValue.url,
|
|
259
|
+
headers,
|
|
260
|
+
body: formValue.body,
|
|
261
|
+
params
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
onImportCurl() {
|
|
266
|
+
this.importCurl.emit();
|
|
267
|
+
}
|
|
268
|
+
onCancel() {
|
|
269
|
+
this.cancelled.emit();
|
|
270
|
+
}
|
|
271
|
+
onCreateStep() {
|
|
272
|
+
if (this.apiForm.valid) {
|
|
273
|
+
const formValue = this.apiForm.value;
|
|
274
|
+
const stepData = {
|
|
275
|
+
method: formValue.method,
|
|
276
|
+
url: formValue.url,
|
|
277
|
+
headers: formValue.headers.map((h) => ({
|
|
278
|
+
name: h.name,
|
|
279
|
+
value: h.value
|
|
280
|
+
})),
|
|
281
|
+
body: formValue.body,
|
|
282
|
+
params: formValue.params ? formValue.params.map((p) => ({
|
|
283
|
+
name: p.name,
|
|
284
|
+
value: p.value
|
|
285
|
+
})) : [],
|
|
286
|
+
scripts: formValue.scripts,
|
|
287
|
+
variableName: formValue.variableName || '',
|
|
288
|
+
validation: formValue.validation ? formValue.validation.map((v) => ({
|
|
289
|
+
jsonPath: v.jsonPath,
|
|
290
|
+
verificationType: v.verificationType,
|
|
291
|
+
expectedType: v.expectedType,
|
|
292
|
+
expectedValue: v.expectedValue,
|
|
293
|
+
result: v.result || 'Not run'
|
|
294
|
+
})) : []
|
|
295
|
+
};
|
|
296
|
+
this.createStep.emit(stepData);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
onNext() {
|
|
300
|
+
// Move to next step or create step if on last step
|
|
301
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
302
|
+
const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
|
|
303
|
+
if (currentIndex < stepOrder.length - 1) {
|
|
304
|
+
this.onProgressStepChange(stepOrder[currentIndex + 1]);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
this.onCreateStep();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
onBack() {
|
|
311
|
+
// Move to previous step
|
|
312
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
313
|
+
const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
|
|
314
|
+
if (currentIndex > 0) {
|
|
315
|
+
this.onProgressStepChange(stepOrder[currentIndex - 1]);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
canGoBack() {
|
|
319
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
320
|
+
const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
|
|
321
|
+
return currentIndex > 0;
|
|
322
|
+
}
|
|
323
|
+
isLastStep() {
|
|
324
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
325
|
+
const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
|
|
326
|
+
return currentIndex === stepOrder.length - 1;
|
|
327
|
+
}
|
|
328
|
+
getProgressStepClass(step) {
|
|
329
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
330
|
+
const currentIndex = stepOrder.indexOf(this.currentStep);
|
|
331
|
+
const stepIndex = stepOrder.indexOf(step);
|
|
332
|
+
if (stepIndex < currentIndex) {
|
|
333
|
+
return 'cqa-text-gray-400'; // Completed
|
|
334
|
+
}
|
|
335
|
+
else if (stepIndex === currentIndex) {
|
|
336
|
+
return 'cqa-text-purple-600 cqa-font-semibold'; // Active
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
return 'cqa-text-gray-400'; // Pending
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
getProgressStepNumber(step) {
|
|
343
|
+
const stepOrder = ['request-details', 'store-response', 'validation'];
|
|
344
|
+
return stepOrder.indexOf(step) + 1;
|
|
345
|
+
}
|
|
346
|
+
getProgressStepLabel(step) {
|
|
347
|
+
const labels = {
|
|
348
|
+
'request-details': 'Request Details',
|
|
349
|
+
'store-response': 'Store Response',
|
|
350
|
+
'validation': 'Validation'
|
|
351
|
+
};
|
|
352
|
+
return labels[step];
|
|
353
|
+
}
|
|
354
|
+
formatJsonResponse(data) {
|
|
355
|
+
if (!data)
|
|
356
|
+
return '';
|
|
357
|
+
try {
|
|
358
|
+
return JSON.stringify(data, null, 2);
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return String(data);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
onProgressStepChange(step) {
|
|
365
|
+
this.selectedProgressStep = step;
|
|
366
|
+
// Initialize validation form array if switching to validation step
|
|
367
|
+
if (step === 'validation' && this.validationFormArray.length === 0) {
|
|
368
|
+
this.addValidationRule();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
addValidationRule() {
|
|
372
|
+
const validationGroup = this.fb.group({
|
|
373
|
+
checked: [false],
|
|
374
|
+
jsonPath: ['', Validators.required],
|
|
375
|
+
verificationType: ['equals'],
|
|
376
|
+
expectedType: ['string'],
|
|
377
|
+
expectedValue: ['', Validators.required],
|
|
378
|
+
result: ['Not run']
|
|
379
|
+
});
|
|
380
|
+
// Ensure all controls are enabled to avoid disabled attribute warnings
|
|
381
|
+
validationGroup.enable({ emitEvent: false });
|
|
382
|
+
this.validationFormArray.push(validationGroup);
|
|
383
|
+
}
|
|
384
|
+
removeValidationRule(index) {
|
|
385
|
+
this.validationFormArray.removeAt(index);
|
|
386
|
+
}
|
|
387
|
+
getValidationFormGroup(index) {
|
|
388
|
+
return this.validationFormArray.at(index);
|
|
389
|
+
}
|
|
390
|
+
trackByValidationRuleIndex(index) {
|
|
391
|
+
return index;
|
|
392
|
+
}
|
|
393
|
+
trackByHeaderIndex(index) {
|
|
394
|
+
return index;
|
|
395
|
+
}
|
|
396
|
+
trackByParamIndex(index) {
|
|
397
|
+
return index;
|
|
398
|
+
}
|
|
399
|
+
getVerificationTypeOptions() {
|
|
400
|
+
return [
|
|
401
|
+
{ id: 'equals', value: 'equals', name: 'Equals', label: 'Equals' },
|
|
402
|
+
{ id: 'not_equals', value: 'not_equals', name: 'Not Equals', label: 'Not Equals' },
|
|
403
|
+
{ id: 'contains', value: 'contains', name: 'Contains', label: 'Contains' },
|
|
404
|
+
{ id: 'not_contains', value: 'not_contains', name: 'Not Contains', label: 'Not Contains' },
|
|
405
|
+
{ id: 'greater_than', value: 'greater_than', name: 'Greater Than', label: 'Greater Than' },
|
|
406
|
+
{ id: 'less_than', value: 'less_than', name: 'Less Than', label: 'Less Than' },
|
|
407
|
+
{ id: 'greater_than_or_equals', value: 'greater_than_or_equals', name: 'Greater Than Or Equals', label: 'Greater Than Or Equals' },
|
|
408
|
+
{ id: 'less_than_or_equals', value: 'less_than_or_equals', name: 'Less Than Or Equals', label: 'Less Than Or Equals' },
|
|
409
|
+
{ id: 'exists', value: 'exists', name: 'Exists', label: 'Exists' },
|
|
410
|
+
{ id: 'not_exists', value: 'not_exists', name: 'Not Exists', label: 'Not Exists' }
|
|
411
|
+
];
|
|
412
|
+
}
|
|
413
|
+
getExpectedTypeOptions() {
|
|
414
|
+
return [
|
|
415
|
+
{ id: 'string', value: 'string', name: 'String', label: 'String' },
|
|
416
|
+
{ id: 'number', value: 'number', name: 'Number', label: 'Number' },
|
|
417
|
+
{ id: 'boolean', value: 'boolean', name: 'Boolean', label: 'Boolean' },
|
|
418
|
+
{ id: 'object', value: 'object', name: 'Object', label: 'Object' },
|
|
419
|
+
{ id: 'array', value: 'array', name: 'Array', label: 'Array' },
|
|
420
|
+
{ id: 'null', value: 'null', name: 'Null', label: 'Null' }
|
|
421
|
+
];
|
|
422
|
+
}
|
|
423
|
+
getVerificationTypeConfig(index) {
|
|
424
|
+
// Cache the config to prevent infinite change detection loops
|
|
425
|
+
if (!this.verificationTypeConfigCache) {
|
|
426
|
+
this.verificationTypeConfigCache = {
|
|
427
|
+
key: 'verificationType',
|
|
428
|
+
placeholder: 'Select verification type',
|
|
429
|
+
multiple: false,
|
|
430
|
+
searchable: false,
|
|
431
|
+
options: this.getVerificationTypeOptions()
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return this.verificationTypeConfigCache;
|
|
435
|
+
}
|
|
436
|
+
getExpectedTypeConfig(index) {
|
|
437
|
+
// Cache the config to prevent infinite change detection loops
|
|
438
|
+
if (!this.expectedTypeConfigCache) {
|
|
439
|
+
this.expectedTypeConfigCache = {
|
|
440
|
+
key: 'expectedType',
|
|
441
|
+
placeholder: 'Select expected type',
|
|
442
|
+
multiple: false,
|
|
443
|
+
searchable: false,
|
|
444
|
+
options: this.getExpectedTypeOptions()
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
return this.expectedTypeConfigCache;
|
|
448
|
+
}
|
|
449
|
+
getResultClass(result) {
|
|
450
|
+
if (result === 'Pass') {
|
|
451
|
+
return 'cqa-bg-green-500 cqa-text-white';
|
|
452
|
+
}
|
|
453
|
+
else if (result === 'Fail') {
|
|
454
|
+
return 'cqa-bg-red-500 cqa-text-white';
|
|
455
|
+
}
|
|
456
|
+
return 'cqa-bg-gray-300 cqa-text-gray-700';
|
|
457
|
+
}
|
|
458
|
+
get allValidationRulesSelected() {
|
|
459
|
+
return this.validationFormArray.length > 0 &&
|
|
460
|
+
this.validationFormArray.controls.every(control => control.get('checked')?.value);
|
|
461
|
+
}
|
|
462
|
+
get someValidationRulesSelected() {
|
|
463
|
+
return this.validationFormArray.controls.some(control => control.get('checked')?.value) &&
|
|
464
|
+
!this.allValidationRulesSelected;
|
|
465
|
+
}
|
|
466
|
+
onSelectAllValidationRules(checked) {
|
|
467
|
+
this.validationFormArray.controls.forEach(control => {
|
|
468
|
+
control.get('checked')?.setValue(checked);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
onDeleteSelectedValidationRules() {
|
|
472
|
+
const indicesToRemove = [];
|
|
473
|
+
this.validationFormArray.controls.forEach((control, index) => {
|
|
474
|
+
if (control.get('checked')?.value) {
|
|
475
|
+
indicesToRemove.push(index);
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
// Remove in reverse order to maintain correct indices
|
|
479
|
+
indicesToRemove.reverse().forEach(index => {
|
|
480
|
+
this.removeValidationRule(index);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
StepBuilderApiComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderApiComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
485
|
+
StepBuilderApiComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderApiComponent, selector: "cqa-step-builder-api", inputs: { httpMethodOptions: "httpMethodOptions", headerNameOptions: "headerNameOptions", currentStep: "currentStep", responsePreview: "responsePreview", isLoading: "isLoading", initialData: "initialData" }, outputs: { createStep: "createStep", cancelled: "cancelled", sendRequest: "sendRequest", importCurl: "importCurl" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create API Test Step\n </h2>\n\n <!-- Progress Tracker -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-mb-6 cqa-pb-4 cqa-border-b cqa-border-gray-200\">\n <!-- <div *ngFor=\"let step of progressSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-2\"\n [ngClass]=\"getProgressStepClass(step)\">\n <span class=\"cqa-text-sm cqa-font-medium\">{{ getProgressStepNumber(step) }} {{ getProgressStepLabel(step) }}</span>\n <span *ngIf=\"step !== 'validation'\" class=\"cqa-text-gray-300\">\u2022</span>\n </div> -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'request-details'}\" (click)=\"onProgressStepChange('request-details')\">\n <div>1</div>\n <div>Request Details</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'store-response'}\" (click)=\"onProgressStepChange('store-response')\">\n <div>2</div>\n <div>Store Response</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'validation'}\" (click)=\"onProgressStepChange('validation')\">\n <div>3</div>\n <div>Validation</div>\n <div></div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"selectedProgressStep === 'request-details'\">\n <!-- API Request Configuration -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-6\">\n <div class=\"cqa-w-32 cqa-flex-shrink-0\">\n <cqa-dynamic-select\n [form]=\"apiForm\"\n [config]=\"getHttpMethodConfig()\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Enter API endpoint URL'\"\n [value]=\"apiForm.get('url')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('url')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <cqa-button\n variant=\"outlined\"\n text=\"Import API cURL\"\n (clicked)=\"onImportCurl()\">\n </cqa-button>\n <cqa-button\n variant=\"filled\"\n text=\"Send Request\"\n (clicked)=\"onSendRequest()\"\n [disabled]=\"!apiForm.get('url')?.value || isLoading\">\n </cqa-button>\n </div>\n\n <!-- Request Details Tabs -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Tab Navigation -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'headers'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'headers'\"\n (click)=\"onTabChange('headers')\">\n Headers\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'body'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'body'\"\n (click)=\"onTabChange('body')\">\n Body\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'params'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'params'\"\n (click)=\"onTabChange('params')\">\n Params\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'scripts'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'scripts'\"\n (click)=\"onTabChange('scripts')\">\n Scripts\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-4 cqa-border cqa-border-gray-200 cqa-border-t-0 cqa-rounded-b-lg\">\n <!-- Headers Tab -->\n <div *ngIf=\"selectedTab === 'headers'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Value</div>\n </div>\n <div *ngFor=\"let header of headersFormArray.controls; let i = index; trackBy: trackByHeaderIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-dynamic-select\n [form]=\"getHeaderFormGroup(i)\"\n [config]=\"getHeaderNameConfig(i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Header value'\"\n [value]=\"getHeaderFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getHeaderFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeHeader(i)\"\n [attr.aria-label]=\"'Remove header'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addHeader()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Header</span>\n </button>\n </div>\n\n <!-- Body Tab -->\n <div *ngIf=\"selectedTab === 'body'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter request body (JSON, XML, etc.)'\"\n [value]=\"apiForm.get('body')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('body')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- Params Tab -->\n <div *ngIf=\"selectedTab === 'params'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Value</div>\n </div>\n <div *ngFor=\"let param of paramsFormArray.controls; let i = index; trackBy: trackByParamIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-custom-input\n [placeholder]=\"'Parameter name'\"\n [value]=\"getParamFormGroup(i).get('name')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('name')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Parameter value'\"\n [value]=\"getParamFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeParam(i)\"\n [attr.aria-label]=\"'Remove parameter'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addParam()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Parameter</span>\n </button>\n </div>\n\n <!-- Scripts Tab -->\n <div *ngIf=\"selectedTab === 'scripts'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter scripts (JavaScript, etc.)'\"\n [value]=\"apiForm.get('scripts')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('scripts')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'store-response'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Store Response Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Store Response\n </h3>\n\n <!-- Variable Name Input -->\n <div class=\"cqa-mb-6\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1 cqa-block\">\n Variable Name\n </label>\n <cqa-custom-input\n [placeholder]=\"'Variable Name'\"\n [value]=\"apiForm.get('variableName')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('variableName')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'validation'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Validation Rules Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Validation Rules\n </h3>\n\n <!-- Validation Rules Table -->\n <div class=\"cqa-bg-white cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-4\">\n <!-- Table Header -->\n <div class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200 cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox\n [checked]=\"allValidationRulesSelected\"\n [indeterminate]=\"someValidationRulesSelected\"\n (change)=\"onSelectAllValidationRules($event.checked)\">\n </mat-checkbox>\n </div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">jsonPath</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">verificationType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedValue</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Result</div>\n </div>\n\n <!-- Table Body -->\n <div class=\"cqa-flex cqa-flex-col\">\n <div *ngFor=\"let validationRule of validationFormArray.controls; let i = index; trackBy: trackByValidationRuleIndex\" \n [formGroup]=\"getValidationFormGroup(i)\"\n class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-border-b cqa-border-gray-200 cqa-items-center cqa-last:border-b-0\">\n <!-- Checkbox -->\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox formControlName=\"checked\">\n </mat-checkbox>\n </div>\n\n <!-- jsonPath -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'jsonPath'\"\n [value]=\"getValidationFormGroup(i).get('jsonPath')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('jsonPath')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- verificationType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getVerificationTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getExpectedTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedValue -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'expectedValue'\"\n [value]=\"getValidationFormGroup(i).get('expectedValue')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('expectedValue')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Result and Delete -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button\n type=\"button\"\n class=\"cqa-px-3 cqa-py-1 cqa-rounded cqa-text-[10px] cqa-font-medium\"\n [ngClass]=\"getResultClass(getValidationFormGroup(i).get('result')?.value || 'Not run')\">\n {{ getValidationFormGroup(i).get('result')?.value || 'Not run' }}\n </button>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeValidationRule(i)\"\n [attr.aria-label]=\"'Delete validation rule'\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Add Another Rule and Delete Selected -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-mb-4\">\n <button\n *ngIf=\"someValidationRulesSelected || allValidationRulesSelected\"\n type=\"button\"\n class=\"cqa-text-red-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-red-700 cqa-transition-colors\"\n (click)=\"onDeleteSelectedValidationRules()\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n <span>Delete Selected</span>\n </button>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addValidationRule()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Another</span>\n </button>\n </div>\n </div>\n</ng-container>\n\n\n <!-- Response Preview Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-6\">\n <div class=\"cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Response Preview</h3>\n </div>\n <div class=\"cqa-p-4 cqa-bg-gray-50 cqa-overflow-auto\" style=\"max-height: 300px;\">\n <pre *ngIf=\"responsePreview\" class=\"cqa-text-xs cqa-font-mono cqa-text-gray-800 cqa-whitespace-pre-wrap\">{{ formatJsonResponse(responsePreview) }}</pre>\n <p *ngIf=\"!responsePreview\" class=\"cqa-text-sm cqa-text-gray-400 cqa-text-center cqa-py-8\">\n No response yet. Send a request to see the response preview.\n </p>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <!-- Cancel button (only on first step) -->\n <cqa-button\n *ngIf=\"selectedProgressStep === 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <!-- Back button (on all steps except first) -->\n <cqa-button\n *ngIf=\"selectedProgressStep !== 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Back\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onBack()\">\n </cqa-button>\n <!-- Next/Create Step button -->\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n [text]=\"isLastStep() ? 'Create Step' : 'Next'\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"isLastStep() ? onCreateStep() : onNext()\">\n </cqa-button>\n </div>\n</div>\n\n", components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore"] }, { type: i3.CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i4.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i6.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle", "customClass"], outputs: ["valueChange", "blurred", "focused"] }, { type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], directives: [{ type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
486
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderApiComponent, decorators: [{
|
|
487
|
+
type: Component,
|
|
488
|
+
args: [{ selector: 'cqa-step-builder-api', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create API Test Step\n </h2>\n\n <!-- Progress Tracker -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-mb-6 cqa-pb-4 cqa-border-b cqa-border-gray-200\">\n <!-- <div *ngFor=\"let step of progressSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-2\"\n [ngClass]=\"getProgressStepClass(step)\">\n <span class=\"cqa-text-sm cqa-font-medium\">{{ getProgressStepNumber(step) }} {{ getProgressStepLabel(step) }}</span>\n <span *ngIf=\"step !== 'validation'\" class=\"cqa-text-gray-300\">\u2022</span>\n </div> -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'request-details'}\" (click)=\"onProgressStepChange('request-details')\">\n <div>1</div>\n <div>Request Details</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'store-response'}\" (click)=\"onProgressStepChange('store-response')\">\n <div>2</div>\n <div>Store Response</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'validation'}\" (click)=\"onProgressStepChange('validation')\">\n <div>3</div>\n <div>Validation</div>\n <div></div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"selectedProgressStep === 'request-details'\">\n <!-- API Request Configuration -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-6\">\n <div class=\"cqa-w-32 cqa-flex-shrink-0\">\n <cqa-dynamic-select\n [form]=\"apiForm\"\n [config]=\"getHttpMethodConfig()\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Enter API endpoint URL'\"\n [value]=\"apiForm.get('url')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('url')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <cqa-button\n variant=\"outlined\"\n text=\"Import API cURL\"\n (clicked)=\"onImportCurl()\">\n </cqa-button>\n <cqa-button\n variant=\"filled\"\n text=\"Send Request\"\n (clicked)=\"onSendRequest()\"\n [disabled]=\"!apiForm.get('url')?.value || isLoading\">\n </cqa-button>\n </div>\n\n <!-- Request Details Tabs -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Tab Navigation -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'headers'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'headers'\"\n (click)=\"onTabChange('headers')\">\n Headers\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'body'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'body'\"\n (click)=\"onTabChange('body')\">\n Body\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'params'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'params'\"\n (click)=\"onTabChange('params')\">\n Params\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'scripts'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'scripts'\"\n (click)=\"onTabChange('scripts')\">\n Scripts\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-4 cqa-border cqa-border-gray-200 cqa-border-t-0 cqa-rounded-b-lg\">\n <!-- Headers Tab -->\n <div *ngIf=\"selectedTab === 'headers'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Value</div>\n </div>\n <div *ngFor=\"let header of headersFormArray.controls; let i = index; trackBy: trackByHeaderIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-dynamic-select\n [form]=\"getHeaderFormGroup(i)\"\n [config]=\"getHeaderNameConfig(i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Header value'\"\n [value]=\"getHeaderFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getHeaderFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeHeader(i)\"\n [attr.aria-label]=\"'Remove header'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addHeader()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Header</span>\n </button>\n </div>\n\n <!-- Body Tab -->\n <div *ngIf=\"selectedTab === 'body'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter request body (JSON, XML, etc.)'\"\n [value]=\"apiForm.get('body')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('body')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- Params Tab -->\n <div *ngIf=\"selectedTab === 'params'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Value</div>\n </div>\n <div *ngFor=\"let param of paramsFormArray.controls; let i = index; trackBy: trackByParamIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-custom-input\n [placeholder]=\"'Parameter name'\"\n [value]=\"getParamFormGroup(i).get('name')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('name')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Parameter value'\"\n [value]=\"getParamFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeParam(i)\"\n [attr.aria-label]=\"'Remove parameter'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addParam()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Parameter</span>\n </button>\n </div>\n\n <!-- Scripts Tab -->\n <div *ngIf=\"selectedTab === 'scripts'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter scripts (JavaScript, etc.)'\"\n [value]=\"apiForm.get('scripts')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('scripts')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'store-response'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Store Response Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Store Response\n </h3>\n\n <!-- Variable Name Input -->\n <div class=\"cqa-mb-6\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1 cqa-block\">\n Variable Name\n </label>\n <cqa-custom-input\n [placeholder]=\"'Variable Name'\"\n [value]=\"apiForm.get('variableName')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('variableName')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'validation'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Validation Rules Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Validation Rules\n </h3>\n\n <!-- Validation Rules Table -->\n <div class=\"cqa-bg-white cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-4\">\n <!-- Table Header -->\n <div class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200 cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox\n [checked]=\"allValidationRulesSelected\"\n [indeterminate]=\"someValidationRulesSelected\"\n (change)=\"onSelectAllValidationRules($event.checked)\">\n </mat-checkbox>\n </div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">jsonPath</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">verificationType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedValue</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Result</div>\n </div>\n\n <!-- Table Body -->\n <div class=\"cqa-flex cqa-flex-col\">\n <div *ngFor=\"let validationRule of validationFormArray.controls; let i = index; trackBy: trackByValidationRuleIndex\" \n [formGroup]=\"getValidationFormGroup(i)\"\n class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-border-b cqa-border-gray-200 cqa-items-center cqa-last:border-b-0\">\n <!-- Checkbox -->\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox formControlName=\"checked\">\n </mat-checkbox>\n </div>\n\n <!-- jsonPath -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'jsonPath'\"\n [value]=\"getValidationFormGroup(i).get('jsonPath')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('jsonPath')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- verificationType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getVerificationTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getExpectedTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedValue -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'expectedValue'\"\n [value]=\"getValidationFormGroup(i).get('expectedValue')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('expectedValue')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Result and Delete -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button\n type=\"button\"\n class=\"cqa-px-3 cqa-py-1 cqa-rounded cqa-text-[10px] cqa-font-medium\"\n [ngClass]=\"getResultClass(getValidationFormGroup(i).get('result')?.value || 'Not run')\">\n {{ getValidationFormGroup(i).get('result')?.value || 'Not run' }}\n </button>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeValidationRule(i)\"\n [attr.aria-label]=\"'Delete validation rule'\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Add Another Rule and Delete Selected -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-mb-4\">\n <button\n *ngIf=\"someValidationRulesSelected || allValidationRulesSelected\"\n type=\"button\"\n class=\"cqa-text-red-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-red-700 cqa-transition-colors\"\n (click)=\"onDeleteSelectedValidationRules()\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n <span>Delete Selected</span>\n </button>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addValidationRule()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Another</span>\n </button>\n </div>\n </div>\n</ng-container>\n\n\n <!-- Response Preview Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-6\">\n <div class=\"cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Response Preview</h3>\n </div>\n <div class=\"cqa-p-4 cqa-bg-gray-50 cqa-overflow-auto\" style=\"max-height: 300px;\">\n <pre *ngIf=\"responsePreview\" class=\"cqa-text-xs cqa-font-mono cqa-text-gray-800 cqa-whitespace-pre-wrap\">{{ formatJsonResponse(responsePreview) }}</pre>\n <p *ngIf=\"!responsePreview\" class=\"cqa-text-sm cqa-text-gray-400 cqa-text-center cqa-py-8\">\n No response yet. Send a request to see the response preview.\n </p>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <!-- Cancel button (only on first step) -->\n <cqa-button\n *ngIf=\"selectedProgressStep === 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <!-- Back button (on all steps except first) -->\n <cqa-button\n *ngIf=\"selectedProgressStep !== 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Back\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onBack()\">\n </cqa-button>\n <!-- Next/Create Step button -->\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n [text]=\"isLastStep() ? 'Create Step' : 'Next'\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"isLastStep() ? onCreateStep() : onNext()\">\n </cqa-button>\n </div>\n</div>\n\n", styles: [] }]
|
|
489
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { httpMethodOptions: [{
|
|
490
|
+
type: Input
|
|
491
|
+
}], headerNameOptions: [{
|
|
492
|
+
type: Input
|
|
493
|
+
}], currentStep: [{
|
|
494
|
+
type: Input
|
|
495
|
+
}], responsePreview: [{
|
|
496
|
+
type: Input
|
|
497
|
+
}], isLoading: [{
|
|
498
|
+
type: Input
|
|
499
|
+
}], initialData: [{
|
|
500
|
+
type: Input
|
|
501
|
+
}], createStep: [{
|
|
502
|
+
type: Output
|
|
503
|
+
}], cancelled: [{
|
|
504
|
+
type: Output
|
|
505
|
+
}], sendRequest: [{
|
|
506
|
+
type: Output
|
|
507
|
+
}], importCurl: [{
|
|
508
|
+
type: Output
|
|
509
|
+
}] } });
|
|
510
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1idWlsZGVyLWFwaS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3N0ZXAtYnVpbGRlci9zdGVwLWJ1aWxkZXItYXBpL3N0ZXAtYnVpbGRlci1hcGkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zdGVwLWJ1aWxkZXIvc3RlcC1idWlsZGVyLWFwaS9zdGVwLWJ1aWxkZXItYXBpLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQW1ELE1BQU0sZUFBZSxDQUFDO0FBQ3hILE9BQU8sRUFBa0QsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7QUF1QzVGLE1BQU0sT0FBTyx1QkFBdUI7SUFvRGxDLFlBQW9CLEVBQWU7UUFBZixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBbkRuQyx1Q0FBdUM7UUFDOUIsc0JBQWlCLEdBQW1CO1lBQzNDLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtZQUN0RCxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7WUFDMUQsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFO1lBQ3RELEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUM5RCxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUs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QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7b0hBdGhCVSx1QkFBdUI7d0dBQXZCLHVCQUF1QiwrYkN4Q3BDLDZ5akJBK1lBOzJGRHZXYSx1QkFBdUI7a0JBTm5DLFNBQVM7K0JBQ0Usc0JBQXNCLFFBRzFCLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRTtrR0FJckIsaUJBQWlCO3NCQUF6QixLQUFLO2dCQVdHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxXQUFXO3NCQUFuQixLQUFLO2dCQUdHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFHRyxXQUFXO3NCQUFuQixLQUFLO2dCQUdJLFVBQVU7c0JBQW5CLE1BQU07Z0JBR0csU0FBUztzQkFBbEIsTUFBTTtnQkFHRyxXQUFXO3NCQUFwQixNQUFNO2dCQUdHLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMsIEFmdGVyVmlld0luaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1BcnJheSwgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEeW5hbWljU2VsZWN0RmllbGRDb25maWcsIFNlbGVjdE9wdGlvbiB9IGZyb20gJy4uLy4uL2R5bmFtaWMtc2VsZWN0L2R5bmFtaWMtc2VsZWN0LWZpZWxkLmNvbXBvbmVudCc7XG5cbmV4cG9ydCB0eXBlIEh0dHBNZXRob2QgPSAnR0VUJyB8ICdQT1NUJyB8ICdQVVQnIHwgJ1BBVENIJyB8ICdERUxFVEUnIHwgJ0hFQUQnIHwgJ09QVElPTlMnO1xuZXhwb3J0IHR5cGUgUmVxdWVzdFRhYiA9ICdoZWFkZXJzJyB8ICdib2R5JyB8ICdwYXJhbXMnIHwgJ3NjcmlwdHMnO1xuZXhwb3J0IHR5cGUgUHJvZ3Jlc3NTdGVwID0gJ3JlcXVlc3QtZGV0YWlscycgfCAnc3RvcmUtcmVzcG9uc2UnIHwgJ3ZhbGlkYXRpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEhlYWRlclJvdyB7XG4gIG5hbWU6IHN0cmluZztcbiAgdmFsdWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uUnVsZSB7XG4gIGpzb25QYXRoOiBzdHJpbmc7XG4gIHZlcmlmaWNhdGlvblR5cGU6IHN0cmluZztcbiAgZXhwZWN0ZWRUeXBlOiBzdHJpbmc7XG4gIGV4cGVjdGVkVmFsdWU6IGFueTtcbiAgcmVzdWx0PzogJ1Bhc3MnIHwgJ0ZhaWwnIHwgJ05vdCBydW4nO1xuICBjaGVja2VkPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBcGlGb3JtRGF0YSB7XG4gIG1ldGhvZDogSHR0cE1ldGhvZDtcbiAgdXJsOiBzdHJpbmc7XG4gIGhlYWRlcnM6IEhlYWRlclJvd1tdO1xuICBib2R5Pzogc3RyaW5nO1xuICBwYXJhbXM/OiBIZWFkZXJSb3dbXTtcbiAgc2NyaXB0cz86IHN0cmluZztcbiAgdmFyaWFibGVOYW1lPzogc3RyaW5nO1xuICBzdG9yZVJlc3BvbnNlPzogYW55O1xuICB2YWxpZGF0aW9uPzogVmFsaWRhdGlvblJ1bGVbXTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLXN0ZXAtYnVpbGRlci1hcGknLFxuICB0ZW1wbGF0ZVVybDogJy4vc3RlcC1idWlsZGVyLWFwaS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW10sXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfVxufSlcbmV4cG9ydCBjbGFzcyBTdGVwQnVpbGRlckFwaUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgLyoqIE9wdGlvbnMgZm9yIEhUVFAgbWV0aG9kIGRyb3Bkb3duICovXG4gIEBJbnB1dCgpIGh0dHBNZXRob2RPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtcbiAgICB7IGlkOiAnR0VUJywgdmFsdWU6ICdHRVQnLCBuYW1lOiAnR0VUJywgbGFiZWw6ICdHRVQnIH0sXG4gICAgeyBpZDogJ1BPU1QnLCB2YWx1ZTogJ1BPU1QnLCBuYW1lOiAnUE9TVCcsIGxhYmVsOiAnUE9TVCcgfSxcbiAgICB7IGlkOiAnUFVUJywgdmFsdWU6ICdQVVQnLCBuYW1lOiAnUFVUJywgbGFiZWw6ICdQVVQnIH0sXG4gICAgeyBpZDogJ1BBVENIJywgdmFsdWU6ICdQQVRDSCcsIG5hbWU6ICdQQVRDSCcsIGxhYmVsOiAnUEFUQ0gnIH0sXG4gICAgeyBpZDogJ0RFTEVURScsIHZhbHVlOiAnREVMRVRFJywgbmFtZTogJ0RFTEVURScsIGxhYmVsOiAnREVMRVRFJyB9LFxuICAgIHsgaWQ6ICdIRUFEJywgdmFsdWU6ICdIRUFEJywgbmFtZTogJ0hFQUQnLCBsYWJlbDogJ0hFQUQnIH0sXG4gICAgeyBpZDogJ09QVElPTlMnLCB2YWx1ZTogJ09QVElPTlMnLCBuYW1lOiAnT1BUSU9OUycsIGxhYmVsOiAnT1BUSU9OUycgfVxuICBdO1xuXG4gIC8qKiBPcHRpb25zIGZvciBoZWFkZXIgbmFtZSBkcm9wZG93biAqL1xuICBASW5wdXQoKSBoZWFkZXJOYW1lT3B0aW9uczogU2VsZWN0T3B0aW9uW10gPSBbXTtcblxuICAvKiogQ3VycmVudCBwcm9ncmVzcyBzdGVwICovXG4gIEBJbnB1dCgpIGN1cnJlbnRTdGVwOiBQcm9ncmVzc1N0ZXAgPSAncmVxdWVzdC1kZXRhaWxzJztcblxuICAvKiogUmVzcG9uc2UgcHJldmlldyBkYXRhICovXG4gIEBJbnB1dCgpIHJlc3BvbnNlUHJldmlldzogYW55ID0gbnVsbDtcblxuICAvKiogTG9hZGluZyBzdGF0ZSAqL1xuICBASW5wdXQoKSBpc0xvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogSW5pdGlhbCBmb3JtIGRhdGEgZm9yIGVkaXQgbW9kZSAqL1xuICBASW5wdXQoKSBpbml0aWFsRGF0YT86IEFwaUZvcm1EYXRhO1xuXG4gIC8qKiBFbWl0IHdoZW4gc3RlcCBpcyBjcmVhdGVkICovXG4gIEBPdXRwdXQoKSBjcmVhdGVTdGVwID0gbmV3IEV2ZW50RW1pdHRlcjxBcGlGb3JtRGF0YT4oKTtcblxuICAvKiogRW1pdCB3aGVuIGNhbmNlbGxlZCAqL1xuICBAT3V0cHV0KCkgY2FuY2VsbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcmVxdWVzdCBpcyBzZW50ICovXG4gIEBPdXRwdXQoKSBzZW5kUmVxdWVzdCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBtZXRob2Q6IEh0dHBNZXRob2Q7IHVybDogc3RyaW5nOyBoZWFkZXJzOiBIZWFkZXJSb3dbXTsgYm9keT86IHN0cmluZzsgcGFyYW1zPzogSGVhZGVyUm93W10gfT4oKTtcblxuICAvKiogRW1pdCB3aGVuIGNVUkwgaXMgaW1wb3J0ZWQgKi9cbiAgQE91dHB1dCgpIGltcG9ydEN1cmwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgYXBpRm9ybTogRm9ybUdyb3VwO1xuICBzZWxlY3RlZFRhYjogUmVxdWVzdFRhYiA9ICdoZWFkZXJzJztcbiAgc2VsZWN0ZWRQcm9ncmVzc1N0ZXA6IFByb2dyZXNzU3RlcCA9ICdyZXF1ZXN0LWRldGFpbHMnO1xuICAvLyBwcm9ncmVzc1N0ZXBzOiBQcm9ncmVzc1N0ZXBbXSA9IFsncmVxdWVzdC1kZXRhaWxzJywgJ3N0b3JlLXJlc3BvbnNlJywgJ3ZhbGlkYXRpb24nXTtcbiAgXG4gIC8vIENhY2hlIGNvbmZpZyBvYmplY3RzIHRvIHByZXZlbnQgaW5maW5pdGUgY2hhbmdlIGRldGVjdGlvbiBsb29wc1xuICBwcml2YXRlIHZlcmlmaWNhdGlvblR5cGVDb25maWdDYWNoZTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZXhwZWN0ZWRUeXBlQ29uZmlnQ2FjaGU6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGh0dHBNZXRob2RDb25maWdDYWNoZTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaGVhZGVyTmFtZUNvbmZpZ0NhY2hlOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwYXJhbU5hbWVDb25maWdDYWNoZTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaGFzTG9hZGVkSW5pdGlhbERhdGE6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGZiOiBGb3JtQnVpbGRlcikge1xuICAgIHRoaXMuYXBpRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgbWV0aG9kOiBbJ0dFVCcsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdXJsOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgaGVhZGVyczogdGhpcy5mYi5hcnJheShbXSksXG4gICAgICBib2R5OiBbJyddLFxuICAgICAgcGFyYW1zOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIHNjcmlwdHM6IFsnJ10sXG4gICAgICB2YXJpYWJsZU5hbWU6IFsnJ10sXG4gICAgICB2YWxpZGF0aW9uOiB0aGlzLmZiLmFycmF5KFtdKVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gU3luYyBjdXJyZW50U3RlcCBpbnB1dCB3aXRoIHNlbGVjdGVkUHJvZ3Jlc3NTdGVwXG4gICAgaWYgKHRoaXMuY3VycmVudFN0ZXApIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPSB0aGlzLmN1cnJlbnRTdGVwO1xuICAgIH1cbiAgICBcbiAgICAvLyBMb2FkIGluaXRpYWwgZGF0YSBpZiBwcm92aWRlZCAoZWRpdCBtb2RlKVxuICAgIGlmICh0aGlzLmluaXRpYWxEYXRhKSB7XG4gICAgICB0aGlzLmxvYWRJbml0aWFsRGF0YSh0aGlzLmluaXRpYWxEYXRhKTtcbiAgICAgIHRoaXMuaGFzTG9hZGVkSW5pdGlhbERhdGEgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBZGQgaW5pdGlhbCBoZWFkZXIgcm93IGZvciBuZXcgc3RlcFxuICAgICAgdGhpcy5hZGRIZWFkZXIoKTtcbiAgICB9XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSB2YWxpZGF0aW9uIGZvcm0gYXJyYXkgaWYgc3RhcnRpbmcgb24gdmFsaWRhdGlvbiBzdGVwXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPT09ICd2YWxpZGF0aW9uJyAmJiB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmFkZFZhbGlkYXRpb25SdWxlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsb2FkSW5pdGlhbERhdGEoZGF0YTogQXBpRm9ybURhdGEpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnbG9hZEluaXRpYWxEYXRhOiBMb2FkaW5nIGRhdGEnLCBkYXRhKTtcbiAgICBjb25zb2xlLmxvZygnbG9hZEluaXRpYWxEYXRhOiBIZWFkZXJzIGNvdW50JywgZGF0YS5oZWFkZXJzPy5sZW5ndGggfHwgMCk7XG4gICAgY29uc29sZS5sb2coJ2xvYWRJbml0aWFsRGF0YTogSGVhZGVycyBkYXRhJywgZGF0YS5oZWFkZXJzKTtcbiAgICBcbiAgICAvLyBTZXQgYmFzaWMgZmllbGRzXG4gICAgdGhpcy5hcGlGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgbWV0aG9kOiBkYXRhLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgIHVybDogZGF0YS51cmwgfHwgJycsXG4gICAgICBib2R5OiBkYXRhLmJvZHkgfHwgJycsXG4gICAgICBzY3JpcHRzOiBkYXRhLnNjcmlwdHMgfHwgJycsXG4gICAgICB2YXJpYWJsZU5hbWU6IGRhdGEudmFyaWFibGVOYW1lIHx8ICcnXG4gICAgfSk7XG5cbiAgICAvLyBMb2FkIGhlYWRlcnNcbiAgICAvLyBDbGVhciBleGlzdGluZyBoZWFkZXJzIGZpcnN0XG4gICAgd2hpbGUgKHRoaXMuaGVhZGVyc0Zvcm1BcnJheS5sZW5ndGggIT09IDApIHtcbiAgICAgIHRoaXMuaGVhZGVyc0Zvcm1BcnJheS5yZW1vdmVBdCgwKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKGRhdGEuaGVhZGVycyAmJiBkYXRhLmhlYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gQWRkIGhlYWRlcnMgZnJvbSBpbml0aWFsIGRhdGEgKGluY2x1ZGUgYWxsIGhlYWRlcnMsIGV2ZW4gaWYgZW1wdHkpXG4gICAgICBkYXRhLmhlYWRlcnMuZm9yRWFjaChoZWFkZXIgPT4ge1xuICAgICAgICBjb25zdCBoZWFkZXJHcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgIG5hbWU6IFtoZWFkZXIubmFtZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgdmFsdWU6IFtoZWFkZXIudmFsdWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhlYWRlcnNGb3JtQXJyYXkucHVzaChoZWFkZXJHcm91cCk7XG4gICAgICB9KTtcbiAgICAgIGNvbnNvbGUubG9nKCdsb2FkSW5pdGlhbERhdGE6IExvYWRlZCBoZWFkZXJzIGludG8gZm9ybSBhcnJheSwgY291bnQ6JywgdGhpcy5oZWFkZXJzRm9ybUFycmF5Lmxlbmd0aCk7XG4gICAgfVxuICAgIFxuICAgIC8vIEVuc3VyZSBhdCBsZWFzdCBvbmUgaGVhZGVyIHJvdyBleGlzdHNcbiAgICBpZiAodGhpcy5oZWFkZXJzRm9ybUFycmF5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS5sb2coJ2xvYWRJbml0aWFsRGF0YTogTm8gaGVhZGVycyBmb3VuZCwgYWRkaW5nIGVtcHR5IGhlYWRlciByb3cnKTtcbiAgICAgIHRoaXMuYWRkSGVhZGVyKCk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBwYXJhbXNcbiAgICAvLyBDbGVhciBleGlzdGluZyBwYXJhbXMgZmlyc3RcbiAgICB3aGlsZSAodGhpcy5wYXJhbXNGb3JtQXJyYXkubGVuZ3RoICE9PSAwKSB7XG4gICAgICB0aGlzLnBhcmFtc0Zvcm1BcnJheS5yZW1vdmVBdCgwKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKGRhdGEucGFyYW1zICYmIGRhdGEucGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIEFkZCBwYXJhbXMgZnJvbSBpbml0aWFsIGRhdGEgKGluY2x1ZGUgYWxsIHBhcmFtcywgZXZlbiBpZiBlbXB0eSlcbiAgICAgIGRhdGEucGFyYW1zLmZvckVhY2gocGFyYW0gPT4ge1xuICAgICAgICBjb25zdCBwYXJhbUdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgbmFtZTogW3BhcmFtLm5hbWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICAgIHZhbHVlOiBbcGFyYW0udmFsdWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhcmFtc0Zvcm1BcnJheS5wdXNoKHBhcmFtR3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCB2YWxpZGF0aW9uIHJ1bGVzXG4gICAgaWYgKGRhdGEudmFsaWRhdGlvbiAmJiBkYXRhLnZhbGlkYXRpb24ubGVuZ3RoID4gMCkge1xuICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgdmFsaWRhdGlvbiBydWxlc1xuICAgICAgd2hpbGUgKHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LnJlbW92ZUF0KDApO1xuICAgICAgfVxuICAgICAgLy8gQWRkIHZhbGlkYXRpb24gcnVsZXMgZnJvbSBpbml0aWFsIGRhdGFcbiAgICAgIGRhdGEudmFsaWRhdGlvbi5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICBjb25zdCB2YWxpZGF0aW9uR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICBqc29uUGF0aDogW3J1bGUuanNvblBhdGggfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICAgIHZlcmlmaWNhdGlvblR5cGU6IFtydWxlLnZlcmlmaWNhdGlvblR5cGUgfHwgJ2VxdWFscycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICAgIGV4cGVjdGVkVHlwZTogW3J1bGUuZXhwZWN0ZWRUeXBlIHx8ICdzdHJpbmcnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgICBleHBlY3RlZFZhbHVlOiBbcnVsZS5leHBlY3RlZFZhbHVlICE9PSB1bmRlZmluZWQgPyBydWxlLmV4cGVjdGVkVmFsdWUgOiAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgcmVzdWx0OiBbcnVsZS5yZXN1bHQgfHwgJ05vdCBydW4nXSxcbiAgICAgICAgICBjaGVja2VkOiBbcnVsZS5jaGVja2VkIHx8IGZhbHNlXVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRW5zdXJlIGFsbCBjb250cm9scyBhcmUgZW5hYmxlZFxuICAgICAgICB2YWxpZGF0aW9uR3JvdXAuZW5hYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LnB1c2godmFsaWRhdGlvbkdyb3VwKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBoZWFkZXJzRm9ybUFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpRm9ybS5nZXQoJ2hlYWRlcnMnKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBnZXQgcGFyYW1zRm9ybUFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpRm9ybS5nZXQoJ3BhcmFtcycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGdldCB2YWxpZGF0aW9uRm9ybUFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpRm9ybS5nZXQoJ3ZhbGlkYXRpb24nKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBhZGRIZWFkZXIoKTogdm9pZCB7XG4gICAgY29uc3QgaGVhZGVyR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIG5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgIH0pO1xuICAgIHRoaXMuaGVhZGVyc0Zvcm1BcnJheS5wdXNoKGhlYWRlckdyb3VwKTtcbiAgfVxuXG4gIHJlbW92ZUhlYWRlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5oZWFkZXJzRm9ybUFycmF5LnJlbW92ZUF0KGluZGV4KTtcbiAgfVxuXG4gIGFkZFBhcmFtKCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmFtR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIG5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgIH0pO1xuICAgIHRoaXMucGFyYW1zRm9ybUFycmF5LnB1c2gocGFyYW1Hcm91cCk7XG4gIH1cblxuICByZW1vdmVQYXJhbShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5wYXJhbXNGb3JtQXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIFJlc2V0IGNvbmZpZyBjYWNoZXMgd2hlbiBpbnB1dHMgY2hhbmdlXG4gICAgaWYgKGNoYW5nZXNbJ2h0dHBNZXRob2RPcHRpb25zJ10pIHtcbiAgICAgIHRoaXMuaHR0cE1ldGhvZENvbmZpZ0NhY2hlID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2hlYWRlck5hbWVPcHRpb25zJ10pIHtcbiAgICAgIHRoaXMuaGVhZGVyTmFtZUNvbmZpZ0NhY2hlID0gbnVsbDtcbiAgICB9XG4gICAgXG4gICAgLy8gTG9hZCBpbml0aWFsIGRhdGEgaWYgaXQncyBzZXQgYWZ0ZXIgY29tcG9uZW50IGluaXRpYWxpemF0aW9uXG4gICAgaWYgKGNoYW5nZXNbJ2luaXRpYWxEYXRhJ10gJiYgIWNoYW5nZXNbJ2luaXRpYWxEYXRhJ10uZmlyc3RDaGFuZ2UgJiYgdGhpcy5pbml0aWFsRGF0YSAmJiAhdGhpcy5oYXNMb2FkZWRJbml0aWFsRGF0YSkge1xuICAgICAgdGhpcy5sb2FkSW5pdGlhbERhdGEodGhpcy5pbml0aWFsRGF0YSk7XG4gICAgICB0aGlzLmhhc0xvYWRlZEluaXRpYWxEYXRhID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRIdHRwTWV0aG9kQ29uZmlnKCk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgaWYgKCF0aGlzLmh0dHBNZXRob2RDb25maWdDYWNoZSkge1xuICAgICAgdGhpcy5odHRwTWV0aG9kQ29uZmlnQ2FjaGUgPSB7XG4gICAgICAgIGtleTogJ21ldGhvZCcsXG4gICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IG1ldGhvZCcsXG4gICAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMuaHR0cE1ldGhvZE9wdGlvbnNcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHBNZXRob2RDb25maWdDYWNoZTtcbiAgfVxuXG4gIGdldEhlYWRlck5hbWVDb25maWcoaW5kZXg6IG51bWJlcik6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgaWYgKCF0aGlzLmhlYWRlck5hbWVDb25maWdDYWNoZSkge1xuICAgICAgY29uc3QgZGVmYXVsdE9wdGlvbnMgPSBbXG4gICAgICAgIHsgaWQ6ICdzdHJpbmcnLCB2YWx1ZTogJ3N0cmluZycsIG5hbWU6ICdzdHJpbmcnLCBsYWJlbDogJ3N0cmluZycgfSxcbiAgICAgICAgeyBpZDogJ0NvbnRlbnQtVHlwZScsIHZhbHVlOiAnQ29udGVudC1UeXBlJywgbmFtZTogJ0NvbnRlbnQtVHlwZScsIGxhYmVsOiAnQ29udGVudC1UeXBlJyB9LFxuICAgICAgICB7IGlkOiAnQXV0aG9yaXphdGlvbicsIHZhbHVlOiAnQXV0aG9yaXphdGlvbicsIG5hbWU6ICdBdXRob3JpemF0aW9uJywgbGFiZWw6ICdBdXRob3JpemF0aW9uJyB9LFxuICAgICAgICB7IGlkOiAnQWNjZXB0JywgdmFsdWU6ICdBY2NlcHQnLCBuYW1lOiAnQWNjZXB0JywgbGFiZWw6ICdBY2NlcHQnIH1cbiAgICAgIF07XG4gICAgICBcbiAgICAgIHRoaXMuaGVhZGVyTmFtZUNvbmZpZ0NhY2hlID0ge1xuICAgICAgICBrZXk6ICduYW1lJyxcbiAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgaGVhZGVyJyxcbiAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLmhlYWRlck5hbWVPcHRpb25zLmxlbmd0aCA+IDAgPyB0aGlzLmhlYWRlck5hbWVPcHRpb25zIDogZGVmYXVsdE9wdGlvbnNcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmhlYWRlck5hbWVDb25maWdDYWNoZTtcbiAgfVxuXG4gIGdldFBhcmFtTmFtZUNvbmZpZyhpbmRleDogbnVtYmVyKTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHtcbiAgICBpZiAoIXRoaXMucGFyYW1OYW1lQ29uZmlnQ2FjaGUpIHtcbiAgICAgIHRoaXMucGFyYW1OYW1lQ29uZmlnQ2FjaGUgPSB7XG4gICAgICAgIGtleTogJ25hbWUnLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1BhcmFtZXRlciBuYW1lJyxcbiAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgICAgb3B0aW9uczogW11cbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBhcmFtTmFtZUNvbmZpZ0NhY2hlO1xuICB9XG5cbiAgZ2V0SGVhZGVyRm9ybUdyb3VwKGluZGV4OiBudW1iZXIpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmhlYWRlcnNGb3JtQXJyYXkuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgfVxuXG4gIGdldFBhcmFtRm9ybUdyb3VwKGluZGV4OiBudW1iZXIpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLnBhcmFtc0Zvcm1BcnJheS5hdChpbmRleCkgYXMgRm9ybUdyb3VwO1xuICB9XG5cbiAgb25UYWJDaGFuZ2UodGFiOiBSZXF1ZXN0VGFiKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFRhYiA9IHRhYjtcbiAgfVxuXG4gIG9uU2VuZFJlcXVlc3QoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXBpRm9ybS52YWxpZCkge1xuICAgICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy5hcGlGb3JtLnZhbHVlO1xuICAgICAgY29uc3QgaGVhZGVycyA9IGZvcm1WYWx1ZS5oZWFkZXJzLm1hcCgoaDogYW55KSA9PiAoe1xuICAgICAgICBuYW1lOiBoLm5hbWUsXG4gICAgICAgIHZhbHVlOiBoLnZhbHVlXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBmb3JtVmFsdWUucGFyYW1zID8gZm9ybVZhbHVlLnBhcmFtcy5tYXAoKHA6IGFueSkgPT4gKHtcbiAgICAgICAgbmFtZTogcC5uYW1lLFxuICAgICAgICB2YWx1ZTogcC52YWx1ZVxuICAgICAgfSkpIDogW107XG5cbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QuZW1pdCh7XG4gICAgICAgIG1ldGhvZDogZm9ybVZhbHVlLm1ldGhvZCxcbiAgICAgICAgdXJsOiBmb3JtVmFsdWUudXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5OiBmb3JtVmFsdWUuYm9keSxcbiAgICAgICAgcGFyYW1zXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvbkltcG9ydEN1cmwoKTogdm9pZCB7XG4gICAgdGhpcy5pbXBvcnRDdXJsLmVtaXQoKTtcbiAgfVxuXG4gIG9uQ2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsbGVkLmVtaXQoKTtcbiAgfVxuXG4gIG9uQ3JlYXRlU3RlcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hcGlGb3JtLnZhbGlkKSB7XG4gICAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmFwaUZvcm0udmFsdWU7XG4gICAgICBjb25zdCBzdGVwRGF0YTogQXBpRm9ybURhdGEgPSB7XG4gICAgICAgIG1ldGhvZDogZm9ybVZhbHVlLm1ldGhvZCxcbiAgICAgICAgdXJsOiBmb3JtVmFsdWUudXJsLFxuICAgICAgICBoZWFkZXJzOiBmb3JtVmFsdWUuaGVhZGVycy5tYXAoKGg6IGFueSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBoLm5hbWUsXG4gICAgICAgICAgdmFsdWU6IGgudmFsdWVcbiAgICAgICAgfSkpLFxuICAgICAgICBib2R5OiBmb3JtVmFsdWUuYm9keSxcbiAgICAgICAgcGFyYW1zOiBmb3JtVmFsdWUucGFyYW1zID8gZm9ybVZhbHVlLnBhcmFtcy5tYXAoKHA6IGFueSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBwLm5hbWUsXG4gICAgICAgICAgdmFsdWU6IHAudmFsdWVcbiAgICAgICAgfSkpIDogW10sXG4gICAgICAgIHNjcmlwdHM6IGZvcm1WYWx1ZS5zY3JpcHRzLFxuICAgICAgICB2YXJpYWJsZU5hbWU6IGZvcm1WYWx1ZS52YXJpYWJsZU5hbWUgfHwgJycsXG4gICAgICAgIHZhbGlkYXRpb246IGZvcm1WYWx1ZS52YWxpZGF0aW9uID8gZm9ybVZhbHVlLnZhbGlkYXRpb24ubWFwKCh2OiBhbnkpID0+ICh7XG4gICAgICAgICAganNvblBhdGg6IHYuanNvblBhdGgsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uVHlwZTogdi52ZXJpZmljYXRpb25UeXBlLFxuICAgICAgICAgIGV4cGVjdGVkVHlwZTogdi5leHBlY3RlZFR5cGUsXG4gICAgICAgICAgZXhwZWN0ZWRWYWx1ZTogdi5leHBlY3RlZFZhbHVlLFxuICAgICAgICAgIHJlc3VsdDogdi5yZXN1bHQgfHwgJ05vdCBydW4nXG4gICAgICAgIH0pKSA6IFtdXG4gICAgICB9O1xuICAgICAgdGhpcy5jcmVhdGVTdGVwLmVtaXQoc3RlcERhdGEpO1xuICAgIH1cbiAgfVxuXG4gIG9uTmV4dCgpOiB2b2lkIHtcbiAgICAvLyBNb3ZlIHRvIG5leHQgc3RlcCBvciBjcmVhdGUgc3RlcCBpZiBvbiBsYXN0IHN0ZXBcbiAgICBjb25zdCBzdGVwT3JkZXI6IFByb2dyZXNzU3RlcFtdID0gWydyZXF1ZXN0LWRldGFpbHMnLCAnc3RvcmUtcmVzcG9uc2UnLCAndmFsaWRhdGlvbiddO1xuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHN0ZXBPcmRlci5pbmRleE9mKHRoaXMuc2VsZWN0ZWRQcm9ncmVzc1N0ZXApO1xuICAgIGlmIChjdXJyZW50SW5kZXggPCBzdGVwT3JkZXIubGVuZ3RoIC0gMSkge1xuICAgICAgdGhpcy5vblByb2dyZXNzU3RlcENoYW5nZShzdGVwT3JkZXJbY3VycmVudEluZGV4ICsgMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uQ3JlYXRlU3RlcCgpO1xuICAgIH1cbiAgfVxuXG4gIG9uQmFjaygpOiB2b2lkIHtcbiAgICAvLyBNb3ZlIHRvIHByZXZpb3VzIHN0ZXBcbiAgICBjb25zdCBzdGVwT3JkZXI6IFByb2dyZXNzU3RlcFtdID0gWydyZXF1ZXN0LWRldGFpbHMnLCAnc3RvcmUtcmVzcG9uc2UnLCAndmFsaWRhdGlvbiddO1xuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHN0ZXBPcmRlci5pbmRleE9mKHRoaXMuc2VsZWN0ZWRQcm9ncmVzc1N0ZXApO1xuICAgIGlmIChjdXJyZW50SW5kZXggPiAwKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKHN0ZXBPcmRlcltjdXJyZW50SW5kZXggLSAxXSk7XG4gICAgfVxuICB9XG5cbiAgY2FuR29CYWNrKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN0ZXBPcmRlcjogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2YodGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCk7XG4gICAgcmV0dXJuIGN1cnJlbnRJbmRleCA+IDA7XG4gIH1cblxuICBpc0xhc3RTdGVwKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN0ZXBPcmRlcjogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2YodGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCk7XG4gICAgcmV0dXJuIGN1cnJlbnRJbmRleCA9PT0gc3RlcE9yZGVyLmxlbmd0aCAtIDE7XG4gIH1cblxuICBnZXRQcm9ncmVzc1N0ZXBDbGFzcyhzdGVwOiBQcm9ncmVzc1N0ZXApOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0ZXBPcmRlcjogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2YodGhpcy5jdXJyZW50U3RlcCk7XG4gICAgY29uc3Qgc3RlcEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2Yoc3RlcCk7XG5cbiAgICBpZiAoc3RlcEluZGV4IDwgY3VycmVudEluZGV4KSB7XG4gICAgICByZXR1cm4gJ2NxYS10ZXh0LWdyYXktNDAwJzsgLy8gQ29tcGxldGVkXG4gICAgfSBlbHNlIGlmIChzdGVwSW5kZXggPT09IGN1cnJlbnRJbmRleCkge1xuICAgICAgcmV0dXJuICdjcWEtdGV4dC1wdXJwbGUtNjAwIGNxYS1mb250LXNlbWlib2xkJzsgLy8gQWN0aXZlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnY3FhLXRleHQtZ3JheS00MDAnOyAvLyBQZW5kaW5nXG4gICAgfVxuICB9XG5cbiAgZ2V0UHJvZ3Jlc3NTdGVwTnVtYmVyKHN0ZXA6IFByb2dyZXNzU3RlcCk6IG51bWJlciB7XG4gICAgY29uc3Qgc3RlcE9yZGVyOiBQcm9ncmVzc1N0ZXBbXSA9IFsncmVxdWVzdC1kZXRhaWxzJywgJ3N0b3JlLXJlc3BvbnNlJywgJ3ZhbGlkYXRpb24nXTtcbiAgICByZXR1cm4gc3RlcE9yZGVyLmluZGV4T2Yoc3RlcCkgKyAxO1xuICB9XG5cbiAgZ2V0UHJvZ3Jlc3NTdGVwTGFiZWwoc3RlcDogUHJvZ3Jlc3NTdGVwKTogc3RyaW5nIHtcbiAgICBjb25zdCBsYWJlbHM6IFJlY29yZDxQcm9ncmVzc1N0ZXAsIHN0cmluZz4gPSB7XG4gICAgICAncmVxdWVzdC1kZXRhaWxzJzogJ1JlcXVlc3QgRGV0YWlscycsXG4gICAgICAnc3RvcmUtcmVzcG9uc2UnOiAnU3RvcmUgUmVzcG9uc2UnLFxuICAgICAgJ3ZhbGlkYXRpb24nOiAnVmFsaWRhdGlvbidcbiAgICB9O1xuICAgIHJldHVybiBsYWJlbHNbc3RlcF07XG4gIH1cblxuICBmb3JtYXRKc29uUmVzcG9uc2UoZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoIWRhdGEpIHJldHVybiAnJztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIFN0cmluZyhkYXRhKTtcbiAgICB9XG4gIH1cbiAgXG4gIG9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKHN0ZXA6IFByb2dyZXNzU3RlcCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPSBzdGVwO1xuICAgIC8vIEluaXRpYWxpemUgdmFsaWRhdGlvbiBmb3JtIGFycmF5IGlmIHN3aXRjaGluZyB0byB2YWxpZGF0aW9uIHN0ZXBcbiAgICBpZiAoc3RlcCA9PT0gJ3ZhbGlkYXRpb24nICYmIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuYWRkVmFsaWRhdGlvblJ1bGUoKTtcbiAgICB9XG4gIH1cblxuICBhZGRWYWxpZGF0aW9uUnVsZSgpOiB2b2lkIHtcbiAgICBjb25zdCB2YWxpZGF0aW9uR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGNoZWNrZWQ6IFtmYWxzZV0sXG4gICAgICBqc29uUGF0aDogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIHZlcmlmaWNhdGlvblR5cGU6IFsnZXF1YWxzJ10sXG4gICAgICBleHBlY3RlZFR5cGU6IFsnc3RyaW5nJ10sXG4gICAgICBleHBlY3RlZFZhbHVlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgcmVzdWx0OiBbJ05vdCBydW4nXVxuICAgIH0pO1xuICAgIC8vIEVuc3VyZSBhbGwgY29udHJvbHMgYXJlIGVuYWJsZWQgdG8gYXZvaWQgZGlzYWJsZWQgYXR0cmlidXRlIHdhcm5pbmdzXG4gICAgdmFsaWRhdGlvbkdyb3VwLmVuYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LnB1c2godmFsaWRhdGlvbkdyb3VwKTtcbiAgfVxuXG4gIHJlbW92ZVZhbGlkYXRpb25SdWxlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICB9XG5cbiAgZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gIH1cblxuICB0cmFja0J5VmFsaWRhdGlvblJ1bGVJbmRleChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICB0cmFja0J5SGVhZGVySW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgdHJhY2tCeVBhcmFtSW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgZ2V0VmVyaWZpY2F0aW9uVHlwZU9wdGlvbnMoKTogU2VsZWN0T3B0aW9uW10ge1xuICAgIHJldHVybiBbXG4gICAgICB7IGlkOiAnZXF1YWxzJywgdmFsdWU6ICdlcXVhbHMnLCBuYW1lOiAnRXF1YWxzJywgbGFiZWw6ICdFcXVhbHMnIH0sXG4gICAgICB7IGlkOiAnbm90X2VxdWFscycsIHZhbHVlOiAnbm90X2VxdWFscycsIG5hbWU6ICdOb3QgRXF1YWxzJywgbGFiZWw6ICdOb3QgRXF1YWxzJyB9LFxuICAgICAgeyBpZDogJ2NvbnRhaW5zJywgdmFsdWU6ICdjb250YWlucycsIG5hbWU6ICdDb250YWlucycsIGxhYmVsOiAnQ29udGFpbnMnIH0sXG4gICAgICB7IGlkOiAnbm90X2NvbnRhaW5zJywgdmFsdWU6ICdub3RfY29udGFpbnMnLCBuYW1lOiAnTm90IENvbnRhaW5zJywgbGFiZWw6ICdOb3QgQ29udGFpbnMnIH0sXG4gICAgICB7IGlkOiAnZ3JlYXRlcl90aGFuJywgdmFsdWU6ICdncmVhdGVyX3RoYW4nLCBuYW1lOiAnR3JlYXRlciBUaGFuJywgbGFiZWw6ICdHcmVhdGVyIFRoYW4nIH0sXG4gICAgICB7IGlkOiAnbGVzc190aGFuJywgdmFsdWU6ICdsZXNzX3RoYW4nLCBuYW1lOiAnTGVzcyBUaGFuJywgbGFiZWw6ICdMZXNzIFRoYW4nIH0sXG4gICAgICB7IGlkOiAnZ3JlYXRlcl90aGFuX29yX2VxdWFscycsIHZhbHVlOiAnZ3JlYXRlcl90aGFuX29yX2VxdWFscycsIG5hbWU6ICdHcmVhdGVyIFRoYW4gT3IgRXF1YWxzJywgbGFiZWw6ICdHcmVhdGVyIFRoYW4gT3IgRXF1YWxzJyB9LFxuICAgICAgeyBpZDogJ2xlc3NfdGhhbl9vcl9lcXVhbHMnLCB2YWx1ZTogJ2xlc3NfdGhhbl9vcl9lcXVhbHMnLCBuYW1lOiAnTGVzcyBUaGFuIE9yIEVxdWFscycsIGxhYmVsOiAnTGVzcyBUaGFuIE9yIEVxdWFscycgfSxcbiAgICAgIHsgaWQ6ICdleGlzdHMnLCB2YWx1ZTogJ2V4aXN0cycsIG5hbWU6ICdFeGlzdHMnLCBsYWJlbDogJ0V4aXN0cycgfSxcbiAgICAgIHsgaWQ6ICdub3RfZXhpc3RzJywgdmFsdWU6ICdub3RfZXhpc3RzJywgbmFtZTogJ05vdCBFeGlzdHMnLCBsYWJlbDogJ05vdCBFeGlzdHMnIH1cbiAgICBdO1xuICB9XG5cbiAgZ2V0RXhwZWN0ZWRUeXBlT3B0aW9ucygpOiBTZWxlY3RPcHRpb25bXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsgaWQ6ICdzdHJpbmcnLCB2YWx1ZTogJ3N0cmluZycsIG5hbWU6ICdTdHJpbmcnLCBsYWJlbDogJ1N0cmluZycgfSxcbiAgICAgIHsgaWQ6ICdudW1iZXInLCB2YWx1ZTogJ251bWJlcicsIG5hbWU6ICdOdW1iZXInLCBsYWJlbDogJ051bWJlcicgfSxcbiAgICAgIHsgaWQ6ICdib29sZWFuJywgdmFsdWU6ICdib29sZWFuJywgbmFtZTogJ0Jvb2xlYW4nLCBsYWJlbDogJ0Jvb2xlYW4nIH0sXG4gICAgICB7IGlkOiAnb2JqZWN0JywgdmFsdWU6ICdvYmplY3QnLCBuYW1lOiAnT2JqZWN0JywgbGFiZWw6ICdPYmplY3QnIH0sXG4gICAgICB7IGlkOiAnYXJyYXknLCB2YWx1ZTogJ2FycmF5JywgbmFtZTogJ0FycmF5JywgbGFiZWw6ICdBcnJheScgfSxcbiAgICAgIHsgaWQ6ICdudWxsJywgdmFsdWU6ICdudWxsJywgbmFtZTogJ051bGwnLCBsYWJlbDogJ051bGwnIH1cbiAgICBdO1xuICB9XG5cbiAgZ2V0VmVyaWZpY2F0aW9uVHlwZUNvbmZpZyhpbmRleDogbnVtYmVyKTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHtcbiAgICAvLyBDYWNoZSB0aGUgY29uZmlnIHRvIHByZXZlbnQgaW5maW5pdGUgY2hhbmdlIGRldGVjdGlvbiBsb29wc1xuICAgIGlmICghdGhpcy52ZXJpZmljYXRpb25UeXBlQ29uZmlnQ2FjaGUpIHtcbiAgICAgIHRoaXMudmVyaWZpY2F0aW9uVHlwZUNvbmZpZ0NhY2hlID0ge1xuICAgICAgICBrZXk6ICd2ZXJpZmljYXRpb25UeXBlJyxcbiAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgdmVyaWZpY2F0aW9uIHR5cGUnLFxuICAgICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLmdldFZlcmlmaWNhdGlvblR5cGVPcHRpb25zKClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZlcmlmaWNhdGlvblR5cGVDb25maWdDYWNoZTtcbiAgfVxuXG4gIGdldEV4cGVjdGVkVHlwZUNvbmZpZyhpbmRleDogbnVtYmVyKTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHtcbiAgICAvLyBDYWNoZSB0aGUgY29uZmlnIHRvIHByZXZlbnQgaW5maW5pdGUgY2hhbmdlIGRldGVjdGlvbiBsb29wc1xuICAgIGlmICghdGhpcy5leHBlY3RlZFR5cGVDb25maWdDYWNoZSkge1xuICAgICAgdGhpcy5leHBlY3RlZFR5cGVDb25maWdDYWNoZSA9IHtcbiAgICAgICAga2V5OiAnZXhwZWN0ZWRUeXBlJyxcbiAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgZXhwZWN0ZWQgdHlwZScsXG4gICAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMuZ2V0RXhwZWN0ZWRUeXBlT3B0aW9ucygpXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5leHBlY3RlZFR5cGVDb25maWdDYWNoZTtcbiAgfVxuXG4gIGdldFJlc3VsdENsYXNzKHJlc3VsdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAocmVzdWx0ID09PSAnUGFzcycpIHtcbiAgICAgIHJldHVybiAnY3FhLWJnLWdyZWVuLTUwMCBjcWEtdGV4dC13aGl0ZSc7XG4gICAgfSBlbHNlIGlmIChyZXN1bHQgPT09ICdGYWlsJykge1xuICAgICAgcmV0dXJuICdjcWEtYmctcmVkLTUwMCBjcWEtdGV4dC13aGl0ZSc7XG4gICAgfVxuICAgIHJldHVybiAnY3FhLWJnLWdyYXktMzAwIGNxYS10ZXh0LWdyYXktNzAwJztcbiAgfVxuXG4gIGdldCBhbGxWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5Lmxlbmd0aCA+IDAgJiYgXG4gICAgICAgICAgIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5jb250cm9scy5ldmVyeShjb250cm9sID0+IGNvbnRyb2wuZ2V0KCdjaGVja2VkJyk/LnZhbHVlKTtcbiAgfVxuXG4gIGdldCBzb21lVmFsaWRhdGlvblJ1bGVzU2VsZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5jb250cm9scy5zb21lKGNvbnRyb2wgPT4gY29udHJvbC5nZXQoJ2NoZWNrZWQnKT8udmFsdWUpICYmIFxuICAgICAgICAgICAhdGhpcy5hbGxWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZDtcbiAgfVxuXG4gIG9uU2VsZWN0QWxsVmFsaWRhdGlvblJ1bGVzKGNoZWNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkuY29udHJvbHMuZm9yRWFjaChjb250cm9sID0+IHtcbiAgICAgIGNvbnRyb2wuZ2V0KCdjaGVja2VkJyk/LnNldFZhbHVlKGNoZWNrZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgb25EZWxldGVTZWxlY3RlZFZhbGlkYXRpb25SdWxlcygpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRpY2VzVG9SZW1vdmU6IG51bWJlcltdID0gW107XG4gICAgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LmNvbnRyb2xzLmZvckVhY2goKGNvbnRyb2wsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoY29udHJvbC5nZXQoJ2NoZWNrZWQnKT8udmFsdWUpIHtcbiAgICAgICAgaW5kaWNlc1RvUmVtb3ZlLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIFJlbW92ZSBpbiByZXZlcnNlIG9yZGVyIHRvIG1haW50YWluIGNvcnJlY3QgaW5kaWNlc1xuICAgIGluZGljZXNUb1JlbW92ZS5yZXZlcnNlKCkuZm9yRWFjaChpbmRleCA9PiB7XG4gICAgICB0aGlzLnJlbW92ZVZhbGlkYXRpb25SdWxlKGluZGV4KTtcbiAgICB9KTtcbiAgfVxufVxuXG4iLCI8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1oLWZ1bGwgY3FhLWJnLXdoaXRlIGNxYS1weC00IGNxYS1weS0yXCI+XG4gIDwhLS0gSGVhZGVyIC0tPlxuICA8aDIgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtYmxhY2stMTAwIGNxYS1tYi00XCI+XG4gICAgQ3JlYXRlIEFQSSBUZXN0IFN0ZXBcbiAgPC9oMj5cblxuICA8IS0tIFByb2dyZXNzIFRyYWNrZXIgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtNCBjcWEtbWItNiBjcWEtcGItNCBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDwhLS0gPGRpdiAqbmdGb3I9XCJsZXQgc3RlcCBvZiBwcm9ncmVzc1N0ZXBzXCJcbiAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIlxuICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0UHJvZ3Jlc3NTdGVwQ2xhc3Moc3RlcClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtXCI+e3sgZ2V0UHJvZ3Jlc3NTdGVwTnVtYmVyKHN0ZXApIH19IHt7IGdldFByb2dyZXNzU3RlcExhYmVsKHN0ZXApIH19PC9zcGFuPlxuICAgICAgPHNwYW4gKm5nSWY9XCJzdGVwICE9PSAndmFsaWRhdGlvbidcIiBjbGFzcz1cImNxYS10ZXh0LWdyYXktMzAwXCI+4oCiPC9zcGFuPlxuICAgIDwvZGl2PiAtLT5cbiAgICA8ZGl2XG4gICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCI+XG4gICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIiBbbmdDbGFzc109XCJ7J2NxYS10ZXh0LXB1cnBsZS02MDAgY3FhLWZvbnQtc2VtaWJvbGQnOiBzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3JlcXVlc3QtZGV0YWlscyd9XCIgKGNsaWNrKT1cIm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKCdyZXF1ZXN0LWRldGFpbHMnKVwiPlxuICAgICAgICAgIDxkaXY+MTwvZGl2PlxuICAgICAgICAgIDxkaXY+UmVxdWVzdCBEZXRhaWxzPC9kaXY+XG4gICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgIDwvZGl2PlxuICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCIgW25nQ2xhc3NdPVwieydjcWEtdGV4dC1wdXJwbGUtNjAwIGNxYS1mb250LXNlbWlib2xkJzogc2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPT09ICdzdG9yZS1yZXNwb25zZSd9XCIgKGNsaWNrKT1cIm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKCdzdG9yZS1yZXNwb25zZScpXCI+XG4gICAgICAgICAgPGRpdj4yPC9kaXY+XG4gICAgICAgICAgPGRpdj5TdG9yZSBSZXNwb25zZTwvZGl2PlxuICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICA8L2Rpdj5cbiAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiIFtuZ0NsYXNzXT1cInsnY3FhLXRleHQtcHVycGxlLTYwMCBjcWEtZm9udC1zZW1pYm9sZCc6IHNlbGVjdGVkUHJvZ3Jlc3NTdGVwID09PSAndmFsaWRhdGlvbid9XCIgKGNsaWNrKT1cIm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKCd2YWxpZGF0aW9uJylcIj5cbiAgICAgICAgICA8ZGl2PjM8L2Rpdj5cbiAgICAgICAgICA8ZGl2PlZhbGlkYXRpb248L2Rpdj5cbiAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPT09ICdyZXF1ZXN0LWRldGFpbHMnXCI+XG4gIDwhLS0gQVBJIFJlcXVlc3QgQ29uZmlndXJhdGlvbiAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS1tYi02XCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS13LTMyIGNxYS1mbGV4LXNocmluay0wXCI+XG4gICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0XG4gICAgICAgIFtmb3JtXT1cImFwaUZvcm1cIlxuICAgICAgICBbY29uZmlnXT1cImdldEh0dHBNZXRob2RDb25maWcoKVwiPlxuICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTFcIj5cbiAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgQVBJIGVuZHBvaW50IFVSTCdcIlxuICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3VybCcpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhcGlGb3JtLmdldCgndXJsJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8Y3FhLWJ1dHRvblxuICAgICAgdmFyaWFudD1cIm91dGxpbmVkXCJcbiAgICAgIHRleHQ9XCJJbXBvcnQgQVBJIGNVUkxcIlxuICAgICAgKGNsaWNrZWQpPVwib25JbXBvcnRDdXJsKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPGNxYS1idXR0b25cbiAgICAgIHZhcmlhbnQ9XCJmaWxsZWRcIlxuICAgICAgdGV4dD1cIlNlbmQgUmVxdWVzdFwiXG4gICAgICAoY2xpY2tlZCk9XCJvblNlbmRSZXF1ZXN0KClcIlxuICAgICAgW2Rpc2FibGVkXT1cIiFhcGlGb3JtLmdldCgndXJsJyk/LnZhbHVlIHx8IGlzTG9hZGluZ1wiPlxuICAgIDwvY3FhLWJ1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBSZXF1ZXN0IERldGFpbHMgVGFicyAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy1oaWRkZW4gY3FhLW1iLTZcIj5cbiAgICA8IS0tIFRhYiBOYXZpZ2F0aW9uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1iZy1ncmF5LTUwXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1weC00IGNxYS1weS0yIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdHJhbnNpdGlvbi1jb2xvcnMgY3FhLWJvcmRlci1iLTJcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdoZWFkZXJzJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAnaGVhZGVycydcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtZ3JheS02MDBdPVwic2VsZWN0ZWRUYWIgIT09ICdoZWFkZXJzJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLXRyYW5zcGFyZW50XT1cInNlbGVjdGVkVGFiICE9PSAnaGVhZGVycydcIlxuICAgICAgICAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ2hlYWRlcnMnKVwiPlxuICAgICAgICBIZWFkZXJzXG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10cmFuc2l0aW9uLWNvbG9ycyBjcWEtYm9yZGVyLWItMlwiXG4gICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ2JvZHknXCJcbiAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdib2R5J1wiXG4gICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ncmF5LTYwMF09XCJzZWxlY3RlZFRhYiAhPT0gJ2JvZHknXCJcbiAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItdHJhbnNwYXJlbnRdPVwic2VsZWN0ZWRUYWIgIT09ICdib2R5J1wiXG4gICAgICAgIChjbGljayk9XCJvblRhYkNoYW5nZSgnYm9keScpXCI+XG4gICAgICAgIEJvZHlcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAncGFyYW1zJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAncGFyYW1zJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ncmF5LTYwMF09XCJzZWxlY3RlZFRhYiAhPT0gJ3BhcmFtcydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci10cmFuc3BhcmVudF09XCJzZWxlY3RlZFRhYiAhPT0gJ3BhcmFtcydcIlxuICAgICAgICAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ3BhcmFtcycpXCI+XG4gICAgICAgIFBhcmFtc1xuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1weC00IGNxYS1weS0yIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdHJhbnNpdGlvbi1jb2xvcnMgY3FhLWJvcmRlci1iLTJcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdzY3JpcHRzJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAnc2NyaXB0cydcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtZ3JheS02MDBdPVwic2VsZWN0ZWRUYWIgIT09ICdzY3JpcHRzJ1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLXRyYW5zcGFyZW50XT1cInNlbGVjdGVkVGFiICE9PSAnc2NyaXB0cydcIlxuICAgICAgICAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ3NjcmlwdHMnKVwiPlxuICAgICAgICBTY3JpcHRzXG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gVGFiIENvbnRlbnQgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW92ZXJmbG93LXktYXV0byBjcWEtcC00IGNxYS1ib3JkZXIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtYm9yZGVyLXQtMCBjcWEtcm91bmRlZC1iLWxnXCI+XG4gICAgICA8IS0tIEhlYWRlcnMgVGFiIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnaGVhZGVycydcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1ncmlkIGNxYS1ncmlkLWNvbHMtMiBjcWEtZ2FwLTQgY3FhLWl0ZW1zLXN0YXJ0XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5IZWFkZXIgTmFtZTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtdXBwZXJjYXNlXCI+SGVhZGVyIFZhbHVlPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgaGVhZGVyc0Zvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUhlYWRlckluZGV4XCIgXG4gICAgICAgICAgICAgY2xhc3M9XCJjcWEtZ3JpZCBjcWEtZ3JpZC1jb2xzLTIgY3FhLWdhcC00IGNxYS1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdFxuICAgICAgICAgICAgICBbZm9ybV09XCJnZXRIZWFkZXJGb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cImdldEhlYWRlck5hbWVDb25maWcoaSlcIj5cbiAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTFcIj5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXRcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0hlYWRlciB2YWx1ZSdcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRIZWFkZXJGb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0SGVhZGVyRm9ybUdyb3VwKGkpLmdldCgndmFsdWUnKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXctOCBjcWEtaC04IGNxYS1yb3VuZGVkIGNxYS10ZXh0LXJlZC01MDAgaG92ZXI6Y3FhLXRleHQtcmVkLTcwMCBob3ZlcjpjcWEtYmctcmVkLTUwIGNxYS10cmFuc2l0aW9uLWNvbG9yc1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVIZWFkZXIoaSlcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidSZW1vdmUgaGVhZGVyJ1wiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1sZ1wiPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cImNxYS10ZXh0LWJsdWUtNjAwIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtc2VsZi1zdGFydCBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMSBob3ZlcjpjcWEtdGV4dC1ibHVlLTcwMCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgIChjbGljayk9XCJhZGRIZWFkZXIoKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS10ZXh0LWJhc2VcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgIDxzcGFuPkFkZCBIZWFkZXI8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQm9keSBUYWIgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdib2R5J1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8Y3FhLWN1c3RvbS10ZXh0YXJlYVxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgcmVxdWVzdCBib2R5IChKU09OLCBYTUwsIGV0Yy4pJ1wiXG4gICAgICAgICAgW3ZhbHVlXT1cImFwaUZvcm0uZ2V0KCdib2R5Jyk/LnZhbHVlIHx8ICcnXCJcbiAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgIFtyb3dzXT1cIjEwXCJcbiAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiYXBpRm9ybS5nZXQoJ2JvZHknKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICA8L2NxYS1jdXN0b20tdGV4dGFyZWE+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBQYXJhbXMgVGFiIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAncGFyYW1zJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWdyaWQgY3FhLWdyaWQtY29scy0yIGNxYS1nYXAtNCBjcWEtaXRlbXMtc3RhcnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQteHMgY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPlBhcmFtZXRlciBOYW1lPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5QYXJhbWV0ZXIgVmFsdWU8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHBhcmFtIG9mIHBhcmFtc0Zvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVBhcmFtSW5kZXhcIiBcbiAgICAgICAgICAgICBjbGFzcz1cImNxYS1ncmlkIGNxYS1ncmlkLWNvbHMtMiBjcWEtZ2FwLTQgY3FhLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1BhcmFtZXRlciBuYW1lJ1wiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRQYXJhbUZvcm1Hcm91cChpKS5nZXQoJ25hbWUnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCduYW1lJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xXCI+XG4gICAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidQYXJhbWV0ZXIgdmFsdWUnXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtdy04IGNxYS1oLTggY3FhLXJvdW5kZWQgY3FhLXRleHQtcmVkLTUwMCBob3ZlcjpjcWEtdGV4dC1yZWQtNzAwIGhvdmVyOmNxYS1iZy1yZWQtNTAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZVBhcmFtKGkpXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInUmVtb3ZlIHBhcmFtZXRlcidcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY3FhLXRleHQtbGdcIj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC1ibHVlLTYwMCBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXNlbGYtc3RhcnQgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgaG92ZXI6Y3FhLXRleHQtYmx1ZS03MDAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgICAoY2xpY2spPVwiYWRkUGFyYW0oKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS10ZXh0LWJhc2VcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgIDxzcGFuPkFkZCBQYXJhbWV0ZXI8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU2NyaXB0cyBUYWIgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdzY3JpcHRzJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8Y3FhLWN1c3RvbS10ZXh0YXJlYVxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgc2NyaXB0cyAoSmF2YVNjcmlwdCwgZXRjLiknXCJcbiAgICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3NjcmlwdHMnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgW3Jvd3NdPVwiMTBcIlxuICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhcGlGb3JtLmdldCgnc2NyaXB0cycpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgIDwvY3FhLWN1c3RvbS10ZXh0YXJlYT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuXG48L25nLWNvbnRhaW5lcj5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3N0b3JlLXJlc3BvbnNlJ1wiPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1mbGV4LTEgY3FhLW1heC1oLVs1MDBweF0gY3FhLW92ZXJmbG93LXktYXV0b1wiPlxuICAgIDwhLS0gU3RvcmUgUmVzcG9uc2UgVGl0bGUgLS0+XG4gICAgPGgzIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWJsYWNrLTEwMCBjcWEtbWItNFwiPlxuICAgICAgU3RvcmUgUmVzcG9uc2VcbiAgICA8L2gzPlxuXG4gICAgPCEtLSBWYXJpYWJsZSBOYW1lIElucHV0IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtbWItNlwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtbWItMSBjcWEtYmxvY2tcIj5cbiAgICAgICAgVmFyaWFibGUgTmFtZVxuICAgICAgPC9sYWJlbD5cbiAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInVmFyaWFibGUgTmFtZSdcIlxuICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3ZhcmlhYmxlTmFtZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhcGlGb3JtLmdldCgndmFyaWFibGVOYW1lJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3ZhbGlkYXRpb24nXCI+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWZsZXgtMSBjcWEtbWF4LWgtWzUwMHB4XSBjcWEtb3ZlcmZsb3cteS1hdXRvXCI+XG4gICAgPCEtLSBWYWxpZGF0aW9uIFJ1bGVzIFRpdGxlIC0tPlxuICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ibGFjay0xMDAgY3FhLW1iLTRcIj5cbiAgICAgIFZhbGlkYXRpb24gUnVsZXNcbiAgICA8L2gzPlxuXG4gICAgPCEtLSBWYWxpZGF0aW9uIFJ1bGVzIFRhYmxlIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtYmctd2hpdGUgY3FhLWJvcmRlciBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1yb3VuZGVkLWxnIGNxYS1vdmVyZmxvdy1oaWRkZW4gY3FhLW1iLTRcIj5cbiAgICAgIDwhLS0gVGFibGUgSGVhZGVyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1ncmlkIGNxYS1ncmlkLWNvbHMtNiBjcWEtZ2FwLTIgY3FhLXAtMyBjcWEtYmctZ3JheS01MCBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgW2NoZWNrZWRdPVwiYWxsVmFsaWRhdGlvblJ1bGVzU2VsZWN0ZWRcIlxuICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic29tZVZhbGlkYXRpb25SdWxlc1NlbGVjdGVkXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwib25TZWxlY3RBbGxWYWxpZGF0aW9uUnVsZXMoJGV2ZW50LmNoZWNrZWQpXCI+XG4gICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5qc29uUGF0aDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj52ZXJpZmljYXRpb25UeXBlPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPmV4cGVjdGVkVHlwZTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5leHBlY3RlZFZhbHVlPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPlJlc3VsdDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFibGUgQm9keSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdmFsaWRhdGlvblJ1bGUgb2YgdmFsaWRhdGlvbkZvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVZhbGlkYXRpb25SdWxlSW5kZXhcIiBcbiAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWdyaWQgY3FhLWdyaWQtY29scy02IGNxYS1nYXAtMiBjcWEtcC0zIGNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1pdGVtcy1jZW50ZXIgY3FhLWxhc3Q6Ym9yZGVyLWItMFwiPlxuICAgICAgICAgIDwhLS0gQ2hlY2tib3ggLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggZm9ybUNvbnRyb2xOYW1lPVwiY2hlY2tlZFwiPlxuICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGpzb25QYXRoIC0tPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ2pzb25QYXRoJ1wiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpLmdldCgnanNvblBhdGgnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2pzb25QYXRoJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gdmVyaWZpY2F0aW9uVHlwZSAtLT5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdFxuICAgICAgICAgICAgICBbZm9ybV09XCJnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJnZXRWZXJpZmljYXRpb25UeXBlQ29uZmlnKGkpXCI+XG4gICAgICAgICAgICA8L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gZXhwZWN0ZWRUeXBlIC0tPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0XG4gICAgICAgICAgICAgIFtmb3JtXT1cImdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cImdldEV4cGVjdGVkVHlwZUNvbmZpZyhpKVwiPlxuICAgICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGV4cGVjdGVkVmFsdWUgLS0+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInZXhwZWN0ZWRWYWx1ZSdcIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2V4cGVjdGVkVmFsdWUnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2V4cGVjdGVkVmFsdWUnKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBSZXN1bHQgYW5kIERlbGV0ZSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTMgY3FhLXB5LTEgY3FhLXJvdW5kZWQgY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LW1lZGl1bVwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFJlc3VsdENsYXNzKGdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSkuZ2V0KCdyZXN1bHQnKT8udmFsdWUgfHwgJ05vdCBydW4nKVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpLmdldCgncmVzdWx0Jyk/LnZhbHVlIHx8ICdOb3QgcnVuJyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTYgY3FhLWgtNiBjcWEtcm91bmRlZCBjcWEtdGV4dC1yZWQtNTAwIGhvdmVyOmNxYS10ZXh0LXJlZC03MDAgaG92ZXI6Y3FhLWJnLXJlZC01MCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlVmFsaWRhdGlvblJ1bGUoaSlcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidEZWxldGUgdmFsaWRhdGlvbiBydWxlJ1wiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBBZGQgQW5vdGhlciBSdWxlIGFuZCBEZWxldGUgU2VsZWN0ZWQgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWl0ZW1zLWNlbnRlciBjcWEtbWItNFwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAqbmdJZj1cInNvbWVWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZCB8fCBhbGxWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZFwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS10ZXh0LXJlZC02MDAgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xIGhvdmVyOmNxYS10ZXh0LXJlZC03MDAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlU2VsZWN0ZWRWYWxpZGF0aW9uUnVsZXMoKVwiPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+RGVsZXRlIFNlbGVjdGVkPC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS10ZXh0LWJsdWUtNjAwIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMSBob3ZlcjpjcWEtdGV4dC1ibHVlLTcwMCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAoY2xpY2spPVwiYWRkVmFsaWRhdGlvblJ1bGUoKVwiPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+QWRkIEFub3RoZXI8L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuXG4gIDwhLS0gUmVzcG9uc2UgUHJldmlldyBTZWN0aW9uIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtcm91bmRlZC1sZyBjcWEtb3ZlcmZsb3ctaGlkZGVuIGNxYS1tYi02XCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1wLTMgY3FhLWJnLWdyYXktNTAgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwXCI+UmVzcG9uc2UgUHJldmlldzwvaDM+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1wLTQgY3FhLWJnLWdyYXktNTAgY3FhLW92ZXJmbG93LWF1dG9cIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDMwMHB4O1wiPlxuICAgICAgPHByZSAqbmdJZj1cInJlc3BvbnNlUHJldmlld1wiIGNsYXNzPVwiY3FhLXRleHQteHMgY3FhLWZvbnQtbW9ubyBjcWEtdGV4dC1ncmF5LTgwMCBjcWEtd2hpdGVzcGFjZS1wcmUtd3JhcFwiPnt7IGZvcm1hdEpzb25SZXNwb25zZShyZXNwb25zZVByZXZpZXcpIH19PC9wcmU+XG4gICAgICA8cCAqbmdJZj1cIiFyZXNwb25zZVByZXZpZXdcIiBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS10ZXh0LWdyYXktNDAwIGNxYS10ZXh0LWNlbnRlciBjcWEtcHktOFwiPlxuICAgICAgICBObyByZXNwb25zZSB5ZXQuIFNlbmQgYSByZXF1ZXN0IHRvIHNlZSB0aGUgcmVzcG9uc2UgcHJldmlldy5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwhLS0gQWN0aW9uIEJ1dHRvbnMgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtdy1mdWxsIGNxYS1nYXAtMiBjcWEtbXQtYXV0byBjcWEtcHQtNCBjcWEtYm9yZGVyLXQgY3FhLWJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDwhLS0gQ2FuY2VsIGJ1dHRvbiAob25seSBvbiBmaXJzdCBzdGVwKSAtLT5cbiAgICA8Y3FhLWJ1dHRvblxuICAgICAgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3JlcXVlc3QtZGV0YWlscydcIlxuICAgICAgY2xhc3M9XCJjcWEtdy0xLzJcIlxuICAgICAgdmFyaWFudD1cIm91dGxpbmVkXCJcbiAgICAgIHRleHQ9XCJDYW5jZWxcIlxuICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIChjbGlja2VkKT1cIm9uQ2FuY2VsKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPCEtLSBCYWNrIGJ1dHRvbiAob24gYWxsIHN0ZXBzIGV4Y2VwdCBmaXJzdCkgLS0+XG4gICAgPGNxYS1idXR0b25cbiAgICAgICpuZ0lmPVwic2VsZWN0ZWRQcm9ncmVzc1N0ZXAgIT09ICdyZXF1ZXN0LWRldGFpbHMnXCJcbiAgICAgIGNsYXNzPVwiY3FhLXctMS8yXCJcbiAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lZFwiXG4gICAgICB0ZXh0PVwiQmFja1wiXG4gICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS1mbGV4LTEgY3FhLXctZnVsbCdcIlxuICAgICAgKGNsaWNrZWQpPVwib25CYWNrKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPCEtLSBOZXh0L0NyZWF0ZSBTdGVwIGJ1dHRvbiAtLT5cbiAgICA8Y3FhLWJ1dHRvblxuICAgICAgY2xhc3M9XCJjcWEtdy0xLzJcIlxuICAgICAgdmFyaWFudD1cImZpbGxlZFwiXG4gICAgICBbdGV4dF09XCJpc0xhc3RTdGVwKCkgPyAnQ3JlYXRlIFN0ZXAnIDogJ05leHQnXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLWZsZXgtMSBjcWEtdy1mdWxsJ1wiXG4gICAgICAoY2xpY2tlZCk9XCJpc0xhc3RTdGVwKCkgPyBvbkNyZWF0ZVN0ZXAoKSA6IG9uTmV4dCgpXCI+XG4gICAgPC9jcWEtYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG4iXX0=
|