@cqa-lib/cqa-ui 1.1.541 → 1.1.542-gamma.10

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.
Files changed (66) hide show
  1. package/.github/workflows/README.md +8 -1
  2. package/esm2020/lib/compare-runs/compare-runs.component.mjs +1 -1
  3. package/esm2020/lib/execution-screen/condition-debug-step/condition-branch-editor.component.mjs +32 -3
  4. package/esm2020/lib/execution-screen/db-query-execution-item/db-query-execution-item.component.mjs +1 -1
  5. package/esm2020/lib/execution-screen/db-verification-step/db-verification-step.component.mjs +1 -1
  6. package/esm2020/lib/iterations-loop/iterations-loop.component.mjs +1 -1
  7. package/esm2020/lib/mixed-variable-input/mixed-variable-input.component.mjs +30 -10
  8. package/esm2020/lib/new-global-variable-dialog/global-variable-tags-input.component.mjs +129 -0
  9. package/esm2020/lib/new-global-variable-dialog/new-global-variable-dialog.component.mjs +16 -5
  10. package/esm2020/lib/new-global-variable-dialog/new-global-variable-dialog.models.mjs +1 -1
  11. package/esm2020/lib/new-test-data-profile-dialog/new-test-data-profile-dialog.component.mjs +50 -51
  12. package/esm2020/lib/new-test-data-profile-dialog/new-test-data-profile-dialog.models.mjs +1 -1
  13. package/esm2020/lib/segment-control/segment-control.component.mjs +12 -4
  14. package/esm2020/lib/step-builder/step-builder-action/step-builder-action.component.mjs +21 -3
  15. package/esm2020/lib/step-builder/step-builder-ai-agent/step-builder-ai-agent.component.mjs +59 -23
  16. package/esm2020/lib/step-builder/step-builder-condition/step-builder-condition.component.mjs +21 -3
  17. package/esm2020/lib/step-builder/step-builder-database/step-builder-database.component.mjs +88 -47
  18. package/esm2020/lib/step-builder/step-builder-loop/step-builder-loop.component.mjs +16 -3
  19. package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +495 -29
  20. package/esm2020/lib/templates/modular-table-template/modular-table-template.component.mjs +24 -6
  21. package/esm2020/lib/templates/table-template.component.mjs +5 -3
  22. package/esm2020/lib/test-case-details/ai-agent-step/ai-agent-step.component.mjs +3 -3
  23. package/esm2020/lib/test-case-details/ai-verify-step/ai-verify-step.component.mjs +3 -3
  24. package/esm2020/lib/test-case-details/api-edit-step/api-edit-step.component.mjs +32 -7
  25. package/esm2020/lib/test-case-details/data-library-panel/data-library-panel.component.mjs +116 -0
  26. package/esm2020/lib/test-case-details/data-library-panel/data-library-panel.models.mjs +2 -0
  27. package/esm2020/lib/test-case-details/data-library-panel/element-card.component.mjs +36 -0
  28. package/esm2020/lib/test-case-details/data-library-panel/test-data-profile-card.component.mjs +38 -0
  29. package/esm2020/lib/test-case-details/test-case-details-edit/test-case-details-edit.component.mjs +43 -4
  30. package/esm2020/lib/test-case-details/test-case-details.models.mjs +3 -1
  31. package/esm2020/lib/test-case-details/test-data-modal/test-data-modal-data.mjs +1 -1
  32. package/esm2020/lib/test-case-details/test-data-modal/test-data-modal.component.mjs +137 -7
  33. package/esm2020/lib/ui-kit.module.mjs +23 -3
  34. package/esm2020/public-api.mjs +6 -1
  35. package/fesm2015/cqa-lib-cqa-ui.mjs +1478 -267
  36. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  37. package/fesm2020/cqa-lib-cqa-ui.mjs +1384 -194
  38. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  39. package/lib/execution-screen/condition-debug-step/condition-branch-editor.component.d.ts +26 -1
  40. package/lib/new-global-variable-dialog/global-variable-tags-input.component.d.ts +39 -0
  41. package/lib/new-global-variable-dialog/new-global-variable-dialog.component.d.ts +5 -2
  42. package/lib/new-global-variable-dialog/new-global-variable-dialog.models.d.ts +8 -0
  43. package/lib/new-test-data-profile-dialog/new-test-data-profile-dialog.component.d.ts +9 -10
  44. package/lib/new-test-data-profile-dialog/new-test-data-profile-dialog.models.d.ts +1 -1
  45. package/lib/segment-control/segment-control.component.d.ts +3 -1
  46. package/lib/step-builder/step-builder-action/step-builder-action.component.d.ts +19 -1
  47. package/lib/step-builder/step-builder-ai-agent/step-builder-ai-agent.component.d.ts +23 -2
  48. package/lib/step-builder/step-builder-condition/step-builder-condition.component.d.ts +19 -1
  49. package/lib/step-builder/step-builder-database/step-builder-database.component.d.ts +40 -11
  50. package/lib/step-builder/step-builder-loop/step-builder-loop.component.d.ts +15 -1
  51. package/lib/step-builder/template-variables-form/template-variables-form.component.d.ts +103 -4
  52. package/lib/templates/modular-table-template/modular-table-template.component.d.ts +15 -2
  53. package/lib/templates/table-template.component.d.ts +8 -1
  54. package/lib/test-case-details/api-edit-step/api-edit-step.component.d.ts +14 -1
  55. package/lib/test-case-details/data-library-panel/data-library-panel.component.d.ts +42 -0
  56. package/lib/test-case-details/data-library-panel/data-library-panel.models.d.ts +17 -0
  57. package/lib/test-case-details/data-library-panel/element-card.component.d.ts +13 -0
  58. package/lib/test-case-details/data-library-panel/test-data-profile-card.component.d.ts +13 -0
  59. package/lib/test-case-details/test-case-details-edit/test-case-details-edit.component.d.ts +7 -0
  60. package/lib/test-case-details/test-case-details.models.d.ts +2 -0
  61. package/lib/test-case-details/test-data-modal/test-data-modal-data.d.ts +23 -1
  62. package/lib/test-case-details/test-data-modal/test-data-modal.component.d.ts +40 -6
  63. package/lib/ui-kit.module.d.ts +100 -96
  64. package/package.json +1 -1
  65. package/public-api.d.ts +5 -0
  66. package/styles.css +1 -1
@@ -21,8 +21,13 @@ export class StepBuilderDatabaseComponent {
21
21
  constructor(fb, cdr) {
22
22
  this.fb = fb;
23
23
  this.cdr = cdr;
24
- /** Options for DB environment dropdown */
25
- this.dbEnvironmentOptions = [];
24
+ /**
25
+ * Options for the DB Config dropdown — env-attached DB configs returned by
26
+ * `/environments/{envId}/db_configs`. Each `SelectOption.id` is the dbConfigId.
27
+ */
28
+ this.dbConfigOptions = [];
29
+ /** True while the parent loads DB configs (initial / search). */
30
+ this.isLoadingDbConfigs = false;
26
31
  /** Options for Normal environment dropdown */
27
32
  this.normalEnvironmentOptions = [];
28
33
  /** Initial queries list */
@@ -39,8 +44,8 @@ export class StepBuilderDatabaseComponent {
39
44
  this.cancelled = new EventEmitter();
40
45
  /** Emit when query is run */
41
46
  this.runQuery = new EventEmitter();
42
- /** Emit when DB environment search is triggered */
43
- this.searchDbEnvironment = new EventEmitter();
47
+ /** Emit when DB Config search is triggered */
48
+ this.searchDbConfig = new EventEmitter();
44
49
  /** Emit when Normal environment search is triggered */
45
50
  this.searchNormalEnvironment = new EventEmitter();
46
51
  /** Emit when query is added */
@@ -112,13 +117,27 @@ export class StepBuilderDatabaseComponent {
112
117
  return null;
113
118
  };
114
119
  this.databaseForm = this.fb.group({
115
- dbEnvironment: ['', Validators.required],
120
+ dbConfigId: ['', Validators.required],
116
121
  normalEnvironment: [''],
117
122
  queries: this.fb.array([])
118
123
  });
119
124
  }
125
+ /**
126
+ * True only under Tier 1 (testCase.environmentId set). Hides the Normal
127
+ * Environment picker — the env banner already states it. Tier 2/3 keep
128
+ * the picker visible. Both 'no suffix' AND 'no deprecation' are required
129
+ * because Tier 2 leaves suffix undefined but populates the env name.
130
+ */
131
+ get hideEnvironmentNameField() {
132
+ const name = (this.testCaseEnvironmentName ?? '').trim();
133
+ const suffix = (this.testCaseEnvironmentLabelSuffix ?? '').trim();
134
+ const deprecation = (this.environmentLegacyDeprecationMessage ?? '').trim();
135
+ return !!name && !suffix && !deprecation;
136
+ }
120
137
  ngOnInit() {
121
138
  this.initializeFormWithInitialValues();
139
+ this.rebuildDbConfigSelectConfig();
140
+ this.rebuildNormalEnvSelectConfig();
122
141
  // If parent provided advanced settings, build from them; otherwise initialize defaults
123
142
  if (this.advancedSettingsVariables && this.advancedSettingsVariables.length > 0) {
124
143
  this.buildAdvancedVariablesForm();
@@ -158,8 +177,8 @@ export class StepBuilderDatabaseComponent {
158
177
  }
159
178
  this.cdr.detectChanges();
160
179
  }
161
- if (changes['initialDbEnvironment'] && changes['initialDbEnvironment'].currentValue) {
162
- this.databaseForm.patchValue({ dbEnvironment: changes['initialDbEnvironment'].currentValue });
180
+ if (changes['initialDbConfigId'] && changes['initialDbConfigId'].currentValue) {
181
+ this.databaseForm.patchValue({ dbConfigId: changes['initialDbConfigId'].currentValue });
163
182
  }
164
183
  if (changes['initialNormalEnvironment'] && changes['initialNormalEnvironment'].currentValue) {
165
184
  this.databaseForm.patchValue({ normalEnvironment: changes['initialNormalEnvironment'].currentValue });
@@ -173,11 +192,51 @@ export class StepBuilderDatabaseComponent {
173
192
  this.initializeAdvancedSettings();
174
193
  }
175
194
  }
195
+ // Stable-reference rebuild of select configs — runs ONLY when the relevant
196
+ // Inputs change. Avoids the CD loop caused by per-pass `.map()` calls.
197
+ if (changes['dbConfigOptions'] || changes['isLoadingDbConfigs']) {
198
+ this.rebuildDbConfigSelectConfig();
199
+ }
200
+ if (changes['normalEnvironmentOptions'] || changes['testCaseEnvironmentName'] || changes['testCaseEnvironmentLabelSuffix']) {
201
+ this.rebuildNormalEnvSelectConfig();
202
+ }
203
+ }
204
+ rebuildDbConfigSelectConfig() {
205
+ this.dbConfigSelectConfig = {
206
+ key: 'dbConfigId',
207
+ placeholder: 'Select DB config',
208
+ multiple: false,
209
+ searchable: true,
210
+ serverSearch: true,
211
+ options: this.dbConfigOptions ?? [],
212
+ isLoading: this.isLoadingDbConfigs,
213
+ onSearch: (query) => { this.searchDbConfig.emit(query); }
214
+ };
215
+ }
216
+ rebuildNormalEnvSelectConfig() {
217
+ const labelSuffix = (this.testCaseEnvironmentLabelSuffix ?? '').trim();
218
+ const lock = !!(this.testCaseEnvironmentName ?? '').trim() || !!labelSuffix;
219
+ const opts = labelSuffix
220
+ ? (this.normalEnvironmentOptions ?? []).map(o => ({
221
+ ...o,
222
+ label: `${String(o.label ?? o.name ?? '')} ${labelSuffix}`,
223
+ }))
224
+ : (this.normalEnvironmentOptions ?? []);
225
+ this.normalEnvSelectConfig = {
226
+ key: 'normalEnvironment',
227
+ placeholder: 'Select Normal environment',
228
+ multiple: false,
229
+ searchable: !lock,
230
+ serverSearch: !lock,
231
+ disabled: lock,
232
+ options: opts,
233
+ onSearch: (query) => { this.searchNormalEnvironment.emit(query); }
234
+ };
176
235
  }
177
236
  initializeFormWithInitialValues() {
178
- // Set initial DB environment if provided
179
- if (this.initialDbEnvironment) {
180
- this.databaseForm.patchValue({ dbEnvironment: this.initialDbEnvironment });
237
+ // Set initial DB Config if provided
238
+ if (this.initialDbConfigId) {
239
+ this.databaseForm.patchValue({ dbConfigId: this.initialDbConfigId });
181
240
  }
182
241
  // Set initial Normal environment if provided
183
242
  if (this.initialNormalEnvironment) {
@@ -275,32 +334,6 @@ export class StepBuilderDatabaseComponent {
275
334
  this.cdr.detectChanges();
276
335
  }
277
336
  }
278
- getDbEnvironmentConfig() {
279
- return {
280
- key: 'dbEnvironment',
281
- placeholder: 'Select DB environment',
282
- multiple: false,
283
- searchable: true,
284
- serverSearch: true,
285
- options: this.dbEnvironmentOptions,
286
- onSearch: (query) => {
287
- this.searchDbEnvironment.emit(query);
288
- }
289
- };
290
- }
291
- getNormalEnvironmentConfig() {
292
- return {
293
- key: 'normalEnvironment',
294
- placeholder: 'Select Normal environment',
295
- multiple: false,
296
- searchable: true,
297
- serverSearch: true,
298
- options: this.normalEnvironmentOptions,
299
- onSearch: (query) => {
300
- this.searchNormalEnvironment.emit(query);
301
- }
302
- };
303
- }
304
337
  getCurrentQuery() {
305
338
  if (this.queries.length > 0 && this.selectedQueryIndex >= 0 && this.selectedQueryIndex < this.queries.length) {
306
339
  return this.queries[this.selectedQueryIndex];
@@ -314,11 +347,11 @@ export class StepBuilderDatabaseComponent {
314
347
  return null;
315
348
  }
316
349
  onRunQuery() {
317
- const dbEnvironment = this.databaseForm.get('dbEnvironment')?.value;
350
+ const dbConfigId = this.databaseForm.get('dbConfigId')?.value;
318
351
  const normalEnvironment = this.databaseForm.get('normalEnvironment')?.value;
319
352
  const currentQuery = this.getCurrentQuery();
320
353
  const queryFormGroup = this.getCurrentQueryFormGroup();
321
- if (currentQuery && queryFormGroup && dbEnvironment) {
354
+ if (currentQuery && queryFormGroup && dbConfigId) {
322
355
  const query = queryFormGroup.get('query')?.value || '';
323
356
  const variable = queryFormGroup.get('variable')?.value || '';
324
357
  // Update the query object
@@ -328,7 +361,7 @@ export class StepBuilderDatabaseComponent {
328
361
  currentQuery,
329
362
  query,
330
363
  variable,
331
- dbEnvironment,
364
+ dbConfigId,
332
365
  normalEnvironment: normalEnvironment || undefined
333
366
  });
334
367
  }
@@ -375,7 +408,7 @@ export class StepBuilderDatabaseComponent {
375
408
  this.cancelled.emit();
376
409
  }
377
410
  isFormValid() {
378
- // Check if main form is valid (dbEnvironment is required)
411
+ // Check if main form is valid (dbConfigId is required)
379
412
  if (!this.databaseForm.valid) {
380
413
  return false;
381
414
  }
@@ -406,7 +439,7 @@ export class StepBuilderDatabaseComponent {
406
439
  }
407
440
  });
408
441
  const stepData = {
409
- dbEnvironment: formValue.dbEnvironment,
442
+ dbConfigId: formValue.dbConfigId,
410
443
  normalEnvironment: formValue.normalEnvironment || undefined,
411
444
  queries: this.queries.map((query, index) => {
412
445
  const queryFormGroup = this.queriesFormArray.at(index);
@@ -858,11 +891,13 @@ export class StepBuilderDatabaseComponent {
858
891
  }
859
892
  }
860
893
  StepBuilderDatabaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderDatabaseComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
861
- StepBuilderDatabaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderDatabaseComponent, selector: "cqa-step-builder-database", inputs: { dbEnvironmentOptions: "dbEnvironmentOptions", normalEnvironmentOptions: "normalEnvironmentOptions", queries: "queries", queryResults: "queryResults", isLoading: "isLoading", initialDbEnvironment: "initialDbEnvironment", initialNormalEnvironment: "initialNormalEnvironment", editMode: "editMode", isCreatingStep: "isCreatingStep", advancedSettingsVariables: "advancedSettingsVariables" }, outputs: { createStep: "createStep", cancelled: "cancelled", runQuery: "runQuery", searchDbEnvironment: "searchDbEnvironment", searchNormalEnvironment: "searchNormalEnvironment", addQuery: "addQuery", deleteQuery: "deleteQuery", assertionDataChange: "assertionDataChange", selectedQueryIndexChange: "selectedQueryIndexChange", activeTabChange: "activeTabChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "assertionsTable", first: true, predicate: ["assertionsTable"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n {{ editMode ? 'Update Database Test Step' : 'Create Database Test Step' }}\n </h2>\n\n <!-- Environment Section (separator line only on bottom) -->\n <div class=\"cqa-flex cqa-w-full cqa-justify-between cqa-gap-1.5 cqa-pb-[0.5rem] cqa-mb-4 cqa-border-0 cqa-border-b cqa-border-solid cqa-border-gray-200\">\n <div class=\"cqa-flex cqa-gap-4 cqa-items-start\">\n <!-- DB Environment -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n DB Environment <span class=\"cqa-text-red-500\">*</span>\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"getDbEnvironmentConfig()\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Database environments from Environments.\n </p>\n </div>\n\n <!-- Normal Environment -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n Normal Environment\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"getNormalEnvironmentConfig()\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Normal environments from Environments.\n </p>\n </div>\n </div>\n <div class=\"cqa-flex cqa-justify-end cqa-mt-2\">\n <cqa-button variant=\"filled\" text=\"Run Query\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!databaseForm.get('dbEnvironment')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[24px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[37px] hover:!cqa-bg-[#1B1FEB] cqa-flex-shrink-0'\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Main Content: Two Column Layout -->\n <div class=\"cqa-flex cqa-gap-[12px] cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Left Panel: Query List -->\n <div\n class=\"cqa-w-[175px] cqa-min-w-[175px] cqa-flex-shrink-0 cqa-flex cqa-flex-col cqa-border-0 cqa-border-r cqa-border-r-[1px] cqa-border-solid cqa-border-[#E0E0E0] cqa-bg-[#FAFAFA] cqa-overflow-hidden\">\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-2\">\n <div *ngFor=\"let query of queries; let i = index\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-[10px] cqa-w-full cqa-pt-[14px] cqa-pb-[14px] cqa-pl-[16px] cqa-pr-[16px] cqa-rounded-[8px] cqa-cursor-pointer cqa-mb-1\"\n [class.cqa-bg-blue-50]=\"selectedQueryIndex === i\"\n [class.cqa-border]=\"selectedQueryIndex === i\"\n [class.cqa-border-blue-500]=\"selectedQueryIndex === i\"\n [class.cqa-bg-grey-400]=\"selectedQueryIndex !== i\"\n (click)=\"onSelectQuery(i)\"\n style=\"height: 49px; min-height: 49px;\">\n <span class=\"cqa-text-sm cqa-font-medium cqa-text-gray-900\">Query {{ i + 1 }}</span>\n <cqa-badge *ngIf=\"query.status\"\n [label]=\"query.status === 'passed' ? 'Passed' : query.status === 'failed' ? 'Failed' : 'Pending'\"\n [variant]=\"query.status === 'passed' ? 'success' : query.status === 'failed' ? 'error' : 'default'\"\n size=\"small\">\n </cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Right Panel: Query Editor -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-overflow-auto\">\n <div class=\"cqa-flex-1 cqa-flex cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-gap-[10px] cqa-mb-4\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[6px]\" style=\"width: 50%;\">\n <div class=\"\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900 cqa-text-[14px]\">Query & Store Response<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span></h3>\n </div>\n\n <div class=\"cqa-flex cqa-justify-between\">\n <!-- SQL Query Textarea -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0 cqa-w-full cqa-rounded-md cqa-bg-gray-50/50\">\n <cqa-custom-textarea [placeholder]=\"'Enter your SQL query here...'\"\n [value]=\"getCurrentQueryFormGroup()?.get('query')?.value || ''\" [fullWidth]=\"true\" [rows]=\"8\"\n [textareaInlineStyle]=\"'padding: 1rem;'\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('query')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-flex cqa-flex-col cqa-gap-[10px] cqa-mb-[8px]\">\n\n\n <!-- Variable Input -->\n <div class=\"cqa-flex cqa-gap-4\">\n <div class=\"cqa-flex-1\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5 cqa-block cqa-text-[14px] cqa-font-semibold\">\n Variable<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n <cqa-custom-input [placeholder]=\"'Variable name'\"\n [value]=\"getCurrentQueryFormGroup()?.get('variable')?.value || ''\" [fullWidth]=\"true\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('variable')?.setValue($event)\">\n </cqa-custom-input>\n <p class=\"cqa-text-xs cqa-text-gray-500 cqa-mt-1\">\n Use letters, numbers, underscore. No spaces. Unique per step. Case sensitive.\n </p>\n </div>\n </div>\n <!-- Action Buttons (pinned to bottom) -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mt-auto\">\n <cqa-button variant=\"outlined\" text=\"Add Query\" icon=\"add\" (clicked)=\"addNewQuery()\"\n [customClass]=\"'cqa-bg-white !cqa-border-[#414146] cqa-text-sm cqa-font-semibold cqa-text-[#414146] cqa-whitespace-nowrap !cqa-py-[10px] !cqa-px-[10px] !cqa-gap-[8px] cqa-rounded-lg hover:!cqa-border-[#414146] hover:cqa-bg-gray-50'\"\n [iconColor]=\"'#414146'\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\"\n [customClass]=\"'cqa-min-w-[40px] cqa-w-10 cqa-h-9 cqa-rounded cqa-bg-gray-100 cqa-flex cqa-items-center cqa-justify-center hover:cqa-bg-gray-200 cqa-p-0'\"\n [tooltip]=\"'Delete query'\" (clicked)=\"deleteQueryById(getCurrentQuery()?.id || '')\"\n [disabled]=\"queries.length <= 1\" [attr.aria-label]=\"'Delete query'\">\n <svg class=\"cqa-flex-shrink-0\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#6B7280\" />\n </svg>\n </cqa-button>\n <cqa-button variant=\"filled\" text=\"Run\" icon=\"play_arrow\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!getCurrentQueryFormGroup()?.get('query')?.value || !databaseForm.get('dbEnvironment')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[16px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[38px] hover:!cqa-bg-[#1B1FEB] !cqa-border-none'\"\n [iconColor]=\"'#FBFCFF'\">\n </cqa-button>\n </div>\n </div>\n </div>\n <!-- Results Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-mb-6\">\n <!-- Tabs -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'output'\" [class.cqa-border-blue-600]=\"selectedTab === 'output'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'output'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'output'\" (click)=\"onTabChange('output')\">\n Output\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'verification'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'verification'\" (click)=\"onTabChange('verification')\">\n Verification\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'advanced'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'advanced'\" (click)=\"onTabChange('advanced')\">\n Advanced\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-p-4\">\n <!-- Output Tab -->\n <div *ngIf=\"selectedTab === 'output'\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3\">\n <h4 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Query Results</h4>\n <cqa-button variant=\"text\" text=\"Copy\" icon=\"content_copy\" [customClass]=\"'cqa-text-blue-600'\"\n (clicked)=\"onCopyResults()\">\n </cqa-button>\n </div>\n\n <!-- Results Table -->\n <div *ngIf=\"getCurrentQueryResult().length > 0\" class=\"cqa-overflow-x-auto\">\n <table class=\"cqa-w-full cqa-border-collapse\">\n <thead>\n <tr class=\"cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <th *ngFor=\"let key of getTableColumns()\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-left cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">\n {{ key }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getCurrentQueryResult()\" class=\"cqa-border-b cqa-border-gray-200 hover:cqa-bg-gray-50\">\n <td *ngFor=\"let key of getTableColumns()\" class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-text-gray-900\">\n {{ row[key] }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div *ngIf=\"getCurrentQueryResult().length === 0\"\n class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-sm\">\n No results yet. Run a query to see results.\n </div>\n </div>\n\n <!-- Verification Tab -->\n <div *ngIf=\"selectedTab === 'verification'\" class=\"assertions-container\">\n <!-- Header Section -->\n <div class=\"assertions-header\">\n <div class=\"header-content\">\n <h3 class=\"header-title\">Assertions</h3>\n <p class=\"header-subtitle\">Use JSONPath to target values in the query output.</p>\n </div>\n <button \n mat-stroked-button \n color=\"primary\" \n class=\"add-assertion-button\"\n (click)=\"addAssertion()\">\n <mat-icon>add</mat-icon>\n Add Assertion\n </button>\n </div>\n\n <!-- Table Section -->\n <form *ngIf=\"getCurrentAssertionsForm()\" [formGroup]=\"getCurrentAssertionsForm()!\" class=\"assertions-form\">\n <div formArrayName=\"assertions\">\n <div class=\"table-scroll-container\">\n <table mat-table [dataSource]=\"assertionsDataSource\" class=\"assertions-table\" #assertionsTable>\n <!-- JSONPath Column -->\n <ng-container matColumnDef=\"jsonPath\">\n <th mat-header-cell *matHeaderCellDef>jsonPath</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <input \n matInput \n formControlName=\"jsonPath\"\n placeholder=\"username\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'jsonPath')?.hasError('required') && \n getFormControlAt(i, 'jsonPath')?.touched\">\n JSONPath is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Verification Type Column -->\n <ng-container matColumnDef=\"verificationType\">\n <th mat-header-cell *matHeaderCellDef>verificationType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select formControlName=\"verificationType\">\n <mat-option value=\"equals\">Equals</mat-option>\n <mat-option value=\"not_equals\">Not Equals</mat-option>\n <mat-option value=\"contains\">Contains</mat-option>\n <mat-option value=\"not_contains\">Not Contains</mat-option>\n <mat-option value=\"greater_than\">Greater Than</mat-option>\n <mat-option value=\"less_than\">Less Than</mat-option>\n <mat-option value=\"greater_than_or_equals\">Greater Than Or Equals</mat-option>\n <mat-option value=\"less_than_or_equals\">Less Than Or Equals</mat-option>\n <mat-option value=\"exists\">Exists</mat-option>\n <mat-option value=\"not_exists\">Not Exists</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Type Column -->\n <ng-container matColumnDef=\"expectedType\">\n <th mat-header-cell *matHeaderCellDef>expectedType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select \n formControlName=\"expectedType\"\n (selectionChange)=\"onExpectedTypeChange(i, $event.value)\">\n <mat-option value=\"string\">String</mat-option>\n <mat-option value=\"number\">Number</mat-option>\n <mat-option value=\"boolean\">Boolean</mat-option>\n <mat-option value=\"object\">Object</mat-option>\n <mat-option value=\"array\">Array</mat-option>\n <mat-option value=\"null\">Null</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Value Column -->\n <ng-container matColumnDef=\"expectedValue\">\n <th mat-header-cell *matHeaderCellDef>expectedValue</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <!-- String, Array, Object Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'string' || getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <textarea \n *ngIf=\"getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n rows=\"3\"\n required></textarea>\n <input \n *ngIf=\"getExpectedType(i) === 'string'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('invalidType')\">\n {{ getFormControlAt(i, 'expectedValue')?.errors?.message }}\n </mat-error>\n </mat-form-field>\n\n <!-- Null Type Display -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'null'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n [disabled]=\"true\">\n </mat-form-field>\n\n <!-- Number Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'number'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n type=\"number\"\n formControlName=\"expectedValue\"\n placeholder=\"Expected Value in Number\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n\n <!-- Boolean Select -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'boolean'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <mat-select formControlName=\"expectedValue\" required>\n <mat-option value=\"true\">true</mat-option>\n <mat-option value=\"false\">false</mat-option>\n </mat-select>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <button \n mat-icon-button \n color=\"warn\"\n class=\"delete-button\"\n (click)=\"removeAssertion(i)\"\n [matTooltip]=\"'Delete assertion'\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"getAssertionsFormArray().length === 0\" class=\"empty-state\">\n <p>No assertions added. Click \"Add Assertion\" to create one.</p>\n </div>\n </div>\n </form>\n </div>\n\n <div *ngIf=\"selectedTab === 'advanced'\">\n <cqa-advanced-variables-form \n [advancedVariables]=\"advancedSettingsVariables\"\n [advancedVariableForm]=\"advancedVariablesForm\"\n (variableBooleanChange)=\"onAdvancedVariableBooleanChange($event.name, $event.value)\"\n (variableValueChange)=\"onAdvancedVariableValueChange($event.name, $event.value)\">\n </cqa-advanced-variables-form>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button *ngIf=\"!isCreatingStep\" class=\"cqa-w-1/2\" variant=\"filled\" [text]=\"editMode ? 'Update Step' : 'Create Step'\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n <div *ngIf=\"isCreatingStep\" class=\"cqa-w-1/2 cqa-flex-1 cqa-min-h-[38px] cqa-rounded-[8px]\">\n <cqa-badge label=\"Creating\u2026\" icon=\"autorenew\" [isLoading]=\"true\" [fullWidth]=\"true\" [centerContent]=\"true\"\n [inlineStyles]=\"'min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center; justify-content: center;'\"\n variant=\"info\" size=\"medium\"></cqa-badge>\n </div>\n </div>\n</div>", 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", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i4.BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading", "fullWidth", "centerContent", "title"] }, { type: i5.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "enableMarkdown", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: i6.CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i7.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i10.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i11.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i12.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i13.AdvancedVariablesFormComponent, selector: "cqa-advanced-variables-form", inputs: ["advancedVariables", "advancedVariableForm"], outputs: ["variableBooleanChange", "variableValueChange"] }], directives: [{ type: i14.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i14.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i9.MatCellDef, selector: "[matCellDef]" }, { type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { type: i15.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i10.MatError, selector: "mat-error", inputs: ["id"] }, { type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i16.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
894
+ StepBuilderDatabaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderDatabaseComponent, selector: "cqa-step-builder-database", inputs: { dbConfigOptions: "dbConfigOptions", isLoadingDbConfigs: "isLoadingDbConfigs", normalEnvironmentOptions: "normalEnvironmentOptions", queries: "queries", queryResults: "queryResults", isLoading: "isLoading", initialDbConfigId: "initialDbConfigId", initialNormalEnvironment: "initialNormalEnvironment", testCaseEnvironmentName: "testCaseEnvironmentName", testCaseEnvironmentLabelSuffix: "testCaseEnvironmentLabelSuffix", environmentLegacyDeprecationMessage: "environmentLegacyDeprecationMessage", editMode: "editMode", isCreatingStep: "isCreatingStep", advancedSettingsVariables: "advancedSettingsVariables" }, outputs: { createStep: "createStep", cancelled: "cancelled", runQuery: "runQuery", searchDbConfig: "searchDbConfig", searchNormalEnvironment: "searchNormalEnvironment", addQuery: "addQuery", deleteQuery: "deleteQuery", assertionDataChange: "assertionDataChange", selectedQueryIndexChange: "selectedQueryIndexChange", activeTabChange: "activeTabChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "assertionsTable", first: true, predicate: ["assertionsTable"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n {{ editMode ? 'Update Database Test Step' : 'Create Database Test Step' }}\n </h2>\n\n <!-- Env banner \u2014 surfaces which environment scopes the DB Config + Normal Env. -->\n <div *ngIf=\"testCaseEnvironmentName\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-text-xs cqa-text-gray-700 cqa-bg-gray-50 cqa-border cqa-border-gray-200\">\n Using <strong class=\"cqa-font-semibold\">{{ testCaseEnvironmentName }} Environment</strong>\n <span class=\"cqa-text-gray-500\">\u00B7</span>\n <span class=\"cqa-text-gray-500\">Environment variables and DB configs are resolved from this environment.</span>\n </div>\n\n <!-- Environment Section (separator line only on bottom) -->\n <div class=\"cqa-flex cqa-w-full cqa-justify-between cqa-gap-1.5 cqa-pb-[0.5rem] cqa-mb-4 cqa-border-0 cqa-border-b cqa-border-solid cqa-border-gray-200\">\n <div class=\"cqa-flex cqa-gap-4 cqa-items-start\">\n <!-- DB Config -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n DB Config <span class=\"cqa-text-red-500\">*</span>\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"dbConfigSelectConfig\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n DB configs attached to the active environment.\n </p>\n </div>\n\n <!-- Normal Environment \u2014 hidden under Tier 1 (testCase.environmentId set);\n the env banner above already names the active env. -->\n <div *ngIf=\"!hideEnvironmentNameField\" class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n Normal Environment\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"normalEnvSelectConfig\">\n </cqa-dynamic-select>\n </div>\n <p *ngIf=\"environmentLegacyDeprecationMessage\"\n class=\"cqa-text-xs cqa-italic cqa-text-amber-600 cqa-m-0\"\n [innerHTML]=\"environmentLegacyDeprecationMessage\"></p>\n <p *ngIf=\"!environmentLegacyDeprecationMessage\" class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Normal environments from Environments.\n </p>\n </div>\n </div>\n <div class=\"cqa-flex cqa-justify-end cqa-mt-2\">\n <cqa-button variant=\"filled\" text=\"Run Query\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!databaseForm.get('dbConfigId')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[24px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[37px] hover:!cqa-bg-[#1B1FEB] cqa-flex-shrink-0'\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Main Content: Two Column Layout -->\n <div class=\"cqa-flex cqa-gap-[12px] cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Left Panel: Query List -->\n <div\n class=\"cqa-w-[175px] cqa-min-w-[175px] cqa-flex-shrink-0 cqa-flex cqa-flex-col cqa-border-0 cqa-border-r cqa-border-r-[1px] cqa-border-solid cqa-border-[#E0E0E0] cqa-bg-[#FAFAFA] cqa-overflow-hidden\">\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-2\">\n <div *ngFor=\"let query of queries; let i = index\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-[10px] cqa-w-full cqa-pt-[14px] cqa-pb-[14px] cqa-pl-[16px] cqa-pr-[16px] cqa-rounded-[8px] cqa-cursor-pointer cqa-mb-1\"\n [class.cqa-bg-blue-50]=\"selectedQueryIndex === i\"\n [class.cqa-border]=\"selectedQueryIndex === i\"\n [class.cqa-border-blue-500]=\"selectedQueryIndex === i\"\n [class.cqa-bg-grey-400]=\"selectedQueryIndex !== i\"\n (click)=\"onSelectQuery(i)\"\n style=\"height: 49px; min-height: 49px;\">\n <span class=\"cqa-text-sm cqa-font-medium cqa-text-gray-900\">Query {{ i + 1 }}</span>\n <cqa-badge *ngIf=\"query.status\"\n [label]=\"query.status === 'passed' ? 'Passed' : query.status === 'failed' ? 'Failed' : 'Pending'\"\n [variant]=\"query.status === 'passed' ? 'success' : query.status === 'failed' ? 'error' : 'default'\"\n size=\"small\">\n </cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Right Panel: Query Editor -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-overflow-auto\">\n <div class=\"cqa-flex-1 cqa-flex cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-gap-[10px] cqa-mb-4\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[6px]\" style=\"width: 50%;\">\n <div class=\"\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900 cqa-text-[14px]\">Query & Store Response<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span></h3>\n </div>\n\n <div class=\"cqa-flex cqa-justify-between\">\n <!-- SQL Query Textarea -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0 cqa-w-full cqa-rounded-md cqa-bg-gray-50/50\">\n <cqa-custom-textarea [placeholder]=\"'Enter your SQL query here...'\"\n [value]=\"getCurrentQueryFormGroup()?.get('query')?.value || ''\" [fullWidth]=\"true\" [rows]=\"8\"\n [textareaInlineStyle]=\"'padding: 1rem;'\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('query')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-flex cqa-flex-col cqa-gap-[10px] cqa-mb-[8px]\">\n\n\n <!-- Variable Input -->\n <div class=\"cqa-flex cqa-gap-4\">\n <div class=\"cqa-flex-1\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5 cqa-block cqa-text-[14px] cqa-font-semibold\">\n Variable<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n <cqa-custom-input [placeholder]=\"'Variable name'\"\n [value]=\"getCurrentQueryFormGroup()?.get('variable')?.value || ''\" [fullWidth]=\"true\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('variable')?.setValue($event)\">\n </cqa-custom-input>\n <p class=\"cqa-text-xs cqa-text-gray-500 cqa-mt-1\">\n Use letters, numbers, underscore. No spaces. Unique per step. Case sensitive.\n </p>\n </div>\n </div>\n <!-- Action Buttons (pinned to bottom) -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mt-auto\">\n <cqa-button variant=\"outlined\" text=\"Add Query\" icon=\"add\" (clicked)=\"addNewQuery()\"\n [customClass]=\"'cqa-bg-white !cqa-border-[#414146] cqa-text-sm cqa-font-semibold cqa-text-[#414146] cqa-whitespace-nowrap !cqa-py-[10px] !cqa-px-[10px] !cqa-gap-[8px] cqa-rounded-lg hover:!cqa-border-[#414146] hover:cqa-bg-gray-50'\"\n [iconColor]=\"'#414146'\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\"\n [customClass]=\"'cqa-min-w-[40px] cqa-w-10 cqa-h-9 cqa-rounded cqa-bg-gray-100 cqa-flex cqa-items-center cqa-justify-center hover:cqa-bg-gray-200 cqa-p-0'\"\n [tooltip]=\"'Delete query'\" (clicked)=\"deleteQueryById(getCurrentQuery()?.id || '')\"\n [disabled]=\"queries.length <= 1\" [attr.aria-label]=\"'Delete query'\">\n <svg class=\"cqa-flex-shrink-0\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#6B7280\" />\n </svg>\n </cqa-button>\n <cqa-button variant=\"filled\" text=\"Run\" icon=\"play_arrow\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!getCurrentQueryFormGroup()?.get('query')?.value || !databaseForm.get('dbConfigId')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[16px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[38px] hover:!cqa-bg-[#1B1FEB] !cqa-border-none'\"\n [iconColor]=\"'#FBFCFF'\">\n </cqa-button>\n </div>\n </div>\n </div>\n <!-- Results Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-mb-6\">\n <!-- Tabs -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'output'\" [class.cqa-border-blue-600]=\"selectedTab === 'output'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'output'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'output'\" (click)=\"onTabChange('output')\">\n Output\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'verification'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'verification'\" (click)=\"onTabChange('verification')\">\n Verification\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'advanced'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'advanced'\" (click)=\"onTabChange('advanced')\">\n Advanced\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-p-4\">\n <!-- Output Tab -->\n <div *ngIf=\"selectedTab === 'output'\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3\">\n <h4 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Query Results</h4>\n <cqa-button variant=\"text\" text=\"Copy\" icon=\"content_copy\" [customClass]=\"'cqa-text-blue-600'\"\n (clicked)=\"onCopyResults()\">\n </cqa-button>\n </div>\n\n <!-- Results Table -->\n <div *ngIf=\"getCurrentQueryResult().length > 0\" class=\"cqa-overflow-x-auto\">\n <table class=\"cqa-w-full cqa-border-collapse\">\n <thead>\n <tr class=\"cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <th *ngFor=\"let key of getTableColumns()\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-left cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">\n {{ key }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getCurrentQueryResult()\" class=\"cqa-border-b cqa-border-gray-200 hover:cqa-bg-gray-50\">\n <td *ngFor=\"let key of getTableColumns()\" class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-text-gray-900\">\n {{ row[key] }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div *ngIf=\"getCurrentQueryResult().length === 0\"\n class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-sm\">\n No results yet. Run a query to see results.\n </div>\n </div>\n\n <!-- Verification Tab -->\n <div *ngIf=\"selectedTab === 'verification'\" class=\"assertions-container\">\n <!-- Header Section -->\n <div class=\"assertions-header\">\n <div class=\"header-content\">\n <h3 class=\"header-title\">Assertions</h3>\n <p class=\"header-subtitle\">Use JSONPath to target values in the query output.</p>\n </div>\n <button \n mat-stroked-button \n color=\"primary\" \n class=\"add-assertion-button\"\n (click)=\"addAssertion()\">\n <mat-icon>add</mat-icon>\n Add Assertion\n </button>\n </div>\n\n <!-- Table Section -->\n <form *ngIf=\"getCurrentAssertionsForm()\" [formGroup]=\"getCurrentAssertionsForm()!\" class=\"assertions-form\">\n <div formArrayName=\"assertions\">\n <div class=\"table-scroll-container\">\n <table mat-table [dataSource]=\"assertionsDataSource\" class=\"assertions-table\" #assertionsTable>\n <!-- JSONPath Column -->\n <ng-container matColumnDef=\"jsonPath\">\n <th mat-header-cell *matHeaderCellDef>jsonPath</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <input \n matInput \n formControlName=\"jsonPath\"\n placeholder=\"username\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'jsonPath')?.hasError('required') && \n getFormControlAt(i, 'jsonPath')?.touched\">\n JSONPath is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Verification Type Column -->\n <ng-container matColumnDef=\"verificationType\">\n <th mat-header-cell *matHeaderCellDef>verificationType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select formControlName=\"verificationType\">\n <mat-option value=\"equals\">Equals</mat-option>\n <mat-option value=\"not_equals\">Not Equals</mat-option>\n <mat-option value=\"contains\">Contains</mat-option>\n <mat-option value=\"not_contains\">Not Contains</mat-option>\n <mat-option value=\"greater_than\">Greater Than</mat-option>\n <mat-option value=\"less_than\">Less Than</mat-option>\n <mat-option value=\"greater_than_or_equals\">Greater Than Or Equals</mat-option>\n <mat-option value=\"less_than_or_equals\">Less Than Or Equals</mat-option>\n <mat-option value=\"exists\">Exists</mat-option>\n <mat-option value=\"not_exists\">Not Exists</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Type Column -->\n <ng-container matColumnDef=\"expectedType\">\n <th mat-header-cell *matHeaderCellDef>expectedType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select \n formControlName=\"expectedType\"\n (selectionChange)=\"onExpectedTypeChange(i, $event.value)\">\n <mat-option value=\"string\">String</mat-option>\n <mat-option value=\"number\">Number</mat-option>\n <mat-option value=\"boolean\">Boolean</mat-option>\n <mat-option value=\"object\">Object</mat-option>\n <mat-option value=\"array\">Array</mat-option>\n <mat-option value=\"null\">Null</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Value Column -->\n <ng-container matColumnDef=\"expectedValue\">\n <th mat-header-cell *matHeaderCellDef>expectedValue</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <!-- String, Array, Object Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'string' || getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <textarea \n *ngIf=\"getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n rows=\"3\"\n required></textarea>\n <input \n *ngIf=\"getExpectedType(i) === 'string'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('invalidType')\">\n {{ getFormControlAt(i, 'expectedValue')?.errors?.message }}\n </mat-error>\n </mat-form-field>\n\n <!-- Null Type Display -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'null'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n [disabled]=\"true\">\n </mat-form-field>\n\n <!-- Number Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'number'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n type=\"number\"\n formControlName=\"expectedValue\"\n placeholder=\"Expected Value in Number\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n\n <!-- Boolean Select -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'boolean'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <mat-select formControlName=\"expectedValue\" required>\n <mat-option value=\"true\">true</mat-option>\n <mat-option value=\"false\">false</mat-option>\n </mat-select>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <button \n mat-icon-button \n color=\"warn\"\n class=\"delete-button\"\n (click)=\"removeAssertion(i)\"\n [matTooltip]=\"'Delete assertion'\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"getAssertionsFormArray().length === 0\" class=\"empty-state\">\n <p>No assertions added. Click \"Add Assertion\" to create one.</p>\n </div>\n </div>\n </form>\n </div>\n\n <div *ngIf=\"selectedTab === 'advanced'\">\n <cqa-advanced-variables-form \n [advancedVariables]=\"advancedSettingsVariables\"\n [advancedVariableForm]=\"advancedVariablesForm\"\n (variableBooleanChange)=\"onAdvancedVariableBooleanChange($event.name, $event.value)\"\n (variableValueChange)=\"onAdvancedVariableValueChange($event.name, $event.value)\">\n </cqa-advanced-variables-form>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button *ngIf=\"!isCreatingStep\" class=\"cqa-w-1/2\" variant=\"filled\" [text]=\"editMode ? 'Update Step' : 'Create Step'\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n <div *ngIf=\"isCreatingStep\" class=\"cqa-w-1/2 cqa-flex-1 cqa-min-h-[38px] cqa-rounded-[8px]\">\n <cqa-badge label=\"Creating\u2026\" icon=\"autorenew\" [isLoading]=\"true\" [fullWidth]=\"true\" [centerContent]=\"true\"\n [inlineStyles]=\"'min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center; justify-content: center;'\"\n variant=\"info\" size=\"medium\"></cqa-badge>\n </div>\n </div>\n</div>", 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", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i4.BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading", "fullWidth", "centerContent", "title"] }, { type: i5.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "enableMarkdown", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: i6.CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i7.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i10.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i11.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i12.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i13.AdvancedVariablesFormComponent, selector: "cqa-advanced-variables-form", inputs: ["advancedVariables", "advancedVariableForm"], outputs: ["variableBooleanChange", "variableValueChange"] }], directives: [{ type: i14.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i14.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i9.MatCellDef, selector: "[matCellDef]" }, { type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { type: i15.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i10.MatError, selector: "mat-error", inputs: ["id"] }, { type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i16.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }] });
862
895
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderDatabaseComponent, decorators: [{
863
896
  type: Component,
864
- args: [{ selector: 'cqa-step-builder-database', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n {{ editMode ? 'Update Database Test Step' : 'Create Database Test Step' }}\n </h2>\n\n <!-- Environment Section (separator line only on bottom) -->\n <div class=\"cqa-flex cqa-w-full cqa-justify-between cqa-gap-1.5 cqa-pb-[0.5rem] cqa-mb-4 cqa-border-0 cqa-border-b cqa-border-solid cqa-border-gray-200\">\n <div class=\"cqa-flex cqa-gap-4 cqa-items-start\">\n <!-- DB Environment -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n DB Environment <span class=\"cqa-text-red-500\">*</span>\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"getDbEnvironmentConfig()\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Database environments from Environments.\n </p>\n </div>\n\n <!-- Normal Environment -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n Normal Environment\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"getNormalEnvironmentConfig()\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Normal environments from Environments.\n </p>\n </div>\n </div>\n <div class=\"cqa-flex cqa-justify-end cqa-mt-2\">\n <cqa-button variant=\"filled\" text=\"Run Query\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!databaseForm.get('dbEnvironment')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[24px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[37px] hover:!cqa-bg-[#1B1FEB] cqa-flex-shrink-0'\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Main Content: Two Column Layout -->\n <div class=\"cqa-flex cqa-gap-[12px] cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Left Panel: Query List -->\n <div\n class=\"cqa-w-[175px] cqa-min-w-[175px] cqa-flex-shrink-0 cqa-flex cqa-flex-col cqa-border-0 cqa-border-r cqa-border-r-[1px] cqa-border-solid cqa-border-[#E0E0E0] cqa-bg-[#FAFAFA] cqa-overflow-hidden\">\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-2\">\n <div *ngFor=\"let query of queries; let i = index\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-[10px] cqa-w-full cqa-pt-[14px] cqa-pb-[14px] cqa-pl-[16px] cqa-pr-[16px] cqa-rounded-[8px] cqa-cursor-pointer cqa-mb-1\"\n [class.cqa-bg-blue-50]=\"selectedQueryIndex === i\"\n [class.cqa-border]=\"selectedQueryIndex === i\"\n [class.cqa-border-blue-500]=\"selectedQueryIndex === i\"\n [class.cqa-bg-grey-400]=\"selectedQueryIndex !== i\"\n (click)=\"onSelectQuery(i)\"\n style=\"height: 49px; min-height: 49px;\">\n <span class=\"cqa-text-sm cqa-font-medium cqa-text-gray-900\">Query {{ i + 1 }}</span>\n <cqa-badge *ngIf=\"query.status\"\n [label]=\"query.status === 'passed' ? 'Passed' : query.status === 'failed' ? 'Failed' : 'Pending'\"\n [variant]=\"query.status === 'passed' ? 'success' : query.status === 'failed' ? 'error' : 'default'\"\n size=\"small\">\n </cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Right Panel: Query Editor -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-overflow-auto\">\n <div class=\"cqa-flex-1 cqa-flex cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-gap-[10px] cqa-mb-4\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[6px]\" style=\"width: 50%;\">\n <div class=\"\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900 cqa-text-[14px]\">Query & Store Response<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span></h3>\n </div>\n\n <div class=\"cqa-flex cqa-justify-between\">\n <!-- SQL Query Textarea -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0 cqa-w-full cqa-rounded-md cqa-bg-gray-50/50\">\n <cqa-custom-textarea [placeholder]=\"'Enter your SQL query here...'\"\n [value]=\"getCurrentQueryFormGroup()?.get('query')?.value || ''\" [fullWidth]=\"true\" [rows]=\"8\"\n [textareaInlineStyle]=\"'padding: 1rem;'\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('query')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-flex cqa-flex-col cqa-gap-[10px] cqa-mb-[8px]\">\n\n\n <!-- Variable Input -->\n <div class=\"cqa-flex cqa-gap-4\">\n <div class=\"cqa-flex-1\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5 cqa-block cqa-text-[14px] cqa-font-semibold\">\n Variable<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n <cqa-custom-input [placeholder]=\"'Variable name'\"\n [value]=\"getCurrentQueryFormGroup()?.get('variable')?.value || ''\" [fullWidth]=\"true\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('variable')?.setValue($event)\">\n </cqa-custom-input>\n <p class=\"cqa-text-xs cqa-text-gray-500 cqa-mt-1\">\n Use letters, numbers, underscore. No spaces. Unique per step. Case sensitive.\n </p>\n </div>\n </div>\n <!-- Action Buttons (pinned to bottom) -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mt-auto\">\n <cqa-button variant=\"outlined\" text=\"Add Query\" icon=\"add\" (clicked)=\"addNewQuery()\"\n [customClass]=\"'cqa-bg-white !cqa-border-[#414146] cqa-text-sm cqa-font-semibold cqa-text-[#414146] cqa-whitespace-nowrap !cqa-py-[10px] !cqa-px-[10px] !cqa-gap-[8px] cqa-rounded-lg hover:!cqa-border-[#414146] hover:cqa-bg-gray-50'\"\n [iconColor]=\"'#414146'\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\"\n [customClass]=\"'cqa-min-w-[40px] cqa-w-10 cqa-h-9 cqa-rounded cqa-bg-gray-100 cqa-flex cqa-items-center cqa-justify-center hover:cqa-bg-gray-200 cqa-p-0'\"\n [tooltip]=\"'Delete query'\" (clicked)=\"deleteQueryById(getCurrentQuery()?.id || '')\"\n [disabled]=\"queries.length <= 1\" [attr.aria-label]=\"'Delete query'\">\n <svg class=\"cqa-flex-shrink-0\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#6B7280\" />\n </svg>\n </cqa-button>\n <cqa-button variant=\"filled\" text=\"Run\" icon=\"play_arrow\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!getCurrentQueryFormGroup()?.get('query')?.value || !databaseForm.get('dbEnvironment')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[16px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[38px] hover:!cqa-bg-[#1B1FEB] !cqa-border-none'\"\n [iconColor]=\"'#FBFCFF'\">\n </cqa-button>\n </div>\n </div>\n </div>\n <!-- Results Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-mb-6\">\n <!-- Tabs -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'output'\" [class.cqa-border-blue-600]=\"selectedTab === 'output'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'output'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'output'\" (click)=\"onTabChange('output')\">\n Output\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'verification'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'verification'\" (click)=\"onTabChange('verification')\">\n Verification\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'advanced'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'advanced'\" (click)=\"onTabChange('advanced')\">\n Advanced\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-p-4\">\n <!-- Output Tab -->\n <div *ngIf=\"selectedTab === 'output'\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3\">\n <h4 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Query Results</h4>\n <cqa-button variant=\"text\" text=\"Copy\" icon=\"content_copy\" [customClass]=\"'cqa-text-blue-600'\"\n (clicked)=\"onCopyResults()\">\n </cqa-button>\n </div>\n\n <!-- Results Table -->\n <div *ngIf=\"getCurrentQueryResult().length > 0\" class=\"cqa-overflow-x-auto\">\n <table class=\"cqa-w-full cqa-border-collapse\">\n <thead>\n <tr class=\"cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <th *ngFor=\"let key of getTableColumns()\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-left cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">\n {{ key }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getCurrentQueryResult()\" class=\"cqa-border-b cqa-border-gray-200 hover:cqa-bg-gray-50\">\n <td *ngFor=\"let key of getTableColumns()\" class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-text-gray-900\">\n {{ row[key] }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div *ngIf=\"getCurrentQueryResult().length === 0\"\n class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-sm\">\n No results yet. Run a query to see results.\n </div>\n </div>\n\n <!-- Verification Tab -->\n <div *ngIf=\"selectedTab === 'verification'\" class=\"assertions-container\">\n <!-- Header Section -->\n <div class=\"assertions-header\">\n <div class=\"header-content\">\n <h3 class=\"header-title\">Assertions</h3>\n <p class=\"header-subtitle\">Use JSONPath to target values in the query output.</p>\n </div>\n <button \n mat-stroked-button \n color=\"primary\" \n class=\"add-assertion-button\"\n (click)=\"addAssertion()\">\n <mat-icon>add</mat-icon>\n Add Assertion\n </button>\n </div>\n\n <!-- Table Section -->\n <form *ngIf=\"getCurrentAssertionsForm()\" [formGroup]=\"getCurrentAssertionsForm()!\" class=\"assertions-form\">\n <div formArrayName=\"assertions\">\n <div class=\"table-scroll-container\">\n <table mat-table [dataSource]=\"assertionsDataSource\" class=\"assertions-table\" #assertionsTable>\n <!-- JSONPath Column -->\n <ng-container matColumnDef=\"jsonPath\">\n <th mat-header-cell *matHeaderCellDef>jsonPath</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <input \n matInput \n formControlName=\"jsonPath\"\n placeholder=\"username\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'jsonPath')?.hasError('required') && \n getFormControlAt(i, 'jsonPath')?.touched\">\n JSONPath is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Verification Type Column -->\n <ng-container matColumnDef=\"verificationType\">\n <th mat-header-cell *matHeaderCellDef>verificationType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select formControlName=\"verificationType\">\n <mat-option value=\"equals\">Equals</mat-option>\n <mat-option value=\"not_equals\">Not Equals</mat-option>\n <mat-option value=\"contains\">Contains</mat-option>\n <mat-option value=\"not_contains\">Not Contains</mat-option>\n <mat-option value=\"greater_than\">Greater Than</mat-option>\n <mat-option value=\"less_than\">Less Than</mat-option>\n <mat-option value=\"greater_than_or_equals\">Greater Than Or Equals</mat-option>\n <mat-option value=\"less_than_or_equals\">Less Than Or Equals</mat-option>\n <mat-option value=\"exists\">Exists</mat-option>\n <mat-option value=\"not_exists\">Not Exists</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Type Column -->\n <ng-container matColumnDef=\"expectedType\">\n <th mat-header-cell *matHeaderCellDef>expectedType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select \n formControlName=\"expectedType\"\n (selectionChange)=\"onExpectedTypeChange(i, $event.value)\">\n <mat-option value=\"string\">String</mat-option>\n <mat-option value=\"number\">Number</mat-option>\n <mat-option value=\"boolean\">Boolean</mat-option>\n <mat-option value=\"object\">Object</mat-option>\n <mat-option value=\"array\">Array</mat-option>\n <mat-option value=\"null\">Null</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Value Column -->\n <ng-container matColumnDef=\"expectedValue\">\n <th mat-header-cell *matHeaderCellDef>expectedValue</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <!-- String, Array, Object Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'string' || getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <textarea \n *ngIf=\"getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n rows=\"3\"\n required></textarea>\n <input \n *ngIf=\"getExpectedType(i) === 'string'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('invalidType')\">\n {{ getFormControlAt(i, 'expectedValue')?.errors?.message }}\n </mat-error>\n </mat-form-field>\n\n <!-- Null Type Display -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'null'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n [disabled]=\"true\">\n </mat-form-field>\n\n <!-- Number Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'number'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n type=\"number\"\n formControlName=\"expectedValue\"\n placeholder=\"Expected Value in Number\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n\n <!-- Boolean Select -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'boolean'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <mat-select formControlName=\"expectedValue\" required>\n <mat-option value=\"true\">true</mat-option>\n <mat-option value=\"false\">false</mat-option>\n </mat-select>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <button \n mat-icon-button \n color=\"warn\"\n class=\"delete-button\"\n (click)=\"removeAssertion(i)\"\n [matTooltip]=\"'Delete assertion'\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"getAssertionsFormArray().length === 0\" class=\"empty-state\">\n <p>No assertions added. Click \"Add Assertion\" to create one.</p>\n </div>\n </div>\n </form>\n </div>\n\n <div *ngIf=\"selectedTab === 'advanced'\">\n <cqa-advanced-variables-form \n [advancedVariables]=\"advancedSettingsVariables\"\n [advancedVariableForm]=\"advancedVariablesForm\"\n (variableBooleanChange)=\"onAdvancedVariableBooleanChange($event.name, $event.value)\"\n (variableValueChange)=\"onAdvancedVariableValueChange($event.name, $event.value)\">\n </cqa-advanced-variables-form>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button *ngIf=\"!isCreatingStep\" class=\"cqa-w-1/2\" variant=\"filled\" [text]=\"editMode ? 'Update Step' : 'Create Step'\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n <div *ngIf=\"isCreatingStep\" class=\"cqa-w-1/2 cqa-flex-1 cqa-min-h-[38px] cqa-rounded-[8px]\">\n <cqa-badge label=\"Creating\u2026\" icon=\"autorenew\" [isLoading]=\"true\" [fullWidth]=\"true\" [centerContent]=\"true\"\n [inlineStyles]=\"'min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center; justify-content: center;'\"\n variant=\"info\" size=\"medium\"></cqa-badge>\n </div>\n </div>\n</div>", styles: [] }]
865
- }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { dbEnvironmentOptions: [{
897
+ args: [{ selector: 'cqa-step-builder-database', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n {{ editMode ? 'Update Database Test Step' : 'Create Database Test Step' }}\n </h2>\n\n <!-- Env banner \u2014 surfaces which environment scopes the DB Config + Normal Env. -->\n <div *ngIf=\"testCaseEnvironmentName\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-text-xs cqa-text-gray-700 cqa-bg-gray-50 cqa-border cqa-border-gray-200\">\n Using <strong class=\"cqa-font-semibold\">{{ testCaseEnvironmentName }} Environment</strong>\n <span class=\"cqa-text-gray-500\">\u00B7</span>\n <span class=\"cqa-text-gray-500\">Environment variables and DB configs are resolved from this environment.</span>\n </div>\n\n <!-- Environment Section (separator line only on bottom) -->\n <div class=\"cqa-flex cqa-w-full cqa-justify-between cqa-gap-1.5 cqa-pb-[0.5rem] cqa-mb-4 cqa-border-0 cqa-border-b cqa-border-solid cqa-border-gray-200\">\n <div class=\"cqa-flex cqa-gap-4 cqa-items-start\">\n <!-- DB Config -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n DB Config <span class=\"cqa-text-red-500\">*</span>\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"dbConfigSelectConfig\">\n </cqa-dynamic-select>\n </div>\n <p class=\"cqa-text-xs cqa-text-gray-500\">\n DB configs attached to the active environment.\n </p>\n </div>\n\n <!-- Normal Environment \u2014 hidden under Tier 1 (testCase.environmentId set);\n the env banner above already names the active env. -->\n <div *ngIf=\"!hideEnvironmentNameField\" class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-block\">\n Normal Environment\n </label>\n <div class=\"cqa-min-w-0\">\n <cqa-dynamic-select [form]=\"databaseForm\" [config]=\"normalEnvSelectConfig\">\n </cqa-dynamic-select>\n </div>\n <p *ngIf=\"environmentLegacyDeprecationMessage\"\n class=\"cqa-text-xs cqa-italic cqa-text-amber-600 cqa-m-0\"\n [innerHTML]=\"environmentLegacyDeprecationMessage\"></p>\n <p *ngIf=\"!environmentLegacyDeprecationMessage\" class=\"cqa-text-xs cqa-text-gray-500\">\n Uses Normal environments from Environments.\n </p>\n </div>\n </div>\n <div class=\"cqa-flex cqa-justify-end cqa-mt-2\">\n <cqa-button variant=\"filled\" text=\"Run Query\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!databaseForm.get('dbConfigId')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[24px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[37px] hover:!cqa-bg-[#1B1FEB] cqa-flex-shrink-0'\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Main Content: Two Column Layout -->\n <div class=\"cqa-flex cqa-gap-[12px] cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Left Panel: Query List -->\n <div\n class=\"cqa-w-[175px] cqa-min-w-[175px] cqa-flex-shrink-0 cqa-flex cqa-flex-col cqa-border-0 cqa-border-r cqa-border-r-[1px] cqa-border-solid cqa-border-[#E0E0E0] cqa-bg-[#FAFAFA] cqa-overflow-hidden\">\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-2\">\n <div *ngFor=\"let query of queries; let i = index\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-[10px] cqa-w-full cqa-pt-[14px] cqa-pb-[14px] cqa-pl-[16px] cqa-pr-[16px] cqa-rounded-[8px] cqa-cursor-pointer cqa-mb-1\"\n [class.cqa-bg-blue-50]=\"selectedQueryIndex === i\"\n [class.cqa-border]=\"selectedQueryIndex === i\"\n [class.cqa-border-blue-500]=\"selectedQueryIndex === i\"\n [class.cqa-bg-grey-400]=\"selectedQueryIndex !== i\"\n (click)=\"onSelectQuery(i)\"\n style=\"height: 49px; min-height: 49px;\">\n <span class=\"cqa-text-sm cqa-font-medium cqa-text-gray-900\">Query {{ i + 1 }}</span>\n <cqa-badge *ngIf=\"query.status\"\n [label]=\"query.status === 'passed' ? 'Passed' : query.status === 'failed' ? 'Failed' : 'Pending'\"\n [variant]=\"query.status === 'passed' ? 'success' : query.status === 'failed' ? 'error' : 'default'\"\n size=\"small\">\n </cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Right Panel: Query Editor -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-overflow-auto\">\n <div class=\"cqa-flex-1 cqa-flex cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-gap-[10px] cqa-mb-4\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[6px]\" style=\"width: 50%;\">\n <div class=\"\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900 cqa-text-[14px]\">Query & Store Response<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span></h3>\n </div>\n\n <div class=\"cqa-flex cqa-justify-between\">\n <!-- SQL Query Textarea -->\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0 cqa-w-full cqa-rounded-md cqa-bg-gray-50/50\">\n <cqa-custom-textarea [placeholder]=\"'Enter your SQL query here...'\"\n [value]=\"getCurrentQueryFormGroup()?.get('query')?.value || ''\" [fullWidth]=\"true\" [rows]=\"8\"\n [textareaInlineStyle]=\"'padding: 1rem;'\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('query')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-flex cqa-flex-col cqa-gap-[10px] cqa-mb-[8px]\">\n\n\n <!-- Variable Input -->\n <div class=\"cqa-flex cqa-gap-4\">\n <div class=\"cqa-flex-1\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5 cqa-block cqa-text-[14px] cqa-font-semibold\">\n Variable<span class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n <cqa-custom-input [placeholder]=\"'Variable name'\"\n [value]=\"getCurrentQueryFormGroup()?.get('variable')?.value || ''\" [fullWidth]=\"true\"\n (valueChange)=\"getCurrentQueryFormGroup()?.get('variable')?.setValue($event)\">\n </cqa-custom-input>\n <p class=\"cqa-text-xs cqa-text-gray-500 cqa-mt-1\">\n Use letters, numbers, underscore. No spaces. Unique per step. Case sensitive.\n </p>\n </div>\n </div>\n <!-- Action Buttons (pinned to bottom) -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mt-auto\">\n <cqa-button variant=\"outlined\" text=\"Add Query\" icon=\"add\" (clicked)=\"addNewQuery()\"\n [customClass]=\"'cqa-bg-white !cqa-border-[#414146] cqa-text-sm cqa-font-semibold cqa-text-[#414146] cqa-whitespace-nowrap !cqa-py-[10px] !cqa-px-[10px] !cqa-gap-[8px] cqa-rounded-lg hover:!cqa-border-[#414146] hover:cqa-bg-gray-50'\"\n [iconColor]=\"'#414146'\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\"\n [customClass]=\"'cqa-min-w-[40px] cqa-w-10 cqa-h-9 cqa-rounded cqa-bg-gray-100 cqa-flex cqa-items-center cqa-justify-center hover:cqa-bg-gray-200 cqa-p-0'\"\n [tooltip]=\"'Delete query'\" (clicked)=\"deleteQueryById(getCurrentQuery()?.id || '')\"\n [disabled]=\"queries.length <= 1\" [attr.aria-label]=\"'Delete query'\">\n <svg class=\"cqa-flex-shrink-0\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#6B7280\" />\n </svg>\n </cqa-button>\n <cqa-button variant=\"filled\" text=\"Run\" icon=\"play_arrow\" (clicked)=\"onRunQuery()\"\n [disabled]=\"!getCurrentQueryFormGroup()?.get('query')?.value || !databaseForm.get('dbConfigId')?.value || isLoading\"\n [customClass]=\"'!cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] cqa-text-sm cqa-font-semibold cqa-whitespace-nowrap !cqa-pt-[10px] !cqa-pb-[10px] !cqa-pl-[16px] !cqa-pr-[24px] !cqa-gap-[8px] cqa-rounded-lg cqa-min-h-[38px] hover:!cqa-bg-[#1B1FEB] !cqa-border-none'\"\n [iconColor]=\"'#FBFCFF'\">\n </cqa-button>\n </div>\n </div>\n </div>\n <!-- Results Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-mb-6\">\n <!-- Tabs -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'output'\" [class.cqa-border-blue-600]=\"selectedTab === 'output'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'output'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'output'\" (click)=\"onTabChange('output')\">\n Output\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'verification'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'verification'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'verification'\" (click)=\"onTabChange('verification')\">\n Verification\n </button>\n <button type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'advanced'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'advanced'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'advanced'\" (click)=\"onTabChange('advanced')\">\n Advanced\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-p-4\">\n <!-- Output Tab -->\n <div *ngIf=\"selectedTab === 'output'\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3\">\n <h4 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Query Results</h4>\n <cqa-button variant=\"text\" text=\"Copy\" icon=\"content_copy\" [customClass]=\"'cqa-text-blue-600'\"\n (clicked)=\"onCopyResults()\">\n </cqa-button>\n </div>\n\n <!-- Results Table -->\n <div *ngIf=\"getCurrentQueryResult().length > 0\" class=\"cqa-overflow-x-auto\">\n <table class=\"cqa-w-full cqa-border-collapse\">\n <thead>\n <tr class=\"cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <th *ngFor=\"let key of getTableColumns()\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-left cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">\n {{ key }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getCurrentQueryResult()\" class=\"cqa-border-b cqa-border-gray-200 hover:cqa-bg-gray-50\">\n <td *ngFor=\"let key of getTableColumns()\" class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-text-gray-900\">\n {{ row[key] }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div *ngIf=\"getCurrentQueryResult().length === 0\"\n class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-sm\">\n No results yet. Run a query to see results.\n </div>\n </div>\n\n <!-- Verification Tab -->\n <div *ngIf=\"selectedTab === 'verification'\" class=\"assertions-container\">\n <!-- Header Section -->\n <div class=\"assertions-header\">\n <div class=\"header-content\">\n <h3 class=\"header-title\">Assertions</h3>\n <p class=\"header-subtitle\">Use JSONPath to target values in the query output.</p>\n </div>\n <button \n mat-stroked-button \n color=\"primary\" \n class=\"add-assertion-button\"\n (click)=\"addAssertion()\">\n <mat-icon>add</mat-icon>\n Add Assertion\n </button>\n </div>\n\n <!-- Table Section -->\n <form *ngIf=\"getCurrentAssertionsForm()\" [formGroup]=\"getCurrentAssertionsForm()!\" class=\"assertions-form\">\n <div formArrayName=\"assertions\">\n <div class=\"table-scroll-container\">\n <table mat-table [dataSource]=\"assertionsDataSource\" class=\"assertions-table\" #assertionsTable>\n <!-- JSONPath Column -->\n <ng-container matColumnDef=\"jsonPath\">\n <th mat-header-cell *matHeaderCellDef>jsonPath</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <input \n matInput \n formControlName=\"jsonPath\"\n placeholder=\"username\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'jsonPath')?.hasError('required') && \n getFormControlAt(i, 'jsonPath')?.touched\">\n JSONPath is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Verification Type Column -->\n <ng-container matColumnDef=\"verificationType\">\n <th mat-header-cell *matHeaderCellDef>verificationType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select formControlName=\"verificationType\">\n <mat-option value=\"equals\">Equals</mat-option>\n <mat-option value=\"not_equals\">Not Equals</mat-option>\n <mat-option value=\"contains\">Contains</mat-option>\n <mat-option value=\"not_contains\">Not Contains</mat-option>\n <mat-option value=\"greater_than\">Greater Than</mat-option>\n <mat-option value=\"less_than\">Less Than</mat-option>\n <mat-option value=\"greater_than_or_equals\">Greater Than Or Equals</mat-option>\n <mat-option value=\"less_than_or_equals\">Less Than Or Equals</mat-option>\n <mat-option value=\"exists\">Exists</mat-option>\n <mat-option value=\"not_exists\">Not Exists</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Type Column -->\n <ng-container matColumnDef=\"expectedType\">\n <th mat-header-cell *matHeaderCellDef>expectedType</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <mat-form-field appearance=\"outline\" class=\"full-width-field\">\n <mat-select \n formControlName=\"expectedType\"\n (selectionChange)=\"onExpectedTypeChange(i, $event.value)\">\n <mat-option value=\"string\">String</mat-option>\n <mat-option value=\"number\">Number</mat-option>\n <mat-option value=\"boolean\">Boolean</mat-option>\n <mat-option value=\"object\">Object</mat-option>\n <mat-option value=\"array\">Array</mat-option>\n <mat-option value=\"null\">Null</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Expected Value Column -->\n <ng-container matColumnDef=\"expectedValue\">\n <th mat-header-cell *matHeaderCellDef>expectedValue</th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <ng-container [formGroupName]=\"i\">\n <!-- String, Array, Object Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'string' || getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <textarea \n *ngIf=\"getExpectedType(i) === 'array' || getExpectedType(i) === 'object'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n rows=\"3\"\n required></textarea>\n <input \n *ngIf=\"getExpectedType(i) === 'string'\"\n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('invalidType')\">\n {{ getFormControlAt(i, 'expectedValue')?.errors?.message }}\n </mat-error>\n </mat-form-field>\n\n <!-- Null Type Display -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'null'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n formControlName=\"expectedValue\"\n [placeholder]=\"getExpectedValuePlaceholder(i)\"\n [disabled]=\"true\">\n </mat-form-field>\n\n <!-- Number Input -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'number'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <input \n matInput \n type=\"number\"\n formControlName=\"expectedValue\"\n placeholder=\"Expected Value in Number\"\n required>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n\n <!-- Boolean Select -->\n <mat-form-field \n *ngIf=\"getExpectedType(i) === 'boolean'\"\n appearance=\"outline\" \n class=\"full-width-field\">\n <mat-select formControlName=\"expectedValue\" required>\n <mat-option value=\"true\">true</mat-option>\n <mat-option value=\"false\">false</mat-option>\n </mat-select>\n <mat-error *ngIf=\"getFormControlAt(i, 'expectedValue')?.hasError('required') && \n getFormControlAt(i, 'expectedValue')?.touched\">\n Expected value is required\n </mat-error>\n </mat-form-field>\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let assertion; let i = index\">\n <button \n mat-icon-button \n color=\"warn\"\n class=\"delete-button\"\n (click)=\"removeAssertion(i)\"\n [matTooltip]=\"'Delete assertion'\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"getAssertionsFormArray().length === 0\" class=\"empty-state\">\n <p>No assertions added. Click \"Add Assertion\" to create one.</p>\n </div>\n </div>\n </form>\n </div>\n\n <div *ngIf=\"selectedTab === 'advanced'\">\n <cqa-advanced-variables-form \n [advancedVariables]=\"advancedSettingsVariables\"\n [advancedVariableForm]=\"advancedVariablesForm\"\n (variableBooleanChange)=\"onAdvancedVariableBooleanChange($event.name, $event.value)\"\n (variableValueChange)=\"onAdvancedVariableValueChange($event.name, $event.value)\">\n </cqa-advanced-variables-form>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button *ngIf=\"!isCreatingStep\" class=\"cqa-w-1/2\" variant=\"filled\" [text]=\"editMode ? 'Update Step' : 'Create Step'\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n <div *ngIf=\"isCreatingStep\" class=\"cqa-w-1/2 cqa-flex-1 cqa-min-h-[38px] cqa-rounded-[8px]\">\n <cqa-badge label=\"Creating\u2026\" icon=\"autorenew\" [isLoading]=\"true\" [fullWidth]=\"true\" [centerContent]=\"true\"\n [inlineStyles]=\"'min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center; justify-content: center;'\"\n variant=\"info\" size=\"medium\"></cqa-badge>\n </div>\n </div>\n</div>", styles: [] }]
898
+ }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { dbConfigOptions: [{
899
+ type: Input
900
+ }], isLoadingDbConfigs: [{
866
901
  type: Input
867
902
  }], normalEnvironmentOptions: [{
868
903
  type: Input
@@ -872,10 +907,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
872
907
  type: Input
873
908
  }], isLoading: [{
874
909
  type: Input
875
- }], initialDbEnvironment: [{
910
+ }], initialDbConfigId: [{
876
911
  type: Input
877
912
  }], initialNormalEnvironment: [{
878
913
  type: Input
914
+ }], testCaseEnvironmentName: [{
915
+ type: Input
916
+ }], testCaseEnvironmentLabelSuffix: [{
917
+ type: Input
918
+ }], environmentLegacyDeprecationMessage: [{
919
+ type: Input
879
920
  }], editMode: [{
880
921
  type: Input
881
922
  }], isCreatingStep: [{
@@ -886,7 +927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
886
927
  type: Output
887
928
  }], runQuery: [{
888
929
  type: Output
889
- }], searchDbEnvironment: [{
930
+ }], searchDbConfig: [{
890
931
  type: Output
891
932
  }], searchNormalEnvironment: [{
892
933
  type: Output
@@ -906,4 +947,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
906
947
  }], advancedSettingsVariables: [{
907
948
  type: Input
908
949
  }] } });
909
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1idWlsZGVyLWRhdGFiYXNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3RlcC1idWlsZGVyL3N0ZXAtYnVpbGRlci1kYXRhYmFzZS9zdGVwLWJ1aWxkZXItZGF0YWJhc2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zdGVwLWJ1aWxkZXIvc3RlcC1idWlsZGVyLWRhdGFiYXNlL3N0ZXAtYnVpbGRlci1kYXRhYmFzZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFvQyxTQUFTLEVBQWdDLE1BQU0sZUFBZSxDQUFDO0FBQ2xKLE9BQU8sRUFBZSxTQUFTLEVBQUUsU0FBUyxFQUFlLFVBQVUsRUFBbUIsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNEI3RyxNQUFNLE9BQU8sNEJBQTRCO0lBeUV2QyxZQUNVLEVBQWUsRUFDZixHQUFzQjtRQUR0QixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ2YsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUExRWhDLDBDQUEwQztRQUNqQyx5QkFBb0IsR0FBbUIsRUFBRSxDQUFDO1FBRW5ELDhDQUE4QztRQUNyQyw2QkFBd0IsR0FBbUIsRUFBRSxDQUFDO1FBRXZELDJCQUEyQjtRQUNsQixZQUFPLEdBQW9CLEVBQUUsQ0FBQztRQUV2Qyx3RUFBd0U7UUFDL0QsaUJBQVksR0FBVSxFQUFFLENBQUM7UUFFbEMsb0JBQW9CO1FBQ1gsY0FBUyxHQUFZLEtBQUssQ0FBQztRQVdwQyx5R0FBeUc7UUFDaEcsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFFekMsZ0NBQWdDO1FBQ3RCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBb0IsQ0FBQztRQUU1RCwwQkFBMEI7UUFDaEIsY0FBUyxHQUFHLElBQUks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S0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBR0ksVUFBVTtzQkFBbkIsTUFBTTtnQkFHRyxTQUFTO3NCQUFsQixNQUFNO2dCQUdHLFFBQVE7c0JBQWpCLE1BQU07Z0JBR0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUdHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFHRyxRQUFRO3NCQUFqQixNQUFNO2dCQUdHLFdBQVc7c0JBQXBCLE1BQU07Z0JBR0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUdHLHdCQUF3QjtzQkFBakMsTUFBTTtnQkFHRyxlQUFlO3NCQUF4QixNQUFNO2dCQVd1QixlQUFlO3NCQUE1QyxTQUFTO3VCQUFDLGlCQUFpQjtnQkFHbkIseUJBQXlCO3NCQUFqQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIENoYW5nZURldGVjdG9yUmVmLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIEZvcm1BcnJheSwgRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMsIEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcbmltcG9ydCB7IE1hdFRhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJhc2VRdWVyeSB7XG4gIGlkOiBzdHJpbmc7XG4gIHF1ZXJ5OiBzdHJpbmc7XG4gIHZhcmlhYmxlOiBzdHJpbmc7XG4gIHN0YXR1cz86ICdwYXNzZWQnIHwgJ2ZhaWxlZCcgfCAncGVuZGluZyc7XG4gIGFzc2VydGlvbkRhdGE/OiBhbnlbXTsgLy8gQXNzZXJ0aW9uIGRhdGEgZm9yIHZlcmlmaWNhdGlvblxuICAvKiogUmVzdWx0IHJvd3MgZm9yIHRoaXMgcXVlcnkgKHNob3duIGluIE91dHB1dCB0YWIpLiAqL1xuICBxdWVyeVJlc3VsdD86IGFueVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlRm9ybURhdGEge1xuICBkYkVudmlyb25tZW50OiBzdHJpbmc7XG4gIG5vcm1hbEVudmlyb25tZW50Pzogc3RyaW5nO1xuICBxdWVyaWVzOiBEYXRhYmFzZVF1ZXJ5W107XG4gIGFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXM/OiBhbnlbXTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLXN0ZXAtYnVpbGRlci1kYXRhYmFzZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdGVwLWJ1aWxkZXItZGF0YWJhc2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFtdLFxuICBob3N0OiB7IGNsYXNzOiAnY3FhLXVpLXJvb3QnIH1cbn0pXG5leHBvcnQgY2xhc3MgU3RlcEJ1aWxkZXJEYXRhYmFzZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKiogT3B0aW9ucyBmb3IgREIgZW52aXJvbm1lbnQgZHJvcGRvd24gKi9cbiAgQElucHV0KCkgZGJFbnZpcm9ubWVudE9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW107XG5cbiAgLyoqIE9wdGlvbnMgZm9yIE5vcm1hbCBlbnZpcm9ubWVudCBkcm9wZG93biAqL1xuICBASW5wdXQoKSBub3JtYWxFbnZpcm9ubWVudE9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW107XG5cbiAgLyoqIEluaXRpYWwgcXVlcmllcyBsaXN0ICovXG4gIEBJbnB1dCgpIHF1ZXJpZXM6IERhdGFiYXNlUXVlcnlbXSA9IFtdO1xuXG4gIC8qKiBRdWVyeSByZXN1bHRzIGRhdGEgKGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgcGVyLXF1ZXJ5IHF1ZXJ5UmVzdWx0KSAqL1xuICBASW5wdXQoKSBxdWVyeVJlc3VsdHM6IGFueVtdID0gW107XG5cbiAgLyoqIExvYWRpbmcgc3RhdGUgKi9cbiAgQElucHV0KCkgaXNMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIEluaXRpYWwgREIgZW52aXJvbm1lbnQgZm9yIGVkaXQgbW9kZSAqL1xuICBASW5wdXQoKSBpbml0aWFsRGJFbnZpcm9ubWVudD86IHN0cmluZztcblxuICAvKiogSW5pdGlhbCBOb3JtYWwgZW52aXJvbm1lbnQgZm9yIGVkaXQgbW9kZSAqL1xuICBASW5wdXQoKSBpbml0aWFsTm9ybWFsRW52aXJvbm1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqIFdoZXRoZXIgaW4gZWRpdCBtb2RlICovXG4gIEBJbnB1dCgpIGVkaXRNb2RlPzogYm9vbGVhbjtcblxuICAvKiogVHJ1ZSB3aGlsZSBwYXJlbnQgaXMgY3JlYXRpbmcgdGhlIHN0ZXAgKEFQSSBpbiBwcm9ncmVzcyk7IHNob3cgbG9hZGVyIG9uIENyZWF0ZS9VcGRhdGUgU3RlcCBidXR0b24gKi9cbiAgQElucHV0KCkgaXNDcmVhdGluZ1N0ZXA6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogRW1pdCB3aGVuIHN0ZXAgaXMgY3JlYXRlZCAqL1xuICBAT3V0cHV0KCkgY3JlYXRlU3RlcCA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0YWJhc2VGb3JtRGF0YT4oKTtcblxuICAvKiogRW1pdCB3aGVuIGNhbmNlbGxlZCAqL1xuICBAT3V0cHV0KCkgY2FuY2VsbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcXVlcnkgaXMgcnVuICovXG4gIEBPdXRwdXQoKSBydW5RdWVyeSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBjdXJyZW50UXVlcnk6IERhdGFiYXNlUXVlcnk7IHF1ZXJ5OiBzdHJpbmc7IHZhcmlhYmxlOiBzdHJpbmc7IGRiRW52aXJvbm1lbnQ6IHN0cmluZzsgbm9ybWFsRW52aXJvbm1lbnQ/OiBzdHJpbmcgfT4oKTtcblxuICAvKiogRW1pdCB3aGVuIERCIGVudmlyb25tZW50IHNlYXJjaCBpcyB0cmlnZ2VyZWQgKi9cbiAgQE91dHB1dCgpIHNlYXJjaERiRW52aXJvbm1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRW1pdCB3aGVuIE5vcm1hbCBlbnZpcm9ubWVudCBzZWFyY2ggaXMgdHJpZ2dlcmVkICovXG4gIEBPdXRwdXQoKSBzZWFyY2hOb3JtYWxFbnZpcm9ubWVudCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcXVlcnkgaXMgYWRkZWQgKi9cbiAgQE91dHB1dCgpIGFkZFF1ZXJ5ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcXVlcnkgaXMgZGVsZXRlZCAqL1xuICBAT3V0cHV0KCkgZGVsZXRlUXVlcnkgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRW1pdCB3aGVuIGFzc2VydGlvbiBkYXRhIGNoYW5nZXMgZm9yIGEgcXVlcnkgKi9cbiAgQE91dHB1dCgpIGFzc2VydGlvbkRhdGFDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcXVlcnlJbmRleDogbnVtYmVyOyBhc3NlcnRpb25EYXRhOiBhbnlbXSB9PigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gc2VsZWN0ZWQgcXVlcnkgaW5kZXggY2hhbmdlcyAqL1xuICBAT3V0cHV0KCkgc2VsZWN0ZWRRdWVyeUluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgLyoqIEVtaXQgd2hlbiBhY3RpdmUgdGFiIGNoYW5nZXMgKi9cbiAgQE91dHB1dCgpIGFjdGl2ZVRhYkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8J291dHB1dCcgfCAndmVyaWZpY2F0aW9uJyB8ICdhZHZhbmNlZCc+KCk7XG5cbiAgZGF0YWJhc2VGb3JtOiBGb3JtR3JvdXA7XG4gIHNlbGVjdGVkVGFiOiAnb3V0cHV0JyB8ICd2ZXJpZmljYXRpb24nIHwgJ2FkdmFuY2VkJyA9ICdvdXRwdXQnO1xuICBzZWxlY3RlZFF1ZXJ5SW5kZXg6IG51bWJlciA9IDA7XG5cbiAgLy8gQXNzZXJ0aW9ucyBmb3JtIG1hbmFnZW1lbnQgLSBvbmUgZm9ybSBwZXIgcXVlcnlcbiAgYXNzZXJ0aW9uc0Zvcm1zOiBNYXA8bnVtYmVyLCBGb3JtR3JvdXA+ID0gbmV3IE1hcCgpO1xuICBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFsnanNvblBhdGgnLCAndmVyaWZpY2F0aW9uVHlwZScsICdleHBlY3RlZFR5cGUnLCAnZXhwZWN0ZWRWYWx1ZScsICdhY3Rpb25zJ107XG4gIGRlZmF1bHRFeHBlY3RlZFR5cGUgPSAnc3RyaW5nJztcbiAgcHJpdmF0ZSBmb3JtU3Vic2NyaXB0aW9uczogTWFwPG51bWJlciwgU3Vic2NyaXB0aW9uPiA9IG5ldyBNYXAoKTtcbiAgQFZpZXdDaGlsZCgnYXNzZXJ0aW9uc1RhYmxlJykgYXNzZXJ0aW9uc1RhYmxlPzogTWF0VGFibGU8YW55PjtcblxuICAvLyBBZHZhbmNlZCBzZXR0aW5ncyB2YXJpYWJsZXMgKGdlbmVyaWMgcGVyIHN0ZXAsIGNhbiBiZSBwcm92aWRlZCBieSBwYXJlbnQpXG4gIEBJbnB1dCgpIGFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXM6IGFueVtdID0gW107XG4gIGFkdmFuY2VkVmFyaWFibGVzRm9ybTogRm9ybUFycmF5ID0gbmV3IEZvcm1BcnJheShbXSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXG4gICkge1xuICAgIHRoaXMuZGF0YWJhc2VGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBkYkVudmlyb25tZW50OiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgbm9ybWFsRW52aXJvbm1lbnQ6IFsnJ10sXG4gICAgICBxdWVyaWVzOiB0aGlzLmZiLmFycmF5KFtdKVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplRm9ybVdpdGhJbml0aWFsVmFsdWVzKCk7XG4gICAgLy8gSWYgcGFyZW50IHByb3ZpZGVkIGFkdmFuY2VkIHNldHRpbmdzLCBidWlsZCBmcm9tIHRoZW07IG90aGVyd2lzZSBpbml0aWFsaXplIGRlZmF1bHRzXG4gICAgaWYgKHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcyAmJiB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5idWlsZEFkdmFuY2VkVmFyaWFibGVzRm9ybSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmluaXRpYWxpemVBZHZhbmNlZFNldHRpbmdzKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydxdWVyaWVzJ10gJiYgIWNoYW5nZXNbJ3F1ZXJpZXMnXS5maXJzdENoYW5nZSkge1xuICAgICAgLy8gUmVidWlsZCBmb3JtIGFycmF5IHdoZW4gcXVlcmllcyBjaGFuZ2VcbiAgICAgIGNvbnN0IHF1ZXJpZXNBcnJheSA9IHRoaXMuZGF0YWJhc2VGb3JtLmdldCgncXVlcmllcycpIGFzIEZvcm1BcnJheTtcbiAgICAgIHdoaWxlIChxdWVyaWVzQXJyYXkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHF1ZXJpZXNBcnJheS5yZW1vdmVBdCgwKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIG9sZCBhc3NlcnRpb25zIGZvcm1zXG4gICAgICB0aGlzLmFzc2VydGlvbnNGb3Jtcy5mb3JFYWNoKChmb3JtLCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5oYXMoaW5kZXgpKSB7XG4gICAgICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5nZXQoaW5kZXgpIS51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmNsZWFyKCk7XG4gICAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmNsZWFyKCk7XG5cbiAgICAgIC8vIFJlYnVpbGQgcXVlcmllcyBhbmQgYXNzZXJ0aW9ucyBmb3Jtc1xuICAgICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKHF1ZXJ5LCBpbmRleCkgPT4ge1xuICAgICAgICAvLyBFbnN1cmUgYXNzZXJ0aW9uIGRhdGEgaXMgaW5pdGlhbGl6ZWRcbiAgICAgICAgaWYgKCFxdWVyeS5hc3NlcnRpb25EYXRhKSB7XG4gICAgICAgICAgcXVlcnkuYXNzZXJ0aW9uRGF0YSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkUXVlcnlUb0Zvcm0ocXVlcnkpO1xuICAgICAgICAvLyBJbml0aWFsaXplIGFzc2VydGlvbnMgZm9ybSBmb3IgZWFjaCBxdWVyeVxuICAgICAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZChpbmRleCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gRW5zdXJlIHNlbGVjdGVkIHF1ZXJ5IGluZGV4IGlzIHZhbGlkXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPj0gdGhpcy5xdWVyaWVzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA9IE1hdGgubWF4KDAsIHRoaXMucXVlcmllcy5sZW5ndGggLSAxKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2luaXRpYWxEYkVudmlyb25tZW50J10gJiYgY2hhbmdlc1snaW5pdGlhbERiRW52aXJvbm1lbnQnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMuZGF0YWJhc2VGb3JtLnBhdGNoVmFsdWUoeyBkYkVudmlyb25tZW50OiBjaGFuZ2VzWydpbml0aWFsRGJFbnZpcm9ubWVudCddLmN1cnJlbnRWYWx1ZSB9KTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2luaXRpYWxOb3JtYWxFbnZpcm9ubWVudCddICYmIGNoYW5nZXNbJ2luaXRpYWxOb3JtYWxFbnZpcm9ubWVudCddLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy5kYXRhYmFzZUZvcm0ucGF0Y2hWYWx1ZSh7IG5vcm1hbEVudmlyb25tZW50OiBjaGFuZ2VzWydpbml0aWFsTm9ybWFsRW52aXJvbm1lbnQnXS5jdXJyZW50VmFsdWUgfSk7XG4gICAgfVxuXG4gICAgLy8gV2hlbiBwYXJlbnQgdXBkYXRlcyBhZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzLCByZWJ1aWxkIGFkdmFuY2VkIGZvcm1cbiAgICBpZiAoY2hhbmdlc1snYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcyddICYmIHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcykge1xuICAgICAgaWYgKHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuYnVpbGRBZHZhbmNlZFZhcmlhYmxlc0Zvcm0oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUFkdmFuY2VkU2V0dGluZ3MoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVGb3JtV2l0aEluaXRpYWxWYWx1ZXMoKTogdm9pZCB7XG4gICAgLy8gU2V0IGluaXRpYWwgREIgZW52aXJvbm1lbnQgaWYgcHJvdmlkZWRcbiAgICBpZiAodGhpcy5pbml0aWFsRGJFbnZpcm9ubWVudCkge1xuICAgICAgdGhpcy5kYXRhYmFzZUZvcm0ucGF0Y2hWYWx1ZSh7IGRiRW52aXJvbm1lbnQ6IHRoaXMuaW5pdGlhbERiRW52aXJvbm1lbnQgfSk7XG4gICAgfVxuICAgIC8vIFNldCBpbml0aWFsIE5vcm1hbCBlbnZpcm9ubWVudCBpZiBwcm92aWRlZFxuICAgIGlmICh0aGlzLmluaXRpYWxOb3JtYWxFbnZpcm9ubWVudCkge1xuICAgICAgdGhpcy5kYXRhYmFzZUZvcm0ucGF0Y2hWYWx1ZSh7IG5vcm1hbEVudmlyb25tZW50OiB0aGlzLmluaXRpYWxOb3JtYWxFbnZpcm9ubWVudCB9KTtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIHdpdGggcXVlcmllcyBpZiBwcm92aWRlZCwgb3RoZXJ3aXNlIGFkZCBkZWZhdWx0IHF1ZXJ5XG4gICAgaWYgKHRoaXMucXVlcmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuYWRkTmV3UXVlcnkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKHF1ZXJ5LCBpbmRleCkgPT4ge1xuICAgICAgICAvLyBFbnN1cmUgYXNzZXJ0aW9uIGRhdGEgaXMgaW5pdGlhbGl6ZWRcbiAgICAgICAgaWYgKCFxdWVyeS5hc3NlcnRpb25EYXRhKSB7XG4gICAgICAgICAgcXVlcnkuYXNzZXJ0aW9uRGF0YSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkUXVlcnlUb0Zvcm0ocXVlcnkpO1xuICAgICAgICAvLyBJbml0aWFsaXplIGFzc2VydGlvbnMgZm9ybSBmb3IgZWFjaCBxdWVyeVxuICAgICAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZChpbmRleCk7XG4gICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID0gMDtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleENoYW5nZS5lbWl0KDApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgcXVlcmllc0Zvcm1BcnJheSgpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlRm9ybS5nZXQoJ3F1ZXJpZXMnKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBhZGROZXdRdWVyeSgpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdRdWVyeTogRGF0YWJhc2VRdWVyeSA9IHtcbiAgICAgIGlkOiBgcXVlcnlfJHtEYXRlLm5vdygpfWAsXG4gICAgICBxdWVyeTogJycsXG4gICAgICB2YXJpYWJsZTogJycsXG4gICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgIGFzc2VydGlvbkRhdGE6IFtdIC8vIEluaXRpYWxpemUgd2l0aCBlbXB0eSBhc3NlcnRpb24gZGF0YVxuICAgIH07XG4gICAgdGhpcy5xdWVyaWVzLnB1c2gobmV3UXVlcnkpO1xuICAgIHRoaXMuYWRkUXVlcnlUb0Zvcm0obmV3UXVlcnkpO1xuICAgIGNvbnN0IG5ld0luZGV4ID0gdGhpcy5xdWVyaWVzLmxlbmd0aCAtIDE7XG4gICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPSBuZXdJbmRleDtcbiAgICAvLyBJbml0aWFsaXplIGFzc2VydGlvbnMgZm9ybSBmb3IgdGhlIG5ldyBxdWVyeVxuICAgIHRoaXMuZW5zdXJlQXNzZXJ0aW9uRGF0YUluaXRpYWxpemVkKG5ld0luZGV4KTtcbiAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleENoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KTtcbiAgICB0aGlzLmFkZFF1ZXJ5LmVtaXQoKTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZFF1ZXJ5VG9Gb3JtKHF1ZXJ5OiBEYXRhYmFzZVF1ZXJ5KTogdm9pZCB7XG4gICAgY29uc3QgcXVlcnlHcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgaWQ6IFtxdWVyeS5pZF0sXG4gICAgICBxdWVyeTogW3F1ZXJ5LnF1ZXJ5LCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIHZhcmlhYmxlOiBbcXVlcnkudmFyaWFibGUsIFZhbGlkYXRvcnMucmVxdWlyZWRdXG4gICAgfSk7XG4gICAgdGhpcy5xdWVyaWVzRm9ybUFycmF5LnB1c2gocXVlcnlHcm91cCk7XG4gIH1cblxuICBkZWxldGVRdWVyeUJ5SWQocXVlcnlJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnF1ZXJpZXMuZmluZEluZGV4KHEgPT4gcS5pZCA9PT0gcXVlcnlJZCk7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gQ2xlYW4gdXAgYXNzZXJ0aW9ucyBmb3JtIGFuZCBzdWJzY3JpcHRpb24gZm9yIHRoaXMgcXVlcnlcbiAgICAgIGlmICh0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmhhcyhpbmRleCkpIHtcbiAgICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5nZXQoaW5kZXgpIS51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmRlbGV0ZShpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLmFzc2VydGlvbnNGb3Jtcy5kZWxldGUoaW5kZXgpO1xuXG4gICAgICAvLyBSZWluZGV4IHJlbWFpbmluZyBmb3JtcyBhbmQgc3Vic2NyaXB0aW9uc1xuICAgICAgY29uc3QgZm9ybXNUb1JlaW5kZXggPSBuZXcgTWFwPG51bWJlciwgRm9ybUdyb3VwPigpO1xuICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uc1RvUmVpbmRleCA9IG5ldyBNYXA8bnVtYmVyLCBTdWJzY3JpcHRpb24+KCk7XG4gICAgICBcbiAgICAgIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmZvckVhY2goKGZvcm0sIG9sZEluZGV4KSA9PiB7XG4gICAgICAgIGlmIChvbGRJbmRleCA+IGluZGV4KSB7XG4gICAgICAgICAgZm9ybXNUb1JlaW5kZXguc2V0KG9sZEluZGV4IC0gMSwgZm9ybSk7XG4gICAgICAgIH0gZWxzZSBpZiAob2xkSW5kZXggPCBpbmRleCkge1xuICAgICAgICAgIGZvcm1zVG9SZWluZGV4LnNldChvbGRJbmRleCwgZm9ybSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmZvckVhY2goKHN1Yiwgb2xkSW5kZXgpID0+IHtcbiAgICAgICAgaWYgKG9sZEluZGV4ID4gaW5kZXgpIHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zVG9SZWluZGV4LnNldChvbGRJbmRleCAtIDEsIHN1Yik7XG4gICAgICAgIH0gZWxzZSBpZiAob2xkSW5kZXggPCBpbmRleCkge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnNUb1JlaW5kZXguc2V0KG9sZEluZGV4LCBzdWIpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5hc3NlcnRpb25zRm9ybXMgPSBmb3Jtc1RvUmVpbmRleDtcbiAgICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMgPSBzdWJzY3JpcHRpb25zVG9SZWluZGV4O1xuXG4gICAgICB0aGlzLnF1ZXJpZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIHRoaXMucXVlcmllc0Zvcm1BcnJheS5yZW1vdmVBdChpbmRleCk7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPj0gdGhpcy5xdWVyaWVzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA9IE1hdGgubWF4KDAsIHRoaXMucXVlcmllcy5sZW5ndGggLSAxKTtcbiAgICAgICAgLy8gRW5zdXJlIGFzc2VydGlvbnMgZm9ybSBpcyBpbml0aWFsaXplZCBmb3IgdGhlIG5ldyBzZWxlY3RlZCBxdWVyeVxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPj0gMCkge1xuICAgICAgICAgIHRoaXMuZW5zdXJlQXNzZXJ0aW9uRGF0YUluaXRpYWxpemVkKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5kZWxldGVRdWVyeS5lbWl0KHF1ZXJ5SWQpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIGdldERiRW52aXJvbm1lbnRDb25maWcoKTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5OiAnZGJFbnZpcm9ubWVudCcsXG4gICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBEQiBlbnZpcm9ubWVudCcsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgICAgc2VydmVyU2VhcmNoOiB0cnVlLFxuICAgICAgb3B0aW9uczogdGhpcy5kYkVudmlyb25tZW50T3B0aW9ucyxcbiAgICAgIG9uU2VhcmNoOiAocXVlcnk6IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLnNlYXJjaERiRW52aXJvbm1lbnQuZW1pdChxdWVyeSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGdldE5vcm1hbEVudmlyb25tZW50Q29uZmlnKCk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogJ25vcm1hbEVudmlyb25tZW50JyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IE5vcm1hbCBlbnZpcm9ubWVudCcsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgICAgc2VydmVyU2VhcmNoOiB0cnVlLFxuICAgICAgb3B0aW9uczogdGhpcy5ub3JtYWxFbnZpcm9ubWVudE9wdGlvbnMsXG4gICAgICBvblNlYXJjaDogKHF1ZXJ5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgdGhpcy5zZWFyY2hOb3JtYWxFbnZpcm9ubWVudC5lbWl0KHF1ZXJ5KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0Q3VycmVudFF1ZXJ5KCk6IERhdGFiYXNlUXVlcnkgfCBudWxsIHtcbiAgICBpZiAodGhpcy5xdWVyaWVzLmxlbmd0aCA+IDAgJiYgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPj0gMCAmJiB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA8IHRoaXMucXVlcmllcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLnF1ZXJpZXNbdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpOiBGb3JtR3JvdXAgfCBudWxsIHtcbiAgICBpZiAodGhpcy5xdWVyaWVzRm9ybUFycmF5ICYmIHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID49IDAgJiYgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPCB0aGlzLnF1ZXJpZXNGb3JtQXJyYXkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5xdWVyaWVzRm9ybUFycmF5LmF0KHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgb25SdW5RdWVyeSgpOiB2b2lkIHtcbiAgICBjb25zdCBkYkVudmlyb25tZW50ID0gdGhpcy5kYXRhYmFzZUZvcm0uZ2V0KCdkYkVudmlyb25tZW50Jyk/LnZhbHVlO1xuICAgIGNvbnN0IG5vcm1hbEVudmlyb25tZW50ID0gdGhpcy5kYXRhYmFzZUZvcm0uZ2V0KCdub3JtYWxFbnZpcm9ubWVudCcpPy52YWx1ZTtcbiAgICBjb25zdCBjdXJyZW50UXVlcnkgPSB0aGlzLmdldEN1cnJlbnRRdWVyeSgpO1xuICAgIGNvbnN0IHF1ZXJ5Rm9ybUdyb3VwID0gdGhpcy5nZXRDdXJyZW50UXVlcnlGb3JtR3JvdXAoKTtcblxuICAgIGlmIChjdXJyZW50UXVlcnkgJiYgcXVlcnlGb3JtR3JvdXAgJiYgZGJFbnZpcm9ubWVudCkge1xuICAgICAgY29uc3QgcXVlcnkgPSBxdWVyeUZvcm1Hcm91cC5nZXQoJ3F1ZXJ5Jyk/LnZhbHVlIHx8ICcnO1xuICAgICAgY29uc3QgdmFyaWFibGUgPSBxdWVyeUZvcm1Hcm91cC5nZXQoJ3ZhcmlhYmxlJyk/LnZhbHVlIHx8ICcnO1xuICAgICAgXG4gICAgICAvLyBVcGRhdGUgdGhlIHF1ZXJ5IG9iamVjdFxuICAgICAgY3VycmVudFF1ZXJ5LnF1ZXJ5ID0gcXVlcnk7XG4gICAgICBjdXJyZW50UXVlcnkudmFyaWFibGUgPSB2YXJpYWJsZTtcblxuICAgICAgdGhpcy5ydW5RdWVyeS5lbWl0KHtcbiAgICAgICAgY3VycmVudFF1ZXJ5LFxuICAgICAgICBxdWVyeSxcbiAgICAgICAgdmFyaWFibGUsXG4gICAgICAgIGRiRW52aXJvbm1lbnQsXG4gICAgICAgIG5vcm1hbEVudmlyb25tZW50OiBub3JtYWxFbnZpcm9ubWVudCB8fCB1bmRlZmluZWRcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VsZWN0UXVlcnkoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIEVuc3VyZSBhc3NlcnRpb24gZGF0YSBpcyBpbml0aWFsaXplZCBmb3IgdGhlIHNlbGVjdGVkIHF1ZXJ5XG4gICAgdGhpcy5lbnN1cmVBc3NlcnRpb25EYXRhSW5pdGlhbGl6ZWQoaW5kZXgpO1xuICAgIHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXhDaGFuZ2UuZW1pdChpbmRleCk7XG4gICAgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIHRvIGVuc3VyZSBhc3NlcnRpb25zIGZvcm0gaXMgZGlzcGxheWVkXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHF1ZXJ5IGluZGV4XG4gICAqL1xuICBnZXRTZWxlY3RlZFF1ZXJ5SW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYlxuICAgKi9cbiAgZ2V0QWN0aXZlVGFiKCk6ICdvdXRwdXQnIHwgJ3ZlcmlmaWNhdGlvbicgfCAnYWR2YW5jZWQnIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFRhYjtcbiAgfVxuXG4gIG9uVGFiQ2hhbmdlKHRhYjogJ291dHB1dCcgfCAndmVyaWZpY2F0aW9uJyB8ICdhZHZhbmNlZCcpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gdGFiO1xuICAgIHRoaXMuYWN0aXZlVGFiQ2hhbmdlLmVtaXQodGFiKTtcbiAgICAvLyBFbnN1cmUgYXNzZXJ0aW9ucyBmb3JtIGlzIGluaXRpYWxpemVkIHdoZW4gc3dpdGNoaW5nIHRvIHZlcmlmaWNhdGlvbiB0YWJcbiAgICBpZiAodGFiID09PSAndmVyaWZpY2F0aW9uJykge1xuICAgICAgdGhpcy5lbnN1cmVBc3NlcnRpb25EYXRhSW5pdGlhbGl6ZWQodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXgpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIG9uQ29weVJlc3VsdHMoKTogdm9pZCB7XG4gICAgY29uc3Qgcm93cyA9IHRoaXMuZ2V0Q3VycmVudFF1ZXJ5UmVzdWx0KCk7XG4gICAgaWYgKHJvd3MgJiYgcm93cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gSlNPTi5zdHJpbmdpZnkocm93cywgbnVsbCwgMik7XG4gICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCh0ZXh0KS50aGVuKCgpID0+IHtcbiAgICAgICAgLy8gQ291bGQgZW1pdCBhbiBldmVudCBvciBzaG93IGEgdG9hc3Qgbm90aWZpY2F0aW9uXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvbkNhbmNlbCgpOiB2b2lkIHtcbiAgICB0aGlzLmNhbmNlbGxlZC5lbWl0KCk7XG4gIH1cblxuICBpc0Zvcm1WYWxpZCgpOiBib29sZWFuIHtcbiAgICAvLyBDaGVjayBpZiBtYWluIGZvcm0gaXMgdmFsaWQgKGRiRW52aXJvbm1lbnQgaXMgcmVxdWlyZWQpXG4gICAgaWYgKCF0aGlzLmRhdGFiYXNlRm9ybS52YWxpZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIHF1ZXJ5XG4gICAgaWYgKHRoaXMucXVlcmllcy5sZW5ndGggPT09IDAgfHwgdGhpcy5xdWVyaWVzRm9ybUFycmF5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGFsbCBxdWVyaWVzIGhhdmUgdmFsaWQgcXVlcnkgYW5kIHZhcmlhYmxlIGZpZWxkc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5xdWVyaWVzRm9ybUFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBxdWVyeUZvcm1Hcm91cCA9IHRoaXMucXVlcmllc0Zvcm1BcnJheS5hdChpKSBhcyBGb3JtR3JvdXA7XG4gICAgICBpZiAoIXF1ZXJ5Rm9ybUdyb3VwLnZhbGlkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG9uQ3JlYXRlU3RlcCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNGb3JtVmFsaWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmRhdGFiYXNlRm9ybS52YWx1ZTtcblxuICAgIC8vIFN5bmMgYWR2YW5jZWQgdmFyaWFibGVzIGZyb20gZm9ybSB0byBhcnJheSBiZWZvcmUgZW1pdHRpbmdcbiAgICB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMuZm9yRWFjaCgodmFyaWFibGUsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5hdChpbmRleCkgYXMgRm9ybUdyb3VwO1xuICAgICAgaWYgKGZvcm1Hcm91cCkge1xuICAgICAgICBjb25zdCBmb3JtVmFsdWVDb250cm9sID0gZm9ybUdyb3VwLmdldCgndmFsdWUnKT8udmFsdWU7XG4gICAgICAgIHZhcmlhYmxlLnZhbHVlID0gZm9ybVZhbHVlQ29udHJvbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHN0ZXBEYXRhOiBEYXRhYmFzZUZvcm1EYXRhID0ge1xuICAgICAgZGJFbnZpcm9ubWVudDogZm9ybVZhbHVlLmRiRW52aXJvbm1lbnQsXG4gICAgICBub3JtYWxFbnZpcm9ubWVudDogZm9ybVZhbHVlLm5vcm1hbEVudmlyb25tZW50IHx8IHVuZGVmaW5lZCxcbiAgICAgIHF1ZXJpZXM6IHRoaXMucXVlcmllcy5tYXAoKHF1ZXJ5LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBxdWVyeUZvcm1Hcm91cCA9IHRoaXMucXVlcmllc0Zvcm1BcnJheS5hdChpbmRleCkgYXMgRm9ybUdyb3VwO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlkOiBxdWVyeS5pZCxcbiAgICAgICAgICBxdWVyeTogcXVlcnlGb3JtR3JvdXAuZ2V0KCdxdWVyeScpPy52YWx1ZSB8fCAnJyxcbiAgICAgICAgICB2YXJpYWJsZTogcXVlcnlGb3JtR3JvdXAuZ2V0KCd2YXJpYWJsZScpPy52YWx1ZSB8fCAnJyxcbiAgICAgICAgICBzdGF0dXM6IHF1ZXJ5LnN0YXR1cyxcbiAgICAgICAgICBhc3NlcnRpb25EYXRhOiBxdWVyeS5hc3NlcnRpb25EYXRhIHx8IFtdIC8vIEluY2x1ZGUgYXNzZXJ0aW9uIGRhdGFcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgICAgYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlczogdGhpcy5hZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzXG4gICAgfTtcbiAgICB0aGlzLmNyZWF0ZVN0ZXAuZW1pdChzdGVwRGF0YSk7XG4gIH1cblxuICBnZXRUYWJsZUNvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLmdldEN1cnJlbnRRdWVyeVJlc3VsdCgpO1xuICAgIGlmICghcm93cyB8fCByb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXMocm93c1swXSk7XG4gIH1cblxuICAvKiogR2V0IHJlc3VsdCByb3dzIGZvciBjdXJyZW50bHkgc2VsZWN0ZWQgcXVlcnkuICovXG4gIGdldEN1cnJlbnRRdWVyeVJlc3VsdCgpOiBhbnlbXSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMucXVlcmllc1t0aGlzLnNlbGVjdGVkUXVlcnlJbmRleF07XG4gICAgaWYgKGN1cnJlbnQgJiYgQXJyYXkuaXNBcnJheShjdXJyZW50LnF1ZXJ5UmVzdWx0KSAmJiBjdXJyZW50LnF1ZXJ5UmVzdWx0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiBjdXJyZW50LnF1ZXJ5UmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFzc2VydGlvbiBkYXRhIGZvciBhIHNwZWNpZmljIHF1ZXJ5XG4gICAqL1xuICBnZXRBc3NlcnRpb25EYXRhRm9yUXVlcnkocXVlcnlJbmRleDogbnVtYmVyKTogYW55W10ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdO1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeS5hc3NlcnRpb25EYXRhKSB7XG4gICAgICByZXR1cm4gcXVlcnkuYXNzZXJ0aW9uRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBhc3NlcnRpb24gZGF0YSBjaGFuZ2UgZnJvbSBleHRlcm5hbCBjb21wb25lbnRcbiAgICovXG4gIG9uQXNzZXJ0aW9uRGF0YUNoYW5nZShhc3NlcnRpb25EYXRhOiBhbnlbXSwgcXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucXVlcmllc1txdWVyeUluZGV4XSkge1xuICAgICAgLy8gQ3JlYXRlIGEgZGVlcCBjb3B5IHRvIGVuc3VyZSBlYWNoIHF1ZXJ5IGhhcyBpdHMgb3duIGRhdGFcbiAgICAgIGlmIChhc3NlcnRpb25EYXRhICYmIGFzc2VydGlvbkRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF0uYXNzZXJ0aW9uRGF0YSA9IGFzc2VydGlvbkRhdGEubWFwKChpdGVtOiBhbnkpID0+IHtcbiAgICAgICAgICAvLyBFbnN1cmUgZXhwZWN0ZWRWYWx1ZSBpcyBwcm9wZXJseSBmb3JtYXR0ZWRcbiAgICAgICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBpdGVtLmV4cGVjdGVkVHlwZSB8fCAnc3RyaW5nJztcbiAgICAgICAgICBsZXQgZXhwZWN0ZWRWYWx1ZSA9IGl0ZW0uZXhwZWN0ZWRWYWx1ZTtcblxuICAgICAgICAgIC8vIEZvciBvYmplY3QvYXJyYXkgdHlwZXMsIGVuc3VyZSBleHBlY3RlZFZhbHVlIGlzIGFuIG9iamVjdC9hcnJheSwgbm90IGEgc3RyaW5nXG4gICAgICAgICAgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGV4cGVjdGVkVmFsdWUgPT09ICdzdHJpbmcnICYmIGV4cGVjdGVkVmFsdWUudHJpbSgpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBleHBlY3RlZFZhbHVlID0gSlNPTi5wYXJzZShleHBlY3RlZFZhbHVlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgLy8gSWYgcGFyc2luZyBmYWlscywga2VlcCBhcyBzdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2FycmF5JyAmJiB0eXBlb2YgZXhwZWN0ZWRWYWx1ZSA9PT0gJ3N0cmluZycgJiYgZXhwZWN0ZWRWYWx1ZS50cmltKCkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSBKU09OLnBhcnNlKGV4cGVjdGVkVmFsdWUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAvLyBJZiBwYXJzaW5nIGZhaWxzLCBrZWVwIGFzIHN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgZXhwZWN0ZWRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSBleHBlY3RlZFZhbHVlICE9PSAnJyA/IE51bWJlcihleHBlY3RlZFZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgaWYgKGV4cGVjdGVkVmFsdWUgPT09ICd0cnVlJyB8fCBleHBlY3RlZFZhbHVlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFZhbHVlID09PSAnZmFsc2UnIHx8IGV4cGVjdGVkVmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAganNvblBhdGg6IGl0ZW0uanNvblBhdGggfHwgJycsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb25UeXBlOiBpdGVtLnZlcmlmaWNhdGlvblR5cGUgfHwgJ2VxdWFscycsXG4gICAgICAgICAgICBleHBlY3RlZFR5cGU6IGV4cGVjdGVkVHlwZSxcbiAgICAgICAgICAgIGV4cGVjdGVkVmFsdWU6IGV4cGVjdGVkVmFsdWVcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucXVlcmllc1txdWVyeUluZGV4XS5hc3NlcnRpb25EYXRhID0gW107XG4gICAgICB9XG5cbiAgICAgIC8vIEVtaXQgdGhlIGNoYW5nZSB0byBwYXJlbnRcbiAgICAgIHRoaXMuYXNzZXJ0aW9uRGF0YUNoYW5nZS5lbWl0KHtcbiAgICAgICAgcXVlcnlJbmRleDogcXVlcnlJbmRleCxcbiAgICAgICAgYXNzZXJ0aW9uRGF0YTogdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdLmFzc2VydGlvbkRhdGEgfHwgW11cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGFzc2VydGlvbiBkYXRhIGZvciBhIHF1ZXJ5IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICovXG4gIHByaXZhdGUgZW5zdXJlQXNzZXJ0aW9uRGF0YUluaXRpYWxpemVkKHF1ZXJ5SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF0gJiYgIXRoaXMucXVlcmllc1txdWVyeUluZGV4XS5hc3NlcnRpb25EYXRhKSB7XG4gICAgICB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF0uYXNzZXJ0aW9uRGF0YSA9IFtdO1xuICAgIH1cbiAgICAvLyBJbml0aWFsaXplIGFzc2VydGlvbnMgZm9ybSBmb3IgdGhpcyBxdWVyeSBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgaWYgKCF0aGlzLmFzc2VydGlvbnNGb3Jtcy5oYXMocXVlcnlJbmRleCkpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUFzc2VydGlvbnNGb3JtKHF1ZXJ5SW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGFzc2VydGlvbnMgZm9ybSBmb3IgYSBzcGVjaWZpYyBxdWVyeVxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQXNzZXJ0aW9uc0Zvcm0ocXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgYXNzZXJ0aW9uc0FycmF5ID0gdGhpcy5mYi5hcnJheShbXSk7XG4gICAgY29uc3QgYXNzZXJ0aW9uc0Zvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGFzc2VydGlvbnM6IGFzc2VydGlvbnNBcnJheVxuICAgIH0pO1xuICAgIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLnNldChxdWVyeUluZGV4LCBhc3NlcnRpb25zRm9ybSk7XG5cbiAgICAvLyBMb2FkIGV4aXN0aW5nIGFzc2VydGlvbnMgaWYgdGhleSBleGlzdFxuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdO1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeS5hc3NlcnRpb25EYXRhICYmIHF1ZXJ5LmFzc2VydGlvbkRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5sb2FkQXNzZXJ0aW9uc0ZvclF1ZXJ5KHF1ZXJ5SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIFN1YnNjcmliZSB0byBmb3JtIGNoYW5nZXNcbiAgICB0aGlzLnN1YnNjcmliZVRvQXNzZXJ0aW9uc0Zvcm1DaGFuZ2VzKHF1ZXJ5SW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhc3NlcnRpb25zIGZvcm0gZm9yIGN1cnJlbnQgcXVlcnlcbiAgICovXG4gIGdldEN1cnJlbnRBc3NlcnRpb25zRm9ybSgpOiBGb3JtR3JvdXAgfCBudWxsIHtcbiAgICBpZiAodGhpcy5hc3NlcnRpb25zRm9ybXMuaGFzKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KSkge1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmdldCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCkhO1xuICAgIH1cbiAgICAvLyBJbml0aWFsaXplIGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCk7XG4gICAgcmV0dXJuIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmdldCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCkgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXNzZXJ0aW9ucyBmb3JtIGFycmF5IGZvciBjdXJyZW50IHF1ZXJ5XG4gICAqL1xuICBnZXRBc3NlcnRpb25zRm9ybUFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZ2V0Q3VycmVudEFzc2VydGlvbnNGb3JtKCk7XG4gICAgaWYgKGZvcm0pIHtcbiAgICAgIHJldHVybiBmb3JtLmdldCgnYXNzZXJ0aW9ucycpIGFzIEZvcm1BcnJheTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmIuYXJyYXkoW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYXNzZXJ0aW9ucyBpbnRvIGZvcm0gZm9yIGEgc3BlY2lmaWMgcXVlcnlcbiAgICovXG4gIHByaXZhdGUgbG9hZEFzc2VydGlvbnNGb3JRdWVyeShxdWVyeUluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5hc3NlcnRpb25zRm9ybXMuZ2V0KHF1ZXJ5SW5kZXgpO1xuICAgIGlmICghZm9ybSkgcmV0dXJuO1xuXG4gICAgY29uc3QgZm9ybUFycmF5ID0gZm9ybS5nZXQoJ2Fzc2VydGlvbnMnKSBhcyBGb3JtQXJyYXk7XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF07XG4gICAgaWYgKCFxdWVyeSB8fCAhcXVlcnkuYXNzZXJ0aW9uRGF0YSkgcmV0dXJuO1xuXG4gICAgLy8gQ2xlYXIgZXhpc3RpbmcgZm9ybSBhcnJheVxuICAgIHdoaWxlIChmb3JtQXJyYXkubGVuZ3RoICE9PSAwKSB7XG4gICAgICBmb3JtQXJyYXkucmVtb3ZlQXQoMCk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBhc3NlcnRpb25zXG4gICAgcXVlcnkuYXNzZXJ0aW9uRGF0YS5mb3JFYWNoKChhc3NlcnRpb246IGFueSkgPT4ge1xuICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gYXNzZXJ0aW9uLmV4cGVjdGVkVHlwZSB8fCAnc3RyaW5nJztcbiAgICAgIGxldCBleHBlY3RlZFZhbHVlOiBhbnkgPSAnJztcblxuICAgICAgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ251bGwnKSB7XG4gICAgICAgIGV4cGVjdGVkVmFsdWUgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdvYmplY3QnIHx8IGV4cGVjdGVkVHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICBpZiAodHlwZW9mIGFzc2VydGlvbi5leHBlY3RlZFZhbHVlID09PSAnb2JqZWN0JyAmJiBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSBKU09OLnN0cmluZ2lmeShhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSwgbnVsbCwgMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGFzc2VydGlvbi5leHBlY3RlZFZhbHVlIHx8ICcnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIGV4cGVjdGVkVmFsdWUgPSAoYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUgPT09IHRydWUgfHwgYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUgPT09ICd0cnVlJykgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGV4cGVjdGVkVmFsdWUgPSBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSAhPT0gbnVsbCAmJiBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBTdHJpbmcoYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUpXG4gICAgICAgICAgOiAnJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4cGVjdGVkVmFsdWUgPSBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSAhPT0gbnVsbCAmJiBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBTdHJpbmcoYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUpXG4gICAgICAgICAgOiAnJztcbiAgICAgIH1cblxuICAgICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgIGpzb25QYXRoOiBbYXNzZXJ0aW9uLmpzb25QYXRoIHx8ICcnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgdmVyaWZpY2F0aW9uVHlwZTogW2Fzc2VydGlvbi52ZXJpZmljYXRpb25UeXBlIHx8ICdlcXVhbHMnXSxcbiAgICAgICAgZXhwZWN0ZWRUeXBlOiBbZXhwZWN0ZWRUeXBlXSxcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZTogW2V4cGVjdGVkVmFsdWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCB0aGlzLmV4cGVjdGVkVmFsdWVWYWxpZGF0b3JdXVxuICAgICAgfSk7XG5cbiAgICAgIGZvcm1BcnJheS5wdXNoKGZvcm1Hcm91cCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIGFzc2VydGlvbnMgZm9ybSBjaGFuZ2VzXG4gICAqL1xuICBwcml2YXRlIHN1YnNjcmliZVRvQXNzZXJ0aW9uc0Zvcm1DaGFuZ2VzKHF1ZXJ5SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmFzc2VydGlvbnNGb3Jtcy5nZXQocXVlcnlJbmRleCk7XG4gICAgaWYgKCFmb3JtKSByZXR1cm47XG5cbiAgICAvLyBVbnN1YnNjcmliZSBmcm9tIHByZXZpb3VzIHN1YnNjcmlwdGlvbiBpZiBleGlzdHNcbiAgICBpZiAodGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5oYXMocXVlcnlJbmRleCkpIHtcbiAgICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuZ2V0KHF1ZXJ5SW5kZXgpIS51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1BcnJheSA9IGZvcm0uZ2V0KCdhc3NlcnRpb25zJykgYXMgRm9ybUFycmF5O1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGZvcm1BcnJheS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuZW1pdEFzc2VydGlvbkRhdGFGb3JRdWVyeShxdWVyeUluZGV4KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuc2V0KHF1ZXJ5SW5kZXgsIHN1YnNjcmlwdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogRW1pdCBhc3NlcnRpb24gZGF0YSBmb3IgYSBzcGVjaWZpYyBxdWVyeVxuICAgKi9cbiAgcHJpdmF0ZSBlbWl0QXNzZXJ0aW9uRGF0YUZvclF1ZXJ5KHF1ZXJ5SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmFzc2VydGlvbnNGb3Jtcy5nZXQocXVlcnlJbmRleCk7XG4gICAgaWYgKCFmb3JtKSByZXR1cm47XG5cbiAgICBjb25zdCBmb3JtQXJyYXkgPSBmb3JtLmdldCgnYXNzZXJ0aW9ucycpIGFzIEZvcm1BcnJheTtcbiAgICBjb25zdCBhc3NlcnRpb25EYXRhID0gZm9ybUFycmF5LmNvbnRyb2xzLm1hcCgoY29udHJvbCkgPT4ge1xuICAgICAgaWYgKCEoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkpIHJldHVybiBudWxsO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB2YWx1ZS5leHBlY3RlZFR5cGUgfHwgJ3N0cmluZyc7XG4gICAgICBsZXQgZXhwZWN0ZWRWYWx1ZTogYW55ID0gdmFsdWUuZXhwZWN0ZWRWYWx1ZTtcblxuICAgICAgLy8gUGFyc2UgZXhwZWN0ZWRWYWx1ZSBiYXNlZCBvbiB0eXBlXG4gICAgICBpZiAoZXhwZWN0ZWRUeXBlID09PSAnbnVsbCcpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGV4cGVjdGVkVmFsdWUgIT09ICcnID8gTnVtYmVyKGV4cGVjdGVkVmFsdWUpIDogbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IChleHBlY3RlZFZhbHVlID09PSAndHJ1ZScgfHwgZXhwZWN0ZWRWYWx1ZSA9PT0gdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2FycmF5JyB8fCBleHBlY3RlZFR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZXhwZWN0ZWRWYWx1ZSA9PT0gJ3N0cmluZycgJiYgZXhwZWN0ZWRWYWx1ZS50cmltKCkpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IEpTT04ucGFyc2UoZXhwZWN0ZWRWYWx1ZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gS2VlcCBhcyBzdHJpbmcgaWYgcGFyc2luZyBmYWlsc1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IFN0cmluZyhleHBlY3RlZFZhbHVlIHx8ICcnKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAganNvblBhdGg6ICh2YWx1ZS5qc29uUGF0aCB8fCAnJykudHJpbSgpLFxuICAgICAgICB2ZXJpZmljYXRpb25UeXBlOiB2YWx1ZS52ZXJpZmljYXRpb25UeXBlIHx8ICdlcXVhbHMnLFxuICAgICAgICBleHBlY3RlZFR5cGU6IGV4cGVjdGVkVHlwZSxcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZTogZXhwZWN0ZWRWYWx1ZVxuICAgICAgfTtcbiAgICB9KS5maWx0ZXIoaXRlbSA9PiBpdGVtICE9PSBudWxsICYmIGl0ZW0hLmpzb25QYXRoKSBhcyBhbnlbXTtcblxuICAgIC8vIFVwZGF0ZSBxdWVyeSdzIGFzc2VydGlvbiBkYXRhXG4gICAgaWYgKHRoaXMucXVlcmllc1txdWVyeUluZGV4XSkge1xuICAgICAgdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdLmFzc2VydGlvbkRhdGEgPSBhc3NlcnRpb25EYXRhO1xuICAgIH1cblxuICAgIC8vIEVtaXQgdG8gcGFyZW50XG4gICAgdGhpcy5hc3NlcnRpb25EYXRhQ2hhbmdlLmVtaXQoe1xuICAgICAgcXVlcnlJbmRleDogcXVlcnlJbmRleCxcbiAgICAgIGFzc2VydGlvbkRhdGE6IGFzc2VydGlvbkRhdGFcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgYXNzZXJ0aW9uXG4gICAqL1xuICBhZGRBc3NlcnRpb24oKTogdm9pZCB7XG4gICAgY29uc3QgZm9ybUFycmF5ID0gdGhpcy5nZXRBc3NlcnRpb25zRm9ybUFycmF5KCk7XG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBqc29uUGF0aDogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIHZlcmlmaWNhdGlvblR5cGU6IFsnZXF1YWxzJ10sXG4gICAgICBleHBlY3RlZFR5cGU6IFt0aGlzLmRlZmF1bHRFeHBlY3RlZFR5cGVdLFxuICAgICAgZXhwZWN0ZWRWYWx1ZTogWycnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgdGhpcy5leHBlY3RlZFZhbHVlVmFsaWRhdG9yXV1cbiAgICB9KTtcbiAgICBmb3JtQXJyYXkucHVzaChmb3JtR3JvdXApO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICBpZiAodGhpcy5hc3NlcnRpb25zVGFibGUpIHtcbiAgICAgIHRoaXMuYXNzZXJ0aW9uc1RhYmxlLnJlbmRlclJvd3MoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFuIGFzc2VydGlvblxuICAgKi9cbiAgcmVtb3ZlQXNzZXJ0aW9uKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEFzc2VydGlvbnNGb3JtQXJyYXkoKTtcbiAgICBmb3JtQXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICBpZiAodGhpcy5hc3NlcnRpb25zVGFibGUpIHtcbiAgICAgIHRoaXMuYXNzZXJ0aW9uc1RhYmxlLnJlbmRlclJvd3MoKTtcbiAgICB9XG4gICAgdGhpcy5lbWl0QXNzZXJ0aW9uRGF0YUZvclF1ZXJ5KHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZm9ybSBjb250cm9sIGF0IHNwZWNpZmljIGluZGV4XG4gICAqL1xuICBnZXRGb3JtQ29udHJvbEF0KGluZGV4OiBudW1iZXIsIGNvbnRyb2xOYW1lOiBzdHJpbmcpOiBBYnN0cmFjdENvbnRyb2wgfCBudWxsIHtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEFzc2VydGlvbnNGb3JtQXJyYXkoKTtcbiAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZvcm1BcnJheS5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGZvcm1Hcm91cCA9IGZvcm1BcnJheS5hdChpbmRleCkgYXMgRm9ybUdyb3VwO1xuICAgIHJldHVybiBmb3JtR3JvdXA/LmdldChjb250cm9sTmFtZSkgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwZWN0ZWQgdHlwZSBmb3IgYW4gYXNzZXJ0aW9uXG4gICAqL1xuICBnZXRFeHBlY3RlZFR5cGUoaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZm9ybUFycmF5ID0gdGhpcy5nZXRBc3NlcnRpb25zRm9ybUFycmF5KCk7XG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmb3JtQXJyYXkubGVuZ3RoKSByZXR1cm4gJ3N0cmluZyc7XG4gICAgY29uc3QgZm9ybUdyb3VwID0gZm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgcmV0dXJuIGZvcm1Hcm91cD8uZ2V0KCdleHBlY3RlZFR5cGUnKT8udmFsdWUgfHwgJ3N0cmluZyc7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGV4cGVjdGVkIHZhbHVlIHBsYWNlaG9sZGVyXG4gICAqL1xuICBnZXRFeHBlY3RlZFZhbHVlUGxhY2Vob2xkZXIoaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gdGhpcy5nZXRFeHBlY3RlZFR5cGUoaW5kZXgpO1xuICAgIHN3aXRjaCAoZXhwZWN0ZWRUeXBlKSB7XG4gICAgICBjYXNlICdzdHJpbmcnOiByZXR1cm4gJ0VudGVyIHZhbHVlJztcbiAgICAgIGNhc2UgJ2FycmF5JzogcmV0dXJuICdFbnRlciBKU09OIGFycmF5JztcbiAgICAgIGNhc2UgJ29iamVjdCc6IHJldHVybiAnRW50ZXIgSlNPTiBvYmplY3QnO1xuICAgICAgY2FzZSAnbnVsbCc6IHJldHVybiAnTm8gdmFsdWUgcmVxdWlyZWQnO1xuICAgICAgZGVmYXVsdDogcmV0dXJuICdFbnRlciB2YWx1ZSc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBleHBlY3RlZCB0eXBlIGNoYW5nZVxuICAgKi9cbiAgb25FeHBlY3RlZFR5cGVDaGFuZ2UoaW5kZXg6IG51bWJlciwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGZvcm1BcnJheSA9IHRoaXMuZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpO1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZm9ybUFycmF5Lmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgZm9ybUdyb3VwID0gZm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgY29uc3QgZXhwZWN0ZWRWYWx1ZUNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KCdleHBlY3RlZFZhbHVlJyk7XG4gICAgaWYgKCFleHBlY3RlZFZhbHVlQ29udHJvbCkgcmV0dXJuO1xuXG4gICAgbGV0IG5ld1ZhbHVlOiBhbnkgPSAnJztcbiAgICBpZiAodmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgbmV3VmFsdWUgPSAndHJ1ZSc7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ251bGwnKSB7XG4gICAgICBuZXdWYWx1ZSA9IG51bGw7XG4gICAgfVxuXG4gICAgZXhwZWN0ZWRWYWx1ZUNvbnRyb2wuY2xlYXJWYWxpZGF0b3JzKCk7XG4gICAgZXhwZWN0ZWRWYWx1ZUNvbnRyb2wuc2V0VmFsdWUobmV3VmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgIGlmICh2YWx1ZSA9PT0gJ251bGwnKSB7XG4gICAgICBleHBlY3RlZFZhbHVlQ29udHJvbC5zZXRWYWxpZGF0b3JzKFt0aGlzLmV4cGVjdGVkVmFsdWVWYWxpZGF0b3JdKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gJ2FycmF5Jykge1xuICAgICAgZXhwZWN0ZWRWYWx1ZUNvbnRyb2wuc2V0VmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5yZXF1aXJlZF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBlY3RlZFZhbHVlQ29udHJvbC5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCB0aGlzLmV4cGVjdGVkVmFsdWVWYWxpZGF0b3JdKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGV4cGVjdGVkVmFsdWVDb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH0sIDEwMCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwZWN0ZWQgdmFsdWUgdmFsaWRhdG9yXG4gICAqL1xuICBleHBlY3RlZFZhbHVlVmFsaWRhdG9yID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfCBudWxsID0+IHtcbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBjb250cm9sLnBhcmVudD8uZ2V0KCdleHBlY3RlZFR5cGUnKT8udmFsdWU7XG4gICAgaWYgKCFleHBlY3RlZFR5cGUgfHwgZXhwZWN0ZWRUeXBlID09PSAnbnVsbCcpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGlmICghdmFsdWUgJiYgdmFsdWUgIT09IDAgJiYgdmFsdWUgIT09IGZhbHNlKSByZXR1cm4gbnVsbDtcblxuICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBpZiAoaXNOYU4oTnVtYmVyKHZhbHVlKSkpIHtcbiAgICAgICAgcmV0dXJuIHsgaW52YWxpZFR5cGU6IHRydWUsIG1lc3NhZ2U6ICdJbnZhbGlkIG51bWJlciB2YWx1ZScgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBpZiAodmFsdWUgIT09ICd0cnVlJyAmJiB2YWx1ZSAhPT0gJ2ZhbHNlJyAmJiB2YWx1ZSAhPT0gdHJ1ZSAmJiB2YWx1ZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHsgaW52YWxpZFR5cGU6IHRydWUsIG1lc3NhZ2U6ICdJbnZhbGlkIGJvb2xlYW4gdmFsdWUnIH07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLnRyaW0oKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShwYXJzZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBpbnZhbGlkVHlwZTogdHJ1ZSwgbWVzc2FnZTogJ1ZhbHVlIG11c3QgYmUgYSB2YWxpZCBKU09OIGFycmF5JyB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJldHVybiB7IGludmFsaWRUeXBlOiB0cnVlLCBtZXNzYWdlOiAnSW52YWxpZCBBcnJheSB2YWx1ZSAtIG11c3QgYmUgdmFsaWQgSlNPTicgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUudHJpbSgpICYmIHZhbHVlLnRyaW0oKSAhPT0gJ3t9Jykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgICAgIGlmIChwYXJzZWQgPT09IG51bGwgfHwgdHlwZW9mIHBhcnNlZCAhPT0gJ29iamVjdCcgfHwgQXJyYXkuaXNBcnJheShwYXJzZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBpbnZhbGlkVHlwZTogdHJ1ZSwgbWVzc2FnZTogJ1ZhbHVlIG11c3QgYmUgYSB2YWxpZCBKU09OIG9iamVjdCcgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZXR1cm4geyBpbnZhbGlkVHlwZTogdHJ1ZSwgbWVzc2FnZTogJ0ludmFsaWQgT2JqZWN0IHZhbHVlIC0gbXVzdCBiZSB2YWxpZCBKU09OJyB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCBhc3NlcnRpb25zIGRhdGEgc291cmNlIGZvciB0YWJsZVxuICAgKi9cbiAgZ2V0IGFzc2VydGlvbnNEYXRhU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLmdldEFzc2VydGlvbnNGb3JtQXJyYXkoKS5jb250cm9scztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBieSBmdW5jdGlvbiBmb3IgdGFibGUgcm93c1xuICAgKi9cbiAgdHJhY2tCeUluZGV4KGluZGV4OiBudW1iZXIpOiBhbnkge1xuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIC8vIENsZWFuIHVwIHN1YnNjcmlwdGlvbnNcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmZvckVhY2goc3ViID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhZHZhbmNlZCBzZXR0aW5ncyB2YXJpYWJsZXMgZm9yIGRhdGFiYXNlIHN0ZXBzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQWR2YW5jZWRTZXR0aW5ncygpOiB2b2lkIHtcbiAgICB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMgPSBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdpc1N0ZXBPcHRpb25hbCcsXG4gICAgICAgIGxhYmVsOiBcIkRvbid0IGZhaWwgdGhlIHRlc3QgaWYgdGhpcyBzdGVwIGZhaWxzLlwiLFxuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdib29sZWFuJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZFNraXAnLFxuICAgICAgICBsYWJlbDogJ1NraXAgdGhpcyBzdGVwIGR1cmluZyBleGVjdXRpb24uJyxcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbidcbiAgICAgIH1cbiAgICBdO1xuXG4gICAgdGhpcy5idWlsZEFkdmFuY2VkVmFyaWFibGVzRm9ybSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHJlYWN0aXZlIGZvcm0gZm9yIGFkdmFuY2VkIHNldHRpbmdzIHZhcmlhYmxlcy5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRBZHZhbmNlZFZhcmlhYmxlc0Zvcm0oKTogdm9pZCB7XG4gICAgd2hpbGUgKHRoaXMuYWR2YW5jZWRWYXJpYWJsZXNGb3JtLmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhpcy5hZHZhbmNlZFZhcmlhYmxlc0Zvcm0ucmVtb3ZlQXQoMCk7XG4gICAgfVxuXG4gICAgdGhpcy5hZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzLmZvckVhY2godmFyaWFibGUgPT4ge1xuICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID1cbiAgICAgICAgdmFyaWFibGUudHlwZSA9PT0gJ2Jvb2xlYW4nIHx8IHR5cGVvZiB2YXJpYWJsZS52YWx1ZSA9PT0gJ2Jvb2xlYW4nXG4gICAgICAgICAgPyAodmFyaWFibGUudmFsdWUgPT09IHRydWUgfHwgdmFyaWFibGUudmFsdWUgPT09ICd0cnVlJyB8fCB2YXJpYWJsZS52YWx1ZSA9PT0gMSlcbiAgICAgICAgICA6ICh2YXJpYWJsZS52YWx1ZSB8fCAnJyk7XG5cbiAgICAgIGNvbnN0IHZhcmlhYmxlR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgbmFtZTogW3ZhcmlhYmxlLm5hbWVdLFxuICAgICAgICB2YWx1ZTogW2RlZmF1bHRWYWx1ZV0sXG4gICAgICAgIHR5cGU6IFt2YXJpYWJsZS50eXBlIHx8ICdzdHJpbmcnXSxcbiAgICAgICAgbGFiZWw6IFt2YXJpYWJsZS5sYWJlbCB8fCAnJ11cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5wdXNoKHZhcmlhYmxlR3JvdXApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBhZHZhbmNlZCBib29sZWFuIGNoYW5nZXMgYW5kIGtlZXAgZGF0YS9mb3JtIGluIHN5bmMuXG4gICAqL1xuICBvbkFkdmFuY2VkVmFyaWFibGVCb29sZWFuQ2hhbmdlKHZhcmlhYmxlTmFtZTogc3RyaW5nLCB2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHZhcmlhYmxlID0gdGhpcy5hZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzLmZpbmQodiA9PiB2Lm5hbWUgPT09IHZhcmlhYmxlTmFtZSk7XG4gICAgaWYgKHZhcmlhYmxlKSB7XG4gICAgICB2YXJpYWJsZS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhcmlhYmxlSW5kZXggPSB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5jb250cm9scy5maW5kSW5kZXgoXG4gICAgICBjb250cm9sID0+IGNvbnRyb2wuZ2V0KCduYW1lJyk/LnZhbHVlID09PSB2YXJpYWJsZU5hbWVcbiAgICApO1xuICAgIGlmICh2YXJpYWJsZUluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5hZHZhbmNlZFZhcmlhYmxlc0Zvcm0uYXQodmFyaWFibGVJbmRleCkuZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgbm9uLWJvb2xlYW4gYWR2YW5jZWQgdmFyaWFibGUgY2hhbmdlcyAocmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UpLlxuICAgKi9cbiAgb25BZHZhbmNlZFZhcmlhYmxlVmFsdWVDaGFuZ2UodmFyaWFibGVOYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcy5maW5kKHYgPT4gdi5uYW1lID09PSB2YXJpYWJsZU5hbWUpO1xuICAgIGlmICh2YXJpYWJsZSkge1xuICAgICAgdmFyaWFibGUudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB2YXJpYWJsZUluZGV4ID0gdGhpcy5hZHZhbmNlZFZhcmlhYmxlc0Zvcm0uY29udHJvbHMuZmluZEluZGV4KFxuICAgICAgY29udHJvbCA9PiBjb250cm9sLmdldCgnbmFtZScpPy52YWx1ZSA9PT0gdmFyaWFibGVOYW1lXG4gICAgKTtcbiAgICBpZiAodmFyaWFibGVJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYWR2YW5jZWRWYXJpYWJsZXNGb3JtLmF0KHZhcmlhYmxlSW5kZXgpLmdldCgndmFsdWUnKT8uc2V0VmFsdWUodmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWgtZnVsbCBjcWEtYmctd2hpdGUgY3FhLXB4LTQgY3FhLXB5LTJcIj5cbiAgPCEtLSBIZWFkZXIgLS0+XG4gIDxoMiBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ibGFjay0xMDAgY3FhLW1iLTRcIj5cbiAgICB7eyBlZGl0TW9kZSA/ICdVcGRhdGUgRGF0YWJhc2UgVGVzdCBTdGVwJyA6ICdDcmVhdGUgRGF0YWJhc2UgVGVzdCBTdGVwJyB9fVxuICA8L2gyPlxuXG4gIDwhLS0gRW52aXJvbm1lbnQgU2VjdGlvbiAoc2VwYXJhdG9yIGxpbmUgb25seSBvbiBib3R0b20pIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLXctZnVsbCBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtMS41IGNxYS1wYi1bMC41cmVtXSBjcWEtbWItNCBjcWEtYm9yZGVyLTAgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZ2FwLTQgY3FhLWl0ZW1zLXN0YXJ0XCI+XG4gICAgICA8IS0tIERCIEVudmlyb25tZW50IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMS41XCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtYmxvY2tcIj5cbiAgICAgICAgICBEQiBFbnZpcm9ubWVudCA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXJlZC01MDBcIj4qPC9zcGFuPlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLW1pbi13LTBcIj5cbiAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImRhdGFiYXNlRm9ybVwiIFtjb25maWddPVwiZ2V0RGJFbnZpcm9ubWVudENvbmZpZygpXCI+XG4gICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgVXNlcyBEYXRhYmFzZSBlbnZpcm9ubWVudHMgZnJvbSBFbnZpcm9ubWVudHMuXG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIE5vcm1hbCBFbnZpcm9ubWVudCAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtZ3JheS03MDAgY3FhLWJsb2NrXCI+XG4gICAgICAgICAgTm9ybWFsIEVudmlyb25tZW50XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtbWluLXctMFwiPlxuICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZGF0YWJhc2VGb3JtXCIgW2NvbmZpZ109XCJnZXROb3JtYWxFbnZpcm9ubWVudENvbmZpZygpXCI+XG4gICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgVXNlcyBOb3JtYWwgZW52aXJvbm1lbnRzIGZyb20gRW52aXJvbm1lbnRzLlxuICAgICAgICA8L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWp1c3RpZnktZW5kIGNxYS1tdC0yXCI+XG4gICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgdGV4dD1cIlJ1biBRdWVyeVwiIChjbGlja2VkKT1cIm9uUnVuUXVlcnkoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIhZGF0YWJhc2VGb3JtLmdldCgnZGJFbnZpcm9ubWVudCcpPy52YWx1ZSB8fCBpc0xvYWRpbmdcIlxuICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJyFjcWEtYmctWyMzRjQzRUVdIGNxYS10ZXh0LVsjRkJGQ0ZGXSBjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1wdC1bMTBweF0gIWNxYS1wYi1bMTBweF0gIWNxYS1wbC1bMjRweF0gIWNxYS1wci1bMjRweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgY3FhLW1pbi1oLVszN3B4XSBob3ZlcjohY3FhLWJnLVsjMUIxRkVCXSBjcWEtZmxleC1zaHJpbmstMCdcIj5cbiAgICAgIDwvY3FhLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNYWluIENvbnRlbnQ6IFR3byBDb2x1bW4gTGF5b3V0IC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWdhcC1bMTJweF0gY3FhLWZsZXgtMSBjcWEtb3ZlcmZsb3ctaGlkZGVuIGNxYS1tYi02XCI+XG4gICAgPCEtLSBMZWZ0IFBhbmVsOiBRdWVyeSBMaXN0IC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY3FhLXctWzE3NXB4XSBjcWEtbWluLXctWzE3NXB4XSBjcWEtZmxleC1zaHJpbmstMCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWJvcmRlci0wIGNxYS1ib3JkZXItciBjcWEtYm9yZGVyLXItWzFweF0gY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjRTBFMEUwXSBjcWEtYmctWyNGQUZBRkFdIGNxYS1vdmVyZmxvdy1oaWRkZW5cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLXAtMlwiPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBxdWVyeSBvZiBxdWVyaWVzOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktYmV0d2VlbiBjcWEtZ2FwLVsxMHB4XSBjcWEtdy1mdWxsIGNxYS1wdC1bMTRweF0gY3FhLXBiLVsxNHB4XSBjcWEtcGwtWzE2cHhdIGNxYS1wci1bMTZweF0gY3FhLXJvdW5kZWQtWzhweF0gY3FhLWN1cnNvci1wb2ludGVyIGNxYS1tYi0xXCJcbiAgICAgICAgICBbY2xhc3MuY3FhLWJnLWJsdWUtNTBdPVwic2VsZWN0ZWRRdWVyeUluZGV4ID09PSBpXCJcbiAgICAgICAgICBbY2xhc3MuY3FhLWJvcmRlcl09XCJzZWxlY3RlZFF1ZXJ5SW5kZXggPT09IGlcIlxuICAgICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNTAwXT1cInNlbGVjdGVkUXVlcnlJbmRleCA9PT0gaVwiXG4gICAgICAgICAgW2NsYXNzLmNxYS1iZy1ncmV5LTQwMF09XCJzZWxlY3RlZFF1ZXJ5SW5kZXggIT09IGlcIlxuICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdFF1ZXJ5KGkpXCJcbiAgICAgICAgICBzdHlsZT1cImhlaWdodDogNDlweDsgbWluLWhlaWdodDogNDlweDtcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTkwMFwiPlF1ZXJ5IHt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgIDxjcWEtYmFkZ2UgKm5nSWY9XCJxdWVyeS5zdGF0dXNcIlxuICAgICAgICAgICAgW2xhYmVsXT1cInF1ZXJ5LnN0YXR1cyA9PT0gJ3Bhc3NlZCcgPyAnUGFzc2VkJyA6IHF1ZXJ5LnN0YXR1cyA9PT0gJ2ZhaWxlZCcgPyAnRmFpbGVkJyA6ICdQZW5kaW5nJ1wiXG4gICAgICAgICAgICBbdmFyaWFudF09XCJxdWVyeS5zdGF0dXMgPT09ICdwYXNzZWQnID8gJ3N1Y2Nlc3MnIDogcXVlcnkuc3RhdHVzID09PSAnZmFpbGVkJyA/ICdlcnJvcicgOiAnZGVmYXVsdCdcIlxuICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCI+XG4gICAgICAgICAgPC9jcWEtYmFkZ2U+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFJpZ2h0IFBhbmVsOiBRdWVyeSBFZGl0b3IgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1vdmVyZmxvdy1hdXRvXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXgtMSBjcWEtZmxleCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItZ3JheS0yMDAgY3FhLXJvdW5kZWQtbGcgY3FhLWdhcC1bMTBweF0gY3FhLW1iLTRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLVs2cHhdXCIgc3R5bGU9XCJ3aWR0aDogNTAlO1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwIGNxYS10ZXh0LVsxNHB4XVwiPlF1ZXJ5ICYgU3RvcmUgUmVzcG9uc2U8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsjRUY0NDQ0XSBjcWEtbWwtMC41XCI+Kjwvc3Bhbj48L2gzPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1qdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgIDwhLS0gU1FMIFF1ZXJ5IFRleHRhcmVhIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1taW4tdy0wIGNxYS13LWZ1bGwgY3FhLXJvdW5kZWQtbWQgY3FhLWJnLWdyYXktNTAvNTBcIj5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20tdGV4dGFyZWEgW3BsYWNlaG9sZGVyXT1cIidFbnRlciB5b3VyIFNRTCBxdWVyeSBoZXJlLi4uJ1wiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpPy5nZXQoJ3F1ZXJ5Jyk/LnZhbHVlIHx8ICcnXCIgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgW3Jvd3NdPVwiOFwiXG4gICAgICAgICAgICAgICAgW3RleHRhcmVhSW5saW5lU3R5bGVdPVwiJ3BhZGRpbmc6IDFyZW07J1wiXG4gICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cImdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpPy5nZXQoJ3F1ZXJ5Jyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgPC9jcWEtY3VzdG9tLXRleHRhcmVhPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtWzEwcHhdIGNxYS1tYi1bOHB4XVwiPlxuXG5cbiAgICAgICAgICA8IS0tIFZhcmlhYmxlIElucHV0IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZ2FwLTRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtbWItMS41IGNxYS1ibG9jayBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtc2VtaWJvbGRcIj5cbiAgICAgICAgICAgICAgICBWYXJpYWJsZTxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWyNFRjQ0NDRdIGNxYS1tbC0wLjVcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiJ1ZhcmlhYmxlIG5hbWUnXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0Q3VycmVudFF1ZXJ5Rm9ybUdyb3VwKCk/LmdldCgndmFyaWFibGUnKT8udmFsdWUgfHwgJydcIiBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJnZXRDdXJyZW50UXVlcnlGb3JtR3JvdXAoKT8uZ2V0KCd2YXJpYWJsZScpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtdGV4dC1ncmF5LTUwMCBjcWEtbXQtMVwiPlxuICAgICAgICAgICAgICAgIFVzZSBsZXR0ZXJzLCBudW1iZXJzLCB1bmRlcnNjb3JlLiBObyBzcGFjZXMuIFVuaXF1ZSBwZXIgc3RlcC4gQ2FzZSBzZW5zaXRpdmUuXG4gICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gQWN0aW9uIEJ1dHRvbnMgKHBpbm5lZCB0byBib3R0b20pIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtbXQtYXV0b1wiPlxuICAgICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgdGV4dD1cIkFkZCBRdWVyeVwiIGljb249XCJhZGRcIiAoY2xpY2tlZCk9XCJhZGROZXdRdWVyeSgpXCJcbiAgICAgICAgICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtYmctd2hpdGUgIWNxYS1ib3JkZXItWyM0MTQxNDZdIGNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjNDE0MTQ2XSBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1weS1bMTBweF0gIWNxYS1weC1bMTBweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgaG92ZXI6IWNxYS1ib3JkZXItWyM0MTQxNDZdIGhvdmVyOmNxYS1iZy1ncmF5LTUwJ1wiXG4gICAgICAgICAgICAgIFtpY29uQ29sb3JdPVwiJyM0MTQxNDYnXCI+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8Y3FhLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgdmFyaWFudD1cInRleHRcIlxuICAgICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS1taW4tdy1bNDBweF0gY3FhLXctMTAgY3FhLWgtOSBjcWEtcm91bmRlZCBjcWEtYmctZ3JheS0xMDAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgaG92ZXI6Y3FhLWJnLWdyYXktMjAwIGNxYS1wLTAnXCJcbiAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiJ0RlbGV0ZSBxdWVyeSdcIiAoY2xpY2tlZCk9XCJkZWxldGVRdWVyeUJ5SWQoZ2V0Q3VycmVudFF1ZXJ5KCk/LmlkIHx8ICcnKVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJxdWVyaWVzLmxlbmd0aCA8PSAxXCIgW2F0dHIuYXJpYS1sYWJlbF09XCInRGVsZXRlIHF1ZXJ5J1wiPlxuICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiY3FhLWZsZXgtc2hyaW5rLTBcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCJcbiAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk0xMC42NjYzIDZWMTIuNjY2N0g1LjMzMzAxVjZIMTAuNjY2M1pNOS42NjYzNCAySDYuMzMzMDFMNS42NjYzNCAyLjY2NjY3SDMuMzMzMDFWNEgxMi42NjYzVjIuNjY2NjdIMTAuMzMzTDkuNjY2MzQgMlpNMTEuOTk5NyA0LjY2NjY3SDMuOTk5NjdWMTIuNjY2N0MzLjk5OTY3IDEzLjQgNC41OTk2NyAxNCA1LjMzMzAxIDE0SDEwLjY2NjNDMTEuMzk5NyAxNCAxMS45OTk3IDEzLjQgMTEuOTk5NyAxMi42NjY3VjQuNjY2NjdaXCJcbiAgICAgICAgICAgICAgICAgIGZpbGw9XCIjNkI3MjgwXCIgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgdGV4dD1cIlJ1blwiIGljb249XCJwbGF5X2Fycm93XCIgKGNsaWNrZWQpPVwib25SdW5RdWVyeSgpXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFnZXRDdXJyZW50UXVlcnlGb3JtR3JvdXAoKT8uZ2V0KCdxdWVyeScpPy52YWx1ZSB8fCAhZGF0YWJhc2VGb3JtLmdldCgnZGJFbnZpcm9ubWVudCcpPy52YWx1ZSB8fCBpc0xvYWRpbmdcIlxuICAgICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJyFjcWEtYmctWyMzRjQzRUVdIGNxYS10ZXh0LVsjRkJGQ0ZGXSBjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1wdC1bMTBweF0gIWNxYS1wYi1bMTBweF0gIWNxYS1wbC1bMTZweF0gIWNxYS1wci1bMjRweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgY3FhLW1pbi1oLVszOHB4XSBob3ZlcjohY3FhLWJnLVsjMUIxRkVCXSAhY3FhLWJvcmRlci1ub25lJ1wiXG4gICAgICAgICAgICAgIFtpY29uQ29sb3JdPVwiJyNGQkZDRkYnXCI+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8IS0tIFJlc3VsdHMgU2VjdGlvbiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWJvcmRlciBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1yb3VuZGVkLWxnIGNxYS1tYi02XCI+XG4gICAgICAgIDwhLS0gVGFicyAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDAgY3FhLWJnLWdyYXktNTBcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ291dHB1dCdcIiBbY2xhc3MuY3FhLWJvcmRlci1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ291dHB1dCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnb3V0cHV0J1wiXG4gICAgICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci10cmFuc3BhcmVudF09XCJzZWxlY3RlZFRhYiAhPT0gJ291dHB1dCdcIiAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ291dHB1dCcpXCI+XG4gICAgICAgICAgICBPdXRwdXRcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ3ZlcmlmaWNhdGlvbidcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICd2ZXJpZmljYXRpb24nXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ncmF5LTYwMF09XCJzZWxlY3RlZFRhYiAhPT0gJ3ZlcmlmaWNhdGlvbidcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItdHJhbnNwYXJlbnRdPVwic2VsZWN0ZWRUYWIgIT09ICd2ZXJpZmljYXRpb24nXCIgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCd2ZXJpZmljYXRpb24nKVwiPlxuICAgICAgICAgICAgVmVyaWZpY2F0aW9uXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10cmFuc2l0aW9uLWNvbG9ycyBjcWEtYm9yZGVyLWItMlwiXG4gICAgICAgICAgICBbY2xhc3MuY3FhLXRleHQtYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdhZHZhbmNlZCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdhZHZhbmNlZCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnYWR2YW5jZWQnXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLXRyYW5zcGFyZW50XT1cInNlbGVjdGVkVGFiICE9PSAnYWR2YW5jZWQnXCIgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCdhZHZhbmNlZCcpXCI+XG4gICAgICAgICAgICBBZHZhbmNlZFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFRhYiBDb250ZW50IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXAtNFwiPlxuICAgICAgICAgIDwhLS0gT3V0cHV0IFRhYiAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdvdXRwdXQnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1tYi0zXCI+XG4gICAgICAgICAgICAgIDxoNCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwXCI+UXVlcnkgUmVzdWx0czwvaDQ+XG4gICAgICAgICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJ0ZXh0XCIgdGV4dD1cIkNvcHlcIiBpY29uPVwiY29udGVudF9jb3B5XCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtdGV4dC1ibHVlLTYwMCdcIlxuICAgICAgICAgICAgICAgIChjbGlja2VkKT1cIm9uQ29weVJlc3VsdHMoKVwiPlxuICAgICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBSZXN1bHRzIFRhYmxlIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImdldEN1cnJlbnRRdWVyeVJlc3VsdCgpLmxlbmd0aCA+IDBcIiBjbGFzcz1cImNxYS1vdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwiY3FhLXctZnVsbCBjcWEtYm9yZGVyLWNvbGxhcHNlXCI+XG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwiY3FhLWJnLWdyYXktNTAgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBrZXkgb2YgZ2V0VGFibGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtbGVmdCBjcWEtdGV4dC14cyBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtdXBwZXJjYXNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sga2V5IH19XG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgZ2V0Q3VycmVudFF1ZXJ5UmVzdWx0KClcIiBjbGFzcz1cImNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwIGhvdmVyOmNxYS1iZy1ncmF5LTUwXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQga2V5IG9mIGdldFRhYmxlQ29sdW1ucygpXCIgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtdGV4dC1ncmF5LTkwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IHJvd1trZXldIH19XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImdldEN1cnJlbnRRdWVyeVJlc3VsdCgpLmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXRleHQtY2VudGVyIGNxYS1weS04IGNxYS10ZXh0LWdyYXktNDAwIGNxYS10ZXh0LXNtXCI+XG4gICAgICAgICAgICAgIE5vIHJlc3VsdHMgeWV0LiBSdW4gYSBxdWVyeSB0byBzZWUgcmVzdWx0cy5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWZXJpZmljYXRpb24gVGFiIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3ZlcmlmaWNhdGlvbidcIiBjbGFzcz1cImFzc2VydGlvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8IS0tIEhlYWRlciBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFzc2VydGlvbnMtaGVhZGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGVudFwiPlxuICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImhlYWRlci10aXRsZVwiPkFzc2VydGlvbnM8L2gzPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiaGVhZGVyLXN1YnRpdGxlXCI+VXNlIEpTT05QYXRoIHRvIHRhcmdldCB2YWx1ZXMgaW4gdGhlIHF1ZXJ5IG91dHB1dC48L3A+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8YnV0dG9uIFxuICAgICAgICAgICAgICAgIG1hdC1zdHJva2VkLWJ1dHRvbiBcbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIiBcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFkZC1hc3NlcnRpb24tYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkQXNzZXJ0aW9uKClcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBBZGQgQXNzZXJ0aW9uXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gVGFibGUgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxmb3JtICpuZ0lmPVwiZ2V0Q3VycmVudEFzc2VydGlvbnNGb3JtKClcIiBbZm9ybUdyb3VwXT1cImdldEN1cnJlbnRBc3NlcnRpb25zRm9ybSgpIVwiIGNsYXNzPVwiYXNzZXJ0aW9ucy1mb3JtXCI+XG4gICAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cImFzc2VydGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtc2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJhc3NlcnRpb25zRGF0YVNvdXJjZVwiIGNsYXNzPVwiYXNzZXJ0aW9ucy10YWJsZVwiICNhc3NlcnRpb25zVGFibGU+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gSlNPTlBhdGggQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImpzb25QYXRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5qc29uUGF0aDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGFzc2VydGlvbjsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbZm9ybUdyb3VwTmFtZV09XCJpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwiZnVsbC13aWR0aC1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwianNvblBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ1c2VybmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnanNvblBhdGgnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rm9ybUNvbnRyb2xBdChpLCAnanNvblBhdGgnKT8udG91Y2hlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTlBhdGggaXMgcmVxdWlyZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gVmVyaWZpY2F0aW9uIFR5cGUgQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInZlcmlmaWNhdGlvblR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPnZlcmlmaWNhdGlvblR5cGU8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBhc3NlcnRpb247IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cImZ1bGwtd2lkdGgtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBmb3JtQ29udHJvbE5hbWU9XCJ2ZXJpZmljYXRpb25UeXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImVxdWFsc1wiPkVxdWFsczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwibm90X2VxdWFsc1wiPk5vdCBFcXVhbHM8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImNvbnRhaW5zXCI+Q29udGFpbnM8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIm5vdF9jb250YWluc1wiPk5vdCBDb250YWluczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZ3JlYXRlcl90aGFuXCI+R3JlYXRlciBUaGFuPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsZXNzX3RoYW5cIj5MZXNzIFRoYW48L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImdyZWF0ZXJfdGhhbl9vcl9lcXVhbHNcIj5HcmVhdGVyIFRoYW4gT3IgRXF1YWxzPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsZXNzX3RoYW5fb3JfZXF1YWxzXCI+TGVzcyBUaGFuIE9yIEVxdWFsczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZXhpc3RzXCI+RXhpc3RzPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJub3RfZXhpc3RzXCI+Tm90IEV4aXN0czwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIEV4cGVjdGVkIFR5cGUgQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImV4cGVjdGVkVHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+ZXhwZWN0ZWRUeXBlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgYXNzZXJ0aW9uOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBlY3RlZFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvbkV4cGVjdGVkVHlwZUNoYW5nZShpLCAkZXZlbnQudmFsdWUpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInN0cmluZ1wiPlN0cmluZzwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwibnVtYmVyXCI+TnVtYmVyPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJib29sZWFuXCI+Qm9vbGVhbjwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwib2JqZWN0XCI+T2JqZWN0PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJhcnJheVwiPkFycmF5PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJudWxsXCI+TnVsbDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIEV4cGVjdGVkIFZhbHVlIENvbHVtbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJleHBlY3RlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5leHBlY3RlZFZhbHVlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgYXNzZXJ0aW9uOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTdHJpbmcsIEFycmF5LCBPYmplY3QgSW5wdXQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldEV4cGVjdGVkVHlwZShpKSA9PT0gJ3N0cmluZycgfHwgZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnYXJyYXknIHx8IGdldEV4cGVjdGVkVHlwZShpKSA9PT0gJ29iamVjdCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRFeHBlY3RlZFR5cGUoaSkgPT09ICdhcnJheScgfHwgZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnb2JqZWN0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImV4cGVjdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImdldEV4cGVjdGVkVmFsdWVQbGFjZWhvbGRlcihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dzPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD48L3RleHRhcmVhPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnc3RyaW5nJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImV4cGVjdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImdldEV4cGVjdGVkVmFsdWVQbGFjZWhvbGRlcihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRGb3JtQ29udHJvbEF0KGksICdleHBlY3RlZFZhbHVlJyk/LnRvdWNoZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlIGlzIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uaGFzRXJyb3IoJ2ludmFsaWRUeXBlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uZXJyb3JzPy5tZXNzYWdlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOdWxsIFR5cGUgRGlzcGxheSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnbnVsbCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXQgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBlY3RlZFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJnZXRFeHBlY3RlZFZhbHVlUGxhY2Vob2xkZXIoaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE51bWJlciBJbnB1dCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnbnVtYmVyJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGgtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZXhwZWN0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkV4cGVjdGVkIFZhbHVlIGluIE51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRGb3JtQ29udHJvbEF0KGksICdleHBlY3RlZFZhbHVlJyk/LnRvdWNoZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlIGlzIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCb29sZWFuIFNlbGVjdCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnYm9vbGVhbidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwiZXhwZWN0ZWRWYWx1ZVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJ0cnVlXCI+dHJ1ZTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZmFsc2VcIj5mYWxzZTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy50b3VjaGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSBpcyByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBY3Rpb25zIENvbHVtbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJhY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBhc3NlcnRpb247IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkZWxldGUtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUFzc2VydGlvbihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidEZWxldGUgYXNzZXJ0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRDb2x1bW5zO1wiPjwvdHI+XG4gICAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBFbXB0eSBTdGF0ZSAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cbiAgICAgICAgICAgICAgICAgIDxwPk5vIGFzc2VydGlvbnMgYWRkZWQuIENsaWNrIFwiQWRkIEFzc2VydGlvblwiIHRvIGNyZWF0ZSBvbmUuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2FkdmFuY2VkJ1wiPlxuICAgICAgICAgICAgPGNxYS1hZHZhbmNlZC12YXJpYWJsZXMtZm9ybSBcbiAgICAgICAgICAgICAgW2FkdmFuY2VkVmFyaWFibGVzXT1cImFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXNcIlxuICAgICAgICAgICAgICBbYWR2YW5jZWRWYXJpYWJsZUZvcm1dPVwiYWR2YW5jZWRWYXJpYWJsZXNGb3JtXCJcbiAgICAgICAgICAgICAgKHZhcmlhYmxlQm9vbGVhbkNoYW5nZSk9XCJvbkFkdmFuY2VkVmFyaWFibGVCb29sZWFuQ2hhbmdlKCRldmVudC5uYW1lLCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAgICAgKHZhcmlhYmxlVmFsdWVDaGFuZ2UpPVwib25BZHZhbmNlZFZhcmlhYmxlVmFsdWVDaGFuZ2UoJGV2ZW50Lm5hbWUsICRldmVudC52YWx1ZSlcIj5cbiAgICAgICAgICAgIDwvY3FhLWFkdmFuY2VkLXZhcmlhYmxlcy1mb3JtPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuXG5cbiAgPCEtLSBBY3Rpb24gQnV0dG9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS13LWZ1bGwgY3FhLWdhcC0yIGNxYS1tdC1hdXRvIGNxYS1wdC00IGNxYS1ib3JkZXItdCBjcWEtYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgPGNxYS1idXR0b24gY2xhc3M9XCJjcWEtdy0xLzJcIiB2YXJpYW50PVwib3V0bGluZWRcIiB0ZXh0PVwiQ2FuY2VsXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIChjbGlja2VkKT1cIm9uQ2FuY2VsKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPGNxYS1idXR0b24gKm5nSWY9XCIhaXNDcmVhdGluZ1N0ZXBcIiBjbGFzcz1cImNxYS13LTEvMlwiIHZhcmlhbnQ9XCJmaWxsZWRcIiBbdGV4dF09XCJlZGl0TW9kZSA/ICdVcGRhdGUgU3RlcCcgOiAnQ3JlYXRlIFN0ZXAnXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhaXNGb3JtVmFsaWQoKVwiXG4gICAgICAoY2xpY2tlZCk9XCJvbkNyZWF0ZVN0ZXAoKVwiPlxuICAgIDwvY3FhLWJ1dHRvbj5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNDcmVhdGluZ1N0ZXBcIiBjbGFzcz1cImNxYS13LTEvMiBjcWEtZmxleC0xIGNxYS1taW4taC1bMzhweF0gY3FhLXJvdW5kZWQtWzhweF1cIj5cbiAgICAgIDxjcWEtYmFkZ2UgbGFiZWw9XCJDcmVhdGluZ+KAplwiIGljb249XCJhdXRvcmVuZXdcIiBbaXNMb2FkaW5nXT1cInRydWVcIiBbZnVsbFdpZHRoXT1cInRydWVcIiBbY2VudGVyQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgW2lubGluZVN0eWxlc109XCInbWluLWhlaWdodDogMzhweDsgaGVpZ2h0OiAzOHB4OyBib3gtc2l6aW5nOiBib3JkZXItYm94OyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsnXCJcbiAgICAgICAgdmFyaWFudD1cImluZm9cIiBzaXplPVwibWVkaXVtXCI+PC9jcWEtYmFkZ2U+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+Il19
950
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1idWlsZGVyLWRhdGFiYXNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3RlcC1idWlsZGVyL3N0ZXAtYnVpbGRlci1kYXRhYmFzZS9zdGVwLWJ1aWxkZXItZGF0YWJhc2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zdGVwLWJ1aWxkZXIvc3RlcC1idWlsZGVyLWRhdGFiYXNlL3N0ZXAtYnVpbGRlci1kYXRhYmFzZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFvQyxTQUFTLEVBQWdDLE1BQU0sZUFBZSxDQUFDO0FBQ2xKLE9BQU8sRUFBZSxTQUFTLEVBQUUsU0FBUyxFQUFlLFVBQVUsRUFBbUIsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNkI3RyxNQUFNLE9BQU8sNEJBQTRCO0lBOEd2QyxZQUNVLEVBQWUsRUFDZixHQUFzQjtRQUR0QixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ2YsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUEvR2hDOzs7V0FHRztRQUNNLG9CQUFlLEdBQW1CLEVBQUUsQ0FBQztRQUU5QyxpRUFBaUU7UUFDeEQsdUJBQWtCLEdBQVksS0FBSyxDQUFDO1FBRTdDLDhDQUE4QztRQUNyQyw2QkFBd0IsR0FBbUIsRUFBRSxDQUFDO1FBRXZELDJCQUEyQjtRQUNsQixZQUFPLEdBQW9CLEVBQUUsQ0FBQztRQUV2Qyx3RUFBd0U7UUFDL0QsaUJBQVksR0FBVSxFQUFFLENBQUM7UUFFbEMsb0JBQW9CO1FBQ1gsY0FBUyxHQUFZLEtBQUssQ0FBQztRQStCcEMseUdBQXlHO1FBQ2hHLG1CQUFjLEdBQVksS0FBSyxDQUFDO1FBRXpDLGdDQUFnQztRQUN0QixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQW9C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IE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIENoYW5nZURldGVjdG9yUmVmLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIEZvcm1BcnJheSwgRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMsIEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcbmltcG9ydCB7IE1hdFRhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJhc2VRdWVyeSB7XG4gIGlkOiBzdHJpbmc7XG4gIHF1ZXJ5OiBzdHJpbmc7XG4gIHZhcmlhYmxlOiBzdHJpbmc7XG4gIHN0YXR1cz86ICdwYXNzZWQnIHwgJ2ZhaWxlZCcgfCAncGVuZGluZyc7XG4gIGFzc2VydGlvbkRhdGE/OiBhbnlbXTsgLy8gQXNzZXJ0aW9uIGRhdGEgZm9yIHZlcmlmaWNhdGlvblxuICAvKiogUmVzdWx0IHJvd3MgZm9yIHRoaXMgcXVlcnkgKHNob3duIGluIE91dHB1dCB0YWIpLiAqL1xuICBxdWVyeVJlc3VsdD86IGFueVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlRm9ybURhdGEge1xuICAvKiogU2VsZWN0ZWQgREIgQ29uZmlnIGlkIChlbnYtYXR0YWNoZWQpLiBSZXBsYWNlcyB0aGUgbGVnYWN5IGRiRW52aXJvbm1lbnQgZmllbGQuICovXG4gIGRiQ29uZmlnSWQ6IHN0cmluZztcbiAgbm9ybWFsRW52aXJvbm1lbnQ/OiBzdHJpbmc7XG4gIHF1ZXJpZXM6IERhdGFiYXNlUXVlcnlbXTtcbiAgYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcz86IGFueVtdO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtc3RlcC1idWlsZGVyLWRhdGFiYXNlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3N0ZXAtYnVpbGRlci1kYXRhYmFzZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW10sXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfVxufSlcbmV4cG9ydCBjbGFzcyBTdGVwQnVpbGRlckRhdGFiYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBPcHRpb25zIGZvciB0aGUgREIgQ29uZmlnIGRyb3Bkb3duIOKAlCBlbnYtYXR0YWNoZWQgREIgY29uZmlncyByZXR1cm5lZCBieVxuICAgKiBgL2Vudmlyb25tZW50cy97ZW52SWR9L2RiX2NvbmZpZ3NgLiBFYWNoIGBTZWxlY3RPcHRpb24uaWRgIGlzIHRoZSBkYkNvbmZpZ0lkLlxuICAgKi9cbiAgQElucHV0KCkgZGJDb25maWdPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtdO1xuXG4gIC8qKiBUcnVlIHdoaWxlIHRoZSBwYXJlbnQgbG9hZHMgREIgY29uZmlncyAoaW5pdGlhbCAvIHNlYXJjaCkuICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZ0RiQ29uZmlnczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBPcHRpb25zIGZvciBOb3JtYWwgZW52aXJvbm1lbnQgZHJvcGRvd24gKi9cbiAgQElucHV0KCkgbm9ybWFsRW52aXJvbm1lbnRPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtdO1xuXG4gIC8qKiBJbml0aWFsIHF1ZXJpZXMgbGlzdCAqL1xuICBASW5wdXQoKSBxdWVyaWVzOiBEYXRhYmFzZVF1ZXJ5W10gPSBbXTtcblxuICAvKiogUXVlcnkgcmVzdWx0cyBkYXRhIChkZXByZWNhdGVkIGluIGZhdm9yIG9mIHBlci1xdWVyeSBxdWVyeVJlc3VsdCkgKi9cbiAgQElucHV0KCkgcXVlcnlSZXN1bHRzOiBhbnlbXSA9IFtdO1xuXG4gIC8qKiBMb2FkaW5nIHN0YXRlICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBJbml0aWFsIERCIENvbmZpZyBpZCBmb3IgZWRpdCBtb2RlIChyZXBsYWNlcyBpbml0aWFsRGJFbnZpcm9ubWVudCkuICovXG4gIEBJbnB1dCgpIGluaXRpYWxEYkNvbmZpZ0lkPzogc3RyaW5nO1xuXG4gIC8qKiBJbml0aWFsIE5vcm1hbCBlbnZpcm9ubWVudCBmb3IgZWRpdCBtb2RlICovXG4gIEBJbnB1dCgpIGluaXRpYWxOb3JtYWxFbnZpcm9ubWVudD86IHN0cmluZztcblxuICAvKiogUmVzb2x2ZWQgdGVzdC1jYXNlIGVudiBuYW1lOyBkcml2ZXMgYmFubmVyICsgTm9ybWFsLUVudiBhdXRvLXNlbGVjdCArIGxvY2suICovXG4gIEBJbnB1dCgpIHRlc3RDYXNlRW52aXJvbm1lbnROYW1lPzogc3RyaW5nO1xuICAvKiogU3VmZml4IGZvciBlbnYtbmFtZSBvcHRpb24gbGFiZWwgKGUuZy4gJyhkZWZhdWx0KScpLiBBbHNvIGxvY2tzIE5vcm1hbCBFbnZpcm9ubWVudCBkcm9wZG93bi4gKi9cbiAgQElucHV0KCkgdGVzdENhc2VFbnZpcm9ubWVudExhYmVsU3VmZml4Pzogc3RyaW5nO1xuICAvKiogSXRhbGljIG5vdGUgcmVuZGVyZWQgdW5kZXIgTm9ybWFsIEVudmlyb25tZW50IGRyb3Bkb3duIOKAlCBsZWdhY3kgc3RlcC1lbnYgZGVwcmVjYXRpb24uICovXG4gIEBJbnB1dCgpIGVudmlyb25tZW50TGVnYWN5RGVwcmVjYXRpb25NZXNzYWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUcnVlIG9ubHkgdW5kZXIgVGllciAxICh0ZXN0Q2FzZS5lbnZpcm9ubWVudElkIHNldCkuIEhpZGVzIHRoZSBOb3JtYWxcbiAgICogRW52aXJvbm1lbnQgcGlja2VyIOKAlCB0aGUgZW52IGJhbm5lciBhbHJlYWR5IHN0YXRlcyBpdC4gVGllciAyLzMga2VlcFxuICAgKiB0aGUgcGlja2VyIHZpc2libGUuIEJvdGggJ25vIHN1ZmZpeCcgQU5EICdubyBkZXByZWNhdGlvbicgYXJlIHJlcXVpcmVkXG4gICAqIGJlY2F1c2UgVGllciAyIGxlYXZlcyBzdWZmaXggdW5kZWZpbmVkIGJ1dCBwb3B1bGF0ZXMgdGhlIGVudiBuYW1lLlxuICAgKi9cbiAgZ2V0IGhpZGVFbnZpcm9ubWVudE5hbWVGaWVsZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBuYW1lID0gKHRoaXMudGVzdENhc2VFbnZpcm9ubWVudE5hbWUgPz8gJycpLnRyaW0oKTtcbiAgICBjb25zdCBzdWZmaXggPSAodGhpcy50ZXN0Q2FzZUVudmlyb25tZW50TGFiZWxTdWZmaXggPz8gJycpLnRyaW0oKTtcbiAgICBjb25zdCBkZXByZWNhdGlvbiA9ICh0aGlzLmVudmlyb25tZW50TGVnYWN5RGVwcmVjYXRpb25NZXNzYWdlID8/ICcnKS50cmltKCk7XG4gICAgcmV0dXJuICEhbmFtZSAmJiAhc3VmZml4ICYmICFkZXByZWNhdGlvbjtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGluIGVkaXQgbW9kZSAqL1xuICBASW5wdXQoKSBlZGl0TW9kZT86IGJvb2xlYW47XG5cbiAgLyoqIFRydWUgd2hpbGUgcGFyZW50IGlzIGNyZWF0aW5nIHRoZSBzdGVwIChBUEkgaW4gcHJvZ3Jlc3MpOyBzaG93IGxvYWRlciBvbiBDcmVhdGUvVXBkYXRlIFN0ZXAgYnV0dG9uICovXG4gIEBJbnB1dCgpIGlzQ3JlYXRpbmdTdGVwOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIEVtaXQgd2hlbiBzdGVwIGlzIGNyZWF0ZWQgKi9cbiAgQE91dHB1dCgpIGNyZWF0ZVN0ZXAgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGFiYXNlRm9ybURhdGE+KCk7XG5cbiAgLyoqIEVtaXQgd2hlbiBjYW5jZWxsZWQgKi9cbiAgQE91dHB1dCgpIGNhbmNlbGxlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRW1pdCB3aGVuIHF1ZXJ5IGlzIHJ1biAqL1xuICBAT3V0cHV0KCkgcnVuUXVlcnkgPSBuZXcgRXZlbnRFbWl0dGVyPHsgY3VycmVudFF1ZXJ5OiBEYXRhYmFzZVF1ZXJ5OyBxdWVyeTogc3RyaW5nOyB2YXJpYWJsZTogc3RyaW5nOyBkYkNvbmZpZ0lkOiBzdHJpbmc7IG5vcm1hbEVudmlyb25tZW50Pzogc3RyaW5nIH0+KCk7XG5cbiAgLyoqIEVtaXQgd2hlbiBEQiBDb25maWcgc2VhcmNoIGlzIHRyaWdnZXJlZCAqL1xuICBAT3V0cHV0KCkgc2VhcmNoRGJDb25maWcgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRW1pdCB3aGVuIE5vcm1hbCBlbnZpcm9ubWVudCBzZWFyY2ggaXMgdHJpZ2dlcmVkICovXG4gIEBPdXRwdXQoKSBzZWFyY2hOb3JtYWxFbnZpcm9ubWVudCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcXVlcnkgaXMgYWRkZWQgKi9cbiAgQE91dHB1dCgpIGFkZFF1ZXJ5ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gcXVlcnkgaXMgZGVsZXRlZCAqL1xuICBAT3V0cHV0KCkgZGVsZXRlUXVlcnkgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRW1pdCB3aGVuIGFzc2VydGlvbiBkYXRhIGNoYW5nZXMgZm9yIGEgcXVlcnkgKi9cbiAgQE91dHB1dCgpIGFzc2VydGlvbkRhdGFDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcXVlcnlJbmRleDogbnVtYmVyOyBhc3NlcnRpb25EYXRhOiBhbnlbXSB9PigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gc2VsZWN0ZWQgcXVlcnkgaW5kZXggY2hhbmdlcyAqL1xuICBAT3V0cHV0KCkgc2VsZWN0ZWRRdWVyeUluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgLyoqIEVtaXQgd2hlbiBhY3RpdmUgdGFiIGNoYW5nZXMgKi9cbiAgQE91dHB1dCgpIGFjdGl2ZVRhYkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8J291dHB1dCcgfCAndmVyaWZpY2F0aW9uJyB8ICdhZHZhbmNlZCc+KCk7XG5cbiAgZGF0YWJhc2VGb3JtOiBGb3JtR3JvdXA7XG4gIHNlbGVjdGVkVGFiOiAnb3V0cHV0JyB8ICd2ZXJpZmljYXRpb24nIHwgJ2FkdmFuY2VkJyA9ICdvdXRwdXQnO1xuICBzZWxlY3RlZFF1ZXJ5SW5kZXg6IG51bWJlciA9IDA7XG5cbiAgLyoqXG4gICAqIENhY2hlZCBzZWxlY3QgY29uZmlncy4gTWV0aG9kLWNhbGwgdGVtcGxhdGUgYmluZGluZ3MgKGBbY29uZmlnXT1cImdldFgoKVwiYCkgYnVpbGRcbiAgICogYSBmcmVzaCBvYmplY3QgZWFjaCBDRCBwYXNzLCBhbmQgd2hlbiB0aGUgaW5uZXIgYG9wdGlvbnNgIGFycmF5IGlzIGFsc28gZnJlc2hcbiAgICogKHdlIG1hcCBhIGNvcHkgdG8gYXBwbHkgdGhlIHN1ZmZpeC9kZWNvcmF0aW9uKSwgYGNxYS1keW5hbWljLXNlbGVjdGAgZGV0ZWN0c1xuICAgKiBhIG5ldyBvcHRpb25zIHJlZmVyZW5jZSBhbmQgcmUtZW1pdHMsIHdoaWNoIHJldHJpZ2dlcnMgcGFyZW50IENEIOKGkiBpbmZpbml0ZVxuICAgKiBsb29wLiBIb2xkaW5nIHRoZSBjb25maWdzIGFzIGZpZWxkcyBhbmQgcmVidWlsZGluZyBvbmx5IGluc2lkZSBgbmdPbkNoYW5nZXNgXG4gICAqIChvciBgbmdPbkluaXRgKSBnaXZlcyB0aGUgZHluYW1pYy1zZWxlY3QgYSBzdGFibGUgcmVmZXJlbmNlIGJldHdlZW4gQ0QgcGFzc2VzLlxuICAgKi9cbiAgZGJDb25maWdTZWxlY3RDb25maWchOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWc7XG4gIG5vcm1hbEVudlNlbGVjdENvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcblxuICAvLyBBc3NlcnRpb25zIGZvcm0gbWFuYWdlbWVudCAtIG9uZSBmb3JtIHBlciBxdWVyeVxuICBhc3NlcnRpb25zRm9ybXM6IE1hcDxudW1iZXIsIEZvcm1Hcm91cD4gPSBuZXcgTWFwKCk7XG4gIGRpc3BsYXllZENvbHVtbnM6IHN0cmluZ1tdID0gWydqc29uUGF0aCcsICd2ZXJpZmljYXRpb25UeXBlJywgJ2V4cGVjdGVkVHlwZScsICdleHBlY3RlZFZhbHVlJywgJ2FjdGlvbnMnXTtcbiAgZGVmYXVsdEV4cGVjdGVkVHlwZSA9ICdzdHJpbmcnO1xuICBwcml2YXRlIGZvcm1TdWJzY3JpcHRpb25zOiBNYXA8bnVtYmVyLCBTdWJzY3JpcHRpb24+ID0gbmV3IE1hcCgpO1xuICBAVmlld0NoaWxkKCdhc3NlcnRpb25zVGFibGUnKSBhc3NlcnRpb25zVGFibGU/OiBNYXRUYWJsZTxhbnk+O1xuXG4gIC8vIEFkdmFuY2VkIHNldHRpbmdzIHZhcmlhYmxlcyAoZ2VuZXJpYyBwZXIgc3RlcCwgY2FuIGJlIHByb3ZpZGVkIGJ5IHBhcmVudClcbiAgQElucHV0KCkgYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlczogYW55W10gPSBbXTtcbiAgYWR2YW5jZWRWYXJpYWJsZXNGb3JtOiBGb3JtQXJyYXkgPSBuZXcgRm9ybUFycmF5KFtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7XG4gICAgdGhpcy5kYXRhYmFzZUZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGRiQ29uZmlnSWQ6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBub3JtYWxFbnZpcm9ubWVudDogWycnXSxcbiAgICAgIHF1ZXJpZXM6IHRoaXMuZmIuYXJyYXkoW10pXG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRpYWxpemVGb3JtV2l0aEluaXRpYWxWYWx1ZXMoKTtcbiAgICB0aGlzLnJlYnVpbGREYkNvbmZpZ1NlbGVjdENvbmZpZygpO1xuICAgIHRoaXMucmVidWlsZE5vcm1hbEVudlNlbGVjdENvbmZpZygpO1xuICAgIC8vIElmIHBhcmVudCBwcm92aWRlZCBhZHZhbmNlZCBzZXR0aW5ncywgYnVpbGQgZnJvbSB0aGVtOyBvdGhlcndpc2UgaW5pdGlhbGl6ZSBkZWZhdWx0c1xuICAgIGlmICh0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMgJiYgdGhpcy5hZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYnVpbGRBZHZhbmNlZFZhcmlhYmxlc0Zvcm0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbml0aWFsaXplQWR2YW5jZWRTZXR0aW5ncygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1sncXVlcmllcyddICYmICFjaGFuZ2VzWydxdWVyaWVzJ10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIC8vIFJlYnVpbGQgZm9ybSBhcnJheSB3aGVuIHF1ZXJpZXMgY2hhbmdlXG4gICAgICBjb25zdCBxdWVyaWVzQXJyYXkgPSB0aGlzLmRhdGFiYXNlRm9ybS5nZXQoJ3F1ZXJpZXMnKSBhcyBGb3JtQXJyYXk7XG4gICAgICB3aGlsZSAocXVlcmllc0FycmF5Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgICBxdWVyaWVzQXJyYXkucmVtb3ZlQXQoMCk7XG4gICAgICB9XG4gICAgICAvLyBDbGVhciBvbGQgYXNzZXJ0aW9ucyBmb3Jtc1xuICAgICAgdGhpcy5hc3NlcnRpb25zRm9ybXMuZm9yRWFjaCgoZm9ybSwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuaGFzKGluZGV4KSkge1xuICAgICAgICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuZ2V0KGluZGV4KSEudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLmFzc2VydGlvbnNGb3Jtcy5jbGVhcigpO1xuICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5jbGVhcigpO1xuXG4gICAgICAvLyBSZWJ1aWxkIHF1ZXJpZXMgYW5kIGFzc2VydGlvbnMgZm9ybXNcbiAgICAgIHRoaXMucXVlcmllcy5mb3JFYWNoKChxdWVyeSwgaW5kZXgpID0+IHtcbiAgICAgICAgLy8gRW5zdXJlIGFzc2VydGlvbiBkYXRhIGlzIGluaXRpYWxpemVkXG4gICAgICAgIGlmICghcXVlcnkuYXNzZXJ0aW9uRGF0YSkge1xuICAgICAgICAgIHF1ZXJ5LmFzc2VydGlvbkRhdGEgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZFF1ZXJ5VG9Gb3JtKHF1ZXJ5KTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBhc3NlcnRpb25zIGZvcm0gZm9yIGVhY2ggcXVlcnlcbiAgICAgICAgdGhpcy5lbnN1cmVBc3NlcnRpb25EYXRhSW5pdGlhbGl6ZWQoaW5kZXgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEVuc3VyZSBzZWxlY3RlZCBxdWVyeSBpbmRleCBpcyB2YWxpZFxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID49IHRoaXMucXVlcmllcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPSBNYXRoLm1heCgwLCB0aGlzLnF1ZXJpZXMubGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydpbml0aWFsRGJDb25maWdJZCddICYmIGNoYW5nZXNbJ2luaXRpYWxEYkNvbmZpZ0lkJ10uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLmRhdGFiYXNlRm9ybS5wYXRjaFZhbHVlKHsgZGJDb25maWdJZDogY2hhbmdlc1snaW5pdGlhbERiQ29uZmlnSWQnXS5jdXJyZW50VmFsdWUgfSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydpbml0aWFsTm9ybWFsRW52aXJvbm1lbnQnXSAmJiBjaGFuZ2VzWydpbml0aWFsTm9ybWFsRW52aXJvbm1lbnQnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMuZGF0YWJhc2VGb3JtLnBhdGNoVmFsdWUoeyBub3JtYWxFbnZpcm9ubWVudDogY2hhbmdlc1snaW5pdGlhbE5vcm1hbEVudmlyb25tZW50J10uY3VycmVudFZhbHVlIH0pO1xuICAgIH1cblxuICAgIC8vIFdoZW4gcGFyZW50IHVwZGF0ZXMgYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcywgcmVidWlsZCBhZHZhbmNlZCBmb3JtXG4gICAgaWYgKGNoYW5nZXNbJ2FkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMnXSAmJiB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMpIHtcbiAgICAgIGlmICh0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmJ1aWxkQWR2YW5jZWRWYXJpYWJsZXNGb3JtKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVBZHZhbmNlZFNldHRpbmdzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU3RhYmxlLXJlZmVyZW5jZSByZWJ1aWxkIG9mIHNlbGVjdCBjb25maWdzIOKAlCBydW5zIE9OTFkgd2hlbiB0aGUgcmVsZXZhbnRcbiAgICAvLyBJbnB1dHMgY2hhbmdlLiBBdm9pZHMgdGhlIENEIGxvb3AgY2F1c2VkIGJ5IHBlci1wYXNzIGAubWFwKClgIGNhbGxzLlxuICAgIGlmIChjaGFuZ2VzWydkYkNvbmZpZ09wdGlvbnMnXSB8fCBjaGFuZ2VzWydpc0xvYWRpbmdEYkNvbmZpZ3MnXSkge1xuICAgICAgdGhpcy5yZWJ1aWxkRGJDb25maWdTZWxlY3RDb25maWcoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ25vcm1hbEVudmlyb25tZW50T3B0aW9ucyddIHx8IGNoYW5nZXNbJ3Rlc3RDYXNlRW52aXJvbm1lbnROYW1lJ10gfHwgY2hhbmdlc1sndGVzdENhc2VFbnZpcm9ubWVudExhYmVsU3VmZml4J10pIHtcbiAgICAgIHRoaXMucmVidWlsZE5vcm1hbEVudlNlbGVjdENvbmZpZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVidWlsZERiQ29uZmlnU2VsZWN0Q29uZmlnKCk6IHZvaWQge1xuICAgIHRoaXMuZGJDb25maWdTZWxlY3RDb25maWcgPSB7XG4gICAgICBrZXk6ICdkYkNvbmZpZ0lkJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IERCIGNvbmZpZycsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgICAgc2VydmVyU2VhcmNoOiB0cnVlLFxuICAgICAgb3B0aW9uczogdGhpcy5kYkNvbmZpZ09wdGlvbnMgPz8gW10sXG4gICAgICBpc0xvYWRpbmc6IHRoaXMuaXNMb2FkaW5nRGJDb25maWdzLFxuICAgICAgb25TZWFyY2g6IChxdWVyeTogc3RyaW5nKSA9PiB7IHRoaXMuc2VhcmNoRGJDb25maWcuZW1pdChxdWVyeSk7IH1cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZWJ1aWxkTm9ybWFsRW52U2VsZWN0Q29uZmlnKCk6IHZvaWQge1xuICAgIGNvbnN0IGxhYmVsU3VmZml4ID0gKHRoaXMudGVzdENhc2VFbnZpcm9ubWVudExhYmVsU3VmZml4ID8/ICcnKS50cmltKCk7XG4gICAgY29uc3QgbG9jayA9ICEhKHRoaXMudGVzdENhc2VFbnZpcm9ubWVudE5hbWUgPz8gJycpLnRyaW0oKSB8fCAhIWxhYmVsU3VmZml4O1xuICAgIGNvbnN0IG9wdHMgPSBsYWJlbFN1ZmZpeFxuICAgICAgPyAodGhpcy5ub3JtYWxFbnZpcm9ubWVudE9wdGlvbnMgPz8gW10pLm1hcChvID0+ICh7XG4gICAgICAgICAgLi4ubyxcbiAgICAgICAgICBsYWJlbDogYCR7U3RyaW5nKG8ubGFiZWwgPz8gby5uYW1lID8/ICcnKX0gJHtsYWJlbFN1ZmZpeH1gLFxuICAgICAgICB9KSlcbiAgICAgIDogKHRoaXMubm9ybWFsRW52aXJvbm1lbnRPcHRpb25zID8/IFtdKTtcbiAgICB0aGlzLm5vcm1hbEVudlNlbGVjdENvbmZpZyA9IHtcbiAgICAgIGtleTogJ25vcm1hbEVudmlyb25tZW50JyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IE5vcm1hbCBlbnZpcm9ubWVudCcsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBzZWFyY2hhYmxlOiAhbG9jayxcbiAgICAgIHNlcnZlclNlYXJjaDogIWxvY2ssXG4gICAgICBkaXNhYmxlZDogbG9jayxcbiAgICAgIG9wdGlvbnM6IG9wdHMsXG4gICAgICBvblNlYXJjaDogKHF1ZXJ5OiBzdHJpbmcpID0+IHsgdGhpcy5zZWFyY2hOb3JtYWxFbnZpcm9ubWVudC5lbWl0KHF1ZXJ5KTsgfVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVGb3JtV2l0aEluaXRpYWxWYWx1ZXMoKTogdm9pZCB7XG4gICAgLy8gU2V0IGluaXRpYWwgREIgQ29uZmlnIGlmIHByb3ZpZGVkXG4gICAgaWYgKHRoaXMuaW5pdGlhbERiQ29uZmlnSWQpIHtcbiAgICAgIHRoaXMuZGF0YWJhc2VGb3JtLnBhdGNoVmFsdWUoeyBkYkNvbmZpZ0lkOiB0aGlzLmluaXRpYWxEYkNvbmZpZ0lkIH0pO1xuICAgIH1cbiAgICAvLyBTZXQgaW5pdGlhbCBOb3JtYWwgZW52aXJvbm1lbnQgaWYgcHJvdmlkZWRcbiAgICBpZiAodGhpcy5pbml0aWFsTm9ybWFsRW52aXJvbm1lbnQpIHtcbiAgICAgIHRoaXMuZGF0YWJhc2VGb3JtLnBhdGNoVmFsdWUoeyBub3JtYWxFbnZpcm9ubWVudDogdGhpcy5pbml0aWFsTm9ybWFsRW52aXJvbm1lbnQgfSk7XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSB3aXRoIHF1ZXJpZXMgaWYgcHJvdmlkZWQsIG90aGVyd2lzZSBhZGQgZGVmYXVsdCBxdWVyeVxuICAgIGlmICh0aGlzLnF1ZXJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmFkZE5ld1F1ZXJ5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucXVlcmllcy5mb3JFYWNoKChxdWVyeSwgaW5kZXgpID0+IHtcbiAgICAgICAgLy8gRW5zdXJlIGFzc2VydGlvbiBkYXRhIGlzIGluaXRpYWxpemVkXG4gICAgICAgIGlmICghcXVlcnkuYXNzZXJ0aW9uRGF0YSkge1xuICAgICAgICAgIHF1ZXJ5LmFzc2VydGlvbkRhdGEgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZFF1ZXJ5VG9Gb3JtKHF1ZXJ5KTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBhc3NlcnRpb25zIGZvcm0gZm9yIGVhY2ggcXVlcnlcbiAgICAgICAgdGhpcy5lbnN1cmVBc3NlcnRpb25EYXRhSW5pdGlhbGl6ZWQoaW5kZXgpO1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA9IDA7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXhDaGFuZ2UuZW1pdCgwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHF1ZXJpZXNGb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZUZvcm0uZ2V0KCdxdWVyaWVzJykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgYWRkTmV3UXVlcnkoKTogdm9pZCB7XG4gICAgY29uc3QgbmV3UXVlcnk6IERhdGFiYXNlUXVlcnkgPSB7XG4gICAgICBpZDogYHF1ZXJ5XyR7RGF0ZS5ub3coKX1gLFxuICAgICAgcXVlcnk6ICcnLFxuICAgICAgdmFyaWFibGU6ICcnLFxuICAgICAgc3RhdHVzOiAncGVuZGluZycsXG4gICAgICBhc3NlcnRpb25EYXRhOiBbXSAvLyBJbml0aWFsaXplIHdpdGggZW1wdHkgYXNzZXJ0aW9uIGRhdGFcbiAgICB9O1xuICAgIHRoaXMucXVlcmllcy5wdXNoKG5ld1F1ZXJ5KTtcbiAgICB0aGlzLmFkZFF1ZXJ5VG9Gb3JtKG5ld1F1ZXJ5KTtcbiAgICBjb25zdCBuZXdJbmRleCA9IHRoaXMucXVlcmllcy5sZW5ndGggLSAxO1xuICAgIHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID0gbmV3SW5kZXg7XG4gICAgLy8gSW5pdGlhbGl6ZSBhc3NlcnRpb25zIGZvcm0gZm9yIHRoZSBuZXcgcXVlcnlcbiAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZChuZXdJbmRleCk7XG4gICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXhDaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCk7XG4gICAgdGhpcy5hZGRRdWVyeS5lbWl0KCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRRdWVyeVRvRm9ybShxdWVyeTogRGF0YWJhc2VRdWVyeSk6IHZvaWQge1xuICAgIGNvbnN0IHF1ZXJ5R3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGlkOiBbcXVlcnkuaWRdLFxuICAgICAgcXVlcnk6IFtxdWVyeS5xdWVyeSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YXJpYWJsZTogW3F1ZXJ5LnZhcmlhYmxlLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgIH0pO1xuICAgIHRoaXMucXVlcmllc0Zvcm1BcnJheS5wdXNoKHF1ZXJ5R3JvdXApO1xuICB9XG5cbiAgZGVsZXRlUXVlcnlCeUlkKHF1ZXJ5SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5xdWVyaWVzLmZpbmRJbmRleChxID0+IHEuaWQgPT09IHF1ZXJ5SWQpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIC8vIENsZWFuIHVwIGFzc2VydGlvbnMgZm9ybSBhbmQgc3Vic2NyaXB0aW9uIGZvciB0aGlzIHF1ZXJ5XG4gICAgICBpZiAodGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5oYXMoaW5kZXgpKSB7XG4gICAgICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuZ2V0KGluZGV4KSEudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5kZWxldGUoaW5kZXgpO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnRpb25zRm9ybXMuZGVsZXRlKGluZGV4KTtcblxuICAgICAgLy8gUmVpbmRleCByZW1haW5pbmcgZm9ybXMgYW5kIHN1YnNjcmlwdGlvbnNcbiAgICAgIGNvbnN0IGZvcm1zVG9SZWluZGV4ID0gbmV3IE1hcDxudW1iZXIsIEZvcm1Hcm91cD4oKTtcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbnNUb1JlaW5kZXggPSBuZXcgTWFwPG51bWJlciwgU3Vic2NyaXB0aW9uPigpO1xuICAgICAgXG4gICAgICB0aGlzLmFzc2VydGlvbnNGb3Jtcy5mb3JFYWNoKChmb3JtLCBvbGRJbmRleCkgPT4ge1xuICAgICAgICBpZiAob2xkSW5kZXggPiBpbmRleCkge1xuICAgICAgICAgIGZvcm1zVG9SZWluZGV4LnNldChvbGRJbmRleCAtIDEsIGZvcm0pO1xuICAgICAgICB9IGVsc2UgaWYgKG9sZEluZGV4IDwgaW5kZXgpIHtcbiAgICAgICAgICBmb3Jtc1RvUmVpbmRleC5zZXQob2xkSW5kZXgsIGZvcm0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzdWIsIG9sZEluZGV4KSA9PiB7XG4gICAgICAgIGlmIChvbGRJbmRleCA+IGluZGV4KSB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uc1RvUmVpbmRleC5zZXQob2xkSW5kZXggLSAxLCBzdWIpO1xuICAgICAgICB9IGVsc2UgaWYgKG9sZEluZGV4IDwgaW5kZXgpIHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zVG9SZWluZGV4LnNldChvbGRJbmRleCwgc3ViKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuYXNzZXJ0aW9uc0Zvcm1zID0gZm9ybXNUb1JlaW5kZXg7XG4gICAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb25zID0gc3Vic2NyaXB0aW9uc1RvUmVpbmRleDtcblxuICAgICAgdGhpcy5xdWVyaWVzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB0aGlzLnF1ZXJpZXNGb3JtQXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID49IHRoaXMucXVlcmllcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPSBNYXRoLm1heCgwLCB0aGlzLnF1ZXJpZXMubGVuZ3RoIC0gMSk7XG4gICAgICAgIC8vIEVuc3VyZSBhc3NlcnRpb25zIGZvcm0gaXMgaW5pdGlhbGl6ZWQgZm9yIHRoZSBuZXcgc2VsZWN0ZWQgcXVlcnlcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4ID49IDApIHtcbiAgICAgICAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuZGVsZXRlUXVlcnkuZW1pdChxdWVyeUlkKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICBnZXRDdXJyZW50UXVlcnkoKTogRGF0YWJhc2VRdWVyeSB8IG51bGwge1xuICAgIGlmICh0aGlzLnF1ZXJpZXMubGVuZ3RoID4gMCAmJiB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA+PSAwICYmIHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4IDwgdGhpcy5xdWVyaWVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMucXVlcmllc1t0aGlzLnNlbGVjdGVkUXVlcnlJbmRleF07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0Q3VycmVudFF1ZXJ5Rm9ybUdyb3VwKCk6IEZvcm1Hcm91cCB8IG51bGwge1xuICAgIGlmICh0aGlzLnF1ZXJpZXNGb3JtQXJyYXkgJiYgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPj0gMCAmJiB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCA8IHRoaXMucXVlcmllc0Zvcm1BcnJheS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLnF1ZXJpZXNGb3JtQXJyYXkuYXQodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBvblJ1blF1ZXJ5KCk6IHZvaWQge1xuICAgIGNvbnN0IGRiQ29uZmlnSWQgPSB0aGlzLmRhdGFiYXNlRm9ybS5nZXQoJ2RiQ29uZmlnSWQnKT8udmFsdWU7XG4gICAgY29uc3Qgbm9ybWFsRW52aXJvbm1lbnQgPSB0aGlzLmRhdGFiYXNlRm9ybS5nZXQoJ25vcm1hbEVudmlyb25tZW50Jyk/LnZhbHVlO1xuICAgIGNvbnN0IGN1cnJlbnRRdWVyeSA9IHRoaXMuZ2V0Q3VycmVudFF1ZXJ5KCk7XG4gICAgY29uc3QgcXVlcnlGb3JtR3JvdXAgPSB0aGlzLmdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpO1xuXG4gICAgaWYgKGN1cnJlbnRRdWVyeSAmJiBxdWVyeUZvcm1Hcm91cCAmJiBkYkNvbmZpZ0lkKSB7XG4gICAgICBjb25zdCBxdWVyeSA9IHF1ZXJ5Rm9ybUdyb3VwLmdldCgncXVlcnknKT8udmFsdWUgfHwgJyc7XG4gICAgICBjb25zdCB2YXJpYWJsZSA9IHF1ZXJ5Rm9ybUdyb3VwLmdldCgndmFyaWFibGUnKT8udmFsdWUgfHwgJyc7XG5cbiAgICAgIC8vIFVwZGF0ZSB0aGUgcXVlcnkgb2JqZWN0XG4gICAgICBjdXJyZW50UXVlcnkucXVlcnkgPSBxdWVyeTtcbiAgICAgIGN1cnJlbnRRdWVyeS52YXJpYWJsZSA9IHZhcmlhYmxlO1xuXG4gICAgICB0aGlzLnJ1blF1ZXJ5LmVtaXQoe1xuICAgICAgICBjdXJyZW50UXVlcnksXG4gICAgICAgIHF1ZXJ5LFxuICAgICAgICB2YXJpYWJsZSxcbiAgICAgICAgZGJDb25maWdJZCxcbiAgICAgICAgbm9ybWFsRW52aXJvbm1lbnQ6IG5vcm1hbEVudmlyb25tZW50IHx8IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgb25TZWxlY3RRdWVyeShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gRW5zdXJlIGFzc2VydGlvbiBkYXRhIGlzIGluaXRpYWxpemVkIGZvciB0aGUgc2VsZWN0ZWQgcXVlcnlcbiAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZChpbmRleCk7XG4gICAgdGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXggPSBpbmRleDtcbiAgICB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleENoYW5nZS5lbWl0KGluZGV4KTtcbiAgICAvLyBUcmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gdG8gZW5zdXJlIGFzc2VydGlvbnMgZm9ybSBpcyBkaXNwbGF5ZWRcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcXVlcnkgaW5kZXhcbiAgICovXG4gIGdldFNlbGVjdGVkUXVlcnlJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkUXVlcnlJbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnRseSBhY3RpdmUgdGFiXG4gICAqL1xuICBnZXRBY3RpdmVUYWIoKTogJ291dHB1dCcgfCAndmVyaWZpY2F0aW9uJyB8ICdhZHZhbmNlZCcge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkVGFiO1xuICB9XG5cbiAgb25UYWJDaGFuZ2UodGFiOiAnb3V0cHV0JyB8ICd2ZXJpZmljYXRpb24nIHwgJ2FkdmFuY2VkJyk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSB0YWI7XG4gICAgdGhpcy5hY3RpdmVUYWJDaGFuZ2UuZW1pdCh0YWIpO1xuICAgIC8vIEVuc3VyZSBhc3NlcnRpb25zIGZvcm0gaXMgaW5pdGlhbGl6ZWQgd2hlbiBzd2l0Y2hpbmcgdG8gdmVyaWZpY2F0aW9uIHRhYlxuICAgIGlmICh0YWIgPT09ICd2ZXJpZmljYXRpb24nKSB7XG4gICAgICB0aGlzLmVuc3VyZUFzc2VydGlvbkRhdGFJbml0aWFsaXplZCh0aGlzLnNlbGVjdGVkUXVlcnlJbmRleCk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgb25Db3B5UmVzdWx0cygpOiB2b2lkIHtcbiAgICBjb25zdCByb3dzID0gdGhpcy5nZXRDdXJyZW50UXVlcnlSZXN1bHQoKTtcbiAgICBpZiAocm93cyAmJiByb3dzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHRleHQgPSBKU09OLnN0cmluZ2lmeShyb3dzLCBudWxsLCAyKTtcbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRleHQpLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBDb3VsZCBlbWl0IGFuIGV2ZW50IG9yIHNob3cgYSB0b2FzdCBub3RpZmljYXRpb25cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsbGVkLmVtaXQoKTtcbiAgfVxuXG4gIGlzRm9ybVZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIC8vIENoZWNrIGlmIG1haW4gZm9ybSBpcyB2YWxpZCAoZGJDb25maWdJZCBpcyByZXF1aXJlZClcbiAgICBpZiAoIXRoaXMuZGF0YWJhc2VGb3JtLnZhbGlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhdCBsZWFzdCBvbmUgcXVlcnlcbiAgICBpZiAodGhpcy5xdWVyaWVzLmxlbmd0aCA9PT0gMCB8fCB0aGlzLnF1ZXJpZXNGb3JtQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYWxsIHF1ZXJpZXMgaGF2ZSB2YWxpZCBxdWVyeSBhbmQgdmFyaWFibGUgZmllbGRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnF1ZXJpZXNGb3JtQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHF1ZXJ5Rm9ybUdyb3VwID0gdGhpcy5xdWVyaWVzRm9ybUFycmF5LmF0KGkpIGFzIEZvcm1Hcm91cDtcbiAgICAgIGlmICghcXVlcnlGb3JtR3JvdXAudmFsaWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgb25DcmVhdGVTdGVwKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0Zvcm1WYWxpZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMuZGF0YWJhc2VGb3JtLnZhbHVlO1xuXG4gICAgLy8gU3luYyBhZHZhbmNlZCB2YXJpYWJsZXMgZnJvbSBmb3JtIHRvIGFycmF5IGJlZm9yZSBlbWl0dGluZ1xuICAgIHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcy5mb3JFYWNoKCh2YXJpYWJsZSwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGZvcm1Hcm91cCA9IHRoaXMuYWR2YW5jZWRWYXJpYWJsZXNGb3JtLmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgICBpZiAoZm9ybUdyb3VwKSB7XG4gICAgICAgIGNvbnN0IGZvcm1WYWx1ZUNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KCd2YWx1ZScpPy52YWx1ZTtcbiAgICAgICAgdmFyaWFibGUudmFsdWUgPSBmb3JtVmFsdWVDb250cm9sO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RlcERhdGE6IERhdGFiYXNlRm9ybURhdGEgPSB7XG4gICAgICBkYkNvbmZpZ0lkOiBmb3JtVmFsdWUuZGJDb25maWdJZCxcbiAgICAgIG5vcm1hbEVudmlyb25tZW50OiBmb3JtVmFsdWUubm9ybWFsRW52aXJvbm1lbnQgfHwgdW5kZWZpbmVkLFxuICAgICAgcXVlcmllczogdGhpcy5xdWVyaWVzLm1hcCgocXVlcnksIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5Rm9ybUdyb3VwID0gdGhpcy5xdWVyaWVzRm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaWQ6IHF1ZXJ5LmlkLFxuICAgICAgICAgIHF1ZXJ5OiBxdWVyeUZvcm1Hcm91cC5nZXQoJ3F1ZXJ5Jyk/LnZhbHVlIHx8ICcnLFxuICAgICAgICAgIHZhcmlhYmxlOiBxdWVyeUZvcm1Hcm91cC5nZXQoJ3ZhcmlhYmxlJyk/LnZhbHVlIHx8ICcnLFxuICAgICAgICAgIHN0YXR1czogcXVlcnkuc3RhdHVzLFxuICAgICAgICAgIGFzc2VydGlvbkRhdGE6IHF1ZXJ5LmFzc2VydGlvbkRhdGEgfHwgW10gLy8gSW5jbHVkZSBhc3NlcnRpb24gZGF0YVxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICBhZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzOiB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXNcbiAgICB9O1xuICAgIHRoaXMuY3JlYXRlU3RlcC5lbWl0KHN0ZXBEYXRhKTtcbiAgfVxuXG4gIGdldFRhYmxlQ29sdW1ucygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgcm93cyA9IHRoaXMuZ2V0Q3VycmVudFF1ZXJ5UmVzdWx0KCk7XG4gICAgaWYgKCFyb3dzIHx8IHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhyb3dzWzBdKTtcbiAgfVxuXG4gIC8qKiBHZXQgcmVzdWx0IHJvd3MgZm9yIGN1cnJlbnRseSBzZWxlY3RlZCBxdWVyeS4gKi9cbiAgZ2V0Q3VycmVudFF1ZXJ5UmVzdWx0KCk6IGFueVtdIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5xdWVyaWVzW3RoaXMuc2VsZWN0ZWRRdWVyeUluZGV4XTtcbiAgICBpZiAoY3VycmVudCAmJiBBcnJheS5pc0FycmF5KGN1cnJlbnQucXVlcnlSZXN1bHQpICYmIGN1cnJlbnQucXVlcnlSZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnQucXVlcnlSZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXNzZXJ0aW9uIGRhdGEgZm9yIGEgc3BlY2lmaWMgcXVlcnlcbiAgICovXG4gIGdldEFzc2VydGlvbkRhdGFGb3JRdWVyeShxdWVyeUluZGV4OiBudW1iZXIpOiBhbnlbXSB7XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF07XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5LmFzc2VydGlvbkRhdGEpIHtcbiAgICAgIHJldHVybiBxdWVyeS5hc3NlcnRpb25EYXRhO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGFzc2VydGlvbiBkYXRhIGNoYW5nZSBmcm9tIGV4dGVybmFsIGNvbXBvbmVudFxuICAgKi9cbiAgb25Bc3NlcnRpb25EYXRhQ2hhbmdlKGFzc2VydGlvbkRhdGE6IGFueVtdLCBxdWVyeUluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdKSB7XG4gICAgICAvLyBDcmVhdGUgYSBkZWVwIGNvcHkgdG8gZW5zdXJlIGVhY2ggcXVlcnkgaGFzIGl0cyBvd24gZGF0YVxuICAgICAgaWYgKGFzc2VydGlvbkRhdGEgJiYgYXNzZXJ0aW9uRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMucXVlcmllc1txdWVyeUluZGV4XS5hc3NlcnRpb25EYXRhID0gYXNzZXJ0aW9uRGF0YS5tYXAoKGl0ZW06IGFueSkgPT4ge1xuICAgICAgICAgIC8vIEVuc3VyZSBleHBlY3RlZFZhbHVlIGlzIHByb3Blcmx5IGZvcm1hdHRlZFxuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGl0ZW0uZXhwZWN0ZWRUeXBlIHx8ICdzdHJpbmcnO1xuICAgICAgICAgIGxldCBleHBlY3RlZFZhbHVlID0gaXRlbS5leHBlY3RlZFZhbHVlO1xuXG4gICAgICAgICAgLy8gRm9yIG9iamVjdC9hcnJheSB0eXBlcywgZW5zdXJlIGV4cGVjdGVkVmFsdWUgaXMgYW4gb2JqZWN0L2FycmF5LCBub3QgYSBzdHJpbmdcbiAgICAgICAgICBpZiAoZXhwZWN0ZWRUeXBlID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZXhwZWN0ZWRWYWx1ZSA9PT0gJ3N0cmluZycgJiYgZXhwZWN0ZWRWYWx1ZS50cmltKCkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGV4cGVjdGVkVmFsdWUgPSBKU09OLnBhcnNlKGV4cGVjdGVkVmFsdWUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAvLyBJZiBwYXJzaW5nIGZhaWxzLCBrZWVwIGFzIHN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnYXJyYXknICYmIHR5cGVvZiBleHBlY3RlZFZhbHVlID09PSAnc3RyaW5nJyAmJiBleHBlY3RlZFZhbHVlLnRyaW0oKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IEpTT04ucGFyc2UoZXhwZWN0ZWRWYWx1ZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIC8vIElmIHBhcnNpbmcgZmFpbHMsIGtlZXAgYXMgc3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdudW1iZXInICYmIHR5cGVvZiBleHBlY3RlZFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGV4cGVjdGVkVmFsdWUgIT09ICcnID8gTnVtYmVyKGV4cGVjdGVkVmFsdWUpIDogbnVsbDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICBpZiAoZXhwZWN0ZWRWYWx1ZSA9PT0gJ3RydWUnIHx8IGV4cGVjdGVkVmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVmFsdWUgPT09ICdmYWxzZScgfHwgZXhwZWN0ZWRWYWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBqc29uUGF0aDogaXRlbS5qc29uUGF0aCB8fCAnJyxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvblR5cGU6IGl0ZW0udmVyaWZpY2F0aW9uVHlwZSB8fCAnZXF1YWxzJyxcbiAgICAgICAgICAgIGV4cGVjdGVkVHlwZTogZXhwZWN0ZWRUeXBlLFxuICAgICAgICAgICAgZXhwZWN0ZWRWYWx1ZTogZXhwZWN0ZWRWYWx1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdLmFzc2VydGlvbkRhdGEgPSBbXTtcbiAgICAgIH1cblxuICAgICAgLy8gRW1pdCB0aGUgY2hhbmdlIHRvIHBhcmVudFxuICAgICAgdGhpcy5hc3NlcnRpb25EYXRhQ2hhbmdlLmVtaXQoe1xuICAgICAgICBxdWVyeUluZGV4OiBxdWVyeUluZGV4LFxuICAgICAgICBhc3NlcnRpb25EYXRhOiB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF0uYXNzZXJ0aW9uRGF0YSB8fCBbXVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYXNzZXJ0aW9uIGRhdGEgZm9yIGEgcXVlcnkgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgKi9cbiAgcHJpdmF0ZSBlbnN1cmVBc3NlcnRpb25EYXRhSW5pdGlhbGl6ZWQocXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucXVlcmllc1txdWVyeUluZGV4XSAmJiAhdGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdLmFzc2VydGlvbkRhdGEpIHtcbiAgICAgIHRoaXMucXVlcmllc1txdWVyeUluZGV4XS5hc3NlcnRpb25EYXRhID0gW107XG4gICAgfVxuICAgIC8vIEluaXRpYWxpemUgYXNzZXJ0aW9ucyBmb3JtIGZvciB0aGlzIHF1ZXJ5IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICBpZiAoIXRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmhhcyhxdWVyeUluZGV4KSkge1xuICAgICAgdGhpcy5pbml0aWFsaXplQXNzZXJ0aW9uc0Zvcm0ocXVlcnlJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYXNzZXJ0aW9ucyBmb3JtIGZvciBhIHNwZWNpZmljIHF1ZXJ5XG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVBc3NlcnRpb25zRm9ybShxdWVyeUluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBhc3NlcnRpb25zQXJyYXkgPSB0aGlzLmZiLmFycmF5KFtdKTtcbiAgICBjb25zdCBhc3NlcnRpb25zRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgYXNzZXJ0aW9uczogYXNzZXJ0aW9uc0FycmF5XG4gICAgfSk7XG4gICAgdGhpcy5hc3NlcnRpb25zRm9ybXMuc2V0KHF1ZXJ5SW5kZXgsIGFzc2VydGlvbnNGb3JtKTtcblxuICAgIC8vIExvYWQgZXhpc3RpbmcgYXNzZXJ0aW9ucyBpZiB0aGV5IGV4aXN0XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF07XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5LmFzc2VydGlvbkRhdGEgJiYgcXVlcnkuYXNzZXJ0aW9uRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmxvYWRBc3NlcnRpb25zRm9yUXVlcnkocXVlcnlJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gU3Vic2NyaWJlIHRvIGZvcm0gY2hhbmdlc1xuICAgIHRoaXMuc3Vic2NyaWJlVG9Bc3NlcnRpb25zRm9ybUNoYW5nZXMocXVlcnlJbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFzc2VydGlvbnMgZm9ybSBmb3IgY3VycmVudCBxdWVyeVxuICAgKi9cbiAgZ2V0Q3VycmVudEFzc2VydGlvbnNGb3JtKCk6IEZvcm1Hcm91cCB8IG51bGwge1xuICAgIGlmICh0aGlzLmFzc2VydGlvbnNGb3Jtcy5oYXModGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hc3NlcnRpb25zRm9ybXMuZ2V0KHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KSE7XG4gICAgfVxuICAgIC8vIEluaXRpYWxpemUgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgIHRoaXMuZW5zdXJlQXNzZXJ0aW9uRGF0YUluaXRpYWxpemVkKHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KTtcbiAgICByZXR1cm4gdGhpcy5hc3NlcnRpb25zRm9ybXMuZ2V0KHRoaXMuc2VsZWN0ZWRRdWVyeUluZGV4KSB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhc3NlcnRpb25zIGZvcm0gYXJyYXkgZm9yIGN1cnJlbnQgcXVlcnlcbiAgICovXG4gIGdldEFzc2VydGlvbnNGb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5nZXRDdXJyZW50QXNzZXJ0aW9uc0Zvcm0oKTtcbiAgICBpZiAoZm9ybSkge1xuICAgICAgcmV0dXJuIGZvcm0uZ2V0KCdhc3NlcnRpb25zJykgYXMgRm9ybUFycmF5O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mYi5hcnJheShbXSk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhc3NlcnRpb25zIGludG8gZm9ybSBmb3IgYSBzcGVjaWZpYyBxdWVyeVxuICAgKi9cbiAgcHJpdmF0ZSBsb2FkQXNzZXJ0aW9uc0ZvclF1ZXJ5KHF1ZXJ5SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmFzc2VydGlvbnNGb3Jtcy5nZXQocXVlcnlJbmRleCk7XG4gICAgaWYgKCFmb3JtKSByZXR1cm47XG5cbiAgICBjb25zdCBmb3JtQXJyYXkgPSBmb3JtLmdldCgnYXNzZXJ0aW9ucycpIGFzIEZvcm1BcnJheTtcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMucXVlcmllc1txdWVyeUluZGV4XTtcbiAgICBpZiAoIXF1ZXJ5IHx8ICFxdWVyeS5hc3NlcnRpb25EYXRhKSByZXR1cm47XG5cbiAgICAvLyBDbGVhciBleGlzdGluZyBmb3JtIGFycmF5XG4gICAgd2hpbGUgKGZvcm1BcnJheS5sZW5ndGggIT09IDApIHtcbiAgICAgIGZvcm1BcnJheS5yZW1vdmVBdCgwKTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIGFzc2VydGlvbnNcbiAgICBxdWVyeS5hc3NlcnRpb25EYXRhLmZvckVhY2goKGFzc2VydGlvbjogYW55KSA9PiB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBhc3NlcnRpb24uZXhwZWN0ZWRUeXBlIHx8ICdzdHJpbmcnO1xuICAgICAgbGV0IGV4cGVjdGVkVmFsdWU6IGFueSA9ICcnO1xuXG4gICAgICBpZiAoZXhwZWN0ZWRUeXBlID09PSAnbnVsbCcpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ29iamVjdCcgfHwgZXhwZWN0ZWRUeXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUgPT09ICdvYmplY3QnICYmIGFzc2VydGlvbi5leHBlY3RlZFZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IEpTT04uc3RyaW5naWZ5KGFzc2VydGlvbi5leHBlY3RlZFZhbHVlLCBudWxsLCAyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBleHBlY3RlZFZhbHVlID0gYXNzZXJ0aW9uLmV4cGVjdGVkVmFsdWUgfHwgJyc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IChhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSA9PT0gdHJ1ZSB8fCBhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSA9PT0gJ3RydWUnKSA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGFzc2VydGlvbi5leHBlY3RlZFZhbHVlICE9PSBudWxsICYmIGFzc2VydGlvbi5leHBlY3RlZFZhbHVlICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IFN0cmluZyhhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSlcbiAgICAgICAgICA6ICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhwZWN0ZWRWYWx1ZSA9IGFzc2VydGlvbi5leHBlY3RlZFZhbHVlICE9PSBudWxsICYmIGFzc2VydGlvbi5leHBlY3RlZFZhbHVlICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IFN0cmluZyhhc3NlcnRpb24uZXhwZWN0ZWRWYWx1ZSlcbiAgICAgICAgICA6ICcnO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAganNvblBhdGg6IFthc3NlcnRpb24uanNvblBhdGggfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICB2ZXJpZmljYXRpb25UeXBlOiBbYXNzZXJ0aW9uLnZlcmlmaWNhdGlvblR5cGUgfHwgJ2VxdWFscyddLFxuICAgICAgICBleHBlY3RlZFR5cGU6IFtleHBlY3RlZFR5cGVdLFxuICAgICAgICBleHBlY3RlZFZhbHVlOiBbZXhwZWN0ZWRWYWx1ZSwgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIHRoaXMuZXhwZWN0ZWRWYWx1ZVZhbGlkYXRvcl1dXG4gICAgICB9KTtcblxuICAgICAgZm9ybUFycmF5LnB1c2goZm9ybUdyb3VwKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmUgdG8gYXNzZXJ0aW9ucyBmb3JtIGNoYW5nZXNcbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9Bc3NlcnRpb25zRm9ybUNoYW5nZXMocXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmdldChxdWVyeUluZGV4KTtcbiAgICBpZiAoIWZvcm0pIHJldHVybjtcblxuICAgIC8vIFVuc3Vic2NyaWJlIGZyb20gcHJldmlvdXMgc3Vic2NyaXB0aW9uIGlmIGV4aXN0c1xuICAgIGlmICh0aGlzLmZvcm1TdWJzY3JpcHRpb25zLmhhcyhxdWVyeUluZGV4KSkge1xuICAgICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5nZXQocXVlcnlJbmRleCkhLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9ybUFycmF5ID0gZm9ybS5nZXQoJ2Fzc2VydGlvbnMnKSBhcyBGb3JtQXJyYXk7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gZm9ybUFycmF5LnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5lbWl0QXNzZXJ0aW9uRGF0YUZvclF1ZXJ5KHF1ZXJ5SW5kZXgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5mb3JtU3Vic2NyaXB0aW9ucy5zZXQocXVlcnlJbmRleCwgc3Vic2NyaXB0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IGFzc2VydGlvbiBkYXRhIGZvciBhIHNwZWNpZmljIHF1ZXJ5XG4gICAqL1xuICBwcml2YXRlIGVtaXRBc3NlcnRpb25EYXRhRm9yUXVlcnkocXVlcnlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuYXNzZXJ0aW9uc0Zvcm1zLmdldChxdWVyeUluZGV4KTtcbiAgICBpZiAoIWZvcm0pIHJldHVybjtcblxuICAgIGNvbnN0IGZvcm1BcnJheSA9IGZvcm0uZ2V0KCdhc3NlcnRpb25zJykgYXMgRm9ybUFycmF5O1xuICAgIGNvbnN0IGFzc2VydGlvbkRhdGEgPSBmb3JtQXJyYXkuY29udHJvbHMubWFwKChjb250cm9sKSA9PiB7XG4gICAgICBpZiAoIShjb250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwKSkgcmV0dXJuIG51bGw7XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHZhbHVlLmV4cGVjdGVkVHlwZSB8fCAnc3RyaW5nJztcbiAgICAgIGxldCBleHBlY3RlZFZhbHVlOiBhbnkgPSB2YWx1ZS5leHBlY3RlZFZhbHVlO1xuXG4gICAgICAvLyBQYXJzZSBleHBlY3RlZFZhbHVlIGJhc2VkIG9uIHR5cGVcbiAgICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICdudWxsJykge1xuICAgICAgICBleHBlY3RlZFZhbHVlID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICBleHBlY3RlZFZhbHVlID0gZXhwZWN0ZWRWYWx1ZSAhPT0gJycgPyBOdW1iZXIoZXhwZWN0ZWRWYWx1ZSkgOiBudWxsO1xuICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICBleHBlY3RlZFZhbHVlID0gKGV4cGVjdGVkVmFsdWUgPT09ICd0cnVlJyB8fCBleHBlY3RlZFZhbHVlID09PSB0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnYXJyYXknIHx8IGV4cGVjdGVkVHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBleHBlY3RlZFZhbHVlID09PSAnc3RyaW5nJyAmJiBleHBlY3RlZFZhbHVlLnRyaW0oKSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBleHBlY3RlZFZhbHVlID0gSlNPTi5wYXJzZShleHBlY3RlZFZhbHVlKTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBLZWVwIGFzIHN0cmluZyBpZiBwYXJzaW5nIGZhaWxzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHBlY3RlZFZhbHVlID0gU3RyaW5nKGV4cGVjdGVkVmFsdWUgfHwgJycpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBqc29uUGF0aDogKHZhbHVlLmpzb25QYXRoIHx8ICcnKS50cmltKCksXG4gICAgICAgIHZlcmlmaWNhdGlvblR5cGU6IHZhbHVlLnZlcmlmaWNhdGlvblR5cGUgfHwgJ2VxdWFscycsXG4gICAgICAgIGV4cGVjdGVkVHlwZTogZXhwZWN0ZWRUeXBlLFxuICAgICAgICBleHBlY3RlZFZhbHVlOiBleHBlY3RlZFZhbHVlXG4gICAgICB9O1xuICAgIH0pLmZpbHRlcihpdGVtID0+IGl0ZW0gIT09IG51bGwgJiYgaXRlbSEuanNvblBhdGgpIGFzIGFueVtdO1xuXG4gICAgLy8gVXBkYXRlIHF1ZXJ5J3MgYXNzZXJ0aW9uIGRhdGFcbiAgICBpZiAodGhpcy5xdWVyaWVzW3F1ZXJ5SW5kZXhdKSB7XG4gICAgICB0aGlzLnF1ZXJpZXNbcXVlcnlJbmRleF0uYXNzZXJ0aW9uRGF0YSA9IGFzc2VydGlvbkRhdGE7XG4gICAgfVxuXG4gICAgLy8gRW1pdCB0byBwYXJlbnRcbiAgICB0aGlzLmFzc2VydGlvbkRhdGFDaGFuZ2UuZW1pdCh7XG4gICAgICBxdWVyeUluZGV4OiBxdWVyeUluZGV4LFxuICAgICAgYXNzZXJ0aW9uRGF0YTogYXNzZXJ0aW9uRGF0YVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyBhc3NlcnRpb25cbiAgICovXG4gIGFkZEFzc2VydGlvbigpOiB2b2lkIHtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEFzc2VydGlvbnNGb3JtQXJyYXkoKTtcbiAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGpzb25QYXRoOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmVyaWZpY2F0aW9uVHlwZTogWydlcXVhbHMnXSxcbiAgICAgIGV4cGVjdGVkVHlwZTogW3RoaXMuZGVmYXVsdEV4cGVjdGVkVHlwZV0sXG4gICAgICBleHBlY3RlZFZhbHVlOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCB0aGlzLmV4cGVjdGVkVmFsdWVWYWxpZGF0b3JdXVxuICAgIH0pO1xuICAgIGZvcm1BcnJheS5wdXNoKGZvcm1Hcm91cCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIGlmICh0aGlzLmFzc2VydGlvbnNUYWJsZSkge1xuICAgICAgdGhpcy5hc3NlcnRpb25zVGFibGUucmVuZGVyUm93cygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYW4gYXNzZXJ0aW9uXG4gICAqL1xuICByZW1vdmVBc3NlcnRpb24oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGZvcm1BcnJheSA9IHRoaXMuZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpO1xuICAgIGZvcm1BcnJheS5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIGlmICh0aGlzLmFzc2VydGlvbnNUYWJsZSkge1xuICAgICAgdGhpcy5hc3NlcnRpb25zVGFibGUucmVuZGVyUm93cygpO1xuICAgIH1cbiAgICB0aGlzLmVtaXRBc3NlcnRpb25EYXRhRm9yUXVlcnkodGhpcy5zZWxlY3RlZFF1ZXJ5SW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBmb3JtIGNvbnRyb2wgYXQgc3BlY2lmaWMgaW5kZXhcbiAgICovXG4gIGdldEZvcm1Db250cm9sQXQoaW5kZXg6IG51bWJlciwgY29udHJvbE5hbWU6IHN0cmluZyk6IEFic3RyYWN0Q29udHJvbCB8IG51bGwge1xuICAgIGNvbnN0IGZvcm1BcnJheSA9IHRoaXMuZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpO1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZm9ybUFycmF5Lmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZm9ybUdyb3VwID0gZm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgcmV0dXJuIGZvcm1Hcm91cD8uZ2V0KGNvbnRyb2xOYW1lKSB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBleHBlY3RlZCB0eXBlIGZvciBhbiBhc3NlcnRpb25cbiAgICovXG4gIGdldEV4cGVjdGVkVHlwZShpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEFzc2VydGlvbnNGb3JtQXJyYXkoKTtcbiAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZvcm1BcnJheS5sZW5ndGgpIHJldHVybiAnc3RyaW5nJztcbiAgICBjb25zdCBmb3JtR3JvdXAgPSBmb3JtQXJyYXkuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICByZXR1cm4gZm9ybUdyb3VwPy5nZXQoJ2V4cGVjdGVkVHlwZScpPy52YWx1ZSB8fCAnc3RyaW5nJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwZWN0ZWQgdmFsdWUgcGxhY2Vob2xkZXJcbiAgICovXG4gIGdldEV4cGVjdGVkVmFsdWVQbGFjZWhvbGRlcihpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShpbmRleCk7XG4gICAgc3dpdGNoIChleHBlY3RlZFR5cGUpIHtcbiAgICAgIGNhc2UgJ3N0cmluZyc6IHJldHVybiAnRW50ZXIgdmFsdWUnO1xuICAgICAgY2FzZSAnYXJyYXknOiByZXR1cm4gJ0VudGVyIEpTT04gYXJyYXknO1xuICAgICAgY2FzZSAnb2JqZWN0JzogcmV0dXJuICdFbnRlciBKU09OIG9iamVjdCc7XG4gICAgICBjYXNlICdudWxsJzogcmV0dXJuICdObyB2YWx1ZSByZXF1aXJlZCc7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gJ0VudGVyIHZhbHVlJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGV4cGVjdGVkIHR5cGUgY2hhbmdlXG4gICAqL1xuICBvbkV4cGVjdGVkVHlwZUNoYW5nZShpbmRleDogbnVtYmVyLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZm9ybUFycmF5ID0gdGhpcy5nZXRBc3NlcnRpb25zRm9ybUFycmF5KCk7XG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmb3JtQXJyYXkubGVuZ3RoKSByZXR1cm47XG5cbiAgICBjb25zdCBmb3JtR3JvdXAgPSBmb3JtQXJyYXkuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICBjb25zdCBleHBlY3RlZFZhbHVlQ29udHJvbCA9IGZvcm1Hcm91cC5nZXQoJ2V4cGVjdGVkVmFsdWUnKTtcbiAgICBpZiAoIWV4cGVjdGVkVmFsdWVDb250cm9sKSByZXR1cm47XG5cbiAgICBsZXQgbmV3VmFsdWU6IGFueSA9ICcnO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBuZXdWYWx1ZSA9ICd0cnVlJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnbnVsbCcpIHtcbiAgICAgIG5ld1ZhbHVlID0gbnVsbDtcbiAgICB9XG5cbiAgICBleHBlY3RlZFZhbHVlQ29udHJvbC5jbGVhclZhbGlkYXRvcnMoKTtcbiAgICBleHBlY3RlZFZhbHVlQ29udHJvbC5zZXRWYWx1ZShuZXdWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgaWYgKHZhbHVlID09PSAnbnVsbCcpIHtcbiAgICAgIGV4cGVjdGVkVmFsdWVDb250cm9sLnNldFZhbGlkYXRvcnMoW3RoaXMuZXhwZWN0ZWRWYWx1ZVZhbGlkYXRvcl0pO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdvYmplY3QnIHx8IHZhbHVlID09PSAnYXJyYXknKSB7XG4gICAgICBleHBlY3RlZFZhbHVlQ29udHJvbC5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnJlcXVpcmVkXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkVmFsdWVDb250cm9sLnNldFZhbGlkYXRvcnMoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIHRoaXMuZXhwZWN0ZWRWYWx1ZVZhbGlkYXRvcl0pO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgZXhwZWN0ZWRWYWx1ZUNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSwgMTAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBlY3RlZCB2YWx1ZSB2YWxpZGF0b3JcbiAgICovXG4gIGV4cGVjdGVkVmFsdWVWYWxpZGF0b3IgPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB8IG51bGwgPT4ge1xuICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGNvbnRyb2wucGFyZW50Py5nZXQoJ2V4cGVjdGVkVHlwZScpPy52YWx1ZTtcbiAgICBpZiAoIWV4cGVjdGVkVHlwZSB8fCBleHBlY3RlZFR5cGUgPT09ICdudWxsJykgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCAmJiB2YWx1ZSAhPT0gZmFsc2UpIHJldHVybiBudWxsO1xuXG4gICAgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGlmIChpc05hTihOdW1iZXIodmFsdWUpKSkge1xuICAgICAgICByZXR1cm4geyBpbnZhbGlkVHlwZTogdHJ1ZSwgbWVzc2FnZTogJ0ludmFsaWQgbnVtYmVyIHZhbHVlJyB9O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gJ3RydWUnICYmIHZhbHVlICE9PSAnZmFsc2UnICYmIHZhbHVlICE9PSB0cnVlICYmIHZhbHVlICE9PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4geyBpbnZhbGlkVHlwZTogdHJ1ZSwgbWVzc2FnZTogJ0ludmFsaWQgYm9vbGVhbiB2YWx1ZScgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUudHJpbSgpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZSh2YWx1ZSk7XG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHBhcnNlZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGludmFsaWRUeXBlOiB0cnVlLCBtZXNzYWdlOiAnVmFsdWUgbXVzdCBiZSBhIHZhbGlkIEpTT04gYXJyYXknIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIHsgaW52YWxpZFR5cGU6IHRydWUsIG1lc3NhZ2U6ICdJbnZhbGlkIEFycmF5IHZhbHVlIC0gbXVzdCBiZSB2YWxpZCBKU09OJyB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkgJiYgdmFsdWUudHJpbSgpICE9PSAne30nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZSh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHBhcnNlZCA9PT0gbnVsbCB8fCB0eXBlb2YgcGFyc2VkICE9PSAnb2JqZWN0JyB8fCBBcnJheS5pc0FycmF5KHBhcnNlZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGludmFsaWRUeXBlOiB0cnVlLCBtZXNzYWdlOiAnVmFsdWUgbXVzdCBiZSBhIHZhbGlkIEpTT04gb2JqZWN0JyB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJldHVybiB7IGludmFsaWRUeXBlOiB0cnVlLCBtZXNzYWdlOiAnSW52YWxpZCBPYmplY3QgdmFsdWUgLSBtdXN0IGJlIHZhbGlkIEpTT04nIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICAvKipcbiAgICogR2V0IGFzc2VydGlvbnMgZGF0YSBzb3VyY2UgZm9yIHRhYmxlXG4gICAqL1xuICBnZXQgYXNzZXJ0aW9uc0RhdGFTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpLmNvbnRyb2xzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGJ5IGZ1bmN0aW9uIGZvciB0YWJsZSByb3dzXG4gICAqL1xuICB0cmFja0J5SW5kZXgoaW5kZXg6IG51bWJlcik6IGFueSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgLy8gQ2xlYW4gdXAgc3Vic2NyaXB0aW9uc1xuICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWIgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgIHRoaXMuZm9ybVN1YnNjcmlwdGlvbnMuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGFkdmFuY2VkIHNldHRpbmdzIHZhcmlhYmxlcyBmb3IgZGF0YWJhc2Ugc3RlcHMuXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVBZHZhbmNlZFNldHRpbmdzKCk6IHZvaWQge1xuICAgIHRoaXMuYWR2YW5jZWRTZXR0aW5nc1ZhcmlhYmxlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2lzU3RlcE9wdGlvbmFsJyxcbiAgICAgICAgbGFiZWw6IFwiRG9uJ3QgZmFpbCB0aGUgdGVzdCBpZiB0aGlzIHN0ZXAgZmFpbHMuXCIsXG4gICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgdHlwZTogJ2Jvb2xlYW4nXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkU2tpcCcsXG4gICAgICAgIGxhYmVsOiAnU2tpcCB0aGlzIHN0ZXAgZHVyaW5nIGV4ZWN1dGlvbi4nLFxuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdib29sZWFuJ1xuICAgICAgfVxuICAgIF07XG5cbiAgICB0aGlzLmJ1aWxkQWR2YW5jZWRWYXJpYWJsZXNGb3JtKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgcmVhY3RpdmUgZm9ybSBmb3IgYWR2YW5jZWQgc2V0dGluZ3MgdmFyaWFibGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEFkdmFuY2VkVmFyaWFibGVzRm9ybSgpOiB2b2lkIHtcbiAgICB3aGlsZSAodGhpcy5hZHZhbmNlZFZhcmlhYmxlc0Zvcm0ubGVuZ3RoICE9PSAwKSB7XG4gICAgICB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5yZW1vdmVBdCgwKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMuZm9yRWFjaCh2YXJpYWJsZSA9PiB7XG4gICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPVxuICAgICAgICB2YXJpYWJsZS50eXBlID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIHZhcmlhYmxlLnZhbHVlID09PSAnYm9vbGVhbidcbiAgICAgICAgICA/ICh2YXJpYWJsZS52YWx1ZSA9PT0gdHJ1ZSB8fCB2YXJpYWJsZS52YWx1ZSA9PT0gJ3RydWUnIHx8IHZhcmlhYmxlLnZhbHVlID09PSAxKVxuICAgICAgICAgIDogKHZhcmlhYmxlLnZhbHVlIHx8ICcnKTtcblxuICAgICAgY29uc3QgdmFyaWFibGVHcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICBuYW1lOiBbdmFyaWFibGUubmFtZV0sXG4gICAgICAgIHZhbHVlOiBbZGVmYXVsdFZhbHVlXSxcbiAgICAgICAgdHlwZTogW3ZhcmlhYmxlLnR5cGUgfHwgJ3N0cmluZyddLFxuICAgICAgICBsYWJlbDogW3ZhcmlhYmxlLmxhYmVsIHx8ICcnXVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuYWR2YW5jZWRWYXJpYWJsZXNGb3JtLnB1c2godmFyaWFibGVHcm91cCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGFkdmFuY2VkIGJvb2xlYW4gY2hhbmdlcyBhbmQga2VlcCBkYXRhL2Zvcm0gaW4gc3luYy5cbiAgICovXG4gIG9uQWR2YW5jZWRWYXJpYWJsZUJvb2xlYW5DaGFuZ2UodmFyaWFibGVOYW1lOiBzdHJpbmcsIHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgdmFyaWFibGUgPSB0aGlzLmFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXMuZmluZCh2ID0+IHYubmFtZSA9PT0gdmFyaWFibGVOYW1lKTtcbiAgICBpZiAodmFyaWFibGUpIHtcbiAgICAgIHZhcmlhYmxlLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgdmFyaWFibGVJbmRleCA9IHRoaXMuYWR2YW5jZWRWYXJpYWJsZXNGb3JtLmNvbnRyb2xzLmZpbmRJbmRleChcbiAgICAgIGNvbnRyb2wgPT4gY29udHJvbC5nZXQoJ25hbWUnKT8udmFsdWUgPT09IHZhcmlhYmxlTmFtZVxuICAgICk7XG4gICAgaWYgKHZhcmlhYmxlSW5kZXggIT09IC0xKSB7XG4gICAgICB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5hdCh2YXJpYWJsZUluZGV4KS5nZXQoJ3ZhbHVlJyk/LnNldFZhbHVlKHZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBub24tYm9vbGVhbiBhZHZhbmNlZCB2YXJpYWJsZSBjaGFuZ2VzIChyZXNlcnZlZCBmb3IgZnV0dXJlIHVzZSkuXG4gICAqL1xuICBvbkFkdmFuY2VkVmFyaWFibGVWYWx1ZUNoYW5nZSh2YXJpYWJsZU5hbWU6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IHZhcmlhYmxlID0gdGhpcy5hZHZhbmNlZFNldHRpbmdzVmFyaWFibGVzLmZpbmQodiA9PiB2Lm5hbWUgPT09IHZhcmlhYmxlTmFtZSk7XG4gICAgaWYgKHZhcmlhYmxlKSB7XG4gICAgICB2YXJpYWJsZS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhcmlhYmxlSW5kZXggPSB0aGlzLmFkdmFuY2VkVmFyaWFibGVzRm9ybS5jb250cm9scy5maW5kSW5kZXgoXG4gICAgICBjb250cm9sID0+IGNvbnRyb2wuZ2V0KCduYW1lJyk/LnZhbHVlID09PSB2YXJpYWJsZU5hbWVcbiAgICApO1xuICAgIGlmICh2YXJpYWJsZUluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5hZHZhbmNlZFZhcmlhYmxlc0Zvcm0uYXQodmFyaWFibGVJbmRleCkuZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtaC1mdWxsIGNxYS1iZy13aGl0ZSBjcWEtcHgtNCBjcWEtcHktMlwiPlxuICA8IS0tIEhlYWRlciAtLT5cbiAgPGgyIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWJsYWNrLTEwMCBjcWEtbWItNFwiPlxuICAgIHt7IGVkaXRNb2RlID8gJ1VwZGF0ZSBEYXRhYmFzZSBUZXN0IFN0ZXAnIDogJ0NyZWF0ZSBEYXRhYmFzZSBUZXN0IFN0ZXAnIH19XG4gIDwvaDI+XG5cbiAgPCEtLSBFbnYgYmFubmVyIOKAlCBzdXJmYWNlcyB3aGljaCBlbnZpcm9ubWVudCBzY29wZXMgdGhlIERCIENvbmZpZyArIE5vcm1hbCBFbnYuIC0tPlxuICA8ZGl2ICpuZ0lmPVwidGVzdENhc2VFbnZpcm9ubWVudE5hbWVcIlxuICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLW1iLTMgY3FhLXB4LTMgY3FhLXB5LTIgY3FhLXJvdW5kZWQtbWQgY3FhLXRleHQteHMgY3FhLXRleHQtZ3JheS03MDAgY3FhLWJnLWdyYXktNTAgY3FhLWJvcmRlciBjcWEtYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgVXNpbmcgPHN0cm9uZyBjbGFzcz1cImNxYS1mb250LXNlbWlib2xkXCI+e3sgdGVzdENhc2VFbnZpcm9ubWVudE5hbWUgfX0gRW52aXJvbm1lbnQ8L3N0cm9uZz5cbiAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LWdyYXktNTAwXCI+wrc8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1ncmF5LTUwMFwiPkVudmlyb25tZW50IHZhcmlhYmxlcyBhbmQgREIgY29uZmlncyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGlzIGVudmlyb25tZW50Ljwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBFbnZpcm9ubWVudCBTZWN0aW9uIChzZXBhcmF0b3IgbGluZSBvbmx5IG9uIGJvdHRvbSkgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtdy1mdWxsIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWdhcC0xLjUgY3FhLXBiLVswLjVyZW1dIGNxYS1tYi00IGNxYS1ib3JkZXItMCBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1nYXAtNCBjcWEtaXRlbXMtc3RhcnRcIj5cbiAgICAgIDwhLS0gREIgQ29uZmlnIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMS41XCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtYmxvY2tcIj5cbiAgICAgICAgICBEQiBDb25maWcgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1yZWQtNTAwXCI+Kjwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1taW4tdy0wXCI+XG4gICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCBbZm9ybV09XCJkYXRhYmFzZUZvcm1cIiBbY29uZmlnXT1cImRiQ29uZmlnU2VsZWN0Q29uZmlnXCI+XG4gICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgREIgY29uZmlncyBhdHRhY2hlZCB0byB0aGUgYWN0aXZlIGVudmlyb25tZW50LlxuICAgICAgICA8L3A+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBOb3JtYWwgRW52aXJvbm1lbnQg4oCUIGhpZGRlbiB1bmRlciBUaWVyIDEgKHRlc3RDYXNlLmVudmlyb25tZW50SWQgc2V0KTtcbiAgICAgICAgICAgdGhlIGVudiBiYW5uZXIgYWJvdmUgYWxyZWFkeSBuYW1lcyB0aGUgYWN0aXZlIGVudi4gLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWhpZGVFbnZpcm9ubWVudE5hbWVGaWVsZFwiIGNsYXNzPVwiY3FhLWZsZXgtMSBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjVcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LWdyYXktNzAwIGNxYS1ibG9ja1wiPlxuICAgICAgICAgIE5vcm1hbCBFbnZpcm9ubWVudFxuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLW1pbi13LTBcIj5cbiAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImRhdGFiYXNlRm9ybVwiIFtjb25maWddPVwibm9ybWFsRW52U2VsZWN0Q29uZmlnXCI+XG4gICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCAqbmdJZj1cImVudmlyb25tZW50TGVnYWN5RGVwcmVjYXRpb25NZXNzYWdlXCJcbiAgICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtaXRhbGljIGNxYS10ZXh0LWFtYmVyLTYwMCBjcWEtbS0wXCJcbiAgICAgICAgICAgW2lubmVySFRNTF09XCJlbnZpcm9ubWVudExlZ2FjeURlcHJlY2F0aW9uTWVzc2FnZVwiPjwvcD5cbiAgICAgICAgPHAgKm5nSWY9XCIhZW52aXJvbm1lbnRMZWdhY3lEZXByZWNhdGlvbk1lc3NhZ2VcIiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgVXNlcyBOb3JtYWwgZW52aXJvbm1lbnRzIGZyb20gRW52aXJvbm1lbnRzLlxuICAgICAgICA8L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWp1c3RpZnktZW5kIGNxYS1tdC0yXCI+XG4gICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgdGV4dD1cIlJ1biBRdWVyeVwiIChjbGlja2VkKT1cIm9uUnVuUXVlcnkoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIhZGF0YWJhc2VGb3JtLmdldCgnZGJDb25maWdJZCcpPy52YWx1ZSB8fCBpc0xvYWRpbmdcIlxuICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJyFjcWEtYmctWyMzRjQzRUVdIGNxYS10ZXh0LVsjRkJGQ0ZGXSBjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1wdC1bMTBweF0gIWNxYS1wYi1bMTBweF0gIWNxYS1wbC1bMjRweF0gIWNxYS1wci1bMjRweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgY3FhLW1pbi1oLVszN3B4XSBob3ZlcjohY3FhLWJnLVsjMUIxRkVCXSBjcWEtZmxleC1zaHJpbmstMCdcIj5cbiAgICAgIDwvY3FhLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNYWluIENvbnRlbnQ6IFR3byBDb2x1bW4gTGF5b3V0IC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWdhcC1bMTJweF0gY3FhLWZsZXgtMSBjcWEtb3ZlcmZsb3ctaGlkZGVuIGNxYS1tYi02XCI+XG4gICAgPCEtLSBMZWZ0IFBhbmVsOiBRdWVyeSBMaXN0IC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY3FhLXctWzE3NXB4XSBjcWEtbWluLXctWzE3NXB4XSBjcWEtZmxleC1zaHJpbmstMCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWJvcmRlci0wIGNxYS1ib3JkZXItciBjcWEtYm9yZGVyLXItWzFweF0gY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjRTBFMEUwXSBjcWEtYmctWyNGQUZBRkFdIGNxYS1vdmVyZmxvdy1oaWRkZW5cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLXAtMlwiPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBxdWVyeSBvZiBxdWVyaWVzOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktYmV0d2VlbiBjcWEtZ2FwLVsxMHB4XSBjcWEtdy1mdWxsIGNxYS1wdC1bMTRweF0gY3FhLXBiLVsxNHB4XSBjcWEtcGwtWzE2cHhdIGNxYS1wci1bMTZweF0gY3FhLXJvdW5kZWQtWzhweF0gY3FhLWN1cnNvci1wb2ludGVyIGNxYS1tYi0xXCJcbiAgICAgICAgICBbY2xhc3MuY3FhLWJnLWJsdWUtNTBdPVwic2VsZWN0ZWRRdWVyeUluZGV4ID09PSBpXCJcbiAgICAgICAgICBbY2xhc3MuY3FhLWJvcmRlcl09XCJzZWxlY3RlZFF1ZXJ5SW5kZXggPT09IGlcIlxuICAgICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNTAwXT1cInNlbGVjdGVkUXVlcnlJbmRleCA9PT0gaVwiXG4gICAgICAgICAgW2NsYXNzLmNxYS1iZy1ncmV5LTQwMF09XCJzZWxlY3RlZFF1ZXJ5SW5kZXggIT09IGlcIlxuICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdFF1ZXJ5KGkpXCJcbiAgICAgICAgICBzdHlsZT1cImhlaWdodDogNDlweDsgbWluLWhlaWdodDogNDlweDtcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTkwMFwiPlF1ZXJ5IHt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgIDxjcWEtYmFkZ2UgKm5nSWY9XCJxdWVyeS5zdGF0dXNcIlxuICAgICAgICAgICAgW2xhYmVsXT1cInF1ZXJ5LnN0YXR1cyA9PT0gJ3Bhc3NlZCcgPyAnUGFzc2VkJyA6IHF1ZXJ5LnN0YXR1cyA9PT0gJ2ZhaWxlZCcgPyAnRmFpbGVkJyA6ICdQZW5kaW5nJ1wiXG4gICAgICAgICAgICBbdmFyaWFudF09XCJxdWVyeS5zdGF0dXMgPT09ICdwYXNzZWQnID8gJ3N1Y2Nlc3MnIDogcXVlcnkuc3RhdHVzID09PSAnZmFpbGVkJyA/ICdlcnJvcicgOiAnZGVmYXVsdCdcIlxuICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCI+XG4gICAgICAgICAgPC9jcWEtYmFkZ2U+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFJpZ2h0IFBhbmVsOiBRdWVyeSBFZGl0b3IgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1vdmVyZmxvdy1hdXRvXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXgtMSBjcWEtZmxleCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItZ3JheS0yMDAgY3FhLXJvdW5kZWQtbGcgY3FhLWdhcC1bMTBweF0gY3FhLW1iLTRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLVs2cHhdXCIgc3R5bGU9XCJ3aWR0aDogNTAlO1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwIGNxYS10ZXh0LVsxNHB4XVwiPlF1ZXJ5ICYgU3RvcmUgUmVzcG9uc2U8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsjRUY0NDQ0XSBjcWEtbWwtMC41XCI+Kjwvc3Bhbj48L2gzPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1qdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgIDwhLS0gU1FMIFF1ZXJ5IFRleHRhcmVhIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1taW4tdy0wIGNxYS13LWZ1bGwgY3FhLXJvdW5kZWQtbWQgY3FhLWJnLWdyYXktNTAvNTBcIj5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20tdGV4dGFyZWEgW3BsYWNlaG9sZGVyXT1cIidFbnRlciB5b3VyIFNRTCBxdWVyeSBoZXJlLi4uJ1wiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpPy5nZXQoJ3F1ZXJ5Jyk/LnZhbHVlIHx8ICcnXCIgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgW3Jvd3NdPVwiOFwiXG4gICAgICAgICAgICAgICAgW3RleHRhcmVhSW5saW5lU3R5bGVdPVwiJ3BhZGRpbmc6IDFyZW07J1wiXG4gICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cImdldEN1cnJlbnRRdWVyeUZvcm1Hcm91cCgpPy5nZXQoJ3F1ZXJ5Jyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgPC9jcWEtY3VzdG9tLXRleHRhcmVhPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtWzEwcHhdIGNxYS1tYi1bOHB4XVwiPlxuXG5cbiAgICAgICAgICA8IS0tIFZhcmlhYmxlIElucHV0IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZ2FwLTRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtbWItMS41IGNxYS1ibG9jayBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtc2VtaWJvbGRcIj5cbiAgICAgICAgICAgICAgICBWYXJpYWJsZTxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWyNFRjQ0NDRdIGNxYS1tbC0wLjVcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiJ1ZhcmlhYmxlIG5hbWUnXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0Q3VycmVudFF1ZXJ5Rm9ybUdyb3VwKCk/LmdldCgndmFyaWFibGUnKT8udmFsdWUgfHwgJydcIiBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJnZXRDdXJyZW50UXVlcnlGb3JtR3JvdXAoKT8uZ2V0KCd2YXJpYWJsZScpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtdGV4dC1ncmF5LTUwMCBjcWEtbXQtMVwiPlxuICAgICAgICAgICAgICAgIFVzZSBsZXR0ZXJzLCBudW1iZXJzLCB1bmRlcnNjb3JlLiBObyBzcGFjZXMuIFVuaXF1ZSBwZXIgc3RlcC4gQ2FzZSBzZW5zaXRpdmUuXG4gICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gQWN0aW9uIEJ1dHRvbnMgKHBpbm5lZCB0byBib3R0b20pIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtbXQtYXV0b1wiPlxuICAgICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgdGV4dD1cIkFkZCBRdWVyeVwiIGljb249XCJhZGRcIiAoY2xpY2tlZCk9XCJhZGROZXdRdWVyeSgpXCJcbiAgICAgICAgICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtYmctd2hpdGUgIWNxYS1ib3JkZXItWyM0MTQxNDZdIGNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjNDE0MTQ2XSBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1weS1bMTBweF0gIWNxYS1weC1bMTBweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgaG92ZXI6IWNxYS1ib3JkZXItWyM0MTQxNDZdIGhvdmVyOmNxYS1iZy1ncmF5LTUwJ1wiXG4gICAgICAgICAgICAgIFtpY29uQ29sb3JdPVwiJyM0MTQxNDYnXCI+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8Y3FhLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgdmFyaWFudD1cInRleHRcIlxuICAgICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS1taW4tdy1bNDBweF0gY3FhLXctMTAgY3FhLWgtOSBjcWEtcm91bmRlZCBjcWEtYmctZ3JheS0xMDAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgaG92ZXI6Y3FhLWJnLWdyYXktMjAwIGNxYS1wLTAnXCJcbiAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiJ0RlbGV0ZSBxdWVyeSdcIiAoY2xpY2tlZCk9XCJkZWxldGVRdWVyeUJ5SWQoZ2V0Q3VycmVudFF1ZXJ5KCk/LmlkIHx8ICcnKVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJxdWVyaWVzLmxlbmd0aCA8PSAxXCIgW2F0dHIuYXJpYS1sYWJlbF09XCInRGVsZXRlIHF1ZXJ5J1wiPlxuICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiY3FhLWZsZXgtc2hyaW5rLTBcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCJcbiAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk0xMC42NjYzIDZWMTIuNjY2N0g1LjMzMzAxVjZIMTAuNjY2M1pNOS42NjYzNCAySDYuMzMzMDFMNS42NjYzNCAyLjY2NjY3SDMuMzMzMDFWNEgxMi42NjYzVjIuNjY2NjdIMTAuMzMzTDkuNjY2MzQgMlpNMTEuOTk5NyA0LjY2NjY3SDMuOTk5NjdWMTIuNjY2N0MzLjk5OTY3IDEzLjQgNC41OTk2NyAxNCA1LjMzMzAxIDE0SDEwLjY2NjNDMTEuMzk5NyAxNCAxMS45OTk3IDEzLjQgMTEuOTk5NyAxMi42NjY3VjQuNjY2NjdaXCJcbiAgICAgICAgICAgICAgICAgIGZpbGw9XCIjNkI3MjgwXCIgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgdGV4dD1cIlJ1blwiIGljb249XCJwbGF5X2Fycm93XCIgKGNsaWNrZWQpPVwib25SdW5RdWVyeSgpXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFnZXRDdXJyZW50UXVlcnlGb3JtR3JvdXAoKT8uZ2V0KCdxdWVyeScpPy52YWx1ZSB8fCAhZGF0YWJhc2VGb3JtLmdldCgnZGJDb25maWdJZCcpPy52YWx1ZSB8fCBpc0xvYWRpbmdcIlxuICAgICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJyFjcWEtYmctWyMzRjQzRUVdIGNxYS10ZXh0LVsjRkJGQ0ZGXSBjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtd2hpdGVzcGFjZS1ub3dyYXAgIWNxYS1wdC1bMTBweF0gIWNxYS1wYi1bMTBweF0gIWNxYS1wbC1bMTZweF0gIWNxYS1wci1bMjRweF0gIWNxYS1nYXAtWzhweF0gY3FhLXJvdW5kZWQtbGcgY3FhLW1pbi1oLVszOHB4XSBob3ZlcjohY3FhLWJnLVsjMUIxRkVCXSAhY3FhLWJvcmRlci1ub25lJ1wiXG4gICAgICAgICAgICAgIFtpY29uQ29sb3JdPVwiJyNGQkZDRkYnXCI+XG4gICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8IS0tIFJlc3VsdHMgU2VjdGlvbiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWJvcmRlciBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1yb3VuZGVkLWxnIGNxYS1tYi02XCI+XG4gICAgICAgIDwhLS0gVGFicyAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDAgY3FhLWJnLWdyYXktNTBcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ291dHB1dCdcIiBbY2xhc3MuY3FhLWJvcmRlci1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ291dHB1dCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnb3V0cHV0J1wiXG4gICAgICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci10cmFuc3BhcmVudF09XCJzZWxlY3RlZFRhYiAhPT0gJ291dHB1dCdcIiAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ291dHB1dCcpXCI+XG4gICAgICAgICAgICBPdXRwdXRcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ3ZlcmlmaWNhdGlvbidcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICd2ZXJpZmljYXRpb24nXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ncmF5LTYwMF09XCJzZWxlY3RlZFRhYiAhPT0gJ3ZlcmlmaWNhdGlvbidcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItdHJhbnNwYXJlbnRdPVwic2VsZWN0ZWRUYWIgIT09ICd2ZXJpZmljYXRpb24nXCIgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCd2ZXJpZmljYXRpb24nKVwiPlxuICAgICAgICAgICAgVmVyaWZpY2F0aW9uXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10cmFuc2l0aW9uLWNvbG9ycyBjcWEtYm9yZGVyLWItMlwiXG4gICAgICAgICAgICBbY2xhc3MuY3FhLXRleHQtYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdhZHZhbmNlZCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdhZHZhbmNlZCdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnYWR2YW5jZWQnXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLXRyYW5zcGFyZW50XT1cInNlbGVjdGVkVGFiICE9PSAnYWR2YW5jZWQnXCIgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCdhZHZhbmNlZCcpXCI+XG4gICAgICAgICAgICBBZHZhbmNlZFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFRhYiBDb250ZW50IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXAtNFwiPlxuICAgICAgICAgIDwhLS0gT3V0cHV0IFRhYiAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdvdXRwdXQnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1tYi0zXCI+XG4gICAgICAgICAgICAgIDxoNCBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwXCI+UXVlcnkgUmVzdWx0czwvaDQ+XG4gICAgICAgICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJ0ZXh0XCIgdGV4dD1cIkNvcHlcIiBpY29uPVwiY29udGVudF9jb3B5XCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtdGV4dC1ibHVlLTYwMCdcIlxuICAgICAgICAgICAgICAgIChjbGlja2VkKT1cIm9uQ29weVJlc3VsdHMoKVwiPlxuICAgICAgICAgICAgICA8L2NxYS1idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBSZXN1bHRzIFRhYmxlIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImdldEN1cnJlbnRRdWVyeVJlc3VsdCgpLmxlbmd0aCA+IDBcIiBjbGFzcz1cImNxYS1vdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwiY3FhLXctZnVsbCBjcWEtYm9yZGVyLWNvbGxhcHNlXCI+XG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwiY3FhLWJnLWdyYXktNTAgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBrZXkgb2YgZ2V0VGFibGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtbGVmdCBjcWEtdGV4dC14cyBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtdXBwZXJjYXNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sga2V5IH19XG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgZ2V0Q3VycmVudFF1ZXJ5UmVzdWx0KClcIiBjbGFzcz1cImNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwIGhvdmVyOmNxYS1iZy1ncmF5LTUwXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQga2V5IG9mIGdldFRhYmxlQ29sdW1ucygpXCIgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtdGV4dC1ncmF5LTkwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IHJvd1trZXldIH19XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImdldEN1cnJlbnRRdWVyeVJlc3VsdCgpLmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXRleHQtY2VudGVyIGNxYS1weS04IGNxYS10ZXh0LWdyYXktNDAwIGNxYS10ZXh0LXNtXCI+XG4gICAgICAgICAgICAgIE5vIHJlc3VsdHMgeWV0LiBSdW4gYSBxdWVyeSB0byBzZWUgcmVzdWx0cy5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWZXJpZmljYXRpb24gVGFiIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3ZlcmlmaWNhdGlvbidcIiBjbGFzcz1cImFzc2VydGlvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8IS0tIEhlYWRlciBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFzc2VydGlvbnMtaGVhZGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGVudFwiPlxuICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImhlYWRlci10aXRsZVwiPkFzc2VydGlvbnM8L2gzPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiaGVhZGVyLXN1YnRpdGxlXCI+VXNlIEpTT05QYXRoIHRvIHRhcmdldCB2YWx1ZXMgaW4gdGhlIHF1ZXJ5IG91dHB1dC48L3A+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8YnV0dG9uIFxuICAgICAgICAgICAgICAgIG1hdC1zdHJva2VkLWJ1dHRvbiBcbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIiBcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFkZC1hc3NlcnRpb24tYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkQXNzZXJ0aW9uKClcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBBZGQgQXNzZXJ0aW9uXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gVGFibGUgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxmb3JtICpuZ0lmPVwiZ2V0Q3VycmVudEFzc2VydGlvbnNGb3JtKClcIiBbZm9ybUdyb3VwXT1cImdldEN1cnJlbnRBc3NlcnRpb25zRm9ybSgpIVwiIGNsYXNzPVwiYXNzZXJ0aW9ucy1mb3JtXCI+XG4gICAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cImFzc2VydGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtc2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJhc3NlcnRpb25zRGF0YVNvdXJjZVwiIGNsYXNzPVwiYXNzZXJ0aW9ucy10YWJsZVwiICNhc3NlcnRpb25zVGFibGU+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gSlNPTlBhdGggQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImpzb25QYXRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5qc29uUGF0aDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGFzc2VydGlvbjsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbZm9ybUdyb3VwTmFtZV09XCJpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwiZnVsbC13aWR0aC1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwianNvblBhdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ1c2VybmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnanNvblBhdGgnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rm9ybUNvbnRyb2xBdChpLCAnanNvblBhdGgnKT8udG91Y2hlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTlBhdGggaXMgcmVxdWlyZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gVmVyaWZpY2F0aW9uIFR5cGUgQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInZlcmlmaWNhdGlvblR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPnZlcmlmaWNhdGlvblR5cGU8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBhc3NlcnRpb247IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cImZ1bGwtd2lkdGgtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBmb3JtQ29udHJvbE5hbWU9XCJ2ZXJpZmljYXRpb25UeXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImVxdWFsc1wiPkVxdWFsczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwibm90X2VxdWFsc1wiPk5vdCBFcXVhbHM8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImNvbnRhaW5zXCI+Q29udGFpbnM8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIm5vdF9jb250YWluc1wiPk5vdCBDb250YWluczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZ3JlYXRlcl90aGFuXCI+R3JlYXRlciBUaGFuPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsZXNzX3RoYW5cIj5MZXNzIFRoYW48L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImdyZWF0ZXJfdGhhbl9vcl9lcXVhbHNcIj5HcmVhdGVyIFRoYW4gT3IgRXF1YWxzPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsZXNzX3RoYW5fb3JfZXF1YWxzXCI+TGVzcyBUaGFuIE9yIEVxdWFsczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZXhpc3RzXCI+RXhpc3RzPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJub3RfZXhpc3RzXCI+Tm90IEV4aXN0czwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIEV4cGVjdGVkIFR5cGUgQ29sdW1uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImV4cGVjdGVkVHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+ZXhwZWN0ZWRUeXBlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgYXNzZXJ0aW9uOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBlY3RlZFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvbkV4cGVjdGVkVHlwZUNoYW5nZShpLCAkZXZlbnQudmFsdWUpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInN0cmluZ1wiPlN0cmluZzwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwibnVtYmVyXCI+TnVtYmVyPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJib29sZWFuXCI+Qm9vbGVhbjwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwib2JqZWN0XCI+T2JqZWN0PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJhcnJheVwiPkFycmF5PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJudWxsXCI+TnVsbDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIEV4cGVjdGVkIFZhbHVlIENvbHVtbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJleHBlY3RlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5leHBlY3RlZFZhbHVlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgYXNzZXJ0aW9uOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTdHJpbmcsIEFycmF5LCBPYmplY3QgSW5wdXQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldEV4cGVjdGVkVHlwZShpKSA9PT0gJ3N0cmluZycgfHwgZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnYXJyYXknIHx8IGdldEV4cGVjdGVkVHlwZShpKSA9PT0gJ29iamVjdCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRFeHBlY3RlZFR5cGUoaSkgPT09ICdhcnJheScgfHwgZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnb2JqZWN0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImV4cGVjdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImdldEV4cGVjdGVkVmFsdWVQbGFjZWhvbGRlcihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dzPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD48L3RleHRhcmVhPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnc3RyaW5nJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImV4cGVjdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImdldEV4cGVjdGVkVmFsdWVQbGFjZWhvbGRlcihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRGb3JtQ29udHJvbEF0KGksICdleHBlY3RlZFZhbHVlJyk/LnRvdWNoZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlIGlzIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uaGFzRXJyb3IoJ2ludmFsaWRUeXBlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uZXJyb3JzPy5tZXNzYWdlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOdWxsIFR5cGUgRGlzcGxheSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnbnVsbCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXQgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBlY3RlZFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJnZXRFeHBlY3RlZFZhbHVlUGxhY2Vob2xkZXIoaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE51bWJlciBJbnB1dCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnbnVtYmVyJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGgtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZXhwZWN0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkV4cGVjdGVkIFZhbHVlIGluIE51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRGb3JtQ29udHJvbEF0KGksICdleHBlY3RlZFZhbHVlJyk/LnRvdWNoZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlIGlzIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCb29sZWFuIFNlbGVjdCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0RXhwZWN0ZWRUeXBlKGkpID09PSAnYm9vbGVhbidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwiZXhwZWN0ZWRWYWx1ZVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJ0cnVlXCI+dHJ1ZTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZmFsc2VcIj5mYWxzZTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldEZvcm1Db250cm9sQXQoaSwgJ2V4cGVjdGVkVmFsdWUnKT8uaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rm9ybUNvbnRyb2xBdChpLCAnZXhwZWN0ZWRWYWx1ZScpPy50b3VjaGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSBpcyByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBY3Rpb25zIENvbHVtbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJhY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBhc3NlcnRpb247IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvbiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkZWxldGUtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUFzc2VydGlvbihpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidEZWxldGUgYXNzZXJ0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRDb2x1bW5zO1wiPjwvdHI+XG4gICAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBFbXB0eSBTdGF0ZSAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZ2V0QXNzZXJ0aW9uc0Zvcm1BcnJheSgpLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cbiAgICAgICAgICAgICAgICAgIDxwPk5vIGFzc2VydGlvbnMgYWRkZWQuIENsaWNrIFwiQWRkIEFzc2VydGlvblwiIHRvIGNyZWF0ZSBvbmUuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2FkdmFuY2VkJ1wiPlxuICAgICAgICAgICAgPGNxYS1hZHZhbmNlZC12YXJpYWJsZXMtZm9ybSBcbiAgICAgICAgICAgICAgW2FkdmFuY2VkVmFyaWFibGVzXT1cImFkdmFuY2VkU2V0dGluZ3NWYXJpYWJsZXNcIlxuICAgICAgICAgICAgICBbYWR2YW5jZWRWYXJpYWJsZUZvcm1dPVwiYWR2YW5jZWRWYXJpYWJsZXNGb3JtXCJcbiAgICAgICAgICAgICAgKHZhcmlhYmxlQm9vbGVhbkNoYW5nZSk9XCJvbkFkdmFuY2VkVmFyaWFibGVCb29sZWFuQ2hhbmdlKCRldmVudC5uYW1lLCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAgICAgKHZhcmlhYmxlVmFsdWVDaGFuZ2UpPVwib25BZHZhbmNlZFZhcmlhYmxlVmFsdWVDaGFuZ2UoJGV2ZW50Lm5hbWUsICRldmVudC52YWx1ZSlcIj5cbiAgICAgICAgICAgIDwvY3FhLWFkdmFuY2VkLXZhcmlhYmxlcy1mb3JtPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuXG5cbiAgPCEtLSBBY3Rpb24gQnV0dG9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS13LWZ1bGwgY3FhLWdhcC0yIGNxYS1tdC1hdXRvIGNxYS1wdC00IGNxYS1ib3JkZXItdCBjcWEtYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgPGNxYS1idXR0b24gY2xhc3M9XCJjcWEtdy0xLzJcIiB2YXJpYW50PVwib3V0bGluZWRcIiB0ZXh0PVwiQ2FuY2VsXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIChjbGlja2VkKT1cIm9uQ2FuY2VsKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPGNxYS1idXR0b24gKm5nSWY9XCIhaXNDcmVhdGluZ1N0ZXBcIiBjbGFzcz1cImNxYS13LTEvMlwiIHZhcmlhbnQ9XCJmaWxsZWRcIiBbdGV4dF09XCJlZGl0TW9kZSA/ICdVcGRhdGUgU3RlcCcgOiAnQ3JlYXRlIFN0ZXAnXCIgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhaXNGb3JtVmFsaWQoKVwiXG4gICAgICAoY2xpY2tlZCk9XCJvbkNyZWF0ZVN0ZXAoKVwiPlxuICAgIDwvY3FhLWJ1dHRvbj5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNDcmVhdGluZ1N0ZXBcIiBjbGFzcz1cImNxYS13LTEvMiBjcWEtZmxleC0xIGNxYS1taW4taC1bMzhweF0gY3FhLXJvdW5kZWQtWzhweF1cIj5cbiAgICAgIDxjcWEtYmFkZ2UgbGFiZWw9XCJDcmVhdGluZ+KAplwiIGljb249XCJhdXRvcmVuZXdcIiBbaXNMb2FkaW5nXT1cInRydWVcIiBbZnVsbFdpZHRoXT1cInRydWVcIiBbY2VudGVyQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgW2lubGluZVN0eWxlc109XCInbWluLWhlaWdodDogMzhweDsgaGVpZ2h0OiAzOHB4OyBib3gtc2l6aW5nOiBib3JkZXItYm94OyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsnXCJcbiAgICAgICAgdmFyaWFudD1cImluZm9cIiBzaXplPVwibWVkaXVtXCI+PC9jcWEtYmFkZ2U+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+Il19