@cqa-lib/cqa-ui 1.0.75 → 1.0.76

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.
@@ -4,11 +4,10 @@ import { DynamicSelectFieldComponent } from '../../dynamic-select/dynamic-select
4
4
  import * as i0 from "@angular/core";
5
5
  import * as i1 from "@angular/forms";
6
6
  import * as i2 from "../../dynamic-select/dynamic-select-field.component";
7
- import * as i3 from "@angular/material/form-field";
8
- import * as i4 from "@angular/material/datepicker";
9
- import * as i5 from "@angular/material/button";
10
- import * as i6 from "../../button/button.component";
11
- import * as i7 from "@angular/common";
7
+ import * as i3 from "../../button/button.component";
8
+ import * as i4 from "@angular/material/form-field";
9
+ import * as i5 from "@angular/common";
10
+ import * as i6 from "ngx-daterangepicker-material";
12
11
  export class DynamicFilterComponent {
13
12
  constructor(fb) {
14
13
  this.fb = fb;
@@ -26,6 +25,22 @@ export class DynamicFilterComponent {
26
25
  this.searchTextByKey = {};
27
26
  this.selectOutsideCleanup = new Map();
28
27
  this.hasSelectedFilters = false;
28
+ // NGX DateRangePicker integration
29
+ this.ngxDateRangeByKey = {};
30
+ this.ngxRanges = {}; // Using 'any' to avoid Dayjs type mismatch - library accepts Date objects at runtime
31
+ this.ngxLocale = { customRangeLabel: 'Custom range' };
32
+ // Disable all dates after today in the ngx datepicker
33
+ this.disableFutureDates = (m) => {
34
+ try {
35
+ const d = m && typeof m.toDate === 'function' ? m.toDate() : new Date(m);
36
+ return d.getTime() > this.maxDate.getTime();
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ };
42
+ // Ensure maxDate is the end of today, so any future dates are disallowed
43
+ this.maxDate = this.endOfDay(new Date());
29
44
  }
30
45
  ngOnChanges(changes) {
31
46
  if (changes['config'] || changes['model']) {
@@ -35,6 +50,25 @@ export class DynamicFilterComponent {
35
50
  onDateChange(event, key) {
36
51
  this.invokeDateRangeChange(key, event);
37
52
  }
53
+ onNgxDatesUpdated(e, key) {
54
+ const group = this.getDateGroup(key);
55
+ if (!group)
56
+ return;
57
+ const clamp = (d) => (d && d.getTime() > this.maxDate.getTime() ? this.maxDate : d);
58
+ const startRaw = e?.startDate ? (typeof e.startDate.toDate === 'function' ? e.startDate.toDate() : new Date(e.startDate)) : null;
59
+ const endRaw = e?.endDate ? (typeof e.endDate.toDate === 'function' ? e.endDate.toDate() : new Date(e.endDate)) : null;
60
+ const start = clamp(startRaw);
61
+ const end = clamp(endRaw);
62
+ group.patchValue({ start, end }, { emitEvent: true });
63
+ const serialized = this.serialize();
64
+ this.hasSelectedFilters = Object.keys(serialized).length > 0;
65
+ if (start && end && group.valid) {
66
+ this.apply();
67
+ }
68
+ else {
69
+ this.filtersChanged.emit(serialized);
70
+ }
71
+ }
38
72
  buildForm() {
39
73
  const ctrls = {};
40
74
  (this.config || []).forEach(c => {
@@ -46,6 +80,11 @@ export class DynamicFilterComponent {
46
80
  start: new FormControl(initialRange.start),
47
81
  end: new FormControl(initialRange.end),
48
82
  });
83
+ // initialize ngx model display
84
+ this.ngxDateRangeByKey[c.key] = {
85
+ startDate: initialRange.start || null,
86
+ endDate: initialRange.end || null
87
+ };
49
88
  }
50
89
  else {
51
90
  const initial = this.resolveInitialSelectValue(c);
@@ -61,6 +100,8 @@ export class DynamicFilterComponent {
61
100
  this.form = this.fb.group(ctrls);
62
101
  // initialize apply button state based on initial values
63
102
  this.hasSelectedFilters = Object.keys(this.serialize()).length > 0;
103
+ // build common ranges for ngx datepicker
104
+ this.ngxRanges = this.buildNgxRanges();
64
105
  this.form.valueChanges.subscribe(() => {
65
106
  const serialized = this.serialize();
66
107
  this.hasSelectedFilters = Object.keys(serialized).length > 0;
@@ -199,10 +240,10 @@ export class DynamicFilterComponent {
199
240
  const modelValue = this.model?.[item.key];
200
241
  const startSource = modelValue?.start ?? item.selectedStartDate ?? null;
201
242
  const endSource = modelValue?.end ?? item.selectedEndDate ?? null;
202
- return {
203
- start: this.normalizeDateValue(startSource),
204
- end: this.normalizeDateValue(endSource),
205
- };
243
+ const start = this.normalizeDateValue(startSource);
244
+ const end = this.normalizeDateValue(endSource);
245
+ const clamp = (d) => (d && d.getTime() > this.maxDate.getTime() ? this.maxDate : d);
246
+ return { start: clamp(start), end: clamp(end) };
206
247
  }
207
248
  normalizeDateValue(value) {
208
249
  if (!value)
@@ -268,6 +309,30 @@ export class DynamicFilterComponent {
268
309
  }
269
310
  }
270
311
  }
312
+ startOfDay(d) { const nd = new Date(d); nd.setHours(0, 0, 0, 0); return nd; }
313
+ endOfDay(d) { const nd = new Date(d); nd.setHours(23, 59, 59, 999); return nd; }
314
+ startOfMonth(year, month) { return new Date(year, month, 1, 0, 0, 0, 0); }
315
+ endOfMonth(year, month) { return new Date(year, month + 1, 0, 23, 59, 59, 999); }
316
+ buildNgxRanges() {
317
+ const today = new Date();
318
+ const yesterday = new Date();
319
+ yesterday.setDate(yesterday.getDate() - 1);
320
+ const last7Start = new Date();
321
+ last7Start.setDate(last7Start.getDate() - 6);
322
+ const last30Start = new Date();
323
+ last30Start.setDate(last30Start.getDate() - 29);
324
+ const thisMonthStart = this.startOfMonth(today.getFullYear(), today.getMonth());
325
+ const lastMonthStart = this.startOfMonth(today.getFullYear(), today.getMonth() - 1);
326
+ const lastMonthEnd = this.endOfMonth(today.getFullYear(), today.getMonth() - 1);
327
+ return {
328
+ 'Today': [this.startOfDay(today), this.endOfDay(today)],
329
+ 'Yesterday': [this.startOfDay(yesterday), this.endOfDay(yesterday)],
330
+ 'Last 7 Days': [this.startOfDay(last7Start), this.endOfDay(today)],
331
+ 'Last 30 Days': [this.startOfDay(last30Start), this.endOfDay(today)],
332
+ 'This Month': [this.startOfDay(thisMonthStart), this.endOfDay(today)],
333
+ 'Last Month': [this.startOfDay(lastMonthStart), this.endOfDay(lastMonthEnd)],
334
+ };
335
+ }
271
336
  getDateValidationError(key) {
272
337
  const dateGroup = this.getDateGroup(key);
273
338
  if (!dateGroup)
@@ -300,10 +365,10 @@ export class DynamicFilterComponent {
300
365
  }
301
366
  }
302
367
  DynamicFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicFilterComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
303
- DynamicFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: { config: "config", model: "model", showFilterPanel: "showFilterPanel", buttonLayout: "buttonLayout" }, outputs: { filtersApplied: "filtersApplied", filtersChanged: "filtersChanged", resetAction: "resetAction", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "selectComponents", predicate: DynamicSelectFieldComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-filter cqa-mb-[28px]\" *ngIf=\"showFilterPanel\" style=\"height: auto;\">\n <!-- Bottom Layout: Current design with selectors in grid and buttons below -->\n <ng-container *ngIf=\"buttonLayout === 'bottom'\">\n <form class=\"ts-form cqa-grid lg:cqa-grid-cols-4 md:cqa-grid-cols-2 cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width cqa-w-full\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </form>\n\n <div class=\"cqa-flex cqa-justify-end cqa-items-stretch cqa-gap-2 cqa-mt-4\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </ng-container>\n\n <!-- Right Layout: Buttons on leftmost side, selectors on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'right'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-first cqa-mr-auto\">\n <cqa-button variant=\"filled\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-justify-end cqa-order-last cqa-ml-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </form>\n </ng-container>\n\n <!-- Left Layout: Selectors on leftmost side, buttons on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'left'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-order-first cqa-mr-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-last cqa-ml-auto\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </form>\n </ng-container>\n </div>\n</div>", components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick"] }, { type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i4.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { type: i4.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { type: i4.MatDatepickerActions, selector: "mat-datepicker-actions, mat-date-range-picker-actions" }, { type: i5.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: i6.ButtonComponent, selector: "cqa-button", inputs: ["variant", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i7.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: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { 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: i4.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { type: i4.MatDatepickerApply, selector: "[matDatepickerApply], [matDateRangePickerApply]" }, { type: i3.MatError, selector: "mat-error", inputs: ["id"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
368
+ DynamicFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: { config: "config", model: "model", showFilterPanel: "showFilterPanel", buttonLayout: "buttonLayout" }, outputs: { filtersApplied: "filtersApplied", filtersChanged: "filtersChanged", resetAction: "resetAction", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "selectComponents", predicate: DynamicSelectFieldComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-filter cqa-mb-[28px]\" *ngIf=\"showFilterPanel\" style=\"height: auto;\">\n <!-- Bottom Layout: Current design with selectors in grid and buttons below -->\n <ng-container *ngIf=\"buttonLayout === 'bottom'\">\n <form class=\"ts-form cqa-grid lg:cqa-grid-cols-4 md:cqa-grid-cols-2 cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cus-range-select cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width cqa-w-full\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <!-- <mat-form-field class=\"mat-date-custom cqa-relative cqa-cursor-pointer\" appearance=\"fill\"> -->\n <div class=\"mat-date-custom cqa-relative cqa-cursor-pointer\">\n <input matInput\n class=\"cqa-cursor-pointer cqa-bg-transparent\"\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n <svg class=\"cqa-absolute cqa-top-[50%] cqa-translate-y-[-50%] cqa-right-4 cqa-z-[-1]\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </div>\n <!-- </mat-form-field> -->\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </form>\n\n <div class=\"cqa-flex cqa-justify-end cqa-items-stretch cqa-gap-2 cqa-mt-4\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </ng-container>\n\n <!-- Right Layout: Buttons on leftmost side, selectors on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'right'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-first cqa-mr-auto\">\n <cqa-button variant=\"filled\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-justify-end cqa-order-last cqa-ml-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <input matInput\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </form>\n </ng-container>\n\n <!-- Left Layout: Selectors on leftmost side, buttons on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'left'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-order-first cqa-mr-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <input matInput\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-last cqa-ml-auto\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </form>\n </ng-container>\n </div>\n</div>", components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick"] }, { type: i3.ButtonComponent, selector: "cqa-button", inputs: ["variant", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }], directives: [{ type: i5.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: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.DaterangepickerDirective, selector: "input[ngxDaterangepickerMd]", inputs: ["minDate", "maxDate", "autoApply", "alwaysShowCalendars", "showCustomRangeLabel", "linkedCalendars", "dateLimit", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "showDropdowns", "isInvalidDate", "isCustomDate", "isTooltipDate", "showClearButton", "customRangeDirection", "ranges", "opens", "drops", "firstMonthDayClass", "lastMonthDayClass", "emptyWeekRowClass", "emptyWeekColumnClass", "firstDayOfNextMonthClass", "lastDayOfPreviousMonthClass", "keepCalendarOpeningWithRange", "showRangeLabelOnInput", "showCancel", "lockStartDate", "timePicker", "timePicker24Hour", "timePickerIncrement", "timePickerSeconds", "closeOnAutoApply", "endKeyHolder", "startKey", "locale", "endKey"], outputs: ["change", "rangeClicked", "datesUpdated", "startDateChanged", "endDateChanged", "clearClicked"] }, { 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.MatError, selector: "mat-error", inputs: ["id"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
304
369
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicFilterComponent, decorators: [{
305
370
  type: Component,
306
- args: [{ selector: 'cqa-dynamic-filter', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-filter cqa-mb-[28px]\" *ngIf=\"showFilterPanel\" style=\"height: auto;\">\n <!-- Bottom Layout: Current design with selectors in grid and buttons below -->\n <ng-container *ngIf=\"buttonLayout === 'bottom'\">\n <form class=\"ts-form cqa-grid lg:cqa-grid-cols-4 md:cqa-grid-cols-2 cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width cqa-w-full\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </form>\n\n <div class=\"cqa-flex cqa-justify-end cqa-items-stretch cqa-gap-2 cqa-mt-4\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </ng-container>\n\n <!-- Right Layout: Buttons on leftmost side, selectors on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'right'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-first cqa-mr-auto\">\n <cqa-button variant=\"filled\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-justify-end cqa-order-last cqa-ml-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </form>\n </ng-container>\n\n <!-- Left Layout: Selectors on leftmost side, buttons on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'left'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-order-first cqa-mr-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <mat-date-range-input [rangePicker]=\"picker\" [formGroup]=\"getDateGroup(c.key)\" [max]=\"maxDate\">\n <input matStartDate formControlName=\"start\" [placeholder]=\"c.placeholder || 'Start date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n <input matEndDate formControlName=\"end\" [placeholder]=\"c.placeholder || 'End date'\" [max]=\"maxDate\" required\n [readonly]=\"true\" (focus)=\"picker.open()\" (click)=\"picker.open()\" />\n </mat-date-range-input>\n <mat-date-range-picker #picker (dateChange)=\"onDateChange($event, c.key)\"\n [panelClass]=\"'ctc-date-range-panel'\">\n <mat-datepicker-actions class=\"ctc-date-actions\">\n <div class=\"ctc-date-presets\">\n <div class=\"cqa-mb-2 cqa-font-medium\">Quick Presets</div>\n <div class=\"btn-group\">\n <button type=\"button\" class=\"preset-btn today\"\n (click)=\"applyPresetToGroup(c.key, 'today'); picker.close()\">Today</button>\n <button type=\"button\" class=\"preset-btn last7days\"\n (click)=\"applyPresetToGroup(c.key, 'last7days'); picker.close()\">Last 7 days</button>\n <button type=\"button\" class=\"preset-btn last30days\"\n (click)=\"applyPresetToGroup(c.key, 'last30days'); picker.close()\">Last 30 days</button>\n <button type=\"button\" class=\"preset-btn last90days\"\n (click)=\"applyPresetToGroup(c.key, 'last90days'); picker.close()\">Last 90 days</button>\n <button type=\"button\" class=\"preset-btn thismonth\"\n (click)=\"applyPresetToGroup(c.key, 'thismonth'); picker.close()\">This month</button>\n <button type=\"button\" class=\"preset-btn lastmonth\"\n (click)=\"applyPresetToGroup(c.key, 'lastmonth'); picker.close()\">Last month</button>\n </div>\n </div>\n <div class=\"cqa-font-medium cqa-mb-2 cqa-mt-[10px] cqa-w-full\">Custom Range</div>\n <button\n class=\"!cqa-bg-[#3f51b5] !cqa-text-white cqa-p-2 cqa-font-medium !cqa-mb-2 !cqa-mt-[10px] cqa-w-[calc(100%-32px)] !cqa-absolute cqa-bottom-[2px]\"\n mat-flat-button color=\"primary\" matDatepickerApply>Apply</button>\n </mat-datepicker-actions>\n </mat-date-range-picker>\n <div (click)=\"picker.open()\" class=\"cqa-cursor-pointer\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\"\n stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key) && !picker.opened\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-last cqa-ml-auto\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </form>\n </ng-container>\n </div>\n</div>", styles: [] }]
371
+ args: [{ selector: 'cqa-dynamic-filter', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-filter cqa-mb-[28px]\" *ngIf=\"showFilterPanel\" style=\"height: auto;\">\n <!-- Bottom Layout: Current design with selectors in grid and buttons below -->\n <ng-container *ngIf=\"buttonLayout === 'bottom'\">\n <form class=\"ts-form cqa-grid lg:cqa-grid-cols-4 md:cqa-grid-cols-2 cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cus-range-select cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width cqa-w-full\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <!-- <mat-form-field class=\"mat-date-custom cqa-relative cqa-cursor-pointer\" appearance=\"fill\"> -->\n <div class=\"mat-date-custom cqa-relative cqa-cursor-pointer\">\n <input matInput\n class=\"cqa-cursor-pointer cqa-bg-transparent\"\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n <svg class=\"cqa-absolute cqa-top-[50%] cqa-translate-y-[-50%] cqa-right-4 cqa-z-[-1]\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.33398 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M10.666 1.33203V3.9987\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M12.6667 2.66797H3.33333C2.59695 2.66797 2 3.26492 2 4.0013V13.3346C2 14.071 2.59695 14.668 3.33333 14.668H12.6667C13.403 14.668 14 14.071 14 13.3346V4.0013C14 3.26492 13.403 2.66797 12.6667 2.66797Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M2 6.66797H14\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </div>\n <!-- </mat-form-field> -->\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </form>\n\n <div class=\"cqa-flex cqa-justify-end cqa-items-stretch cqa-gap-2 cqa-mt-4\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </ng-container>\n\n <!-- Right Layout: Buttons on leftmost side, selectors on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'right'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-first cqa-mr-auto\">\n <cqa-button variant=\"filled\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-justify-end cqa-order-last cqa-ml-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <input matInput\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </form>\n </ng-container>\n\n <!-- Left Layout: Selectors on leftmost side, buttons on rightmost side -->\n <ng-container *ngIf=\"buttonLayout === 'left'\">\n <form class=\"ts-form cqa-flex cqa-flex-wrap cqa-items-end cqa-justify-between cqa-gap-4\" [formGroup]=\"form\"\n (keydown.enter)=\"(false)\" novalidate=\"novalidate\" style=\"height: auto;\">\n <div class=\"cqa-flex cqa-flex-wrap cqa-items-end cqa-gap-4 cqa-flex-1 cqa-order-first cqa-mr-auto\">\n <ng-container *ngFor=\"let c of config\">\n <ng-container *ngIf=\"!c.hidden\">\n <div class=\"form-group cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-shrink-0 filter-selector-width\">\n <!-- Select -->\n <ng-container *ngIf=\"c.type === 'select'\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(c)\"></cqa-dynamic-select>\n </ng-container>\n\n <!-- Date Range --> \n <ng-container *ngIf=\"c.type === 'date-range'\">\n <label\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4]\">{{\n c.label }}</label>\n <mat-form-field class=\"mat-date-custom\" appearance=\"fill\">\n <input matInput\n ngxDaterangepickerMd\n [autoApply]=\"true\"\n [alwaysShowCalendars]=\"true\"\n [ranges]=\"ngxRanges\"\n [locale]=\"ngxLocale\"\n [maxDate]=\"maxDate\"\n [isInvalidDate]=\"disableFutureDates\"\n [(ngModel)]=\"ngxDateRangeByKey[c.key]\"\n (datesUpdated)=\"onNgxDatesUpdated($event, c.key)\"\n [readonly]=\"true\"\n [placeholder]=\"c.placeholder || (c.label + ' range')\">\n </mat-form-field>\n <!-- Specific validation messages -->\n <mat-error *ngIf=\"getDateValidationError(c.key)\">\n {{ getDateValidationError(c.key) }}\n </mat-error>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </div>\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-flex-shrink-0 cqa-order-last cqa-ml-auto\">\n <cqa-button variant=\"filled\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"apply()\" [disabled]=\"!hasSelectedFilters\">Apply Filter</cqa-button>\n <cqa-button variant=\"outlined\" (mousedown)=\"preparePrimaryAction()\" (clicked)=\"reset()\">Reset</cqa-button>\n </div>\n </form>\n </ng-container>\n </div>\n</div>", styles: [] }]
307
372
  }], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { config: [{
308
373
  type: Input
309
374
  }], model: [{
@@ -326,4 +391,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
326
391
  type: ViewChildren,
327
392
  args: [DynamicSelectFieldComponent]
328
393
  }] } });
329
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWx0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9maWx0ZXJzL2R5bmFtaWMtZmlsdGVyL2R5bmFtaWMtZmlsdGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZmlsdGVycy9keW5hbWljLWZpbHRlci9keW5hbWljLWZpbHRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFpQixZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDbkosT0FBTyxFQUFlLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdyRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQzs7Ozs7Ozs7O0FBeUNsRyxNQUFNLE9BQU8sc0JBQXNCO0lBa0JqQyxZQUE2QixFQUFlO1FBQWYsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQWpCbkMsV0FBTSxHQUF3QixFQUFFLENBQUM7UUFDakMsVUFBSyxHQUF3QixFQUFFLENBQUM7UUFDaEMsb0JBQWUsR0FBWSxJQUFJLENBQUM7UUFDaEMsaUJBQVksR0FBZ0MsUUFBUSxDQUFDO1FBQ3BELG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFDekQsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUN6RCxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDdkMsdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFDN0QsdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUV4RCxTQUFJLEdBQWMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEMsWUFBTyxH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dkIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBT29DLGdCQUFnQjtzQkFBMUQsWUFBWTt1QkFBQywyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkcmVuLCBRdWVyeUxpc3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGF0ZXBpY2tlcklucHV0RXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB9IGZyb20gJy4uLy4uL2R5bmFtaWMtc2VsZWN0L2R5bmFtaWMtc2VsZWN0LWZpZWxkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQgfSBmcm9tICcuLi8uLi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQnO1xuXG50eXBlIEZpbHRlclR5cGUgPSAnc2VsZWN0JyB8ICdkYXRlLXJhbmdlJztcblxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljRmlsdGVyT3B0aW9uIHtcbiAgaWQ/OiBudW1iZXIgfCBzdHJpbmc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHZhbHVlPzogYW55O1xuICBsYWJlbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljRmlsdGVySXRlbSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICB0eXBlOiBGaWx0ZXJUeXBlO1xuICBrZXk6IHN0cmluZztcbiAgb3B0aW9ucz86IER5bmFtaWNGaWx0ZXJPcHRpb25bXTtcbiAgbXVsdGlwbGU/OiBib29sZWFuO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIGhpZGRlbj86IGJvb2xlYW47XG4gIHNlYXJjaGFibGU/OiBib29sZWFuO1xuICBvcHRpb25TdHlsZT86ICdjaGVja21hcmsnIHwgJ2NoZWNrYm94JztcbiAgc2hvd1NlbGVjdEFsbD86IGJvb2xlYW47XG4gIHNlbGVjdEFsbExhYmVsPzogc3RyaW5nO1xuICBzZWxlY3RlZFZhbHVlPzogYW55IHwgYW55W107XG4gIHNlbGVjdGVkU3RhcnREYXRlPzogRGF0ZSB8IHN0cmluZztcbiAgc2VsZWN0ZWRFbmREYXRlPzogRGF0ZSB8IHN0cmluZztcbiAgb25EYXRlQ2hhbmdlPzogKHZhbHVlOiB7IHN0YXJ0OiBEYXRlIHwgbnVsbDsgZW5kOiBEYXRlIHwgbnVsbCB9LCBldmVudD86IE1hdERhdGVwaWNrZXJJbnB1dEV2ZW50PERhdGU+IHwgRXZlbnQpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRHluYW1pY0ZpbHRlclZhbHVlcyB7XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLWR5bmFtaWMtZmlsdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2R5bmFtaWMtZmlsdGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfVxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljRmlsdGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY29uZmlnOiBEeW5hbWljRmlsdGVySXRlbVtdID0gW107XG4gIEBJbnB1dCgpIG1vZGVsOiBEeW5hbWljRmlsdGVyVmFsdWVzID0ge307XG4gIEBJbnB1dCgpIHNob3dGaWx0ZXJQYW5lbDogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGJ1dHRvbkxheW91dDogJ2xlZnQnIHwgJ3JpZ2h0JyB8ICdib3R0b20nID0gJ2JvdHRvbSc7XG4gIEBPdXRwdXQoKSBmaWx0ZXJzQXBwbGllZCA9IG5ldyBFdmVudEVtaXR0ZXI8RHluYW1pY0ZpbHRlclZhbHVlcz4oKTtcbiAgQE91dHB1dCgpIGZpbHRlcnNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxEeW5hbWljRmlsdGVyVmFsdWVzPigpO1xuICBAT3V0cHV0KCkgcmVzZXRBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBvbkFwcGx5RmlsdGVyQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPER5bmFtaWNGaWx0ZXJWYWx1ZXM+KCk7XG4gIEBPdXRwdXQoKSBvblJlc2V0RmlsdGVyQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgZm9ybTogRm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cCh7fSk7XG4gIG1heERhdGUgPSBuZXcgRGF0ZSgpO1xuICBzZWFyY2hUZXh0QnlLZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgcHJpdmF0ZSBzZWxlY3RPdXRzaWRlQ2xlYW51cCA9IG5ldyBNYXA8YW55LCAoKSA9PiB2b2lkPigpO1xuICBoYXNTZWxlY3RlZEZpbHRlcnMgPSBmYWxzZTtcbiAgQFZpZXdDaGlsZHJlbihEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQpIHNlbGVjdENvbXBvbmVudHM/OiBRdWVyeUxpc3Q8RHluYW1pY1NlbGVjdEZpZWxkQ29tcG9uZW50PjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGZiOiBGb3JtQnVpbGRlcikge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2NvbmZpZyddIHx8IGNoYW5nZXNbJ21vZGVsJ10pIHtcbiAgICAgIHRoaXMuYnVpbGRGb3JtKCk7XG4gICAgfVxuICB9XG5cbiAgb25EYXRlQ2hhbmdlKGV2ZW50OiBNYXREYXRlcGlja2VySW5wdXRFdmVudDxEYXRlPiB8IEV2ZW50LCBrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuaW52b2tlRGF0ZVJhbmdlQ2hhbmdlKGtleSwgZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEZvcm0oKTogdm9pZCB7XG4gICAgY29uc3QgY3RybHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAodGhpcy5jb25maWcgfHwgW10pLmZvckVhY2goYyA9PiB7XG4gICAgICBpZiAoYy5oaWRkZW4pIHJldHVybjtcbiAgICAgIGlmIChjLnR5cGUgPT09ICdkYXRlLXJhbmdlJykge1xuICAgICAgICBjb25zdCBpbml0aWFsUmFuZ2UgPSB0aGlzLmdldEluaXRpYWxEYXRlUmFuZ2VWYWx1ZShjKTtcbiAgICAgICAgY3RybHNbYy5rZXldID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgc3RhcnQ6IG5ldyBGb3JtQ29udHJvbChpbml0aWFsUmFuZ2Uuc3RhcnQpLFxuICAgICAgICAgIGVuZDogbmV3IEZvcm1Db250cm9sKGluaXRpYWxSYW5nZS5lbmQpLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWwgPSB0aGlzLnJlc29sdmVJbml0aWFsU2VsZWN0VmFsdWUoYyk7XG4gICAgICAgIGlmIChjLm11bHRpcGxlKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBBcnJheS5pc0FycmF5KGluaXRpYWwpID8gaW5pdGlhbCA6IChpbml0aWFsICE9IG51bGwgPyBbaW5pdGlhbF0gOiBbXSk7XG4gICAgICAgICAgY3RybHNbYy5rZXldID0gbmV3IEZvcm1Db250cm9sKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdHJsc1tjLmtleV0gPSBuZXcgRm9ybUNvbnRyb2wodGhpcy5jb2VyY2VUb1NpbmdsZVZhbHVlKGluaXRpYWwpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuZm9ybSA9IHRoaXMuZmIuZ3JvdXAoY3RybHMpO1xuICAgIC8vIGluaXRpYWxpemUgYXBwbHkgYnV0dG9uIHN0YXRlIGJhc2VkIG9uIGluaXRpYWwgdmFsdWVzXG4gICAgdGhpcy5oYXNTZWxlY3RlZEZpbHRlcnMgPSBPYmplY3Qua2V5cyh0aGlzLnNlcmlhbGl6ZSgpKS5sZW5ndGggPiAwO1xuICAgIHRoaXMuZm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB0aGlzLnNlcmlhbGl6ZSgpO1xuICAgICAgdGhpcy5oYXNTZWxlY3RlZEZpbHRlcnMgPSBPYmplY3Qua2V5cyhzZXJpYWxpemVkKS5sZW5ndGggPiAwO1xuICAgICAgdGhpcy5maWx0ZXJzQ2hhbmdlZC5lbWl0KHNlcmlhbGl6ZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgb25TZWxlY3RPcGVuZWRDaGFuZ2Uob3BlbmVkOiBib29sZWFuLCBzZWxlY3Q6IGFueSk6IHZvaWQge1xuICAgIGlmIChvcGVuZWQpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBvbkRvY0Rvd24gPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhbmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNkay1vdmVybGF5LXBhbmUgLm1hdC1zZWxlY3QtcGFuZWwnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgYXMgTm9kZSB8IG51bGw7XG4gICAgICAgICAgY29uc3Qgb3JpZ2luRWwgPSAoc2VsZWN0Py5fZWxlbWVudFJlZj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkgfHwgbnVsbDtcbiAgICAgICAgICBjb25zdCBpbnNpZGVQYW5lbCA9ICEhKHBhbmVsICYmIHRhcmdldCAmJiBwYW5lbC5jb250YWlucyh0YXJnZXQpKTtcbiAgICAgICAgICBjb25zdCBpbnNpZGVPcmlnaW4gPSAhIShvcmlnaW5FbCAmJiB0YXJnZXQgJiYgb3JpZ2luRWwuY29udGFpbnModGFyZ2V0KSk7XG4gICAgICAgICAgaWYgKCFpbnNpZGVQYW5lbCAmJiAhaW5zaWRlT3JpZ2luKSB7XG4gICAgICAgICAgICBzZWxlY3QuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uRG9jRG93biwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2VsZWN0T3V0c2lkZUNsZWFudXAuc2V0KHNlbGVjdCwgKCkgPT4gZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25Eb2NEb3duLCB0cnVlKSk7XG4gICAgICB9LCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xlYW51cCA9IHRoaXMuc2VsZWN0T3V0c2lkZUNsZWFudXAuZ2V0KHNlbGVjdCk7XG4gICAgICBpZiAoY2xlYW51cCkgY2xlYW51cCgpO1xuICAgICAgdGhpcy5zZWxlY3RPdXRzaWRlQ2xlYW51cC5kZWxldGUoc2VsZWN0KTtcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaChrZXk6IHN0cmluZywgdGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hUZXh0QnlLZXlba2V5XSA9ICh0ZXh0IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgZmlsdGVyZWRPcHRpb25zKGl0ZW06IER5bmFtaWNGaWx0ZXJJdGVtKTogRHluYW1pY0ZpbHRlck9wdGlvbltdIHtcbiAgICBjb25zdCBvcHRpb25zID0gaXRlbT8ub3B0aW9ucyB8fCBbXTtcbiAgICBjb25zdCBxID0gKHRoaXMuc2VhcmNoVGV4dEJ5S2V5W2l0ZW0ua2V5XSB8fCAnJykudHJpbSgpO1xuICAgIGlmICghcSkgcmV0dXJuIG9wdGlvbnM7XG4gICAgcmV0dXJuIG9wdGlvbnMuZmlsdGVyKG9wdCA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gKG9wdC5uYW1lID8/IG9wdC5sYWJlbCA/PyBTdHJpbmcob3B0LnZhbHVlID8/ICcnKSkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiBuYW1lLmluY2x1ZGVzKHEpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RGF0ZUdyb3VwKGtleTogc3RyaW5nKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtLmdldChrZXkpIGFzIEZvcm1Hcm91cDtcbiAgfVxuXG4gIGdldFNlbGVjdENvbmZpZyhpdGVtOiBEeW5hbWljRmlsdGVySXRlbSk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICBsYWJlbDogaXRlbS5sYWJlbCxcbiAgICAgIHBsYWNlaG9sZGVyOiBpdGVtLnBsYWNlaG9sZGVyLFxuICAgICAgZGlzYWJsZWQ6IGl0ZW0uZGlzYWJsZWQsXG4gICAgICBtdWx0aXBsZTogaXRlbS5tdWx0aXBsZSxcbiAgICAgIHNlYXJjaGFibGU6IGl0ZW0uc2VhcmNoYWJsZSxcbiAgICAgIG9wdGlvblN0eWxlOiBpdGVtLm9wdGlvblN0eWxlLFxuICAgICAgc2hvd1NlbGVjdEFsbDogaXRlbS5zaG93U2VsZWN0QWxsLFxuICAgICAgc2VsZWN0QWxsTGFiZWw6IGl0ZW0uc2VsZWN0QWxsTGFiZWwsXG4gICAgICBzZWxlY3RlZFZhbHVlOiBpdGVtLnNlbGVjdGVkVmFsdWUsXG4gICAgICBvcHRpb25zOiBpdGVtLm9wdGlvbnMgfHwgW11cbiAgICB9O1xuICB9XG5cbiAgYXBwbHkoKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUFsbE9wZW5TZWxlY3RzKCk7XG4gICAgY29uc3QgZmlsdGVyVmFsdWVzID0gdGhpcy5zZXJpYWxpemUoKTtcbiAgICB0aGlzLmZpbHRlcnNBcHBsaWVkLmVtaXQoZmlsdGVyVmFsdWVzKTtcbiAgICB0aGlzLm9uQXBwbHlGaWx0ZXJDbGljay5lbWl0KGZpbHRlclZhbHVlcyk7XG4gIH1cblxuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQWxsT3BlblNlbGVjdHMoKTtcbiAgICBPYmplY3Qua2V5cyh0aGlzLmZvcm0uY29udHJvbHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm0uZ2V0KGtleSk7XG4gICAgICBpZiAoY3RybCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICBjdHJsLmdldCgnc3RhcnQnKT8uc2V0VmFsdWUodW5kZWZpbmVkKTtcbiAgICAgICAgY3RybC5nZXQoJ2VuZCcpPy5zZXRWYWx1ZSh1bmRlZmluZWQpO1xuICAgICAgICB0aGlzLmludm9rZURhdGVSYW5nZUNoYW5nZShrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3RybD8uc2V0VmFsdWUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnJlc2V0QWN0aW9uLmVtaXQoKTtcbiAgICB0aGlzLm9uUmVzZXRGaWx0ZXJDbGljay5lbWl0KCk7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IHRoaXMuc2VyaWFsaXplKCk7XG4gICAgdGhpcy5oYXNTZWxlY3RlZEZpbHRlcnMgPSBPYmplY3Qua2V5cyhzZXJpYWxpemVkKS5sZW5ndGggPiAwO1xuICAgIHRoaXMuZmlsdGVyc0NoYW5nZWQuZW1pdChzZXJpYWxpemVkKTtcbiAgfVxuXG4gIC8qKiBDbG9zZSBhbnkgb3BlbiBNYXRTZWxlY3QgcGFuZWxzIGJlZm9yZSBwcmltYXJ5IGFjdGlvbnMgdG8gYXZvaWQgZG91YmxlLWNsaWNrIGlzc3VlcyAqL1xuICBwcmVwYXJlUHJpbWFyeUFjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQWxsT3BlblNlbGVjdHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VBbGxPcGVuU2VsZWN0cygpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnRzPy5mb3JFYWNoKGMgPT4gYy5jbG9zZVBhbmVsKCkpO1xuICAgIH0gY2F0Y2gge31cbiAgfVxuXG4gIHByaXZhdGUgc2VyaWFsaXplKCk6IER5bmFtaWNGaWx0ZXJWYWx1ZXMge1xuICAgIGNvbnN0IHJlc3VsdDogRHluYW1pY0ZpbHRlclZhbHVlcyA9IHt9O1xuICAgICh0aGlzLmNvbmZpZyB8fCBbXSkuZm9yRWFjaChjID0+IHtcbiAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm0uZ2V0KGMua2V5KTtcbiAgICAgIGlmICghY3RybCkgcmV0dXJuO1xuICAgICAgbGV0IHZhbDogYW55ID0gY3RybCBpbnN0YW5jZW9mIEZvcm1Hcm91cCA/IChjdHJsIGFzIEZvcm1Hcm91cCkuZ2V0UmF3VmFsdWUoKSA6IGN0cmwudmFsdWU7XG4gICAgICBpZiAoYy50eXBlID09PSAnZGF0ZS1yYW5nZScpIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB2YWw/LnN0YXJ0OyBjb25zdCBlbmQgPSB2YWw/LmVuZDtcbiAgICAgICAgaWYgKHN0YXJ0IHx8IGVuZCkgcmVzdWx0W2Mua2V5XSA9IHsgc3RhcnQsIGVuZCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHZhbCAhPT0gdW5kZWZpbmVkICYmIHZhbCAhPT0gbnVsbCAmJiAoQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsLmxlbmd0aCA+IDAgOiB2YWwgIT09ICcnKSkge1xuICAgICAgICAgIHJlc3VsdFtjLmtleV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlSW5pdGlhbFNlbGVjdFZhbHVlKGl0ZW06IER5bmFtaWNGaWx0ZXJJdGVtKTogYW55IHtcbiAgICBpZiAodGhpcy5tb2RlbCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5tb2RlbCwgaXRlbS5rZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5tb2RlbFtpdGVtLmtleV07XG4gICAgfVxuICAgIGlmIChpdGVtLnNlbGVjdGVkVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGl0ZW0uc2VsZWN0ZWRWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgY29lcmNlVG9TaW5nbGVWYWx1ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPyB2YWx1ZVswXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJbml0aWFsRGF0ZVJhbmdlVmFsdWUoaXRlbTogRHluYW1pY0ZpbHRlckl0ZW0pOiB7IHN0YXJ0OiBEYXRlIHwgbnVsbDsgZW5kOiBEYXRlIHwgbnVsbCB9IHtcbiAgICBjb25zdCBtb2RlbFZhbHVlID0gdGhpcy5tb2RlbD8uW2l0ZW0ua2V5XTtcbiAgICBjb25zdCBzdGFydFNvdXJjZSA9IG1vZGVsVmFsdWU/LnN0YXJ0ID8/IGl0ZW0uc2VsZWN0ZWRTdGFydERhdGUgPz8gbnVsbDtcbiAgICBjb25zdCBlbmRTb3VyY2UgPSBtb2RlbFZhbHVlPy5lbmQgPz8gaXRlbS5zZWxlY3RlZEVuZERhdGUgPz8gbnVsbDtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnQ6IHRoaXMubm9ybWFsaXplRGF0ZVZhbHVlKHN0YXJ0U291cmNlKSxcbiAgICAgIGVuZDogdGhpcy5ub3JtYWxpemVEYXRlVmFsdWUoZW5kU291cmNlKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVEYXRlVmFsdWUodmFsdWU6IGFueSk6IERhdGUgfCBudWxsIHtcbiAgICBpZiAoIXZhbHVlKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTih2YWx1ZS5nZXRUaW1lKCkpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICByZXR1cm4gaXNOYU4ocGFyc2VkLmdldFRpbWUoKSkgPyBudWxsIDogcGFyc2VkO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnZva2VEYXRlUmFuZ2VDaGFuZ2Uoa2V5OiBzdHJpbmcsIGV2ZW50PzogTWF0RGF0ZXBpY2tlcklucHV0RXZlbnQ8RGF0ZT4gfCBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW0gPSAodGhpcy5jb25maWcgfHwgW10pLmZpbmQoY2ZnID0+IGNmZy5rZXkgPT09IGtleSk7XG4gICAgaWYgKCFpdGVtPy5vbkRhdGVDaGFuZ2UpIHJldHVybjtcbiAgICBjb25zdCBkYXRlR3JvdXAgPSB0aGlzLmdldERhdGVHcm91cChrZXkpO1xuICAgIGlmICghZGF0ZUdyb3VwKSByZXR1cm47XG4gICAgY29uc3QgeyBzdGFydCwgZW5kIH0gPSBkYXRlR3JvdXAuZ2V0UmF3VmFsdWUoKSB8fCB7fTtcbiAgICBpdGVtLm9uRGF0ZUNoYW5nZShcbiAgICAgIHtcbiAgICAgICAgc3RhcnQ6IHRoaXMubm9ybWFsaXplRGF0ZVZhbHVlKHN0YXJ0KSxcbiAgICAgICAgZW5kOiB0aGlzLm5vcm1hbGl6ZURhdGVWYWx1ZShlbmQpLFxuICAgICAgfSxcbiAgICAgIGV2ZW50XG4gICAgKTtcbiAgfVxuXG4gIC8vIE1hdCBkYXRlIHJhbmdlIHBpY2tlciBvdmVybGF5IHByZXNldCBoZWxwZXJzXG4gIGFwcGx5UHJlc2V0VG9Hcm91cChrZXk6IHN0cmluZywgcHJlc2V0S2V5OiAndG9kYXknIHwgJ2xhc3Q3ZGF5cycgfCAnbGFzdDMwZGF5cycgfCAnbGFzdDkwZGF5cycgfCAndGhpc21vbnRoJyB8ICdsYXN0bW9udGgnKTogdm9pZCB7XG4gICAgY29uc3QgZGF0ZUdyb3VwID0gdGhpcy5nZXREYXRlR3JvdXAoa2V5KTtcbiAgICBpZiAoIWRhdGVHcm91cCkgcmV0dXJuO1xuICAgIGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gdGhpcy5nZXRQcmVzZXREYXRlcyhwcmVzZXRLZXkpO1xuICAgIGRhdGVHcm91cC5wYXRjaFZhbHVlKHsgc3RhcnQsIGVuZCB9KTtcbiAgICB0aGlzLmZpbHRlcnNDaGFuZ2VkLmVtaXQodGhpcy5zZXJpYWxpemUoKSk7XG4gICAgdGhpcy5pbnZva2VEYXRlUmFuZ2VDaGFuZ2Uoa2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHJlc2V0RGF0ZXMocHJlc2V0S2V5OiAndG9kYXknIHwgJ2xhc3Q3ZGF5cycgfCAnbGFzdDMwZGF5cycgfCAnbGFzdDkwZGF5cycgfCAndGhpc21vbnRoJyB8ICdsYXN0bW9udGgnKTogeyBzdGFydDogRGF0ZTsgZW5kOiBEYXRlIH0ge1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCBjbGFtcFRvRW5kT2ZUb2RheSA9IChkOiBEYXRlKSA9PiB7IGNvbnN0IG5kID0gbmV3IERhdGUoZCk7IG5kLnNldEhvdXJzKDIzLDU5LDU5LDk5OSk7IHJldHVybiBuZDsgfTtcbiAgICBzd2l0Y2ggKHByZXNldEtleSkge1xuICAgICAgY2FzZSAndG9kYXknOlxuICAgICAgICByZXR1cm4geyBzdGFydDogdG9kYXksIGVuZDogdG9kYXkgfTtcbiAgICAgIGNhc2UgJ2xhc3Q3ZGF5cyc6IHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSgpOyBzdGFydC5zZXREYXRlKHN0YXJ0LmdldERhdGUoKSAtIDYpO1xuICAgICAgICByZXR1cm4geyBzdGFydCwgZW5kOiB0b2RheSB9O1xuICAgICAgfVxuICAgICAgY2FzZSAnbGFzdDMwZGF5cyc6IHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSgpOyBzdGFydC5zZXREYXRlKHN0YXJ0LmdldERhdGUoKSAtIDI5KTtcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZDogdG9kYXkgfTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xhc3Q5MGRheXMnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoKTsgc3RhcnQuc2V0RGF0ZShzdGFydC5nZXREYXRlKCkgLSA4OSk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQ6IHRvZGF5IH07XG4gICAgICB9XG4gICAgICBjYXNlICd0aGlzbW9udGgnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgMSk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQ6IHRvZGF5IH07XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0bW9udGgnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSAtIDEsIDEpO1xuICAgICAgICBjb25zdCBlbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpLCAwKTtcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZDogY2xhbXBUb0VuZE9mVG9kYXkoZW5kKSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBnZXREYXRlVmFsaWRhdGlvbkVycm9yKGtleTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgZGF0ZUdyb3VwID0gdGhpcy5nZXREYXRlR3JvdXAoa2V5KTtcbiAgICBpZiAoIWRhdGVHcm91cCkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBzdGFydEN0cmwgPSBkYXRlR3JvdXAuY29udHJvbHNbJ3N0YXJ0J107XG4gICAgY29uc3QgZW5kQ3RybCA9IGRhdGVHcm91cC5jb250cm9sc1snZW5kJ107XG4gICAgY29uc3Qgc3RhcnRWYWwgPSBzdGFydEN0cmw/LnZhbHVlO1xuICAgIGNvbnN0IGVuZFZhbCA9IGVuZEN0cmw/LnZhbHVlO1xuICAgIGNvbnN0IHN0YXJ0UGFyc2VFcnIgPSBzdGFydEN0cmw/LmVycm9ycz8uWydtYXREYXRlcGlja2VyUGFyc2UnXT8udGV4dDtcbiAgICBjb25zdCBlbmRQYXJzZUVyciA9IGVuZEN0cmw/LmVycm9ycz8uWydtYXREYXRlcGlja2VyUGFyc2UnXT8udGV4dDtcblxuICAgIGlmICghc3RhcnRWYWwgJiYgIWVuZFZhbCAmJiAhc3RhcnRQYXJzZUVyciAmJiAhZW5kUGFyc2VFcnIpIHJldHVybiBudWxsO1xuXG4gICAgaWYgKHN0YXJ0UGFyc2VFcnIpIHJldHVybiBgSW52YWxpZCBzdGFydCBkYXRlIGZvcm1hdGA7XG4gICAgaWYgKGVuZFBhcnNlRXJyKSByZXR1cm4gYEludmFsaWQgZW5kIGRhdGUgZm9ybWF0YDtcblxuICAgIGlmIChzdGFydFZhbCAmJiAhZW5kVmFsKSByZXR1cm4gYFBsZWFzZSBzZWxlY3QgYW4gZW5kIGRhdGVgO1xuICAgIGlmICghc3RhcnRWYWwgJiYgZW5kVmFsKSByZXR1cm4gYFBsZWFzZSBzZWxlY3QgYSBzdGFydCBkYXRlYDtcblxuICAgIGlmIChkYXRlR3JvdXAuaGFzRXJyb3IoJ21hdFN0YXJ0RGF0ZUludmFsaWQnKSkgcmV0dXJuIGBTdGFydCBkYXRlIG11c3QgYmUgYmVmb3JlIGVuZCBkYXRlYDtcbiAgICBpZiAoZGF0ZUdyb3VwLmhhc0Vycm9yKCdtYXRFbmREYXRlSW52YWxpZCcpKSByZXR1cm4gYEVuZCBkYXRlIG11c3QgYmUgYWZ0ZXIgc3RhcnQgZGF0ZWA7XG5cbiAgICBpZiAoZGF0ZUdyb3VwLmludmFsaWQpIHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnPy5maW5kKGMgPT4gYy5rZXkgPT09IGtleSk7XG4gICAgICByZXR1cm4gY29uZmlnID8gYCR7Y29uZmlnLmxhYmVsfSBpcyBpbnZhbGlkYCA6ICdEYXRlIHJhbmdlIGlzIGludmFsaWQnO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gRHluYW1pYyBEYXRlIFBpY2tlciBJbnRlZ3JhdGlvbiBNZXRob2RzIHJlbW92ZWQgKGNvbXBvbmVudCBubyBsb25nZXIgdXNlZClcbn1cblxuXG4iLCI8ZGl2IGNsYXNzPVwiY3FhLXVpLXJvb3RcIj5cbiAgPGRpdiBjbGFzcz1cImNxYS1maWx0ZXIgY3FhLW1iLVsyOHB4XVwiICpuZ0lmPVwic2hvd0ZpbHRlclBhbmVsXCIgc3R5bGU9XCJoZWlnaHQ6IGF1dG87XCI+XG4gICAgPCEtLSBCb3R0b20gTGF5b3V0OiBDdXJyZW50IGRlc2lnbiB3aXRoIHNlbGVjdG9ycyBpbiBncmlkIGFuZCBidXR0b25zIGJlbG93IC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJidXR0b25MYXlvdXQgPT09ICdib3R0b20nXCI+XG4gICAgICA8Zm9ybSBjbGFzcz1cInRzLWZvcm0gY3FhLWdyaWQgbGc6Y3FhLWdyaWQtY29scy00IG1kOmNxYS1ncmlkLWNvbHMtMiBjcWEtZ2FwLTRcIiBbZm9ybUdyb3VwXT1cImZvcm1cIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIoZmFsc2UpXCIgbm92YWxpZGF0ZT1cIm5vdmFsaWRhdGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYyBvZiBjb25maWdcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWMuaGlkZGVuXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0yIGNxYS1mbGV4LXNocmluay0wIGZpbHRlci1zZWxlY3Rvci13aWR0aCBjcWEtdy1mdWxsXCI+XG4gICAgICAgICAgICAgIDwhLS0gU2VsZWN0IC0tPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnc2VsZWN0J1wiPlxuICAgICAgICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwiZ2V0U2VsZWN0Q29uZmlnKGMpXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgIDwhLS0gRGF0ZSBSYW5nZSAtLT4gXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjLnR5cGUgPT09ICdkYXRlLXJhbmdlJ1wiPlxuICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWxhYmVsIGNxYS10ZXh0LVsjMzc0MTUxXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS1ibG9jayBjcWEtbGVhZGluZy1bMS40XVwiPnt7XG4gICAgICAgICAgICAgICAgICBjLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJtYXQtZGF0ZS1jdXN0b21cIiBhcHBlYXJhbmNlPVwiZmlsbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlLXJhbmdlLWlucHV0IFtyYW5nZVBpY2tlcl09XCJwaWNrZXJcIiBbZm9ybUdyb3VwXT1cImdldERhdGVHcm91cChjLmtleSlcIiBbbWF4XT1cIm1heERhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdFN0YXJ0RGF0ZSBmb3JtQ29udHJvbE5hbWU9XCJzdGFydFwiIFtwbGFjZWhvbGRlcl09XCJjLnBsYWNlaG9sZGVyIHx8ICdTdGFydCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdEVuZERhdGUgZm9ybUNvbnRyb2xOYW1lPVwiZW5kXCIgW3BsYWNlaG9sZGVyXT1cImMucGxhY2Vob2xkZXIgfHwgJ0VuZCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWRhdGUtcmFuZ2UtaW5wdXQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWRhdGUtcmFuZ2UtcGlja2VyICNwaWNrZXIgKGRhdGVDaGFuZ2UpPVwib25EYXRlQ2hhbmdlKCRldmVudCwgYy5rZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgW3BhbmVsQ2xhc3NdPVwiJ2N0Yy1kYXRlLXJhbmdlLXBhbmVsJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXItYWN0aW9ucyBjbGFzcz1cImN0Yy1kYXRlLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3RjLWRhdGUtcHJlc2V0c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1tYi0yIGNxYS1mb250LW1lZGl1bVwiPlF1aWNrIFByZXNldHM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIHRvZGF5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndG9kYXknKTsgcGlja2VyLmNsb3NlKClcIj5Ub2RheTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdDdkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDdkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCA3IGRheXM8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIGxhc3QzMGRheXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseVByZXNldFRvR3JvdXAoYy5rZXksICdsYXN0MzBkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCAzMCBkYXlzPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0biBsYXN0OTBkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDkwZGF5cycpOyBwaWNrZXIuY2xvc2UoKVwiPkxhc3QgOTAgZGF5czwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gdGhpc21vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndGhpc21vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+VGhpcyBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdG1vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdG1vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mb250LW1lZGl1bSBjcWEtbWItMiBjcWEtbXQtWzEwcHhdIGNxYS13LWZ1bGxcIj5DdXN0b20gUmFuZ2U8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiFjcWEtYmctWyMzZjUxYjVdICFjcWEtdGV4dC13aGl0ZSBjcWEtcC0yIGNxYS1mb250LW1lZGl1bSAhY3FhLW1iLTIgIWNxYS1tdC1bMTBweF0gY3FhLXctW2NhbGMoMTAwJS0zMnB4KV0gIWNxYS1hYnNvbHV0ZSBjcWEtYm90dG9tLVsycHhdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBtYXREYXRlcGlja2VyQXBwbHk+QXBwbHk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZXBpY2tlci1hY3Rpb25zPlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZS1yYW5nZS1waWNrZXI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgY2xhc3M9XCJjcWEtY3Vyc29yLXBvaW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjMzMzk4IDEuMzMyMDNWMy45OTg3XCIgc3Ryb2tlPVwiIzBBMEEwQVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEwLjY2NiAxLjMzMjAzVjMuOTk4N1wiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTIuNjY2NyAyLjY2Nzk3SDMuMzMzMzNDMi41OTY5NSAyLjY2Nzk3IDIgMy4yNjQ5MiAyIDQuMDAxM1YxMy4zMzQ2QzIgMTQuMDcxIDIuNTk2OTUgMTQuNjY4IDMuMzMzMzMgMTQuNjY4SDEyLjY2NjdDMTMuNDAzIDE0LjY2OCAxNCAxNC4wNzEgMTQgMTMuMzM0NlY0LjAwMTNDMTQgMy4yNjQ5MiAxMy40MDMgMi42Njc5NyAxMi42NjY3IDIuNjY3OTdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIgNi42Njc5N0gxNFwiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8IS0tIFNwZWNpZmljIHZhbGlkYXRpb24gbWVzc2FnZXMgLS0+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldERhdGVWYWxpZGF0aW9uRXJyb3IoYy5rZXkpICYmICFwaWNrZXIub3BlbmVkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KSB9fVxuICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZm9ybT5cblxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1qdXN0aWZ5LWVuZCBjcWEtaXRlbXMtc3RyZXRjaCBjcWEtZ2FwLTIgY3FhLW10LTRcIj5cbiAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIChtb3VzZWRvd24pPVwicHJlcGFyZVByaW1hcnlBY3Rpb24oKVwiIChjbGlja2VkKT1cImFwcGx5KClcIiBbZGlzYWJsZWRdPVwiIWhhc1NlbGVjdGVkRmlsdGVyc1wiPkFwcGx5IEZpbHRlcjwvY3FhLWJ1dHRvbj5cbiAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgKG1vdXNlZG93bik9XCJwcmVwYXJlUHJpbWFyeUFjdGlvbigpXCIgKGNsaWNrZWQpPVwicmVzZXQoKVwiPlJlc2V0PC9jcWEtYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIFJpZ2h0IExheW91dDogQnV0dG9ucyBvbiBsZWZ0bW9zdCBzaWRlLCBzZWxlY3RvcnMgb24gcmlnaHRtb3N0IHNpZGUgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJ1dHRvbkxheW91dCA9PT0gJ3JpZ2h0J1wiPlxuICAgICAgPGZvcm0gY2xhc3M9XCJ0cy1mb3JtIGNxYS1mbGV4IGNxYS1mbGV4LXdyYXAgY3FhLWl0ZW1zLWVuZCBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtNFwiIFtmb3JtR3JvdXBdPVwiZm9ybVwiXG4gICAgICAgIChrZXlkb3duLmVudGVyKT1cIihmYWxzZSlcIiBub3ZhbGlkYXRlPVwibm92YWxpZGF0ZVwiIHN0eWxlPVwiaGVpZ2h0OiBhdXRvO1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLXN0cmV0Y2ggY3FhLWdhcC0yIGNxYS1mbGV4LXNocmluay0wIGNxYS1vcmRlci1maXJzdCBjcWEtbXItYXV0b1wiPlxuICAgICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJmaWxsZWRcIiAoY2xpY2tlZCk9XCJhcHBseSgpXCIgW2Rpc2FibGVkXT1cIiFoYXNTZWxlY3RlZEZpbHRlcnNcIj5BcHBseSBGaWx0ZXI8L2NxYS1idXR0b24+XG4gICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgKGNsaWNrZWQpPVwicmVzZXQoKVwiPlJlc2V0PC9jcWEtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LXdyYXAgY3FhLWl0ZW1zLWVuZCBjcWEtZ2FwLTQgY3FhLWZsZXgtMSBjcWEtanVzdGlmeS1lbmQgY3FhLW9yZGVyLWxhc3QgY3FhLW1sLWF1dG9cIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjIG9mIGNvbmZpZ1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYy5oaWRkZW5cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTIgY3FhLWZsZXgtc2hyaW5rLTAgZmlsdGVyLXNlbGVjdG9yLXdpZHRoXCI+XG4gICAgICAgICAgICAgIDwhLS0gU2VsZWN0IC0tPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnc2VsZWN0J1wiPlxuICAgICAgICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwiZ2V0U2VsZWN0Q29uZmlnKGMpXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgIDwhLS0gRGF0ZSBSYW5nZSAtLT4gXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjLnR5cGUgPT09ICdkYXRlLXJhbmdlJ1wiPlxuICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWxhYmVsIGNxYS10ZXh0LVsjMzc0MTUxXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS1ibG9jayBjcWEtbGVhZGluZy1bMS40XVwiPnt7XG4gICAgICAgICAgICAgICAgICBjLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJtYXQtZGF0ZS1jdXN0b21cIiBhcHBlYXJhbmNlPVwiZmlsbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlLXJhbmdlLWlucHV0IFtyYW5nZVBpY2tlcl09XCJwaWNrZXJcIiBbZm9ybUdyb3VwXT1cImdldERhdGVHcm91cChjLmtleSlcIiBbbWF4XT1cIm1heERhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdFN0YXJ0RGF0ZSBmb3JtQ29udHJvbE5hbWU9XCJzdGFydFwiIFtwbGFjZWhvbGRlcl09XCJjLnBsYWNlaG9sZGVyIHx8ICdTdGFydCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdEVuZERhdGUgZm9ybUNvbnRyb2xOYW1lPVwiZW5kXCIgW3BsYWNlaG9sZGVyXT1cImMucGxhY2Vob2xkZXIgfHwgJ0VuZCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWRhdGUtcmFuZ2UtaW5wdXQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWRhdGUtcmFuZ2UtcGlja2VyICNwaWNrZXIgKGRhdGVDaGFuZ2UpPVwib25EYXRlQ2hhbmdlKCRldmVudCwgYy5rZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgW3BhbmVsQ2xhc3NdPVwiJ2N0Yy1kYXRlLXJhbmdlLXBhbmVsJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXItYWN0aW9ucyBjbGFzcz1cImN0Yy1kYXRlLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3RjLWRhdGUtcHJlc2V0c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1tYi0yIGNxYS1mb250LW1lZGl1bVwiPlF1aWNrIFByZXNldHM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIHRvZGF5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndG9kYXknKTsgcGlja2VyLmNsb3NlKClcIj5Ub2RheTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdDdkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDdkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCA3IGRheXM8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIGxhc3QzMGRheXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseVByZXNldFRvR3JvdXAoYy5rZXksICdsYXN0MzBkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCAzMCBkYXlzPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0biBsYXN0OTBkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDkwZGF5cycpOyBwaWNrZXIuY2xvc2UoKVwiPkxhc3QgOTAgZGF5czwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gdGhpc21vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndGhpc21vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+VGhpcyBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdG1vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdG1vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mb250LW1lZGl1bSBjcWEtbWItMiBjcWEtbXQtWzEwcHhdIGNxYS13LWZ1bGxcIj5DdXN0b20gUmFuZ2U8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiFjcWEtYmctWyMzZjUxYjVdICFjcWEtdGV4dC13aGl0ZSBjcWEtcC0yIGNxYS1mb250LW1lZGl1bSAhY3FhLW1iLTIgIWNxYS1tdC1bMTBweF0gY3FhLXctW2NhbGMoMTAwJS0zMnB4KV0gIWNxYS1hYnNvbHV0ZSBjcWEtYm90dG9tLVsycHhdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBtYXREYXRlcGlja2VyQXBwbHk+QXBwbHk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZXBpY2tlci1hY3Rpb25zPlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZS1yYW5nZS1waWNrZXI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgY2xhc3M9XCJjcWEtY3Vyc29yLXBvaW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjMzMzk4IDEuMzMyMDNWMy45OTg3XCIgc3Ryb2tlPVwiIzBBMEEwQVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEwLjY2NiAxLjMzMjAzVjMuOTk4N1wiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTIuNjY2NyAyLjY2Nzk3SDMuMzMzMzNDMi41OTY5NSAyLjY2Nzk3IDIgMy4yNjQ5MiAyIDQuMDAxM1YxMy4zMzQ2QzIgMTQuMDcxIDIuNTk2OTUgMTQuNjY4IDMuMzMzMzMgMTQuNjY4SDEyLjY2NjdDMTMuNDAzIDE0LjY2OCAxNCAxNC4wNzEgMTQgMTMuMzM0NlY0LjAwMTNDMTQgMy4yNjQ5MiAxMy40MDMgMi42Njc5NyAxMi42NjY3IDIuNjY3OTdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIgNi42Njc5N0gxNFwiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8IS0tIFNwZWNpZmljIHZhbGlkYXRpb24gbWVzc2FnZXMgLS0+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldERhdGVWYWxpZGF0aW9uRXJyb3IoYy5rZXkpICYmICFwaWNrZXIub3BlbmVkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KSB9fVxuICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIExlZnQgTGF5b3V0OiBTZWxlY3RvcnMgb24gbGVmdG1vc3Qgc2lkZSwgYnV0dG9ucyBvbiByaWdodG1vc3Qgc2lkZSAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYnV0dG9uTGF5b3V0ID09PSAnbGVmdCdcIj5cbiAgICAgIDxmb3JtIGNsYXNzPVwidHMtZm9ybSBjcWEtZmxleCBjcWEtZmxleC13cmFwIGNxYS1pdGVtcy1lbmQgY3FhLWp1c3RpZnktYmV0d2VlbiBjcWEtZ2FwLTRcIiBbZm9ybUdyb3VwXT1cImZvcm1cIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIoZmFsc2UpXCIgbm92YWxpZGF0ZT1cIm5vdmFsaWRhdGVcIiBzdHlsZT1cImhlaWdodDogYXV0bztcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LXdyYXAgY3FhLWl0ZW1zLWVuZCBjcWEtZ2FwLTQgY3FhLWZsZXgtMSBjcWEtb3JkZXItZmlyc3QgY3FhLW1yLWF1dG9cIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjIG9mIGNvbmZpZ1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYy5oaWRkZW5cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTIgY3FhLWZsZXgtc2hyaW5rLTAgZmlsdGVyLXNlbGVjdG9yLXdpZHRoXCI+XG4gICAgICAgICAgICAgIDwhLS0gU2VsZWN0IC0tPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnc2VsZWN0J1wiPlxuICAgICAgICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwiZ2V0U2VsZWN0Q29uZmlnKGMpXCI+PC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgIDwhLS0gRGF0ZSBSYW5nZSAtLT4gXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjLnR5cGUgPT09ICdkYXRlLXJhbmdlJ1wiPlxuICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWxhYmVsIGNxYS10ZXh0LVsjMzc0MTUxXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS1ibG9jayBjcWEtbGVhZGluZy1bMS40XVwiPnt7XG4gICAgICAgICAgICAgICAgICBjLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJtYXQtZGF0ZS1jdXN0b21cIiBhcHBlYXJhbmNlPVwiZmlsbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlLXJhbmdlLWlucHV0IFtyYW5nZVBpY2tlcl09XCJwaWNrZXJcIiBbZm9ybUdyb3VwXT1cImdldERhdGVHcm91cChjLmtleSlcIiBbbWF4XT1cIm1heERhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdFN0YXJ0RGF0ZSBmb3JtQ29udHJvbE5hbWU9XCJzdGFydFwiIFtwbGFjZWhvbGRlcl09XCJjLnBsYWNlaG9sZGVyIHx8ICdTdGFydCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdEVuZERhdGUgZm9ybUNvbnRyb2xOYW1lPVwiZW5kXCIgW3BsYWNlaG9sZGVyXT1cImMucGxhY2Vob2xkZXIgfHwgJ0VuZCBkYXRlJ1wiIFttYXhdPVwibWF4RGF0ZVwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIiAoZm9jdXMpPVwicGlja2VyLm9wZW4oKVwiIChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWRhdGUtcmFuZ2UtaW5wdXQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWRhdGUtcmFuZ2UtcGlja2VyICNwaWNrZXIgKGRhdGVDaGFuZ2UpPVwib25EYXRlQ2hhbmdlKCRldmVudCwgYy5rZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgW3BhbmVsQ2xhc3NdPVwiJ2N0Yy1kYXRlLXJhbmdlLXBhbmVsJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXItYWN0aW9ucyBjbGFzcz1cImN0Yy1kYXRlLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3RjLWRhdGUtcHJlc2V0c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1tYi0yIGNxYS1mb250LW1lZGl1bVwiPlF1aWNrIFByZXNldHM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIHRvZGF5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndG9kYXknKTsgcGlja2VyLmNsb3NlKClcIj5Ub2RheTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdDdkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDdkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCA3IGRheXM8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuIGxhc3QzMGRheXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseVByZXNldFRvR3JvdXAoYy5rZXksICdsYXN0MzBkYXlzJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCAzMCBkYXlzPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0biBsYXN0OTBkYXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdDkwZGF5cycpOyBwaWNrZXIuY2xvc2UoKVwiPkxhc3QgOTAgZGF5czwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gdGhpc21vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAndGhpc21vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+VGhpcyBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG4gbGFzdG1vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlQcmVzZXRUb0dyb3VwKGMua2V5LCAnbGFzdG1vbnRoJyk7IHBpY2tlci5jbG9zZSgpXCI+TGFzdCBtb250aDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mb250LW1lZGl1bSBjcWEtbWItMiBjcWEtbXQtWzEwcHhdIGNxYS13LWZ1bGxcIj5DdXN0b20gUmFuZ2U8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiFjcWEtYmctWyMzZjUxYjVdICFjcWEtdGV4dC13aGl0ZSBjcWEtcC0yIGNxYS1mb250LW1lZGl1bSAhY3FhLW1iLTIgIWNxYS1tdC1bMTBweF0gY3FhLXctW2NhbGMoMTAwJS0zMnB4KV0gIWNxYS1hYnNvbHV0ZSBjcWEtYm90dG9tLVsycHhdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBtYXREYXRlcGlja2VyQXBwbHk+QXBwbHk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZXBpY2tlci1hY3Rpb25zPlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZGF0ZS1yYW5nZS1waWNrZXI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJwaWNrZXIub3BlbigpXCIgY2xhc3M9XCJjcWEtY3Vyc29yLXBvaW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjMzMzk4IDEuMzMyMDNWMy45OTg3XCIgc3Ryb2tlPVwiIzBBMEEwQVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEwLjY2NiAxLjMzMjAzVjMuOTk4N1wiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTIuNjY2NyAyLjY2Nzk3SDMuMzMzMzNDMi41OTY5NSAyLjY2Nzk3IDIgMy4yNjQ5MiAyIDQuMDAxM1YxMy4zMzQ2QzIgMTQuMDcxIDIuNTk2OTUgMTQuNjY4IDMuMzMzMzMgMTQuNjY4SDEyLjY2NjdDMTMuNDAzIDE0LjY2OCAxNCAxNC4wNzEgMTQgMTMuMzM0NlY0LjAwMTNDMTQgMy4yNjQ5MiAxMy40MDMgMi42Njc5NyAxMi42NjY3IDIuNjY3OTdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIgNi42Njc5N0gxNFwiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8IS0tIFNwZWNpZmljIHZhbGlkYXRpb24gbWVzc2FnZXMgLS0+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImdldERhdGVWYWxpZGF0aW9uRXJyb3IoYy5rZXkpICYmICFwaWNrZXIub3BlbmVkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KSB9fVxuICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtc3RyZXRjaCBjcWEtZ2FwLTIgY3FhLWZsZXgtc2hyaW5rLTAgY3FhLW9yZGVyLWxhc3QgY3FhLW1sLWF1dG9cIj5cbiAgICAgICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgKG1vdXNlZG93bik9XCJwcmVwYXJlUHJpbWFyeUFjdGlvbigpXCIgKGNsaWNrZWQpPVwiYXBwbHkoKVwiIFtkaXNhYmxlZF09XCIhaGFzU2VsZWN0ZWRGaWx0ZXJzXCI+QXBwbHkgRmlsdGVyPC9jcWEtYnV0dG9uPlxuICAgICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJvdXRsaW5lZFwiIChtb3VzZWRvd24pPVwicHJlcGFyZVByaW1hcnlBY3Rpb24oKVwiIChjbGlja2VkKT1cInJlc2V0KClcIj5SZXNldDwvY3FhLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuPC9kaXY+Il19
394
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWx0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9maWx0ZXJzL2R5bmFtaWMtZmlsdGVyL2R5bmFtaWMtZmlsdGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZmlsdGVycy9keW5hbWljLWZpbHRlci9keW5hbWljLWZpbHRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFpQixZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDbkosT0FBTyxFQUFlLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdyRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQzs7Ozs7Ozs7QUF5Q2xHLE1BQU0sT0FBTyxzQkFBc0I7SUFrQmpDLFlBQTZCLEVBQWU7UUFBZixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBakJuQyxXQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUNqQyxVQUFLLEdBQXdCLEVBQUUsQ0FBQztRQUNoQyxvQkFBZSxHQUFZLElBQUksQ0FBQztRQUNoQyxpQkFBWSxHQUFnQyxRQUFRLENBQUM7UUFDcEQsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUN6RCxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUF1QixDQUFDO1FBQ3pELGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUN2Qyx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUM3RCx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXhELFNBQUksR0FBYyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQyxZQUFPLEdB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QUFJLFNBQVMsQ0FBQyxPQUFPLEVBQUU7WUFDckIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUMsdUJBQXVCLENBQUM7U0FDeEU7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7O21IQWpXVSxzQkFBc0I7dUdBQXRCLHNCQUFzQix5YkFnQm5CLDJCQUEyQixxRUM3RDNDLG1vU0FxSk07MkZEeEdPLHNCQUFzQjtrQkFQbEMsU0FBUzsrQkFDRSxvQkFBb0IsbUJBR2IsdUJBQXVCLENBQUMsTUFBTSxRQUN6QyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7a0dBR3JCLE1BQU07c0JBQWQsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNJLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBT29DLGdCQUFnQjtzQkFBMUQsWUFBWTt1QkFBQywyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkcmVuLCBRdWVyeUxpc3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGF0ZXBpY2tlcklucHV0RXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB9IGZyb20gJy4uLy4uL2R5bmFtaWMtc2VsZWN0L2R5bmFtaWMtc2VsZWN0LWZpZWxkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQgfSBmcm9tICcuLi8uLi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQnO1xuXG50eXBlIEZpbHRlclR5cGUgPSAnc2VsZWN0JyB8ICdkYXRlLXJhbmdlJztcblxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljRmlsdGVyT3B0aW9uIHtcbiAgaWQ/OiBudW1iZXIgfCBzdHJpbmc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHZhbHVlPzogYW55O1xuICBsYWJlbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljRmlsdGVySXRlbSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICB0eXBlOiBGaWx0ZXJUeXBlO1xuICBrZXk6IHN0cmluZztcbiAgb3B0aW9ucz86IER5bmFtaWNGaWx0ZXJPcHRpb25bXTtcbiAgbXVsdGlwbGU/OiBib29sZWFuO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIGhpZGRlbj86IGJvb2xlYW47XG4gIHNlYXJjaGFibGU/OiBib29sZWFuO1xuICBvcHRpb25TdHlsZT86ICdjaGVja21hcmsnIHwgJ2NoZWNrYm94JztcbiAgc2hvd1NlbGVjdEFsbD86IGJvb2xlYW47XG4gIHNlbGVjdEFsbExhYmVsPzogc3RyaW5nO1xuICBzZWxlY3RlZFZhbHVlPzogYW55IHwgYW55W107XG4gIHNlbGVjdGVkU3RhcnREYXRlPzogRGF0ZSB8IHN0cmluZztcbiAgc2VsZWN0ZWRFbmREYXRlPzogRGF0ZSB8IHN0cmluZztcbiAgb25EYXRlQ2hhbmdlPzogKHZhbHVlOiB7IHN0YXJ0OiBEYXRlIHwgbnVsbDsgZW5kOiBEYXRlIHwgbnVsbCB9LCBldmVudD86IE1hdERhdGVwaWNrZXJJbnB1dEV2ZW50PERhdGU+IHwgRXZlbnQpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRHluYW1pY0ZpbHRlclZhbHVlcyB7XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLWR5bmFtaWMtZmlsdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2R5bmFtaWMtZmlsdGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfVxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljRmlsdGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY29uZmlnOiBEeW5hbWljRmlsdGVySXRlbVtdID0gW107XG4gIEBJbnB1dCgpIG1vZGVsOiBEeW5hbWljRmlsdGVyVmFsdWVzID0ge307XG4gIEBJbnB1dCgpIHNob3dGaWx0ZXJQYW5lbDogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGJ1dHRvbkxheW91dDogJ2xlZnQnIHwgJ3JpZ2h0JyB8ICdib3R0b20nID0gJ2JvdHRvbSc7XG4gIEBPdXRwdXQoKSBmaWx0ZXJzQXBwbGllZCA9IG5ldyBFdmVudEVtaXR0ZXI8RHluYW1pY0ZpbHRlclZhbHVlcz4oKTtcbiAgQE91dHB1dCgpIGZpbHRlcnNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxEeW5hbWljRmlsdGVyVmFsdWVzPigpO1xuICBAT3V0cHV0KCkgcmVzZXRBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBvbkFwcGx5RmlsdGVyQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPER5bmFtaWNGaWx0ZXJWYWx1ZXM+KCk7XG4gIEBPdXRwdXQoKSBvblJlc2V0RmlsdGVyQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgZm9ybTogRm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cCh7fSk7XG4gIG1heERhdGUgPSBuZXcgRGF0ZSgpO1xuICBzZWFyY2hUZXh0QnlLZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgcHJpdmF0ZSBzZWxlY3RPdXRzaWRlQ2xlYW51cCA9IG5ldyBNYXA8YW55LCAoKSA9PiB2b2lkPigpO1xuICBoYXNTZWxlY3RlZEZpbHRlcnMgPSBmYWxzZTtcbiAgQFZpZXdDaGlsZHJlbihEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQpIHNlbGVjdENvbXBvbmVudHM/OiBRdWVyeUxpc3Q8RHluYW1pY1NlbGVjdEZpZWxkQ29tcG9uZW50PjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGZiOiBGb3JtQnVpbGRlcikge1xuICAgIC8vIEVuc3VyZSBtYXhEYXRlIGlzIHRoZSBlbmQgb2YgdG9kYXksIHNvIGFueSBmdXR1cmUgZGF0ZXMgYXJlIGRpc2FsbG93ZWRcbiAgICB0aGlzLm1heERhdGUgPSB0aGlzLmVuZE9mRGF5KG5ldyBEYXRlKCkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydjb25maWcnXSB8fCBjaGFuZ2VzWydtb2RlbCddKSB7XG4gICAgICB0aGlzLmJ1aWxkRm9ybSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uRGF0ZUNoYW5nZShldmVudDogTWF0RGF0ZXBpY2tlcklucHV0RXZlbnQ8RGF0ZT4gfCBFdmVudCwga2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmludm9rZURhdGVSYW5nZUNoYW5nZShrZXksIGV2ZW50KTtcbiAgfVxuXG4gIC8vIE5HWCBEYXRlUmFuZ2VQaWNrZXIgaW50ZWdyYXRpb25cbiAgbmd4RGF0ZVJhbmdlQnlLZXk6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgbmd4UmFuZ2VzOiBhbnkgPSB7fTsgLy8gVXNpbmcgJ2FueScgdG8gYXZvaWQgRGF5anMgdHlwZSBtaXNtYXRjaCAtIGxpYnJhcnkgYWNjZXB0cyBEYXRlIG9iamVjdHMgYXQgcnVudGltZVxuICBuZ3hMb2NhbGUgPSB7IGN1c3RvbVJhbmdlTGFiZWw6ICdDdXN0b20gcmFuZ2UnIH07XG4gIC8vIERpc2FibGUgYWxsIGRhdGVzIGFmdGVyIHRvZGF5IGluIHRoZSBuZ3ggZGF0ZXBpY2tlclxuICBkaXNhYmxlRnV0dXJlRGF0ZXMgPSAobTogYW55KTogYm9vbGVhbiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGQ6IERhdGUgPSBtICYmIHR5cGVvZiBtLnRvRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IG0udG9EYXRlKCkgOiBuZXcgRGF0ZShtKTtcbiAgICAgIHJldHVybiBkLmdldFRpbWUoKSA+IHRoaXMubWF4RGF0ZS5nZXRUaW1lKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuICBvbk5neERhdGVzVXBkYXRlZChlOiBhbnksIGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZ3JvdXAgPSB0aGlzLmdldERhdGVHcm91cChrZXkpO1xuICAgIGlmICghZ3JvdXApIHJldHVybjtcbiAgICBjb25zdCBjbGFtcCA9IChkOiBEYXRlIHwgbnVsbCkgPT4gKGQgJiYgZC5nZXRUaW1lKCkgPiB0aGlzLm1heERhdGUuZ2V0VGltZSgpID8gdGhpcy5tYXhEYXRlIDogZCk7XG4gICAgY29uc3Qgc3RhcnRSYXcgPSBlPy5zdGFydERhdGUgPyAodHlwZW9mIGUuc3RhcnREYXRlLnRvRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IGUuc3RhcnREYXRlLnRvRGF0ZSgpIDogbmV3IERhdGUoZS5zdGFydERhdGUpKSA6IG51bGw7XG4gICAgY29uc3QgZW5kUmF3ID0gZT8uZW5kRGF0ZSA/ICh0eXBlb2YgZS5lbmREYXRlLnRvRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IGUuZW5kRGF0ZS50b0RhdGUoKSA6IG5ldyBEYXRlKGUuZW5kRGF0ZSkpIDogbnVsbDtcbiAgICBjb25zdCBzdGFydCA9IGNsYW1wKHN0YXJ0UmF3KTtcbiAgICBjb25zdCBlbmQgPSBjbGFtcChlbmRSYXcpO1xuICAgIGdyb3VwLnBhdGNoVmFsdWUoeyBzdGFydCwgZW5kIH0sIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB0aGlzLnNlcmlhbGl6ZSgpO1xuICAgIHRoaXMuaGFzU2VsZWN0ZWRGaWx0ZXJzID0gT2JqZWN0LmtleXMoc2VyaWFsaXplZCkubGVuZ3RoID4gMDtcbiAgICBpZiAoc3RhcnQgJiYgZW5kICYmIGdyb3VwLnZhbGlkKSB7XG4gICAgICB0aGlzLmFwcGx5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmlsdGVyc0NoYW5nZWQuZW1pdChzZXJpYWxpemVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRm9ybSgpOiB2b2lkIHtcbiAgICBjb25zdCBjdHJsczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICh0aGlzLmNvbmZpZyB8fCBbXSkuZm9yRWFjaChjID0+IHtcbiAgICAgIGlmIChjLmhpZGRlbikgcmV0dXJuO1xuICAgICAgaWYgKGMudHlwZSA9PT0gJ2RhdGUtcmFuZ2UnKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxSYW5nZSA9IHRoaXMuZ2V0SW5pdGlhbERhdGVSYW5nZVZhbHVlKGMpO1xuICAgICAgICBjdHJsc1tjLmtleV0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICBzdGFydDogbmV3IEZvcm1Db250cm9sKGluaXRpYWxSYW5nZS5zdGFydCksXG4gICAgICAgICAgZW5kOiBuZXcgRm9ybUNvbnRyb2woaW5pdGlhbFJhbmdlLmVuZCksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBpbml0aWFsaXplIG5neCBtb2RlbCBkaXNwbGF5XG4gICAgICAgIHRoaXMubmd4RGF0ZVJhbmdlQnlLZXlbYy5rZXldID0ge1xuICAgICAgICAgIHN0YXJ0RGF0ZTogaW5pdGlhbFJhbmdlLnN0YXJ0IHx8IG51bGwsXG4gICAgICAgICAgZW5kRGF0ZTogaW5pdGlhbFJhbmdlLmVuZCB8fCBudWxsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBpbml0aWFsID0gdGhpcy5yZXNvbHZlSW5pdGlhbFNlbGVjdFZhbHVlKGMpO1xuICAgICAgICBpZiAoYy5tdWx0aXBsZSkge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gQXJyYXkuaXNBcnJheShpbml0aWFsKSA/IGluaXRpYWwgOiAoaW5pdGlhbCAhPSBudWxsID8gW2luaXRpYWxdIDogW10pO1xuICAgICAgICAgIGN0cmxzW2Mua2V5XSA9IG5ldyBGb3JtQ29udHJvbCh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3RybHNbYy5rZXldID0gbmV3IEZvcm1Db250cm9sKHRoaXMuY29lcmNlVG9TaW5nbGVWYWx1ZShpbml0aWFsKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKGN0cmxzKTtcbiAgICAvLyBpbml0aWFsaXplIGFwcGx5IGJ1dHRvbiBzdGF0ZSBiYXNlZCBvbiBpbml0aWFsIHZhbHVlc1xuICAgIHRoaXMuaGFzU2VsZWN0ZWRGaWx0ZXJzID0gT2JqZWN0LmtleXModGhpcy5zZXJpYWxpemUoKSkubGVuZ3RoID4gMDtcbiAgICAvLyBidWlsZCBjb21tb24gcmFuZ2VzIGZvciBuZ3ggZGF0ZXBpY2tlclxuICAgIHRoaXMubmd4UmFuZ2VzID0gdGhpcy5idWlsZE5neFJhbmdlcygpO1xuICAgIHRoaXMuZm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB0aGlzLnNlcmlhbGl6ZSgpO1xuICAgICAgdGhpcy5oYXNTZWxlY3RlZEZpbHRlcnMgPSBPYmplY3Qua2V5cyhzZXJpYWxpemVkKS5sZW5ndGggPiAwO1xuICAgICAgdGhpcy5maWx0ZXJzQ2hhbmdlZC5lbWl0KHNlcmlhbGl6ZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgb25TZWxlY3RPcGVuZWRDaGFuZ2Uob3BlbmVkOiBib29sZWFuLCBzZWxlY3Q6IGFueSk6IHZvaWQge1xuICAgIGlmIChvcGVuZWQpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBvbkRvY0Rvd24gPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhbmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNkay1vdmVybGF5LXBhbmUgLm1hdC1zZWxlY3QtcGFuZWwnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgYXMgTm9kZSB8IG51bGw7XG4gICAgICAgICAgY29uc3Qgb3JpZ2luRWwgPSAoc2VsZWN0Py5fZWxlbWVudFJlZj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkgfHwgbnVsbDtcbiAgICAgICAgICBjb25zdCBpbnNpZGVQYW5lbCA9ICEhKHBhbmVsICYmIHRhcmdldCAmJiBwYW5lbC5jb250YWlucyh0YXJnZXQpKTtcbiAgICAgICAgICBjb25zdCBpbnNpZGVPcmlnaW4gPSAhIShvcmlnaW5FbCAmJiB0YXJnZXQgJiYgb3JpZ2luRWwuY29udGFpbnModGFyZ2V0KSk7XG4gICAgICAgICAgaWYgKCFpbnNpZGVQYW5lbCAmJiAhaW5zaWRlT3JpZ2luKSB7XG4gICAgICAgICAgICBzZWxlY3QuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uRG9jRG93biwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2VsZWN0T3V0c2lkZUNsZWFudXAuc2V0KHNlbGVjdCwgKCkgPT4gZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25Eb2NEb3duLCB0cnVlKSk7XG4gICAgICB9LCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xlYW51cCA9IHRoaXMuc2VsZWN0T3V0c2lkZUNsZWFudXAuZ2V0KHNlbGVjdCk7XG4gICAgICBpZiAoY2xlYW51cCkgY2xlYW51cCgpO1xuICAgICAgdGhpcy5zZWxlY3RPdXRzaWRlQ2xlYW51cC5kZWxldGUoc2VsZWN0KTtcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaChrZXk6IHN0cmluZywgdGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hUZXh0QnlLZXlba2V5XSA9ICh0ZXh0IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgZmlsdGVyZWRPcHRpb25zKGl0ZW06IER5bmFtaWNGaWx0ZXJJdGVtKTogRHluYW1pY0ZpbHRlck9wdGlvbltdIHtcbiAgICBjb25zdCBvcHRpb25zID0gaXRlbT8ub3B0aW9ucyB8fCBbXTtcbiAgICBjb25zdCBxID0gKHRoaXMuc2VhcmNoVGV4dEJ5S2V5W2l0ZW0ua2V5XSB8fCAnJykudHJpbSgpO1xuICAgIGlmICghcSkgcmV0dXJuIG9wdGlvbnM7XG4gICAgcmV0dXJuIG9wdGlvbnMuZmlsdGVyKG9wdCA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gKG9wdC5uYW1lID8/IG9wdC5sYWJlbCA/PyBTdHJpbmcob3B0LnZhbHVlID8/ICcnKSkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiBuYW1lLmluY2x1ZGVzKHEpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RGF0ZUdyb3VwKGtleTogc3RyaW5nKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtLmdldChrZXkpIGFzIEZvcm1Hcm91cDtcbiAgfVxuXG4gIGdldFNlbGVjdENvbmZpZyhpdGVtOiBEeW5hbWljRmlsdGVySXRlbSk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICBsYWJlbDogaXRlbS5sYWJlbCxcbiAgICAgIHBsYWNlaG9sZGVyOiBpdGVtLnBsYWNlaG9sZGVyLFxuICAgICAgZGlzYWJsZWQ6IGl0ZW0uZGlzYWJsZWQsXG4gICAgICBtdWx0aXBsZTogaXRlbS5tdWx0aXBsZSxcbiAgICAgIHNlYXJjaGFibGU6IGl0ZW0uc2VhcmNoYWJsZSxcbiAgICAgIG9wdGlvblN0eWxlOiBpdGVtLm9wdGlvblN0eWxlLFxuICAgICAgc2hvd1NlbGVjdEFsbDogaXRlbS5zaG93U2VsZWN0QWxsLFxuICAgICAgc2VsZWN0QWxsTGFiZWw6IGl0ZW0uc2VsZWN0QWxsTGFiZWwsXG4gICAgICBzZWxlY3RlZFZhbHVlOiBpdGVtLnNlbGVjdGVkVmFsdWUsXG4gICAgICBvcHRpb25zOiBpdGVtLm9wdGlvbnMgfHwgW11cbiAgICB9O1xuICB9XG5cbiAgYXBwbHkoKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUFsbE9wZW5TZWxlY3RzKCk7XG4gICAgY29uc3QgZmlsdGVyVmFsdWVzID0gdGhpcy5zZXJpYWxpemUoKTtcbiAgICB0aGlzLmZpbHRlcnNBcHBsaWVkLmVtaXQoZmlsdGVyVmFsdWVzKTtcbiAgICB0aGlzLm9uQXBwbHlGaWx0ZXJDbGljay5lbWl0KGZpbHRlclZhbHVlcyk7XG4gIH1cblxuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQWxsT3BlblNlbGVjdHMoKTtcbiAgICBPYmplY3Qua2V5cyh0aGlzLmZvcm0uY29udHJvbHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm0uZ2V0KGtleSk7XG4gICAgICBpZiAoY3RybCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICBjdHJsLmdldCgnc3RhcnQnKT8uc2V0VmFsdWUodW5kZWZpbmVkKTtcbiAgICAgICAgY3RybC5nZXQoJ2VuZCcpPy5zZXRWYWx1ZSh1bmRlZmluZWQpO1xuICAgICAgICB0aGlzLmludm9rZURhdGVSYW5nZUNoYW5nZShrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3RybD8uc2V0VmFsdWUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnJlc2V0QWN0aW9uLmVtaXQoKTtcbiAgICB0aGlzLm9uUmVzZXRGaWx0ZXJDbGljay5lbWl0KCk7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IHRoaXMuc2VyaWFsaXplKCk7XG4gICAgdGhpcy5oYXNTZWxlY3RlZEZpbHRlcnMgPSBPYmplY3Qua2V5cyhzZXJpYWxpemVkKS5sZW5ndGggPiAwO1xuICAgIHRoaXMuZmlsdGVyc0NoYW5nZWQuZW1pdChzZXJpYWxpemVkKTtcbiAgfVxuXG4gIC8qKiBDbG9zZSBhbnkgb3BlbiBNYXRTZWxlY3QgcGFuZWxzIGJlZm9yZSBwcmltYXJ5IGFjdGlvbnMgdG8gYXZvaWQgZG91YmxlLWNsaWNrIGlzc3VlcyAqL1xuICBwcmVwYXJlUHJpbWFyeUFjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQWxsT3BlblNlbGVjdHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VBbGxPcGVuU2VsZWN0cygpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnRzPy5mb3JFYWNoKGMgPT4gYy5jbG9zZVBhbmVsKCkpO1xuICAgIH0gY2F0Y2gge31cbiAgfVxuXG4gIHByaXZhdGUgc2VyaWFsaXplKCk6IER5bmFtaWNGaWx0ZXJWYWx1ZXMge1xuICAgIGNvbnN0IHJlc3VsdDogRHluYW1pY0ZpbHRlclZhbHVlcyA9IHt9O1xuICAgICh0aGlzLmNvbmZpZyB8fCBbXSkuZm9yRWFjaChjID0+IHtcbiAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm0uZ2V0KGMua2V5KTtcbiAgICAgIGlmICghY3RybCkgcmV0dXJuO1xuICAgICAgbGV0IHZhbDogYW55ID0gY3RybCBpbnN0YW5jZW9mIEZvcm1Hcm91cCA/IChjdHJsIGFzIEZvcm1Hcm91cCkuZ2V0UmF3VmFsdWUoKSA6IGN0cmwudmFsdWU7XG4gICAgICBpZiAoYy50eXBlID09PSAnZGF0ZS1yYW5nZScpIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB2YWw/LnN0YXJ0OyBjb25zdCBlbmQgPSB2YWw/LmVuZDtcbiAgICAgICAgaWYgKHN0YXJ0IHx8IGVuZCkgcmVzdWx0W2Mua2V5XSA9IHsgc3RhcnQsIGVuZCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHZhbCAhPT0gdW5kZWZpbmVkICYmIHZhbCAhPT0gbnVsbCAmJiAoQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsLmxlbmd0aCA+IDAgOiB2YWwgIT09ICcnKSkge1xuICAgICAgICAgIHJlc3VsdFtjLmtleV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlSW5pdGlhbFNlbGVjdFZhbHVlKGl0ZW06IER5bmFtaWNGaWx0ZXJJdGVtKTogYW55IHtcbiAgICBpZiAodGhpcy5tb2RlbCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5tb2RlbCwgaXRlbS5rZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5tb2RlbFtpdGVtLmtleV07XG4gICAgfVxuICAgIGlmIChpdGVtLnNlbGVjdGVkVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGl0ZW0uc2VsZWN0ZWRWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgY29lcmNlVG9TaW5nbGVWYWx1ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPyB2YWx1ZVswXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJbml0aWFsRGF0ZVJhbmdlVmFsdWUoaXRlbTogRHluYW1pY0ZpbHRlckl0ZW0pOiB7IHN0YXJ0OiBEYXRlIHwgbnVsbDsgZW5kOiBEYXRlIHwgbnVsbCB9IHtcbiAgICBjb25zdCBtb2RlbFZhbHVlID0gdGhpcy5tb2RlbD8uW2l0ZW0ua2V5XTtcbiAgICBjb25zdCBzdGFydFNvdXJjZSA9IG1vZGVsVmFsdWU/LnN0YXJ0ID8/IGl0ZW0uc2VsZWN0ZWRTdGFydERhdGUgPz8gbnVsbDtcbiAgICBjb25zdCBlbmRTb3VyY2UgPSBtb2RlbFZhbHVlPy5lbmQgPz8gaXRlbS5zZWxlY3RlZEVuZERhdGUgPz8gbnVsbDtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMubm9ybWFsaXplRGF0ZVZhbHVlKHN0YXJ0U291cmNlKTtcbiAgICBjb25zdCBlbmQgPSB0aGlzLm5vcm1hbGl6ZURhdGVWYWx1ZShlbmRTb3VyY2UpO1xuICAgIGNvbnN0IGNsYW1wID0gKGQ6IERhdGUgfCBudWxsKSA9PiAoZCAmJiBkLmdldFRpbWUoKSA+IHRoaXMubWF4RGF0ZS5nZXRUaW1lKCkgPyB0aGlzLm1heERhdGUgOiBkKTtcbiAgICByZXR1cm4geyBzdGFydDogY2xhbXAoc3RhcnQpLCBlbmQ6IGNsYW1wKGVuZCkgfTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplRGF0ZVZhbHVlKHZhbHVlOiBhbnkpOiBEYXRlIHwgbnVsbCB7XG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiAhaXNOYU4odmFsdWUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWQgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgcmV0dXJuIGlzTmFOKHBhcnNlZC5nZXRUaW1lKCkpID8gbnVsbCA6IHBhcnNlZDtcbiAgfVxuXG4gIHByaXZhdGUgaW52b2tlRGF0ZVJhbmdlQ2hhbmdlKGtleTogc3RyaW5nLCBldmVudD86IE1hdERhdGVwaWNrZXJJbnB1dEV2ZW50PERhdGU+IHwgRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBpdGVtID0gKHRoaXMuY29uZmlnIHx8IFtdKS5maW5kKGNmZyA9PiBjZmcua2V5ID09PSBrZXkpO1xuICAgIGlmICghaXRlbT8ub25EYXRlQ2hhbmdlKSByZXR1cm47XG4gICAgY29uc3QgZGF0ZUdyb3VwID0gdGhpcy5nZXREYXRlR3JvdXAoa2V5KTtcbiAgICBpZiAoIWRhdGVHcm91cCkgcmV0dXJuO1xuICAgIGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gZGF0ZUdyb3VwLmdldFJhd1ZhbHVlKCkgfHwge307XG4gICAgaXRlbS5vbkRhdGVDaGFuZ2UoXG4gICAgICB7XG4gICAgICAgIHN0YXJ0OiB0aGlzLm5vcm1hbGl6ZURhdGVWYWx1ZShzdGFydCksXG4gICAgICAgIGVuZDogdGhpcy5ub3JtYWxpemVEYXRlVmFsdWUoZW5kKSxcbiAgICAgIH0sXG4gICAgICBldmVudFxuICAgICk7XG4gIH1cblxuICAvLyBNYXQgZGF0ZSByYW5nZSBwaWNrZXIgb3ZlcmxheSBwcmVzZXQgaGVscGVyc1xuICBhcHBseVByZXNldFRvR3JvdXAoa2V5OiBzdHJpbmcsIHByZXNldEtleTogJ3RvZGF5JyB8ICdsYXN0N2RheXMnIHwgJ2xhc3QzMGRheXMnIHwgJ2xhc3Q5MGRheXMnIHwgJ3RoaXNtb250aCcgfCAnbGFzdG1vbnRoJyk6IHZvaWQge1xuICAgIGNvbnN0IGRhdGVHcm91cCA9IHRoaXMuZ2V0RGF0ZUdyb3VwKGtleSk7XG4gICAgaWYgKCFkYXRlR3JvdXApIHJldHVybjtcbiAgICBjb25zdCB7IHN0YXJ0LCBlbmQgfSA9IHRoaXMuZ2V0UHJlc2V0RGF0ZXMocHJlc2V0S2V5KTtcbiAgICBkYXRlR3JvdXAucGF0Y2hWYWx1ZSh7IHN0YXJ0LCBlbmQgfSk7XG4gICAgdGhpcy5maWx0ZXJzQ2hhbmdlZC5lbWl0KHRoaXMuc2VyaWFsaXplKCkpO1xuICAgIHRoaXMuaW52b2tlRGF0ZVJhbmdlQ2hhbmdlKGtleSk7XG4gIH1cblxuICBwcml2YXRlIGdldFByZXNldERhdGVzKHByZXNldEtleTogJ3RvZGF5JyB8ICdsYXN0N2RheXMnIHwgJ2xhc3QzMGRheXMnIHwgJ2xhc3Q5MGRheXMnIHwgJ3RoaXNtb250aCcgfCAnbGFzdG1vbnRoJyk6IHsgc3RhcnQ6IERhdGU7IGVuZDogRGF0ZSB9IHtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgY2xhbXBUb0VuZE9mVG9kYXkgPSAoZDogRGF0ZSkgPT4geyBjb25zdCBuZCA9IG5ldyBEYXRlKGQpOyBuZC5zZXRIb3VycygyMyw1OSw1OSw5OTkpOyByZXR1cm4gbmQ7IH07XG4gICAgc3dpdGNoIChwcmVzZXRLZXkpIHtcbiAgICAgIGNhc2UgJ3RvZGF5JzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHRvZGF5LCBlbmQ6IHRvZGF5IH07XG4gICAgICBjYXNlICdsYXN0N2RheXMnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoKTsgc3RhcnQuc2V0RGF0ZShzdGFydC5nZXREYXRlKCkgLSA2KTtcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZDogdG9kYXkgfTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xhc3QzMGRheXMnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoKTsgc3RhcnQuc2V0RGF0ZShzdGFydC5nZXREYXRlKCkgLSAyOSk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQ6IHRvZGF5IH07XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0OTBkYXlzJzoge1xuICAgICAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKCk7IHN0YXJ0LnNldERhdGUoc3RhcnQuZ2V0RGF0ZSgpIC0gODkpO1xuICAgICAgICByZXR1cm4geyBzdGFydCwgZW5kOiB0b2RheSB9O1xuICAgICAgfVxuICAgICAgY2FzZSAndGhpc21vbnRoJzoge1xuICAgICAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCksIDEpO1xuICAgICAgICByZXR1cm4geyBzdGFydCwgZW5kOiB0b2RheSB9O1xuICAgICAgfVxuICAgICAgY2FzZSAnbGFzdG1vbnRoJzoge1xuICAgICAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCkgLSAxLCAxKTtcbiAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgMCk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQ6IGNsYW1wVG9FbmRPZlRvZGF5KGVuZCkgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBzdGFydE9mRGF5KGQ6IERhdGUpOiBEYXRlIHsgY29uc3QgbmQgPSBuZXcgRGF0ZShkKTsgbmQuc2V0SG91cnMoMCwwLDAsMCk7IHJldHVybiBuZDsgfVxuICBwcml2YXRlIGVuZE9mRGF5KGQ6IERhdGUpOiBEYXRlIHsgY29uc3QgbmQgPSBuZXcgRGF0ZShkKTsgbmQuc2V0SG91cnMoMjMsNTksNTksOTk5KTsgcmV0dXJuIG5kOyB9XG4gIHByaXZhdGUgc3RhcnRPZk1vbnRoKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IERhdGUgeyByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIDEsIDAsMCwwLDApOyB9XG4gIHByaXZhdGUgZW5kT2ZNb250aCh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBEYXRlIHsgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoICsgMSwgMCwgMjMsNTksNTksOTk5KTsgfVxuICBwcml2YXRlIGJ1aWxkTmd4UmFuZ2VzKCk6IFJlY29yZDxzdHJpbmcsIFtEYXRlLCBEYXRlXT4ge1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB5ZXN0ZXJkYXkgPSBuZXcgRGF0ZSgpOyB5ZXN0ZXJkYXkuc2V0RGF0ZSh5ZXN0ZXJkYXkuZ2V0RGF0ZSgpIC0gMSk7XG4gICAgY29uc3QgbGFzdDdTdGFydCA9IG5ldyBEYXRlKCk7IGxhc3Q3U3RhcnQuc2V0RGF0ZShsYXN0N1N0YXJ0LmdldERhdGUoKSAtIDYpO1xuICAgIGNvbnN0IGxhc3QzMFN0YXJ0ID0gbmV3IERhdGUoKTsgbGFzdDMwU3RhcnQuc2V0RGF0ZShsYXN0MzBTdGFydC5nZXREYXRlKCkgLSAyOSk7XG4gICAgY29uc3QgdGhpc01vbnRoU3RhcnQgPSB0aGlzLnN0YXJ0T2ZNb250aCh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpKTtcbiAgICBjb25zdCBsYXN0TW9udGhTdGFydCA9IHRoaXMuc3RhcnRPZk1vbnRoKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCkgLSAxKTtcbiAgICBjb25zdCBsYXN0TW9udGhFbmQgPSB0aGlzLmVuZE9mTW9udGgodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSAtIDEpO1xuICAgIHJldHVybiB7XG4gICAgICAnVG9kYXknOiBbdGhpcy5zdGFydE9mRGF5KHRvZGF5KSwgdGhpcy5lbmRPZkRheSh0b2RheSldLFxuICAgICAgJ1llc3RlcmRheSc6IFt0aGlzLnN0YXJ0T2ZEYXkoeWVzdGVyZGF5KSwgdGhpcy5lbmRPZkRheSh5ZXN0ZXJkYXkpXSxcbiAgICAgICdMYXN0IDcgRGF5cyc6IFt0aGlzLnN0YXJ0T2ZEYXkobGFzdDdTdGFydCksIHRoaXMuZW5kT2ZEYXkodG9kYXkpXSxcbiAgICAgICdMYXN0IDMwIERheXMnOiBbdGhpcy5zdGFydE9mRGF5KGxhc3QzMFN0YXJ0KSwgdGhpcy5lbmRPZkRheSh0b2RheSldLFxuICAgICAgJ1RoaXMgTW9udGgnOiBbdGhpcy5zdGFydE9mRGF5KHRoaXNNb250aFN0YXJ0KSwgdGhpcy5lbmRPZkRheSh0b2RheSldLFxuICAgICAgJ0xhc3QgTW9udGgnOiBbdGhpcy5zdGFydE9mRGF5KGxhc3RNb250aFN0YXJ0KSwgdGhpcy5lbmRPZkRheShsYXN0TW9udGhFbmQpXSxcbiAgICB9O1xuICB9XG4gIGdldERhdGVWYWxpZGF0aW9uRXJyb3Ioa2V5OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBkYXRlR3JvdXAgPSB0aGlzLmdldERhdGVHcm91cChrZXkpO1xuICAgIGlmICghZGF0ZUdyb3VwKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHN0YXJ0Q3RybCA9IGRhdGVHcm91cC5jb250cm9sc1snc3RhcnQnXTtcbiAgICBjb25zdCBlbmRDdHJsID0gZGF0ZUdyb3VwLmNvbnRyb2xzWydlbmQnXTtcbiAgICBjb25zdCBzdGFydFZhbCA9IHN0YXJ0Q3RybD8udmFsdWU7XG4gICAgY29uc3QgZW5kVmFsID0gZW5kQ3RybD8udmFsdWU7XG4gICAgY29uc3Qgc3RhcnRQYXJzZUVyciA9IHN0YXJ0Q3RybD8uZXJyb3JzPy5bJ21hdERhdGVwaWNrZXJQYXJzZSddPy50ZXh0O1xuICAgIGNvbnN0IGVuZFBhcnNlRXJyID0gZW5kQ3RybD8uZXJyb3JzPy5bJ21hdERhdGVwaWNrZXJQYXJzZSddPy50ZXh0O1xuXG4gICAgaWYgKCFzdGFydFZhbCAmJiAhZW5kVmFsICYmICFzdGFydFBhcnNlRXJyICYmICFlbmRQYXJzZUVycikgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAoc3RhcnRQYXJzZUVycikgcmV0dXJuIGBJbnZhbGlkIHN0YXJ0IGRhdGUgZm9ybWF0YDtcbiAgICBpZiAoZW5kUGFyc2VFcnIpIHJldHVybiBgSW52YWxpZCBlbmQgZGF0ZSBmb3JtYXRgO1xuXG4gICAgaWYgKHN0YXJ0VmFsICYmICFlbmRWYWwpIHJldHVybiBgUGxlYXNlIHNlbGVjdCBhbiBlbmQgZGF0ZWA7XG4gICAgaWYgKCFzdGFydFZhbCAmJiBlbmRWYWwpIHJldHVybiBgUGxlYXNlIHNlbGVjdCBhIHN0YXJ0IGRhdGVgO1xuXG4gICAgaWYgKGRhdGVHcm91cC5oYXNFcnJvcignbWF0U3RhcnREYXRlSW52YWxpZCcpKSByZXR1cm4gYFN0YXJ0IGRhdGUgbXVzdCBiZSBiZWZvcmUgZW5kIGRhdGVgO1xuICAgIGlmIChkYXRlR3JvdXAuaGFzRXJyb3IoJ21hdEVuZERhdGVJbnZhbGlkJykpIHJldHVybiBgRW5kIGRhdGUgbXVzdCBiZSBhZnRlciBzdGFydCBkYXRlYDtcblxuICAgIGlmIChkYXRlR3JvdXAuaW52YWxpZCkge1xuICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc/LmZpbmQoYyA9PiBjLmtleSA9PT0ga2V5KTtcbiAgICAgIHJldHVybiBjb25maWcgPyBgJHtjb25maWcubGFiZWx9IGlzIGludmFsaWRgIDogJ0RhdGUgcmFuZ2UgaXMgaW52YWxpZCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBEeW5hbWljIERhdGUgUGlja2VyIEludGVncmF0aW9uIE1ldGhvZHMgcmVtb3ZlZCAoY29tcG9uZW50IG5vIGxvbmdlciB1c2VkKVxufVxuXG5cbiIsIjxkaXYgY2xhc3M9XCJjcWEtdWktcm9vdFwiPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZpbHRlciBjcWEtbWItWzI4cHhdXCIgKm5nSWY9XCJzaG93RmlsdGVyUGFuZWxcIiBzdHlsZT1cImhlaWdodDogYXV0bztcIj5cbiAgICA8IS0tIEJvdHRvbSBMYXlvdXQ6IEN1cnJlbnQgZGVzaWduIHdpdGggc2VsZWN0b3JzIGluIGdyaWQgYW5kIGJ1dHRvbnMgYmVsb3cgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJ1dHRvbkxheW91dCA9PT0gJ2JvdHRvbSdcIj5cbiAgICAgIDxmb3JtIGNsYXNzPVwidHMtZm9ybSBjcWEtZ3JpZCBsZzpjcWEtZ3JpZC1jb2xzLTQgbWQ6Y3FhLWdyaWQtY29scy0yIGNxYS1nYXAtNFwiIFtmb3JtR3JvdXBdPVwiZm9ybVwiXG4gICAgICAgIChrZXlkb3duLmVudGVyKT1cIihmYWxzZSlcIiBub3ZhbGlkYXRlPVwibm92YWxpZGF0ZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjIG9mIGNvbmZpZ1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYy5oaWRkZW5cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGN1cy1yYW5nZS1zZWxlY3QgY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMiBjcWEtZmxleC1zaHJpbmstMCBmaWx0ZXItc2VsZWN0b3Itd2lkdGggY3FhLXctZnVsbFwiPlxuICAgICAgICAgICAgICA8IS0tIFNlbGVjdCAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImMudHlwZSA9PT0gJ3NlbGVjdCdcIj5cbiAgICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhjKVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICA8IS0tIERhdGUgUmFuZ2UgLS0+IFxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnZGF0ZS1yYW5nZSdcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1sYWJlbCBjcWEtdGV4dC1bIzM3NDE1MV0gY3FhLXRleHQtWzE0cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtYmxvY2sgY3FhLWxlYWRpbmctWzEuNF1cIj57e1xuICAgICAgICAgICAgICAgICAgYy5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPCEtLSA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJtYXQtZGF0ZS1jdXN0b20gY3FhLXJlbGF0aXZlIGNxYS1jdXJzb3ItcG9pbnRlclwiIGFwcGVhcmFuY2U9XCJmaWxsXCI+IC0tPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1hdC1kYXRlLWN1c3RvbSBjcWEtcmVsYXRpdmUgY3FhLWN1cnNvci1wb2ludGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNxYS1jdXJzb3ItcG9pbnRlciBjcWEtYmctdHJhbnNwYXJlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbmd4RGF0ZXJhbmdlcGlja2VyTWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdXRvQXBwbHldPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbYWx3YXlzU2hvd0NhbGVuZGFyc109XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyYW5nZXNdPVwibmd4UmFuZ2VzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsb2NhbGVdPVwibmd4TG9jYWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52YWxpZERhdGVdPVwiZGlzYWJsZUZ1dHVyZURhdGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwibmd4RGF0ZVJhbmdlQnlLZXlbYy5rZXldXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChkYXRlc1VwZGF0ZWQpPVwib25OZ3hEYXRlc1VwZGF0ZWQoJGV2ZW50LCBjLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImMucGxhY2Vob2xkZXIgfHwgKGMubGFiZWwgKyAnIHJhbmdlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtdG9wLVs1MCVdIGNxYS10cmFuc2xhdGUteS1bLTUwJV0gY3FhLXJpZ2h0LTQgY3FhLXotWy0xXVwiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj48cGF0aCBkPVwiTTUuMzMzOTggMS4zMzIwM1YzLjk5ODdcIiBzdHJva2U9XCIjMEEwQTBBXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPjwvcGF0aD48cGF0aCBkPVwiTTEwLjY2NiAxLjMzMjAzVjMuOTk4N1wiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCI+PC9wYXRoPjxwYXRoIGQ9XCJNMTIuNjY2NyAyLjY2Nzk3SDMuMzMzMzNDMi41OTY5NSAyLjY2Nzk3IDIgMy4yNjQ5MiAyIDQuMDAxM1YxMy4zMzQ2QzIgMTQuMDcxIDIuNTk2OTUgMTQuNjY4IDMuMzMzMzMgMTQuNjY4SDEyLjY2NjdDMTMuNDAzIDE0LjY2OCAxNCAxNC4wNzEgMTQgMTMuMzM0NlY0LjAwMTNDMTQgMy4yNjQ5MiAxMy40MDMgMi42Njc5NyAxMi42NjY3IDIuNjY3OTdaXCIgc3Ryb2tlPVwiIzBBMEEwQVwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIj48L3BhdGg+PHBhdGggZD1cIk0yIDYuNjY3OTdIMTRcIiBzdHJva2U9XCIjMEEwQTBBXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPjwvcGF0aD48L3N2Zz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gPC9tYXQtZm9ybS1maWVsZD4gLS0+XG4gICAgICAgICAgICAgICAgPCEtLSBTcGVjaWZpYyB2YWxpZGF0aW9uIG1lc3NhZ2VzIC0tPlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KVwiPlxuICAgICAgICAgICAgICAgICAge3sgZ2V0RGF0ZVZhbGlkYXRpb25FcnJvcihjLmtleSkgfX1cbiAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Zvcm0+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtanVzdGlmeS1lbmQgY3FhLWl0ZW1zLXN0cmV0Y2ggY3FhLWdhcC0yIGNxYS1tdC00XCI+XG4gICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJmaWxsZWRcIiAobW91c2Vkb3duKT1cInByZXBhcmVQcmltYXJ5QWN0aW9uKClcIiAoY2xpY2tlZCk9XCJhcHBseSgpXCIgW2Rpc2FibGVkXT1cIiFoYXNTZWxlY3RlZEZpbHRlcnNcIj5BcHBseSBGaWx0ZXI8L2NxYS1idXR0b24+XG4gICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJvdXRsaW5lZFwiIChtb3VzZWRvd24pPVwicHJlcGFyZVByaW1hcnlBY3Rpb24oKVwiIChjbGlja2VkKT1cInJlc2V0KClcIj5SZXNldDwvY3FhLWJ1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBSaWdodCBMYXlvdXQ6IEJ1dHRvbnMgb24gbGVmdG1vc3Qgc2lkZSwgc2VsZWN0b3JzIG9uIHJpZ2h0bW9zdCBzaWRlIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJidXR0b25MYXlvdXQgPT09ICdyaWdodCdcIj5cbiAgICAgIDxmb3JtIGNsYXNzPVwidHMtZm9ybSBjcWEtZmxleCBjcWEtZmxleC13cmFwIGNxYS1pdGVtcy1lbmQgY3FhLWp1c3RpZnktYmV0d2VlbiBjcWEtZ2FwLTRcIiBbZm9ybUdyb3VwXT1cImZvcm1cIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIoZmFsc2UpXCIgbm92YWxpZGF0ZT1cIm5vdmFsaWRhdGVcIiBzdHlsZT1cImhlaWdodDogYXV0bztcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1zdHJldGNoIGNxYS1nYXAtMiBjcWEtZmxleC1zaHJpbmstMCBjcWEtb3JkZXItZmlyc3QgY3FhLW1yLWF1dG9cIj5cbiAgICAgICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwiZmlsbGVkXCIgKGNsaWNrZWQpPVwiYXBwbHkoKVwiIFtkaXNhYmxlZF09XCIhaGFzU2VsZWN0ZWRGaWx0ZXJzXCI+QXBwbHkgRmlsdGVyPC9jcWEtYnV0dG9uPlxuICAgICAgICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJvdXRsaW5lZFwiIChjbGlja2VkKT1cInJlc2V0KClcIj5SZXNldDwvY3FhLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC13cmFwIGNxYS1pdGVtcy1lbmQgY3FhLWdhcC00IGNxYS1mbGV4LTEgY3FhLWp1c3RpZnktZW5kIGNxYS1vcmRlci1sYXN0IGNxYS1tbC1hdXRvXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYyBvZiBjb25maWdcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWMuaGlkZGVuXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0yIGNxYS1mbGV4LXNocmluay0wIGZpbHRlci1zZWxlY3Rvci13aWR0aFwiPlxuICAgICAgICAgICAgICA8IS0tIFNlbGVjdCAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImMudHlwZSA9PT0gJ3NlbGVjdCdcIj5cbiAgICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhjKVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICA8IS0tIERhdGUgUmFuZ2UgLS0+IFxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnZGF0ZS1yYW5nZSdcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1sYWJlbCBjcWEtdGV4dC1bIzM3NDE1MV0gY3FhLXRleHQtWzE0cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtYmxvY2sgY3FhLWxlYWRpbmctWzEuNF1cIj57e1xuICAgICAgICAgICAgICAgICAgYy5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwibWF0LWRhdGUtY3VzdG9tXCIgYXBwZWFyYW5jZT1cImZpbGxcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgIG5neERhdGVyYW5nZXBpY2tlck1kXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9BcHBseV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbYWx3YXlzU2hvd0NhbGVuZGFyc109XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcmFuZ2VzXT1cIm5neFJhbmdlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2xvY2FsZV09XCJuZ3hMb2NhbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmFsaWREYXRlXT1cImRpc2FibGVGdXR1cmVEYXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJuZ3hEYXRlUmFuZ2VCeUtleVtjLmtleV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgIChkYXRlc1VwZGF0ZWQpPVwib25OZ3hEYXRlc1VwZGF0ZWQoJGV2ZW50LCBjLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiYy5wbGFjZWhvbGRlciB8fCAoYy5sYWJlbCArICcgcmFuZ2UnKVwiPlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPCEtLSBTcGVjaWZpYyB2YWxpZGF0aW9uIG1lc3NhZ2VzIC0tPlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KVwiPlxuICAgICAgICAgICAgICAgICAge3sgZ2V0RGF0ZVZhbGlkYXRpb25FcnJvcihjLmtleSkgfX1cbiAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9mb3JtPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBMZWZ0IExheW91dDogU2VsZWN0b3JzIG9uIGxlZnRtb3N0IHNpZGUsIGJ1dHRvbnMgb24gcmlnaHRtb3N0IHNpZGUgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJ1dHRvbkxheW91dCA9PT0gJ2xlZnQnXCI+XG4gICAgICA8Zm9ybSBjbGFzcz1cInRzLWZvcm0gY3FhLWZsZXggY3FhLWZsZXgtd3JhcCBjcWEtaXRlbXMtZW5kIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWdhcC00XCIgW2Zvcm1Hcm91cF09XCJmb3JtXCJcbiAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiKGZhbHNlKVwiIG5vdmFsaWRhdGU9XCJub3ZhbGlkYXRlXCIgc3R5bGU9XCJoZWlnaHQ6IGF1dG87XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC13cmFwIGNxYS1pdGVtcy1lbmQgY3FhLWdhcC00IGNxYS1mbGV4LTEgY3FhLW9yZGVyLWZpcnN0IGNxYS1tci1hdXRvXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYyBvZiBjb25maWdcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWMuaGlkZGVuXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0yIGNxYS1mbGV4LXNocmluay0wIGZpbHRlci1zZWxlY3Rvci13aWR0aFwiPlxuICAgICAgICAgICAgICA8IS0tIFNlbGVjdCAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImMudHlwZSA9PT0gJ3NlbGVjdCdcIj5cbiAgICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhjKVwiPjwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICA8IS0tIERhdGUgUmFuZ2UgLS0+IFxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYy50eXBlID09PSAnZGF0ZS1yYW5nZSdcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1sYWJlbCBjcWEtdGV4dC1bIzM3NDE1MV0gY3FhLXRleHQtWzE0cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtYmxvY2sgY3FhLWxlYWRpbmctWzEuNF1cIj57e1xuICAgICAgICAgICAgICAgICAgYy5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwibWF0LWRhdGUtY3VzdG9tXCIgYXBwZWFyYW5jZT1cImZpbGxcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgIG5neERhdGVyYW5nZXBpY2tlck1kXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9BcHBseV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbYWx3YXlzU2hvd0NhbGVuZGFyc109XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcmFuZ2VzXT1cIm5neFJhbmdlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2xvY2FsZV09XCJuZ3hMb2NhbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmFsaWREYXRlXT1cImRpc2FibGVGdXR1cmVEYXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJuZ3hEYXRlUmFuZ2VCeUtleVtjLmtleV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgIChkYXRlc1VwZGF0ZWQpPVwib25OZ3hEYXRlc1VwZGF0ZWQoJGV2ZW50LCBjLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiYy5wbGFjZWhvbGRlciB8fCAoYy5sYWJlbCArICcgcmFuZ2UnKVwiPlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPCEtLSBTcGVjaWZpYyB2YWxpZGF0aW9uIG1lc3NhZ2VzIC0tPlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJnZXREYXRlVmFsaWRhdGlvbkVycm9yKGMua2V5KVwiPlxuICAgICAgICAgICAgICAgICAge3sgZ2V0RGF0ZVZhbGlkYXRpb25FcnJvcihjLmtleSkgfX1cbiAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLXN0cmV0Y2ggY3FhLWdhcC0yIGNxYS1mbGV4LXNocmluay0wIGNxYS1vcmRlci1sYXN0IGNxYS1tbC1hdXRvXCI+XG4gICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIChtb3VzZWRvd24pPVwicHJlcGFyZVByaW1hcnlBY3Rpb24oKVwiIChjbGlja2VkKT1cImFwcGx5KClcIiBbZGlzYWJsZWRdPVwiIWhhc1NlbGVjdGVkRmlsdGVyc1wiPkFwcGx5IEZpbHRlcjwvY3FhLWJ1dHRvbj5cbiAgICAgICAgICA8Y3FhLWJ1dHRvbiB2YXJpYW50PVwib3V0bGluZWRcIiAobW91c2Vkb3duKT1cInByZXBhcmVQcmltYXJ5QWN0aW9uKClcIiAoY2xpY2tlZCk9XCJyZXNldCgpXCI+UmVzZXQ8L2NxYS1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9mb3JtPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==