@cqa-lib/cqa-ui 1.1.238 → 1.1.239
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/test-case-details/ai-agent-step/ai-agent-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/ai-verify-step/ai-verify-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/api-step/api-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/condition-step/condition-step.component.mjs +38 -3
- package/esm2020/lib/test-case-details/custom-code-step/custom-code-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/database-step/database-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/loop-step/loop-step.component.mjs +506 -44
- package/esm2020/lib/test-case-details/normal-step/normal-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/restore-session-step/restore-session-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/screenshot-step/screenshot-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/scroll-step/scroll-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/step-group/step-group.component.mjs +18 -5
- package/esm2020/lib/test-case-details/test-case-details-renderer/test-case-details-renderer.component.mjs +21 -7
- package/esm2020/lib/test-case-details/test-case-step.models.mjs +1 -1
- package/esm2020/lib/test-case-details/upload-step/upload-step.component.mjs +3 -3
- package/esm2020/lib/test-case-details/verify-url-step/verify-url-step.component.mjs +3 -3
- package/fesm2015/cqa-lib-cqa-ui.mjs +610 -110
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +597 -77
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/test-case-details/condition-step/condition-step.component.d.ts +12 -1
- package/lib/test-case-details/loop-step/loop-step.component.d.ts +70 -8
- package/lib/test-case-details/step-group/step-group.component.d.ts +8 -1
- package/lib/test-case-details/test-case-details-renderer/test-case-details-renderer.component.d.ts +6 -2
- package/lib/test-case-details/test-case-step.models.d.ts +5 -0
- package/package.json +1 -1
- package/styles.css +1 -1
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
2
|
+
import { FormControl } from '@angular/forms';
|
|
2
3
|
import { StepTypes } from '../test-case-step.models';
|
|
3
4
|
import { STEP_ROW_ACTIONS_STYLES } from '../step-row-actions.styles';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
import * as i1 from "@angular/forms";
|
|
6
7
|
import * as i2 from "../../dynamic-select/dynamic-select-field.component";
|
|
7
|
-
import * as i3 from "../../
|
|
8
|
-
import * as i4 from "
|
|
9
|
-
import * as i5 from "
|
|
10
|
-
import * as i6 from "
|
|
8
|
+
import * as i3 from "../../autocomplete/autocomplete.component";
|
|
9
|
+
import * as i4 from "@angular/material/slide-toggle";
|
|
10
|
+
import * as i5 from "../../custom-input/custom-input.component";
|
|
11
|
+
import * as i6 from "../../button/button.component";
|
|
12
|
+
import * as i7 from "../test-case-details-renderer/test-case-details-renderer.component";
|
|
13
|
+
import * as i8 from "@angular/common";
|
|
14
|
+
import * as i9 from "ngx-drag-drop";
|
|
11
15
|
export class TestCaseLoopStepComponent {
|
|
12
|
-
constructor(fb) {
|
|
16
|
+
constructor(fb, cdr) {
|
|
13
17
|
this.fb = fb;
|
|
18
|
+
this.cdr = cdr;
|
|
14
19
|
this.loopType = 'for';
|
|
15
20
|
this.nestedSteps = [];
|
|
16
21
|
this.expanded = true;
|
|
@@ -26,6 +31,8 @@ export class TestCaseLoopStepComponent {
|
|
|
26
31
|
this.isLoadingDataProfiles = false;
|
|
27
32
|
/** Options for natural text actions (for while loop condition) */
|
|
28
33
|
this.naturalTextActionsOptions = [];
|
|
34
|
+
/** Function to process template variables for while condition (same as condition-step) */
|
|
35
|
+
this.setConditionTemplateVariables = () => [];
|
|
29
36
|
/** Show "Add Step Between" button above nested steps */
|
|
30
37
|
this.addStepBetweenAbove = false;
|
|
31
38
|
/** Show "Add Step Between" button below nested steps */
|
|
@@ -39,6 +46,7 @@ export class TestCaseLoopStepComponent {
|
|
|
39
46
|
this.conditionChange = new EventEmitter();
|
|
40
47
|
this.maxIterationsChange = new EventEmitter();
|
|
41
48
|
this.nestedStepChange = new EventEmitter();
|
|
49
|
+
/** Emits void when add is from nested content; emits { loopStepConfig } when empty-state add is clicked (same behaviour as add-step-between). */
|
|
42
50
|
this.addStep = new EventEmitter();
|
|
43
51
|
this.deleteStep = new EventEmitter();
|
|
44
52
|
this.duplicate = new EventEmitter();
|
|
@@ -64,6 +72,10 @@ export class TestCaseLoopStepComponent {
|
|
|
64
72
|
this.numberFn = Number;
|
|
65
73
|
/** When true, header shows inline edit form (dropdowns, inputs, Cancel/Apply) */
|
|
66
74
|
this.isEditing = false;
|
|
75
|
+
/** Selected template for while condition (same pattern as condition-step) */
|
|
76
|
+
this.selectedTemplate = null;
|
|
77
|
+
/** Template variables for while condition */
|
|
78
|
+
this.templateVariables = [];
|
|
67
79
|
/** Options for Loop Start / Loop End dropdowns (1-10) */
|
|
68
80
|
this.loopStepOptions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
69
81
|
/** Local copy of values while editing (for Cancel revert) */
|
|
@@ -92,25 +104,179 @@ export class TestCaseLoopStepComponent {
|
|
|
92
104
|
ngOnChanges(changes) {
|
|
93
105
|
if (changes['config'] && this.config) {
|
|
94
106
|
this.selected = this.config.selected || false;
|
|
107
|
+
if (this.loopType === 'while') {
|
|
108
|
+
this.rebuildWhileConditionFromNaturalTextAction();
|
|
109
|
+
}
|
|
110
|
+
// FOR loop: when step config has forLoopTestDataId/forLoopStartIndex/forLoopEndIndex, sync form and refresh select configs so dropdowns show selected
|
|
111
|
+
if (this.loopType === 'for') {
|
|
112
|
+
this.updateForLoopSelectConfigsSelectedValues();
|
|
113
|
+
if (this.editForm)
|
|
114
|
+
this.syncForLoopEditFormFromConfig();
|
|
115
|
+
this.cdr.detectChanges();
|
|
116
|
+
}
|
|
95
117
|
}
|
|
96
118
|
if (changes['dataProfileOptions'] || changes['hasMoreDataProfiles'] || changes['isLoadingDataProfiles']) {
|
|
97
119
|
this.updateTestDataProfileSelectConfig();
|
|
120
|
+
// When data profiles load in edit mode, sync form value so dropdown shows selected (forLoopTestDataId or testDataProfile)
|
|
121
|
+
if (this.loopType === 'for' && this.editForm && this.dataProfileOptions?.length) {
|
|
122
|
+
const cfg = this.config;
|
|
123
|
+
if (cfg?.forLoopTestDataId != null || this.testDataProfile)
|
|
124
|
+
this.syncForLoopEditFormFromConfig();
|
|
125
|
+
this.cdr.detectChanges();
|
|
126
|
+
}
|
|
98
127
|
}
|
|
99
128
|
if (changes['naturalTextActionsOptions']) {
|
|
100
129
|
this.updateConditionSelectConfig();
|
|
130
|
+
// When options load, populate condition + template from naturalTextActionId (same as condition-step)
|
|
131
|
+
if (this.loopType === 'while' && this.editForm && this.naturalTextActionsOptions?.length) {
|
|
132
|
+
this.rebuildWhileConditionFromNaturalTextAction();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Derive forOptionType for FOR loop from config so dropdown shows existing selection */
|
|
137
|
+
getForOptionTypeFromConfig() {
|
|
138
|
+
if (this.loopType !== 'for')
|
|
139
|
+
return null;
|
|
140
|
+
const cfg = this.config;
|
|
141
|
+
const hasTestDataId = cfg?.forLoopTestDataId != null || cfg?.dataMapJson?.forLoopTestDataId != null || cfg?.dataMapBean?.for_loop?.testDataId != null;
|
|
142
|
+
if (hasTestDataId || this.testDataProfile)
|
|
143
|
+
return 'test-data';
|
|
144
|
+
const hasFixed = cfg?.forLoopStartIndex != null || cfg?.forLoopEndIndex != null
|
|
145
|
+
|| cfg?.dataMapJson?.forLoopStartIndex != null || cfg?.dataMapJson?.forLoopEndIndex != null
|
|
146
|
+
|| cfg?.dataMapBean?.for_loop?.startIndex != null || cfg?.dataMapBean?.for_loop?.endIndex != null;
|
|
147
|
+
if (this.startStep != null || this.endStep != null || hasFixed)
|
|
148
|
+
return 'fixed';
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
/** Test Data Profile dropdown value: prefer forLoopTestDataId from config (or dataMapJson/dataMapBean). Use option.id when options loaded so type matches select. */
|
|
152
|
+
getTestDataProfileFormValue() {
|
|
153
|
+
const cfg = this.config;
|
|
154
|
+
const idFromConfig = cfg?.forLoopTestDataId ?? cfg?.dataMapJson?.forLoopTestDataId ?? cfg?.dataMapBean?.for_loop?.testDataId;
|
|
155
|
+
// When we have options, resolve by id so form value matches option.id (strict equality in dynamic-select)
|
|
156
|
+
if (this.loopType === 'for' && this.dataProfileOptions?.length) {
|
|
157
|
+
if (idFromConfig != null) {
|
|
158
|
+
const match = this.dataProfileOptions.find(o => o.id === idFromConfig || String(o.id) === String(idFromConfig));
|
|
159
|
+
if (match)
|
|
160
|
+
return match.id;
|
|
161
|
+
return idFromConfig;
|
|
162
|
+
}
|
|
163
|
+
const value = this.testDataProfile ?? '';
|
|
164
|
+
if (value !== '') {
|
|
165
|
+
const match = this.dataProfileOptions.find(o => o.name === value || String(o.id) === String(value));
|
|
166
|
+
if (match)
|
|
167
|
+
return match.id;
|
|
168
|
+
}
|
|
169
|
+
return value;
|
|
101
170
|
}
|
|
171
|
+
if (idFromConfig != null)
|
|
172
|
+
return idFromConfig;
|
|
173
|
+
return (this.testDataProfile ?? '');
|
|
174
|
+
}
|
|
175
|
+
/** Loop Start dropdown value: prefer forLoopStartIndex from config (or dataMapJson/dataMapBean), else startStep */
|
|
176
|
+
getLoopStartFormValue() {
|
|
177
|
+
const cfg = this.config;
|
|
178
|
+
const v = cfg?.forLoopStartIndex ?? cfg?.dataMapJson?.forLoopStartIndex ?? cfg?.dataMapBean?.for_loop?.startIndex;
|
|
179
|
+
if (v != null)
|
|
180
|
+
return Number(v);
|
|
181
|
+
return this.startStep ?? null;
|
|
182
|
+
}
|
|
183
|
+
/** Loop End dropdown value: prefer forLoopEndIndex from config (or dataMapJson/dataMapBean), else endStep */
|
|
184
|
+
getLoopEndFormValue() {
|
|
185
|
+
const cfg = this.config;
|
|
186
|
+
const v = cfg?.forLoopEndIndex ?? cfg?.dataMapJson?.forLoopEndIndex ?? cfg?.dataMapBean?.for_loop?.endIndex;
|
|
187
|
+
if (v != null)
|
|
188
|
+
return Number(v);
|
|
189
|
+
return this.endStep ?? null;
|
|
102
190
|
}
|
|
103
191
|
buildEditForm() {
|
|
192
|
+
// For while loop: if config has naturalTextActionId and options are already loaded, use them for initial condition + template
|
|
193
|
+
let conditionValue = this.condition ?? '';
|
|
194
|
+
if (this.loopType === 'while') {
|
|
195
|
+
const populated = this.populateWhileConditionFromNaturalTextActionId();
|
|
196
|
+
if (populated?.condition != null) {
|
|
197
|
+
conditionValue = populated.condition;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// For FOR loop: initial form values so dropdowns show existing selection (forOptionType, forLoopTestDataId/testDataProfile, forLoopStartIndex/forLoopEndIndex)
|
|
201
|
+
const forOptionType = this.getForOptionTypeFromConfig();
|
|
202
|
+
const testDataProfileValue = this.loopType === 'for' ? this.getTestDataProfileFormValue() : (this.testDataProfile ?? '');
|
|
203
|
+
const loopStartValue = this.loopType === 'for' ? this.getLoopStartFormValue() : (this.startStep ?? null);
|
|
204
|
+
const loopEndValue = this.loopType === 'for' ? this.getLoopEndFormValue() : (this.endStep ?? null);
|
|
104
205
|
this.editForm = this.fb.group({
|
|
105
|
-
forOptionType: [
|
|
106
|
-
testDataProfile: [
|
|
107
|
-
startStep: [
|
|
108
|
-
endStep: [
|
|
109
|
-
condition: [
|
|
206
|
+
forOptionType: [forOptionType],
|
|
207
|
+
testDataProfile: [testDataProfileValue],
|
|
208
|
+
startStep: [loopStartValue],
|
|
209
|
+
endStep: [loopEndValue],
|
|
210
|
+
condition: [conditionValue],
|
|
110
211
|
maxIterations: [this.maxIterations ?? 5],
|
|
111
212
|
});
|
|
213
|
+
if (!this.templateVariablesForm) {
|
|
214
|
+
this.templateVariablesForm = this.fb.group({});
|
|
215
|
+
}
|
|
112
216
|
}
|
|
113
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* Populate condition, selectedTemplate and template variables from config.naturalTextActionId when options are available.
|
|
219
|
+
* Returns { condition } if a match was found so buildEditForm can set initial form value.
|
|
220
|
+
*/
|
|
221
|
+
populateWhileConditionFromNaturalTextActionId() {
|
|
222
|
+
const configWithId = this.config;
|
|
223
|
+
if (!configWithId?.naturalTextActionId || !this.naturalTextActionsOptions?.length) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const matchingOption = this.naturalTextActionsOptions.find((option) => String(option.id) === String(configWithId.naturalTextActionId));
|
|
227
|
+
if (!matchingOption) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
const naturalText = matchingOption.naturalText ?? matchingOption.name ?? matchingOption.value ?? '';
|
|
231
|
+
if (!naturalText) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
this.condition = naturalText;
|
|
235
|
+
const fullTemplate = matchingOption.template || matchingOption;
|
|
236
|
+
this.selectedTemplate = fullTemplate;
|
|
237
|
+
if (fullTemplate?.variables) {
|
|
238
|
+
this.templateVariables = this.setConditionTemplateVariables(fullTemplate) || [];
|
|
239
|
+
this.buildTemplateVariablesForm();
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
this.templateVariables = [];
|
|
243
|
+
}
|
|
244
|
+
this.cdr.detectChanges();
|
|
245
|
+
return { condition: naturalText };
|
|
246
|
+
}
|
|
247
|
+
/** Rebuild condition + template state when naturalTextActionsOptions load or config changes (same as condition-step). */
|
|
248
|
+
rebuildWhileConditionFromNaturalTextAction() {
|
|
249
|
+
if (!this.editForm || this.loopType !== 'while') {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const configWithId = this.config;
|
|
253
|
+
if (!configWithId?.naturalTextActionId || !this.naturalTextActionsOptions?.length) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const matchingOption = this.naturalTextActionsOptions.find((option) => String(option.id) === String(configWithId.naturalTextActionId));
|
|
257
|
+
if (!matchingOption) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const naturalText = matchingOption.naturalText ?? matchingOption.name ?? matchingOption.value ?? '';
|
|
261
|
+
if (naturalText) {
|
|
262
|
+
const currentValue = this.editForm.get('condition')?.value ?? '';
|
|
263
|
+
if (!currentValue || currentValue !== naturalText) {
|
|
264
|
+
this.editForm.get('condition')?.setValue(naturalText);
|
|
265
|
+
}
|
|
266
|
+
this.condition = naturalText;
|
|
267
|
+
}
|
|
268
|
+
const fullTemplate = matchingOption.template || matchingOption;
|
|
269
|
+
this.selectedTemplate = fullTemplate;
|
|
270
|
+
if (fullTemplate?.variables) {
|
|
271
|
+
this.templateVariables = this.setConditionTemplateVariables(fullTemplate) || [];
|
|
272
|
+
this.buildTemplateVariablesForm();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
this.templateVariables = [];
|
|
276
|
+
}
|
|
277
|
+
this.cdr.detectChanges();
|
|
278
|
+
}
|
|
279
|
+
/** Build select configs once (same option shape as default stories: id + name); FOR loop adds selectedValue from step */
|
|
114
280
|
buildSelectConfigs() {
|
|
115
281
|
const stepOptions = this.loopStepOptions.map((n) => ({
|
|
116
282
|
id: n,
|
|
@@ -128,21 +294,25 @@ export class TestCaseLoopStepComponent {
|
|
|
128
294
|
],
|
|
129
295
|
};
|
|
130
296
|
this.updateTestDataProfileSelectConfig();
|
|
297
|
+
const startVal = this.loopType === 'for' ? this.getLoopStartFormValue() : null;
|
|
298
|
+
const endVal = this.loopType === 'for' ? this.getLoopEndFormValue() : null;
|
|
131
299
|
this.startStepSelectConfig = {
|
|
132
300
|
key: 'startStep',
|
|
133
301
|
placeholder: 'Loop Start',
|
|
134
302
|
searchable: false,
|
|
135
303
|
options: stepOptions.map((o) => ({ ...o })),
|
|
304
|
+
...(startVal != null && { selectedValue: startVal }),
|
|
136
305
|
};
|
|
137
306
|
this.endStepSelectConfig = {
|
|
138
307
|
key: 'endStep',
|
|
139
308
|
placeholder: 'Loop End',
|
|
140
309
|
searchable: false,
|
|
141
310
|
options: stepOptions.map((o) => ({ ...o })),
|
|
311
|
+
...(endVal != null && { selectedValue: endVal }),
|
|
142
312
|
};
|
|
143
313
|
this.updateConditionSelectConfig();
|
|
144
314
|
}
|
|
145
|
-
/** Update condition select config with natural text actions options */
|
|
315
|
+
/** Update condition select config with natural text actions options (legacy mat-select) */
|
|
146
316
|
updateConditionSelectConfig() {
|
|
147
317
|
this.conditionSelectConfig = {
|
|
148
318
|
key: 'condition',
|
|
@@ -150,9 +320,115 @@ export class TestCaseLoopStepComponent {
|
|
|
150
320
|
searchable: true,
|
|
151
321
|
options: this.naturalTextActionsOptions || [],
|
|
152
322
|
};
|
|
323
|
+
this.updateWhileConditionSelectConfig();
|
|
324
|
+
}
|
|
325
|
+
/** While loop: only show options with stepActionType === "WHILE_LOOP" */
|
|
326
|
+
updateWhileConditionSelectConfig() {
|
|
327
|
+
const filteredOptions = (this.naturalTextActionsOptions || []).filter((option) => {
|
|
328
|
+
return option.stepActionType === 'WHILE_LOOP';
|
|
329
|
+
});
|
|
330
|
+
this.whileConditionSelectConfig = {
|
|
331
|
+
key: 'condition',
|
|
332
|
+
placeholder: 'Select condition',
|
|
333
|
+
searchable: true,
|
|
334
|
+
options: filteredOptions,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/** Options for the while condition autocomplete (WHILE_LOOP natural text actions only) */
|
|
338
|
+
get whileConditionAutocompleteOptions() {
|
|
339
|
+
const opts = this.whileConditionSelectConfig?.options ?? [];
|
|
340
|
+
return opts.map((option) => {
|
|
341
|
+
const naturalText = option.naturalText ?? option.name ?? option.value ?? String(option.id ?? '');
|
|
342
|
+
return {
|
|
343
|
+
value: naturalText,
|
|
344
|
+
label: naturalText,
|
|
345
|
+
template: option.template || option,
|
|
346
|
+
};
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
onConditionSelect(option) {
|
|
350
|
+
this.editForm?.get('condition')?.setValue(option.value);
|
|
351
|
+
const matchingTemplate = option.template;
|
|
352
|
+
let fullTemplate = matchingTemplate;
|
|
353
|
+
if (!fullTemplate || !fullTemplate.variables) {
|
|
354
|
+
const matchingOption = (this.naturalTextActionsOptions || []).find((opt) => opt.naturalText === option.value || opt.name === option.value || opt.value === option.value);
|
|
355
|
+
fullTemplate = matchingOption?.template || matchingOption;
|
|
356
|
+
}
|
|
357
|
+
if (fullTemplate && fullTemplate.variables) {
|
|
358
|
+
this.selectedTemplate = fullTemplate;
|
|
359
|
+
this.templateVariables = this.setConditionTemplateVariables(fullTemplate) || [];
|
|
360
|
+
this.buildTemplateVariablesForm();
|
|
361
|
+
this.cdr.detectChanges();
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
this.selectedTemplate = null;
|
|
365
|
+
this.templateVariables = [];
|
|
366
|
+
if (!this.templateVariablesForm) {
|
|
367
|
+
this.templateVariablesForm = this.fb.group({});
|
|
368
|
+
}
|
|
369
|
+
this.cdr.detectChanges();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
buildTemplateVariablesForm() {
|
|
373
|
+
if (!this.templateVariablesForm) {
|
|
374
|
+
this.templateVariablesForm = this.fb.group({});
|
|
375
|
+
}
|
|
376
|
+
Object.keys(this.templateVariablesForm.controls).forEach(key => {
|
|
377
|
+
this.templateVariablesForm.removeControl(key);
|
|
378
|
+
});
|
|
379
|
+
const configWithData = this.config;
|
|
380
|
+
const existingData = configWithData.templateVariablesData || {};
|
|
381
|
+
this.templateVariables.forEach(variable => {
|
|
382
|
+
let defaultValue;
|
|
383
|
+
if (existingData.hasOwnProperty(variable.name)) {
|
|
384
|
+
defaultValue = existingData[variable.name];
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
defaultValue = variable.type === 'boolean'
|
|
388
|
+
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
389
|
+
: (variable.value || '');
|
|
390
|
+
}
|
|
391
|
+
if (variable.type === 'boolean' && typeof defaultValue === 'string') {
|
|
392
|
+
defaultValue = defaultValue === 'true' || defaultValue === '1';
|
|
393
|
+
}
|
|
394
|
+
this.templateVariablesForm.addControl(variable.name, new FormControl(defaultValue));
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
getSelectConfigForVariable(variable) {
|
|
398
|
+
const options = (variable.options || []).map((opt) => ({
|
|
399
|
+
id: opt,
|
|
400
|
+
value: opt,
|
|
401
|
+
name: opt,
|
|
402
|
+
label: opt
|
|
403
|
+
}));
|
|
404
|
+
return {
|
|
405
|
+
key: variable.name,
|
|
406
|
+
placeholder: `Select ${variable.label}`,
|
|
407
|
+
multiple: false,
|
|
408
|
+
searchable: false,
|
|
409
|
+
options: options,
|
|
410
|
+
onChange: (value) => {
|
|
411
|
+
if (this.templateVariablesForm && this.templateVariablesForm.get(variable.name)) {
|
|
412
|
+
this.templateVariablesForm.get(variable.name)?.setValue(value);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
153
416
|
}
|
|
154
|
-
/** Update test data profile select config with current options and
|
|
417
|
+
/** Update test data profile select config with current options and selectedValue (forLoopTestDataId). Ensure selected id is in options so mat-select can display it. */
|
|
155
418
|
updateTestDataProfileSelectConfig() {
|
|
419
|
+
let options = this.convertDataProfileOptionsToSelectOptions(this.dataProfileOptions);
|
|
420
|
+
const cfg = this.config;
|
|
421
|
+
const forLoopTestDataId = cfg?.forLoopTestDataId ?? cfg?.dataMapJson?.forLoopTestDataId ?? cfg?.dataMapBean?.for_loop?.testDataId;
|
|
422
|
+
const selectedVal = this.loopType === 'for' ? this.getTestDataProfileFormValue() : undefined;
|
|
423
|
+
// If we have a preselected id but it's not in the current options list (e.g. options not loaded yet), add a placeholder option so the dropdown can show the selection
|
|
424
|
+
if (this.loopType === 'for' && forLoopTestDataId != null) {
|
|
425
|
+
const idStr = String(forLoopTestDataId);
|
|
426
|
+
const alreadyInList = options.some((o) => String(o.id ?? o.value) === idStr);
|
|
427
|
+
if (!alreadyInList) {
|
|
428
|
+
const displayName = this.testDataProfile || 'Selected profile';
|
|
429
|
+
options = [{ id: forLoopTestDataId, value: forLoopTestDataId, name: displayName, label: displayName }, ...options];
|
|
430
|
+
}
|
|
431
|
+
}
|
|
156
432
|
this.testDataProfileSelectConfig = {
|
|
157
433
|
key: 'testDataProfile',
|
|
158
434
|
placeholder: 'Testdataprofile',
|
|
@@ -160,7 +436,8 @@ export class TestCaseLoopStepComponent {
|
|
|
160
436
|
serverSearch: true,
|
|
161
437
|
hasMore: this.hasMoreDataProfiles,
|
|
162
438
|
isLoading: this.isLoadingDataProfiles,
|
|
163
|
-
options
|
|
439
|
+
options,
|
|
440
|
+
...(selectedVal !== undefined && selectedVal !== '' && { selectedValue: selectedVal }),
|
|
164
441
|
onChange: (value) => {
|
|
165
442
|
this.onDataProfileChange(value);
|
|
166
443
|
},
|
|
@@ -172,6 +449,36 @@ export class TestCaseLoopStepComponent {
|
|
|
172
449
|
},
|
|
173
450
|
};
|
|
174
451
|
}
|
|
452
|
+
/** Update Loop Start / Loop End select configs with selectedValue (forLoopStartIndex, forLoopEndIndex) so dropdowns show selected */
|
|
453
|
+
updateStartEndStepSelectConfigsSelectedValues() {
|
|
454
|
+
if (this.loopType !== 'for')
|
|
455
|
+
return;
|
|
456
|
+
const startVal = this.getLoopStartFormValue();
|
|
457
|
+
const endVal = this.getLoopEndFormValue();
|
|
458
|
+
const stepOptions = this.loopStepOptions.map((n) => ({
|
|
459
|
+
id: n,
|
|
460
|
+
value: n,
|
|
461
|
+
name: String(n),
|
|
462
|
+
label: String(n),
|
|
463
|
+
}));
|
|
464
|
+
this.startStepSelectConfig = {
|
|
465
|
+
...this.startStepSelectConfig,
|
|
466
|
+
options: stepOptions.map((o) => ({ ...o })),
|
|
467
|
+
...(startVal != null && { selectedValue: startVal }),
|
|
468
|
+
};
|
|
469
|
+
this.endStepSelectConfig = {
|
|
470
|
+
...this.endStepSelectConfig,
|
|
471
|
+
options: stepOptions.map((o) => ({ ...o })),
|
|
472
|
+
...(endVal != null && { selectedValue: endVal }),
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
/** Update all FOR loop select configs (testDataProfile, startStep, endStep) with selectedValue from step so dropdowns show selected */
|
|
476
|
+
updateForLoopSelectConfigsSelectedValues() {
|
|
477
|
+
if (this.loopType !== 'for')
|
|
478
|
+
return;
|
|
479
|
+
this.updateTestDataProfileSelectConfig();
|
|
480
|
+
this.updateStartEndStepSelectConfigsSelectedValues();
|
|
481
|
+
}
|
|
175
482
|
/** Convert DataProfileOption[] to SelectOption[] */
|
|
176
483
|
convertDataProfileOptionsToSelectOptions(options) {
|
|
177
484
|
return options.map(option => ({
|
|
@@ -208,33 +515,64 @@ export class TestCaseLoopStepComponent {
|
|
|
208
515
|
getEndLabel() {
|
|
209
516
|
return this.loopType === 'for' ? 'END FOR' : 'END WHILE';
|
|
210
517
|
}
|
|
518
|
+
/** Resolve display start index: prefer forLoopStartIndex from step (or dataMapJson/dataMapBean), else startStep, else from nested steps */
|
|
519
|
+
getDisplayStartIndex() {
|
|
520
|
+
const cfg = this.config;
|
|
521
|
+
const v = cfg?.forLoopStartIndex ?? cfg?.dataMapJson?.forLoopStartIndex ?? cfg?.dataMapBean?.for_loop?.startIndex;
|
|
522
|
+
if (v != null)
|
|
523
|
+
return Number(v);
|
|
524
|
+
if (this.startStep != null)
|
|
525
|
+
return this.startStep;
|
|
526
|
+
return this.nestedSteps[0]?.stepNumber;
|
|
527
|
+
}
|
|
528
|
+
/** Resolve display end index: prefer forLoopEndIndex from step (or dataMapJson/dataMapBean), else endStep, else from nested steps */
|
|
529
|
+
getDisplayEndIndex() {
|
|
530
|
+
const cfg = this.config;
|
|
531
|
+
const v = cfg?.forLoopEndIndex ?? cfg?.dataMapJson?.forLoopEndIndex ?? cfg?.dataMapBean?.for_loop?.endIndex;
|
|
532
|
+
if (v != null)
|
|
533
|
+
return Number(v);
|
|
534
|
+
if (this.endStep != null)
|
|
535
|
+
return this.endStep;
|
|
536
|
+
const last = this.nestedSteps[this.nestedSteps.length - 1];
|
|
537
|
+
return last?.stepNumber ?? this.nestedSteps.length;
|
|
538
|
+
}
|
|
539
|
+
/** Resolve display profile name: map forLoopTestDataId to profile name from dataProfileOptions, else use testDataProfile */
|
|
540
|
+
getDisplayTestDataProfileName() {
|
|
541
|
+
const cfg = this.config;
|
|
542
|
+
const id = cfg?.forLoopTestDataId ?? cfg?.dataMapJson?.forLoopTestDataId ?? cfg?.dataMapBean?.for_loop?.testDataId;
|
|
543
|
+
if (id != null && this.dataProfileOptions?.length) {
|
|
544
|
+
const match = this.dataProfileOptions.find(o => o.id === id || String(o.id) === String(id));
|
|
545
|
+
if (match)
|
|
546
|
+
return match.name;
|
|
547
|
+
}
|
|
548
|
+
return this.testDataProfile ?? '';
|
|
549
|
+
}
|
|
211
550
|
getStepsSummary() {
|
|
212
551
|
if (this.nestedSteps.length === 0) {
|
|
213
552
|
return '0 steps';
|
|
214
553
|
}
|
|
215
|
-
const start = this.
|
|
216
|
-
const end = this.
|
|
554
|
+
const start = this.getDisplayStartIndex() ?? 1;
|
|
555
|
+
const end = this.getDisplayEndIndex() ?? this.nestedSteps.length;
|
|
217
556
|
const count = this.nestedSteps.length;
|
|
218
557
|
return `Steps ${start}-${end} (${count} step${count !== 1 ? 's' : ''})`;
|
|
219
558
|
}
|
|
220
559
|
getStartStepLabel() {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return `Start: ${defaultStart}`;
|
|
560
|
+
const start = this.getDisplayStartIndex();
|
|
561
|
+
if (start != null)
|
|
562
|
+
return `Start: ${start}`;
|
|
563
|
+
return `Start: ${this.nestedSteps[0]?.stepNumber ?? 1}`;
|
|
226
564
|
}
|
|
227
565
|
getEndStepLabel() {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const defaultEnd = this.nestedSteps[this.nestedSteps.length - 1]?.stepNumber
|
|
566
|
+
const end = this.getDisplayEndIndex();
|
|
567
|
+
if (end != null)
|
|
568
|
+
return `End: ${end}`;
|
|
569
|
+
const defaultEnd = this.nestedSteps[this.nestedSteps.length - 1]?.stepNumber ?? this.nestedSteps.length;
|
|
232
570
|
return `End: ${defaultEnd}`;
|
|
233
571
|
}
|
|
234
572
|
getTestDataProfileLabel() {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
573
|
+
const name = this.getDisplayTestDataProfileName();
|
|
574
|
+
if (name)
|
|
575
|
+
return `Test Data profile: ${name}`;
|
|
238
576
|
return 'Test Data profile';
|
|
239
577
|
}
|
|
240
578
|
getConditionDisplay() {
|
|
@@ -289,8 +627,25 @@ export class TestCaseLoopStepComponent {
|
|
|
289
627
|
onAddStep() {
|
|
290
628
|
this.addStep.emit();
|
|
291
629
|
}
|
|
292
|
-
|
|
293
|
-
|
|
630
|
+
/** Called from empty-state plus only; same behaviour as add-step-between (parentId = loop step id, position = parent + 1). */
|
|
631
|
+
onAddStepEmpty() {
|
|
632
|
+
this.addStep.emit({ loopStepConfig: this.config });
|
|
633
|
+
}
|
|
634
|
+
onDeleteStep(payloadOrIndex, index) {
|
|
635
|
+
const idx = typeof index === 'number' ? index : payloadOrIndex;
|
|
636
|
+
const payload = typeof index === 'number' ? payloadOrIndex : undefined;
|
|
637
|
+
this.deleteStep.emit(idx);
|
|
638
|
+
if (payload?.step)
|
|
639
|
+
this.delete.emit(payload);
|
|
640
|
+
}
|
|
641
|
+
/** Re-emit edit from nested step so the portal can open edit modal (same as root level). */
|
|
642
|
+
onNestedEdit(event) {
|
|
643
|
+
if (event?.step != null)
|
|
644
|
+
this.edit.emit(event);
|
|
645
|
+
}
|
|
646
|
+
/** Re-emit duplicate from nested step so the portal can duplicate (same as root level). */
|
|
647
|
+
onNestedDuplicate(event, step) {
|
|
648
|
+
this.duplicate.emit((event && event.step != null) ? event : { step });
|
|
294
649
|
}
|
|
295
650
|
isNormalStep(step) {
|
|
296
651
|
return 'eventType' in step;
|
|
@@ -337,6 +692,31 @@ export class TestCaseLoopStepComponent {
|
|
|
337
692
|
onOpenExternal() {
|
|
338
693
|
// Not used in loop step, but needed for recursive step groups
|
|
339
694
|
}
|
|
695
|
+
/** Sync FOR loop edit form so dropdowns show existing config (forOptionType, forLoopTestDataId/testDataProfile, forLoopStartIndex/forLoopEndIndex) */
|
|
696
|
+
syncForLoopEditFormFromConfig() {
|
|
697
|
+
if (!this.editForm || this.loopType !== 'for')
|
|
698
|
+
return;
|
|
699
|
+
const testDataVal = this.getTestDataProfileFormValue();
|
|
700
|
+
const startVal = this.getLoopStartFormValue();
|
|
701
|
+
const endVal = this.getLoopEndFormValue();
|
|
702
|
+
this.editForm.patchValue({
|
|
703
|
+
forOptionType: this.getForOptionTypeFromConfig() ?? null,
|
|
704
|
+
testDataProfile: testDataVal,
|
|
705
|
+
startStep: startVal,
|
|
706
|
+
endStep: endVal,
|
|
707
|
+
});
|
|
708
|
+
// Explicitly set each control so mat-select picks up the value (patchValue can be ignored by child in some timing cases)
|
|
709
|
+
const testDataCtrl = this.editForm.get('testDataProfile');
|
|
710
|
+
const startCtrl = this.editForm.get('startStep');
|
|
711
|
+
const endCtrl = this.editForm.get('endStep');
|
|
712
|
+
if (testDataCtrl && testDataVal !== undefined && testDataVal !== '')
|
|
713
|
+
testDataCtrl.setValue(testDataVal, { emitEvent: false });
|
|
714
|
+
if (startCtrl && startVal != null)
|
|
715
|
+
startCtrl.setValue(startVal, { emitEvent: false });
|
|
716
|
+
if (endCtrl && endVal != null)
|
|
717
|
+
endCtrl.setValue(endVal, { emitEvent: false });
|
|
718
|
+
this.cdr.detectChanges();
|
|
719
|
+
}
|
|
340
720
|
onEdit() {
|
|
341
721
|
this.editSnapshot = {
|
|
342
722
|
testDataProfile: this.testDataProfile,
|
|
@@ -344,15 +724,48 @@ export class TestCaseLoopStepComponent {
|
|
|
344
724
|
endStep: this.endStep,
|
|
345
725
|
condition: this.condition,
|
|
346
726
|
maxIterations: this.maxIterations,
|
|
727
|
+
selectedTemplate: this.selectedTemplate,
|
|
728
|
+
templateVariables: this.templateVariables ? [...this.templateVariables] : [],
|
|
729
|
+
conditionTemplateFormValue: this.templateVariablesForm ? { ...this.templateVariablesForm.value } : undefined,
|
|
347
730
|
};
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
731
|
+
// FOR loop: refresh select configs (so Test Data Profile options include selected id if needed) then sync form so dropdowns show selected
|
|
732
|
+
if (this.loopType === 'for') {
|
|
733
|
+
this.updateForLoopSelectConfigsSelectedValues();
|
|
734
|
+
this.syncForLoopEditFormFromConfig();
|
|
735
|
+
setTimeout(() => {
|
|
736
|
+
this.syncForLoopEditFormFromConfig();
|
|
737
|
+
this.cdr.detectChanges();
|
|
738
|
+
}, 0);
|
|
739
|
+
}
|
|
740
|
+
else {
|
|
741
|
+
this.editForm.patchValue({
|
|
742
|
+
testDataProfile: this.testDataProfile ?? '',
|
|
743
|
+
startStep: this.startStep ?? null,
|
|
744
|
+
endStep: this.endStep ?? null,
|
|
745
|
+
condition: this.condition ?? '',
|
|
746
|
+
maxIterations: this.maxIterations ?? 5,
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
if (this.loopType === 'while') {
|
|
750
|
+
this.editForm.patchValue({
|
|
751
|
+
condition: this.condition ?? '',
|
|
752
|
+
maxIterations: this.maxIterations ?? 5,
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
// While loop: restore selected template and template variables from config when opening edit
|
|
756
|
+
if (this.loopType === 'while' && (this.condition || this.config.templateVariablesData)) {
|
|
757
|
+
const configWithData = this.config;
|
|
758
|
+
const conditionStr = this.condition || configWithData.condition || '';
|
|
759
|
+
if (conditionStr && (this.naturalTextActionsOptions || []).length > 0) {
|
|
760
|
+
const matchingOption = this.naturalTextActionsOptions.find((opt) => (opt.naturalText || opt.name || opt.value) === conditionStr);
|
|
761
|
+
const fullTemplate = matchingOption?.template || matchingOption;
|
|
762
|
+
if (fullTemplate && fullTemplate.variables) {
|
|
763
|
+
this.selectedTemplate = fullTemplate;
|
|
764
|
+
this.templateVariables = this.setConditionTemplateVariables(fullTemplate) || [];
|
|
765
|
+
this.buildTemplateVariablesForm();
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
356
769
|
this.isEditing = true;
|
|
357
770
|
this.edit.emit();
|
|
358
771
|
}
|
|
@@ -384,7 +797,22 @@ export class TestCaseLoopStepComponent {
|
|
|
384
797
|
else {
|
|
385
798
|
this.testDataProfile = testDataProfileValue;
|
|
386
799
|
}
|
|
387
|
-
//
|
|
800
|
+
// While loop: build templateVariablesData and naturalTextActionId from selected template (same as condition-step)
|
|
801
|
+
let templateVariablesData;
|
|
802
|
+
let naturalTextActionId;
|
|
803
|
+
if (this.loopType === 'while' && this.templateVariablesForm && this.templateVariables?.length) {
|
|
804
|
+
templateVariablesData = {};
|
|
805
|
+
this.templateVariables.forEach((variable) => {
|
|
806
|
+
const value = this.templateVariablesForm.get(variable.name)?.value;
|
|
807
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
808
|
+
templateVariablesData[variable.name] = value;
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
if (this.selectedTemplate?.id != null) {
|
|
812
|
+
naturalTextActionId = this.selectedTemplate.id;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
// Update config with new values (include testDataProfileId, templateVariablesData, naturalTextActionId for while; forLoopTestDataId, forLoopStartIndex/forLoopEndIndex for for)
|
|
388
816
|
const updatedConfig = {
|
|
389
817
|
...this.config,
|
|
390
818
|
testDataProfile: this.testDataProfile,
|
|
@@ -393,6 +821,11 @@ export class TestCaseLoopStepComponent {
|
|
|
393
821
|
endStep: this.endStep,
|
|
394
822
|
condition: this.condition,
|
|
395
823
|
maxIterations: this.maxIterations,
|
|
824
|
+
...(this.loopType === 'while' && Object.keys(templateVariablesData || {}).length > 0 && { templateVariablesData }),
|
|
825
|
+
...(this.loopType === 'while' && naturalTextActionId != null && { naturalTextActionId }),
|
|
826
|
+
...(this.loopType === 'for' && testDataProfileId != null && { forLoopTestDataId: Number(testDataProfileId) }),
|
|
827
|
+
...(this.loopType === 'for' && this.startStep != null && { forLoopStartIndex: this.startStep }),
|
|
828
|
+
...(this.loopType === 'for' && this.endStep != null && { forLoopEndIndex: this.endStep }),
|
|
396
829
|
};
|
|
397
830
|
// Emit individual change events
|
|
398
831
|
this.testDataProfileChange.emit(this.testDataProfile);
|
|
@@ -413,6 +846,11 @@ export class TestCaseLoopStepComponent {
|
|
|
413
846
|
this.endStep = this.editSnapshot.endStep;
|
|
414
847
|
this.condition = this.editSnapshot.condition;
|
|
415
848
|
this.maxIterations = this.editSnapshot.maxIterations;
|
|
849
|
+
this.selectedTemplate = this.editSnapshot.selectedTemplate;
|
|
850
|
+
this.templateVariables = this.editSnapshot.templateVariables || [];
|
|
851
|
+
if (this.templateVariablesForm && this.editSnapshot.conditionTemplateFormValue) {
|
|
852
|
+
this.templateVariablesForm.patchValue(this.editSnapshot.conditionTemplateFormValue);
|
|
853
|
+
}
|
|
416
854
|
this.isEditing = false;
|
|
417
855
|
}
|
|
418
856
|
onEditInDepth() {
|
|
@@ -454,12 +892,34 @@ export class TestCaseLoopStepComponent {
|
|
|
454
892
|
}
|
|
455
893
|
}
|
|
456
894
|
}
|
|
457
|
-
TestCaseLoopStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseLoopStepComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
458
|
-
TestCaseLoopStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TestCaseLoopStepComponent, selector: "cqa-test-case-loop-step", inputs: { config: "config", id: "id", loopType: "loopType", stepNumber: "stepNumber", condition: "condition", maxIterations: "maxIterations", testDataProfile: "testDataProfile", startStep: "startStep", endStep: "endStep", nestedSteps: "nestedSteps", expanded: "expanded", isNested: "isNested", isInsideLoop: "isInsideLoop", isReorder: "isReorder", selected: "selected", dataProfileOptions: "dataProfileOptions", hasMoreDataProfiles: "hasMoreDataProfiles", isLoadingDataProfiles: "isLoadingDataProfiles", naturalTextActionsOptions: "naturalTextActionsOptions", addStepBetweenAbove: "addStepBetweenAbove", addStepBetweenBelow: "addStepBetweenBelow", addStepBetween: "addStepBetween" }, outputs: { toggleExpanded: "toggleExpanded", testDataProfileChange: "testDataProfileChange", startStepChange: "startStepChange", endStepChange: "endStepChange", conditionChange: "conditionChange", maxIterationsChange: "maxIterationsChange", nestedStepChange: "nestedStepChange", addStep: "addStep", deleteStep: "deleteStep", duplicate: "duplicate", delete: "delete", moreOptions: "moreOptions", viewDetails: "viewDetails", editInDepth: "editInDepth", edit: "edit", dndDropInZone: "dndDropInZone", loadMoreDataProfiles: "loadMoreDataProfiles", searchDataProfiles: "searchDataProfiles", stepUpdate: "stepUpdate", clickAction: "clickAction", addStepBetweenClick: "addStepBetweenClick", selectionChange: "selectionChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "viewDetailsTrigger", first: true, predicate: ["viewDetailsTrigger"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col\">\n <!-- Inline Edit Mode: Frame 2147224910 - flex row, 1056\u00D736, gap 12px, flex-none -->\n <div *ngIf=\"isEditing\" class=\"cqa-py-2.5 cqa-px-4 cqa-flex cqa-items-center cqa-gap-3 cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-grow\">\n <!-- Loop Type Label -->\n <div class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getLoopTypeLabel() }}\n </div>\n\n <!-- FOR LOOP inline edit: cqa-dynamic-select (same usage as default stories) -->\n <ng-container *ngIf=\"loopType === 'for'\">\n <!-- First select: width 216.25px, height 36px, gap 4px, opacity 1 -->\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"forOptionTypeSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"testDataProfileSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"startStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"endStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- WHILE LOOP inline edit -->\n <ng-container *ngIf=\"isWhileLoop()\">\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"conditionSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Edit In depth link -->\n <a href=\"#\" (click)=\"onEditInDepth(); $event.preventDefault()\"\n class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-[2px] cqa-no-underline\">\n Edit In depth\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <!-- Cancel / Apply -->\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Cancel'\"\n (clicked)=\"onEditCancel()\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Apply'\"\n (clicked)=\"onEditApply()\"></cqa-button>\n </div>\n </div>\n\n <!-- Loop Header (normal view when not editing) -->\n <div *ngIf=\"!isEditing\"\n [class]=\"'step-row cqa-flex cqa-items-center cqa-gap-3 cqa-py-2 ' + (isInsideLoop ? 'cqa-pl-10 cqa-pr-4' : 'cqa-px-4')\">\n <div class=\"cqa-inline-flex cqa-items-center\">\n <!-- Drag Handle Icon (when isReorder is true) -->\n <div *ngIf=\"isReorder\" class=\"cqa-mr-2 cqa-cursor-move cqa-text-[#6B7280] hover:cqa-text-[#111827]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n </svg>\n </div>\n <!-- Checkbox (when isReorder is false) -->\n <label *ngIf=\"!isReorder\" class=\"cqa-flex cqa-items-center cqa-cursor-pointer cqa-relative cqa-mr-2\">\n <input type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"onSelectionChange($event)\"\n class=\"cqa-h-4 cqa-w-4 cqa-cursor-pointer cqa-transition-all cqa-appearance-none cqa-rounded shadow hover:cqa-shadow-md cqa-border cqa-border-solid cqa-border-slate-300 cqa-flex-shrink-0\"\n [class.cqa-bg-[#3F43EE]]=\"selected\"\n [class.cqa-border-[#3F43EE]]=\"selected\"\n id=\"check-loop-step\" />\n <span class=\"cqa-absolute cqa-text-white cqa-top-1/2 cqa-left-1/2 cqa--translate-x-1/2 cqa--translate-y-1/2 cqa-pointer-events-none cqa-flex cqa-items-center cqa-justify-center\"\n [class.cqa-opacity-0]=\"!selected\"\n [class.cqa-opacity-100]=\"selected\">\n <svg width=\"12\" height=\"13\" viewBox=\"0 0 12 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3.125L4.5 8.625L2 6.125\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </span>\n </label>\n </div>\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px]\">{{ stepNumber }}</span>\n <!-- Expand/Collapse Icon -->\n <button type=\"button\" (click)=\"onToggleExpanded()\" class=\"cqa-p-0\">\n <svg [class.cqa-rotate-180]=\"!expanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 10L8 6L4 10\" stroke=\"#6B7280\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Loop Icon -->\n <div *ngIf=\"loopType === 'for'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div *ngIf=\"loopType === 'while'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Loop Type Label -->\n <span class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-none\">\n {{ getLoopTypeLabel() }}\n </span>\n\n <!-- For Loop Controls -->\n <div *ngIf=\"loopType === 'for'\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2\">\n <!-- Test Data Profile Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"testDataProfile\" [class.cqa-text-primary]=\"testDataProfile\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getTestDataProfileLabel() }}\n </button>\n\n <!-- Start Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"startStep\" [class.cqa-text-primary]=\"startStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getStartStepLabel() }}\n </button>\n\n <!-- End Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"endStep\" [class.cqa-text-primary]=\"endStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getEndStepLabel() }}\n </button>\n </div>\n\n <!-- While Loop Condition (only show if condition exists) -->\n <div *ngIf=\"isWhileLoop() && condition\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2 cqa-flex-1\">\n <span class=\"cqa-text-gray-700 cqa-text-sm\">\n While\n </span>\n <span class=\"cqa-text-gray-900 cqa-text-sm\" [innerHTML]=\"getConditionDisplay()\"></span>\n </div>\n\n <!-- Steps Summary -->\n <div\n class=\"cqa-ml-auto cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-lg cqa-py-0.5 cqa-px-2 cqa-text-[#0A0A0A] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getStepsSummary() }}\n </div>\n\n <!-- View Details Link (show only if description is not empty) -->\n <a *ngIf=\"config.description && config.description.trim() !== ''\" #viewDetailsTrigger href=\"#\" (click)=\"onViewDetails($event)\" class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-2 cqa-no-underline cqa-ml-auto\">View Details<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\" fill=\"#3F43EE\"/></svg></a>\n\n <!-- Action Icons: Edit, Link, Duplicate, Delete (show on hover) -->\n <div class=\"step-actions cqa-flex cqa-items-center cqa-gap-3 cqa-px-[7px]\">\n <button type=\"button\" (click)=\"onEdit(); $event.stopPropagation()\" title=\"Edit\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 11.6666H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.55208 2.1128C9.7843 1.88058 10.0993 1.75012 10.4277 1.75012C10.7561 1.75012 11.071 1.88058 11.3033 2.1128C11.5355 2.34502 11.6659 2.65998 11.6659 2.98838C11.6659 3.31679 11.5355 3.63175 11.3033 3.86397L4.29742 10.8704C4.15864 11.0092 3.9871 11.1107 3.79867 11.1656L2.12333 11.6544C2.07314 11.669 2.01993 11.6699 1.96928 11.6569C1.91863 11.6439 1.8724 11.6176 1.83543 11.5806C1.79846 11.5437 1.7721 11.4974 1.75913 11.4468C1.74615 11.3961 1.74703 11.3429 1.76167 11.2927L2.2505 9.61738C2.30546 9.42916 2.40698 9.25783 2.54567 9.11922L9.55208 2.1128Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onLink(); $event.stopPropagation()\" title=\"Link\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.00065 9.91671H3.66732C2.78326 9.91671 1.93542 9.60942 1.3103 9.06244C0.685174 8.51545 0.333984 7.77359 0.333984 7.00004C0.333984 6.22649 0.685174 5.48463 1.3103 4.93765C1.93542 4.39066 2.78326 4.08337 3.66732 4.08337H5.00065\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M9 4.08337H10.3333C11.2174 4.08337 12.0652 4.39066 12.6904 4.93765C13.3155 5.48463 13.6667 6.22649 13.6667 7.00004C13.6667 7.77359 13.3155 8.51545 12.6904 9.06244C12.0652 9.60942 11.2174 9.91671 10.3333 9.91671H9\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.33398 7H9.66732\" stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDuplicate(); $event.stopPropagation()\" title=\"Duplicate\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.666 4.66663H5.83268C5.18835 4.66663 4.66602 5.18896 4.66602 5.83329V11.6666C4.66602 12.311 5.18835 12.8333 5.83268 12.8333H11.666C12.3103 12.8333 12.8327 12.311 12.8327 11.6666V5.83329C12.8327 5.18896 12.3103 4.66663 11.666 4.66663Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M2.33268 9.33329C1.69102 9.33329 1.16602 8.80829 1.16602 8.16663V2.33329C1.16602 1.69163 1.69102 1.16663 2.33268 1.16663H8.16602C8.80768 1.16663 9.33268 1.69163 9.33268 2.33329\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDelete(); $event.stopPropagation()\" title=\"Delete\"\n class=\"cqa-p-0 cqa-text-[#ff6467] hover:cqa-text-[#C63535]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.75 3.5H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M11.0827 3.5V11.6667C11.0827 12.25 10.4993 12.8333 9.91602 12.8333H4.08268C3.49935 12.8333 2.91602 12.25 2.91602 11.6667V3.5\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M4.66602 3.49996V2.33329C4.66602 1.74996 5.24935 1.16663 5.83268 1.16663H8.16602C8.74935 1.16663 9.33268 1.74996 9.33268 2.33329V3.49996\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.83398 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M8.16602 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <!-- Expanded Content with Nested Steps (renderer dispatches by step type, n-level nesting) -->\n <div *ngIf=\"expanded\" class=\"cqa-flex cqa-flex-col\">\n <div *ngIf=\"!isReorder\" class=\"cqa-flex cqa-flex-col\">\n <cqa-test-case-details-renderer *ngFor=\"let step of nestedSteps; let i = index\" [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep(i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n <div *ngIf=\"isReorder\" class=\"cqa-flex cqa-flex-col nested-step-drop-list\"\n [dndDropzone]=\"['step']\"\n dndEffectAllowed=\"move\"\n dndDragoverClass=\"dndDragover\"\n (dndDrop)=\"onDndDrop($event)\">\n <div dndPlaceholderRef class=\"step-drag-placeholder-nested cqa-my-1 cqa-min-h-[50px] cqa-border-2 cqa-border-dashed cqa-border-[#3F43EE] cqa-rounded cqa-bg-[rgba(63,67,238,0.08)] cqa-flex cqa-items-center cqa-justify-center cqa-text-[#3F43EE] cqa-text-xs\">Drop here</div>\n <div *ngFor=\"let step of nestedSteps; let i = index\" class=\"nested-step-drag-item\"\n [dndDraggable]=\"step\"\n dndEffectAllowed=\"move\"\n dndType=\"step\">\n <cqa-test-case-details-renderer [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetweenAbove]=\"addStepBetweenAbove\"\n [addStepBetweenBelow]=\"addStepBetweenBelow\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep(i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n </div>\n\n <!-- END Marker -->\n <div\n [class]=\"'cqa-pl-4 cqa-py-1 cqa-bg-[#DBEAFE80] cqa-text-[#1C398E] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium'\"\n style=\"border-top: 1px solid #BEDBFF;\">\n {{ getEndLabel() }}\n </div>\n </div>\n</div>", styles: [".step-actions{opacity:0;transition:opacity .15s ease}.step-row:hover .step-actions{opacity:1}\n"], components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i3.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i4.TestCaseDetailsRendererComponent, selector: "cqa-test-case-details-renderer", inputs: ["step", "index", "isNested", "isInsideLoop", "branch", "isReorder", "selected", "addStepBetweenAbove", "addStepBetweenBelow", "addStepBetween", "dataProfileOptions", "hasMoreDataProfiles", "isLoadingDataProfiles", "naturalTextActionsOptions", "setConditionTemplateVariables"], outputs: ["nestedStepChange", "addStep", "deleteStep", "toggleExpanded", "groupNameChange", "descriptionChange", "reusableChange", "openExternal", "edit", "link", "duplicate", "delete", "viewDetails", "selectionChange", "conditionChange", "branchStepChange", "addStepForBranch", "deleteStepWithBranch", "addBranch", "addElse", "deleteBranch", "testDataProfileChange", "startStepChange", "endStepChange", "maxIterationsChange", "eventTypeChange", "parameterChange", "clickAction", "dndDropInZone", "loadMoreDataProfiles", "searchDataProfiles", "stepUpdate", "addStepBetweenClick", "editInDepth"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.DndDropzoneDirective, selector: "[dndDropzone]", inputs: ["dndDropzone", "dndEffectAllowed", "dndAllowExternal", "dndHorizontal", "dndDragoverClass", "dndDropzoneDisabledClass", "dndDisableIf", "dndDisableDropIf"], outputs: ["dndDragover", "dndDrop"] }, { type: i6.DndPlaceholderRefDirective, selector: "[dndPlaceholderRef]" }, { type: i6.DndDraggableDirective, selector: "[dndDraggable]", inputs: ["dndDraggable", "dndEffectAllowed", "dndType", "dndDraggingClass", "dndDraggingSourceClass", "dndDraggableDisabledClass", "dndDragImageOffsetFunction", "dndDisableIf", "dndDisableDragIf"], outputs: ["dndStart", "dndDrag", "dndEnd", "dndMoved", "dndCopied", "dndLinked", "dndCanceled"] }] });
|
|
895
|
+
TestCaseLoopStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseLoopStepComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
896
|
+
TestCaseLoopStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TestCaseLoopStepComponent, selector: "cqa-test-case-loop-step", inputs: { config: "config", id: "id", loopType: "loopType", stepNumber: "stepNumber", condition: "condition", maxIterations: "maxIterations", testDataProfile: "testDataProfile", startStep: "startStep", endStep: "endStep", nestedSteps: "nestedSteps", expanded: "expanded", isNested: "isNested", isInsideLoop: "isInsideLoop", isReorder: "isReorder", selected: "selected", dataProfileOptions: "dataProfileOptions", hasMoreDataProfiles: "hasMoreDataProfiles", isLoadingDataProfiles: "isLoadingDataProfiles", naturalTextActionsOptions: "naturalTextActionsOptions", setConditionTemplateVariables: "setConditionTemplateVariables", addStepBetweenAbove: "addStepBetweenAbove", addStepBetweenBelow: "addStepBetweenBelow", addStepBetween: "addStepBetween" }, outputs: { toggleExpanded: "toggleExpanded", testDataProfileChange: "testDataProfileChange", startStepChange: "startStepChange", endStepChange: "endStepChange", conditionChange: "conditionChange", maxIterationsChange: "maxIterationsChange", nestedStepChange: "nestedStepChange", addStep: "addStep", deleteStep: "deleteStep", duplicate: "duplicate", delete: "delete", moreOptions: "moreOptions", viewDetails: "viewDetails", editInDepth: "editInDepth", edit: "edit", dndDropInZone: "dndDropInZone", loadMoreDataProfiles: "loadMoreDataProfiles", searchDataProfiles: "searchDataProfiles", stepUpdate: "stepUpdate", clickAction: "clickAction", addStepBetweenClick: "addStepBetweenClick", selectionChange: "selectionChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "viewDetailsTrigger", first: true, predicate: ["viewDetailsTrigger"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"loop-step-row cqa-flex cqa-flex-col\">\n <!-- Inline Edit Mode: Frame 2147224910 - flex row, 1056\u00D736, gap 12px, flex-none -->\n <div *ngIf=\"isEditing\" class=\"cqa-py-2.5 cqa-px-4 cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-grow\">\n <!-- Loop Type Label -->\n <div class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getLoopTypeLabel() }}\n </div>\n\n <!-- FOR LOOP inline edit: cqa-dynamic-select (same usage as default stories) -->\n <ng-container *ngIf=\"loopType === 'for'\">\n <!-- First select: width 216.25px, height 36px, gap 4px, opacity 1 -->\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"forOptionTypeSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"testDataProfileSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"startStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"endStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- WHILE LOOP inline edit: cqa-autocomplete + template variables (same as condition-step) -->\n <ng-container *ngIf=\"isWhileLoop()\">\n <cqa-autocomplete\n *ngIf=\"editForm\"\n [options]=\"whileConditionAutocompleteOptions\"\n [value]=\"editForm.get('condition')?.value ?? ''\"\n (valueChange)=\"onEditFormFieldChange('condition', $event)\"\n (optionSelect)=\"onConditionSelect($event)\"\n placeholder=\"Select condition\"\n [fullWidth]=\"true\"\n class=\"cqa-w-full cqa-max-w-[216px]\">\n </cqa-autocomplete>\n <!-- Template variables (shown when template is selected, same as condition-step) -->\n <div *ngIf=\"selectedTemplate && templateVariables && templateVariables.length > 0\" class=\"cqa-flex cqa-flex-row cqa-flex-wrap cqa-gap-3\">\n <ng-container *ngFor=\"let variable of templateVariables\">\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700\">{{ variable.label }}</label>\n <mat-slide-toggle\n [checked]=\"templateVariablesForm.get(variable.name)?.value || variable.value || false\"\n (change)=\"templateVariablesForm.get(variable.name)?.setValue($event.checked)\"\n color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'boolean' && variable.name !== 'custom_code'\">\n <ng-container *ngIf=\"variable.name === 'type' || variable.name === 'scrollTo' || variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"min-width: 150px;\">\n <cqa-dynamic-select\n [form]=\"templateVariablesForm\"\n [config]=\"getSelectConfigForVariable(variable)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.name !== 'type' && variable.name !== 'scrollTo' && !variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"min-width: 150px;\">\n <cqa-custom-input\n [placeholder]=\"'Enter ' + variable.label\"\n [value]=\"templateVariablesForm.get(variable.name)?.value || variable.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"templateVariablesForm.get(variable.name)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Edit In depth link -->\n <a href=\"#\" (click)=\"onEditInDepth(); $event.preventDefault()\"\n class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-[2px] cqa-no-underline\">\n Edit In depth\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <!-- Cancel / Apply -->\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Cancel'\"\n (clicked)=\"onEditCancel()\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Apply'\"\n (clicked)=\"onEditApply()\"></cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Loop Header (normal view when not editing) -->\n <div *ngIf=\"!isEditing\"\n [class]=\"'step-row cqa-flex cqa-items-center cqa-gap-3 cqa-py-2 ' + (isInsideLoop ? 'cqa-pl-10 cqa-pr-4' : 'cqa-px-4')\">\n <div class=\"cqa-inline-flex cqa-items-center\">\n <!-- Drag Handle Icon (when isReorder is true) -->\n <div *ngIf=\"isReorder\" class=\"cqa-mr-2 cqa-cursor-move cqa-text-[#6B7280] hover:cqa-text-[#111827]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n </svg>\n </div>\n <!-- Checkbox (when isReorder is false) -->\n <label *ngIf=\"!isReorder\" class=\"cqa-flex cqa-items-center cqa-cursor-pointer cqa-relative cqa-mr-2\">\n <input type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"onSelectionChange($event)\"\n class=\"cqa-h-4 cqa-w-4 cqa-cursor-pointer cqa-transition-all cqa-appearance-none cqa-rounded shadow hover:cqa-shadow-md cqa-border cqa-border-solid cqa-border-slate-300 cqa-flex-shrink-0\"\n [class.cqa-bg-[#3F43EE]]=\"selected\"\n [class.cqa-border-[#3F43EE]]=\"selected\"\n id=\"check-loop-step\" />\n <span class=\"cqa-absolute cqa-text-white cqa-top-1/2 cqa-left-1/2 cqa--translate-x-1/2 cqa--translate-y-1/2 cqa-pointer-events-none cqa-flex cqa-items-center cqa-justify-center\"\n [class.cqa-opacity-0]=\"!selected\"\n [class.cqa-opacity-100]=\"selected\">\n <svg width=\"12\" height=\"13\" viewBox=\"0 0 12 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3.125L4.5 8.625L2 6.125\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </span>\n </label>\n </div>\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px]\">{{ stepNumber }}</span>\n <!-- Expand/Collapse Icon -->\n <button type=\"button\" (click)=\"onToggleExpanded()\" class=\"cqa-p-0\">\n <svg [class.cqa-rotate-180]=\"!expanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 10L8 6L4 10\" stroke=\"#6B7280\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Step Number -->\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px] cqa-flex-shrink-0\">{{ stepNumber }}</span>\n\n <!-- Loop Icon -->\n <div *ngIf=\"loopType === 'for'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div *ngIf=\"loopType === 'while'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Loop Type Label -->\n <span class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-none\">\n {{ getLoopTypeLabel() }}\n </span>\n\n <!-- For Loop Controls -->\n <div *ngIf=\"loopType === 'for'\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2\">\n <!-- Test Data Profile Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"testDataProfile\" [class.cqa-text-primary]=\"testDataProfile\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getTestDataProfileLabel() }}\n </button>\n\n <!-- Start Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"startStep\" [class.cqa-text-primary]=\"startStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getStartStepLabel() }}\n </button>\n\n <!-- End Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"endStep\" [class.cqa-text-primary]=\"endStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getEndStepLabel() }}\n </button>\n </div>\n\n <!-- While Loop Condition (only show if condition exists) -->\n <div *ngIf=\"isWhileLoop() && condition\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2 cqa-flex-1\">\n <span class=\"cqa-text-gray-700 cqa-text-sm\">\n While\n </span>\n <span class=\"cqa-text-gray-900 cqa-text-sm\" [innerHTML]=\"getConditionDisplay()\"></span>\n </div>\n\n <!-- Steps Summary -->\n <div\n class=\"cqa-ml-auto cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-lg cqa-py-0.5 cqa-px-2 cqa-text-[#0A0A0A] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getStepsSummary() }}\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-ml-auto\">\n <!-- View Details Link (show only if description is not empty) -->\n <a *ngIf=\"config.description && config.description.trim() !== ''\" #viewDetailsTrigger href=\"#\" (click)=\"onViewDetails($event)\" class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-2 cqa-no-underline cqa-ml-auto\">View Details<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\" fill=\"#3F43EE\"/></svg></a>\n\n <!-- Action Icons: Edit, Link, Duplicate, Delete (show on hover) -->\n <div class=\"step-actions cqa-flex cqa-items-center cqa-gap-3 cqa-px-[7px]\">\n <button type=\"button\" (click)=\"onEdit(); $event.stopPropagation()\" title=\"Edit\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 11.6666H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.55208 2.1128C9.7843 1.88058 10.0993 1.75012 10.4277 1.75012C10.7561 1.75012 11.071 1.88058 11.3033 2.1128C11.5355 2.34502 11.6659 2.65998 11.6659 2.98838C11.6659 3.31679 11.5355 3.63175 11.3033 3.86397L4.29742 10.8704C4.15864 11.0092 3.9871 11.1107 3.79867 11.1656L2.12333 11.6544C2.07314 11.669 2.01993 11.6699 1.96928 11.6569C1.91863 11.6439 1.8724 11.6176 1.83543 11.5806C1.79846 11.5437 1.7721 11.4974 1.75913 11.4468C1.74615 11.3961 1.74703 11.3429 1.76167 11.2927L2.2505 9.61738C2.30546 9.42916 2.40698 9.25783 2.54567 9.11922L9.55208 2.1128Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <!-- <button type=\"button\" (click)=\"onLink(); $event.stopPropagation()\" title=\"Link\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.00065 9.91671H3.66732C2.78326 9.91671 1.93542 9.60942 1.3103 9.06244C0.685174 8.51545 0.333984 7.77359 0.333984 7.00004C0.333984 6.22649 0.685174 5.48463 1.3103 4.93765C1.93542 4.39066 2.78326 4.08337 3.66732 4.08337H5.00065\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M9 4.08337H10.3333C11.2174 4.08337 12.0652 4.39066 12.6904 4.93765C13.3155 5.48463 13.6667 6.22649 13.6667 7.00004C13.6667 7.77359 13.3155 8.51545 12.6904 9.06244C12.0652 9.60942 11.2174 9.91671 10.3333 9.91671H9\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.33398 7H9.66732\" stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button> -->\n <button type=\"button\" (click)=\"onDuplicate(); $event.stopPropagation()\" title=\"Duplicate\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.666 4.66663H5.83268C5.18835 4.66663 4.66602 5.18896 4.66602 5.83329V11.6666C4.66602 12.311 5.18835 12.8333 5.83268 12.8333H11.666C12.3103 12.8333 12.8327 12.311 12.8327 11.6666V5.83329C12.8327 5.18896 12.3103 4.66663 11.666 4.66663Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M2.33268 9.33329C1.69102 9.33329 1.16602 8.80829 1.16602 8.16663V2.33329C1.16602 1.69163 1.69102 1.16663 2.33268 1.16663H8.16602C8.80768 1.16663 9.33268 1.69163 9.33268 2.33329\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDelete(); $event.stopPropagation()\" title=\"Delete\"\n class=\"cqa-p-0 cqa-text-[#ff6467] hover:cqa-text-[#C63535]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.75 3.5H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M11.0827 3.5V11.6667C11.0827 12.25 10.4993 12.8333 9.91602 12.8333H4.08268C3.49935 12.8333 2.91602 12.25 2.91602 11.6667V3.5\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M4.66602 3.49996V2.33329C4.66602 1.74996 5.24935 1.16663 5.83268 1.16663H8.16602C8.74935 1.16663 9.33268 1.74996 9.33268 2.33329V3.49996\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.83398 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M8.16602 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Expanded Content with Nested Steps (renderer dispatches by step type, n-level nesting) -->\n <div *ngIf=\"expanded\" class=\"cqa-flex cqa-flex-col\">\n <div *ngIf=\"!isReorder\" class=\"cqa-flex cqa-flex-col\">\n <cqa-test-case-details-renderer *ngFor=\"let step of nestedSteps; let i = index\" [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedEdit($event)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedDuplicate($event, step)\" (delete)=\"onDeleteStep($event, i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n <div *ngIf=\"isReorder\" class=\"cqa-flex cqa-flex-col nested-step-drop-list\"\n [dndDropzone]=\"['step']\"\n dndEffectAllowed=\"move\"\n dndDragoverClass=\"dndDragover\"\n (dndDrop)=\"onDndDrop($event)\">\n <div dndPlaceholderRef class=\"step-drag-placeholder-nested cqa-my-1 cqa-min-h-[50px] cqa-border-2 cqa-border-dashed cqa-border-[#3F43EE] cqa-rounded cqa-bg-[rgba(63,67,238,0.08)] cqa-flex cqa-items-center cqa-justify-center cqa-text-[#3F43EE] cqa-text-xs\">Drop here</div>\n <div *ngFor=\"let step of nestedSteps; let i = index\" class=\"nested-step-drag-item\"\n [dndDraggable]=\"step\"\n dndEffectAllowed=\"move\"\n dndType=\"step\">\n <cqa-test-case-details-renderer [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetweenAbove]=\"addStepBetweenAbove\"\n [addStepBetweenBelow]=\"addStepBetweenBelow\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep($event, i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n </div>\n\n <!-- Empty loop: show plus icon on hover when expanded and no steps -->\n <div *ngIf=\"nestedSteps.length === 0\" class=\"loop-step-empty cqa-min-h-[52px] cqa-flex cqa-items-center cqa-justify-center cqa-pl-4 cqa-pr-4\">\n <button type=\"button\" (click)=\"onAddStepEmpty(); $event.stopPropagation()\" title=\"Add step\"\n class=\"loop-step-empty-add\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"21.1822\" height=\"22\" rx=\"10.5911\" fill=\"white\" />\n <rect x=\"1\" y=\"1\" width=\"21.1822\" height=\"22\" rx=\"10.5911\" stroke=\"#3F43EE\" stroke-width=\"2\" />\n <path d=\"M8.5 12H15.5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12 8.5V15.5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- END Marker -->\n <div\n [class]=\"'cqa-pl-4 cqa-py-1 cqa-bg-[#DBEAFE80] cqa-text-[#1C398E] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium'\"\n style=\"border-top: 1px solid #BEDBFF;\">\n {{ getEndLabel() }}\n </div>\n </div>\n</div>", styles: [".step-actions{opacity:0;transition:opacity .15s ease}.step-row:hover .step-actions{opacity:1}\n", ".loop-step-empty{opacity:0;transition:opacity .1s ease}.loop-step-row:hover .loop-step-empty{opacity:1}.loop-step-empty-add{padding:0;background:transparent;border:0;cursor:pointer;color:#3f43ee;transition:opacity .15s ease}.loop-step-empty-add:hover{opacity:.9}\n"], components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i3.AutocompleteComponent, selector: "cqa-autocomplete", inputs: ["placeholder", "options", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "optionSelect", "cleared"] }, { type: i4.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { type: i5.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: i6.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i7.TestCaseDetailsRendererComponent, selector: "cqa-test-case-details-renderer", inputs: ["step", "index", "isNested", "isInsideLoop", "branch", "isReorder", "selected", "addStepBetweenAbove", "addStepBetweenBelow", "addStepBetween", "dataProfileOptions", "hasMoreDataProfiles", "isLoadingDataProfiles", "naturalTextActionsOptions", "setConditionTemplateVariables"], outputs: ["nestedStepChange", "addStep", "deleteStep", "toggleExpanded", "groupNameChange", "descriptionChange", "reusableChange", "openExternal", "edit", "link", "duplicate", "delete", "viewDetails", "selectionChange", "conditionChange", "branchStepChange", "addStepForBranch", "addStepForLoop", "deleteStepWithBranch", "addBranch", "addElse", "deleteBranch", "testDataProfileChange", "startStepChange", "endStepChange", "maxIterationsChange", "eventTypeChange", "parameterChange", "clickAction", "dndDropInZone", "loadMoreDataProfiles", "searchDataProfiles", "stepUpdate", "addStepBetweenClick", "editInDepth"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i9.DndDropzoneDirective, selector: "[dndDropzone]", inputs: ["dndDropzone", "dndEffectAllowed", "dndAllowExternal", "dndHorizontal", "dndDragoverClass", "dndDropzoneDisabledClass", "dndDisableIf", "dndDisableDropIf"], outputs: ["dndDragover", "dndDrop"] }, { type: i9.DndPlaceholderRefDirective, selector: "[dndPlaceholderRef]" }, { type: i9.DndDraggableDirective, selector: "[dndDraggable]", inputs: ["dndDraggable", "dndEffectAllowed", "dndType", "dndDraggingClass", "dndDraggingSourceClass", "dndDraggableDisabledClass", "dndDragImageOffsetFunction", "dndDisableIf", "dndDisableDragIf"], outputs: ["dndStart", "dndDrag", "dndEnd", "dndMoved", "dndCopied", "dndLinked", "dndCanceled"] }] });
|
|
459
897
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseLoopStepComponent, decorators: [{
|
|
460
898
|
type: Component,
|
|
461
|
-
args: [{ selector: 'cqa-test-case-loop-step', host: { class: 'cqa-ui-root' }, styles: [STEP_ROW_ACTIONS_STYLES], template: "<div class=\"cqa-flex cqa-flex-col\">\n <!-- Inline Edit Mode: Frame 2147224910 - flex row, 1056\u00D736, gap 12px, flex-none -->\n <div *ngIf=\"isEditing\" class=\"cqa-py-2.5 cqa-px-4 cqa-flex cqa-items-center cqa-gap-3 cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-grow\">\n <!-- Loop Type Label -->\n <div class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getLoopTypeLabel() }}\n </div>\n\n <!-- FOR LOOP inline edit: cqa-dynamic-select (same usage as default stories) -->\n <ng-container *ngIf=\"loopType === 'for'\">\n <!-- First select: width 216.25px, height 36px, gap 4px, opacity 1 -->\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"forOptionTypeSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"testDataProfileSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"startStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"endStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- WHILE LOOP inline edit -->\n <ng-container *ngIf=\"isWhileLoop()\">\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"conditionSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Edit In depth link -->\n <a href=\"#\" (click)=\"onEditInDepth(); $event.preventDefault()\"\n class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-[2px] cqa-no-underline\">\n Edit In depth\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <!-- Cancel / Apply -->\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Cancel'\"\n (clicked)=\"onEditCancel()\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Apply'\"\n (clicked)=\"onEditApply()\"></cqa-button>\n </div>\n </div>\n\n <!-- Loop Header (normal view when not editing) -->\n <div *ngIf=\"!isEditing\"\n [class]=\"'step-row cqa-flex cqa-items-center cqa-gap-3 cqa-py-2 ' + (isInsideLoop ? 'cqa-pl-10 cqa-pr-4' : 'cqa-px-4')\">\n <div class=\"cqa-inline-flex cqa-items-center\">\n <!-- Drag Handle Icon (when isReorder is true) -->\n <div *ngIf=\"isReorder\" class=\"cqa-mr-2 cqa-cursor-move cqa-text-[#6B7280] hover:cqa-text-[#111827]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n </svg>\n </div>\n <!-- Checkbox (when isReorder is false) -->\n <label *ngIf=\"!isReorder\" class=\"cqa-flex cqa-items-center cqa-cursor-pointer cqa-relative cqa-mr-2\">\n <input type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"onSelectionChange($event)\"\n class=\"cqa-h-4 cqa-w-4 cqa-cursor-pointer cqa-transition-all cqa-appearance-none cqa-rounded shadow hover:cqa-shadow-md cqa-border cqa-border-solid cqa-border-slate-300 cqa-flex-shrink-0\"\n [class.cqa-bg-[#3F43EE]]=\"selected\"\n [class.cqa-border-[#3F43EE]]=\"selected\"\n id=\"check-loop-step\" />\n <span class=\"cqa-absolute cqa-text-white cqa-top-1/2 cqa-left-1/2 cqa--translate-x-1/2 cqa--translate-y-1/2 cqa-pointer-events-none cqa-flex cqa-items-center cqa-justify-center\"\n [class.cqa-opacity-0]=\"!selected\"\n [class.cqa-opacity-100]=\"selected\">\n <svg width=\"12\" height=\"13\" viewBox=\"0 0 12 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3.125L4.5 8.625L2 6.125\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </span>\n </label>\n </div>\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px]\">{{ stepNumber }}</span>\n <!-- Expand/Collapse Icon -->\n <button type=\"button\" (click)=\"onToggleExpanded()\" class=\"cqa-p-0\">\n <svg [class.cqa-rotate-180]=\"!expanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 10L8 6L4 10\" stroke=\"#6B7280\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Loop Icon -->\n <div *ngIf=\"loopType === 'for'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div *ngIf=\"loopType === 'while'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Loop Type Label -->\n <span class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-none\">\n {{ getLoopTypeLabel() }}\n </span>\n\n <!-- For Loop Controls -->\n <div *ngIf=\"loopType === 'for'\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2\">\n <!-- Test Data Profile Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"testDataProfile\" [class.cqa-text-primary]=\"testDataProfile\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getTestDataProfileLabel() }}\n </button>\n\n <!-- Start Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"startStep\" [class.cqa-text-primary]=\"startStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getStartStepLabel() }}\n </button>\n\n <!-- End Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"endStep\" [class.cqa-text-primary]=\"endStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getEndStepLabel() }}\n </button>\n </div>\n\n <!-- While Loop Condition (only show if condition exists) -->\n <div *ngIf=\"isWhileLoop() && condition\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2 cqa-flex-1\">\n <span class=\"cqa-text-gray-700 cqa-text-sm\">\n While\n </span>\n <span class=\"cqa-text-gray-900 cqa-text-sm\" [innerHTML]=\"getConditionDisplay()\"></span>\n </div>\n\n <!-- Steps Summary -->\n <div\n class=\"cqa-ml-auto cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-lg cqa-py-0.5 cqa-px-2 cqa-text-[#0A0A0A] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getStepsSummary() }}\n </div>\n\n <!-- View Details Link (show only if description is not empty) -->\n <a *ngIf=\"config.description && config.description.trim() !== ''\" #viewDetailsTrigger href=\"#\" (click)=\"onViewDetails($event)\" class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-2 cqa-no-underline cqa-ml-auto\">View Details<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\" fill=\"#3F43EE\"/></svg></a>\n\n <!-- Action Icons: Edit, Link, Duplicate, Delete (show on hover) -->\n <div class=\"step-actions cqa-flex cqa-items-center cqa-gap-3 cqa-px-[7px]\">\n <button type=\"button\" (click)=\"onEdit(); $event.stopPropagation()\" title=\"Edit\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 11.6666H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.55208 2.1128C9.7843 1.88058 10.0993 1.75012 10.4277 1.75012C10.7561 1.75012 11.071 1.88058 11.3033 2.1128C11.5355 2.34502 11.6659 2.65998 11.6659 2.98838C11.6659 3.31679 11.5355 3.63175 11.3033 3.86397L4.29742 10.8704C4.15864 11.0092 3.9871 11.1107 3.79867 11.1656L2.12333 11.6544C2.07314 11.669 2.01993 11.6699 1.96928 11.6569C1.91863 11.6439 1.8724 11.6176 1.83543 11.5806C1.79846 11.5437 1.7721 11.4974 1.75913 11.4468C1.74615 11.3961 1.74703 11.3429 1.76167 11.2927L2.2505 9.61738C2.30546 9.42916 2.40698 9.25783 2.54567 9.11922L9.55208 2.1128Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onLink(); $event.stopPropagation()\" title=\"Link\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.00065 9.91671H3.66732C2.78326 9.91671 1.93542 9.60942 1.3103 9.06244C0.685174 8.51545 0.333984 7.77359 0.333984 7.00004C0.333984 6.22649 0.685174 5.48463 1.3103 4.93765C1.93542 4.39066 2.78326 4.08337 3.66732 4.08337H5.00065\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M9 4.08337H10.3333C11.2174 4.08337 12.0652 4.39066 12.6904 4.93765C13.3155 5.48463 13.6667 6.22649 13.6667 7.00004C13.6667 7.77359 13.3155 8.51545 12.6904 9.06244C12.0652 9.60942 11.2174 9.91671 10.3333 9.91671H9\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.33398 7H9.66732\" stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDuplicate(); $event.stopPropagation()\" title=\"Duplicate\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.666 4.66663H5.83268C5.18835 4.66663 4.66602 5.18896 4.66602 5.83329V11.6666C4.66602 12.311 5.18835 12.8333 5.83268 12.8333H11.666C12.3103 12.8333 12.8327 12.311 12.8327 11.6666V5.83329C12.8327 5.18896 12.3103 4.66663 11.666 4.66663Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M2.33268 9.33329C1.69102 9.33329 1.16602 8.80829 1.16602 8.16663V2.33329C1.16602 1.69163 1.69102 1.16663 2.33268 1.16663H8.16602C8.80768 1.16663 9.33268 1.69163 9.33268 2.33329\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDelete(); $event.stopPropagation()\" title=\"Delete\"\n class=\"cqa-p-0 cqa-text-[#ff6467] hover:cqa-text-[#C63535]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.75 3.5H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M11.0827 3.5V11.6667C11.0827 12.25 10.4993 12.8333 9.91602 12.8333H4.08268C3.49935 12.8333 2.91602 12.25 2.91602 11.6667V3.5\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M4.66602 3.49996V2.33329C4.66602 1.74996 5.24935 1.16663 5.83268 1.16663H8.16602C8.74935 1.16663 9.33268 1.74996 9.33268 2.33329V3.49996\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.83398 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M8.16602 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <!-- Expanded Content with Nested Steps (renderer dispatches by step type, n-level nesting) -->\n <div *ngIf=\"expanded\" class=\"cqa-flex cqa-flex-col\">\n <div *ngIf=\"!isReorder\" class=\"cqa-flex cqa-flex-col\">\n <cqa-test-case-details-renderer *ngFor=\"let step of nestedSteps; let i = index\" [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep(i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n <div *ngIf=\"isReorder\" class=\"cqa-flex cqa-flex-col nested-step-drop-list\"\n [dndDropzone]=\"['step']\"\n dndEffectAllowed=\"move\"\n dndDragoverClass=\"dndDragover\"\n (dndDrop)=\"onDndDrop($event)\">\n <div dndPlaceholderRef class=\"step-drag-placeholder-nested cqa-my-1 cqa-min-h-[50px] cqa-border-2 cqa-border-dashed cqa-border-[#3F43EE] cqa-rounded cqa-bg-[rgba(63,67,238,0.08)] cqa-flex cqa-items-center cqa-justify-center cqa-text-[#3F43EE] cqa-text-xs\">Drop here</div>\n <div *ngFor=\"let step of nestedSteps; let i = index\" class=\"nested-step-drag-item\"\n [dndDraggable]=\"step\"\n dndEffectAllowed=\"move\"\n dndType=\"step\">\n <cqa-test-case-details-renderer [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetweenAbove]=\"addStepBetweenAbove\"\n [addStepBetweenBelow]=\"addStepBetweenBelow\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep(i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n </div>\n\n <!-- END Marker -->\n <div\n [class]=\"'cqa-pl-4 cqa-py-1 cqa-bg-[#DBEAFE80] cqa-text-[#1C398E] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium'\"\n style=\"border-top: 1px solid #BEDBFF;\">\n {{ getEndLabel() }}\n </div>\n </div>\n</div>" }]
|
|
462
|
-
|
|
899
|
+
args: [{ selector: 'cqa-test-case-loop-step', host: { class: 'cqa-ui-root' }, styles: [
|
|
900
|
+
STEP_ROW_ACTIONS_STYLES,
|
|
901
|
+
`
|
|
902
|
+
.loop-step-empty {
|
|
903
|
+
opacity: 0;
|
|
904
|
+
transition: opacity 0.1s ease;
|
|
905
|
+
}
|
|
906
|
+
.loop-step-row:hover .loop-step-empty {
|
|
907
|
+
opacity: 1;
|
|
908
|
+
}
|
|
909
|
+
.loop-step-empty-add {
|
|
910
|
+
padding: 0;
|
|
911
|
+
background: transparent;
|
|
912
|
+
border: 0;
|
|
913
|
+
cursor: pointer;
|
|
914
|
+
color: #3F43EE;
|
|
915
|
+
transition: opacity 0.15s ease;
|
|
916
|
+
}
|
|
917
|
+
.loop-step-empty-add:hover {
|
|
918
|
+
opacity: 0.9;
|
|
919
|
+
}
|
|
920
|
+
`,
|
|
921
|
+
], template: "<div class=\"loop-step-row cqa-flex cqa-flex-col\">\n <!-- Inline Edit Mode: Frame 2147224910 - flex row, 1056\u00D736, gap 12px, flex-none -->\n <div *ngIf=\"isEditing\" class=\"cqa-py-2.5 cqa-px-4 cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-grow\">\n <!-- Loop Type Label -->\n <div class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getLoopTypeLabel() }}\n </div>\n\n <!-- FOR LOOP inline edit: cqa-dynamic-select (same usage as default stories) -->\n <ng-container *ngIf=\"loopType === 'for'\">\n <!-- First select: width 216.25px, height 36px, gap 4px, opacity 1 -->\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"forOptionTypeSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"testDataProfileSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"startStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"editForm\" [config]=\"endStepSelectConfig\"\n class=\"cqa-w-full cqa-max-w-[216px]\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- WHILE LOOP inline edit: cqa-autocomplete + template variables (same as condition-step) -->\n <ng-container *ngIf=\"isWhileLoop()\">\n <cqa-autocomplete\n *ngIf=\"editForm\"\n [options]=\"whileConditionAutocompleteOptions\"\n [value]=\"editForm.get('condition')?.value ?? ''\"\n (valueChange)=\"onEditFormFieldChange('condition', $event)\"\n (optionSelect)=\"onConditionSelect($event)\"\n placeholder=\"Select condition\"\n [fullWidth]=\"true\"\n class=\"cqa-w-full cqa-max-w-[216px]\">\n </cqa-autocomplete>\n <!-- Template variables (shown when template is selected, same as condition-step) -->\n <div *ngIf=\"selectedTemplate && templateVariables && templateVariables.length > 0\" class=\"cqa-flex cqa-flex-row cqa-flex-wrap cqa-gap-3\">\n <ng-container *ngFor=\"let variable of templateVariables\">\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700\">{{ variable.label }}</label>\n <mat-slide-toggle\n [checked]=\"templateVariablesForm.get(variable.name)?.value || variable.value || false\"\n (change)=\"templateVariablesForm.get(variable.name)?.setValue($event.checked)\"\n color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'boolean' && variable.name !== 'custom_code'\">\n <ng-container *ngIf=\"variable.name === 'type' || variable.name === 'scrollTo' || variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"min-width: 150px;\">\n <cqa-dynamic-select\n [form]=\"templateVariablesForm\"\n [config]=\"getSelectConfigForVariable(variable)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.name !== 'type' && variable.name !== 'scrollTo' && !variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"min-width: 150px;\">\n <cqa-custom-input\n [placeholder]=\"'Enter ' + variable.label\"\n [value]=\"templateVariablesForm.get(variable.name)?.value || variable.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"templateVariablesForm.get(variable.name)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Edit In depth link -->\n <a href=\"#\" (click)=\"onEditInDepth(); $event.preventDefault()\"\n class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-[2px] cqa-no-underline\">\n Edit In depth\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <!-- Cancel / Apply -->\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Cancel'\"\n (clicked)=\"onEditCancel()\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [customClass]=\"'cqa-text-[14px] cqa-py-[9px]'\" [text]=\"'Apply'\"\n (clicked)=\"onEditApply()\"></cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Loop Header (normal view when not editing) -->\n <div *ngIf=\"!isEditing\"\n [class]=\"'step-row cqa-flex cqa-items-center cqa-gap-3 cqa-py-2 ' + (isInsideLoop ? 'cqa-pl-10 cqa-pr-4' : 'cqa-px-4')\">\n <div class=\"cqa-inline-flex cqa-items-center\">\n <!-- Drag Handle Icon (when isReorder is true) -->\n <div *ngIf=\"isReorder\" class=\"cqa-mr-2 cqa-cursor-move cqa-text-[#6B7280] hover:cqa-text-[#111827]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"currentColor\"/>\n </svg>\n </div>\n <!-- Checkbox (when isReorder is false) -->\n <label *ngIf=\"!isReorder\" class=\"cqa-flex cqa-items-center cqa-cursor-pointer cqa-relative cqa-mr-2\">\n <input type=\"checkbox\"\n [ngModel]=\"selected\"\n (ngModelChange)=\"onSelectionChange($event)\"\n class=\"cqa-h-4 cqa-w-4 cqa-cursor-pointer cqa-transition-all cqa-appearance-none cqa-rounded shadow hover:cqa-shadow-md cqa-border cqa-border-solid cqa-border-slate-300 cqa-flex-shrink-0\"\n [class.cqa-bg-[#3F43EE]]=\"selected\"\n [class.cqa-border-[#3F43EE]]=\"selected\"\n id=\"check-loop-step\" />\n <span class=\"cqa-absolute cqa-text-white cqa-top-1/2 cqa-left-1/2 cqa--translate-x-1/2 cqa--translate-y-1/2 cqa-pointer-events-none cqa-flex cqa-items-center cqa-justify-center\"\n [class.cqa-opacity-0]=\"!selected\"\n [class.cqa-opacity-100]=\"selected\">\n <svg width=\"12\" height=\"13\" viewBox=\"0 0 12 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3.125L4.5 8.625L2 6.125\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </span>\n </label>\n </div>\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px]\">{{ stepNumber }}</span>\n <!-- Expand/Collapse Icon -->\n <button type=\"button\" (click)=\"onToggleExpanded()\" class=\"cqa-p-0\">\n <svg [class.cqa-rotate-180]=\"!expanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 10L8 6L4 10\" stroke=\"#6B7280\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Step Number -->\n <span class=\"cqa-text-[#6B7280] cqa-text-[14px] cqa-leading-[18px] cqa-min-w-[32px] cqa-flex-shrink-0\">{{ stepNumber }}</span>\n\n <!-- Loop Icon -->\n <div *ngIf=\"loopType === 'for'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#1C398E\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#1C398E\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div *ngIf=\"loopType === 'while'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.334 1.33325L14.0007 3.99992L11.334 6.66659\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 7.33333V6.66667C2 5.95942 2.28095 5.28115 2.78105 4.78105C3.28115 4.28095 3.95942 4 4.66667 4H14\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.66667 14.6666L2 11.9999L4.66667 9.33325\" stroke=\"#59168B\" stroke-width=\"1.33333\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M14 8.66675V9.33341C14 10.0407 13.719 10.7189 13.219 11.219C12.7189 11.7191 12.0406 12.0001 11.3333 12.0001H2\"\n stroke=\"#59168B\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Loop Type Label -->\n <span class=\"cqa-font-semibold cqa-text-[#1C398E] cqa-text-[12px] cqa-leading-none\">\n {{ getLoopTypeLabel() }}\n </span>\n\n <!-- For Loop Controls -->\n <div *ngIf=\"loopType === 'for'\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2\">\n <!-- Test Data Profile Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"testDataProfile\" [class.cqa-text-primary]=\"testDataProfile\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getTestDataProfileLabel() }}\n </button>\n\n <!-- Start Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"startStep\" [class.cqa-text-primary]=\"startStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getStartStepLabel() }}\n </button>\n\n <!-- End Button -->\n <button type=\"button\" [class.cqa-bg-primary-100]=\"endStep\" [class.cqa-text-primary]=\"endStep\"\n class=\"cqa-py-0.5 cqa-px-2 cqa-text-[#3F43EE] cqa-text-[14px] cqa-leading-[17px] cqa-font-semibold cqa-border cqa-border-solid cqa-border-[#8A8CF4] cqa-rounded cqa-bg-[#D8D9FC]\">\n {{ getEndStepLabel() }}\n </button>\n </div>\n\n <!-- While Loop Condition (only show if condition exists) -->\n <div *ngIf=\"isWhileLoop() && condition\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-ml-2 cqa-flex-1\">\n <span class=\"cqa-text-gray-700 cqa-text-sm\">\n While\n </span>\n <span class=\"cqa-text-gray-900 cqa-text-sm\" [innerHTML]=\"getConditionDisplay()\"></span>\n </div>\n\n <!-- Steps Summary -->\n <div\n class=\"cqa-ml-auto cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-lg cqa-py-0.5 cqa-px-2 cqa-text-[#0A0A0A] cqa-text-[12px] cqa-leading-[15px]\">\n {{ getStepsSummary() }}\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-ml-auto\">\n <!-- View Details Link (show only if description is not empty) -->\n <a *ngIf=\"config.description && config.description.trim() !== ''\" #viewDetailsTrigger href=\"#\" (click)=\"onViewDetails($event)\" class=\"cqa-text-[#3F43EE] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-2 cqa-no-underline cqa-ml-auto\">View Details<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03809 6.74329L2.62809 7.33329L5.96142 3.99996L2.62809 0.666626L2.03809 1.25663L4.78142 3.99996L2.03809 6.74329Z\" fill=\"#3F43EE\"/></svg></a>\n\n <!-- Action Icons: Edit, Link, Duplicate, Delete (show on hover) -->\n <div class=\"step-actions cqa-flex cqa-items-center cqa-gap-3 cqa-px-[7px]\">\n <button type=\"button\" (click)=\"onEdit(); $event.stopPropagation()\" title=\"Edit\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 11.6666H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.55208 2.1128C9.7843 1.88058 10.0993 1.75012 10.4277 1.75012C10.7561 1.75012 11.071 1.88058 11.3033 2.1128C11.5355 2.34502 11.6659 2.65998 11.6659 2.98838C11.6659 3.31679 11.5355 3.63175 11.3033 3.86397L4.29742 10.8704C4.15864 11.0092 3.9871 11.1107 3.79867 11.1656L2.12333 11.6544C2.07314 11.669 2.01993 11.6699 1.96928 11.6569C1.91863 11.6439 1.8724 11.6176 1.83543 11.5806C1.79846 11.5437 1.7721 11.4974 1.75913 11.4468C1.74615 11.3961 1.74703 11.3429 1.76167 11.2927L2.2505 9.61738C2.30546 9.42916 2.40698 9.25783 2.54567 9.11922L9.55208 2.1128Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <!-- <button type=\"button\" (click)=\"onLink(); $event.stopPropagation()\" title=\"Link\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.00065 9.91671H3.66732C2.78326 9.91671 1.93542 9.60942 1.3103 9.06244C0.685174 8.51545 0.333984 7.77359 0.333984 7.00004C0.333984 6.22649 0.685174 5.48463 1.3103 4.93765C1.93542 4.39066 2.78326 4.08337 3.66732 4.08337H5.00065\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M9 4.08337H10.3333C11.2174 4.08337 12.0652 4.39066 12.6904 4.93765C13.3155 5.48463 13.6667 6.22649 13.6667 7.00004C13.6667 7.77359 13.3155 8.51545 12.6904 9.06244C12.0652 9.60942 11.2174 9.91671 10.3333 9.91671H9\"\n stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.33398 7H9.66732\" stroke=\"currentColor\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button> -->\n <button type=\"button\" (click)=\"onDuplicate(); $event.stopPropagation()\" title=\"Duplicate\"\n class=\"cqa-p-0 cqa-text-[#99A1Af] hover:cqa-text-[#1447E6]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.666 4.66663H5.83268C5.18835 4.66663 4.66602 5.18896 4.66602 5.83329V11.6666C4.66602 12.311 5.18835 12.8333 5.83268 12.8333H11.666C12.3103 12.8333 12.8327 12.311 12.8327 11.6666V5.83329C12.8327 5.18896 12.3103 4.66663 11.666 4.66663Z\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M2.33268 9.33329C1.69102 9.33329 1.16602 8.80829 1.16602 8.16663V2.33329C1.16602 1.69163 1.69102 1.16663 2.33268 1.16663H8.16602C8.80768 1.16663 9.33268 1.69163 9.33268 2.33329\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button type=\"button\" (click)=\"onDelete(); $event.stopPropagation()\" title=\"Delete\"\n class=\"cqa-p-0 cqa-text-[#ff6467] hover:cqa-text-[#C63535]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.75 3.5H12.25\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M11.0827 3.5V11.6667C11.0827 12.25 10.4993 12.8333 9.91602 12.8333H4.08268C3.49935 12.8333 2.91602 12.25 2.91602 11.6667V3.5\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M4.66602 3.49996V2.33329C4.66602 1.74996 5.24935 1.16663 5.83268 1.16663H8.16602C8.74935 1.16663 9.33268 1.74996 9.33268 2.33329V3.49996\"\n stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.83398 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M8.16602 6.41663V9.91663\" stroke=\"currentColor\" stroke-width=\"1.16667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Expanded Content with Nested Steps (renderer dispatches by step type, n-level nesting) -->\n <div *ngIf=\"expanded\" class=\"cqa-flex cqa-flex-col\">\n <div *ngIf=\"!isReorder\" class=\"cqa-flex cqa-flex-col\">\n <cqa-test-case-details-renderer *ngFor=\"let step of nestedSteps; let i = index\" [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedEdit($event)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedDuplicate($event, step)\" (delete)=\"onDeleteStep($event, i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n <div *ngIf=\"isReorder\" class=\"cqa-flex cqa-flex-col nested-step-drop-list\"\n [dndDropzone]=\"['step']\"\n dndEffectAllowed=\"move\"\n dndDragoverClass=\"dndDragover\"\n (dndDrop)=\"onDndDrop($event)\">\n <div dndPlaceholderRef class=\"step-drag-placeholder-nested cqa-my-1 cqa-min-h-[50px] cqa-border-2 cqa-border-dashed cqa-border-[#3F43EE] cqa-rounded cqa-bg-[rgba(63,67,238,0.08)] cqa-flex cqa-items-center cqa-justify-center cqa-text-[#3F43EE] cqa-text-xs\">Drop here</div>\n <div *ngFor=\"let step of nestedSteps; let i = index\" class=\"nested-step-drag-item\"\n [dndDraggable]=\"step\"\n dndEffectAllowed=\"move\"\n dndType=\"step\">\n <cqa-test-case-details-renderer [step]=\"step\" [index]=\"i\"\n [selected]=\"$any(step).selected\"\n [isNested]=\"true\" [isInsideLoop]=\"true\" [isReorder]=\"isReorder\"\n [addStepBetweenAbove]=\"addStepBetweenAbove\"\n [addStepBetweenBelow]=\"addStepBetweenBelow\"\n [addStepBetween]=\"addStepBetween\"\n [dataProfileOptions]=\"dataProfileOptions\" [hasMoreDataProfiles]=\"hasMoreDataProfiles\" [isLoadingDataProfiles]=\"isLoadingDataProfiles\"\n [naturalTextActionsOptions]=\"naturalTextActionsOptions\"\n (nestedStepChange)=\"onNestedStepChange($event.step, $event.index)\"\n (addStep)=\"onAddStep()\" (deleteStep)=\"onDeleteStep($event)\"\n (toggleExpanded)=\"onNestedToggleExpanded($event, step, i)\"\n (groupNameChange)=\"$any(step).groupName = $event; onNestedStepChange(step, i)\"\n (descriptionChange)=\"$any(step).description = $event; onNestedStepChange(step, i)\"\n (reusableChange)=\"$any(step).reusable = $event; onNestedStepChange(step, i)\"\n (openExternal)=\"onNestedStepChange(step, i)\" (edit)=\"onNestedStepChange(step, i)\"\n (link)=\"onNestedStepChange(step, i)\" (duplicate)=\"onNestedStepChange(step, i)\" (delete)=\"onDeleteStep($event, i)\"\n (viewDetails)=\"viewDetails.emit($event)\"\n (conditionChange)=\"$any(step).condition = $event; onNestedStepChange(step, i)\"\n (branchStepChange)=\"onNestedStepChange(step, i)\" (addBranch)=\"onNestedConditionAddBranch($any(step), i)\"\n (deleteBranch)=\"onNestedConditionDeleteBranch($any(step), $event, i)\"\n (testDataProfileChange)=\"$any(step).testDataProfile = $event; onNestedStepChange(step, i)\"\n (startStepChange)=\"$any(step).startStep = $event; onNestedStepChange(step, i)\"\n (endStepChange)=\"$any(step).endStep = $event; onNestedStepChange(step, i)\"\n (maxIterationsChange)=\"$any(step).maxIterations = $event; onNestedStepChange(step, i)\"\n (eventTypeChange)=\"$any(step).eventType = $event; onNestedStepChange(step, i)\"\n (parameterChange)=\"onNestedStepChange(step, i)\"\n (selectionChange)=\"$any(step).selected = $event; onNestedStepChange(step, i)\"\n (loadMoreDataProfiles)=\"loadMoreDataProfiles.emit($event)\"\n (searchDataProfiles)=\"searchDataProfiles.emit($event)\"\n (dndDropInZone)=\"dndDropInZone.emit($event)\"\n (clickAction)=\"clickAction.emit($event)\"\n (editInDepth)=\"editInDepth.emit($event)\"\n (addStepBetweenClick)=\"addStepBetweenClick.emit($event)\">\n </cqa-test-case-details-renderer>\n </div>\n </div>\n\n <!-- Empty loop: show plus icon on hover when expanded and no steps -->\n <div *ngIf=\"nestedSteps.length === 0\" class=\"loop-step-empty cqa-min-h-[52px] cqa-flex cqa-items-center cqa-justify-center cqa-pl-4 cqa-pr-4\">\n <button type=\"button\" (click)=\"onAddStepEmpty(); $event.stopPropagation()\" title=\"Add step\"\n class=\"loop-step-empty-add\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"21.1822\" height=\"22\" rx=\"10.5911\" fill=\"white\" />\n <rect x=\"1\" y=\"1\" width=\"21.1822\" height=\"22\" rx=\"10.5911\" stroke=\"#3F43EE\" stroke-width=\"2\" />\n <path d=\"M8.5 12H15.5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12 8.5V15.5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- END Marker -->\n <div\n [class]=\"'cqa-pl-4 cqa-py-1 cqa-bg-[#DBEAFE80] cqa-text-[#1C398E] cqa-text-[10px] cqa-leading-[15px] cqa-font-medium'\"\n style=\"border-top: 1px solid #BEDBFF;\">\n {{ getEndLabel() }}\n </div>\n </div>\n</div>" }]
|
|
922
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { config: [{
|
|
463
923
|
type: Input
|
|
464
924
|
}], id: [{
|
|
465
925
|
type: Input
|
|
@@ -497,6 +957,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
497
957
|
type: Input
|
|
498
958
|
}], naturalTextActionsOptions: [{
|
|
499
959
|
type: Input
|
|
960
|
+
}], setConditionTemplateVariables: [{
|
|
961
|
+
type: Input
|
|
500
962
|
}], addStepBetweenAbove: [{
|
|
501
963
|
type: Input
|
|
502
964
|
}], addStepBetweenBelow: [{
|
|
@@ -551,4 +1013,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
551
1013
|
type: ViewChild,
|
|
552
1014
|
args: ['viewDetailsTrigger', { static: false }]
|
|
553
1015
|
}] } });
|
|
554
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9vcC1zdGVwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvbG9vcC1zdGVwL2xvb3Atc3RlcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL2xvb3Atc3RlcC9sb29wLXN0ZXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBb0MsU0FBUyxFQUFjLE1BQU0sZUFBZSxDQUFDO0FBSWhJLE9BQU8sRUFBK0csU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbEssT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7O0FBVXJFLE1BQU0sT0FBTyx5QkFBeUI7SUE4RnBDLFlBQ1UsRUFBZTtRQUFmLE9BQUUsR0FBRixFQUFFLENBQWE7UUE1RmhCLGFBQVEsR0FBb0IsS0FBSyxDQUFDO1FBT2xDLGdCQUFXLEdBQXlCLEVBQUUsQ0FBQztRQUN2QyxhQUFRLEdBQVksSUFBSSxDQUFDO1FBQ3pCLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFDMUIsaUJBQVksR0FBWSxLQUFLLENBQUM7UUFDOUIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUMzQixhQUFRLEdBQVksS0FBSyxDQUFDO1FBQ25DLGdGQUFnRjtRQUN2RSx1QkFBa0IsR0FBd0IsRUFBRSxDQUFDO1FBQ3RELGdFQUFnRTtRQUN2RCx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDOUMsc0NBQXNDO1FBQzdCLDBCQUFxQixHQUFZLEtBQUssQ0FBQztRQUNoRCxrRUFBa0U7UUFDekQsOEJBQXlCLEdBQW1CLEVBQUUsQ0FBQztRQUN4RCx3REFBd0Q7UUFDL0Msd0JBQW1CLEdBQVksS0FBSyxDQUFDO1FBQzlDLHdEQUF3RDtRQUMvQyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDOUMsNEdBQTRHO1FBQ25HLG1CQUFjLEdBQVksS0FBSyxDQUFDO1FBRS9CLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQStDLENBQUM7UUFDakYsMEJBQXFCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUNuRCxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDN0Msa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQzNDLG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUM3Qyx3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ2pELHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUErQyxDQUFDO1FBQ25GLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ25DLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3hDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ3JDLFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ2xDLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUN2QyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFzQixDQUFDO1FBQ3JELGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQStDLENBQUM7UUFDOUUsU0FBSSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDaEMsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBNkQsQ0FBQztRQUN4RyxxREFBcUQ7UUFDM0MseUJBQW9CLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUM1RCxrREFBa0Q7UUFDeEMsdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUMxRCxvRUFBb0U7UUFDMUQsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFrQixDQUFDO1FBQzFELDJHQUEyRztRQUNqRyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFtRCxDQUFDO1FBQzVGLHdEQUF3RDtRQUM5Qyx3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBMEUsQ0FBQztRQUNqSCxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFNeEQsMkZBQTJGO1FBQ2xGLGFBQVEsR0FBRyxNQUFNLENBQUM7UUFDbEIsYUFBUSxHQUFHLE1BQU0sQ0FBQztRQUUzQixpRkFBaUY7UUFDakYsY0FBUyxHQUFZLEtBQUssQ0FBQztRQVkzQix5REFBeUQ7UUFDekQsb0JBQWUsR0FBYSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBSTVELDZEQUE2RDtRQUNyRCxpQkFBWSxHQU1oQixFQUFFLENBQUM7SUFJSixDQUFDO0lBckNKLFNBQVMsQ0FBQyxLQUFtQjtRQUMzQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQXFDRCxRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDekMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUN2QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO1lBQy9DLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUM7WUFDbkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUN2QyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ2pGLElBQUksQ0FBQyxRQUFRLEdBQUksSUFBSSxDQUFDLE1BQWMsQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDO1NBQ3hEO1FBQ0QsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNwQyxJQUFJLENBQUMsUUFBUSxHQUFJLElBQUksQ0FBQyxNQUFjLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQztTQUN4RDtRQUNELElBQUksT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksT0FBTyxDQUFDLHFCQUFxQixDQUFDLElBQUksT0FBTyxDQUFDLHVCQUF1QixDQUFDLEVBQUU7WUFDdkcsSUFBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7U0FDMUM7UUFDRCxJQUFJLE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxFQUFFO1lBQ3hDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1NBQ3BDO0lBQ0gsQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUM1QixhQUFhLEVBQUUsQ0FBQyxJQUFxQixDQUFDO1lBQ3RDLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDO1lBQzdDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBcUIsQ0FBQztZQUNwRCxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQXFCLENBQUM7WUFDaEQsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7WUFDakMsYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUM7U0FDekMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtGQUFrRjtJQUMxRSxrQkFBa0I7UUFDeEIsTUFBTSxXQUFXLEdBQW1CLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLEVBQUUsRUFBRSxDQUFDO1lBQ0wsS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNmLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBQ0osSUFBSSxDQUFDLHlCQUF5QixHQUFHO1lBQy9CLEdBQUcsRUFBRSxlQUFlO1lBQ3BCLFdBQVcsRUFBRSxlQUFlO1lBQzVCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLE9BQU8sRUFBRTtnQkFDUCxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFO2dCQUM5RixFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7YUFDM0U7U0FDRixDQUFDO1FBQ0YsSUFBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixHQUFHO1lBQzNCLEdBQUcsRUFBRSxXQUFXO1lBQ2hCLFdBQVcsRUFBRSxZQUFZO1lBQ3pCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLE9BQU8sRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzVDLENBQUM7UUFDRixJQUFJLENBQUMsbUJBQW1CLEdBQUc7WUFDekIsR0FBRyxFQUFFLFNBQVM7WUFDZCxXQUFXLEVBQUUsVUFBVTtZQUN2QixVQUFVLEVBQUUsS0FBSztZQUNqQixPQUFPLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUM1QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7SUFDckMsQ0FBQztJQUVELHVFQUF1RTtJQUMvRCwyQkFBMkI7UUFDakMsSUFBSSxDQUFDLHFCQUFxQixHQUFHO1lBQzNCLEdBQUcsRUFBRSxXQUFXO1lBQ2hCLFdBQVcsRUFBRSxrQkFBa0I7WUFDL0IsVUFBVSxFQUFFLElBQUk7WUFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxFQUFFO1NBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQsZ0ZBQWdGO0lBQ3hFLGlDQUFpQztRQUN2QyxJQUFJLENBQUMsMkJBQTJCLEdBQUc7WUFDakMsR0FBRyxFQUFFLGlCQUFpQjtZQUN0QixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLFlBQVksRUFBRSxJQUFJO1lBQ2xCLE9BQU8sRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQ2pDLFNBQVMsRUFBRSxJQUFJLENBQUMscUJBQXFCO1lBQ3JDLE9BQU8sRUFBRSxJQUFJLENBQUMsd0NBQXdDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1lBQy9FLFFBQVEsRUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO2dCQUN2QixJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEMsQ0FBQztZQUNELFFBQVEsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFO2dCQUMxQixJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUNELFVBQVUsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFO2dCQUM3QixJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzNDLENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELG9EQUFvRDtJQUM1Qyx3Q0FBd0MsQ0FBQyxPQUE0QjtRQUMzRSxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzVCLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNiLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNoQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7WUFDakIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJO1NBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUVELG9DQUFvQztJQUM1QixtQkFBbUIsQ0FBQyxTQUFjO1FBQ3hDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsc0NBQXNDO0lBQzlCLG9CQUFvQixDQUFDLEtBQWE7UUFDeEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQscUNBQXFDO0lBQzdCLHNCQUFzQixDQUFDLEtBQWE7UUFDMUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQscUJBQXFCLENBQUMsV0FBbUIsRUFBRSxLQUFzQjtRQUMvRCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO0lBQzdELENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQztJQUNuQyxDQUFDO0lBRUQsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUM7SUFDakMsQ0FBQztJQUVELFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztJQUMzRCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ2pDLE9BQU8sU0FBUyxDQUFDO1NBQ2xCO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsSUFBSSxDQUFDLENBQUM7UUFDckUsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUNqSCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUN0QyxPQUFPLFNBQVMsS0FBSyxJQUFJLEdBQUcsS0FBSyxLQUFLLFFBQVEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztJQUMxRSxDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xCLE9BQU8sVUFBVSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDbkM7UUFDRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsSUFBSSxDQUFDLENBQUM7UUFDMUQsT0FBTyxVQUFVLFlBQVksRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLE9BQU8sUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDL0I7UUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUN4RyxPQUFPLFFBQVEsVUFBVSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVELHVCQUF1QjtRQUNyQixJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFDeEIsT0FBTyxzQkFBc0IsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1NBQ3JEO1FBQ0QsT0FBTyxtQkFBbUIsQ0FBQztJQUM3QixDQUFDO0lBRUQsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSSxzQ0FBc0MsQ0FBQztJQUNsRSxDQUFDO0lBRUQsZ0JBQWdCO1FBQ2QsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBQyxNQUFNLEVBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELHVCQUF1QixDQUFDLEtBQWE7UUFDbkMsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsaUJBQWlCLENBQUMsS0FBYTtRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsZUFBZSxDQUFDLEtBQWE7UUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELGlCQUFpQixDQUFDLEtBQWE7UUFDN0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELHFCQUFxQixDQUFDLEtBQWE7UUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBd0IsRUFBRSxLQUFhO1FBQ3hELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsc0JBQXNCLENBQUMsS0FBZ0UsRUFBRSxJQUF3QixFQUFFLEtBQWE7UUFDOUgseUNBQXlDO1FBQ3pDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksVUFBVSxJQUFJLEtBQUssRUFBRTtZQUN0RSxvREFBb0Q7WUFDbkQsSUFBWSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1lBQ3hDLHFFQUFxRTtZQUNyRSx5R0FBeUc7WUFDekcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDbEMsMEZBQTBGO2dCQUMxRixzR0FBc0c7Z0JBQ3RHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUErQixFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFDLENBQUMsQ0FBQzthQUNyRztTQUNGO2FBQU07WUFDTCx1Q0FBdUM7WUFDdEMsSUFBWSxDQUFDLFFBQVEsR0FBRyxLQUFnQixDQUFDO1NBQzNDO1FBQ0QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsU0FBUztRQUNQLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFhO1FBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBd0I7UUFDbkMsT0FBTyxXQUFXLElBQUksSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBd0I7UUFDakMsT0FBTyxVQUFVLElBQUksSUFBSSxDQUFDO0lBQzVCLENBQUM7SUFFRCxlQUFlLENBQUMsSUFBd0I7UUFDdEMsT0FBTyxXQUFXLElBQUksSUFBSSxJQUFJLFVBQVUsSUFBSSxJQUFJLENBQUM7SUFDbkQsQ0FBQztJQUVELFdBQVcsQ0FBQyxJQUF3QjtRQUNsQyxPQUFPLFdBQVcsSUFBSSxJQUFJLENBQUM7SUFDN0IsQ0FBQztJQUVELFdBQVc7UUFDVCxrRUFBa0U7SUFDcEUsQ0FBQztJQUVELGNBQWMsQ0FBQyxNQUFXO1FBQ3hCLGtFQUFrRTtJQUNwRSxDQUFDO0lBRUQsMEJBQTBCLENBQUMsVUFBK0IsRUFBRSxLQUFhO1FBQ3ZFLGdEQUFnRDtRQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRTtZQUN4QixVQUFVLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztTQUMxQjtRQUNELE1BQU0sU0FBUyxHQUFvQjtZQUNqQyxJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU07WUFDdEQsS0FBSyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBQzVELFFBQVEsRUFBRSxTQUFTLENBQUMsWUFBWTtZQUNoQyxXQUFXLEVBQUUsRUFBRTtTQUNoQixDQUFDO1FBQ0YsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsNkJBQTZCLENBQUMsVUFBK0IsRUFBRSxNQUFXLEVBQUUsS0FBYTtRQUN2RixpREFBaUQ7UUFDakQsSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFO1lBQ3ZCLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQyxFQUFFO2dCQUNwQixVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDNUM7U0FDRjtRQUNELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGNBQWM7UUFDWiw4REFBOEQ7SUFDaEUsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsWUFBWSxHQUFHO1lBQ2xCLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZTtZQUNyQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO1lBQ3ZCLGFBQWEsRUFBRSxJQUFJO1lBQ25CLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZSxJQUFJLEVBQUU7WUFDM0MsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSTtZQUNqQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJO1lBQzdCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUU7WUFDL0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQztTQUN2QyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCxXQUFXO1FBQ1QsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDOUIsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUMsZUFBZSxJQUFJLEVBQUUsQ0FBQztRQUNyRCxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxTQUFTLElBQUksU0FBUyxDQUFDO1FBQzFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sSUFBSSxTQUFTLENBQUM7UUFDdEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDO1FBQy9CLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUksSUFBSSxNQUFNLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTFILGdFQUFnRTtRQUNoRSxJQUFJLGlCQUE4QyxDQUFDO1FBQ25ELElBQUksbUJBQW1CLEdBQVcsRUFBRSxDQUFDO1FBRXJDLElBQUksb0JBQW9CLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDOUQsdURBQXVEO1lBQ3ZELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQ2xELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsb0JBQW9CLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLG9CQUFvQixJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQ25KLENBQUM7WUFDRixJQUFJLGVBQWUsRUFBRTtnQkFDbkIsaUJBQWlCLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQztnQkFDdkMsbUJBQW1CLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQztnQkFDM0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxtQkFBbUIsQ0FBQzthQUM1QztpQkFBTTtnQkFDTCwwREFBMEQ7Z0JBQzFELElBQUksQ0FBQyxlQUFlLEdBQUcsb0JBQW9CLENBQUM7Z0JBQzVDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLFNBQVMsQ0FBQzthQUMvRDtTQUNGO2FBQU07WUFDTCxJQUFJLENBQUMsZUFBZSxHQUFHLG9CQUFvQixDQUFDO1NBQzdDO1FBRUQsbUZBQW1GO1FBQ25GLE1BQU0sYUFBYSxHQUE2RDtZQUM5RSxHQUFHLElBQUksQ0FBQyxNQUFNO1lBQ2QsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ3JDLGlCQUFpQixFQUFFLGlCQUFpQjtZQUNwQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQztRQUVGLGdDQUFnQztRQUNoQyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDM0MsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLE9BQU8sRUFBRTtZQUM3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQ3hEO1FBRUQsMENBQTBDO1FBQzFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFcEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDO1FBQ3pELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUM7UUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQztRQUN6QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUM7UUFDckQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQztJQUVELGFBQWE7UUFDWCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hCLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsVUFBVSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hKLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUE0QixFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN0RyxDQUFDO0lBRUQsTUFBTTtRQUNKLDhEQUE4RDtJQUNoRSxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxPQUFnQjtRQUNoQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFrQjtRQUM5QixJQUFJLEtBQUssRUFBRTtZQUNULEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDekI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3JFLE9BQU87U0FDUjtRQUVELElBQUksS0FBSyxFQUFFO1lBQ1QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQztZQUNsRixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztnQkFDcEIsS0FBSztnQkFDTCxLQUFLO2dCQUNMLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7YUFDckMsQ0FBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDOztzSEFyaEJVLHlCQUF5QjswR0FBekIseUJBQXlCLG9uRENmdEMsazhxQkFzVE07MkZEdlNPLHlCQUF5QjtrQkFOckMsU0FBUzsrQkFDRSx5QkFBeUIsUUFFN0IsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFVBQ3RCLENBQUMsdUJBQXVCLENBQUM7a0dBR3hCLE1BQU07c0JBQWQsS0FBSztnQkFDRyxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFFRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBRUcscUJBQXFCO3NCQUE3QixLQUFLO2dCQUVHLHlCQUF5QjtzQkFBakMsS0FBSztnQkFFRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBRUcsbUJBQW1CO3NCQUEzQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUksY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxPQUFPO3NCQUFoQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBRUcsb0JBQW9CO3NCQUE3QixNQUFNO2dCQUVHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFFRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLFdBQVc7c0JBQXBCLE1BQU07Z0JBRUcsbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBMEI2QyxrQkFBa0I7c0JBQXJFLFNBQVM7dUJBQUMsb0JBQW9CLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEbmREcm9wRXZlbnQgfSBmcm9tICduZ3gtZHJhZy1kcm9wJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcbmltcG9ydCB7IExvb3BTdGVwQ29uZmlnLCBUZXN0Q2FzZVN0ZXBDb25maWcsIE5vcm1hbFN0ZXBDb25maWcsIENvbmRpdGlvblN0ZXBDb25maWcsIFN0ZXBHcm91cENvbmZpZywgQ29uZGl0aW9uQnJhbmNoLCBTdGVwVHlwZXMgfSBmcm9tICcuLi90ZXN0LWNhc2Utc3RlcC5tb2RlbHMnO1xuaW1wb3J0IHsgU1RFUF9ST1dfQUNUSU9OU19TVFlMRVMgfSBmcm9tICcuLi9zdGVwLXJvdy1hY3Rpb25zLnN0eWxlcyc7XG5pbXBvcnQgeyBEYXRhUHJvZmlsZU9wdGlvbiB9IGZyb20gJy4uLy4uL3N0ZXAtYnVpbGRlci9zdGVwLWJ1aWxkZXItbG9vcC9zdGVwLWJ1aWxkZXItbG9vcC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVmlld0RldGFpbHNQYXlsb2FkIH0gZnJvbSAnLi4vc3RlcC1kZXRhaWxzLW1vZGFsL3N0ZXAtZGV0YWlscy1tb2RhbC1kYXRhJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLXRlc3QtY2FzZS1sb29wLXN0ZXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vbG9vcC1zdGVwLmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9LFxuICBzdHlsZXM6IFtTVEVQX1JPV19BQ1RJT05TX1NUWUxFU10sXG59KVxuZXhwb3J0IGNsYXNzIFRlc3RDYXNlTG9vcFN0ZXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGNvbmZpZyE6IExvb3BTdGVwQ29uZmlnO1xuICBASW5wdXQoKSBpZCE6IHN0cmluZztcbiAgQElucHV0KCkgbG9vcFR5cGU6ICdmb3InIHwgJ3doaWxlJyA9ICdmb3InO1xuICBASW5wdXQoKSBzdGVwTnVtYmVyITogbnVtYmVyIHwgc3RyaW5nO1xuICBASW5wdXQoKSBjb25kaXRpb24/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIG1heEl0ZXJhdGlvbnM/OiBudW1iZXI7XG4gIEBJbnB1dCgpIHRlc3REYXRhUHJvZmlsZT86IHN0cmluZztcbiAgQElucHV0KCkgc3RhcnRTdGVwPzogbnVtYmVyO1xuICBASW5wdXQoKSBlbmRTdGVwPzogbnVtYmVyO1xuICBASW5wdXQoKSBuZXN0ZWRTdGVwczogVGVzdENhc2VTdGVwQ29uZmlnW10gPSBbXTtcbiAgQElucHV0KCkgZXhwYW5kZWQ6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBpc05lc3RlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBpc0luc2lkZUxvb3A6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaXNSZW9yZGVyOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNlbGVjdGVkOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBPcHRpb25zIGZvciB0aGUgZGF0YSBwcm9maWxlIGRyb3Bkb3duIC0gYWNjZXB0cyBEYXRhUHJvZmlsZU9wdGlvbiBvYmplY3RzICovXG4gIEBJbnB1dCgpIGRhdGFQcm9maWxlT3B0aW9uczogRGF0YVByb2ZpbGVPcHRpb25bXSA9IFtdO1xuICAvKiogSW5kaWNhdGVzIGlmIG1vcmUgZGF0YSBwcm9maWxlcyBhcmUgYXZhaWxhYmxlIGZvciBsb2FkaW5nICovXG4gIEBJbnB1dCgpIGhhc01vcmVEYXRhUHJvZmlsZXM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqIExvYWRpbmcgc3RhdGUgZm9yIGRhdGEgcHJvZmlsZXMgKi9cbiAgQElucHV0KCkgaXNMb2FkaW5nRGF0YVByb2ZpbGVzOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBPcHRpb25zIGZvciBuYXR1cmFsIHRleHQgYWN0aW9ucyAoZm9yIHdoaWxlIGxvb3AgY29uZGl0aW9uKSAqL1xuICBASW5wdXQoKSBuYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtdO1xuICAvKiogU2hvdyBcIkFkZCBTdGVwIEJldHdlZW5cIiBidXR0b24gYWJvdmUgbmVzdGVkIHN0ZXBzICovXG4gIEBJbnB1dCgpIGFkZFN0ZXBCZXR3ZWVuQWJvdmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqIFNob3cgXCJBZGQgU3RlcCBCZXR3ZWVuXCIgYnV0dG9uIGJlbG93IG5lc3RlZCBzdGVwcyAqL1xuICBASW5wdXQoKSBhZGRTdGVwQmV0d2VlbkJlbG93OiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgYWRkU3RlcEJldHdlZW5BYm92ZSBhbmQgYWRkU3RlcEJldHdlZW5CZWxvdyBpbnN0ZWFkLiBJZiBzZXQsIGFwcGxpZXMgdG8gYm90aCBidXR0b25zLiAqL1xuICBASW5wdXQoKSBhZGRTdGVwQmV0d2VlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSB0b2dnbGVFeHBhbmRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8e2NvbmZpZzogTG9vcFN0ZXBDb25maWcsIGV4cGFuZGVkOiBib29sZWFufT4oKTtcbiAgQE91dHB1dCgpIHRlc3REYXRhUHJvZmlsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgc3RhcnRTdGVwQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIEBPdXRwdXQoKSBlbmRTdGVwQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIEBPdXRwdXQoKSBjb25kaXRpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIG1heEl0ZXJhdGlvbnNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIG5lc3RlZFN0ZXBDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHsgc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnOyBpbmRleDogbnVtYmVyIH0+KCk7XG4gIEBPdXRwdXQoKSBhZGRTdGVwID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZGVsZXRlU3RlcCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgZHVwbGljYXRlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZGVsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgbW9yZU9wdGlvbnMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSB2aWV3RGV0YWlscyA9IG5ldyBFdmVudEVtaXR0ZXI8Vmlld0RldGFpbHNQYXlsb2FkPigpO1xuICBAT3V0cHV0KCkgZWRpdEluRGVwdGggPSBuZXcgRXZlbnRFbWl0dGVyPHsgc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnOyBpbmRleDogbnVtYmVyIH0+KCk7XG4gIEBPdXRwdXQoKSBlZGl0ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZG5kRHJvcEluWm9uZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBldmVudDogRG5kRHJvcEV2ZW50OyB0YXJnZXRMaXN0OiBUZXN0Q2FzZVN0ZXBDb25maWdbXSB9PigpO1xuICAvKiogRW1pdCB3aGVuIG1vcmUgZGF0YSBwcm9maWxlcyBuZWVkIHRvIGJlIGxvYWRlZCAqL1xuICBAT3V0cHV0KCkgbG9hZE1vcmVEYXRhUHJvZmlsZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIEVtaXQgd2hlbiBkYXRhIHByb2ZpbGUgc2VhcmNoIHF1ZXJ5IGNoYW5nZXMgKi9cbiAgQE91dHB1dCgpIHNlYXJjaERhdGFQcm9maWxlcyA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogRW1pdCB3aGVuIHN0ZXAgaXMgdXBkYXRlZCAoQXBwbHkgYnV0dG9uIGNsaWNrZWQgaW4gZWRpdCBtb2RlKSAqL1xuICBAT3V0cHV0KCkgc3RlcFVwZGF0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TG9vcFN0ZXBDb25maWc+KCk7XG4gIC8qKiBSZS1lbWl0IHdoZW4gYSBuZXN0ZWQgc3RlcCAoZS5nLiBub3JtYWwtc3RlcCkgZW1pdHMgY2xpY2tBY3Rpb24gKGUuZy4gZWxlbWVudC9sYWJlbCBjbGljayBmb3IgcG9wdXApICovXG4gIEBPdXRwdXQoKSBjbGlja0FjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBldmVudDogTW91c2VFdmVudDsgc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnIH0+KCk7XG4gIC8qKiBSZS1lbWl0IGFkZFN0ZXBCZXR3ZWVuQ2xpY2sgZnJvbSBuZXN0ZWQgcmVuZGVyZXJzICovXG4gIEBPdXRwdXQoKSBhZGRTdGVwQmV0d2VlbkNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx7c3RlcDogVGVzdENhc2VTdGVwQ29uZmlnLCBpbmRleDogbnVtYmVyLCBwb3NpdGlvbjogJ0FCT1ZFJyB8ICdCRUxPVyd9PigpO1xuICBAT3V0cHV0KCkgc2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIG9uRG5kRHJvcChldmVudDogRG5kRHJvcEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5kbmREcm9wSW5ab25lLmVtaXQoeyBldmVudCwgdGFyZ2V0TGlzdDogdGhpcy5uZXN0ZWRTdGVwcyB9KTtcbiAgfVxuXG4gIC8qKiBFeHBvc2UgZ2xvYmFsIGNvbnN0cnVjdG9ycyBmb3IgdGVtcGxhdGUgKEFuZ3VsYXIgdGVtcGxhdGVzIGRvbid0IGhhdmUgU3RyaW5nL051bWJlcikgKi9cbiAgcmVhZG9ubHkgc3RyaW5nRm4gPSBTdHJpbmc7XG4gIHJlYWRvbmx5IG51bWJlckZuID0gTnVtYmVyO1xuXG4gIC8qKiBXaGVuIHRydWUsIGhlYWRlciBzaG93cyBpbmxpbmUgZWRpdCBmb3JtIChkcm9wZG93bnMsIGlucHV0cywgQ2FuY2VsL0FwcGx5KSAqL1xuICBpc0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogRm9ybSBmb3IgZWRpdCBtb2RlOyBib3VuZCB0byBjcWEtZHluYW1pYy1zZWxlY3QgKHNhbWUgcGF0dGVybiBhcyBkZWZhdWx0IHN0b3JpZXMpICovXG4gIGVkaXRGb3JtITogRm9ybUdyb3VwO1xuXG4gIC8qKiBDYWNoZWQgc2VsZWN0IGNvbmZpZ3MgKHN0YWJsZSByZWZzIHRvIGF2b2lkIGNoYW5nZS1kZXRlY3Rpb24gbG9vcHMpICovXG4gIGZvck9wdGlvblR5cGVTZWxlY3RDb25maWchOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWc7XG4gIHRlc3REYXRhUHJvZmlsZVNlbGVjdENvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcbiAgc3RhcnRTdGVwU2VsZWN0Q29uZmlnITogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnO1xuICBlbmRTdGVwU2VsZWN0Q29uZmlnITogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnO1xuICBjb25kaXRpb25TZWxlY3RDb25maWchOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWc7XG5cbiAgLyoqIE9wdGlvbnMgZm9yIExvb3AgU3RhcnQgLyBMb29wIEVuZCBkcm9wZG93bnMgKDEtMTApICovXG4gIGxvb3BTdGVwT3B0aW9uczogbnVtYmVyW10gPSBbMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTBdO1xuXG4gIEBWaWV3Q2hpbGQoJ3ZpZXdEZXRhaWxzVHJpZ2dlcicsIHsgc3RhdGljOiBmYWxzZSB9KSB2aWV3RGV0YWlsc1RyaWdnZXI/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAvKiogTG9jYWwgY29weSBvZiB2YWx1ZXMgd2hpbGUgZWRpdGluZyAoZm9yIENhbmNlbCByZXZlcnQpICovXG4gIHByaXZhdGUgZWRpdFNuYXBzaG90OiB7XG4gICAgdGVzdERhdGFQcm9maWxlPzogc3RyaW5nO1xuICAgIHN0YXJ0U3RlcD86IG51bWJlcjtcbiAgICBlbmRTdGVwPzogbnVtYmVyO1xuICAgIGNvbmRpdGlvbj86IHN0cmluZztcbiAgICBtYXhJdGVyYXRpb25zPzogbnVtYmVyO1xuICB9ID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXJcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZykge1xuICAgICAgdGhpcy5pZCA9IHRoaXMuY29uZmlnLmlkO1xuICAgICAgdGhpcy5sb29wVHlwZSA9IHRoaXMuY29uZmlnLmxvb3BUeXBlO1xuICAgICAgdGhpcy5zdGVwTnVtYmVyID0gdGhpcy5jb25maWcuc3RlcE51bWJlcjtcbiAgICAgIHRoaXMuY29uZGl0aW9uID0gdGhpcy5jb25maWcuY29uZGl0aW9uO1xuICAgICAgdGhpcy5tYXhJdGVyYXRpb25zID0gdGhpcy5jb25maWcubWF4SXRlcmF0aW9ucztcbiAgICAgIHRoaXMudGVzdERhdGFQcm9maWxlID0gdGhpcy5jb25maWcudGVzdERhdGFQcm9maWxlO1xuICAgICAgdGhpcy5zdGFydFN0ZXAgPSB0aGlzLmNvbmZpZy5zdGFydFN0ZXA7XG4gICAgICB0aGlzLmVuZFN0ZXAgPSB0aGlzLmNvbmZpZy5lbmRTdGVwO1xuICAgICAgdGhpcy5uZXN0ZWRTdGVwcyA9IHRoaXMuY29uZmlnLm5lc3RlZFN0ZXBzIHx8IFtdO1xuICAgICAgdGhpcy5leHBhbmRlZCA9IHRoaXMuY29uZmlnLmV4cGFuZGVkICE9PSB1bmRlZmluZWQgPyB0aGlzLmNvbmZpZy5leHBhbmRlZCA6IHRydWU7XG4gICAgICB0aGlzLnNlbGVjdGVkID0gKHRoaXMuY29uZmlnIGFzIGFueSkuc2VsZWN0ZWQgfHwgZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuYnVpbGRFZGl0Rm9ybSgpO1xuICAgIHRoaXMuYnVpbGRTZWxlY3RDb25maWdzKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2NvbmZpZyddICYmIHRoaXMuY29uZmlnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkID0gKHRoaXMuY29uZmlnIGFzIGFueSkuc2VsZWN0ZWQgfHwgZmFsc2U7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydkYXRhUHJvZmlsZU9wdGlvbnMnXSB8fCBjaGFuZ2VzWydoYXNNb3JlRGF0YVByb2ZpbGVzJ10gfHwgY2hhbmdlc1snaXNMb2FkaW5nRGF0YVByb2ZpbGVzJ10pIHtcbiAgICAgIHRoaXMudXBkYXRlVGVzdERhdGFQcm9maWxlU2VsZWN0Q29uZmlnKCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWyduYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zJ10pIHtcbiAgICAgIHRoaXMudXBkYXRlQ29uZGl0aW9uU2VsZWN0Q29uZmlnKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEVkaXRGb3JtKCk6IHZvaWQge1xuICAgIHRoaXMuZWRpdEZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGZvck9wdGlvblR5cGU6IFtudWxsIGFzIHN0cmluZyB8IG51bGxdLFxuICAgICAgdGVzdERhdGFQcm9maWxlOiBbdGhpcy50ZXN0RGF0YVByb2ZpbGUgPz8gJyddLFxuICAgICAgc3RhcnRTdGVwOiBbdGhpcy5zdGFydFN0ZXAgPz8gbnVsbCBhcyBudW1iZXIgfCBudWxsXSxcbiAgICAgIGVuZFN0ZXA6IFt0aGlzLmVuZFN0ZXAgPz8gbnVsbCBhcyBudW1iZXIgfCBudWxsXSxcbiAgICAgIGNvbmRpdGlvbjogW3RoaXMuY29uZGl0aW9uID8/ICcnXSxcbiAgICAgIG1heEl0ZXJhdGlvbnM6IFt0aGlzLm1heEl0ZXJhdGlvbnMgPz8gNV0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogQnVpbGQgc2VsZWN0IGNvbmZpZ3Mgb25jZSAoc2FtZSBvcHRpb24gc2hhcGUgYXMgZGVmYXVsdCBzdG9yaWVzOiBpZCArIG5hbWUpICovXG4gIHByaXZhdGUgYnVpbGRTZWxlY3RDb25maWdzKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0ZXBPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IHRoaXMubG9vcFN0ZXBPcHRpb25zLm1hcCgobikgPT4gKHtcbiAgICAgIGlkOiBuLFxuICAgICAgdmFsdWU6IG4sXG4gICAgICBuYW1lOiBTdHJpbmcobiksXG4gICAgICBsYWJlbDogU3RyaW5nKG4pLFxuICAgIH0pKTtcbiAgICB0aGlzLmZvck9wdGlvblR5cGVTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdmb3JPcHRpb25UeXBlJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IG9wdGlvbicsXG4gICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgeyBpZDogJ3Rlc3QtZGF0YScsIHZhbHVlOiAndGVzdC1kYXRhJywgbmFtZTogJ1Rlc3QgRGF0YSBQcm9maWxlJywgbGFiZWw6ICdUZXN0IERhdGEgUHJvZmlsZScgfSxcbiAgICAgICAgeyBpZDogJ2ZpeGVkJywgdmFsdWU6ICdmaXhlZCcsIG5hbWU6ICdGaXhlZCBjb3VudCcsIGxhYmVsOiAnRml4ZWQgY291bnQnIH0sXG4gICAgICBdLFxuICAgIH07XG4gICAgdGhpcy51cGRhdGVUZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWcoKTtcbiAgICB0aGlzLnN0YXJ0U3RlcFNlbGVjdENvbmZpZyA9IHtcbiAgICAgIGtleTogJ3N0YXJ0U3RlcCcsXG4gICAgICBwbGFjZWhvbGRlcjogJ0xvb3AgU3RhcnQnLFxuICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICBvcHRpb25zOiBzdGVwT3B0aW9ucy5tYXAoKG8pID0+ICh7IC4uLm8gfSkpLFxuICAgIH07XG4gICAgdGhpcy5lbmRTdGVwU2VsZWN0Q29uZmlnID0ge1xuICAgICAga2V5OiAnZW5kU3RlcCcsXG4gICAgICBwbGFjZWhvbGRlcjogJ0xvb3AgRW5kJyxcbiAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgb3B0aW9uczogc3RlcE9wdGlvbnMubWFwKChvKSA9PiAoeyAuLi5vIH0pKSxcbiAgICB9O1xuICAgIHRoaXMudXBkYXRlQ29uZGl0aW9uU2VsZWN0Q29uZmlnKCk7XG4gIH1cblxuICAvKiogVXBkYXRlIGNvbmRpdGlvbiBzZWxlY3QgY29uZmlnIHdpdGggbmF0dXJhbCB0ZXh0IGFjdGlvbnMgb3B0aW9ucyAqL1xuICBwcml2YXRlIHVwZGF0ZUNvbmRpdGlvblNlbGVjdENvbmZpZygpOiB2b2lkIHtcbiAgICB0aGlzLmNvbmRpdGlvblNlbGVjdENvbmZpZyA9IHtcbiAgICAgIGtleTogJ2NvbmRpdGlvbicsXG4gICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBjb25kaXRpb24nLFxuICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgIG9wdGlvbnM6IHRoaXMubmF0dXJhbFRleHRBY3Rpb25zT3B0aW9ucyB8fCBbXSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFVwZGF0ZSB0ZXN0IGRhdGEgcHJvZmlsZSBzZWxlY3QgY29uZmlnIHdpdGggY3VycmVudCBvcHRpb25zIGFuZCBjYWxsYmFja3MgKi9cbiAgcHJpdmF0ZSB1cGRhdGVUZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWcoKTogdm9pZCB7XG4gICAgdGhpcy50ZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICd0ZXN0RGF0YVByb2ZpbGUnLFxuICAgICAgcGxhY2Vob2xkZXI6ICdUZXN0ZGF0YXByb2ZpbGUnLFxuICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgIHNlcnZlclNlYXJjaDogdHJ1ZSxcbiAgICAgIGhhc01vcmU6IHRoaXMuaGFzTW9yZURhdGFQcm9maWxlcyxcbiAgICAgIGlzTG9hZGluZzogdGhpcy5pc0xvYWRpbmdEYXRhUHJvZmlsZXMsXG4gICAgICBvcHRpb25zOiB0aGlzLmNvbnZlcnREYXRhUHJvZmlsZU9wdGlvbnNUb1NlbGVjdE9wdGlvbnModGhpcy5kYXRhUHJvZmlsZU9wdGlvbnMpLFxuICAgICAgb25DaGFuZ2U6ICh2YWx1ZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMub25EYXRhUHJvZmlsZUNoYW5nZSh2YWx1ZSk7XG4gICAgICB9LFxuICAgICAgb25TZWFyY2g6IChxdWVyeTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMub25TZWFyY2hEYXRhUHJvZmlsZXMocXVlcnkpO1xuICAgICAgfSxcbiAgICAgIG9uTG9hZE1vcmU6IChxdWVyeT86IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLm9uTG9hZE1vcmVEYXRhUHJvZmlsZXMocXVlcnkgfHwgJycpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIENvbnZlcnQgRGF0YVByb2ZpbGVPcHRpb25bXSB0byBTZWxlY3RPcHRpb25bXSAqL1xuICBwcml2YXRlIGNvbnZlcnREYXRhUHJvZmlsZU9wdGlvbnNUb1NlbGVjdE9wdGlvbnMob3B0aW9uczogRGF0YVByb2ZpbGVPcHRpb25bXSk6IFNlbGVjdE9wdGlvbltdIHtcbiAgICByZXR1cm4gb3B0aW9ucy5tYXAob3B0aW9uID0+ICh7XG4gICAgICBpZDogb3B0aW9uLmlkLFxuICAgICAgdmFsdWU6IG9wdGlvbi5pZCxcbiAgICAgIG5hbWU6IG9wdGlvbi5uYW1lLFxuICAgICAgbGFiZWw6IG9wdGlvbi5uYW1lXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqIEhhbmRsZSBkYXRhIHByb2ZpbGUgc2VsZWN0aW9uICovXG4gIHByaXZhdGUgb25EYXRhUHJvZmlsZUNoYW5nZShwcm9maWxlSWQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25UZXN0RGF0YVByb2ZpbGVDaGFuZ2UocHJvZmlsZUlkKTtcbiAgfVxuXG4gIC8qKiBIYW5kbGUgc2VhcmNoIGZvciBkYXRhIHByb2ZpbGVzICovXG4gIHByaXZhdGUgb25TZWFyY2hEYXRhUHJvZmlsZXMocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoRGF0YVByb2ZpbGVzLmVtaXQocXVlcnkpO1xuICB9XG5cbiAgLyoqIEhhbmRsZSBsb2FkIG1vcmUgZGF0YSBwcm9maWxlcyAqL1xuICBwcml2YXRlIG9uTG9hZE1vcmVEYXRhUHJvZmlsZXMocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubG9hZE1vcmVEYXRhUHJvZmlsZXMuZW1pdChxdWVyeSk7XG4gIH1cblxuICBvbkVkaXRGb3JtRmllbGRDaGFuZ2UoY29udHJvbE5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdEZvcm0uZ2V0KGNvbnRyb2xOYW1lKT8uc2V0VmFsdWUodmFsdWUpO1xuICB9XG5cbiAgZ2V0TG9vcFR5cGVMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdGT1IgTE9PUCcgOiAnV0hJTEUgTE9PUCc7XG4gIH1cblxuICBpc1doaWxlTG9vcCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJztcbiAgfVxuXG4gIGlzRm9yTG9vcCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb29wVHlwZSA9PT0gJ2Zvcic7XG4gIH1cblxuICBnZXRFbmRMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdFTkQgRk9SJyA6ICdFTkQgV0hJTEUnO1xuICB9XG5cbiAgZ2V0U3RlcHNTdW1tYXJ5KCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMubmVzdGVkU3RlcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJzAgc3RlcHMnO1xuICAgIH1cbiAgICBjb25zdCBzdGFydCA9IHRoaXMuc3RhcnRTdGVwIHx8IHRoaXMubmVzdGVkU3RlcHNbMF0/LnN0ZXBOdW1iZXIgfHwgMTtcbiAgICBjb25zdCBlbmQgPSB0aGlzLmVuZFN0ZXAgfHwgdGhpcy5uZXN0ZWRTdGVwc1t0aGlzLm5lc3RlZFN0ZXBzLmxlbmd0aCAtIDFdPy5zdGVwTnVtYmVyIHx8IHRoaXMubmVzdGVkU3RlcHMubGVuZ3RoO1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5uZXN0ZWRTdGVwcy5sZW5ndGg7XG4gICAgcmV0dXJuIGBTdGVwcyAke3N0YXJ0fS0ke2VuZH0gKCR7Y291bnR9IHN0ZXAke2NvdW50ICE9PSAxID8gJ3MnIDogJyd9KWA7XG4gIH1cblxuICBnZXRTdGFydFN0ZXBMYWJlbCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnN0YXJ0U3RlcCkge1xuICAgICAgcmV0dXJuIGBTdGFydDogJHt0aGlzLnN0YXJ0U3RlcH1gO1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0U3RhcnQgPSB0aGlzLm5lc3RlZFN0ZXBzWzBdPy5zdGVwTnVtYmVyIHx8IDE7XG4gICAgcmV0dXJuIGBTdGFydDogJHtkZWZhdWx0U3RhcnR9YDtcbiAgfVxuXG4gIGdldEVuZFN0ZXBMYWJlbCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmVuZFN0ZXApIHtcbiAgICAgIHJldHVybiBgRW5kOiAke3RoaXMuZW5kU3RlcH1gO1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0RW5kID0gdGhpcy5uZXN0ZWRTdGVwc1t0aGlzLm5lc3RlZFN0ZXBzLmxlbmd0aCAtIDFdPy5zdGVwTnVtYmVyIHx8IHRoaXMubmVzdGVkU3RlcHMubGVuZ3RoO1xuICAgIHJldHVybiBgRW5kOiAke2RlZmF1bHRFbmR9YDtcbiAgfVxuXG4gIGdldFRlc3REYXRhUHJvZmlsZUxhYmVsKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMudGVzdERhdGFQcm9maWxlKSB7XG4gICAgICByZXR1cm4gYFRlc3QgRGF0YSBwcm9maWxlOiAke3RoaXMudGVzdERhdGFQcm9maWxlfWA7XG4gICAgfVxuICAgIHJldHVybiAnVGVzdCBEYXRhIHByb2ZpbGUnO1xuICB9XG5cbiAgZ2V0Q29uZGl0aW9uRGlzcGxheSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbmRpdGlvbiB8fCAnZWxlbWVudCBcIi5ub3RpZmljYXRpb24tYmFkZ2VcIiBleGlzdHMnO1xuICB9XG5cbiAgb25Ub2dnbGVFeHBhbmRlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmV4cGFuZGVkID0gIXRoaXMuZXhwYW5kZWQ7XG4gICAgdGhpcy50b2dnbGVFeHBhbmRlZC5lbWl0KHtjb25maWc6dGhpcy5jb25maWcsIGV4cGFuZGVkOnRoaXMuZXhwYW5kZWR9KTtcbiAgfVxuXG4gIG9uVGVzdERhdGFQcm9maWxlQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnRlc3REYXRhUHJvZmlsZSA9IHZhbHVlO1xuICAgIHRoaXMudGVzdERhdGFQcm9maWxlQ2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgb25TdGFydFN0ZXBDaGFuZ2UodmFsdWU6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuc3RhcnRTdGVwID0gdmFsdWU7XG4gICAgdGhpcy5zdGFydFN0ZXBDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICBvbkVuZFN0ZXBDaGFuZ2UodmFsdWU6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZW5kU3RlcCA9IHZhbHVlO1xuICAgIHRoaXMuZW5kU3RlcENoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIG9uQ29uZGl0aW9uQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNvbmRpdGlvbiA9IHZhbHVlO1xuICAgIHRoaXMuY29uZGl0aW9uQ2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgb25NYXhJdGVyYXRpb25zQ2hhbmdlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLm1heEl0ZXJhdGlvbnMgPSB2YWx1ZTtcbiAgICB0aGlzLm1heEl0ZXJhdGlvbnNDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5uZXN0ZWRTdGVwQ2hhbmdlLmVtaXQoeyBzdGVwLCBpbmRleCB9KTtcbiAgfVxuXG4gIG9uTmVzdGVkVG9nZ2xlRXhwYW5kZWQoZXZlbnQ6IGJvb2xlYW4gfCB7Y29uZmlnOiBUZXN0Q2FzZVN0ZXBDb25maWcsIGV4cGFuZGVkOiBib29sZWFufSwgc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gSGFuZGxlIGJvdGggYm9vbGVhbiBhbmQgb2JqZWN0IGZvcm1hdHNcbiAgICBpZiAodHlwZW9mIGV2ZW50ID09PSAnb2JqZWN0JyAmJiBldmVudCAhPT0gbnVsbCAmJiAnZXhwYW5kZWQnIGluIGV2ZW50KSB7XG4gICAgICAvLyBPYmplY3QgZm9ybWF0IGZyb20gc3RlcC1ncm91cDoge2NvbmZpZywgZXhwYW5kZWR9XG4gICAgICAoc3RlcCBhcyBhbnkpLmV4cGFuZGVkID0gZXZlbnQuZXhwYW5kZWQ7XG4gICAgICAvLyBDaGVjayBpZiB0aGUgZXZlbnQncyBjb25maWcgaXMgYSBzdGVwLWdyb3VwIChub3QgdGhlIGN1cnJlbnQgc3RlcClcbiAgICAgIC8vIFRoaXMgZW5zdXJlcyBuZXN0ZWQgc3RlcC1ncm91cCBldmVudHMgYnViYmxlIHVwIGNvcnJlY3RseSBldmVuIHdoZW4gY29uZGl0aW9uIHN0ZXAgaXMgaW5zaWRlIGxvb3Agc3RlcFxuICAgICAgaWYgKHRoaXMuaXNTdGVwR3JvdXAoZXZlbnQuY29uZmlnKSkge1xuICAgICAgICAvLyBSZS1lbWl0IHRoZSB0b2dnbGVFeHBhbmRlZCBldmVudCB3aXRoIHRoZSBvYmplY3QgZm9ybWF0LCBwcmVzZXJ2aW5nIHRoZSBvcmlnaW5hbCBjb25maWdcbiAgICAgICAgLy8gQ2FzdCB0byBzYXRpc2Z5IFR5cGVTY3JpcHQgLSB0aGUgcmVuZGVyZXIgYWNjZXB0cyBUZXN0Q2FzZVN0ZXBDb25maWcgd2hpY2ggaW5jbHVkZXMgU3RlcEdyb3VwQ29uZmlnXG4gICAgICAgIHRoaXMudG9nZ2xlRXhwYW5kZWQuZW1pdCh7Y29uZmlnOiBldmVudC5jb25maWcgYXMgYW55IGFzIExvb3BTdGVwQ29uZmlnLCBleHBhbmRlZDogZXZlbnQuZXhwYW5kZWR9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQm9vbGVhbiBmb3JtYXQgZnJvbSBvdGhlciBzdGVwIHR5cGVzXG4gICAgICAoc3RlcCBhcyBhbnkpLmV4cGFuZGVkID0gZXZlbnQgYXMgYm9vbGVhbjtcbiAgICB9XG4gICAgdGhpcy5vbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaW5kZXgpO1xuICB9XG5cbiAgb25BZGRTdGVwKCk6IHZvaWQge1xuICAgIHRoaXMuYWRkU3RlcC5lbWl0KCk7XG4gIH1cblxuICBvbkRlbGV0ZVN0ZXAoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZGVsZXRlU3RlcC5lbWl0KGluZGV4KTtcbiAgfVxuXG4gIGlzTm9ybWFsU3RlcChzdGVwOiBUZXN0Q2FzZVN0ZXBDb25maWcpOiBzdGVwIGlzIE5vcm1hbFN0ZXBDb25maWcge1xuICAgIHJldHVybiAnZXZlbnRUeXBlJyBpbiBzdGVwO1xuICB9XG5cbiAgaXNMb29wU3RlcChzdGVwOiBUZXN0Q2FzZVN0ZXBDb25maWcpOiBzdGVwIGlzIExvb3BTdGVwQ29uZmlnIHtcbiAgICByZXR1cm4gJ2xvb3BUeXBlJyBpbiBzdGVwO1xuICB9XG5cbiAgaXNDb25kaXRpb25TdGVwKHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZyk6IHN0ZXAgaXMgQ29uZGl0aW9uU3RlcENvbmZpZyB7XG4gICAgcmV0dXJuICdjb25kaXRpb24nIGluIHN0ZXAgJiYgJ2JyYW5jaGVzJyBpbiBzdGVwO1xuICB9XG5cbiAgaXNTdGVwR3JvdXAoc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnKTogc3RlcCBpcyBTdGVwR3JvdXBDb25maWcge1xuICAgIHJldHVybiAnZ3JvdXBOYW1lJyBpbiBzdGVwO1xuICB9XG5cbiAgb25BZGRCcmFuY2goKTogdm9pZCB7XG4gICAgLy8gTm90IHVzZWQgaW4gbG9vcCBzdGVwLCBidXQgbmVlZGVkIGZvciByZWN1cnNpdmUgY29uZGl0aW9uIHN0ZXBzXG4gIH1cblxuICBvbkRlbGV0ZUJyYW5jaChicmFuY2g6IGFueSk6IHZvaWQge1xuICAgIC8vIE5vdCB1c2VkIGluIGxvb3Agc3RlcCwgYnV0IG5lZWRlZCBmb3IgcmVjdXJzaXZlIGNvbmRpdGlvbiBzdGVwc1xuICB9XG5cbiAgb25OZXN0ZWRDb25kaXRpb25BZGRCcmFuY2gobmVzdGVkU3RlcDogQ29uZGl0aW9uU3RlcENvbmZpZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIEFkZCBhIG5ldyBicmFuY2ggdG8gdGhlIG5lc3RlZCBjb25kaXRpb24gc3RlcFxuICAgIGlmICghbmVzdGVkU3RlcC5icmFuY2hlcykge1xuICAgICAgbmVzdGVkU3RlcC5icmFuY2hlcyA9IFtdO1xuICAgIH1cbiAgICBjb25zdCBuZXdCcmFuY2g6IENvbmRpdGlvbkJyYW5jaCA9IHtcbiAgICAgIHR5cGU6IG5lc3RlZFN0ZXAuYnJhbmNoZXMubGVuZ3RoID09PSAwID8gJ2lmJyA6ICdlbHNlJyxcbiAgICAgIGxhYmVsOiBuZXN0ZWRTdGVwLmJyYW5jaGVzLmxlbmd0aCA9PT0gMCA/ICdJRiBUUlVFJyA6ICdFTFNFJywgXG4gICAgICBzdGVwVHlwZTogU3RlcFR5cGVzLkNPTkRJVElPTl9JRixcbiAgICAgIG5lc3RlZFN0ZXBzOiBbXVxuICAgIH07XG4gICAgbmVzdGVkU3RlcC5icmFuY2hlcy5wdXNoKG5ld0JyYW5jaCk7XG4gICAgdGhpcy5vbk5lc3RlZFN0ZXBDaGFuZ2UobmVzdGVkU3RlcCwgaW5kZXgpO1xuICB9XG5cbiAgb25OZXN0ZWRDb25kaXRpb25EZWxldGVCcmFuY2gobmVzdGVkU3RlcDogQ29uZGl0aW9uU3RlcENvbmZpZywgYnJhbmNoOiBhbnksIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBEZWxldGUgYSBicmFuY2ggZnJvbSB0aGUgbmVzdGVkIGNvbmRpdGlvbiBzdGVwXG4gICAgaWYgKG5lc3RlZFN0ZXAuYnJhbmNoZXMpIHtcbiAgICAgIGNvbnN0IGJyYW5jaEluZGV4ID0gbmVzdGVkU3RlcC5icmFuY2hlcy5pbmRleE9mKGJyYW5jaCk7XG4gICAgICBpZiAoYnJhbmNoSW5kZXggPiAtMSkge1xuICAgICAgICBuZXN0ZWRTdGVwLmJyYW5jaGVzLnNwbGljZShicmFuY2hJbmRleCwgMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMub25OZXN0ZWRTdGVwQ2hhbmdlKG5lc3RlZFN0ZXAsIGluZGV4KTtcbiAgfVxuXG4gIG9uT3BlbkV4dGVybmFsKCk6IHZvaWQge1xuICAgIC8vIE5vdCB1c2VkIGluIGxvb3Agc3RlcCwgYnV0IG5lZWRlZCBmb3IgcmVjdXJzaXZlIHN0ZXAgZ3JvdXBzXG4gIH1cblxuICBvbkVkaXQoKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0U25hcHNob3QgPSB7XG4gICAgICB0ZXN0RGF0YVByb2ZpbGU6IHRoaXMudGVzdERhdGFQcm9maWxlLFxuICAgICAgc3RhcnRTdGVwOiB0aGlzLnN0YXJ0U3RlcCxcbiAgICAgIGVuZFN0ZXA6IHRoaXMuZW5kU3RlcCxcbiAgICAgIGNvbmRpdGlvbjogdGhpcy5jb25kaXRpb24sXG4gICAgICBtYXhJdGVyYXRpb25zOiB0aGlzLm1heEl0ZXJhdGlvbnMsXG4gICAgfTtcbiAgICB0aGlzLmVkaXRGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgZm9yT3B0aW9uVHlwZTogbnVsbCxcbiAgICAgIHRlc3REYXRhUHJvZmlsZTogdGhpcy50ZXN0RGF0YVByb2ZpbGUgPz8gJycsXG4gICAgICBzdGFydFN0ZXA6IHRoaXMuc3RhcnRTdGVwID8/IG51bGwsXG4gICAgICBlbmRTdGVwOiB0aGlzLmVuZFN0ZXAgPz8gbnVsbCxcbiAgICAgIGNvbmRpdGlvbjogdGhpcy5jb25kaXRpb24gPz8gJycsXG4gICAgICBtYXhJdGVyYXRpb25zOiB0aGlzLm1heEl0ZXJhdGlvbnMgPz8gNSxcbiAgICB9KTtcbiAgICB0aGlzLmlzRWRpdGluZyA9IHRydWU7XG4gICAgdGhpcy5lZGl0LmVtaXQoKTtcbiAgfVxuXG4gIG9uRWRpdEFwcGx5KCk6IHZvaWQge1xuICAgIGNvbnN0IHYgPSB0aGlzLmVkaXRGb3JtLnZhbHVlO1xuICAgIGNvbnN0IHRlc3REYXRhUHJvZmlsZVZhbHVlID0gdi50ZXN0RGF0YVByb2ZpbGUgPz8gJyc7XG4gICAgdGhpcy5zdGFydFN0ZXAgPSB2LnN0YXJ0U3RlcCA/PyB1bmRlZmluZWQ7XG4gICAgdGhpcy5lbmRTdGVwID0gdi5lbmRTdGVwID8/IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbmRpdGlvbiA9IHYuY29uZGl0aW9uID8/ICcnO1xuICAgIGNvbnN0IG1heFZhbCA9IHYubWF4SXRlcmF0aW9ucztcbiAgICB0aGlzLm1heEl0ZXJhdGlvbnMgPSB0eXBlb2YgbWF4VmFsID09PSAnbnVtYmVyJyA/IG1heFZhbCA6IChtYXhWYWwgIT0gbnVsbCAmJiBtYXhWYWwgIT09ICcnID8gTnVtYmVyKG1heFZhbCkgOiB1bmRlZmluZWQpO1xuICAgIFxuICAgIC8vIEZpbmQgdGhlIHNlbGVjdGVkIGRhdGEgcHJvZmlsZSBvcHRpb24gdG8gZ2V0IGJvdGggSUQgYW5kIG5hbWVcbiAgICBsZXQgdGVzdERhdGFQcm9maWxlSWQ6IHN0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdGVzdERhdGFQcm9maWxlTmFtZTogc3RyaW5nID0gJyc7XG4gICAgXG4gICAgaWYgKHRlc3REYXRhUHJvZmlsZVZhbHVlICYmIHRoaXMuZGF0YVByb2ZpbGVPcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFRoZSBmb3JtIHZhbHVlIG1pZ2h0IGJlIElEIChudW1iZXIpIG9yIG5hbWUgKHN0cmluZylcbiAgICAgIGNvbnN0IHNlbGVjdGVkUHJvZmlsZSA9IHRoaXMuZGF0YVByb2ZpbGVPcHRpb25zLmZpbmQoXG4gICAgICAgIG9wdGlvbiA9PiBvcHRpb24uaWQgPT09IE51bWJlcih0ZXN0RGF0YVByb2ZpbGVWYWx1ZSkgfHwgb3B0aW9uLm5hbWUgPT09IHRlc3REYXRhUHJvZmlsZVZhbHVlIHx8IFN0cmluZyhvcHRpb24uaWQpID09PSBTdHJpbmcodGVzdERhdGFQcm9maWxlVmFsdWUpXG4gICAgICApO1xuICAgICAgaWYgKHNlbGVjdGVkUHJvZmlsZSkge1xuICAgICAgICB0ZXN0RGF0YVByb2ZpbGVJZCA9IHNlbGVjdGVkUHJvZmlsZS5pZDtcbiAgICAgICAgdGVzdERhdGFQcm9maWxlTmFtZSA9IHNlbGVjdGVkUHJvZmlsZS5uYW1lO1xuICAgICAgICB0aGlzLnRlc3REYXRhUHJvZmlsZSA9IHRlc3REYXRhUHJvZmlsZU5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBub3QgZm91bmQsIHVzZSB0aGUgdmFsdWUgYXMtaXMgKG1pZ2h0IGJlIElEIG9yIG5hbWUpXG4gICAgICAgIHRoaXMudGVzdERhdGFQcm9maWxlID0gdGVzdERhdGFQcm9maWxlVmFsdWU7XG4gICAgICAgIHRlc3REYXRhUHJvZmlsZUlkID0gTnVtYmVyKHRlc3REYXRhUHJvZmlsZVZhbHVlKSB8fCB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGVzdERhdGFQcm9maWxlID0gdGVzdERhdGFQcm9maWxlVmFsdWU7XG4gICAgfVxuICAgIFxuICAgIC8vIFVwZGF0ZSBjb25maWcgd2l0aCBuZXcgdmFsdWVzIChpbmNsdWRlIHRlc3REYXRhUHJvZmlsZUlkIGFzIGFkZGl0aW9uYWwgcHJvcGVydHkpXG4gICAgY29uc3QgdXBkYXRlZENvbmZpZzogTG9vcFN0ZXBDb25maWcgJiB7IHRlc3REYXRhUHJvZmlsZUlkPzogc3RyaW5nIHwgbnVtYmVyIH0gPSB7XG4gICAgICAuLi50aGlzLmNvbmZpZyxcbiAgICAgIHRlc3REYXRhUHJvZmlsZTogdGhpcy50ZXN0RGF0YVByb2ZpbGUsXG4gICAgICB0ZXN0RGF0YVByb2ZpbGVJZDogdGVzdERhdGFQcm9maWxlSWQsIC8vIEFkZCBJRCBmb3IgQVBJIGNhbGxcbiAgICAgIHN0YXJ0U3RlcDogdGhpcy5zdGFydFN0ZXAsXG4gICAgICBlbmRTdGVwOiB0aGlzLmVuZFN0ZXAsXG4gICAgICBjb25kaXRpb246IHRoaXMuY29uZGl0aW9uLFxuICAgICAgbWF4SXRlcmF0aW9uczogdGhpcy5tYXhJdGVyYXRpb25zLFxuICAgIH07XG4gICAgXG4gICAgLy8gRW1pdCBpbmRpdmlkdWFsIGNoYW5nZSBldmVudHNcbiAgICB0aGlzLnRlc3REYXRhUHJvZmlsZUNoYW5nZS5lbWl0KHRoaXMudGVzdERhdGFQcm9maWxlKTtcbiAgICB0aGlzLnN0YXJ0U3RlcENoYW5nZS5lbWl0KHRoaXMuc3RhcnRTdGVwID8/IDEpO1xuICAgIHRoaXMuZW5kU3RlcENoYW5nZS5lbWl0KHRoaXMuZW5kU3RlcCA/PyAxKTtcbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJykge1xuICAgICAgdGhpcy5jb25kaXRpb25DaGFuZ2UuZW1pdCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICB0aGlzLm1heEl0ZXJhdGlvbnNDaGFuZ2UuZW1pdCh0aGlzLm1heEl0ZXJhdGlvbnMgPz8gNSk7XG4gICAgfVxuICAgIFxuICAgIC8vIEVtaXQgc3RlcCB1cGRhdGUgZXZlbnQgd2l0aCBmdWxsIGNvbmZpZ1xuICAgIGNvbnNvbGUubG9nKCdMb29wLXN0ZXA6IEVtaXR0aW5nIHN0ZXBVcGRhdGUgZXZlbnQnLCB1cGRhdGVkQ29uZmlnKTtcbiAgICB0aGlzLnN0ZXBVcGRhdGUuZW1pdCh1cGRhdGVkQ29uZmlnKTtcbiAgICBcbiAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgb25FZGl0Q2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMudGVzdERhdGFQcm9maWxlID0gdGhpcy5lZGl0U25hcHNob3QudGVzdERhdGFQcm9maWxlO1xuICAgIHRoaXMuc3RhcnRTdGVwID0gdGhpcy5lZGl0U25hcHNob3Quc3RhcnRTdGVwO1xuICAgIHRoaXMuZW5kU3RlcCA9IHRoaXMuZWRpdFNuYXBzaG90LmVuZFN0ZXA7XG4gICAgdGhpcy5jb25kaXRpb24gPSB0aGlzLmVkaXRTbmFwc2hvdC5jb25kaXRpb247XG4gICAgdGhpcy5tYXhJdGVyYXRpb25zID0gdGhpcy5lZGl0U25hcHNob3QubWF4SXRlcmF0aW9ucztcbiAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgb25FZGl0SW5EZXB0aCgpOiB2b2lkIHtcbiAgICB0aGlzLm1vcmVPcHRpb25zLmVtaXQoKTtcbiAgICBjb25zdCBpbmRleCA9IHR5cGVvZiB0aGlzLnN0ZXBOdW1iZXIgPT09ICdudW1iZXInID8gdGhpcy5zdGVwTnVtYmVyIDogKHR5cGVvZiB0aGlzLnN0ZXBOdW1iZXIgPT09ICdzdHJpbmcnID8gcGFyc2VJbnQodGhpcy5zdGVwTnVtYmVyLCAxMCkgOiAwKTtcbiAgICB0aGlzLmVkaXRJbkRlcHRoLmVtaXQoeyBzdGVwOiB0aGlzLmNvbmZpZyBhcyBUZXN0Q2FzZVN0ZXBDb25maWcsIGluZGV4OiBpc05hTihpbmRleCkgPyAwIDogaW5kZXggfSk7XG4gIH1cblxuICBvbkxpbmsoKTogdm9pZCB7XG4gICAgLy8gTm90IHVzZWQgaW4gbG9vcCBzdGVwLCBidXQgbmVlZGVkIGZvciByZWN1cnNpdmUgc3RlcCBncm91cHNcbiAgfVxuXG4gIG9uRHVwbGljYXRlKCk6IHZvaWQge1xuICAgIHRoaXMuZHVwbGljYXRlLmVtaXQoKTtcbiAgfVxuXG4gIG9uRGVsZXRlKCk6IHZvaWQge1xuICAgIHRoaXMuZGVsZXRlLmVtaXQoKTtcbiAgfVxuXG4gIG9uU2VsZWN0aW9uQ2hhbmdlKGNoZWNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkID0gY2hlY2tlZDtcbiAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KGNoZWNrZWQpO1xuICB9XG5cbiAgb25Nb3JlT3B0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1vcmVPcHRpb25zLmVtaXQoKTtcbiAgfVxuXG4gIG9uVmlld0RldGFpbHMoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICAgIFxuICAgIGlmICghdGhpcy5jb25maWcuZGVzY3JpcHRpb24gfHwgdGhpcy5jb25maWcuZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudCkge1xuICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdGT1IgTE9PUCBEZXRhaWxzJyA6ICdXSElMRSBMT09QIERldGFpbHMnO1xuICAgICAgdGhpcy52aWV3RGV0YWlscy5lbWl0KHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRpdGxlLFxuICAgICAgICBkZXNjcmlwdGlvbjogdGhpcy5jb25maWcuZGVzY3JpcHRpb24sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIj5cbiAgPCEtLSBJbmxpbmUgRWRpdCBNb2RlOiBGcmFtZSAyMTQ3MjI0OTEwIC0gZmxleCByb3csIDEwNTbDlzM2LCBnYXAgMTJweCwgZmxleC1ub25lIC0tPlxuICA8ZGl2ICpuZ0lmPVwiaXNFZGl0aW5nXCIgY2xhc3M9XCJjcWEtcHktMi41IGNxYS1weC00IGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0zIGNxYS1qdXN0aWZ5LWJldHdlZW5cIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTMgY3FhLWZsZXgtZ3Jvd1wiPlxuICAgICAgPCEtLSBMb29wIFR5cGUgTGFiZWwgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtWyMxQzM5OEVdIGNxYS10ZXh0LVsxMnB4XSBjcWEtbGVhZGluZy1bMTVweF1cIj5cbiAgICAgICAge3sgZ2V0TG9vcFR5cGVMYWJlbCgpIH19XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBGT1IgTE9PUCBpbmxpbmUgZWRpdDogY3FhLWR5bmFtaWMtc2VsZWN0IChzYW1lIHVzYWdlIGFzIGRlZmF1bHQgc3RvcmllcykgLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9vcFR5cGUgPT09ICdmb3InXCI+XG4gICAgICAgIDwhLS0gRmlyc3Qgc2VsZWN0OiB3aWR0aCAyMTYuMjVweCwgaGVpZ2h0IDM2cHgsIGdhcCA0cHgsIG9wYWNpdHkgMSAtLT5cbiAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCBbZm9ybV09XCJlZGl0Rm9ybVwiIFtjb25maWddPVwiZm9yT3B0aW9uVHlwZVNlbGVjdENvbmZpZ1wiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1tYXgtdy1bMjE2cHhdXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cInRlc3REYXRhUHJvZmlsZVNlbGVjdENvbmZpZ1wiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1tYXgtdy1bMjE2cHhdXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cInN0YXJ0U3RlcFNlbGVjdENvbmZpZ1wiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1tYXgtdy1bMjE2cHhdXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cImVuZFN0ZXBTZWxlY3RDb25maWdcIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLXctZnVsbCBjcWEtbWF4LXctWzIxNnB4XVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gV0hJTEUgTE9PUCBpbmxpbmUgZWRpdCAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1doaWxlTG9vcCgpXCI+XG4gICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cImNvbmRpdGlvblNlbGVjdENvbmZpZ1wiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1tYXgtdy1bMjE2cHhdXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBFZGl0IEluIGRlcHRoIGxpbmsgLS0+XG4gICAgICA8YSBocmVmPVwiI1wiIChjbGljayk9XCJvbkVkaXRJbkRlcHRoKCk7ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC1bIzNGNDNFRV0gY3FhLXRleHQtWzEwcHhdIGNxYS1sZWFkaW5nLVsxNXB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLVsycHhdIGNxYS1uby11bmRlcmxpbmVcIj5cbiAgICAgICAgRWRpdCBJbiBkZXB0aFxuICAgICAgICA8c3ZnIHdpZHRoPVwiOFwiIGhlaWdodD1cIjhcIiB2aWV3Qm94PVwiMCAwIDggOFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICBkPVwiTTIuMDM4MDkgNi43NDMyOUwyLjYyODA5IDcuMzMzMjlMNS45NjE0MiAzLjk5OTk2TDIuNjI4MDkgMC42NjY2MjZMMi4wMzgwOSAxLjI1NjYzTDQuNzgxNDIgMy45OTk5NkwyLjAzODA5IDYuNzQzMjlaXCJcbiAgICAgICAgICAgIGZpbGw9XCIjM0Y0M0VFXCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICA8L2E+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEuNVwiPlxuICAgICAgPCEtLSBDYW5jZWwgLyBBcHBseSAtLT5cbiAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJvdXRsaW5lZFwiIGJ0blNpemU9XCJsZ1wiIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSdcIiBbdGV4dF09XCInQ2FuY2VsJ1wiXG4gICAgICAgIChjbGlja2VkKT1cIm9uRWRpdENhbmNlbCgpXCI+PC9jcWEtYnV0dG9uPlxuICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIGJ0blNpemU9XCJsZ1wiIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSdcIiBbdGV4dF09XCInQXBwbHknXCJcbiAgICAgICAgKGNsaWNrZWQpPVwib25FZGl0QXBwbHkoKVwiPjwvY3FhLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBMb29wIEhlYWRlciAobm9ybWFsIHZpZXcgd2hlbiBub3QgZWRpdGluZykgLS0+XG4gIDxkaXYgKm5nSWY9XCIhaXNFZGl0aW5nXCJcbiAgICBbY2xhc3NdPVwiJ3N0ZXAtcm93IGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0zIGNxYS1weS0yICcgKyAoaXNJbnNpZGVMb29wID8gJ2NxYS1wbC0xMCBjcWEtcHItNCcgOiAnY3FhLXB4LTQnKVwiPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtaW5saW5lLWZsZXggY3FhLWl0ZW1zLWNlbnRlclwiPlxuICAgIDwhLS0gRHJhZyBIYW5kbGUgSWNvbiAod2hlbiBpc1Jlb3JkZXIgaXMgdHJ1ZSkgLS0+XG4gICAgPGRpdiAqbmdJZj1cImlzUmVvcmRlclwiIGNsYXNzPVwiY3FhLW1yLTIgY3FhLWN1cnNvci1tb3ZlIGNxYS10ZXh0LVsjNkI3MjgwXSBob3ZlcjpjcWEtdGV4dC1bIzExMTgyN11cIj5cbiAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiM1wiIGN5PVwiM1wiIHI9XCIxLjVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiOFwiIGN5PVwiM1wiIHI9XCIxLjVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiMTNcIiBjeT1cIjNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjNcIiBjeT1cIjhcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjhcIiBjeT1cIjhcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjEzXCIgY3k9XCI4XCIgcj1cIjEuNVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIi8+XG4gICAgICAgIDxjaXJjbGUgY3g9XCIzXCIgY3k9XCIxM1wiIHI9XCIxLjVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiOFwiIGN5PVwiMTNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjEzXCIgY3k9XCIxM1wiIHI9XCIxLjVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgPC9zdmc+XG4gICAgPC9kaXY+XG4gICAgPCEtLSBDaGVja2JveCAod2hlbiBpc1Jlb3JkZXIgaXMgZmFsc2UpIC0tPlxuICAgIDxsYWJlbCAqbmdJZj1cIiFpc1Jlb3JkZXJcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWN1cnNvci1wb2ludGVyIGNxYS1yZWxhdGl2ZSBjcWEtbXItMlwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkXCJcbiAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25TZWxlY3Rpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgIGNsYXNzPVwiY3FhLWgtNCBjcWEtdy00IGNxYS1jdXJzb3ItcG9pbnRlciBjcWEtdHJhbnNpdGlvbi1hbGwgY3FhLWFwcGVhcmFuY2Utbm9uZSBjcWEtcm91bmRlZCBzaGFkb3cgaG92ZXI6Y3FhLXNoYWRvdy1tZCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci1zbGF0ZS0zMDAgY3FhLWZsZXgtc2hyaW5rLTBcIlxuICAgICAgICBbY2xhc3MuY3FhLWJnLVsjM0Y0M0VFXV09XCJzZWxlY3RlZFwiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLVsjM0Y0M0VFXV09XCJzZWxlY3RlZFwiXG4gICAgICAgIGlkPVwiY2hlY2stbG9vcC1zdGVwXCIgLz5cbiAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLWFic29sdXRlIGNxYS10ZXh0LXdoaXRlIGNxYS10b3AtMS8yIGNxYS1sZWZ0LTEvMiBjcWEtLXRyYW5zbGF0ZS14LTEvMiBjcWEtLXRyYW5zbGF0ZS15LTEvMiBjcWEtcG9pbnRlci1ldmVudHMtbm9uZSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlclwiXG4gICAgICAgIFtjbGFzcy5jcWEtb3BhY2l0eS0wXT1cIiFzZWxlY3RlZFwiXG4gICAgICAgIFtjbGFzcy5jcWEtb3BhY2l0eS0xMDBdPVwic2VsZWN0ZWRcIj5cbiAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTNcIiB2aWV3Qm94PVwiMCAwIDEyIDEzXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk0xMCAzLjEyNUw0LjUgOC42MjVMMiA2LjEyNVwiIHN0cm9rZT1cIndoaXRlXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPjwvc3ZnPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbGFiZWw+XG4gICAgPC9kaXY+XG4gICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLXRleHQtWzE0cHhdIGNxYS1sZWFkaW5nLVsxOHB4XSBjcWEtbWluLXctWzMycHhdXCI+e3sgc3RlcE51bWJlciB9fTwvc3Bhbj5cbiAgICA8IS0tIEV4cGFuZC9Db2xsYXBzZSBJY29uIC0tPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvblRvZ2dsZUV4cGFuZGVkKClcIiBjbGFzcz1cImNxYS1wLTBcIj5cbiAgICAgIDxzdmcgW2NsYXNzLmNxYS1yb3RhdGUtMTgwXT1cIiFleHBhbmRlZFwiIGNsYXNzPVwiY3FhLXRyYW5zaXRpb24tdHJhbnNmb3JtXCIgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCJcbiAgICAgICAgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICA8cGF0aCBkPVwiTTEyIDEwTDggNkw0IDEwXCIgc3Ryb2tlPVwiIzZCNzI4MFwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICA8L3N2Zz5cbiAgICA8L2J1dHRvbj5cblxuICAgIDwhLS0gTG9vcCBJY29uIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJsb29wVHlwZSA9PT0gJ2ZvcidcIj5cbiAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICA8cGF0aCBkPVwiTTExLjMzNCAxLjMzMzI1TDE0LjAwMDcgMy45OTk5MkwxMS4zMzQgNi42NjY1OVwiIHN0cm9rZT1cIiMxQzM5OEVcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCJcbiAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8cGF0aCBkPVwiTTIgNy4zMzMzM1Y2LjY2NjY3QzIgNS45NTk0MiAyLjI4MDk1IDUuMjgxMTUgMi43ODEwNSA0Ljc4MTA1QzMuMjgxMTUgNC4yODA5NSAzLjk1OTQyIDQgNC42NjY2NyA0SDE0XCJcbiAgICAgICAgICBzdHJva2U9XCIjMUMzOThFXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoIGQ9XCJNNC42NjY2NyAxNC42NjY2TDIgMTEuOTk5OUw0LjY2NjY3IDkuMzMzMjVcIiBzdHJva2U9XCIjMUMzOThFXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiXG4gICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPHBhdGhcbiAgICAgICAgICBkPVwiTTE0IDguNjY2NzVWOS4zMzM0MUMxNCAxMC4wNDA3IDEzLjcxOSAxMC43MTg5IDEzLjIxOSAxMS4yMTlDMTIuNzE4OSAxMS43MTkxIDEyLjA0MDYgMTIuMDAwMSAxMS4zMzMzIDEyLjAwMDFIMlwiXG4gICAgICAgICAgc3Ryb2tlPVwiIzFDMzk4RVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPC9zdmc+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImxvb3BUeXBlID09PSAnd2hpbGUnXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xMS4zMzQgMS4zMzMyNUwxNC4wMDA3IDMuOTk5OTJMMTEuMzM0IDYuNjY2NTlcIiBzdHJva2U9XCIjNTkxNjhCXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiXG4gICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPHBhdGggZD1cIk0yIDcuMzMzMzNWNi42NjY2N0MyIDUuOTU5NDIgMi4yODA5NSA1LjI4MTE1IDIuNzgxMDUgNC43ODEwNUMzLjI4MTE1IDQuMjgwOTUgMy45NTk0MiA0IDQuNjY2NjcgNEgxNFwiXG4gICAgICAgICAgc3Ryb2tlPVwiIzU5MTY4QlwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8cGF0aCBkPVwiTTQuNjY2NjcgMTQuNjY2NkwyIDExLjk5OTlMNC42NjY2NyA5LjMzMzI1XCIgc3Ryb2tlPVwiIzU5MTY4QlwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIlxuICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgZD1cIk0xNCA4LjY2Njc1VjkuMzMzNDFDMTQgMTAuMDQwNyAxMy43MTkgMTAuNzE4OSAxMy4yMTkgMTEuMjE5QzEyLjcxODkgMTEuNzE5MSAxMi4wNDA2IDEyLjAwMDEgMTEuMzMzMyAxMi4wMDAxSDJcIlxuICAgICAgICAgIHN0cm9rZT1cIiM1OTE2OEJcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBMb29wIFR5cGUgTGFiZWwgLS0+XG4gICAgPHNwYW4gY2xhc3M9XCJjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1bIzFDMzk4RV0gY3FhLXRleHQtWzEycHhdIGNxYS1sZWFkaW5nLW5vbmVcIj5cbiAgICAgIHt7IGdldExvb3BUeXBlTGFiZWwoKSB9fVxuICAgIDwvc3Bhbj5cblxuICAgIDwhLS0gRm9yIExvb3AgQ29udHJvbHMgLS0+XG4gICAgPGRpdiAqbmdJZj1cImxvb3BUeXBlID09PSAnZm9yJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLW1sLTJcIj5cbiAgICAgIDwhLS0gVGVzdCBEYXRhIFByb2ZpbGUgQnV0dG9uIC0tPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2NsYXNzLmNxYS1iZy1wcmltYXJ5LTEwMF09XCJ0ZXN0RGF0YVByb2ZpbGVcIiBbY2xhc3MuY3FhLXRleHQtcHJpbWFyeV09XCJ0ZXN0RGF0YVByb2ZpbGVcIlxuICAgICAgICBjbGFzcz1cImNxYS1weS0wLjUgY3FhLXB4LTIgY3FhLXRleHQtWyMzRjQzRUVdIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMTdweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyM4QThDRjRdIGNxYS1yb3VuZGVkIGNxYS1iZy1bI0Q4RDlGQ11cIj5cbiAgICAgICAge3sgZ2V0VGVzdERhdGFQcm9maWxlTGFiZWwoKSB9fVxuICAgICAgPC9idXR0b24+XG5cbiAgICAgIDwhLS0gU3RhcnQgQnV0dG9uIC0tPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2NsYXNzLmNxYS1iZy1wcmltYXJ5LTEwMF09XCJzdGFydFN0ZXBcIiBbY2xhc3MuY3FhLXRleHQtcHJpbWFyeV09XCJzdGFydFN0ZXBcIlxuICAgICAgICBjbGFzcz1cImNxYS1weS0wLjUgY3FhLXB4LTIgY3FhLXRleHQtWyMzRjQzRUVdIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMTdweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyM4QThDRjRdIGNxYS1yb3VuZGVkIGNxYS1iZy1bI0Q4RDlGQ11cIj5cbiAgICAgICAge3sgZ2V0U3RhcnRTdGVwTGFiZWwoKSB9fVxuICAgICAgPC9idXR0b24+XG5cbiAgICAgIDwhLS0gRW5kIEJ1dHRvbiAtLT5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtjbGFzcy5jcWEtYmctcHJpbWFyeS0xMDBdPVwiZW5kU3RlcFwiIFtjbGFzcy5jcWEtdGV4dC1wcmltYXJ5XT1cImVuZFN0ZXBcIlxuICAgICAgICBjbGFzcz1cImNxYS1weS0wLjUgY3FhLXB4LTIgY3FhLXRleHQtWyMzRjQzRUVdIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMTdweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyM4QThDRjRdIGNxYS1yb3VuZGVkIGNxYS1iZy1bI0Q4RDlGQ11cIj5cbiAgICAgICAge3sgZ2V0RW5kU3RlcExhYmVsKCkgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBXaGlsZSBMb29wIENvbmRpdGlvbiAob25seSBzaG93IGlmIGNvbmRpdGlvbiBleGlzdHMpIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJpc1doaWxlTG9vcCgpICYmIGNvbmRpdGlvblwiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLW1sLTIgY3FhLWZsZXgtMVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1ncmF5LTcwMCBjcWEtdGV4dC1zbVwiPlxuICAgICAgICBXaGlsZVxuICAgICAgPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1ncmF5LTkwMCBjcWEtdGV4dC1zbVwiIFtpbm5lckhUTUxdPVwiZ2V0Q29uZGl0aW9uRGlzcGxheSgpXCI+PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBTdGVwcyBTdW1tYXJ5IC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY3FhLW1sLWF1dG8gY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNFNUU1RTVdIGNxYS1yb3VuZGVkLWxnIGNxYS1weS0wLjUgY3FhLXB4LTIgY3FhLXRleHQtWyMwQTBBMEFdIGNxYS10ZXh0LVsxMnB4XSBjcWEtbGVhZGluZy1bMTVweF1cIj5cbiAgICAgIHt7IGdldFN0ZXBzU3VtbWFyeSgpIH19XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFZpZXcgRGV0YWlscyBMaW5rIChzaG93IG9ubHkgaWYgZGVzY3JpcHRpb24gaXMgbm90IGVtcHR5KSAtLT5cbiAgICA8YSAqbmdJZj1cImNvbmZpZy5kZXNjcmlwdGlvbiAmJiBjb25maWcuZGVzY3JpcHRpb24udHJpbSgpICE9PSAnJ1wiICN2aWV3RGV0YWlsc1RyaWdnZXIgaHJlZj1cIiNcIiAoY2xpY2spPVwib25WaWV3RGV0YWlscygkZXZlbnQpXCIgY2xhc3M9XCJjcWEtdGV4dC1bIzNGNDNFRV0gY3FhLXRleHQtWzEwcHhdIGNxYS1sZWFkaW5nLVsxNXB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLW5vLXVuZGVybGluZSBjcWEtbWwtYXV0b1wiPlZpZXcgRGV0YWlsczxzdmcgd2lkdGg9XCI4XCIgaGVpZ2h0PVwiOFwiIHZpZXdCb3g9XCIwIDAgOCA4XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk0yLjAzODA5IDYuNzQzMjlMMi42MjgwOSA3LjMzMzI5TDUuOTYxNDIgMy45OTk5NkwyLjYyODA5IDAuNjY2NjI2TDIuMDM4MDkgMS4yNTY2M0w0Ljc4MTQyIDMuOTk5OTZMMi4wMzgwOSA2Ljc0MzI5WlwiIGZpbGw9XCIjM0Y0M0VFXCIvPjwvc3ZnPjwvYT5cblxuICAgIDwhLS0gQWN0aW9uIEljb25zOiBFZGl0LCBMaW5rLCBEdXBsaWNhdGUsIERlbGV0ZSAoc2hvdyBvbiBob3ZlcikgLS0+XG4gICAgPGRpdiBjbGFzcz1cInN0ZXAtYWN0aW9ucyBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtcHgtWzdweF1cIj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkVkaXQoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJFZGl0XCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcC0wIGNxYS10ZXh0LVsjOTlBMUFmXSBob3ZlcjpjcWEtdGV4dC1bIzE0NDdFNl1cIj5cbiAgICAgICAgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGggZD1cIk03IDExLjY2NjZIMTIuMjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjE2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgIGQ9XCJNOS41NTIwOCAyLjExMjhDOS43ODQzIDEuODgwNTggMTAuMDk5MyAxLjc1MDEyIDEwLjQyNzcgMS43NTAxMkMxMC43NTYxIDEuNzUwMTIgMTEuMDcxIDEuODgwNTggMTEuMzAzMyAyLjExMjhDMTEuNTM1NSAyLjM0NTAyIDExLjY2NTkgMi42NTk5OCAxMS42NjU5IDIuOTg4MzhDMTEuNjY1OSAzLjMxNjc5IDExLjUzNTUgMy42MzE3NSAxMS4zMDMzIDMuODYzOTdMNC4yOTc0MiAxMC44NzA0QzQuMTU4NjQgMTEuMDA5MiAzLjk4NzEgMTEuMTEwNyAzLjc5ODY3IDExLjE2NTZMMi4xMjMzMyAxMS42NTQ0QzIuMDczMTQgMTEuNjY5IDIuMDE5OTMgMTEuNjY5OSAxLjk2OTI4IDExLjY1NjlDMS45MTg2MyAxMS42NDM5IDEuODcyNCAxMS42MTc2IDEuODM1NDMgMTEuNTgwNkMxLjc5ODQ2IDExLjU0MzcgMS43NzIxIDExLjQ5NzQgMS43NTkxMyAxMS40NDY4QzEuNzQ2MTUgMTEuMzk2MSAxLjc0NzAzIDExLjM0MjkgMS43NjE2NyAxMS4yOTI3TDIuMjUwNSA5LjYxNzM4QzIuMzA1NDYgOS40MjkxNiAyLjQwNjk4IDkuMjU3ODMgMi41NDU2NyA5LjExOTIyTDkuNTUyMDggMi4xMTI4WlwiXG4gICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjE2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkxpbmsoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJMaW5rXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcC0wIGNxYS10ZXh0LVsjOTlBMUFmXSBob3ZlcjpjcWEtdGV4dC1bIzE0NDdFNl1cIj5cbiAgICAgICAgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgIGQ9XCJNNS4wMDA2NSA5LjkxNjcxSDMuNjY3MzJDMi43ODMyNiA5LjkxNjcxIDEuOTM1NDIgOS42MDk0MiAxLjMxMDMgOS4wNjI0NEMwLjY4NTE3NCA4LjUxNTQ1IDAuMzMzOTg0IDcuNzczNTkgMC4zMzM5ODQgNy4wMDAwNEMwLjMzMzk4NCA2LjIyNjQ5IDAuNjg1MTc0IDUuNDg0NjMgMS4zMTAzIDQuOTM3NjVDMS45MzU0MiA0LjM5MDY2IDIuNzgzMjYgNC4wODMzNyAzLjY2NzMyIDQuMDgzMzdINS4wMDA2NVwiXG4gICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgZD1cIk05IDQuMDgzMzdIMTAuMzMzM0MxMS4yMTc0IDQuMDgzMzcgMTIuMDY1MiA0LjM5MDY2IDEyLjY5MDQgNC45Mzc2NUMxMy4zMTU1IDUuNDg0NjMgMTMuNjY2NyA2LjIyNjQ5IDEzLjY2NjcgNy4wMDAwNEMxMy42NjY3IDcuNzczNTkgMTMuMzE1NSA4LjUxNTQ1IDEyLjY5MDQgOS4wNjI0NEMxMi4wNjUyIDkuNjA5NDIgMTEuMjE3NCA5LjkxNjcxIDEwLjMzMzMgOS45MTY3MUg5XCJcbiAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgIDxwYXRoIGQ9XCJNNC4zMzM5OCA3SDkuNjY3MzJcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25EdXBsaWNhdGUoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJEdXBsaWNhdGVcIlxuICAgICAgICBjbGFzcz1cImNxYS1wLTAgY3FhLXRleHQtWyM5OUExQWZdIGhvdmVyOmNxYS10ZXh0LVsjMTQ0N0U2XVwiPlxuICAgICAgICA8c3ZnIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMTQgMTRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgZD1cIk0xMS42NjYgNC42NjY2M0g1LjgzMjY4QzUuMTg4MzUgNC42NjY2MyA0LjY2NjAyIDUuMTg4OTYgNC42NjYwMiA1LjgzMzI5VjExLjY2NjZDNC42NjYwMiAxMi4zMTEgNS4xODgzNSAxMi44MzMzIDUuODMyNjggMTIuODMzM0gxMS42NjZDMTIuMzEwMyAxMi44MzMzIDEyLjgzMjcgMTIuMzExIDEyLjgzMjcgMTEuNjY2NlY1LjgzMzI5QzEyLjgzMjcgNS4xODg5NiAxMi4zMTAzIDQuNjY2NjMgMTEuNjY2IDQuNjY2NjNaXCJcbiAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMTY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICBkPVwiTTIuMzMyNjggOS4zMzMyOUMxLjY5MTAyIDkuMzMzMjkgMS4xNjYwMiA4LjgwODI5IDEuMTY2MDIgOC4xNjY2M1YyLjMzMzI5QzEuMTY2MDIgMS42OTE2MyAxLjY5MTAyIDEuMTY2NjMgMi4zMzI2OCAxLjE2NjYzSDguMTY2MDJDOC44MDc2OCAxLjE2NjYzIDkuMzMyNjggMS42OTE2MyA5LjMzMjY4IDIuMzMzMjlcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25EZWxldGUoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJEZWxldGVcIlxuICAgICAgICBjbGFzcz1cImNxYS1wLTAgY3FhLXRleHQtWyNmZjY0NjddIGhvdmVyOmNxYS10ZXh0LVsjQzYzNTM1XVwiPlxuICAgICAgICA8c3ZnIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMTQgMTRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICA8cGF0aCBkPVwiTTEuNzUgMy41SDEyLjI1XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICBkPVwiTTExLjA4MjcgMy41VjExLjY2NjdDMTEuMDgyNyAxMi4yNSAxMC40OTkzIDEyLjgzMzMgOS45MTYwMiAxMi44MzMzSDQuMDgyNjhDMy40OTkzNSAxMi44MzMzIDIuOTE2MDIgMTIuMjUgMi45MTYwMiAxMS42NjY3VjMuNVwiXG4gICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjE2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgZD1cIk00LjY2NjAyIDMuNDk5OTZWMi4zMzMyOUM0LjY2NjAyIDEuNzQ5OTYgNS4yNDkzNSAxLjE2NjYzIDUuODMyNjggMS4xNjY2M0g4LjE2NjAyQzguNzQ5MzUgMS4xNjY2MyA5LjMzMjY4IDEuNzQ5OTYgOS4zMzI2OCAyLjMzMzI5VjMuNDk5OTZcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgPHBhdGggZD1cIk01LjgzMzk4IDYuNDE2NjNWOS45MTY2M1wiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMTY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICA8cGF0aCBkPVwiTTguMTY2MDIgNi40MTY2M1Y5LjkxNjYzXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIEV4cGFuZGVkIENvbnRlbnQgd2l0aCBOZXN0ZWQgU3RlcHMgKHJlbmRlcmVyIGRpc3BhdGNoZXMgYnkgc3RlcCB0eXBlLCBuLWxldmVsIG5lc3RpbmcpIC0tPlxuICA8ZGl2ICpuZ0lmPVwiZXhwYW5kZWRcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiPlxuICAgIDxkaXYgKm5nSWY9XCIhaXNSZW9yZGVyXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIj5cbiAgICAgIDxjcWEtdGVzdC1jYXNlLWRldGFpbHMtcmVuZGVyZXIgKm5nRm9yPVwibGV0IHN0ZXAgb2YgbmVzdGVkU3RlcHM7IGxldCBpID0gaW5kZXhcIiBbc3RlcF09XCJzdGVwXCIgW2luZGV4XT1cImlcIlxuICAgICAgICBbc2VsZWN0ZWRdPVwiJGFueShzdGVwKS5zZWxlY3RlZFwiXG4gICAgICAgIFtpc05lc3RlZF09XCJ0cnVlXCIgW2lzSW5zaWRlTG9vcF09XCJ0cnVlXCIgW2lzUmVvcmRlcl09XCJpc1Jlb3JkZXJcIlxuICAgICAgICBbYWRkU3RlcEJldHdlZW5dPVwiYWRkU3RlcEJldHdlZW5cIlxuICAgICAgICBbZGF0YVByb2ZpbGVPcHRpb25zXT1cImRhdGFQcm9maWxlT3B0aW9uc1wiIFtoYXNNb3JlRGF0YVByb2ZpbGVzXT1cImhhc01vcmVEYXRhUHJvZmlsZXNcIiBbaXNMb2FkaW5nRGF0YVByb2ZpbGVzXT1cImlzTG9hZGluZ0RhdGFQcm9maWxlc1wiXG4gICAgICAgIFtuYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zXT1cIm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnNcIlxuICAgICAgICAobmVzdGVkU3RlcENoYW5nZSk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2UoJGV2ZW50LnN0ZXAsICRldmVudC5pbmRleClcIlxuICAgICAgICAoYWRkU3RlcCk9XCJvbkFkZFN0ZXAoKVwiIChkZWxldGVTdGVwKT1cIm9uRGVsZXRlU3RlcCgkZXZlbnQpXCJcbiAgICAgICAgKHRvZ2dsZUV4cGFuZGVkKT1cIm9uTmVzdGVkVG9nZ2xlRXhwYW5kZWQoJGV2ZW50LCBzdGVwLCBpKVwiXG4gICAgICAgIChncm91cE5hbWVDaGFuZ2UpPVwiJGFueShzdGVwKS5ncm91cE5hbWUgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChkZXNjcmlwdGlvbkNoYW5nZSk9XCIkYW55KHN0ZXApLmRlc2NyaXB0aW9uID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAocmV1c2FibGVDaGFuZ2UpPVwiJGFueShzdGVwKS5yZXVzYWJsZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKG9wZW5FeHRlcm5hbCk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIiAoZWRpdCk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAobGluayk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIiAoZHVwbGljYXRlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChkZWxldGUpPVwib25EZWxldGVTdGVwKGkpXCJcbiAgICAgICAgKHZpZXdEZXRhaWxzKT1cInZpZXdEZXRhaWxzLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChjb25kaXRpb25DaGFuZ2UpPVwiJGFueShzdGVwKS5jb25kaXRpb24gPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChicmFuY2hTdGVwQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChhZGRCcmFuY2gpPVwib25OZXN0ZWRDb25kaXRpb25BZGRCcmFuY2goJGFueShzdGVwKSwgaSlcIlxuICAgICAgICAoZGVsZXRlQnJhbmNoKT1cIm9uTmVzdGVkQ29uZGl0aW9uRGVsZXRlQnJhbmNoKCRhbnkoc3RlcCksICRldmVudCwgaSlcIlxuICAgICAgICAodGVzdERhdGFQcm9maWxlQ2hhbmdlKT1cIiRhbnkoc3RlcCkudGVzdERhdGFQcm9maWxlID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAoc3RhcnRTdGVwQ2hhbmdlKT1cIiRhbnkoc3RlcCkuc3RhcnRTdGVwID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAoZW5kU3RlcENoYW5nZSk9XCIkYW55KHN0ZXApLmVuZFN0ZXAgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChtYXhJdGVyYXRpb25zQ2hhbmdlKT1cIiRhbnkoc3RlcCkubWF4SXRlcmF0aW9ucyA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKGV2ZW50VHlwZUNoYW5nZSk9XCIkYW55KHN0ZXApLmV2ZW50VHlwZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKHBhcmFtZXRlckNoYW5nZSk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIiRhbnkoc3RlcCkuc2VsZWN0ZWQgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChsb2FkTW9yZURhdGFQcm9maWxlcyk9XCJsb2FkTW9yZURhdGFQcm9maWxlcy5lbWl0KCRldmVudClcIlxuICAgICAgICAoc2VhcmNoRGF0YVByb2ZpbGVzKT1cInNlYXJjaERhdGFQcm9maWxlcy5lbWl0KCRldmVudClcIlxuICAgICAgICAoZG5kRHJvcEluWm9uZSk9XCJkbmREcm9wSW5ab25lLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChjbGlja0FjdGlvbik9XCJjbGlja0FjdGlvbi5lbWl0KCRldmVudClcIlxuICAgICAgICAoZWRpdEluRGVwdGgpPVwiZWRpdEluRGVwdGguZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGFkZFN0ZXBCZXR3ZWVuQ2xpY2spPVwiYWRkU3RlcEJldHdlZW5DbGljay5lbWl0KCRldmVudClcIj5cbiAgICAgIDwvY3FhLXRlc3QtY2FzZS1kZXRhaWxzLXJlbmRlcmVyPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJpc1Jlb3JkZXJcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBuZXN0ZWQtc3RlcC1kcm9wLWxpc3RcIlxuICAgICAgICAgW2RuZERyb3B6b25lXT1cIlsnc3RlcCddXCJcbiAgICAgICAgIGRuZEVmZmVjdEFsbG93ZWQ9XCJtb3ZlXCJcbiAgICAgICAgIGRuZERyYWdvdmVyQ2xhc3M9XCJkbmREcmFnb3ZlclwiXG4gICAgICAgICAoZG5kRHJvcCk9XCJvbkRuZERyb3AoJGV2ZW50KVwiPlxuICAgICAgPGRpdiBkbmRQbGFjZWhvbGRlclJlZiBjbGFzcz1cInN0ZXAtZHJhZy1wbGFjZWhvbGRlci1uZXN0ZWQgY3FhLW15LTEgY3FhLW1pbi1oLVs1MHB4XSBjcWEtYm9yZGVyLTIgY3FhLWJvcmRlci1kYXNoZWQgY3FhLWJvcmRlci1bIzNGNDNFRV0gY3FhLXJvdW5kZWQgY3FhLWJnLVtyZ2JhKDYzLDY3LDIzOCwwLjA4KV0gY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXRleHQtWyMzRjQzRUVdIGNxYS10ZXh0LXhzXCI+RHJvcCBoZXJlPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBzdGVwIG9mIG5lc3RlZFN0ZXBzOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJuZXN0ZWQtc3RlcC1kcmFnLWl0ZW1cIlxuICAgICAgICAgICBbZG5kRHJhZ2dhYmxlXT1cInN0ZXBcIlxuICAgICAgICAgICBkbmRFZmZlY3RBbGxvd2VkPVwibW92ZVwiXG4gICAgICAgICAgIGRuZFR5cGU9XCJzdGVwXCI+XG4gICAgICAgIDxjcWEtdGVzdC1jYXNlLWRldGFpbHMtcmVuZGVyZXIgW3N0ZXBdPVwic3RlcFwiIFtpbmRleF09XCJpXCJcbiAgICAgICAgICBbc2VsZWN0ZWRdPVwiJGFueShzdGVwKS5zZWxlY3RlZFwiXG4gICAgICAgICAgW2lzTmVzdGVkXT1cInRydWVcIiBbaXNJbnNpZGVMb29wXT1cInRydWVcIiBbaXNSZW9yZGVyXT1cImlzUmVvcmRlclwiXG4gICAgICAgICAgW2FkZFN0ZXBCZXR3ZWVuQWJvdmVdPVwiYWRkU3RlcEJldHdlZW5BYm92ZVwiXG4gICAgICAgICAgW2FkZFN0ZXBCZXR3ZWVuQmVsb3ddPVwiYWRkU3RlcEJldHdlZW5CZWxvd1wiXG4gICAgICAgICAgW2FkZFN0ZXBCZXR3ZWVuXT1cImFkZFN0ZXBCZXR3ZWVuXCJcbiAgICAgICAgICBbZGF0YVByb2ZpbGVPcHRpb25zXT1cImRhdGFQcm9maWxlT3B0aW9uc1wiIFtoYXNNb3JlRGF0YVByb2ZpbGVzXT1cImhhc01vcmVEYXRhUHJvZmlsZXNcIiBbaXNMb2FkaW5nRGF0YVByb2ZpbGVzXT1cImlzTG9hZGluZ0RhdGFQcm9maWxlc1wiXG4gICAgICAgICAgW25hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnNdPVwibmF0dXJhbFRleHRBY3Rpb25zT3B0aW9uc1wiXG4gICAgICAgICAgKG5lc3RlZFN0ZXBDaGFuZ2UpPVwib25OZXN0ZWRTdGVwQ2hhbmdlKCRldmVudC5zdGVwLCAkZXZlbnQuaW5kZXgpXCJcbiAgICAgICAgICAoYWRkU3RlcCk9XCJvbkFkZFN0ZXAoKVwiIChkZWxldGVTdGVwKT1cIm9uRGVsZXRlU3RlcCgkZXZlbnQpXCJcbiAgICAgICAgICAodG9nZ2xlRXhwYW5kZWQpPVwib25OZXN0ZWRUb2dnbGVFeHBhbmRlZCgkZXZlbnQsIHN0ZXAsIGkpXCJcbiAgICAgICAgICAoZ3JvdXBOYW1lQ2hhbmdlKT1cIiRhbnkoc3RlcCkuZ3JvdXBOYW1lID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChkZXNjcmlwdGlvbkNoYW5nZSk9XCIkYW55KHN0ZXApLmRlc2NyaXB0aW9uID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChyZXVzYWJsZUNoYW5nZSk9XCIkYW55KHN0ZXApLnJldXNhYmxlID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChvcGVuRXh0ZXJuYWwpPVwib25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCIgKGVkaXQpPVwib25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAobGluayk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIiAoZHVwbGljYXRlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChkZWxldGUpPVwib25EZWxldGVTdGVwKGkpXCJcbiAgICAgICAgICAodmlld0RldGFpbHMpPVwidmlld0RldGFpbHMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAoY29uZGl0aW9uQ2hhbmdlKT1cIiRhbnkoc3RlcCkuY29uZGl0aW9uID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChicmFuY2hTdGVwQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChhZGRCcmFuY2gpPVwib25OZXN0ZWRDb25kaXRpb25BZGRCcmFuY2goJGFueShzdGVwKSwgaSlcIlxuICAgICAgICAgIChkZWxldGVCcmFuY2gpPVwib25OZXN0ZWRDb25kaXRpb25EZWxldGVCcmFuY2goJGFueShzdGVwKSwgJGV2ZW50LCBpKVwiXG4gICAgICAgICAgKHRlc3REYXRhUHJvZmlsZUNoYW5nZSk9XCIkYW55KHN0ZXApLnRlc3REYXRhUHJvZmlsZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAoc3RhcnRTdGVwQ2hhbmdlKT1cIiRhbnkoc3RlcCkuc3RhcnRTdGVwID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChlbmRTdGVwQ2hhbmdlKT1cIiRhbnkoc3RlcCkuZW5kU3RlcCA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAobWF4SXRlcmF0aW9uc0NoYW5nZSk9XCIkYW55KHN0ZXApLm1heEl0ZXJhdGlvbnMgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgICAgKGV2ZW50VHlwZUNoYW5nZSk9XCIkYW55KHN0ZXApLmV2ZW50VHlwZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAocGFyYW1ldGVyQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCIkYW55KHN0ZXApLnNlbGVjdGVkID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAobG9hZE1vcmVEYXRhUHJvZmlsZXMpPVwibG9hZE1vcmVEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHNlYXJjaERhdGFQcm9maWxlcyk9XCJzZWFyY2hEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGRuZERyb3BJblpvbmUpPVwiZG5kRHJvcEluWm9uZS5lbWl0KCRldmVudClcIlxuICAgICAgICAoY2xpY2tBY3Rpb24pPVwiY2xpY2tBY3Rpb24uZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGVkaXRJbkRlcHRoKT1cImVkaXRJbkRlcHRoLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChhZGRTdGVwQmV0d2VlbkNsaWNrKT1cImFkZFN0ZXBCZXR3ZWVuQ2xpY2suZW1pdCgkZXZlbnQpXCI+XG4gICAgICAgIDwvY3FhLXRlc3QtY2FzZS1kZXRhaWxzLXJlbmRlcmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEVORCBNYXJrZXIgLS0+XG4gICAgPGRpdlxuICAgICAgW2NsYXNzXT1cIidjcWEtcGwtNCBjcWEtcHktMSBjcWEtYmctWyNEQkVBRkU4MF0gY3FhLXRleHQtWyMxQzM5OEVdIGNxYS10ZXh0LVsxMHB4XSBjcWEtbGVhZGluZy1bMTVweF0gY3FhLWZvbnQtbWVkaXVtJ1wiXG4gICAgICBzdHlsZT1cImJvcmRlci10b3A6IDFweCBzb2xpZCAjQkVEQkZGO1wiPlxuICAgICAge3sgZ2V0RW5kTGFiZWwoKSB9fVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==
|
|
1016
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9vcC1zdGVwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvbG9vcC1zdGVwL2xvb3Atc3RlcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL2xvb3Atc3RlcC9sb29wLXN0ZXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBb0MsU0FBUyxFQUFpQyxNQUFNLGVBQWUsQ0FBQztBQUNuSixPQUFPLEVBQTBCLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR3JFLE9BQU8sRUFBK0csU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbEssT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7Ozs7O0FBaUNyRSxNQUFNLE9BQU8seUJBQXlCO0lBNkdwQyxZQUNVLEVBQWUsRUFDZixHQUFzQjtRQUR0QixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ2YsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUE1R3ZCLGFBQVEsR0FBb0IsS0FBSyxDQUFDO1FBT2xDLGdCQUFXLEdBQXlCLEVBQUUsQ0FBQztRQUN2QyxhQUFRLEdBQVksSUFBSSxDQUFDO1FBQ3pCLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFDMUIsaUJBQVksR0FBWSxLQUFLLENBQUM7UUFDOUIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUMzQixhQUFRLEdBQVksS0FBSyxDQUFDO1FBQ25DLGdGQUFnRjtRQUN2RSx1QkFBa0IsR0FBd0IsRUFBRSxDQUFDO1FBQ3RELGdFQUFnRTtRQUN2RCx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDOUMsc0NBQXNDO1FBQzdCLDBCQUFxQixHQUFZLEtBQUssQ0FBQztRQUNo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O3NCQUF0QixNQUFNO2dCQUVHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFFRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNO2dCQUVHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxlQUFlO3NCQUF4QixNQUFNO2dCQW1DNkMsa0JBQWtCO3NCQUFyRSxTQUFTO3VCQUFDLG9CQUFvQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEbmREcm9wRXZlbnQgfSBmcm9tICduZ3gtZHJhZy1kcm9wJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcbmltcG9ydCB7IExvb3BTdGVwQ29uZmlnLCBUZXN0Q2FzZVN0ZXBDb25maWcsIE5vcm1hbFN0ZXBDb25maWcsIENvbmRpdGlvblN0ZXBDb25maWcsIFN0ZXBHcm91cENvbmZpZywgQ29uZGl0aW9uQnJhbmNoLCBTdGVwVHlwZXMgfSBmcm9tICcuLi90ZXN0LWNhc2Utc3RlcC5tb2RlbHMnO1xuaW1wb3J0IHsgU1RFUF9ST1dfQUNUSU9OU19TVFlMRVMgfSBmcm9tICcuLi9zdGVwLXJvdy1hY3Rpb25zLnN0eWxlcyc7XG5pbXBvcnQgeyBEYXRhUHJvZmlsZU9wdGlvbiB9IGZyb20gJy4uLy4uL3N0ZXAtYnVpbGRlci9zdGVwLWJ1aWxkZXItbG9vcC9zdGVwLWJ1aWxkZXItbG9vcC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVmlld0RldGFpbHNQYXlsb2FkIH0gZnJvbSAnLi4vc3RlcC1kZXRhaWxzLW1vZGFsL3N0ZXAtZGV0YWlscy1tb2RhbC1kYXRhJztcbmltcG9ydCB7IENxYUF1dG9jb21wbGV0ZU9wdGlvbiB9IGZyb20gJy4uLy4uL2F1dG9jb21wbGV0ZS9hdXRvY29tcGxldGUubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtdGVzdC1jYXNlLWxvb3Atc3RlcCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9sb29wLXN0ZXAuY29tcG9uZW50Lmh0bWwnLFxuICBob3N0OiB7IGNsYXNzOiAnY3FhLXVpLXJvb3QnIH0sXG4gIHN0eWxlczogW1xuICAgIFNURVBfUk9XX0FDVElPTlNfU1RZTEVTLFxuICAgIGBcbiAgICAubG9vcC1zdGVwLWVtcHR5IHtcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuMXMgZWFzZTtcbiAgICB9XG4gICAgLmxvb3Atc3RlcC1yb3c6aG92ZXIgLmxvb3Atc3RlcC1lbXB0eSB7XG4gICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICAubG9vcC1zdGVwLWVtcHR5LWFkZCB7XG4gICAgICBwYWRkaW5nOiAwO1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBib3JkZXI6IDA7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICBjb2xvcjogIzNGNDNFRTtcbiAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMC4xNXMgZWFzZTtcbiAgICB9XG4gICAgLmxvb3Atc3RlcC1lbXB0eS1hZGQ6aG92ZXIge1xuICAgICAgb3BhY2l0eTogMC45O1xuICAgIH1cbiAgICBgLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBUZXN0Q2FzZUxvb3BTdGVwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBjb25maWchOiBMb29wU3RlcENvbmZpZztcbiAgQElucHV0KCkgaWQhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGxvb3BUeXBlOiAnZm9yJyB8ICd3aGlsZScgPSAnZm9yJztcbiAgQElucHV0KCkgc3RlcE51bWJlciE6IG51bWJlciB8IHN0cmluZztcbiAgQElucHV0KCkgY29uZGl0aW9uPzogc3RyaW5nO1xuICBASW5wdXQoKSBtYXhJdGVyYXRpb25zPzogbnVtYmVyO1xuICBASW5wdXQoKSB0ZXN0RGF0YVByb2ZpbGU/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN0YXJ0U3RlcD86IG51bWJlcjtcbiAgQElucHV0KCkgZW5kU3RlcD86IG51bWJlcjtcbiAgQElucHV0KCkgbmVzdGVkU3RlcHM6IFRlc3RDYXNlU3RlcENvbmZpZ1tdID0gW107XG4gIEBJbnB1dCgpIGV4cGFuZGVkOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgaXNOZXN0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaXNJbnNpZGVMb29wOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGlzUmVvcmRlcjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzZWxlY3RlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogT3B0aW9ucyBmb3IgdGhlIGRhdGEgcHJvZmlsZSBkcm9wZG93biAtIGFjY2VwdHMgRGF0YVByb2ZpbGVPcHRpb24gb2JqZWN0cyAqL1xuICBASW5wdXQoKSBkYXRhUHJvZmlsZU9wdGlvbnM6IERhdGFQcm9maWxlT3B0aW9uW10gPSBbXTtcbiAgLyoqIEluZGljYXRlcyBpZiBtb3JlIGRhdGEgcHJvZmlsZXMgYXJlIGF2YWlsYWJsZSBmb3IgbG9hZGluZyAqL1xuICBASW5wdXQoKSBoYXNNb3JlRGF0YVByb2ZpbGVzOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBMb2FkaW5nIHN0YXRlIGZvciBkYXRhIHByb2ZpbGVzICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZ0RhdGFQcm9maWxlczogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogT3B0aW9ucyBmb3IgbmF0dXJhbCB0ZXh0IGFjdGlvbnMgKGZvciB3aGlsZSBsb29wIGNvbmRpdGlvbikgKi9cbiAgQElucHV0KCkgbmF0dXJhbFRleHRBY3Rpb25zT3B0aW9uczogU2VsZWN0T3B0aW9uW10gPSBbXTtcbiAgLyoqIEZ1bmN0aW9uIHRvIHByb2Nlc3MgdGVtcGxhdGUgdmFyaWFibGVzIGZvciB3aGlsZSBjb25kaXRpb24gKHNhbWUgYXMgY29uZGl0aW9uLXN0ZXApICovXG4gIEBJbnB1dCgpIHNldENvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzOiAodGVtcGxhdGU6IGFueSkgPT4gYW55W10gPSAoKSA9PiBbXTtcbiAgLyoqIFNob3cgXCJBZGQgU3RlcCBCZXR3ZWVuXCIgYnV0dG9uIGFib3ZlIG5lc3RlZCBzdGVwcyAqL1xuICBASW5wdXQoKSBhZGRTdGVwQmV0d2VlbkFib3ZlOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBTaG93IFwiQWRkIFN0ZXAgQmV0d2VlblwiIGJ1dHRvbiBiZWxvdyBuZXN0ZWQgc3RlcHMgKi9cbiAgQElucHV0KCkgYWRkU3RlcEJldHdlZW5CZWxvdzogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogQGRlcHJlY2F0ZWQgVXNlIGFkZFN0ZXBCZXR3ZWVuQWJvdmUgYW5kIGFkZFN0ZXBCZXR3ZWVuQmVsb3cgaW5zdGVhZC4gSWYgc2V0LCBhcHBsaWVzIHRvIGJvdGggYnV0dG9ucy4gKi9cbiAgQElucHV0KCkgYWRkU3RlcEJldHdlZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICBAT3V0cHV0KCkgdG9nZ2xlRXhwYW5kZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHtjb25maWc6IExvb3BTdGVwQ29uZmlnLCBleHBhbmRlZDogYm9vbGVhbn0+KCk7XG4gIEBPdXRwdXQoKSB0ZXN0RGF0YVByb2ZpbGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIHN0YXJ0U3RlcENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgZW5kU3RlcENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgY29uZGl0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSBtYXhJdGVyYXRpb25zQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIEBPdXRwdXQoKSBuZXN0ZWRTdGVwQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx7IHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZzsgaW5kZXg6IG51bWJlciB9PigpO1xuICAvKiogRW1pdHMgdm9pZCB3aGVuIGFkZCBpcyBmcm9tIG5lc3RlZCBjb250ZW50OyBlbWl0cyB7IGxvb3BTdGVwQ29uZmlnIH0gd2hlbiBlbXB0eS1zdGF0ZSBhZGQgaXMgY2xpY2tlZCAoc2FtZSBiZWhhdmlvdXIgYXMgYWRkLXN0ZXAtYmV0d2VlbikuICovXG4gIEBPdXRwdXQoKSBhZGRTdGVwID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkIHwgeyBsb29wU3RlcENvbmZpZzogTG9vcFN0ZXBDb25maWcgfT4oKTtcbiAgQE91dHB1dCgpIGRlbGV0ZVN0ZXAgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIGR1cGxpY2F0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGRlbGV0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIG1vcmVPcHRpb25zID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgdmlld0RldGFpbHMgPSBuZXcgRXZlbnRFbWl0dGVyPFZpZXdEZXRhaWxzUGF5bG9hZD4oKTtcbiAgQE91dHB1dCgpIGVkaXRJbkRlcHRoID0gbmV3IEV2ZW50RW1pdHRlcjx7IHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZzsgaW5kZXg6IG51bWJlciB9PigpO1xuICBAT3V0cHV0KCkgZWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGRuZERyb3BJblpvbmUgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IERuZERyb3BFdmVudDsgdGFyZ2V0TGlzdDogVGVzdENhc2VTdGVwQ29uZmlnW10gfT4oKTtcbiAgLyoqIEVtaXQgd2hlbiBtb3JlIGRhdGEgcHJvZmlsZXMgbmVlZCB0byBiZSBsb2FkZWQgKi9cbiAgQE91dHB1dCgpIGxvYWRNb3JlRGF0YVByb2ZpbGVzID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBFbWl0IHdoZW4gZGF0YSBwcm9maWxlIHNlYXJjaCBxdWVyeSBjaGFuZ2VzICovXG4gIEBPdXRwdXQoKSBzZWFyY2hEYXRhUHJvZmlsZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIEVtaXQgd2hlbiBzdGVwIGlzIHVwZGF0ZWQgKEFwcGx5IGJ1dHRvbiBjbGlja2VkIGluIGVkaXQgbW9kZSkgKi9cbiAgQE91dHB1dCgpIHN0ZXBVcGRhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPExvb3BTdGVwQ29uZmlnPigpO1xuICAvKiogUmUtZW1pdCB3aGVuIGEgbmVzdGVkIHN0ZXAgKGUuZy4gbm9ybWFsLXN0ZXApIGVtaXRzIGNsaWNrQWN0aW9uIChlLmcuIGVsZW1lbnQvbGFiZWwgY2xpY2sgZm9yIHBvcHVwKSAqL1xuICBAT3V0cHV0KCkgY2xpY2tBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IE1vdXNlRXZlbnQ7IHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZyB9PigpO1xuICAvKiogUmUtZW1pdCBhZGRTdGVwQmV0d2VlbkNsaWNrIGZyb20gbmVzdGVkIHJlbmRlcmVycyAqL1xuICBAT3V0cHV0KCkgYWRkU3RlcEJldHdlZW5DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8e3N0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZywgaW5kZXg6IG51bWJlciwgcG9zaXRpb246ICdBQk9WRScgfCAnQkVMT1cnfT4oKTtcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICBvbkRuZERyb3AoZXZlbnQ6IERuZERyb3BFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuZG5kRHJvcEluWm9uZS5lbWl0KHsgZXZlbnQsIHRhcmdldExpc3Q6IHRoaXMubmVzdGVkU3RlcHMgfSk7XG4gIH1cblxuICAvKiogRXhwb3NlIGdsb2JhbCBjb25zdHJ1Y3RvcnMgZm9yIHRlbXBsYXRlIChBbmd1bGFyIHRlbXBsYXRlcyBkb24ndCBoYXZlIFN0cmluZy9OdW1iZXIpICovXG4gIHJlYWRvbmx5IHN0cmluZ0ZuID0gU3RyaW5nO1xuICByZWFkb25seSBudW1iZXJGbiA9IE51bWJlcjtcblxuICAvKiogV2hlbiB0cnVlLCBoZWFkZXIgc2hvd3MgaW5saW5lIGVkaXQgZm9ybSAoZHJvcGRvd25zLCBpbnB1dHMsIENhbmNlbC9BcHBseSkgKi9cbiAgaXNFZGl0aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIEZvcm0gZm9yIGVkaXQgbW9kZTsgYm91bmQgdG8gY3FhLWR5bmFtaWMtc2VsZWN0IChzYW1lIHBhdHRlcm4gYXMgZGVmYXVsdCBzdG9yaWVzKSAqL1xuICBlZGl0Rm9ybSE6IEZvcm1Hcm91cDtcblxuICAvKiogQ2FjaGVkIHNlbGVjdCBjb25maWdzIChzdGFibGUgcmVmcyB0byBhdm9pZCBjaGFuZ2UtZGV0ZWN0aW9uIGxvb3BzKSAqL1xuICBmb3JPcHRpb25UeXBlU2VsZWN0Q29uZmlnITogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnO1xuICB0ZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWchOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWc7XG4gIHN0YXJ0U3RlcFNlbGVjdENvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcbiAgZW5kU3RlcFNlbGVjdENvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcbiAgY29uZGl0aW9uU2VsZWN0Q29uZmlnITogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnO1xuICAvKiogV2hpbGUgbG9vcDogY29uZmlnIGZvciBhdXRvY29tcGxldGUgb3B0aW9ucyAoV0hJTEVfQ09ORElUSU9OIG9ubHkpICovXG4gIHdoaWxlQ29uZGl0aW9uU2VsZWN0Q29uZmlnITogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnO1xuXG4gIC8qKiBTZWxlY3RlZCB0ZW1wbGF0ZSBmb3Igd2hpbGUgY29uZGl0aW9uIChzYW1lIHBhdHRlcm4gYXMgY29uZGl0aW9uLXN0ZXApICovXG4gIHNlbGVjdGVkVGVtcGxhdGU6IGFueSA9IG51bGw7XG4gIC8qKiBUZW1wbGF0ZSB2YXJpYWJsZXMgZm9yIHdoaWxlIGNvbmRpdGlvbiAqL1xuICB0ZW1wbGF0ZVZhcmlhYmxlczogYW55W10gPSBbXTtcbiAgLyoqIEZvcm0gZ3JvdXAgZm9yIHRlbXBsYXRlIHZhcmlhYmxlcyAqL1xuICB0ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0hOiBGb3JtR3JvdXA7XG5cbiAgLyoqIE9wdGlvbnMgZm9yIExvb3AgU3RhcnQgLyBMb29wIEVuZCBkcm9wZG93bnMgKDEtMTApICovXG4gIGxvb3BTdGVwT3B0aW9uczogbnVtYmVyW10gPSBbMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTBdO1xuXG4gIEBWaWV3Q2hpbGQoJ3ZpZXdEZXRhaWxzVHJpZ2dlcicsIHsgc3RhdGljOiBmYWxzZSB9KSB2aWV3RGV0YWlsc1RyaWdnZXI/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAvKiogTG9jYWwgY29weSBvZiB2YWx1ZXMgd2hpbGUgZWRpdGluZyAoZm9yIENhbmNlbCByZXZlcnQpICovXG4gIHByaXZhdGUgZWRpdFNuYXBzaG90OiB7XG4gICAgdGVzdERhdGFQcm9maWxlPzogc3RyaW5nO1xuICAgIHN0YXJ0U3RlcD86IG51bWJlcjtcbiAgICBlbmRTdGVwPzogbnVtYmVyO1xuICAgIGNvbmRpdGlvbj86IHN0cmluZztcbiAgICBtYXhJdGVyYXRpb25zPzogbnVtYmVyO1xuICAgIHNlbGVjdGVkVGVtcGxhdGU/OiBhbnk7XG4gICAgdGVtcGxhdGVWYXJpYWJsZXM/OiBhbnlbXTtcbiAgICBjb25kaXRpb25UZW1wbGF0ZUZvcm1WYWx1ZT86IGFueTtcbiAgfSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnKSB7XG4gICAgICB0aGlzLmlkID0gdGhpcy5jb25maWcuaWQ7XG4gICAgICB0aGlzLmxvb3BUeXBlID0gdGhpcy5jb25maWcubG9vcFR5cGU7XG4gICAgICB0aGlzLnN0ZXBOdW1iZXIgPSB0aGlzLmNvbmZpZy5zdGVwTnVtYmVyO1xuICAgICAgdGhpcy5jb25kaXRpb24gPSB0aGlzLmNvbmZpZy5jb25kaXRpb247XG4gICAgICB0aGlzLm1heEl0ZXJhdGlvbnMgPSB0aGlzLmNvbmZpZy5tYXhJdGVyYXRpb25zO1xuICAgICAgdGhpcy50ZXN0RGF0YVByb2ZpbGUgPSB0aGlzLmNvbmZpZy50ZXN0RGF0YVByb2ZpbGU7XG4gICAgICB0aGlzLnN0YXJ0U3RlcCA9IHRoaXMuY29uZmlnLnN0YXJ0U3RlcDtcbiAgICAgIHRoaXMuZW5kU3RlcCA9IHRoaXMuY29uZmlnLmVuZFN0ZXA7XG4gICAgICB0aGlzLm5lc3RlZFN0ZXBzID0gdGhpcy5jb25maWcubmVzdGVkU3RlcHMgfHwgW107XG4gICAgICB0aGlzLmV4cGFuZGVkID0gdGhpcy5jb25maWcuZXhwYW5kZWQgIT09IHVuZGVmaW5lZCA/IHRoaXMuY29uZmlnLmV4cGFuZGVkIDogdHJ1ZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSAodGhpcy5jb25maWcgYXMgYW55KS5zZWxlY3RlZCB8fCBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5idWlsZEVkaXRGb3JtKCk7XG4gICAgdGhpcy5idWlsZFNlbGVjdENvbmZpZ3MoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29uZmlnJ10gJiYgdGhpcy5jb25maWcpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSAodGhpcy5jb25maWcgYXMgYW55KS5zZWxlY3RlZCB8fCBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmxvb3BUeXBlID09PSAnd2hpbGUnKSB7XG4gICAgICAgIHRoaXMucmVidWlsZFdoaWxlQ29uZGl0aW9uRnJvbU5hdHVyYWxUZXh0QWN0aW9uKCk7XG4gICAgICB9XG4gICAgICAvLyBGT1IgbG9vcDogd2hlbiBzdGVwIGNvbmZpZyBoYXMgZm9yTG9vcFRlc3REYXRhSWQvZm9yTG9vcFN0YXJ0SW5kZXgvZm9yTG9vcEVuZEluZGV4LCBzeW5jIGZvcm0gYW5kIHJlZnJlc2ggc2VsZWN0IGNvbmZpZ3Mgc28gZHJvcGRvd25zIHNob3cgc2VsZWN0ZWRcbiAgICAgIGlmICh0aGlzLmxvb3BUeXBlID09PSAnZm9yJykge1xuICAgICAgICB0aGlzLnVwZGF0ZUZvckxvb3BTZWxlY3RDb25maWdzU2VsZWN0ZWRWYWx1ZXMoKTtcbiAgICAgICAgaWYgKHRoaXMuZWRpdEZvcm0pIHRoaXMuc3luY0Zvckxvb3BFZGl0Rm9ybUZyb21Db25maWcoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snZGF0YVByb2ZpbGVPcHRpb25zJ10gfHwgY2hhbmdlc1snaGFzTW9yZURhdGFQcm9maWxlcyddIHx8IGNoYW5nZXNbJ2lzTG9hZGluZ0RhdGFQcm9maWxlcyddKSB7XG4gICAgICB0aGlzLnVwZGF0ZVRlc3REYXRhUHJvZmlsZVNlbGVjdENvbmZpZygpO1xuICAgICAgLy8gV2hlbiBkYXRhIHByb2ZpbGVzIGxvYWQgaW4gZWRpdCBtb2RlLCBzeW5jIGZvcm0gdmFsdWUgc28gZHJvcGRvd24gc2hvd3Mgc2VsZWN0ZWQgKGZvckxvb3BUZXN0RGF0YUlkIG9yIHRlc3REYXRhUHJvZmlsZSlcbiAgICAgIGlmICh0aGlzLmxvb3BUeXBlID09PSAnZm9yJyAmJiB0aGlzLmVkaXRGb3JtICYmIHRoaXMuZGF0YVByb2ZpbGVPcHRpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgICAgICBpZiAoY2ZnPy5mb3JMb29wVGVzdERhdGFJZCAhPSBudWxsIHx8IHRoaXMudGVzdERhdGFQcm9maWxlKSB0aGlzLnN5bmNGb3JMb29wRWRpdEZvcm1Gcm9tQ29uZmlnKCk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ25hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnMnXSkge1xuICAgICAgdGhpcy51cGRhdGVDb25kaXRpb25TZWxlY3RDb25maWcoKTtcbiAgICAgIC8vIFdoZW4gb3B0aW9ucyBsb2FkLCBwb3B1bGF0ZSBjb25kaXRpb24gKyB0ZW1wbGF0ZSBmcm9tIG5hdHVyYWxUZXh0QWN0aW9uSWQgKHNhbWUgYXMgY29uZGl0aW9uLXN0ZXApXG4gICAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJyAmJiB0aGlzLmVkaXRGb3JtICYmIHRoaXMubmF0dXJhbFRleHRBY3Rpb25zT3B0aW9ucz8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucmVidWlsZFdoaWxlQ29uZGl0aW9uRnJvbU5hdHVyYWxUZXh0QWN0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIERlcml2ZSBmb3JPcHRpb25UeXBlIGZvciBGT1IgbG9vcCBmcm9tIGNvbmZpZyBzbyBkcm9wZG93biBzaG93cyBleGlzdGluZyBzZWxlY3Rpb24gKi9cbiAgcHJpdmF0ZSBnZXRGb3JPcHRpb25UeXBlRnJvbUNvbmZpZygpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAodGhpcy5sb29wVHlwZSAhPT0gJ2ZvcicpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGNmZyA9IHRoaXMuY29uZmlnIGFzIGFueTtcbiAgICBjb25zdCBoYXNUZXN0RGF0YUlkID0gY2ZnPy5mb3JMb29wVGVzdERhdGFJZCAhPSBudWxsIHx8IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BUZXN0RGF0YUlkICE9IG51bGwgfHwgY2ZnPy5kYXRhTWFwQmVhbj8uZm9yX2xvb3A/LnRlc3REYXRhSWQgIT0gbnVsbDtcbiAgICBpZiAoaGFzVGVzdERhdGFJZCB8fCB0aGlzLnRlc3REYXRhUHJvZmlsZSkgcmV0dXJuICd0ZXN0LWRhdGEnO1xuICAgIGNvbnN0IGhhc0ZpeGVkID0gY2ZnPy5mb3JMb29wU3RhcnRJbmRleCAhPSBudWxsIHx8IGNmZz8uZm9yTG9vcEVuZEluZGV4ICE9IG51bGxcbiAgICAgIHx8IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BTdGFydEluZGV4ICE9IG51bGwgfHwgY2ZnPy5kYXRhTWFwSnNvbj8uZm9yTG9vcEVuZEluZGV4ICE9IG51bGxcbiAgICAgIHx8IGNmZz8uZGF0YU1hcEJlYW4/LmZvcl9sb29wPy5zdGFydEluZGV4ICE9IG51bGwgfHwgY2ZnPy5kYXRhTWFwQmVhbj8uZm9yX2xvb3A/LmVuZEluZGV4ICE9IG51bGw7XG4gICAgaWYgKHRoaXMuc3RhcnRTdGVwICE9IG51bGwgfHwgdGhpcy5lbmRTdGVwICE9IG51bGwgfHwgaGFzRml4ZWQpIHJldHVybiAnZml4ZWQnO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqIFRlc3QgRGF0YSBQcm9maWxlIGRyb3Bkb3duIHZhbHVlOiBwcmVmZXIgZm9yTG9vcFRlc3REYXRhSWQgZnJvbSBjb25maWcgKG9yIGRhdGFNYXBKc29uL2RhdGFNYXBCZWFuKS4gVXNlIG9wdGlvbi5pZCB3aGVuIG9wdGlvbnMgbG9hZGVkIHNvIHR5cGUgbWF0Y2hlcyBzZWxlY3QuICovXG4gIHByaXZhdGUgZ2V0VGVzdERhdGFQcm9maWxlRm9ybVZhbHVlKCk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IGlkRnJvbUNvbmZpZyA9IGNmZz8uZm9yTG9vcFRlc3REYXRhSWQgPz8gY2ZnPy5kYXRhTWFwSnNvbj8uZm9yTG9vcFRlc3REYXRhSWQgPz8gY2ZnPy5kYXRhTWFwQmVhbj8uZm9yX2xvb3A/LnRlc3REYXRhSWQ7XG4gICAgLy8gV2hlbiB3ZSBoYXZlIG9wdGlvbnMsIHJlc29sdmUgYnkgaWQgc28gZm9ybSB2YWx1ZSBtYXRjaGVzIG9wdGlvbi5pZCAoc3RyaWN0IGVxdWFsaXR5IGluIGR5bmFtaWMtc2VsZWN0KVxuICAgIGlmICh0aGlzLmxvb3BUeXBlID09PSAnZm9yJyAmJiB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucz8ubGVuZ3RoKSB7XG4gICAgICBpZiAoaWRGcm9tQ29uZmlnICE9IG51bGwpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucy5maW5kKFxuICAgICAgICAgIG8gPT4gby5pZCA9PT0gaWRGcm9tQ29uZmlnIHx8IFN0cmluZyhvLmlkKSA9PT0gU3RyaW5nKGlkRnJvbUNvbmZpZylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG1hdGNoKSByZXR1cm4gbWF0Y2guaWQ7XG4gICAgICAgIHJldHVybiBpZEZyb21Db25maWcgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgICAgfVxuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnRlc3REYXRhUHJvZmlsZSA/PyAnJztcbiAgICAgIGlmICh2YWx1ZSAhPT0gJycpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucy5maW5kKFxuICAgICAgICAgIG8gPT4gby5uYW1lID09PSB2YWx1ZSB8fCBTdHJpbmcoby5pZCkgPT09IFN0cmluZyh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG1hdGNoKSByZXR1cm4gbWF0Y2guaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWUgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgIH1cbiAgICBpZiAoaWRGcm9tQ29uZmlnICE9IG51bGwpIHJldHVybiBpZEZyb21Db25maWcgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgIHJldHVybiAodGhpcy50ZXN0RGF0YVByb2ZpbGUgPz8gJycpIGFzIHN0cmluZyB8IG51bWJlcjtcbiAgfVxuXG4gIC8qKiBMb29wIFN0YXJ0IGRyb3Bkb3duIHZhbHVlOiBwcmVmZXIgZm9yTG9vcFN0YXJ0SW5kZXggZnJvbSBjb25maWcgKG9yIGRhdGFNYXBKc29uL2RhdGFNYXBCZWFuKSwgZWxzZSBzdGFydFN0ZXAgKi9cbiAgcHJpdmF0ZSBnZXRMb29wU3RhcnRGb3JtVmFsdWUoKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IHYgPSBjZmc/LmZvckxvb3BTdGFydEluZGV4ID8/IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BTdGFydEluZGV4ID8/IGNmZz8uZGF0YU1hcEJlYW4/LmZvcl9sb29wPy5zdGFydEluZGV4O1xuICAgIGlmICh2ICE9IG51bGwpIHJldHVybiBOdW1iZXIodik7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRTdGVwID8/IG51bGw7XG4gIH1cblxuICAvKiogTG9vcCBFbmQgZHJvcGRvd24gdmFsdWU6IHByZWZlciBmb3JMb29wRW5kSW5kZXggZnJvbSBjb25maWcgKG9yIGRhdGFNYXBKc29uL2RhdGFNYXBCZWFuKSwgZWxzZSBlbmRTdGVwICovXG4gIHByaXZhdGUgZ2V0TG9vcEVuZEZvcm1WYWx1ZSgpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBjZmcgPSB0aGlzLmNvbmZpZyBhcyBhbnk7XG4gICAgY29uc3QgdiA9IGNmZz8uZm9yTG9vcEVuZEluZGV4ID8/IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BFbmRJbmRleCA/PyBjZmc/LmRhdGFNYXBCZWFuPy5mb3JfbG9vcD8uZW5kSW5kZXg7XG4gICAgaWYgKHYgIT0gbnVsbCkgcmV0dXJuIE51bWJlcih2KTtcbiAgICByZXR1cm4gdGhpcy5lbmRTdGVwID8/IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRWRpdEZvcm0oKTogdm9pZCB7XG4gICAgLy8gRm9yIHdoaWxlIGxvb3A6IGlmIGNvbmZpZyBoYXMgbmF0dXJhbFRleHRBY3Rpb25JZCBhbmQgb3B0aW9ucyBhcmUgYWxyZWFkeSBsb2FkZWQsIHVzZSB0aGVtIGZvciBpbml0aWFsIGNvbmRpdGlvbiArIHRlbXBsYXRlXG4gICAgbGV0IGNvbmRpdGlvblZhbHVlID0gdGhpcy5jb25kaXRpb24gPz8gJyc7XG4gICAgaWYgKHRoaXMubG9vcFR5cGUgPT09ICd3aGlsZScpIHtcbiAgICAgIGNvbnN0IHBvcHVsYXRlZCA9IHRoaXMucG9wdWxhdGVXaGlsZUNvbmRpdGlvbkZyb21OYXR1cmFsVGV4dEFjdGlvbklkKCk7XG4gICAgICBpZiAocG9wdWxhdGVkPy5jb25kaXRpb24gIT0gbnVsbCkge1xuICAgICAgICBjb25kaXRpb25WYWx1ZSA9IHBvcHVsYXRlZC5jb25kaXRpb247XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEZvciBGT1IgbG9vcDogaW5pdGlhbCBmb3JtIHZhbHVlcyBzbyBkcm9wZG93bnMgc2hvdyBleGlzdGluZyBzZWxlY3Rpb24gKGZvck9wdGlvblR5cGUsIGZvckxvb3BUZXN0RGF0YUlkL3Rlc3REYXRhUHJvZmlsZSwgZm9yTG9vcFN0YXJ0SW5kZXgvZm9yTG9vcEVuZEluZGV4KVxuICAgIGNvbnN0IGZvck9wdGlvblR5cGUgPSB0aGlzLmdldEZvck9wdGlvblR5cGVGcm9tQ29uZmlnKCk7XG4gICAgY29uc3QgdGVzdERhdGFQcm9maWxlVmFsdWUgPSB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/IHRoaXMuZ2V0VGVzdERhdGFQcm9maWxlRm9ybVZhbHVlKCkgOiAodGhpcy50ZXN0RGF0YVByb2ZpbGUgPz8gJycpO1xuICAgIGNvbnN0IGxvb3BTdGFydFZhbHVlID0gdGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicgPyB0aGlzLmdldExvb3BTdGFydEZvcm1WYWx1ZSgpIDogKHRoaXMuc3RhcnRTdGVwID8/IG51bGwpO1xuICAgIGNvbnN0IGxvb3BFbmRWYWx1ZSA9IHRoaXMubG9vcFR5cGUgPT09ICdmb3InID8gdGhpcy5nZXRMb29wRW5kRm9ybVZhbHVlKCkgOiAodGhpcy5lbmRTdGVwID8/IG51bGwpO1xuICAgIHRoaXMuZWRpdEZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGZvck9wdGlvblR5cGU6IFtmb3JPcHRpb25UeXBlIGFzIHN0cmluZyB8IG51bGxdLFxuICAgICAgdGVzdERhdGFQcm9maWxlOiBbdGVzdERhdGFQcm9maWxlVmFsdWVdLFxuICAgICAgc3RhcnRTdGVwOiBbbG9vcFN0YXJ0VmFsdWUgYXMgbnVtYmVyIHwgbnVsbF0sXG4gICAgICBlbmRTdGVwOiBbbG9vcEVuZFZhbHVlIGFzIG51bWJlciB8IG51bGxdLFxuICAgICAgY29uZGl0aW9uOiBbY29uZGl0aW9uVmFsdWVdLFxuICAgICAgbWF4SXRlcmF0aW9uczogW3RoaXMubWF4SXRlcmF0aW9ucyA/PyA1XSxcbiAgICB9KTtcbiAgICBpZiAoIXRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtKSB7XG4gICAgICB0aGlzLnRlbXBsYXRlVmFyaWFibGVzRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe30pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQb3B1bGF0ZSBjb25kaXRpb24sIHNlbGVjdGVkVGVtcGxhdGUgYW5kIHRlbXBsYXRlIHZhcmlhYmxlcyBmcm9tIGNvbmZpZy5uYXR1cmFsVGV4dEFjdGlvbklkIHdoZW4gb3B0aW9ucyBhcmUgYXZhaWxhYmxlLlxuICAgKiBSZXR1cm5zIHsgY29uZGl0aW9uIH0gaWYgYSBtYXRjaCB3YXMgZm91bmQgc28gYnVpbGRFZGl0Rm9ybSBjYW4gc2V0IGluaXRpYWwgZm9ybSB2YWx1ZS5cbiAgICovXG4gIHByaXZhdGUgcG9wdWxhdGVXaGlsZUNvbmRpdGlvbkZyb21OYXR1cmFsVGV4dEFjdGlvbklkKCk6IHsgY29uZGl0aW9uOiBzdHJpbmcgfSB8IG51bGwge1xuICAgIGNvbnN0IGNvbmZpZ1dpdGhJZCA9IHRoaXMuY29uZmlnIGFzIGFueTtcbiAgICBpZiAoIWNvbmZpZ1dpdGhJZD8ubmF0dXJhbFRleHRBY3Rpb25JZCB8fCAhdGhpcy5uYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBtYXRjaGluZ09wdGlvbiA9ICh0aGlzLm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnMgYXMgYW55W10pLmZpbmQoXG4gICAgICAob3B0aW9uOiBhbnkpID0+IFN0cmluZyhvcHRpb24uaWQpID09PSBTdHJpbmcoY29uZmlnV2l0aElkLm5hdHVyYWxUZXh0QWN0aW9uSWQpXG4gICAgKTtcbiAgICBpZiAoIW1hdGNoaW5nT3B0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgbmF0dXJhbFRleHQgPSBtYXRjaGluZ09wdGlvbi5uYXR1cmFsVGV4dCA/PyBtYXRjaGluZ09wdGlvbi5uYW1lID8/IG1hdGNoaW5nT3B0aW9uLnZhbHVlID8/ICcnO1xuICAgIGlmICghbmF0dXJhbFRleHQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0aGlzLmNvbmRpdGlvbiA9IG5hdHVyYWxUZXh0O1xuICAgIGNvbnN0IGZ1bGxUZW1wbGF0ZSA9IG1hdGNoaW5nT3B0aW9uLnRlbXBsYXRlIHx8IG1hdGNoaW5nT3B0aW9uO1xuICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZSA9IGZ1bGxUZW1wbGF0ZTtcbiAgICBpZiAoZnVsbFRlbXBsYXRlPy52YXJpYWJsZXMpIHtcbiAgICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXMgPSB0aGlzLnNldENvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzKGZ1bGxUZW1wbGF0ZSkgfHwgW107XG4gICAgICB0aGlzLmJ1aWxkVGVtcGxhdGVWYXJpYWJsZXNGb3JtKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHJldHVybiB7IGNvbmRpdGlvbjogbmF0dXJhbFRleHQgfTtcbiAgfVxuXG4gIC8qKiBSZWJ1aWxkIGNvbmRpdGlvbiArIHRlbXBsYXRlIHN0YXRlIHdoZW4gbmF0dXJhbFRleHRBY3Rpb25zT3B0aW9ucyBsb2FkIG9yIGNvbmZpZyBjaGFuZ2VzIChzYW1lIGFzIGNvbmRpdGlvbi1zdGVwKS4gKi9cbiAgcHJpdmF0ZSByZWJ1aWxkV2hpbGVDb25kaXRpb25Gcm9tTmF0dXJhbFRleHRBY3Rpb24oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRGb3JtIHx8IHRoaXMubG9vcFR5cGUgIT09ICd3aGlsZScpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnV2l0aElkID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGlmICghY29uZmlnV2l0aElkPy5uYXR1cmFsVGV4dEFjdGlvbklkIHx8ICF0aGlzLm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnM/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtYXRjaGluZ09wdGlvbiA9ICh0aGlzLm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnMgYXMgYW55W10pLmZpbmQoXG4gICAgICAob3B0aW9uOiBhbnkpID0+IFN0cmluZyhvcHRpb24uaWQpID09PSBTdHJpbmcoY29uZmlnV2l0aElkLm5hdHVyYWxUZXh0QWN0aW9uSWQpXG4gICAgKTtcbiAgICBpZiAoIW1hdGNoaW5nT3B0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5hdHVyYWxUZXh0ID0gbWF0Y2hpbmdPcHRpb24ubmF0dXJhbFRleHQgPz8gbWF0Y2hpbmdPcHRpb24ubmFtZSA/PyBtYXRjaGluZ09wdGlvbi52YWx1ZSA/PyAnJztcbiAgICBpZiAobmF0dXJhbFRleHQpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuZWRpdEZvcm0uZ2V0KCdjb25kaXRpb24nKT8udmFsdWUgPz8gJyc7XG4gICAgICBpZiAoIWN1cnJlbnRWYWx1ZSB8fCBjdXJyZW50VmFsdWUgIT09IG5hdHVyYWxUZXh0KSB7XG4gICAgICAgIHRoaXMuZWRpdEZvcm0uZ2V0KCdjb25kaXRpb24nKT8uc2V0VmFsdWUobmF0dXJhbFRleHQpO1xuICAgICAgfVxuICAgICAgdGhpcy5jb25kaXRpb24gPSBuYXR1cmFsVGV4dDtcbiAgICB9XG4gICAgY29uc3QgZnVsbFRlbXBsYXRlID0gbWF0Y2hpbmdPcHRpb24udGVtcGxhdGUgfHwgbWF0Y2hpbmdPcHRpb247XG4gICAgdGhpcy5zZWxlY3RlZFRlbXBsYXRlID0gZnVsbFRlbXBsYXRlO1xuICAgIGlmIChmdWxsVGVtcGxhdGU/LnZhcmlhYmxlcykge1xuICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlcyA9IHRoaXMuc2V0Q29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMoZnVsbFRlbXBsYXRlKSB8fCBbXTtcbiAgICAgIHRoaXMuYnVpbGRUZW1wbGF0ZVZhcmlhYmxlc0Zvcm0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlcyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKiogQnVpbGQgc2VsZWN0IGNvbmZpZ3Mgb25jZSAoc2FtZSBvcHRpb24gc2hhcGUgYXMgZGVmYXVsdCBzdG9yaWVzOiBpZCArIG5hbWUpOyBGT1IgbG9vcCBhZGRzIHNlbGVjdGVkVmFsdWUgZnJvbSBzdGVwICovXG4gIHByaXZhdGUgYnVpbGRTZWxlY3RDb25maWdzKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0ZXBPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IHRoaXMubG9vcFN0ZXBPcHRpb25zLm1hcCgobikgPT4gKHtcbiAgICAgIGlkOiBuLFxuICAgICAgdmFsdWU6IG4sXG4gICAgICBuYW1lOiBTdHJpbmcobiksXG4gICAgICBsYWJlbDogU3RyaW5nKG4pLFxuICAgIH0pKTtcbiAgICB0aGlzLmZvck9wdGlvblR5cGVTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdmb3JPcHRpb25UeXBlJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IG9wdGlvbicsXG4gICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgeyBpZDogJ3Rlc3QtZGF0YScsIHZhbHVlOiAndGVzdC1kYXRhJywgbmFtZTogJ1Rlc3QgRGF0YSBQcm9maWxlJywgbGFiZWw6ICdUZXN0IERhdGEgUHJvZmlsZScgfSxcbiAgICAgICAgeyBpZDogJ2ZpeGVkJywgdmFsdWU6ICdmaXhlZCcsIG5hbWU6ICdGaXhlZCBjb3VudCcsIGxhYmVsOiAnRml4ZWQgY291bnQnIH0sXG4gICAgICBdLFxuICAgIH07XG4gICAgdGhpcy51cGRhdGVUZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWcoKTtcbiAgICBjb25zdCBzdGFydFZhbCA9IHRoaXMubG9vcFR5cGUgPT09ICdmb3InID8gdGhpcy5nZXRMb29wU3RhcnRGb3JtVmFsdWUoKSA6IG51bGw7XG4gICAgY29uc3QgZW5kVmFsID0gdGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicgPyB0aGlzLmdldExvb3BFbmRGb3JtVmFsdWUoKSA6IG51bGw7XG4gICAgdGhpcy5zdGFydFN0ZXBTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdzdGFydFN0ZXAnLFxuICAgICAgcGxhY2Vob2xkZXI6ICdMb29wIFN0YXJ0JyxcbiAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgb3B0aW9uczogc3RlcE9wdGlvbnMubWFwKChvKSA9PiAoeyAuLi5vIH0pKSxcbiAgICAgIC4uLihzdGFydFZhbCAhPSBudWxsICYmIHsgc2VsZWN0ZWRWYWx1ZTogc3RhcnRWYWwgfSksXG4gICAgfTtcbiAgICB0aGlzLmVuZFN0ZXBTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdlbmRTdGVwJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnTG9vcCBFbmQnLFxuICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICBvcHRpb25zOiBzdGVwT3B0aW9ucy5tYXAoKG8pID0+ICh7IC4uLm8gfSkpLFxuICAgICAgLi4uKGVuZFZhbCAhPSBudWxsICYmIHsgc2VsZWN0ZWRWYWx1ZTogZW5kVmFsIH0pLFxuICAgIH07XG4gICAgdGhpcy51cGRhdGVDb25kaXRpb25TZWxlY3RDb25maWcoKTtcbiAgfVxuXG4gIC8qKiBVcGRhdGUgY29uZGl0aW9uIHNlbGVjdCBjb25maWcgd2l0aCBuYXR1cmFsIHRleHQgYWN0aW9ucyBvcHRpb25zIChsZWdhY3kgbWF0LXNlbGVjdCkgKi9cbiAgcHJpdmF0ZSB1cGRhdGVDb25kaXRpb25TZWxlY3RDb25maWcoKTogdm9pZCB7XG4gICAgdGhpcy5jb25kaXRpb25TZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdjb25kaXRpb24nLFxuICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgY29uZGl0aW9uJyxcbiAgICAgIHNlYXJjaGFibGU6IHRydWUsXG4gICAgICBvcHRpb25zOiB0aGlzLm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnMgfHwgW10sXG4gICAgfTtcbiAgICB0aGlzLnVwZGF0ZVdoaWxlQ29uZGl0aW9uU2VsZWN0Q29uZmlnKCk7XG4gIH1cblxuICAvKiogV2hpbGUgbG9vcDogb25seSBzaG93IG9wdGlvbnMgd2l0aCBzdGVwQWN0aW9uVHlwZSA9PT0gXCJXSElMRV9MT09QXCIgKi9cbiAgcHJpdmF0ZSB1cGRhdGVXaGlsZUNvbmRpdGlvblNlbGVjdENvbmZpZygpOiB2b2lkIHtcbiAgICBjb25zdCBmaWx0ZXJlZE9wdGlvbnMgPSAodGhpcy5uYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zIHx8IFtdKS5maWx0ZXIoKG9wdGlvbjogYW55KSA9PiB7XG4gICAgICByZXR1cm4gb3B0aW9uLnN0ZXBBY3Rpb25UeXBlID09PSAnV0hJTEVfTE9PUCc7XG4gICAgfSk7XG4gICAgdGhpcy53aGlsZUNvbmRpdGlvblNlbGVjdENvbmZpZyA9IHtcbiAgICAgIGtleTogJ2NvbmRpdGlvbicsXG4gICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBjb25kaXRpb24nLFxuICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgIG9wdGlvbnM6IGZpbHRlcmVkT3B0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgLyoqIE9wdGlvbnMgZm9yIHRoZSB3aGlsZSBjb25kaXRpb24gYXV0b2NvbXBsZXRlIChXSElMRV9MT09QIG5hdHVyYWwgdGV4dCBhY3Rpb25zIG9ubHkpICovXG4gIGdldCB3aGlsZUNvbmRpdGlvbkF1dG9jb21wbGV0ZU9wdGlvbnMoKTogKENxYUF1dG9jb21wbGV0ZU9wdGlvbiAmIHsgdGVtcGxhdGU/OiBhbnkgfSlbXSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMud2hpbGVDb25kaXRpb25TZWxlY3RDb25maWc/Lm9wdGlvbnMgPz8gW107XG4gICAgcmV0dXJuIG9wdHMubWFwKChvcHRpb246IGFueSkgPT4ge1xuICAgICAgY29uc3QgbmF0dXJhbFRleHQgPSBvcHRpb24ubmF0dXJhbFRleHQgPz8gb3B0aW9uLm5hbWUgPz8gb3B0aW9uLnZhbHVlID8/IFN0cmluZyhvcHRpb24uaWQgPz8gJycpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IG5hdHVyYWxUZXh0LFxuICAgICAgICBsYWJlbDogbmF0dXJhbFRleHQsXG4gICAgICAgIHRlbXBsYXRlOiBvcHRpb24udGVtcGxhdGUgfHwgb3B0aW9uLFxuICAgICAgfSBhcyBDcWFBdXRvY29tcGxldGVPcHRpb24gJiB7IHRlbXBsYXRlPzogYW55IH07XG4gICAgfSk7XG4gIH1cblxuICBvbkNvbmRpdGlvblNlbGVjdChvcHRpb246IENxYUF1dG9jb21wbGV0ZU9wdGlvbiAmIHsgdGVtcGxhdGU/OiBhbnkgfSk6IHZvaWQge1xuICAgIHRoaXMuZWRpdEZvcm0/LmdldCgnY29uZGl0aW9uJyk/LnNldFZhbHVlKG9wdGlvbi52YWx1ZSk7XG4gICAgY29uc3QgbWF0Y2hpbmdUZW1wbGF0ZSA9IG9wdGlvbi50ZW1wbGF0ZTtcbiAgICBsZXQgZnVsbFRlbXBsYXRlID0gbWF0Y2hpbmdUZW1wbGF0ZTtcbiAgICBpZiAoIWZ1bGxUZW1wbGF0ZSB8fCAhZnVsbFRlbXBsYXRlLnZhcmlhYmxlcykge1xuICAgICAgY29uc3QgbWF0Y2hpbmdPcHRpb24gPSAodGhpcy5uYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zIHx8IFtdKS5maW5kKFxuICAgICAgICAob3B0OiBhbnkpID0+IG9wdC5uYXR1cmFsVGV4dCA9PT0gb3B0aW9uLnZhbHVlIHx8IG9wdC5uYW1lID09PSBvcHRpb24udmFsdWUgfHwgb3B0LnZhbHVlID09PSBvcHRpb24udmFsdWVcbiAgICAgICkgYXMgYW55O1xuICAgICAgZnVsbFRlbXBsYXRlID0gbWF0Y2hpbmdPcHRpb24/LnRlbXBsYXRlIHx8IG1hdGNoaW5nT3B0aW9uO1xuICAgIH1cbiAgICBpZiAoZnVsbFRlbXBsYXRlICYmIGZ1bGxUZW1wbGF0ZS52YXJpYWJsZXMpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZSA9IGZ1bGxUZW1wbGF0ZTtcbiAgICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXMgPSB0aGlzLnNldENvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzKGZ1bGxUZW1wbGF0ZSkgfHwgW107XG4gICAgICB0aGlzLmJ1aWxkVGVtcGxhdGVWYXJpYWJsZXNGb3JtKCk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZSA9IG51bGw7XG4gICAgICB0aGlzLnRlbXBsYXRlVmFyaWFibGVzID0gW107XG4gICAgICBpZiAoIXRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtKSB7XG4gICAgICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtID0gdGhpcy5mYi5ncm91cCh7fSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRlbXBsYXRlVmFyaWFibGVzRm9ybSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtKSB7XG4gICAgICB0aGlzLnRlbXBsYXRlVmFyaWFibGVzRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe30pO1xuICAgIH1cbiAgICBPYmplY3Qua2V5cyh0aGlzLnRlbXBsYXRlVmFyaWFibGVzRm9ybS5jb250cm9scykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0ucmVtb3ZlQ29udHJvbChrZXkpO1xuICAgIH0pO1xuICAgIGNvbnN0IGNvbmZpZ1dpdGhEYXRhID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IGV4aXN0aW5nRGF0YSA9IGNvbmZpZ1dpdGhEYXRhLnRlbXBsYXRlVmFyaWFibGVzRGF0YSB8fCB7fTtcbiAgICB0aGlzLnRlbXBsYXRlVmFyaWFibGVzLmZvckVhY2godmFyaWFibGUgPT4ge1xuICAgICAgbGV0IGRlZmF1bHRWYWx1ZTogYW55O1xuICAgICAgaWYgKGV4aXN0aW5nRGF0YS5oYXNPd25Qcm9wZXJ0eSh2YXJpYWJsZS5uYW1lKSkge1xuICAgICAgICBkZWZhdWx0VmFsdWUgPSBleGlzdGluZ0RhdGFbdmFyaWFibGUubmFtZV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZhdWx0VmFsdWUgPSB2YXJpYWJsZS50eXBlID09PSAnYm9vbGVhbidcbiAgICAgICAgICA/ICh2YXJpYWJsZS52YWx1ZSA9PT0gdHJ1ZSB8fCB2YXJpYWJsZS52YWx1ZSA9PT0gJ3RydWUnIHx8IHZhcmlhYmxlLnZhbHVlID09PSAxKVxuICAgICAgICAgIDogKHZhcmlhYmxlLnZhbHVlIHx8ICcnKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YXJpYWJsZS50eXBlID09PSAnYm9vbGVhbicgJiYgdHlwZW9mIGRlZmF1bHRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlID09PSAndHJ1ZScgfHwgZGVmYXVsdFZhbHVlID09PSAnMSc7XG4gICAgICB9XG4gICAgICB0aGlzLnRlbXBsYXRlVmFyaWFibGVzRm9ybS5hZGRDb250cm9sKHZhcmlhYmxlLm5hbWUsIG5ldyBGb3JtQ29udHJvbChkZWZhdWx0VmFsdWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFNlbGVjdENvbmZpZ0ZvclZhcmlhYmxlKHZhcmlhYmxlOiBhbnkpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIGNvbnN0IG9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gKHZhcmlhYmxlLm9wdGlvbnMgfHwgW10pLm1hcCgob3B0OiBzdHJpbmcpID0+ICh7XG4gICAgICBpZDogb3B0LFxuICAgICAgdmFsdWU6IG9wdCxcbiAgICAgIG5hbWU6IG9wdCxcbiAgICAgIGxhYmVsOiBvcHRcbiAgICB9KSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogdmFyaWFibGUubmFtZSxcbiAgICAgIHBsYWNlaG9sZGVyOiBgU2VsZWN0ICR7dmFyaWFibGUubGFiZWx9YCxcbiAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgIG9uQ2hhbmdlOiAodmFsdWU6IGFueSkgPT4ge1xuICAgICAgICBpZiAodGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0gJiYgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0uZ2V0KHZhcmlhYmxlLm5hbWUpKSB7XG4gICAgICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0uZ2V0KHZhcmlhYmxlLm5hbWUpPy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqIFVwZGF0ZSB0ZXN0IGRhdGEgcHJvZmlsZSBzZWxlY3QgY29uZmlnIHdpdGggY3VycmVudCBvcHRpb25zIGFuZCBzZWxlY3RlZFZhbHVlIChmb3JMb29wVGVzdERhdGFJZCkuIEVuc3VyZSBzZWxlY3RlZCBpZCBpcyBpbiBvcHRpb25zIHNvIG1hdC1zZWxlY3QgY2FuIGRpc3BsYXkgaXQuICovXG4gIHByaXZhdGUgdXBkYXRlVGVzdERhdGFQcm9maWxlU2VsZWN0Q29uZmlnKCk6IHZvaWQge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jb252ZXJ0RGF0YVByb2ZpbGVPcHRpb25zVG9TZWxlY3RPcHRpb25zKHRoaXMuZGF0YVByb2ZpbGVPcHRpb25zKTtcbiAgICBjb25zdCBjZmcgPSB0aGlzLmNvbmZpZyBhcyBhbnk7XG4gICAgY29uc3QgZm9yTG9vcFRlc3REYXRhSWQgPSBjZmc/LmZvckxvb3BUZXN0RGF0YUlkID8/IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BUZXN0RGF0YUlkID8/IGNmZz8uZGF0YU1hcEJlYW4/LmZvcl9sb29wPy50ZXN0RGF0YUlkO1xuICAgIGNvbnN0IHNlbGVjdGVkVmFsID0gdGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicgPyB0aGlzLmdldFRlc3REYXRhUHJvZmlsZUZvcm1WYWx1ZSgpIDogdW5kZWZpbmVkO1xuICAgIC8vIElmIHdlIGhhdmUgYSBwcmVzZWxlY3RlZCBpZCBidXQgaXQncyBub3QgaW4gdGhlIGN1cnJlbnQgb3B0aW9ucyBsaXN0IChlLmcuIG9wdGlvbnMgbm90IGxvYWRlZCB5ZXQpLCBhZGQgYSBwbGFjZWhvbGRlciBvcHRpb24gc28gdGhlIGRyb3Bkb3duIGNhbiBzaG93IHRoZSBzZWxlY3Rpb25cbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicgJiYgZm9yTG9vcFRlc3REYXRhSWQgIT0gbnVsbCkge1xuICAgICAgY29uc3QgaWRTdHIgPSBTdHJpbmcoZm9yTG9vcFRlc3REYXRhSWQpO1xuICAgICAgY29uc3QgYWxyZWFkeUluTGlzdCA9IG9wdGlvbnMuc29tZSgobzogU2VsZWN0T3B0aW9uKSA9PiBTdHJpbmcoby5pZCA/PyBvLnZhbHVlKSA9PT0gaWRTdHIpO1xuICAgICAgaWYgKCFhbHJlYWR5SW5MaXN0KSB7XG4gICAgICAgIGNvbnN0IGRpc3BsYXlOYW1lID0gdGhpcy50ZXN0RGF0YVByb2ZpbGUgfHwgJ1NlbGVjdGVkIHByb2ZpbGUnO1xuICAgICAgICBvcHRpb25zID0gW3sgaWQ6IGZvckxvb3BUZXN0RGF0YUlkLCB2YWx1ZTogZm9yTG9vcFRlc3REYXRhSWQsIG5hbWU6IGRpc3BsYXlOYW1lLCBsYWJlbDogZGlzcGxheU5hbWUgfSwgLi4ub3B0aW9uc107XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudGVzdERhdGFQcm9maWxlU2VsZWN0Q29uZmlnID0ge1xuICAgICAga2V5OiAndGVzdERhdGFQcm9maWxlJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnVGVzdGRhdGFwcm9maWxlJyxcbiAgICAgIHNlYXJjaGFibGU6IHRydWUsXG4gICAgICBzZXJ2ZXJTZWFyY2g6IHRydWUsXG4gICAgICBoYXNNb3JlOiB0aGlzLmhhc01vcmVEYXRhUHJvZmlsZXMsXG4gICAgICBpc0xvYWRpbmc6IHRoaXMuaXNMb2FkaW5nRGF0YVByb2ZpbGVzLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIC4uLihzZWxlY3RlZFZhbCAhPT0gdW5kZWZpbmVkICYmIHNlbGVjdGVkVmFsICE9PSAnJyAmJiB7IHNlbGVjdGVkVmFsdWU6IHNlbGVjdGVkVmFsIH0pLFxuICAgICAgb25DaGFuZ2U6ICh2YWx1ZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMub25EYXRhUHJvZmlsZUNoYW5nZSh2YWx1ZSk7XG4gICAgICB9LFxuICAgICAgb25TZWFyY2g6IChxdWVyeTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMub25TZWFyY2hEYXRhUHJvZmlsZXMocXVlcnkpO1xuICAgICAgfSxcbiAgICAgIG9uTG9hZE1vcmU6IChxdWVyeT86IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLm9uTG9hZE1vcmVEYXRhUHJvZmlsZXMocXVlcnkgfHwgJycpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFVwZGF0ZSBMb29wIFN0YXJ0IC8gTG9vcCBFbmQgc2VsZWN0IGNvbmZpZ3Mgd2l0aCBzZWxlY3RlZFZhbHVlIChmb3JMb29wU3RhcnRJbmRleCwgZm9yTG9vcEVuZEluZGV4KSBzbyBkcm9wZG93bnMgc2hvdyBzZWxlY3RlZCAqL1xuICBwcml2YXRlIHVwZGF0ZVN0YXJ0RW5kU3RlcFNlbGVjdENvbmZpZ3NTZWxlY3RlZFZhbHVlcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sb29wVHlwZSAhPT0gJ2ZvcicpIHJldHVybjtcbiAgICBjb25zdCBzdGFydFZhbCA9IHRoaXMuZ2V0TG9vcFN0YXJ0Rm9ybVZhbHVlKCk7XG4gICAgY29uc3QgZW5kVmFsID0gdGhpcy5nZXRMb29wRW5kRm9ybVZhbHVlKCk7XG4gICAgY29uc3Qgc3RlcE9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gdGhpcy5sb29wU3RlcE9wdGlvbnMubWFwKChuKSA9PiAoe1xuICAgICAgaWQ6IG4sXG4gICAgICB2YWx1ZTogbixcbiAgICAgIG5hbWU6IFN0cmluZyhuKSxcbiAgICAgIGxhYmVsOiBTdHJpbmcobiksXG4gICAgfSkpO1xuICAgIHRoaXMuc3RhcnRTdGVwU2VsZWN0Q29uZmlnID0ge1xuICAgICAgLi4udGhpcy5zdGFydFN0ZXBTZWxlY3RDb25maWcsXG4gICAgICBvcHRpb25zOiBzdGVwT3B0aW9ucy5tYXAoKG8pID0+ICh7IC4uLm8gfSkpLFxuICAgICAgLi4uKHN0YXJ0VmFsICE9IG51bGwgJiYgeyBzZWxlY3RlZFZhbHVlOiBzdGFydFZhbCB9KSxcbiAgICB9O1xuICAgIHRoaXMuZW5kU3RlcFNlbGVjdENvbmZpZyA9IHtcbiAgICAgIC4uLnRoaXMuZW5kU3RlcFNlbGVjdENvbmZpZyxcbiAgICAgIG9wdGlvbnM6IHN0ZXBPcHRpb25zLm1hcCgobykgPT4gKHsgLi4ubyB9KSksXG4gICAgICAuLi4oZW5kVmFsICE9IG51bGwgJiYgeyBzZWxlY3RlZFZhbHVlOiBlbmRWYWwgfSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBVcGRhdGUgYWxsIEZPUiBsb29wIHNlbGVjdCBjb25maWdzICh0ZXN0RGF0YVByb2ZpbGUsIHN0YXJ0U3RlcCwgZW5kU3RlcCkgd2l0aCBzZWxlY3RlZFZhbHVlIGZyb20gc3RlcCBzbyBkcm9wZG93bnMgc2hvdyBzZWxlY3RlZCAqL1xuICBwcml2YXRlIHVwZGF0ZUZvckxvb3BTZWxlY3RDb25maWdzU2VsZWN0ZWRWYWx1ZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9vcFR5cGUgIT09ICdmb3InKSByZXR1cm47XG4gICAgdGhpcy51cGRhdGVUZXN0RGF0YVByb2ZpbGVTZWxlY3RDb25maWcoKTtcbiAgICB0aGlzLnVwZGF0ZVN0YXJ0RW5kU3RlcFNlbGVjdENvbmZpZ3NTZWxlY3RlZFZhbHVlcygpO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgRGF0YVByb2ZpbGVPcHRpb25bXSB0byBTZWxlY3RPcHRpb25bXSAqL1xuICBwcml2YXRlIGNvbnZlcnREYXRhUHJvZmlsZU9wdGlvbnNUb1NlbGVjdE9wdGlvbnMob3B0aW9uczogRGF0YVByb2ZpbGVPcHRpb25bXSk6IFNlbGVjdE9wdGlvbltdIHtcbiAgICByZXR1cm4gb3B0aW9ucy5tYXAob3B0aW9uID0+ICh7XG4gICAgICBpZDogb3B0aW9uLmlkLFxuICAgICAgdmFsdWU6IG9wdGlvbi5pZCxcbiAgICAgIG5hbWU6IG9wdGlvbi5uYW1lLFxuICAgICAgbGFiZWw6IG9wdGlvbi5uYW1lXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqIEhhbmRsZSBkYXRhIHByb2ZpbGUgc2VsZWN0aW9uICovXG4gIHByaXZhdGUgb25EYXRhUHJvZmlsZUNoYW5nZShwcm9maWxlSWQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25UZXN0RGF0YVByb2ZpbGVDaGFuZ2UocHJvZmlsZUlkKTtcbiAgfVxuXG4gIC8qKiBIYW5kbGUgc2VhcmNoIGZvciBkYXRhIHByb2ZpbGVzICovXG4gIHByaXZhdGUgb25TZWFyY2hEYXRhUHJvZmlsZXMocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoRGF0YVByb2ZpbGVzLmVtaXQocXVlcnkpO1xuICB9XG5cbiAgLyoqIEhhbmRsZSBsb2FkIG1vcmUgZGF0YSBwcm9maWxlcyAqL1xuICBwcml2YXRlIG9uTG9hZE1vcmVEYXRhUHJvZmlsZXMocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubG9hZE1vcmVEYXRhUHJvZmlsZXMuZW1pdChxdWVyeSk7XG4gIH1cblxuICBvbkVkaXRGb3JtRmllbGRDaGFuZ2UoY29udHJvbE5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdEZvcm0uZ2V0KGNvbnRyb2xOYW1lKT8uc2V0VmFsdWUodmFsdWUpO1xuICB9XG5cbiAgZ2V0TG9vcFR5cGVMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdGT1IgTE9PUCcgOiAnV0hJTEUgTE9PUCc7XG4gIH1cblxuICBpc1doaWxlTG9vcCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJztcbiAgfVxuXG4gIGlzRm9yTG9vcCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb29wVHlwZSA9PT0gJ2Zvcic7XG4gIH1cblxuICBnZXRFbmRMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdFTkQgRk9SJyA6ICdFTkQgV0hJTEUnO1xuICB9XG5cbiAgLyoqIFJlc29sdmUgZGlzcGxheSBzdGFydCBpbmRleDogcHJlZmVyIGZvckxvb3BTdGFydEluZGV4IGZyb20gc3RlcCAob3IgZGF0YU1hcEpzb24vZGF0YU1hcEJlYW4pLCBlbHNlIHN0YXJ0U3RlcCwgZWxzZSBmcm9tIG5lc3RlZCBzdGVwcyAqL1xuICBwcml2YXRlIGdldERpc3BsYXlTdGFydEluZGV4KCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IHYgPSBjZmc/LmZvckxvb3BTdGFydEluZGV4ID8/IGNmZz8uZGF0YU1hcEpzb24/LmZvckxvb3BTdGFydEluZGV4ID8/IGNmZz8uZGF0YU1hcEJlYW4/LmZvcl9sb29wPy5zdGFydEluZGV4O1xuICAgIGlmICh2ICE9IG51bGwpIHJldHVybiBOdW1iZXIodik7XG4gICAgaWYgKHRoaXMuc3RhcnRTdGVwICE9IG51bGwpIHJldHVybiB0aGlzLnN0YXJ0U3RlcDtcbiAgICByZXR1cm4gdGhpcy5uZXN0ZWRTdGVwc1swXT8uc3RlcE51bWJlciBhcyBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIH1cblxuICAvKiogUmVzb2x2ZSBkaXNwbGF5IGVuZCBpbmRleDogcHJlZmVyIGZvckxvb3BFbmRJbmRleCBmcm9tIHN0ZXAgKG9yIGRhdGFNYXBKc29uL2RhdGFNYXBCZWFuKSwgZWxzZSBlbmRTdGVwLCBlbHNlIGZyb20gbmVzdGVkIHN0ZXBzICovXG4gIHByaXZhdGUgZ2V0RGlzcGxheUVuZEluZGV4KCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IHYgPSBjZmc/LmZvckxvb3BFbmRJbmRleCA/PyBjZmc/LmRhdGFNYXBKc29uPy5mb3JMb29wRW5kSW5kZXggPz8gY2ZnPy5kYXRhTWFwQmVhbj8uZm9yX2xvb3A/LmVuZEluZGV4O1xuICAgIGlmICh2ICE9IG51bGwpIHJldHVybiBOdW1iZXIodik7XG4gICAgaWYgKHRoaXMuZW5kU3RlcCAhPSBudWxsKSByZXR1cm4gdGhpcy5lbmRTdGVwO1xuICAgIGNvbnN0IGxhc3QgPSB0aGlzLm5lc3RlZFN0ZXBzW3RoaXMubmVzdGVkU3RlcHMubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIGxhc3Q/LnN0ZXBOdW1iZXIgYXMgbnVtYmVyIHwgdW5kZWZpbmVkID8/IHRoaXMubmVzdGVkU3RlcHMubGVuZ3RoO1xuICB9XG5cbiAgLyoqIFJlc29sdmUgZGlzcGxheSBwcm9maWxlIG5hbWU6IG1hcCBmb3JMb29wVGVzdERhdGFJZCB0byBwcm9maWxlIG5hbWUgZnJvbSBkYXRhUHJvZmlsZU9wdGlvbnMsIGVsc2UgdXNlIHRlc3REYXRhUHJvZmlsZSAqL1xuICBwcml2YXRlIGdldERpc3BsYXlUZXN0RGF0YVByb2ZpbGVOYW1lKCk6IHN0cmluZyB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIGNvbnN0IGlkID0gY2ZnPy5mb3JMb29wVGVzdERhdGFJZCA/PyBjZmc/LmRhdGFNYXBKc29uPy5mb3JMb29wVGVzdERhdGFJZCA/PyBjZmc/LmRhdGFNYXBCZWFuPy5mb3JfbG9vcD8udGVzdERhdGFJZDtcbiAgICBpZiAoaWQgIT0gbnVsbCAmJiB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IHRoaXMuZGF0YVByb2ZpbGVPcHRpb25zLmZpbmQoXG4gICAgICAgIG8gPT4gby5pZCA9PT0gaWQgfHwgU3RyaW5nKG8uaWQpID09PSBTdHJpbmcoaWQpXG4gICAgICApO1xuICAgICAgaWYgKG1hdGNoKSByZXR1cm4gbWF0Y2gubmFtZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudGVzdERhdGFQcm9maWxlID8/ICcnO1xuICB9XG5cbiAgZ2V0U3RlcHNTdW1tYXJ5KCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMubmVzdGVkU3RlcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJzAgc3RlcHMnO1xuICAgIH1cbiAgICBjb25zdCBzdGFydCA9IHRoaXMuZ2V0RGlzcGxheVN0YXJ0SW5kZXgoKSA/PyAxO1xuICAgIGNvbnN0IGVuZCA9IHRoaXMuZ2V0RGlzcGxheUVuZEluZGV4KCkgPz8gdGhpcy5uZXN0ZWRTdGVwcy5sZW5ndGg7XG4gICAgY29uc3QgY291bnQgPSB0aGlzLm5lc3RlZFN0ZXBzLmxlbmd0aDtcbiAgICByZXR1cm4gYFN0ZXBzICR7c3RhcnR9LSR7ZW5kfSAoJHtjb3VudH0gc3RlcCR7Y291bnQgIT09IDEgPyAncycgOiAnJ30pYDtcbiAgfVxuXG4gIGdldFN0YXJ0U3RlcExhYmVsKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmdldERpc3BsYXlTdGFydEluZGV4KCk7XG4gICAgaWYgKHN0YXJ0ICE9IG51bGwpIHJldHVybiBgU3RhcnQ6ICR7c3RhcnR9YDtcbiAgICByZXR1cm4gYFN0YXJ0OiAke3RoaXMubmVzdGVkU3RlcHNbMF0/LnN0ZXBOdW1iZXIgPz8gMX1gO1xuICB9XG5cbiAgZ2V0RW5kU3RlcExhYmVsKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZW5kID0gdGhpcy5nZXREaXNwbGF5RW5kSW5kZXgoKTtcbiAgICBpZiAoZW5kICE9IG51bGwpIHJldHVybiBgRW5kOiAke2VuZH1gO1xuICAgIGNvbnN0IGRlZmF1bHRFbmQgPSB0aGlzLm5lc3RlZFN0ZXBzW3RoaXMubmVzdGVkU3RlcHMubGVuZ3RoIC0gMV0/LnN0ZXBOdW1iZXIgPz8gdGhpcy5uZXN0ZWRTdGVwcy5sZW5ndGg7XG4gICAgcmV0dXJuIGBFbmQ6ICR7ZGVmYXVsdEVuZH1gO1xuICB9XG5cbiAgZ2V0VGVzdERhdGFQcm9maWxlTGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5nZXREaXNwbGF5VGVzdERhdGFQcm9maWxlTmFtZSgpO1xuICAgIGlmIChuYW1lKSByZXR1cm4gYFRlc3QgRGF0YSBwcm9maWxlOiAke25hbWV9YDtcbiAgICByZXR1cm4gJ1Rlc3QgRGF0YSBwcm9maWxlJztcbiAgfVxuXG4gIGdldENvbmRpdGlvbkRpc3BsYXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb25kaXRpb24gfHwgJ2VsZW1lbnQgXCIubm90aWZpY2F0aW9uLWJhZGdlXCIgZXhpc3RzJztcbiAgfVxuXG4gIG9uVG9nZ2xlRXhwYW5kZWQoKTogdm9pZCB7XG4gICAgdGhpcy5leHBhbmRlZCA9ICF0aGlzLmV4cGFuZGVkO1xuICAgIHRoaXMudG9nZ2xlRXhwYW5kZWQuZW1pdCh7Y29uZmlnOnRoaXMuY29uZmlnLCBleHBhbmRlZDp0aGlzLmV4cGFuZGVkfSk7XG4gIH1cblxuICBvblRlc3REYXRhUHJvZmlsZUNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy50ZXN0RGF0YVByb2ZpbGUgPSB2YWx1ZTtcbiAgICB0aGlzLnRlc3REYXRhUHJvZmlsZUNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIG9uU3RhcnRTdGVwQ2hhbmdlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnN0YXJ0U3RlcCA9IHZhbHVlO1xuICAgIHRoaXMuc3RhcnRTdGVwQ2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgb25FbmRTdGVwQ2hhbmdlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmVuZFN0ZXAgPSB2YWx1ZTtcbiAgICB0aGlzLmVuZFN0ZXBDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICBvbkNvbmRpdGlvbkNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jb25kaXRpb24gPSB2YWx1ZTtcbiAgICB0aGlzLmNvbmRpdGlvbkNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIG9uTWF4SXRlcmF0aW9uc0NoYW5nZSh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5tYXhJdGVyYXRpb25zID0gdmFsdWU7XG4gICAgdGhpcy5tYXhJdGVyYXRpb25zQ2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubmVzdGVkU3RlcENoYW5nZS5lbWl0KHsgc3RlcCwgaW5kZXggfSk7XG4gIH1cblxuICBvbk5lc3RlZFRvZ2dsZUV4cGFuZGVkKGV2ZW50OiBib29sZWFuIHwge2NvbmZpZzogVGVzdENhc2VTdGVwQ29uZmlnLCBleHBhbmRlZDogYm9vbGVhbn0sIHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIEhhbmRsZSBib3RoIGJvb2xlYW4gYW5kIG9iamVjdCBmb3JtYXRzXG4gICAgaWYgKHR5cGVvZiBldmVudCA9PT0gJ29iamVjdCcgJiYgZXZlbnQgIT09IG51bGwgJiYgJ2V4cGFuZGVkJyBpbiBldmVudCkge1xuICAgICAgLy8gT2JqZWN0IGZvcm1hdCBmcm9tIHN0ZXAtZ3JvdXA6IHtjb25maWcsIGV4cGFuZGVkfVxuICAgICAgKHN0ZXAgYXMgYW55KS5leHBhbmRlZCA9IGV2ZW50LmV4cGFuZGVkO1xuICAgICAgLy8gQ2hlY2sgaWYgdGhlIGV2ZW50J3MgY29uZmlnIGlzIGEgc3RlcC1ncm91cCAobm90IHRoZSBjdXJyZW50IHN0ZXApXG4gICAgICAvLyBUaGlzIGVuc3VyZXMgbmVzdGVkIHN0ZXAtZ3JvdXAgZXZlbnRzIGJ1YmJsZSB1cCBjb3JyZWN0bHkgZXZlbiB3aGVuIGNvbmRpdGlvbiBzdGVwIGlzIGluc2lkZSBsb29wIHN0ZXBcbiAgICAgIGlmICh0aGlzLmlzU3RlcEdyb3VwKGV2ZW50LmNvbmZpZykpIHtcbiAgICAgICAgLy8gUmUtZW1pdCB0aGUgdG9nZ2xlRXhwYW5kZWQgZXZlbnQgd2l0aCB0aGUgb2JqZWN0IGZvcm1hdCwgcHJlc2VydmluZyB0aGUgb3JpZ2luYWwgY29uZmlnXG4gICAgICAgIC8vIENhc3QgdG8gc2F0aXNmeSBUeXBlU2NyaXB0IC0gdGhlIHJlbmRlcmVyIGFjY2VwdHMgVGVzdENhc2VTdGVwQ29uZmlnIHdoaWNoIGluY2x1ZGVzIFN0ZXBHcm91cENvbmZpZ1xuICAgICAgICB0aGlzLnRvZ2dsZUV4cGFuZGVkLmVtaXQoe2NvbmZpZzogZXZlbnQuY29uZmlnIGFzIGFueSBhcyBMb29wU3RlcENvbmZpZywgZXhwYW5kZWQ6IGV2ZW50LmV4cGFuZGVkfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEJvb2xlYW4gZm9ybWF0IGZyb20gb3RoZXIgc3RlcCB0eXBlc1xuICAgICAgKHN0ZXAgYXMgYW55KS5leHBhbmRlZCA9IGV2ZW50IGFzIGJvb2xlYW47XG4gICAgfVxuICAgIHRoaXMub25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGluZGV4KTtcbiAgfVxuXG4gIG9uQWRkU3RlcCgpOiB2b2lkIHtcbiAgICB0aGlzLmFkZFN0ZXAuZW1pdCgpO1xuICB9XG5cbiAgLyoqIENhbGxlZCBmcm9tIGVtcHR5LXN0YXRlIHBsdXMgb25seTsgc2FtZSBiZWhhdmlvdXIgYXMgYWRkLXN0ZXAtYmV0d2VlbiAocGFyZW50SWQgPSBsb29wIHN0ZXAgaWQsIHBvc2l0aW9uID0gcGFyZW50ICsgMSkuICovXG4gIG9uQWRkU3RlcEVtcHR5KCk6IHZvaWQge1xuICAgIHRoaXMuYWRkU3RlcC5lbWl0KHsgbG9vcFN0ZXBDb25maWc6IHRoaXMuY29uZmlnIH0pO1xuICB9XG5cbiAgb25EZWxldGVTdGVwKHBheWxvYWRPckluZGV4OiBhbnksIGluZGV4PzogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgaWR4ID0gdHlwZW9mIGluZGV4ID09PSAnbnVtYmVyJyA/IGluZGV4IDogcGF5bG9hZE9ySW5kZXg7XG4gICAgY29uc3QgcGF5bG9hZCA9IHR5cGVvZiBpbmRleCA9PT0gJ251bWJlcicgPyBwYXlsb2FkT3JJbmRleCA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRlbGV0ZVN0ZXAuZW1pdChpZHgpO1xuICAgIGlmIChwYXlsb2FkPy5zdGVwKSB0aGlzLmRlbGV0ZS5lbWl0KHBheWxvYWQpO1xuICB9XG5cbiAgLyoqIFJlLWVtaXQgZWRpdCBmcm9tIG5lc3RlZCBzdGVwIHNvIHRoZSBwb3J0YWwgY2FuIG9wZW4gZWRpdCBtb2RhbCAoc2FtZSBhcyByb290IGxldmVsKS4gKi9cbiAgb25OZXN0ZWRFZGl0KGV2ZW50OiB7IHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZzsgaW5kZXg6IG51bWJlciB9KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50Py5zdGVwICE9IG51bGwpIHRoaXMuZWRpdC5lbWl0KGV2ZW50IGFzIGFueSk7XG4gIH1cblxuICAvKiogUmUtZW1pdCBkdXBsaWNhdGUgZnJvbSBuZXN0ZWQgc3RlcCBzbyB0aGUgcG9ydGFsIGNhbiBkdXBsaWNhdGUgKHNhbWUgYXMgcm9vdCBsZXZlbCkuICovXG4gIG9uTmVzdGVkRHVwbGljYXRlKGV2ZW50OiBhbnksIHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMuZHVwbGljYXRlLmVtaXQoKGV2ZW50ICYmIGV2ZW50LnN0ZXAgIT0gbnVsbCkgPyBldmVudCA6IHsgc3RlcCB9IGFzIGFueSk7XG4gIH1cblxuICBpc05vcm1hbFN0ZXAoc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnKTogc3RlcCBpcyBOb3JtYWxTdGVwQ29uZmlnIHtcbiAgICByZXR1cm4gJ2V2ZW50VHlwZScgaW4gc3RlcDtcbiAgfVxuXG4gIGlzTG9vcFN0ZXAoc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnKTogc3RlcCBpcyBMb29wU3RlcENvbmZpZyB7XG4gICAgcmV0dXJuICdsb29wVHlwZScgaW4gc3RlcDtcbiAgfVxuXG4gIGlzQ29uZGl0aW9uU3RlcChzdGVwOiBUZXN0Q2FzZVN0ZXBDb25maWcpOiBzdGVwIGlzIENvbmRpdGlvblN0ZXBDb25maWcge1xuICAgIHJldHVybiAnY29uZGl0aW9uJyBpbiBzdGVwICYmICdicmFuY2hlcycgaW4gc3RlcDtcbiAgfVxuXG4gIGlzU3RlcEdyb3VwKHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZyk6IHN0ZXAgaXMgU3RlcEdyb3VwQ29uZmlnIHtcbiAgICByZXR1cm4gJ2dyb3VwTmFtZScgaW4gc3RlcDtcbiAgfVxuXG4gIG9uQWRkQnJhbmNoKCk6IHZvaWQge1xuICAgIC8vIE5vdCB1c2VkIGluIGxvb3Agc3RlcCwgYnV0IG5lZWRlZCBmb3IgcmVjdXJzaXZlIGNvbmRpdGlvbiBzdGVwc1xuICB9XG5cbiAgb25EZWxldGVCcmFuY2goYnJhbmNoOiBhbnkpOiB2b2lkIHtcbiAgICAvLyBOb3QgdXNlZCBpbiBsb29wIHN0ZXAsIGJ1dCBuZWVkZWQgZm9yIHJlY3Vyc2l2ZSBjb25kaXRpb24gc3RlcHNcbiAgfVxuXG4gIG9uTmVzdGVkQ29uZGl0aW9uQWRkQnJhbmNoKG5lc3RlZFN0ZXA6IENvbmRpdGlvblN0ZXBDb25maWcsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBBZGQgYSBuZXcgYnJhbmNoIHRvIHRoZSBuZXN0ZWQgY29uZGl0aW9uIHN0ZXBcbiAgICBpZiAoIW5lc3RlZFN0ZXAuYnJhbmNoZXMpIHtcbiAgICAgIG5lc3RlZFN0ZXAuYnJhbmNoZXMgPSBbXTtcbiAgICB9XG4gICAgY29uc3QgbmV3QnJhbmNoOiBDb25kaXRpb25CcmFuY2ggPSB7XG4gICAgICB0eXBlOiBuZXN0ZWRTdGVwLmJyYW5jaGVzLmxlbmd0aCA9PT0gMCA/ICdpZicgOiAnZWxzZScsXG4gICAgICBsYWJlbDogbmVzdGVkU3RlcC5icmFuY2hlcy5sZW5ndGggPT09IDAgPyAnSUYgVFJVRScgOiAnRUxTRScsIFxuICAgICAgc3RlcFR5cGU6IFN0ZXBUeXBlcy5DT05ESVRJT05fSUYsXG4gICAgICBuZXN0ZWRTdGVwczogW11cbiAgICB9O1xuICAgIG5lc3RlZFN0ZXAuYnJhbmNoZXMucHVzaChuZXdCcmFuY2gpO1xuICAgIHRoaXMub25OZXN0ZWRTdGVwQ2hhbmdlKG5lc3RlZFN0ZXAsIGluZGV4KTtcbiAgfVxuXG4gIG9uTmVzdGVkQ29uZGl0aW9uRGVsZXRlQnJhbmNoKG5lc3RlZFN0ZXA6IENvbmRpdGlvblN0ZXBDb25maWcsIGJyYW5jaDogYW55LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gRGVsZXRlIGEgYnJhbmNoIGZyb20gdGhlIG5lc3RlZCBjb25kaXRpb24gc3RlcFxuICAgIGlmIChuZXN0ZWRTdGVwLmJyYW5jaGVzKSB7XG4gICAgICBjb25zdCBicmFuY2hJbmRleCA9IG5lc3RlZFN0ZXAuYnJhbmNoZXMuaW5kZXhPZihicmFuY2gpO1xuICAgICAgaWYgKGJyYW5jaEluZGV4ID4gLTEpIHtcbiAgICAgICAgbmVzdGVkU3RlcC5icmFuY2hlcy5zcGxpY2UoYnJhbmNoSW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm9uTmVzdGVkU3RlcENoYW5nZShuZXN0ZWRTdGVwLCBpbmRleCk7XG4gIH1cblxuICBvbk9wZW5FeHRlcm5hbCgpOiB2b2lkIHtcbiAgICAvLyBOb3QgdXNlZCBpbiBsb29wIHN0ZXAsIGJ1dCBuZWVkZWQgZm9yIHJlY3Vyc2l2ZSBzdGVwIGdyb3Vwc1xuICB9XG5cbiAgLyoqIFN5bmMgRk9SIGxvb3AgZWRpdCBmb3JtIHNvIGRyb3Bkb3ducyBzaG93IGV4aXN0aW5nIGNvbmZpZyAoZm9yT3B0aW9uVHlwZSwgZm9yTG9vcFRlc3REYXRhSWQvdGVzdERhdGFQcm9maWxlLCBmb3JMb29wU3RhcnRJbmRleC9mb3JMb29wRW5kSW5kZXgpICovXG4gIHByaXZhdGUgc3luY0Zvckxvb3BFZGl0Rm9ybUZyb21Db25maWcoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRGb3JtIHx8IHRoaXMubG9vcFR5cGUgIT09ICdmb3InKSByZXR1cm47XG4gICAgY29uc3QgdGVzdERhdGFWYWwgPSB0aGlzLmdldFRlc3REYXRhUHJvZmlsZUZvcm1WYWx1ZSgpO1xuICAgIGNvbnN0IHN0YXJ0VmFsID0gdGhpcy5nZXRMb29wU3RhcnRGb3JtVmFsdWUoKTtcbiAgICBjb25zdCBlbmRWYWwgPSB0aGlzLmdldExvb3BFbmRGb3JtVmFsdWUoKTtcbiAgICB0aGlzLmVkaXRGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgZm9yT3B0aW9uVHlwZTogdGhpcy5nZXRGb3JPcHRpb25UeXBlRnJvbUNvbmZpZygpID8/IG51bGwsXG4gICAgICB0ZXN0RGF0YVByb2ZpbGU6IHRlc3REYXRhVmFsLFxuICAgICAgc3RhcnRTdGVwOiBzdGFydFZhbCxcbiAgICAgIGVuZFN0ZXA6IGVuZFZhbCxcbiAgICB9KTtcbiAgICAvLyBFeHBsaWNpdGx5IHNldCBlYWNoIGNvbnRyb2wgc28gbWF0LXNlbGVjdCBwaWNrcyB1cCB0aGUgdmFsdWUgKHBhdGNoVmFsdWUgY2FuIGJlIGlnbm9yZWQgYnkgY2hpbGQgaW4gc29tZSB0aW1pbmcgY2FzZXMpXG4gICAgY29uc3QgdGVzdERhdGFDdHJsID0gdGhpcy5lZGl0Rm9ybS5nZXQoJ3Rlc3REYXRhUHJvZmlsZScpO1xuICAgIGNvbnN0IHN0YXJ0Q3RybCA9IHRoaXMuZWRpdEZvcm0uZ2V0KCdzdGFydFN0ZXAnKTtcbiAgICBjb25zdCBlbmRDdHJsID0gdGhpcy5lZGl0Rm9ybS5nZXQoJ2VuZFN0ZXAnKTtcbiAgICBpZiAodGVzdERhdGFDdHJsICYmIHRlc3REYXRhVmFsICE9PSB1bmRlZmluZWQgJiYgdGVzdERhdGFWYWwgIT09ICcnKSB0ZXN0RGF0YUN0cmwuc2V0VmFsdWUodGVzdERhdGFWYWwsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICBpZiAoc3RhcnRDdHJsICYmIHN0YXJ0VmFsICE9IG51bGwpIHN0YXJ0Q3RybC5zZXRWYWx1ZShzdGFydFZhbCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIGlmIChlbmRDdHJsICYmIGVuZFZhbCAhPSBudWxsKSBlbmRDdHJsLnNldFZhbHVlKGVuZFZhbCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIG9uRWRpdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRTbmFwc2hvdCA9IHtcbiAgICAgIHRlc3REYXRhUHJvZmlsZTogdGhpcy50ZXN0RGF0YVByb2ZpbGUsXG4gICAgICBzdGFydFN0ZXA6IHRoaXMuc3RhcnRTdGVwLFxuICAgICAgZW5kU3RlcDogdGhpcy5lbmRTdGVwLFxuICAgICAgY29uZGl0aW9uOiB0aGlzLmNvbmRpdGlvbixcbiAgICAgIG1heEl0ZXJhdGlvbnM6IHRoaXMubWF4SXRlcmF0aW9ucyxcbiAgICAgIHNlbGVjdGVkVGVtcGxhdGU6IHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZSxcbiAgICAgIHRlbXBsYXRlVmFyaWFibGVzOiB0aGlzLnRlbXBsYXRlVmFyaWFibGVzID8gWy4uLnRoaXMudGVtcGxhdGVWYXJpYWJsZXNdIDogW10sXG4gICAgICBjb25kaXRpb25UZW1wbGF0ZUZvcm1WYWx1ZTogdGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0gPyB7IC4uLnRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtLnZhbHVlIH0gOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgICAvLyBGT1IgbG9vcDogcmVmcmVzaCBzZWxlY3QgY29uZmlncyAoc28gVGVzdCBEYXRhIFByb2ZpbGUgb3B0aW9ucyBpbmNsdWRlIHNlbGVjdGVkIGlkIGlmIG5lZWRlZCkgdGhlbiBzeW5jIGZvcm0gc28gZHJvcGRvd25zIHNob3cgc2VsZWN0ZWRcbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicpIHtcbiAgICAgIHRoaXMudXBkYXRlRm9yTG9vcFNlbGVjdENvbmZpZ3NTZWxlY3RlZFZhbHVlcygpO1xuICAgICAgdGhpcy5zeW5jRm9yTG9vcEVkaXRGb3JtRnJvbUNvbmZpZygpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuc3luY0Zvckxvb3BFZGl0Rm9ybUZyb21Db25maWcoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWRpdEZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIHRlc3REYXRhUHJvZmlsZTogdGhpcy50ZXN0RGF0YVByb2ZpbGUgPz8gJycsXG4gICAgICAgIHN0YXJ0U3RlcDogdGhpcy5zdGFydFN0ZXAgPz8gbnVsbCxcbiAgICAgICAgZW5kU3RlcDogdGhpcy5lbmRTdGVwID8/IG51bGwsXG4gICAgICAgIGNvbmRpdGlvbjogdGhpcy5jb25kaXRpb24gPz8gJycsXG4gICAgICAgIG1heEl0ZXJhdGlvbnM6IHRoaXMubWF4SXRlcmF0aW9ucyA/PyA1LFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmxvb3BUeXBlID09PSAnd2hpbGUnKSB7XG4gICAgICB0aGlzLmVkaXRGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBjb25kaXRpb246IHRoaXMuY29uZGl0aW9uID8/ICcnLFxuICAgICAgICBtYXhJdGVyYXRpb25zOiB0aGlzLm1heEl0ZXJhdGlvbnMgPz8gNSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBXaGlsZSBsb29wOiByZXN0b3JlIHNlbGVjdGVkIHRlbXBsYXRlIGFuZCB0ZW1wbGF0ZSB2YXJpYWJsZXMgZnJvbSBjb25maWcgd2hlbiBvcGVuaW5nIGVkaXRcbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJyAmJiAodGhpcy5jb25kaXRpb24gfHwgKHRoaXMuY29uZmlnIGFzIGFueSkudGVtcGxhdGVWYXJpYWJsZXNEYXRhKSkge1xuICAgICAgY29uc3QgY29uZmlnV2l0aERhdGEgPSB0aGlzLmNvbmZpZyBhcyBhbnk7XG4gICAgICBjb25zdCBjb25kaXRpb25TdHIgPSB0aGlzLmNvbmRpdGlvbiB8fCBjb25maWdXaXRoRGF0YS5jb25kaXRpb24gfHwgJyc7XG4gICAgICBpZiAoY29uZGl0aW9uU3RyICYmICh0aGlzLm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdPcHRpb24gPSAodGhpcy5uYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zIGFzIGFueVtdKS5maW5kKFxuICAgICAgICAgIChvcHQ6IGFueSkgPT4gKG9wdC5uYXR1cmFsVGV4dCB8fCBvcHQubmFtZSB8fCBvcHQudmFsdWUpID09PSBjb25kaXRpb25TdHJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZnVsbFRlbXBsYXRlID0gbWF0Y2hpbmdPcHRpb24/LnRlbXBsYXRlIHx8IG1hdGNoaW5nT3B0aW9uO1xuICAgICAgICBpZiAoZnVsbFRlbXBsYXRlICYmIGZ1bGxUZW1wbGF0ZS52YXJpYWJsZXMpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVGVtcGxhdGUgPSBmdWxsVGVtcGxhdGU7XG4gICAgICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlcyA9IHRoaXMuc2V0Q29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMoZnVsbFRlbXBsYXRlKSB8fCBbXTtcbiAgICAgICAgICB0aGlzLmJ1aWxkVGVtcGxhdGVWYXJpYWJsZXNGb3JtKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5pc0VkaXRpbmcgPSB0cnVlO1xuICAgIHRoaXMuZWRpdC5lbWl0KCk7XG4gIH1cblxuICBvbkVkaXRBcHBseSgpOiB2b2lkIHtcbiAgICBjb25zdCB2ID0gdGhpcy5lZGl0Rm9ybS52YWx1ZTtcbiAgICBjb25zdCB0ZXN0RGF0YVByb2ZpbGVWYWx1ZSA9IHYudGVzdERhdGFQcm9maWxlID8/ICcnO1xuICAgIHRoaXMuc3RhcnRTdGVwID0gdi5zdGFydFN0ZXAgPz8gdW5kZWZpbmVkO1xuICAgIHRoaXMuZW5kU3RlcCA9IHYuZW5kU3RlcCA/PyB1bmRlZmluZWQ7XG4gICAgdGhpcy5jb25kaXRpb24gPSB2LmNvbmRpdGlvbiA/PyAnJztcbiAgICBjb25zdCBtYXhWYWwgPSB2Lm1heEl0ZXJhdGlvbnM7XG4gICAgdGhpcy5tYXhJdGVyYXRpb25zID0gdHlwZW9mIG1heFZhbCA9PT0gJ251bWJlcicgPyBtYXhWYWwgOiAobWF4VmFsICE9IG51bGwgJiYgbWF4VmFsICE9PSAnJyA/IE51bWJlcihtYXhWYWwpIDogdW5kZWZpbmVkKTtcbiAgICBcbiAgICAvLyBGaW5kIHRoZSBzZWxlY3RlZCBkYXRhIHByb2ZpbGUgb3B0aW9uIHRvIGdldCBib3RoIElEIGFuZCBuYW1lXG4gICAgbGV0IHRlc3REYXRhUHJvZmlsZUlkOiBzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHRlc3REYXRhUHJvZmlsZU5hbWU6IHN0cmluZyA9ICcnO1xuICAgIFxuICAgIGlmICh0ZXN0RGF0YVByb2ZpbGVWYWx1ZSAmJiB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBUaGUgZm9ybSB2YWx1ZSBtaWdodCBiZSBJRCAobnVtYmVyKSBvciBuYW1lIChzdHJpbmcpXG4gICAgICBjb25zdCBzZWxlY3RlZFByb2ZpbGUgPSB0aGlzLmRhdGFQcm9maWxlT3B0aW9ucy5maW5kKFxuICAgICAgICBvcHRpb24gPT4gb3B0aW9uLmlkID09PSBOdW1iZXIodGVzdERhdGFQcm9maWxlVmFsdWUpIHx8IG9wdGlvbi5uYW1lID09PSB0ZXN0RGF0YVByb2ZpbGVWYWx1ZSB8fCBTdHJpbmcob3B0aW9uLmlkKSA9PT0gU3RyaW5nKHRlc3REYXRhUHJvZmlsZVZhbHVlKVxuICAgICAgKTtcbiAgICAgIGlmIChzZWxlY3RlZFByb2ZpbGUpIHtcbiAgICAgICAgdGVzdERhdGFQcm9maWxlSWQgPSBzZWxlY3RlZFByb2ZpbGUuaWQ7XG4gICAgICAgIHRlc3REYXRhUHJvZmlsZU5hbWUgPSBzZWxlY3RlZFByb2ZpbGUubmFtZTtcbiAgICAgICAgdGhpcy50ZXN0RGF0YVByb2ZpbGUgPSB0ZXN0RGF0YVByb2ZpbGVOYW1lO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSWYgbm90IGZvdW5kLCB1c2UgdGhlIHZhbHVlIGFzLWlzIChtaWdodCBiZSBJRCBvciBuYW1lKVxuICAgICAgICB0aGlzLnRlc3REYXRhUHJvZmlsZSA9IHRlc3REYXRhUHJvZmlsZVZhbHVlO1xuICAgICAgICB0ZXN0RGF0YVByb2ZpbGVJZCA9IE51bWJlcih0ZXN0RGF0YVByb2ZpbGVWYWx1ZSkgfHwgdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRlc3REYXRhUHJvZmlsZSA9IHRlc3REYXRhUHJvZmlsZVZhbHVlO1xuICAgIH1cbiAgICBcbiAgICAvLyBXaGlsZSBsb29wOiBidWlsZCB0ZW1wbGF0ZVZhcmlhYmxlc0RhdGEgYW5kIG5hdHVyYWxUZXh0QWN0aW9uSWQgZnJvbSBzZWxlY3RlZCB0ZW1wbGF0ZSAoc2FtZSBhcyBjb25kaXRpb24tc3RlcClcbiAgICBsZXQgdGVtcGxhdGVWYXJpYWJsZXNEYXRhOiBhbnk7XG4gICAgbGV0IG5hdHVyYWxUZXh0QWN0aW9uSWQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJyAmJiB0aGlzLnRlbXBsYXRlVmFyaWFibGVzRm9ybSAmJiB0aGlzLnRlbXBsYXRlVmFyaWFibGVzPy5sZW5ndGgpIHtcbiAgICAgIHRlbXBsYXRlVmFyaWFibGVzRGF0YSA9IHt9O1xuICAgICAgdGhpcy50ZW1wbGF0ZVZhcmlhYmxlcy5mb3JFYWNoKCh2YXJpYWJsZTogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0uZ2V0KHZhcmlhYmxlLm5hbWUpPy52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgdGVtcGxhdGVWYXJpYWJsZXNEYXRhW3ZhcmlhYmxlLm5hbWVdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZT8uaWQgIT0gbnVsbCkge1xuICAgICAgICBuYXR1cmFsVGV4dEFjdGlvbklkID0gdGhpcy5zZWxlY3RlZFRlbXBsYXRlLmlkO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBVcGRhdGUgY29uZmlnIHdpdGggbmV3IHZhbHVlcyAoaW5jbHVkZSB0ZXN0RGF0YVByb2ZpbGVJZCwgdGVtcGxhdGVWYXJpYWJsZXNEYXRhLCBuYXR1cmFsVGV4dEFjdGlvbklkIGZvciB3aGlsZTsgZm9yTG9vcFRlc3REYXRhSWQsIGZvckxvb3BTdGFydEluZGV4L2Zvckxvb3BFbmRJbmRleCBmb3IgZm9yKVxuICAgIGNvbnN0IHVwZGF0ZWRDb25maWc6IExvb3BTdGVwQ29uZmlnICYgeyB0ZXN0RGF0YVByb2ZpbGVJZD86IHN0cmluZyB8IG51bWJlcjsgdGVtcGxhdGVWYXJpYWJsZXNEYXRhPzogYW55OyBuYXR1cmFsVGV4dEFjdGlvbklkPzogbnVtYmVyIH0gPSB7XG4gICAgICAuLi50aGlzLmNvbmZpZyxcbiAgICAgIHRlc3REYXRhUHJvZmlsZTogdGhpcy50ZXN0RGF0YVByb2ZpbGUsXG4gICAgICB0ZXN0RGF0YVByb2ZpbGVJZDogdGVzdERhdGFQcm9maWxlSWQsIC8vIEFkZCBJRCBmb3IgQVBJIGNhbGxcbiAgICAgIHN0YXJ0U3RlcDogdGhpcy5zdGFydFN0ZXAsXG4gICAgICBlbmRTdGVwOiB0aGlzLmVuZFN0ZXAsXG4gICAgICBjb25kaXRpb246IHRoaXMuY29uZGl0aW9uLFxuICAgICAgbWF4SXRlcmF0aW9uczogdGhpcy5tYXhJdGVyYXRpb25zLFxuICAgICAgLi4uKHRoaXMubG9vcFR5cGUgPT09ICd3aGlsZScgJiYgT2JqZWN0LmtleXModGVtcGxhdGVWYXJpYWJsZXNEYXRhIHx8IHt9KS5sZW5ndGggPiAwICYmIHsgdGVtcGxhdGVWYXJpYWJsZXNEYXRhIH0pLFxuICAgICAgLi4uKHRoaXMubG9vcFR5cGUgPT09ICd3aGlsZScgJiYgbmF0dXJhbFRleHRBY3Rpb25JZCAhPSBudWxsICYmIHsgbmF0dXJhbFRleHRBY3Rpb25JZCB9KSxcbiAgICAgIC4uLih0aGlzLmxvb3BUeXBlID09PSAnZm9yJyAmJiB0ZXN0RGF0YVByb2ZpbGVJZCAhPSBudWxsICYmIHsgZm9yTG9vcFRlc3REYXRhSWQ6IE51bWJlcih0ZXN0RGF0YVByb2ZpbGVJZCkgfSksXG4gICAgICAuLi4odGhpcy5sb29wVHlwZSA9PT0gJ2ZvcicgJiYgdGhpcy5zdGFydFN0ZXAgIT0gbnVsbCAmJiB7IGZvckxvb3BTdGFydEluZGV4OiB0aGlzLnN0YXJ0U3RlcCB9KSxcbiAgICAgIC4uLih0aGlzLmxvb3BUeXBlID09PSAnZm9yJyAmJiB0aGlzLmVuZFN0ZXAgIT0gbnVsbCAmJiB7IGZvckxvb3BFbmRJbmRleDogdGhpcy5lbmRTdGVwIH0pLFxuICAgIH07XG4gICAgXG4gICAgLy8gRW1pdCBpbmRpdmlkdWFsIGNoYW5nZSBldmVudHNcbiAgICB0aGlzLnRlc3REYXRhUHJvZmlsZUNoYW5nZS5lbWl0KHRoaXMudGVzdERhdGFQcm9maWxlKTtcbiAgICB0aGlzLnN0YXJ0U3RlcENoYW5nZS5lbWl0KHRoaXMuc3RhcnRTdGVwID8/IDEpO1xuICAgIHRoaXMuZW5kU3RlcENoYW5nZS5lbWl0KHRoaXMuZW5kU3RlcCA/PyAxKTtcbiAgICBpZiAodGhpcy5sb29wVHlwZSA9PT0gJ3doaWxlJykge1xuICAgICAgdGhpcy5jb25kaXRpb25DaGFuZ2UuZW1pdCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICB0aGlzLm1heEl0ZXJhdGlvbnNDaGFuZ2UuZW1pdCh0aGlzLm1heEl0ZXJhdGlvbnMgPz8gNSk7XG4gICAgfVxuICAgIFxuICAgIC8vIEVtaXQgc3RlcCB1cGRhdGUgZXZlbnQgd2l0aCBmdWxsIGNvbmZpZ1xuICAgIGNvbnNvbGUubG9nKCdMb29wLXN0ZXA6IEVtaXR0aW5nIHN0ZXBVcGRhdGUgZXZlbnQnLCB1cGRhdGVkQ29uZmlnKTtcbiAgICB0aGlzLnN0ZXBVcGRhdGUuZW1pdCh1cGRhdGVkQ29uZmlnKTtcbiAgICBcbiAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgb25FZGl0Q2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMudGVzdERhdGFQcm9maWxlID0gdGhpcy5lZGl0U25hcHNob3QudGVzdERhdGFQcm9maWxlO1xuICAgIHRoaXMuc3RhcnRTdGVwID0gdGhpcy5lZGl0U25hcHNob3Quc3RhcnRTdGVwO1xuICAgIHRoaXMuZW5kU3RlcCA9IHRoaXMuZWRpdFNuYXBzaG90LmVuZFN0ZXA7XG4gICAgdGhpcy5jb25kaXRpb24gPSB0aGlzLmVkaXRTbmFwc2hvdC5jb25kaXRpb247XG4gICAgdGhpcy5tYXhJdGVyYXRpb25zID0gdGhpcy5lZGl0U25hcHNob3QubWF4SXRlcmF0aW9ucztcbiAgICB0aGlzLnNlbGVjdGVkVGVtcGxhdGUgPSB0aGlzLmVkaXRTbmFwc2hvdC5zZWxlY3RlZFRlbXBsYXRlO1xuICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXMgPSB0aGlzLmVkaXRTbmFwc2hvdC50ZW1wbGF0ZVZhcmlhYmxlcyB8fCBbXTtcbiAgICBpZiAodGhpcy50ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0gJiYgdGhpcy5lZGl0U25hcHNob3QuY29uZGl0aW9uVGVtcGxhdGVGb3JtVmFsdWUpIHtcbiAgICAgIHRoaXMudGVtcGxhdGVWYXJpYWJsZXNGb3JtLnBhdGNoVmFsdWUodGhpcy5lZGl0U25hcHNob3QuY29uZGl0aW9uVGVtcGxhdGVGb3JtVmFsdWUpO1xuICAgIH1cbiAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgb25FZGl0SW5EZXB0aCgpOiB2b2lkIHtcbiAgICB0aGlzLm1vcmVPcHRpb25zLmVtaXQoKTtcbiAgICBjb25zdCBpbmRleCA9IHR5cGVvZiB0aGlzLnN0ZXBOdW1iZXIgPT09ICdudW1iZXInID8gdGhpcy5zdGVwTnVtYmVyIDogKHR5cGVvZiB0aGlzLnN0ZXBOdW1iZXIgPT09ICdzdHJpbmcnID8gcGFyc2VJbnQodGhpcy5zdGVwTnVtYmVyLCAxMCkgOiAwKTtcbiAgICB0aGlzLmVkaXRJbkRlcHRoLmVtaXQoeyBzdGVwOiB0aGlzLmNvbmZpZyBhcyBUZXN0Q2FzZVN0ZXBDb25maWcsIGluZGV4OiBpc05hTihpbmRleCkgPyAwIDogaW5kZXggfSk7XG4gIH1cblxuICBvbkxpbmsoKTogdm9pZCB7XG4gICAgLy8gTm90IHVzZWQgaW4gbG9vcCBzdGVwLCBidXQgbmVlZGVkIGZvciByZWN1cnNpdmUgc3RlcCBncm91cHNcbiAgfVxuXG4gIG9uRHVwbGljYXRlKCk6IHZvaWQge1xuICAgIHRoaXMuZHVwbGljYXRlLmVtaXQoKTtcbiAgfVxuXG4gIG9uRGVsZXRlKCk6IHZvaWQge1xuICAgIHRoaXMuZGVsZXRlLmVtaXQoKTtcbiAgfVxuXG4gIG9uU2VsZWN0aW9uQ2hhbmdlKGNoZWNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkID0gY2hlY2tlZDtcbiAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KGNoZWNrZWQpO1xuICB9XG5cbiAgb25Nb3JlT3B0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1vcmVPcHRpb25zLmVtaXQoKTtcbiAgfVxuXG4gIG9uVmlld0RldGFpbHMoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICAgIFxuICAgIGlmICghdGhpcy5jb25maWcuZGVzY3JpcHRpb24gfHwgdGhpcy5jb25maWcuZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudCkge1xuICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLmxvb3BUeXBlID09PSAnZm9yJyA/ICdGT1IgTE9PUCBEZXRhaWxzJyA6ICdXSElMRSBMT09QIERldGFpbHMnO1xuICAgICAgdGhpcy52aWV3RGV0YWlscy5lbWl0KHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRpdGxlLFxuICAgICAgICBkZXNjcmlwdGlvbjogdGhpcy5jb25maWcuZGVzY3JpcHRpb24sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJsb29wLXN0ZXAtcm93IGNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiPlxuICA8IS0tIElubGluZSBFZGl0IE1vZGU6IEZyYW1lIDIxNDcyMjQ5MTAgLSBmbGV4IHJvdywgMTA1NsOXMzYsIGdhcCAxMnB4LCBmbGV4LW5vbmUgLS0+XG4gIDxkaXYgKm5nSWY9XCJpc0VkaXRpbmdcIiBjbGFzcz1cImNxYS1weS0yLjUgY3FhLXB4LTQgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtanVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTMgY3FhLWZsZXgtZ3Jvd1wiPlxuICAgICAgICA8IS0tIExvb3AgVHlwZSBMYWJlbCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjMUMzOThFXSBjcWEtdGV4dC1bMTJweF0gY3FhLWxlYWRpbmctWzE1cHhdXCI+XG4gICAgICAgICAge3sgZ2V0TG9vcFR5cGVMYWJlbCgpIH19XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gRk9SIExPT1AgaW5saW5lIGVkaXQ6IGNxYS1keW5hbWljLXNlbGVjdCAoc2FtZSB1c2FnZSBhcyBkZWZhdWx0IHN0b3JpZXMpIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9vcFR5cGUgPT09ICdmb3InXCI+XG4gICAgICAgICAgPCEtLSBGaXJzdCBzZWxlY3Q6IHdpZHRoIDIxNi4yNXB4LCBoZWlnaHQgMzZweCwgZ2FwIDRweCwgb3BhY2l0eSAxIC0tPlxuICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cImZvck9wdGlvblR5cGVTZWxlY3RDb25maWdcIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1tYXgtdy1bMjE2cHhdXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCBbZm9ybV09XCJlZGl0Rm9ybVwiIFtjb25maWddPVwidGVzdERhdGFQcm9maWxlU2VsZWN0Q29uZmlnXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXctZnVsbCBjcWEtbWF4LXctWzIxNnB4XVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZWRpdEZvcm1cIiBbY29uZmlnXT1cInN0YXJ0U3RlcFNlbGVjdENvbmZpZ1wiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS13LWZ1bGwgY3FhLW1heC13LVsyMTZweF1cIj48L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImVkaXRGb3JtXCIgW2NvbmZpZ109XCJlbmRTdGVwU2VsZWN0Q29uZmlnXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXctZnVsbCBjcWEtbWF4LXctWzIxNnB4XVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFdISUxFIExPT1AgaW5saW5lIGVkaXQ6IGNxYS1hdXRvY29tcGxldGUgKyB0ZW1wbGF0ZSB2YXJpYWJsZXMgKHNhbWUgYXMgY29uZGl0aW9uLXN0ZXApIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNXaGlsZUxvb3AoKVwiPlxuICAgICAgICAgIDxjcWEtYXV0b2NvbXBsZXRlXG4gICAgICAgICAgICAqbmdJZj1cImVkaXRGb3JtXCJcbiAgICAgICAgICAgIFtvcHRpb25zXT1cIndoaWxlQ29uZGl0aW9uQXV0b2NvbXBsZXRlT3B0aW9uc1wiXG4gICAgICAgICAgICBbdmFsdWVdPVwiZWRpdEZvcm0uZ2V0KCdjb25kaXRpb24nKT8udmFsdWUgPz8gJydcIlxuICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uRWRpdEZvcm1GaWVsZENoYW5nZSgnY29uZGl0aW9uJywgJGV2ZW50KVwiXG4gICAgICAgICAgICAob3B0aW9uU2VsZWN0KT1cIm9uQ29uZGl0aW9uU2VsZWN0KCRldmVudClcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgY29uZGl0aW9uXCJcbiAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS13LWZ1bGwgY3FhLW1heC13LVsyMTZweF1cIj5cbiAgICAgICAgICA8L2NxYS1hdXRvY29tcGxldGU+XG4gICAgICAgICAgPCEtLSBUZW1wbGF0ZSB2YXJpYWJsZXMgKHNob3duIHdoZW4gdGVtcGxhdGUgaXMgc2VsZWN0ZWQsIHNhbWUgYXMgY29uZGl0aW9uLXN0ZXApIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRlbXBsYXRlICYmIHRlbXBsYXRlVmFyaWFibGVzICYmIHRlbXBsYXRlVmFyaWFibGVzLmxlbmd0aCA+IDBcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LXJvdyBjcWEtZmxleC13cmFwIGNxYS1nYXAtM1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdmFyaWFibGUgb2YgdGVtcGxhdGVWYXJpYWJsZXNcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInZhcmlhYmxlLnR5cGUgPT09ICdib29sZWFuJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMFwiPnt7IHZhcmlhYmxlLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInRlbXBsYXRlVmFyaWFibGVzRm9ybS5nZXQodmFyaWFibGUubmFtZSk/LnZhbHVlIHx8IHZhcmlhYmxlLnZhbHVlIHx8IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ0ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0uZ2V0KHZhcmlhYmxlLm5hbWUpPy5zZXRWYWx1ZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2YXJpYWJsZS50eXBlICE9PSAnYm9vbGVhbicgJiYgdmFyaWFibGUubmFtZSAhPT0gJ2N1c3RvbV9jb2RlJ1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2YXJpYWJsZS5uYW1lID09PSAndHlwZScgfHwgdmFyaWFibGUubmFtZSA9PT0gJ3Njcm9sbFRvJyB8fCB2YXJpYWJsZS5vcHRpb25zXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCIgc3R5bGU9XCJtaW4td2lkdGg6IDE1MHB4O1wiPlxuICAgICAgICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgW2Zvcm1dPVwidGVtcGxhdGVWYXJpYWJsZXNGb3JtXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZ0ZvclZhcmlhYmxlKHZhcmlhYmxlKVwiPlxuICAgICAgICAgICAgICAgICAgICA8L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2YXJpYWJsZS5uYW1lICE9PSAndHlwZScgJiYgdmFyaWFibGUubmFtZSAhPT0gJ3Njcm9sbFRvJyAmJiAhdmFyaWFibGUub3B0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiIHN0eWxlPVwibWluLXdpZHRoOiAxNTBweDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0VudGVyICcgKyB2YXJpYWJsZS5sYWJlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInRlbXBsYXRlVmFyaWFibGVzRm9ybS5nZXQodmFyaWFibGUubmFtZSk/LnZhbHVlIHx8IHZhcmlhYmxlLnZhbHVlIHx8ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJ0ZW1wbGF0ZVZhcmlhYmxlc0Zvcm0uZ2V0KHZhcmlhYmxlLm5hbWUpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIEVkaXQgSW4gZGVwdGggbGluayAtLT5cbiAgICAgIDxhIGhyZWY9XCIjXCIgKGNsaWNrKT1cIm9uRWRpdEluRGVwdGgoKTsgJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIlxuICAgICAgICBjbGFzcz1cImNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC1bMTBweF0gY3FhLWxlYWRpbmctWzE1cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtWzJweF0gY3FhLW5vLXVuZGVybGluZVwiPlxuICAgICAgICBFZGl0IEluIGRlcHRoXG4gICAgICAgIDxzdmcgd2lkdGg9XCI4XCIgaGVpZ2h0PVwiOFwiIHZpZXdCb3g9XCIwIDAgOCA4XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgIGQ9XCJNMi4wMzgwOSA2Ljc0MzI5TDIuNjI4MDkgNy4zMzMyOUw1Ljk2MTQyIDMuOTk5OTZMMi42MjgwOSAwLjY2NjYyNkwyLjAzODA5IDEuMjU2NjNMNC43ODE0MiAzLjk5OTk2TDIuMDM4MDkgNi43NDMyOVpcIlxuICAgICAgICAgICAgZmlsbD1cIiMzRjQzRUVcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvYT5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICA8IS0tIENhbmNlbCAvIEFwcGx5IC0tPlxuICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgYnRuU2l6ZT1cImxnXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtdGV4dC1bMTRweF0gY3FhLXB5LVs5cHhdJ1wiIFt0ZXh0XT1cIidDYW5jZWwnXCJcbiAgICAgICAgKGNsaWNrZWQpPVwib25FZGl0Q2FuY2VsKClcIj48L2NxYS1idXR0b24+XG4gICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgYnRuU2l6ZT1cImxnXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtdGV4dC1bMTRweF0gY3FhLXB5LVs5cHhdJ1wiIFt0ZXh0XT1cIidBcHBseSdcIlxuICAgICAgICAoY2xpY2tlZCk9XCJvbkVkaXRBcHBseSgpXCI+PC9jcWEtYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwhLS0gTG9vcCBIZWFkZXIgKG5vcm1hbCB2aWV3IHdoZW4gbm90IGVkaXRpbmcpIC0tPlxuICA8ZGl2ICpuZ0lmPVwiIWlzRWRpdGluZ1wiXG4gICAgW2NsYXNzXT1cIidzdGVwLXJvdyBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtcHktMiAnICsgKGlzSW5zaWRlTG9vcCA/ICdjcWEtcGwtMTAgY3FhLXByLTQnIDogJ2NxYS1weC00JylcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWlubGluZS1mbGV4IGNxYS1pdGVtcy1jZW50ZXJcIj5cbiAgICA8IS0tIERyYWcgSGFuZGxlIEljb24gKHdoZW4gaXNSZW9yZGVyIGlzIHRydWUpIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJpc1Jlb3JkZXJcIiBjbGFzcz1cImNxYS1tci0yIGNxYS1jdXJzb3ItbW92ZSBjcWEtdGV4dC1bIzZCNzI4MF0gaG92ZXI6Y3FhLXRleHQtWyMxMTE4MjddXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjNcIiBjeT1cIjNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjhcIiBjeT1cIjNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjEzXCIgY3k9XCIzXCIgcj1cIjEuNVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIi8+XG4gICAgICAgIDxjaXJjbGUgY3g9XCIzXCIgY3k9XCI4XCIgcj1cIjEuNVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIi8+XG4gICAgICAgIDxjaXJjbGUgY3g9XCI4XCIgY3k9XCI4XCIgcj1cIjEuNVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIi8+XG4gICAgICAgIDxjaXJjbGUgY3g9XCIxM1wiIGN5PVwiOFwiIHI9XCIxLjVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiM1wiIGN5PVwiMTNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgICAgPGNpcmNsZSBjeD1cIjhcIiBjeT1cIjEzXCIgcj1cIjEuNVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIi8+XG4gICAgICAgIDxjaXJjbGUgY3g9XCIxM1wiIGN5PVwiMTNcIiByPVwiMS41XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICAgIDwhLS0gQ2hlY2tib3ggKHdoZW4gaXNSZW9yZGVyIGlzIGZhbHNlKSAtLT5cbiAgICA8bGFiZWwgKm5nSWY9XCIhaXNSZW9yZGVyXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1jdXJzb3ItcG9pbnRlciBjcWEtcmVsYXRpdmUgY3FhLW1yLTJcIj5cbiAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFwiXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKCRldmVudClcIlxuICAgICAgICBjbGFzcz1cImNxYS1oLTQgY3FhLXctNCBjcWEtY3Vyc29yLXBvaW50ZXIgY3FhLXRyYW5zaXRpb24tYWxsIGNxYS1hcHBlYXJhbmNlLW5vbmUgY3FhLXJvdW5kZWQgc2hhZG93IGhvdmVyOmNxYS1zaGFkb3ctbWQgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItc2xhdGUtMzAwIGNxYS1mbGV4LXNocmluay0wXCJcbiAgICAgICAgW2NsYXNzLmNxYS1iZy1bIzNGNDNFRV1dPVwic2VsZWN0ZWRcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci1bIzNGNDNFRV1dPVwic2VsZWN0ZWRcIlxuICAgICAgICBpZD1cImNoZWNrLWxvb3Atc3RlcFwiIC8+XG4gICAgICA8c3BhbiBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtdGV4dC13aGl0ZSBjcWEtdG9wLTEvMiBjcWEtbGVmdC0xLzIgY3FhLS10cmFuc2xhdGUteC0xLzIgY3FhLS10cmFuc2xhdGUteS0xLzIgY3FhLXBvaW50ZXItZXZlbnRzLW5vbmUgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXJcIlxuICAgICAgICBbY2xhc3MuY3FhLW9wYWNpdHktMF09XCIhc2VsZWN0ZWRcIlxuICAgICAgICBbY2xhc3MuY3FhLW9wYWNpdHktMTAwXT1cInNlbGVjdGVkXCI+XG4gICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjEzXCIgdmlld0JveD1cIjAgMCAxMiAxM1wiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPjxwYXRoIGQ9XCJNMTAgMy4xMjVMNC41IDguNjI1TDIgNi4xMjVcIiBzdHJva2U9XCJ3aGl0ZVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz48L3N2Zz5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L2xhYmVsPlxuICAgIDwvZGl2PlxuICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWyM2QjcyODBdIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMThweF0gY3FhLW1pbi13LVszMnB4XVwiPnt7IHN0ZXBOdW1iZXIgfX08L3NwYW4+XG4gICAgPCEtLSBFeHBhbmQvQ29sbGFwc2UgSWNvbiAtLT5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25Ub2dnbGVFeHBhbmRlZCgpXCIgY2xhc3M9XCJjcWEtcC0wXCI+XG4gICAgICA8c3ZnIFtjbGFzcy5jcWEtcm90YXRlLTE4MF09XCIhZXhwYW5kZWRcIiBjbGFzcz1cImNxYS10cmFuc2l0aW9uLXRyYW5zZm9ybVwiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiXG4gICAgICAgIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xMiAxMEw4IDZMNCAxMFwiIHN0cm9rZT1cIiM2QjcyODBcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPC9zdmc+XG4gICAgPC9idXR0b24+XG5cbiAgICA8IS0tIFN0ZXAgTnVtYmVyIC0tPlxuICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWyM2QjcyODBdIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMThweF0gY3FhLW1pbi13LVszMnB4XSBjcWEtZmxleC1zaHJpbmstMFwiPnt7IHN0ZXBOdW1iZXIgfX08L3NwYW4+XG5cbiAgICA8IS0tIExvb3AgSWNvbiAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibG9vcFR5cGUgPT09ICdmb3InXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xMS4zMzQgMS4zMzMyNUwxNC4wMDA3IDMuOTk5OTJMMTEuMzM0IDYuNjY2NTlcIiBzdHJva2U9XCIjMUMzOThFXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiXG4gICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPHBhdGggZD1cIk0yIDcuMzMzMzNWNi42NjY2N0MyIDUuOTU5NDIgMi4yODA5NSA1LjI4MTE1IDIuNzgxMDUgNC43ODEwNUMzLjI4MTE1IDQuMjgwOTUgMy45NTk0MiA0IDQuNjY2NjcgNEgxNFwiXG4gICAgICAgICAgc3Ryb2tlPVwiIzFDMzk4RVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8cGF0aCBkPVwiTTQuNjY2NjcgMTQuNjY2NkwyIDExLjk5OTlMNC42NjY2NyA5LjMzMzI1XCIgc3Ryb2tlPVwiIzFDMzk4RVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIlxuICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgZD1cIk0xNCA4LjY2Njc1VjkuMzMzNDFDMTQgMTAuMDQwNyAxMy43MTkgMTAuNzE4OSAxMy4yMTkgMTEuMjE5QzEyLjcxODkgMTEuNzE5MSAxMi4wNDA2IDEyLjAwMDEgMTEuMzMzMyAxMi4wMDAxSDJcIlxuICAgICAgICAgIHN0cm9rZT1cIiMxQzM5OEVcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJsb29wVHlwZSA9PT0gJ3doaWxlJ1wiPlxuICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNMTEuMzM0IDEuMzMzMjVMMTQuMDAwNyAzLjk5OTkyTDExLjMzNCA2LjY2NjU5XCIgc3Ryb2tlPVwiIzU5MTY4QlwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIlxuICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoIGQ9XCJNMiA3LjMzMzMzVjYuNjY2NjdDMiA1Ljk1OTQyIDIuMjgwOTUgNS4yODExNSAyLjc4MTA1IDQuNzgxMDVDMy4yODExNSA0LjI4MDk1IDMuOTU5NDIgNCA0LjY2NjY3IDRIMTRcIlxuICAgICAgICAgIHN0cm9rZT1cIiM1OTE2OEJcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPHBhdGggZD1cIk00LjY2NjY3IDE0LjY2NjZMMiAxMS45OTk5TDQuNjY2NjcgOS4zMzMyNVwiIHN0cm9rZT1cIiM1OTE2OEJcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCJcbiAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8cGF0aFxuICAgICAgICAgIGQ9XCJNMTQgOC42NjY3NVY5LjMzMzQxQzE0IDEwLjA0MDcgMTMuNzE5IDEwLjcxODkgMTMuMjE5IDExLjIxOUMxMi43MTg5IDExLjcxOTEgMTIuMDQwNiAxMi4wMDAxIDExLjMzMzMgMTIuMDAwMUgyXCJcbiAgICAgICAgICBzdHJva2U9XCIjNTkxNjhCXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICA8L3N2Zz5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gTG9vcCBUeXBlIExhYmVsIC0tPlxuICAgIDxzcGFuIGNsYXNzPVwiY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtWyMxQzM5OEVdIGNxYS10ZXh0LVsxMnB4XSBjcWEtbGVhZGluZy1ub25lXCI+XG4gICAgICB7eyBnZXRMb29wVHlwZUxhYmVsKCkgfX1cbiAgICA8L3NwYW4+XG5cbiAgICA8IS0tIEZvciBMb29wIENvbnRyb2xzIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJsb29wVHlwZSA9PT0gJ2ZvcidcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS1tbC0yXCI+XG4gICAgICA8IS0tIFRlc3QgRGF0YSBQcm9maWxlIEJ1dHRvbiAtLT5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtjbGFzcy5jcWEtYmctcHJpbWFyeS0xMDBdPVwidGVzdERhdGFQcm9maWxlXCIgW2NsYXNzLmNxYS10ZXh0LXByaW1hcnldPVwidGVzdERhdGFQcm9maWxlXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHktMC41IGNxYS1weC0yIGNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjOEE4Q0Y0XSBjcWEtcm91bmRlZCBjcWEtYmctWyNEOEQ5RkNdXCI+XG4gICAgICAgIHt7IGdldFRlc3REYXRhUHJvZmlsZUxhYmVsKCkgfX1cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIFN0YXJ0IEJ1dHRvbiAtLT5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtjbGFzcy5jcWEtYmctcHJpbWFyeS0xMDBdPVwic3RhcnRTdGVwXCIgW2NsYXNzLmNxYS10ZXh0LXByaW1hcnldPVwic3RhcnRTdGVwXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHktMC41IGNxYS1weC0yIGNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjOEE4Q0Y0XSBjcWEtcm91bmRlZCBjcWEtYmctWyNEOEQ5RkNdXCI+XG4gICAgICAgIHt7IGdldFN0YXJ0U3RlcExhYmVsKCkgfX1cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8IS0tIEVuZCBCdXR0b24gLS0+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBbY2xhc3MuY3FhLWJnLXByaW1hcnktMTAwXT1cImVuZFN0ZXBcIiBbY2xhc3MuY3FhLXRleHQtcHJpbWFyeV09XCJlbmRTdGVwXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHktMC41IGNxYS1weC0yIGNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjOEE4Q0Y0XSBjcWEtcm91bmRlZCBjcWEtYmctWyNEOEQ5RkNdXCI+XG4gICAgICAgIHt7IGdldEVuZFN0ZXBMYWJlbCgpIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gV2hpbGUgTG9vcCBDb25kaXRpb24gKG9ubHkgc2hvdyBpZiBjb25kaXRpb24gZXhpc3RzKSAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNXaGlsZUxvb3AoKSAmJiBjb25kaXRpb25cIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS1tbC0yIGNxYS1mbGV4LTFcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtZ3JheS03MDAgY3FhLXRleHQtc21cIj5cbiAgICAgICAgV2hpbGVcbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtZ3JheS05MDAgY3FhLXRleHQtc21cIiBbaW5uZXJIVE1MXT1cImdldENvbmRpdGlvbkRpc3BsYXkoKVwiPjwvc3Bhbj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gU3RlcHMgU3VtbWFyeSAtLT5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImNxYS1tbC1hdXRvIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjRTVFNUU1XSBjcWEtcm91bmRlZC1sZyBjcWEtcHktMC41IGNxYS1weC0yIGNxYS10ZXh0LVsjMEEwQTBBXSBjcWEtdGV4dC1bMTJweF0gY3FhLWxlYWRpbmctWzE1cHhdXCI+XG4gICAgICB7eyBnZXRTdGVwc1N1bW1hcnkoKSB9fVxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0zIGNxYS1tbC1hdXRvXCI+XG4gICAgICA8IS0tIFZpZXcgRGV0YWlscyBMaW5rIChzaG93IG9ubHkgaWYgZGVzY3JpcHRpb24gaXMgbm90IGVtcHR5KSAtLT5cbiAgICAgIDxhICpuZ0lmPVwiY29uZmlnLmRlc2NyaXB0aW9uICYmIGNvbmZpZy5kZXNjcmlwdGlvbi50cmltKCkgIT09ICcnXCIgI3ZpZXdEZXRhaWxzVHJpZ2dlciBocmVmPVwiI1wiIChjbGljayk9XCJvblZpZXdEZXRhaWxzKCRldmVudClcIiBjbGFzcz1cImNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC1bMTBweF0gY3FhLWxlYWRpbmctWzE1cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtbm8tdW5kZXJsaW5lIGNxYS1tbC1hdXRvXCI+VmlldyBEZXRhaWxzPHN2ZyB3aWR0aD1cIjhcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCA4IDhcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj48cGF0aCBkPVwiTTIuMDM4MDkgNi43NDMyOUwyLjYyODA5IDcuMzMzMjlMNS45NjE0MiAzLjk5OTk2TDIuNjI4MDkgMC42NjY2MjZMMi4wMzgwOSAxLjI1NjYzTDQuNzgxNDIgMy45OTk5NkwyLjAzODA5IDYuNzQzMjlaXCIgZmlsbD1cIiMzRjQzRUVcIi8+PC9zdmc+PC9hPlxuXG4gICAgICA8IS0tIEFjdGlvbiBJY29uczogRWRpdCwgTGluaywgRHVwbGljYXRlLCBEZWxldGUgKHNob3cgb24gaG92ZXIpIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInN0ZXAtYWN0aW9ucyBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtcHgtWzdweF1cIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uRWRpdCgpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiB0aXRsZT1cIkVkaXRcIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLXAtMCBjcWEtdGV4dC1bIzk5QTFBZl0gaG92ZXI6Y3FhLXRleHQtWyMxNDQ3RTZdXCI+XG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTcgMTEuNjY2NkgxMi4yNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMTY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgZD1cIk05LjU1MjA4IDIuMTEyOEM5Ljc4NDMgMS44ODA1OCAxMC4wOTkzIDEuNzUwMTIgMTAuNDI3NyAxLjc1MDEyQzEwLjc1NjEgMS43NTAxMiAxMS4wNzEgMS44ODA1OCAxMS4zMDMzIDIuMTEyOEMxMS41MzU1IDIuMzQ1MDIgMTEuNjY1OSAyLjY1OTk4IDExLjY2NTkgMi45ODgzOEMxMS42NjU5IDMuMzE2NzkgMTEuNTM1NSAzLjYzMTc1IDExLjMwMzMgMy44NjM5N0w0LjI5NzQyIDEwLjg3MDRDNC4xNTg2NCAxMS4wMDkyIDMuOTg3MSAxMS4xMTA3IDMuNzk4NjcgMTEuMTY1NkwyLjEyMzMzIDExLjY1NDRDMi4wNzMxNCAxMS42NjkgMi4wMTk5MyAxMS42Njk5IDEuOTY5MjggMTEuNjU2OUMxLjkxODYzIDExLjY0MzkgMS44NzI0IDExLjYxNzYgMS44MzU0MyAxMS41ODA2QzEuNzk4NDYgMTEuNTQzNyAxLjc3MjEgMTEuNDk3NCAxLjc1OTEzIDExLjQ0NjhDMS43NDYxNSAxMS4zOTYxIDEuNzQ3MDMgMTEuMzQyOSAxLjc2MTY3IDExLjI5MjdMMi4yNTA1IDkuNjE3MzhDMi4zMDU0NiA5LjQyOTE2IDIuNDA2OTggOS4yNTc4MyAyLjU0NTY3IDkuMTE5MjJMOS41NTIwOCAyLjExMjhaXCJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8IS0tIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkxpbmsoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJMaW5rXCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1wLTAgY3FhLXRleHQtWyM5OUExQWZdIGhvdmVyOmNxYS10ZXh0LVsjMTQ0N0U2XVwiPlxuICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAxNCAxNFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgZD1cIk01LjAwMDY1IDkuOTE2NzFIMy42NjczMkMyLjc4MzI2IDkuOTE2NzEgMS45MzU0MiA5LjYwOTQyIDEuMzEwMyA5LjA2MjQ0QzAuNjg1MTc0IDguNTE1NDUgMC4zMzM5ODQgNy43NzM1OSAwLjMzMzk4NCA3LjAwMDA0QzAuMzMzOTg0IDYuMjI2NDkgMC42ODUxNzQgNS40ODQ2MyAxLjMxMDMgNC45Mzc2NUMxLjkzNTQyIDQuMzkwNjYgMi43ODMyNiA0LjA4MzM3IDMuNjY3MzIgNC4wODMzN0g1LjAwMDY1XCJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICBkPVwiTTkgNC4wODMzN0gxMC4zMzMzQzExLjIxNzQgNC4wODMzNyAxMi4wNjUyIDQuMzkwNjYgMTIuNjkwNCA0LjkzNzY1QzEzLjMxNTUgNS40ODQ2MyAxMy42NjY3IDYuMjI2NDkgMTMuNjY2NyA3LjAwMDA0QzEzLjY2NjcgNy43NzM1OSAxMy4zMTU1IDguNTE1NDUgMTIuNjkwNCA5LjA2MjQ0QzEyLjA2NTIgOS42MDk0MiAxMS4yMTc0IDkuOTE2NzEgMTAuMzMzMyA5LjkxNjcxSDlcIlxuICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9XCJNNC4zMzM5OCA3SDkuNjY3MzJcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9idXR0b24+IC0tPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25EdXBsaWNhdGUoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJEdXBsaWNhdGVcIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLXAtMCBjcWEtdGV4dC1bIzk5QTFBZl0gaG92ZXI6Y3FhLXRleHQtWyMxNDQ3RTZdXCI+XG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICBkPVwiTTExLjY2NiA0LjY2NjYzSDUuODMyNjhDNS4xODgzNSA0LjY2NjYzIDQuNjY2MDIgNS4xODg5NiA0LjY2NjAyIDUuODMzMjlWMTEuNjY2NkM0LjY2NjAyIDEyLjMxMSA1LjE4ODM1IDEyLjgzMzMgNS44MzI2OCAxMi44MzMzSDExLjY2NkMxMi4zMTAzIDEyLjgzMzMgMTIuODMyNyAxMi4zMTEgMTIuODMyNyAxMS42NjY2VjUuODMzMjlDMTIuODMyNyA1LjE4ODk2IDEyLjMxMDMgNC42NjY2MyAxMS42NjYgNC42NjY2M1pcIlxuICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjE2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgIGQ9XCJNMi4zMzI2OCA5LjMzMzI5QzEuNjkxMDIgOS4zMzMyOSAxLjE2NjAyIDguODA4MjkgMS4xNjYwMiA4LjE2NjYzVjIuMzMzMjlDMS4xNjYwMiAxLjY5MTYzIDEuNjkxMDIgMS4xNjY2MyAyLjMzMjY4IDEuMTY2NjNIOC4xNjYwMkM4LjgwNzY4IDEuMTY2NjMgOS4zMzI2OCAxLjY5MTYzIDkuMzMyNjggMi4zMzMyOVwiXG4gICAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMTY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uRGVsZXRlKCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIHRpdGxlPVwiRGVsZXRlXCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1wLTAgY3FhLXRleHQtWyNmZjY0NjddIGhvdmVyOmNxYS10ZXh0LVsjQzYzNTM1XVwiPlxuICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAxNCAxNFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICAgPHBhdGggZD1cIk0xLjc1IDMuNUgxMi4yNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMTY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgZD1cIk0xMS4wODI3IDMuNVYxMS42NjY3QzExLjA4MjcgMTIuMjUgMTAuNDk5MyAxMi44MzMzIDkuOTE2MDIgMTIuODMzM0g0LjA4MjY4QzMuNDk5MzUgMTIuODMzMyAyLjkxNjAyIDEyLjI1IDIuOTE2MDIgMTEuNjY2N1YzLjVcIlxuICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjE2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgIGQ9XCJNNC42NjYwMiAzLjQ5OTk2VjIuMzMzMjlDNC42NjYwMiAxLjc0OTk2IDUuMjQ5MzUgMS4xNjY2MyA1LjgzMjY4IDEuMTY2NjNIOC4xNjYwMkM4Ljc0OTM1IDEuMTY2NjMgOS4zMzI2OCAxLjc0OTk2IDkuMzMyNjggMi4zMzMyOVYzLjQ5OTk2XCJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTUuODMzOTggNi40MTY2M1Y5LjkxNjYzXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTguMTY2MDIgNi40MTY2M1Y5LjkxNjYzXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS4xNjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwhLS0gRXhwYW5kZWQgQ29udGVudCB3aXRoIE5lc3RlZCBTdGVwcyAocmVuZGVyZXIgZGlzcGF0Y2hlcyBieSBzdGVwIHR5cGUsIG4tbGV2ZWwgbmVzdGluZykgLS0+XG4gIDxkaXYgKm5nSWY9XCJleHBhbmRlZFwiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCI+XG4gICAgPGRpdiAqbmdJZj1cIiFpc1Jlb3JkZXJcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiPlxuICAgICAgPGNxYS10ZXN0LWNhc2UtZGV0YWlscy1yZW5kZXJlciAqbmdGb3I9XCJsZXQgc3RlcCBvZiBuZXN0ZWRTdGVwczsgbGV0IGkgPSBpbmRleFwiIFtzdGVwXT1cInN0ZXBcIiBbaW5kZXhdPVwiaVwiXG4gICAgICAgIFtzZWxlY3RlZF09XCIkYW55KHN0ZXApLnNlbGVjdGVkXCJcbiAgICAgICAgW2lzTmVzdGVkXT1cInRydWVcIiBbaXNJbnNpZGVMb29wXT1cInRydWVcIiBbaXNSZW9yZGVyXT1cImlzUmVvcmRlclwiXG4gICAgICAgIFthZGRTdGVwQmV0d2Vlbl09XCJhZGRTdGVwQmV0d2VlblwiXG4gICAgICAgIFtkYXRhUHJvZmlsZU9wdGlvbnNdPVwiZGF0YVByb2ZpbGVPcHRpb25zXCIgW2hhc01vcmVEYXRhUHJvZmlsZXNdPVwiaGFzTW9yZURhdGFQcm9maWxlc1wiIFtpc0xvYWRpbmdEYXRhUHJvZmlsZXNdPVwiaXNMb2FkaW5nRGF0YVByb2ZpbGVzXCJcbiAgICAgICAgW25hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnNdPVwibmF0dXJhbFRleHRBY3Rpb25zT3B0aW9uc1wiXG4gICAgICAgIChuZXN0ZWRTdGVwQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZSgkZXZlbnQuc3RlcCwgJGV2ZW50LmluZGV4KVwiXG4gICAgICAgIChhZGRTdGVwKT1cIm9uQWRkU3RlcCgpXCIgKGRlbGV0ZVN0ZXApPVwib25EZWxldGVTdGVwKCRldmVudClcIlxuICAgICAgICAodG9nZ2xlRXhwYW5kZWQpPVwib25OZXN0ZWRUb2dnbGVFeHBhbmRlZCgkZXZlbnQsIHN0ZXAsIGkpXCJcbiAgICAgICAgKGdyb3VwTmFtZUNoYW5nZSk9XCIkYW55KHN0ZXApLmdyb3VwTmFtZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKGRlc2NyaXB0aW9uQ2hhbmdlKT1cIiRhbnkoc3RlcCkuZGVzY3JpcHRpb24gPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChyZXVzYWJsZUNoYW5nZSk9XCIkYW55KHN0ZXApLnJldXNhYmxlID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAob3BlbkV4dGVybmFsKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChlZGl0KT1cIm9uTmVzdGVkRWRpdCgkZXZlbnQpXCJcbiAgICAgICAgKGxpbmspPVwib25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCIgKGR1cGxpY2F0ZSk9XCJvbk5lc3RlZER1cGxpY2F0ZSgkZXZlbnQsIHN0ZXApXCIgKGRlbGV0ZSk9XCJvbkRlbGV0ZVN0ZXAoJGV2ZW50LCBpKVwiXG4gICAgICAgICh2aWV3RGV0YWlscyk9XCJ2aWV3RGV0YWlscy5lbWl0KCRldmVudClcIlxuICAgICAgICAoY29uZGl0aW9uQ2hhbmdlKT1cIiRhbnkoc3RlcCkuY29uZGl0aW9uID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAoYnJhbmNoU3RlcENoYW5nZSk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIiAoYWRkQnJhbmNoKT1cIm9uTmVzdGVkQ29uZGl0aW9uQWRkQnJhbmNoKCRhbnkoc3RlcCksIGkpXCJcbiAgICAgICAgKGRlbGV0ZUJyYW5jaCk9XCJvbk5lc3RlZENvbmRpdGlvbkRlbGV0ZUJyYW5jaCgkYW55KHN0ZXApLCAkZXZlbnQsIGkpXCJcbiAgICAgICAgKHRlc3REYXRhUHJvZmlsZUNoYW5nZSk9XCIkYW55KHN0ZXApLnRlc3REYXRhUHJvZmlsZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKHN0YXJ0U3RlcENoYW5nZSk9XCIkYW55KHN0ZXApLnN0YXJ0U3RlcCA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKGVuZFN0ZXBDaGFuZ2UpPVwiJGFueShzdGVwKS5lbmRTdGVwID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAobWF4SXRlcmF0aW9uc0NoYW5nZSk9XCIkYW55KHN0ZXApLm1heEl0ZXJhdGlvbnMgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChldmVudFR5cGVDaGFuZ2UpPVwiJGFueShzdGVwKS5ldmVudFR5cGUgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgIChwYXJhbWV0ZXJDaGFuZ2UpPVwib25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCIkYW55KHN0ZXApLnNlbGVjdGVkID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAobG9hZE1vcmVEYXRhUHJvZmlsZXMpPVwibG9hZE1vcmVEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHNlYXJjaERhdGFQcm9maWxlcyk9XCJzZWFyY2hEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGRuZERyb3BJblpvbmUpPVwiZG5kRHJvcEluWm9uZS5lbWl0KCRldmVudClcIlxuICAgICAgICAoY2xpY2tBY3Rpb24pPVwiY2xpY2tBY3Rpb24uZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGVkaXRJbkRlcHRoKT1cImVkaXRJbkRlcHRoLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChhZGRTdGVwQmV0d2VlbkNsaWNrKT1cImFkZFN0ZXBCZXR3ZWVuQ2xpY2suZW1pdCgkZXZlbnQpXCI+XG4gICAgICA8L2NxYS10ZXN0LWNhc2UtZGV0YWlscy1yZW5kZXJlcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNSZW9yZGVyXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgbmVzdGVkLXN0ZXAtZHJvcC1saXN0XCJcbiAgICAgICAgIFtkbmREcm9wem9uZV09XCJbJ3N0ZXAnXVwiXG4gICAgICAgICBkbmRFZmZlY3RBbGxvd2VkPVwibW92ZVwiXG4gICAgICAgICBkbmREcmFnb3ZlckNsYXNzPVwiZG5kRHJhZ292ZXJcIlxuICAgICAgICAgKGRuZERyb3ApPVwib25EbmREcm9wKCRldmVudClcIj5cbiAgICAgIDxkaXYgZG5kUGxhY2Vob2xkZXJSZWYgY2xhc3M9XCJzdGVwLWRyYWctcGxhY2Vob2xkZXItbmVzdGVkIGNxYS1teS0xIGNxYS1taW4taC1bNTBweF0gY3FhLWJvcmRlci0yIGNxYS1ib3JkZXItZGFzaGVkIGNxYS1ib3JkZXItWyMzRjQzRUVdIGNxYS1yb3VuZGVkIGNxYS1iZy1bcmdiYSg2Myw2NywyMzgsMC4wOCldIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS10ZXh0LVsjM0Y0M0VFXSBjcWEtdGV4dC14c1wiPkRyb3AgaGVyZTwvZGl2PlxuICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgc3RlcCBvZiBuZXN0ZWRTdGVwczsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwibmVzdGVkLXN0ZXAtZHJhZy1pdGVtXCJcbiAgICAgICAgICAgW2RuZERyYWdnYWJsZV09XCJzdGVwXCJcbiAgICAgICAgICAgZG5kRWZmZWN0QWxsb3dlZD1cIm1vdmVcIlxuICAgICAgICAgICBkbmRUeXBlPVwic3RlcFwiPlxuICAgICAgICA8Y3FhLXRlc3QtY2FzZS1kZXRhaWxzLXJlbmRlcmVyIFtzdGVwXT1cInN0ZXBcIiBbaW5kZXhdPVwiaVwiXG4gICAgICAgICAgW3NlbGVjdGVkXT1cIiRhbnkoc3RlcCkuc2VsZWN0ZWRcIlxuICAgICAgICAgIFtpc05lc3RlZF09XCJ0cnVlXCIgW2lzSW5zaWRlTG9vcF09XCJ0cnVlXCIgW2lzUmVvcmRlcl09XCJpc1Jlb3JkZXJcIlxuICAgICAgICAgIFthZGRTdGVwQmV0d2VlbkFib3ZlXT1cImFkZFN0ZXBCZXR3ZWVuQWJvdmVcIlxuICAgICAgICAgIFthZGRTdGVwQmV0d2VlbkJlbG93XT1cImFkZFN0ZXBCZXR3ZWVuQmVsb3dcIlxuICAgICAgICAgIFthZGRTdGVwQmV0d2Vlbl09XCJhZGRTdGVwQmV0d2VlblwiXG4gICAgICAgICAgW2RhdGFQcm9maWxlT3B0aW9uc109XCJkYXRhUHJvZmlsZU9wdGlvbnNcIiBbaGFzTW9yZURhdGFQcm9maWxlc109XCJoYXNNb3JlRGF0YVByb2ZpbGVzXCIgW2lzTG9hZGluZ0RhdGFQcm9maWxlc109XCJpc0xvYWRpbmdEYXRhUHJvZmlsZXNcIlxuICAgICAgICAgIFtuYXR1cmFsVGV4dEFjdGlvbnNPcHRpb25zXT1cIm5hdHVyYWxUZXh0QWN0aW9uc09wdGlvbnNcIlxuICAgICAgICAgIChuZXN0ZWRTdGVwQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZSgkZXZlbnQuc3RlcCwgJGV2ZW50LmluZGV4KVwiXG4gICAgICAgICAgKGFkZFN0ZXApPVwib25BZGRTdGVwKClcIiAoZGVsZXRlU3RlcCk9XCJvbkRlbGV0ZVN0ZXAoJGV2ZW50KVwiXG4gICAgICAgICAgKHRvZ2dsZUV4cGFuZGVkKT1cIm9uTmVzdGVkVG9nZ2xlRXhwYW5kZWQoJGV2ZW50LCBzdGVwLCBpKVwiXG4gICAgICAgICAgKGdyb3VwTmFtZUNoYW5nZSk9XCIkYW55KHN0ZXApLmdyb3VwTmFtZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAoZGVzY3JpcHRpb25DaGFuZ2UpPVwiJGFueShzdGVwKS5kZXNjcmlwdGlvbiA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAocmV1c2FibGVDaGFuZ2UpPVwiJGFueShzdGVwKS5yZXVzYWJsZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAob3BlbkV4dGVybmFsKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChlZGl0KT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgICAgKGxpbmspPVwib25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCIgKGR1cGxpY2F0ZSk9XCJvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIiAoZGVsZXRlKT1cIm9uRGVsZXRlU3RlcCgkZXZlbnQsIGkpXCJcbiAgICAgICAgICAodmlld0RldGFpbHMpPVwidmlld0RldGFpbHMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAoY29uZGl0aW9uQ2hhbmdlKT1cIiRhbnkoc3RlcCkuY29uZGl0aW9uID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChicmFuY2hTdGVwQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiIChhZGRCcmFuY2gpPVwib25OZXN0ZWRDb25kaXRpb25BZGRCcmFuY2goJGFueShzdGVwKSwgaSlcIlxuICAgICAgICAgIChkZWxldGVCcmFuY2gpPVwib25OZXN0ZWRDb25kaXRpb25EZWxldGVCcmFuY2goJGFueShzdGVwKSwgJGV2ZW50LCBpKVwiXG4gICAgICAgICAgKHRlc3REYXRhUHJvZmlsZUNoYW5nZSk9XCIkYW55KHN0ZXApLnRlc3REYXRhUHJvZmlsZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAoc3RhcnRTdGVwQ2hhbmdlKT1cIiRhbnkoc3RlcCkuc3RhcnRTdGVwID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAgIChlbmRTdGVwQ2hhbmdlKT1cIiRhbnkoc3RlcCkuZW5kU3RlcCA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAobWF4SXRlcmF0aW9uc0NoYW5nZSk9XCIkYW55KHN0ZXApLm1heEl0ZXJhdGlvbnMgPSAkZXZlbnQ7IG9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgICAgKGV2ZW50VHlwZUNoYW5nZSk9XCIkYW55KHN0ZXApLmV2ZW50VHlwZSA9ICRldmVudDsgb25OZXN0ZWRTdGVwQ2hhbmdlKHN0ZXAsIGkpXCJcbiAgICAgICAgICAocGFyYW1ldGVyQ2hhbmdlKT1cIm9uTmVzdGVkU3RlcENoYW5nZShzdGVwLCBpKVwiXG4gICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCIkYW55KHN0ZXApLnNlbGVjdGVkID0gJGV2ZW50OyBvbk5lc3RlZFN0ZXBDaGFuZ2Uoc3RlcCwgaSlcIlxuICAgICAgICAobG9hZE1vcmVEYXRhUHJvZmlsZXMpPVwibG9hZE1vcmVEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHNlYXJjaERhdGFQcm9maWxlcyk9XCJzZWFyY2hEYXRhUHJvZmlsZXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGRuZERyb3BJblpvbmUpPVwiZG5kRHJvcEluWm9uZS5lbWl0KCRldmVudClcIlxuICAgICAgICAoY2xpY2tBY3Rpb24pPVwiY2xpY2tBY3Rpb24uZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGVkaXRJbkRlcHRoKT1cImVkaXRJbkRlcHRoLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChhZGRTdGVwQmV0d2VlbkNsaWNrKT1cImFkZFN0ZXBCZXR3ZWVuQ2xpY2suZW1pdCgkZXZlbnQpXCI+XG4gICAgICAgIDwvY3FhLXRlc3QtY2FzZS1kZXRhaWxzLXJlbmRlcmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEVtcHR5IGxvb3A6IHNob3cgcGx1cyBpY29uIG9uIGhvdmVyIHdoZW4gZXhwYW5kZWQgYW5kIG5vIHN0ZXBzIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJuZXN0ZWRTdGVwcy5sZW5ndGggPT09IDBcIiBjbGFzcz1cImxvb3Atc3RlcC1lbXB0eSBjcWEtbWluLWgtWzUycHhdIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1wbC00IGNxYS1wci00XCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25BZGRTdGVwRW1wdHkoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgdGl0bGU9XCJBZGQgc3RlcFwiXG4gICAgICAgIGNsYXNzPVwibG9vcC1zdGVwLWVtcHR5LWFkZFwiPlxuICAgICAgICA8c3ZnIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICA8cmVjdCB4PVwiMVwiIHk9XCIxXCIgd2lkdGg9XCIyMS4xODIyXCIgaGVpZ2h0PVwiMjJcIiByeD1cIjEwLjU5MTFcIiBmaWxsPVwid2hpdGVcIiAvPlxuICAgICAgICAgIDxyZWN0IHg9XCIxXCIgeT1cIjFcIiB3aWR0aD1cIjIxLjE4MjJcIiBoZWlnaHQ9XCIyMlwiIHJ4PVwiMTAuNTkxMVwiIHN0cm9rZT1cIiMzRjQzRUVcIiBzdHJva2Utd2lkdGg9XCIyXCIgLz5cbiAgICAgICAgICA8cGF0aCBkPVwiTTguNSAxMkgxNS41XCIgc3Ryb2tlPVwiIzNGNDNFRVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgPHBhdGggZD1cIk0xMiA4LjVWMTUuNVwiIHN0cm9rZT1cIiMzRjQzRUVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBFTkQgTWFya2VyIC0tPlxuICAgIDxkaXZcbiAgICAgIFtjbGFzc109XCInY3FhLXBsLTQgY3FhLXB5LTEgY3FhLWJnLVsjREJFQUZFODBdIGNxYS10ZXh0LVsjMUMzOThFXSBjcWEtdGV4dC1bMTBweF0gY3FhLWxlYWRpbmctWzE1cHhdIGNxYS1mb250LW1lZGl1bSdcIlxuICAgICAgc3R5bGU9XCJib3JkZXItdG9wOiAxcHggc29saWQgI0JFREJGRjtcIj5cbiAgICAgIHt7IGdldEVuZExhYmVsKCkgfX1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=
|