@cqa-lib/cqa-ui 1.0.16 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/esm2020/lib/column-visibility/column-visibility.component.mjs +3 -3
  2. package/esm2020/lib/dashboards/chart-card/chart-card.component.mjs +5 -3
  3. package/esm2020/lib/dashboards/dashboard-header/dashboard-header.component.mjs +22 -5
  4. package/esm2020/lib/dashboards/failed-test-cases-card/failed-test-cases-card.component.mjs +7 -3
  5. package/esm2020/lib/dashboards/heat-error-map-cell/heat-error-map-cell.component.mjs +5 -3
  6. package/esm2020/lib/dashboards/insight-card/insight-card.component.mjs +3 -3
  7. package/esm2020/lib/dashboards/test-distribution-card/test-distribution-card.component.mjs +3 -3
  8. package/esm2020/lib/dynamic-select/dynamic-select-field.component.mjs +82 -5
  9. package/esm2020/lib/filters/dynamic-filter/dynamic-filter.component.mjs +62 -13
  10. package/esm2020/lib/segment-control/segment-control.component.mjs +30 -11
  11. package/esm2020/lib/table/dynamic-table/dynamic-table.component.mjs +38 -9
  12. package/esm2020/lib/templates/table-template.component.mjs +7 -24
  13. package/esm2020/lib/ui-kit.module.mjs +7 -3
  14. package/fesm2015/cqa-lib-cqa-ui.mjs +259 -73
  15. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  16. package/fesm2020/cqa-lib-cqa-ui.mjs +254 -69
  17. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  18. package/lib/dashboards/chart-card/chart-card.component.d.ts +2 -1
  19. package/lib/dashboards/dashboard-header/dashboard-header.component.d.ts +6 -1
  20. package/lib/dashboards/failed-test-cases-card/failed-test-cases-card.component.d.ts +3 -1
  21. package/lib/dynamic-select/dynamic-select-field.component.d.ts +16 -4
  22. package/lib/filters/dynamic-filter/dynamic-filter.component.d.ts +14 -1
  23. package/lib/segment-control/segment-control.component.d.ts +8 -0
  24. package/lib/table/dynamic-table/dynamic-table.component.d.ts +18 -0
  25. package/lib/templates/table-template.component.d.ts +0 -2
  26. package/lib/ui-kit.module.d.ts +2 -0
  27. package/package.json +1 -1
  28. package/styles.css +1 -1
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, Input, ViewChild, ElementRef, HostListener } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, Input, ViewChild, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  import * as i1 from "@angular/material/form-field";
4
4
  import * as i2 from "@angular/material/select";
@@ -7,6 +7,7 @@ import * as i4 from "@angular/forms";
7
7
  import * as i5 from "@angular/common";
8
8
  export class DynamicSelectFieldComponent {
9
9
  constructor() {
10
+ this.selectionChange = new EventEmitter();
10
11
  // Must be public for template access in Angular's strict template checking mode
11
12
  this.searchTextByKey = {};
12
13
  }
@@ -14,11 +15,24 @@ export class DynamicSelectFieldComponent {
14
15
  if (!this.config || !this.config.key) {
15
16
  throw new Error('cqa-dynamic-select: input "config.key" is required.');
16
17
  }
18
+ this.applySelectedValueIfNeeded();
19
+ }
20
+ get displayPlaceholder() {
21
+ const key = this.config?.key;
22
+ if (!key || !this.form)
23
+ return this.config?.placeholder;
24
+ const controlValue = this.form.get(key)?.value;
25
+ const value = this.hasExistingValue(controlValue) ? controlValue : this.config?.selectedValue;
26
+ return this.hasExistingValue(value) ? undefined : this.config?.placeholder;
17
27
  }
18
28
  ngOnChanges(changes) {
19
29
  if ('config' in changes) {
20
30
  // When config changes (including toggling multiple), ensure control value shape matches
21
31
  this.syncControlValueForMultipleMode();
32
+ this.applySelectedValueIfNeeded();
33
+ }
34
+ if ('form' in changes && !changes['form'].firstChange) {
35
+ this.applySelectedValueIfNeeded();
22
36
  }
23
37
  }
24
38
  get panelClass() {
@@ -65,6 +79,54 @@ export class DynamicSelectFieldComponent {
65
79
  control.setValue(currentValue.length ? currentValue[0] : null, { emitEvent: false });
66
80
  }
67
81
  }
82
+ applySelectedValueIfNeeded() {
83
+ const key = this.config?.key;
84
+ if (!key || !this.form)
85
+ return;
86
+ const control = this.form.get(key);
87
+ if (!control)
88
+ return;
89
+ const selectedValue = this.config?.selectedValue;
90
+ if (selectedValue === undefined || selectedValue === null) {
91
+ // If consumer explicitly clears selectedValue, ensure the control is cleared so placeholder shows.
92
+ if (this.isMultiple && control.value !== null && control.value !== undefined && control.value.length) {
93
+ control.setValue([], { emitEvent: false });
94
+ }
95
+ else if (!this.isMultiple && this.hasExistingValue(control.value)) {
96
+ control.setValue(null, { emitEvent: false });
97
+ }
98
+ return;
99
+ }
100
+ const currentValue = control.value;
101
+ if (this.hasExistingValue(currentValue))
102
+ return;
103
+ if (this.isMultiple) {
104
+ const normalized = (Array.isArray(selectedValue) ? selectedValue : [selectedValue]).filter((val) => val !== undefined);
105
+ if (!normalized.length)
106
+ return;
107
+ control.setValue(normalized, { emitEvent: false });
108
+ }
109
+ else {
110
+ const normalized = Array.isArray(selectedValue)
111
+ ? (selectedValue.length ? selectedValue[0] : undefined)
112
+ : selectedValue;
113
+ if (normalized === undefined)
114
+ return;
115
+ control.setValue(normalized, { emitEvent: false });
116
+ }
117
+ }
118
+ hasExistingValue(value) {
119
+ if (value === null || value === undefined) {
120
+ return false;
121
+ }
122
+ if (Array.isArray(value)) {
123
+ return value.some((val) => val !== null && val !== undefined && val !== '');
124
+ }
125
+ if (typeof value === 'string') {
126
+ return value.trim().length > 0;
127
+ }
128
+ return true;
129
+ }
68
130
  onSelectOpenedChange(opened, _select) {
69
131
  if (!opened) {
70
132
  // Reset search text on close so the next open shows full list
@@ -99,7 +161,7 @@ export class DynamicSelectFieldComponent {
99
161
  });
100
162
  }
101
163
  // Close when an option is selected if requested. Always close for single-select.
102
- onOptionSelected(select) {
164
+ onSelectionChange(event, select) {
103
165
  // Let Angular Material auto-close for single-select.
104
166
  // For multi-select, close only if explicitly requested.
105
167
  const shouldClose = this.isMultiple ? !!this.config?.closeOnSelect : false;
@@ -113,6 +175,19 @@ export class DynamicSelectFieldComponent {
113
175
  if (this.config?.searchable && this.config?.key) {
114
176
  this.searchTextByKey[this.config.key] = '';
115
177
  }
178
+ if (typeof this.config?.onChange === 'function') {
179
+ try {
180
+ this.config.onChange(event.value, event);
181
+ }
182
+ catch (error) {
183
+ console.error('cqa-dynamic-select onChange handler error:', error);
184
+ }
185
+ }
186
+ this.selectionChange.emit({
187
+ key: this.config?.key,
188
+ value: event.value,
189
+ event,
190
+ });
116
191
  }
117
192
  handleDocumentClick(event) {
118
193
  // Close when clicking outside of the trigger and outside of the open panel
@@ -139,14 +214,16 @@ export class DynamicSelectFieldComponent {
139
214
  }
140
215
  }
141
216
  DynamicSelectFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
- DynamicSelectFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: { form: "form", config: "config" }, host: { listeners: { "document:click": "handleDocumentClick($event)" } }, viewQueries: [{ propertyName: "selectRef", first: true, predicate: ["selectRef"], descendants: true }, { propertyName: "hostEl", first: true, predicate: ["host"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div id=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"config.placeholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onOptionSelected(selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n\n <mat-option *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\"\n [textContent]=\"opt.name ?? opt.label ?? opt.value\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </mat-option>\n </mat-select>\n\n <div>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", components: [{ type: i1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
217
+ DynamicSelectFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: { form: "form", config: "config" }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "document:click": "handleDocumentClick($event)" } }, viewQueries: [{ propertyName: "selectRef", first: true, predicate: ["selectRef"], descendants: true }, { propertyName: "hostEl", first: true, predicate: ["host"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div id=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n\n <mat-option *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\"\n [textContent]=\"opt.name ?? opt.label ?? opt.value\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </mat-option>\n </mat-select>\n\n <div>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", components: [{ type: i1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
143
218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicSelectFieldComponent, decorators: [{
144
219
  type: Component,
145
- args: [{ selector: 'cqa-dynamic-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div id=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"config.placeholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onOptionSelected(selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n\n <mat-option *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\"\n [textContent]=\"opt.name ?? opt.label ?? opt.value\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </mat-option>\n </mat-select>\n\n <div>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", styles: [] }]
220
+ args: [{ selector: 'cqa-dynamic-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div id=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n\n <mat-option *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\"\n [textContent]=\"opt.name ?? opt.label ?? opt.value\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </mat-option>\n </mat-select>\n\n <div>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", styles: [] }]
146
221
  }], propDecorators: { form: [{
147
222
  type: Input
148
223
  }], config: [{
149
224
  type: Input
225
+ }], selectionChange: [{
226
+ type: Output
150
227
  }], selectRef: [{
151
228
  type: ViewChild,
152
229
  args: ['selectRef', { static: false }]
@@ -157,4 +234,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
157
234
  type: HostListener,
158
235
  args: ['document:click', ['$event']]
159
236
  }] } });
160
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2R5bmFtaWMtc2VsZWN0L2R5bmFtaWMtc2VsZWN0LWZpZWxkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFvQyxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQThCakosTUFBTSxPQUFPLDJCQUEyQjtJQU54QztRQWFFLGdGQUFnRjtRQUNoRixvQkFBZSxHQUEyQixFQUFFLENBQUM7S0FtSTlDO0lBaElDLFFBQVE7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQztTQUN4RTtJQUNILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxRQUFRLElBQUksT0FBTyxFQUFFO1lBQ3ZCLHdGQUF3RjtZQUN4RixJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQztTQUN4QztJQUNILENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixPQUFPLG9CQUFvQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3hFLENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMvQyxDQUFD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c0JBQTdELFNBQVM7dUJBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQWlIdEQsbUJBQW1CO3NCQURsQixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcblxuLy8gTG9jYWwgb3B0aW9uIG1vZGVsIChwcmV2aW91c2x5IGltcG9ydGVkIGZyb20gcmVtb3ZlZCBjcWEtc2VsZWN0IGNvbXBvbmVudClcbmV4cG9ydCBpbnRlcmZhY2UgU2VsZWN0T3B0aW9uIHtcbiAgaWQ/OiBhbnk7XG4gIHZhbHVlPzogYW55O1xuICBuYW1lPzogc3RyaW5nO1xuICBsYWJlbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICBrZXk6IHN0cmluZztcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIG11bHRpcGxlPzogYm9vbGVhbjtcbiAgc2VhcmNoYWJsZT86IGJvb2xlYW47XG4gIC8qKiBJZiB0cnVlLCBjbG9zZSB0aGUgcGFuZWwgd2hlbiBhbiBvcHRpb24gaXMgc2VsZWN0ZWQgKHVzZWZ1bCBmb3IgbXVsdGktc2VsZWN0IGluIGhlYWRlcnMpLiAqL1xuICBjbG9zZU9uU2VsZWN0PzogYm9vbGVhbjtcbiAgb3B0aW9uczogU2VsZWN0T3B0aW9uW107XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NxYS1keW5hbWljLXNlbGVjdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGZvcm0hOiBGb3JtR3JvdXA7XG4gIEBJbnB1dCgpIGNvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcblxuICBAVmlld0NoaWxkKCdzZWxlY3RSZWYnLCB7IHN0YXRpYzogZmFsc2UgfSkgc2VsZWN0UmVmPzogTWF0U2VsZWN0O1xuICBAVmlld0NoaWxkKCdob3N0JywgeyBzdGF0aWM6IGZhbHNlLCByZWFkOiBFbGVtZW50UmVmIH0pIGhvc3RFbD86IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIC8vIE11c3QgYmUgcHVibGljIGZvciB0ZW1wbGF0ZSBhY2Nlc3MgaW4gQW5ndWxhcidzIHN0cmljdCB0ZW1wbGF0ZSBjaGVja2luZyBtb2RlXG4gIHNlYXJjaFRleHRCeUtleTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBwcml2YXRlIG91dHNpZGVDbGVhbnVwPzogKCkgPT4gdm9pZDtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnIHx8ICF0aGlzLmNvbmZpZy5rZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3FhLWR5bmFtaWMtc2VsZWN0OiBpbnB1dCBcImNvbmZpZy5rZXlcIiBpcyByZXF1aXJlZC4nKTtcbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKCdjb25maWcnIGluIGNoYW5nZXMpIHtcbiAgICAgIC8vIFdoZW4gY29uZmlnIGNoYW5nZXMgKGluY2x1ZGluZyB0b2dnbGluZyBtdWx0aXBsZSksIGVuc3VyZSBjb250cm9sIHZhbHVlIHNoYXBlIG1hdGNoZXNcbiAgICAgIHRoaXMuc3luY0NvbnRyb2xWYWx1ZUZvck11bHRpcGxlTW9kZSgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBwYW5lbENsYXNzKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBjdGMtc2VsZWN0LXBhbmVsICR7dGhpcy5pc011bHRpcGxlID8gJ211bHRpcGxlJyA6ICcnfWAudHJpbSgpO1xuICB9XG5cbiAgZ2V0IGlzTXVsdGlwbGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudG9Cb29sZWFuKHRoaXMuY29uZmlnPy5tdWx0aXBsZSk7XG4gIH1cblxuICBnZXQgaXNEaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy50b0Jvb2xlYW4odGhpcy5jb25maWc/LmRpc2FibGVkKTtcbiAgfVxuXG4gIHByaXZhdGUgdG9Cb29sZWFuKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IHYgPSB2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICh2ID09PSAndHJ1ZScgfHwgdiA9PT0gJzEnKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmICh2ID09PSAnZmFsc2UnIHx8IHYgPT09ICcwJyB8fCB2ID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHRydWU7IC8vIGFueSBvdGhlciBub24tZW1wdHkgc3RyaW5nIHRyZWF0ZWQgYXMgdHJ1dGh5XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT09IDA7XG4gICAgfVxuICAgIHJldHVybiAhIXZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jQ29udHJvbFZhbHVlRm9yTXVsdGlwbGVNb2RlKCk6IHZvaWQge1xuICAgIGNvbnN0IGtleSA9IHRoaXMuY29uZmlnPy5rZXk7XG4gICAgaWYgKCFrZXkgfHwgIXRoaXMuZm9ybSkgcmV0dXJuO1xuICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGtleSk7XG4gICAgaWYgKCFjb250cm9sKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudFZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBpZiAodGhpcy5pc011bHRpcGxlKSB7XG4gICAgICBpZiAoY3VycmVudFZhbHVlID09IG51bGwpIHJldHVybjtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnRWYWx1ZSkpIHJldHVybjtcbiAgICAgIGNvbnRyb2wuc2V0VmFsdWUoW2N1cnJlbnRWYWx1ZV0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGN1cnJlbnRWYWx1ZSkpIHJldHVybjtcbiAgICAgIGNvbnRyb2wuc2V0VmFsdWUoY3VycmVudFZhbHVlLmxlbmd0aCA/IGN1cnJlbnRWYWx1ZVswXSA6IG51bGwsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB9XG4gIH1cblxuICBvblNlbGVjdE9wZW5lZENoYW5nZShvcGVuZWQ6IGJvb2xlYW4sIF9zZWxlY3Q6IE1hdFNlbGVjdCk6IHZvaWQge1xuICAgIGlmICghb3BlbmVkKSB7XG4gICAgICAvLyBSZXNldCBzZWFyY2ggdGV4dCBvbiBjbG9zZSBzbyB0aGUgbmV4dCBvcGVuIHNob3dzIGZ1bGwgbGlzdFxuICAgICAgaWYgKHRoaXMuY29uZmlnPy5rZXkpIHtcbiAgICAgICAgdGhpcy5zZWFyY2hUZXh0QnlLZXlbdGhpcy5jb25maWcua2V5XSA9ICcnO1xuICAgICAgfVxuICAgICAgLy8gRW5zdXJlIGFueSBwcmV2aW91cyBjdXN0b20gbGlzdGVuZXJzIGFyZSBjbGVhcmVkIChsZWdhY3kgY29tcGF0aWJpbGl0eSlcbiAgICAgIGlmICh0aGlzLm91dHNpZGVDbGVhbnVwKSB7XG4gICAgICAgIHRoaXMub3V0c2lkZUNsZWFudXAoKTtcbiAgICAgICAgdGhpcy5vdXRzaWRlQ2xlYW51cCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBGb2N1cyB0aGUgc2VhcmNoIGJveCBpZiBlbmFibGVkXG4gICAgaWYgKHRoaXMuY29uZmlnPy5zZWFyY2hhYmxlKSB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxJbnB1dEVsZW1lbnQ+KCcudHMtc2VsZWN0LXNlYXJjaC1pbnB1dCcpO1xuICAgICAgICBpbnB1dD8uZm9jdXMoKTtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VhcmNoKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hUZXh0QnlLZXlba2V5XSA9IHZhbHVlID8/ICcnO1xuICB9XG5cbiAgZmlsdGVyZWRPcHRpb25zKGM6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyk6IFNlbGVjdE9wdGlvbltdIHtcbiAgICBjb25zdCB0ID0gKHRoaXMuc2VhcmNoVGV4dEJ5S2V5W2Mua2V5XSB8fCAnJykudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgaWYgKCF0KSByZXR1cm4gYy5vcHRpb25zIHx8IFtdO1xuICAgIHJldHVybiAoYy5vcHRpb25zIHx8IFtdKS5maWx0ZXIoKG9wdCkgPT4ge1xuICAgICAgY29uc3QgdGV4dCA9IFN0cmluZyhvcHQubmFtZSA/PyBvcHQubGFiZWwgPz8gb3B0LnZhbHVlID8/ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgcmV0dXJuIHRleHQuaW5jbHVkZXModCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBDbG9zZSB3aGVuIGFuIG9wdGlvbiBpcyBzZWxlY3RlZCBpZiByZXF1ZXN0ZWQuIEFsd2F5cyBjbG9zZSBmb3Igc2luZ2xlLXNlbGVjdC5cbiAgb25PcHRpb25TZWxlY3RlZChzZWxlY3Q6IE1hdFNlbGVjdCk6IHZvaWQge1xuICAgIC8vIExldCBBbmd1bGFyIE1hdGVyaWFsIGF1dG8tY2xvc2UgZm9yIHNpbmdsZS1zZWxlY3QuXG4gICAgLy8gRm9yIG11bHRpLXNlbGVjdCwgY2xvc2Ugb25seSBpZiBleHBsaWNpdGx5IHJlcXVlc3RlZC5cbiAgICBjb25zdCBzaG91bGRDbG9zZSA9IHRoaXMuaXNNdWx0aXBsZSA/ICEhdGhpcy5jb25maWc/LmNsb3NlT25TZWxlY3QgOiBmYWxzZTtcbiAgICBpZiAoc2hvdWxkQ2xvc2UpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNlbGVjdC5jbG9zZSgpO1xuICAgICAgfSBjYXRjaCB7fVxuICAgIH1cbiAgICAvLyBJZiBzZWFyY2hhYmxlLCBjbGVhciB0aGUgc2VhcmNoIGFmdGVyIHNlbGVjdGlvbiBzbyByZW9wZW5pbmcgd29ya3MgcHJlZGljdGFibHlcbiAgICBpZiAodGhpcy5jb25maWc/LnNlYXJjaGFibGUgJiYgdGhpcy5jb25maWc/LmtleSkge1xuICAgICAgdGhpcy5zZWFyY2hUZXh0QnlLZXlbdGhpcy5jb25maWcua2V5XSA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgaGFuZGxlRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIC8vIENsb3NlIHdoZW4gY2xpY2tpbmcgb3V0c2lkZSBvZiB0aGUgdHJpZ2dlciBhbmQgb3V0c2lkZSBvZiB0aGUgb3BlbiBwYW5lbFxuICAgIGlmICghdGhpcy5zZWxlY3RSZWY/LnBhbmVsT3Blbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgLy8gSWYgY2xpY2sgaXMgaW5zaWRlIHRoZSBjb21wb25lbnQgaG9zdCwgaWdub3JlXG4gICAgaWYgKHRoaXMuaG9zdEVsPy5uYXRpdmVFbGVtZW50ICYmIHRoaXMuaG9zdEVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBJZiBjbGljayBpcyBpbnNpZGUgYW55IG9wZW4gbWF0LXNlbGVjdCBwYW5lbCwgaWdub3JlXG4gICAgY29uc3QgcGFuZWxFbHMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5tYXQtc2VsZWN0LXBhbmVsJykpIGFzIEhUTUxFbGVtZW50W107XG4gICAgY29uc3QgY2xpY2tJbnNpZGVQYW5lbCA9IHBhbmVsRWxzLnNvbWUoKGVsKSA9PiBlbC5jb250YWlucyh0YXJnZXQpKTtcbiAgICBpZiAoY2xpY2tJbnNpZGVQYW5lbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdGhpcy5zZWxlY3RSZWYuY2xvc2UoKTtcbiAgICB9IGNhdGNoIHt9XG4gIH1cbn1cblxuXG4iLCI8ZGl2IGlkPVwiY3FhLXVpLXJvb3RcIj5cbiAgPG5nLWNvbnRhaW5lciBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICA8bGFiZWwgKm5nSWY9XCJjb25maWcubGFiZWxcIlxuICAgICAgY2xhc3M9XCJmb3JtLWxhYmVsIGNxYS10ZXh0LVsjMzc0MTUxXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS1ibG9jayBjcWEtbGVhZGluZy1bMS40XSBjcWEtbWItMlwiPnt7XG4gICAgICBjb25maWcubGFiZWwgfX08L2xhYmVsPlxuICAgIDxtYXQtZm9ybS1maWVsZCAjaG9zdCBjbGFzcz1cIm1hdC1zZWxlY3QtY3VzdG9tIGNxYS13LWZ1bGxcIiBhcHBlYXJhbmNlPVwiZmlsbFwiPlxuICAgICAgPG1hdC1zZWxlY3QgI3NlbGVjdFJlZj1cIm1hdFNlbGVjdFwiIFtwbGFjZWhvbGRlcl09XCJjb25maWcucGxhY2Vob2xkZXJcIiBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiIFttdWx0aXBsZV09XCJpc011bHRpcGxlXCJcbiAgICAgICAgZGlzYWJsZU9wdGlvbkNlbnRlcmluZyBbcGFuZWxDbGFzc109XCJwYW5lbENsYXNzXCIgW2Zvcm1Db250cm9sTmFtZV09XCJjb25maWcua2V5XCJcbiAgICAgICAgKG9wZW5lZENoYW5nZSk9XCJvblNlbGVjdE9wZW5lZENoYW5nZSgkZXZlbnQsIHNlbGVjdFJlZilcIiAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uT3B0aW9uU2VsZWN0ZWQoc2VsZWN0UmVmKVwiPlxuXG4gICAgICAgIDxtYXQtb3B0aW9uICpuZ0lmPVwiY29uZmlnLnNlYXJjaGFibGVcIiBjbGFzcz1cInRzLXNlbGVjdC1zZWFyY2hcIiBkaXNhYmxlZD5cbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0cy1zZWxlY3Qtc2VhcmNoLWlucHV0XCIgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwic2VhcmNoVGV4dEJ5S2V5W2NvbmZpZy5rZXldIHx8ICcnXCJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoaW5wdXQpPVwib25TZWFyY2goY29uZmlnLmtleSwgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIiAvPlxuICAgICAgICA8L21hdC1vcHRpb24+XG5cbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBmaWx0ZXJlZE9wdGlvbnMoY29uZmlnKVwiIFt2YWx1ZV09XCJvcHQuaWQgPz8gb3B0LnZhbHVlXCJcbiAgICAgICAgICBbdGV4dENvbnRlbnRdPVwib3B0Lm5hbWUgPz8gb3B0LmxhYmVsID8/IG9wdC52YWx1ZVwiPlxuICAgICAgICAgIHt7IG9wdC5uYW1lID8/IG9wdC5sYWJlbCA/PyBvcHQudmFsdWUgfX1cbiAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgPC9tYXQtc2VsZWN0PlxuXG4gICAgICA8ZGl2PlxuICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICA8cGF0aCBkPVwiTTQgNkw4IDEwTDEyIDZcIiBzdHJva2U9XCIjMEEwQTBBXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvZGl2PlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+Il19
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2R5bmFtaWMtc2VsZWN0L2R5bmFtaWMtc2VsZWN0LWZpZWxkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFvQyxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7O0FBa0N2SyxNQUFNLE9BQU8sMkJBQTJCO0lBTnhDO1FBU1ksb0JBQWUsR0FBRyxJQUFJLFlBQVksRUFBdUQsQ0FBQztRQUtwRyxnRkFBZ0Y7UUFDaEYsb0JBQWUsR0FBMkIsRUFBRSxDQUFDO0tBNk05QztJQTFNQyxRQUFRO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7U0FDeEU7UUFDRCxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRUQsSUFBSSxrQkFBa0I7UUFDcEIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQztRQUN4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUM7UUFDL0Ms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a0RDeEN0RCxtdkRBK0JNOzJGREdPLDJCQUEyQjtrQkFOdkMsU0FBUzsrQkFDRSxvQkFBb0IsbUJBR2IsdUJBQXVCLENBQUMsTUFBTTs4QkFHdEMsSUFBSTtzQkFBWixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDSSxlQUFlO3NCQUF4QixNQUFNO2dCQUVvQyxTQUFTO3NCQUFuRCxTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBQ2UsTUFBTTtzQkFBN0QsU0FBUzt1QkFBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUU7Z0JBMkx0RCxtQkFBbUI7c0JBRGxCLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0U2VsZWN0LCBNYXRTZWxlY3RDaGFuZ2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuXG4vLyBMb2NhbCBvcHRpb24gbW9kZWwgKHByZXZpb3VzbHkgaW1wb3J0ZWQgZnJvbSByZW1vdmVkIGNxYS1zZWxlY3QgY29tcG9uZW50KVxuZXhwb3J0IGludGVyZmFjZSBTZWxlY3RPcHRpb24ge1xuICBpZD86IGFueTtcbiAgdmFsdWU/OiBhbnk7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIGxhYmVsPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gIGtleTogc3RyaW5nO1xuICBsYWJlbD86IHN0cmluZztcbiAgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gIGRpc2FibGVkPzogYm9vbGVhbjtcbiAgbXVsdGlwbGU/OiBib29sZWFuO1xuICBzZWFyY2hhYmxlPzogYm9vbGVhbjtcbiAgLyoqIElmIHRydWUsIGNsb3NlIHRoZSBwYW5lbCB3aGVuIGFuIG9wdGlvbiBpcyBzZWxlY3RlZCAodXNlZnVsIGZvciBtdWx0aS1zZWxlY3QgaW4gaGVhZGVycykuICovXG4gIGNsb3NlT25TZWxlY3Q/OiBib29sZWFuO1xuICAvKiogUHJvdmlkZSBhIGRlZmF1bHQgc2VsZWN0ZWQgdmFsdWUgKG9yIGFycmF5IGZvciBtdWx0aS1zZWxlY3QpIGlmIHRoZSBjb250cm9sIGhhcyBubyB2YWx1ZSB5ZXQuICovXG4gIHNlbGVjdGVkVmFsdWU/OiBhbnkgfCBhbnlbXTtcbiAgLyoqIE9wdGlvbmFsIGNhbGxiYWNrIGludm9rZWQgd2hlbmV2ZXIgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLiAqL1xuICBvbkNoYW5nZT86ICh2YWx1ZTogYW55LCBldmVudD86IE1hdFNlbGVjdENoYW5nZSkgPT4gdm9pZDtcbiAgb3B0aW9uczogU2VsZWN0T3B0aW9uW107XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NxYS1keW5hbWljLXNlbGVjdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljU2VsZWN0RmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGZvcm0hOiBGb3JtR3JvdXA7XG4gIEBJbnB1dCgpIGNvbmZpZyE6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZztcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBrZXk6IHN0cmluZzsgdmFsdWU6IGFueTsgZXZlbnQ6IE1hdFNlbGVjdENoYW5nZSB9PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3NlbGVjdFJlZicsIHsgc3RhdGljOiBmYWxzZSB9KSBzZWxlY3RSZWY/OiBNYXRTZWxlY3Q7XG4gIEBWaWV3Q2hpbGQoJ2hvc3QnLCB7IHN0YXRpYzogZmFsc2UsIHJlYWQ6IEVsZW1lbnRSZWYgfSkgaG9zdEVsPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgLy8gTXVzdCBiZSBwdWJsaWMgZm9yIHRlbXBsYXRlIGFjY2VzcyBpbiBBbmd1bGFyJ3Mgc3RyaWN0IHRlbXBsYXRlIGNoZWNraW5nIG1vZGVcbiAgc2VhcmNoVGV4dEJ5S2V5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByaXZhdGUgb3V0c2lkZUNsZWFudXA/OiAoKSA9PiB2b2lkO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb25maWcgfHwgIXRoaXMuY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcWEtZHluYW1pYy1zZWxlY3Q6IGlucHV0IFwiY29uZmlnLmtleVwiIGlzIHJlcXVpcmVkLicpO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5U2VsZWN0ZWRWYWx1ZUlmTmVlZGVkKCk7XG4gIH1cblxuICBnZXQgZGlzcGxheVBsYWNlaG9sZGVyKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5jb25maWc/LmtleTtcbiAgICBpZiAoIWtleSB8fCAhdGhpcy5mb3JtKSByZXR1cm4gdGhpcy5jb25maWc/LnBsYWNlaG9sZGVyO1xuICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IHRoaXMuZm9ybS5nZXQoa2V5KT8udmFsdWU7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmhhc0V4aXN0aW5nVmFsdWUoY29udHJvbFZhbHVlKSA/IGNvbnRyb2xWYWx1ZSA6IHRoaXMuY29uZmlnPy5zZWxlY3RlZFZhbHVlO1xuICAgIHJldHVybiB0aGlzLmhhc0V4aXN0aW5nVmFsdWUodmFsdWUpID8gdW5kZWZpbmVkIDogdGhpcy5jb25maWc/LnBsYWNlaG9sZGVyO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICgnY29uZmlnJyBpbiBjaGFuZ2VzKSB7XG4gICAgICAvLyBXaGVuIGNvbmZpZyBjaGFuZ2VzIChpbmNsdWRpbmcgdG9nZ2xpbmcgbXVsdGlwbGUpLCBlbnN1cmUgY29udHJvbCB2YWx1ZSBzaGFwZSBtYXRjaGVzXG4gICAgICB0aGlzLnN5bmNDb250cm9sVmFsdWVGb3JNdWx0aXBsZU1vZGUoKTtcbiAgICAgIHRoaXMuYXBwbHlTZWxlY3RlZFZhbHVlSWZOZWVkZWQoKTtcbiAgICB9XG4gICAgaWYgKCdmb3JtJyBpbiBjaGFuZ2VzICYmICFjaGFuZ2VzWydmb3JtJ10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMuYXBwbHlTZWxlY3RlZFZhbHVlSWZOZWVkZWQoKTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFuZWxDbGFzcygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgY3RjLXNlbGVjdC1wYW5lbCAke3RoaXMuaXNNdWx0aXBsZSA/ICdtdWx0aXBsZScgOiAnJ31gLnRyaW0oKTtcbiAgfVxuXG4gIGdldCBpc011bHRpcGxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRvQm9vbGVhbih0aGlzLmNvbmZpZz8ubXVsdGlwbGUpO1xuICB9XG5cbiAgZ2V0IGlzRGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudG9Cb29sZWFuKHRoaXMuY29uZmlnPy5kaXNhYmxlZCk7XG4gIH1cblxuICBwcml2YXRlIHRvQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCB2ID0gdmFsdWUudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAodiA9PT0gJ3RydWUnIHx8IHYgPT09ICcxJykgcmV0dXJuIHRydWU7XG4gICAgICBpZiAodiA9PT0gJ2ZhbHNlJyB8fCB2ID09PSAnMCcgfHwgdiA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB0cnVlOyAvLyBhbnkgb3RoZXIgbm9uLWVtcHR5IHN0cmluZyB0cmVhdGVkIGFzIHRydXRoeVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHZhbHVlICE9PSAwO1xuICAgIH1cbiAgICByZXR1cm4gISF2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3luY0NvbnRyb2xWYWx1ZUZvck11bHRpcGxlTW9kZSgpOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmNvbmZpZz8ua2V5O1xuICAgIGlmICgha2V5IHx8ICF0aGlzLmZvcm0pIHJldHVybjtcbiAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmdldChrZXkpO1xuICAgIGlmICghY29udHJvbCkgcmV0dXJuO1xuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHRoaXMuaXNNdWx0aXBsZSkge1xuICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PSBudWxsKSByZXR1cm47XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyZW50VmFsdWUpKSByZXR1cm47XG4gICAgICBjb250cm9sLnNldFZhbHVlKFtjdXJyZW50VmFsdWVdLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShjdXJyZW50VmFsdWUpKSByZXR1cm47XG4gICAgICBjb250cm9sLnNldFZhbHVlKGN1cnJlbnRWYWx1ZS5sZW5ndGggPyBjdXJyZW50VmFsdWVbMF0gOiBudWxsLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVNlbGVjdGVkVmFsdWVJZk5lZWRlZCgpOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmNvbmZpZz8ua2V5O1xuICAgIGlmICgha2V5IHx8ICF0aGlzLmZvcm0pIHJldHVybjtcbiAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmdldChrZXkpO1xuICAgIGlmICghY29udHJvbCkgcmV0dXJuO1xuICAgIGNvbnN0IHNlbGVjdGVkVmFsdWUgPSB0aGlzLmNvbmZpZz8uc2VsZWN0ZWRWYWx1ZTtcbiAgICBpZiAoc2VsZWN0ZWRWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHNlbGVjdGVkVmFsdWUgPT09IG51bGwpIHtcbiAgICAgIC8vIElmIGNvbnN1bWVyIGV4cGxpY2l0bHkgY2xlYXJzIHNlbGVjdGVkVmFsdWUsIGVuc3VyZSB0aGUgY29udHJvbCBpcyBjbGVhcmVkIHNvIHBsYWNlaG9sZGVyIHNob3dzLlxuICAgICAgaWYgKHRoaXMuaXNNdWx0aXBsZSAmJiBjb250cm9sLnZhbHVlICE9PSBudWxsICYmIGNvbnRyb2wudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBjb250cm9sLnZhbHVlLmxlbmd0aCkge1xuICAgICAgICBjb250cm9sLnNldFZhbHVlKFtdLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLmlzTXVsdGlwbGUgJiYgdGhpcy5oYXNFeGlzdGluZ1ZhbHVlKGNvbnRyb2wudmFsdWUpKSB7XG4gICAgICAgIGNvbnRyb2wuc2V0VmFsdWUobnVsbCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHRoaXMuaGFzRXhpc3RpbmdWYWx1ZShjdXJyZW50VmFsdWUpKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5pc011bHRpcGxlKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gKEFycmF5LmlzQXJyYXkoc2VsZWN0ZWRWYWx1ZSkgPyBzZWxlY3RlZFZhbHVlIDogW3NlbGVjdGVkVmFsdWVdKS5maWx0ZXIoXG4gICAgICAgICh2YWwpID0+IHZhbCAhPT0gdW5kZWZpbmVkLFxuICAgICAgKTtcbiAgICAgIGlmICghbm9ybWFsaXplZC5sZW5ndGgpIHJldHVybjtcbiAgICAgIGNvbnRyb2wuc2V0VmFsdWUobm9ybWFsaXplZCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gQXJyYXkuaXNBcnJheShzZWxlY3RlZFZhbHVlKVxuICAgICAgICA/IChzZWxlY3RlZFZhbHVlLmxlbmd0aCA/IHNlbGVjdGVkVmFsdWVbMF0gOiB1bmRlZmluZWQpXG4gICAgICAgIDogc2VsZWN0ZWRWYWx1ZTtcbiAgICAgIGlmIChub3JtYWxpemVkID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGNvbnRyb2wuc2V0VmFsdWUobm9ybWFsaXplZCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFzRXhpc3RpbmdWYWx1ZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWUuc29tZSgodmFsKSA9PiB2YWwgIT09IG51bGwgJiYgdmFsICE9PSB1bmRlZmluZWQgJiYgdmFsICE9PSAnJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsdWUudHJpbSgpLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgb25TZWxlY3RPcGVuZWRDaGFuZ2Uob3BlbmVkOiBib29sZWFuLCBfc2VsZWN0OiBNYXRTZWxlY3QpOiB2b2lkIHtcbiAgICBpZiAoIW9wZW5lZCkge1xuICAgICAgLy8gUmVzZXQgc2VhcmNoIHRleHQgb24gY2xvc2Ugc28gdGhlIG5leHQgb3BlbiBzaG93cyBmdWxsIGxpc3RcbiAgICAgIGlmICh0aGlzLmNvbmZpZz8ua2V5KSB7XG4gICAgICAgIHRoaXMuc2VhcmNoVGV4dEJ5S2V5W3RoaXMuY29uZmlnLmtleV0gPSAnJztcbiAgICAgIH1cbiAgICAgIC8vIEVuc3VyZSBhbnkgcHJldmlvdXMgY3VzdG9tIGxpc3RlbmVycyBhcmUgY2xlYXJlZCAobGVnYWN5IGNvbXBhdGliaWxpdHkpXG4gICAgICBpZiAodGhpcy5vdXRzaWRlQ2xlYW51cCkge1xuICAgICAgICB0aGlzLm91dHNpZGVDbGVhbnVwKCk7XG4gICAgICAgIHRoaXMub3V0c2lkZUNsZWFudXAgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRm9jdXMgdGhlIHNlYXJjaCBib3ggaWYgZW5hYmxlZFxuICAgIGlmICh0aGlzLmNvbmZpZz8uc2VhcmNoYWJsZSkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MSW5wdXRFbGVtZW50PignLnRzLXNlbGVjdC1zZWFyY2gtaW5wdXQnKTtcbiAgICAgICAgaW5wdXQ/LmZvY3VzKCk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVGV4dEJ5S2V5W2tleV0gPSB2YWx1ZSA/PyAnJztcbiAgfVxuXG4gIGZpbHRlcmVkT3B0aW9ucyhjOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcpOiBTZWxlY3RPcHRpb25bXSB7XG4gICAgY29uc3QgdCA9ICh0aGlzLnNlYXJjaFRleHRCeUtleVtjLmtleV0gfHwgJycpLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgIGlmICghdCkgcmV0dXJuIGMub3B0aW9ucyB8fCBbXTtcbiAgICByZXR1cm4gKGMub3B0aW9ucyB8fCBbXSkuZmlsdGVyKChvcHQpID0+IHtcbiAgICAgIGNvbnN0IHRleHQgPSBTdHJpbmcob3B0Lm5hbWUgPz8gb3B0LmxhYmVsID8/IG9wdC52YWx1ZSA/PyAnJykudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiB0ZXh0LmluY2x1ZGVzKHQpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ2xvc2Ugd2hlbiBhbiBvcHRpb24gaXMgc2VsZWN0ZWQgaWYgcmVxdWVzdGVkLiBBbHdheXMgY2xvc2UgZm9yIHNpbmdsZS1zZWxlY3QuXG4gIG9uU2VsZWN0aW9uQ2hhbmdlKGV2ZW50OiBNYXRTZWxlY3RDaGFuZ2UsIHNlbGVjdDogTWF0U2VsZWN0KTogdm9pZCB7XG4gICAgLy8gTGV0IEFuZ3VsYXIgTWF0ZXJpYWwgYXV0by1jbG9zZSBmb3Igc2luZ2xlLXNlbGVjdC5cbiAgICAvLyBGb3IgbXVsdGktc2VsZWN0LCBjbG9zZSBvbmx5IGlmIGV4cGxpY2l0bHkgcmVxdWVzdGVkLlxuICAgIGNvbnN0IHNob3VsZENsb3NlID0gdGhpcy5pc011bHRpcGxlID8gISF0aGlzLmNvbmZpZz8uY2xvc2VPblNlbGVjdCA6IGZhbHNlO1xuICAgIGlmIChzaG91bGRDbG9zZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZWN0LmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIHt9XG4gICAgfVxuICAgIC8vIElmIHNlYXJjaGFibGUsIGNsZWFyIHRoZSBzZWFyY2ggYWZ0ZXIgc2VsZWN0aW9uIHNvIHJlb3BlbmluZyB3b3JrcyBwcmVkaWN0YWJseVxuICAgIGlmICh0aGlzLmNvbmZpZz8uc2VhcmNoYWJsZSAmJiB0aGlzLmNvbmZpZz8ua2V5KSB7XG4gICAgICB0aGlzLnNlYXJjaFRleHRCeUtleVt0aGlzLmNvbmZpZy5rZXldID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmNvbmZpZz8ub25DaGFuZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY29uZmlnLm9uQ2hhbmdlKGV2ZW50LnZhbHVlLCBldmVudCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdjcWEtZHluYW1pYy1zZWxlY3Qgb25DaGFuZ2UgaGFuZGxlciBlcnJvcjonLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdCh7XG4gICAgICBrZXk6IHRoaXMuY29uZmlnPy5rZXksXG4gICAgICB2YWx1ZTogZXZlbnQudmFsdWUsXG4gICAgICBldmVudCxcbiAgICB9KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgaGFuZGxlRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIC8vIENsb3NlIHdoZW4gY2xpY2tpbmcgb3V0c2lkZSBvZiB0aGUgdHJpZ2dlciBhbmQgb3V0c2lkZSBvZiB0aGUgb3BlbiBwYW5lbFxuICAgIGlmICghdGhpcy5zZWxlY3RSZWY/LnBhbmVsT3Blbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgLy8gSWYgY2xpY2sgaXMgaW5zaWRlIHRoZSBjb21wb25lbnQgaG9zdCwgaWdub3JlXG4gICAgaWYgKHRoaXMuaG9zdEVsPy5uYXRpdmVFbGVtZW50ICYmIHRoaXMuaG9zdEVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBJZiBjbGljayBpcyBpbnNpZGUgYW55IG9wZW4gbWF0LXNlbGVjdCBwYW5lbCwgaWdub3JlXG4gICAgY29uc3QgcGFuZWxFbHMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5tYXQtc2VsZWN0LXBhbmVsJykpIGFzIEhUTUxFbGVtZW50W107XG4gICAgY29uc3QgY2xpY2tJbnNpZGVQYW5lbCA9IHBhbmVsRWxzLnNvbWUoKGVsKSA9PiBlbC5jb250YWlucyh0YXJnZXQpKTtcbiAgICBpZiAoY2xpY2tJbnNpZGVQYW5lbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdGhpcy5zZWxlY3RSZWYuY2xvc2UoKTtcbiAgICB9IGNhdGNoIHt9XG4gIH1cbn1cblxuXG4iLCI8ZGl2IGlkPVwiY3FhLXVpLXJvb3RcIj5cbiAgPG5nLWNvbnRhaW5lciBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICA8bGFiZWwgKm5nSWY9XCJjb25maWcubGFiZWxcIlxuICAgICAgY2xhc3M9XCJmb3JtLWxhYmVsIGNxYS10ZXh0LVsjMzc0MTUxXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS1ibG9jayBjcWEtbGVhZGluZy1bMS40XSBjcWEtbWItMlwiPnt7XG4gICAgICBjb25maWcubGFiZWwgfX08L2xhYmVsPlxuICAgIDxtYXQtZm9ybS1maWVsZCAjaG9zdCBjbGFzcz1cIm1hdC1zZWxlY3QtY3VzdG9tIGNxYS13LWZ1bGxcIiBhcHBlYXJhbmNlPVwiZmlsbFwiPlxuICAgICAgPG1hdC1zZWxlY3QgI3NlbGVjdFJlZj1cIm1hdFNlbGVjdFwiIFtwbGFjZWhvbGRlcl09XCJkaXNwbGF5UGxhY2Vob2xkZXJcIiBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiIFttdWx0aXBsZV09XCJpc011bHRpcGxlXCJcbiAgICAgICAgZGlzYWJsZU9wdGlvbkNlbnRlcmluZyBbcGFuZWxDbGFzc109XCJwYW5lbENsYXNzXCIgW2Zvcm1Db250cm9sTmFtZV09XCJjb25maWcua2V5XCJcbiAgICAgICAgKG9wZW5lZENoYW5nZSk9XCJvblNlbGVjdE9wZW5lZENoYW5nZSgkZXZlbnQsIHNlbGVjdFJlZilcIiAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKCRldmVudCwgc2VsZWN0UmVmKVwiPlxuXG4gICAgICAgIDxtYXQtb3B0aW9uICpuZ0lmPVwiY29uZmlnLnNlYXJjaGFibGVcIiBjbGFzcz1cInRzLXNlbGVjdC1zZWFyY2hcIiBkaXNhYmxlZD5cbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0cy1zZWxlY3Qtc2VhcmNoLWlucHV0XCIgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwic2VhcmNoVGV4dEJ5S2V5W2NvbmZpZy5rZXldIHx8ICcnXCJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoaW5wdXQpPVwib25TZWFyY2goY29uZmlnLmtleSwgJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIiAvPlxuICAgICAgICA8L21hdC1vcHRpb24+XG5cbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBmaWx0ZXJlZE9wdGlvbnMoY29uZmlnKVwiIFt2YWx1ZV09XCJvcHQuaWQgPz8gb3B0LnZhbHVlXCJcbiAgICAgICAgICBbdGV4dENvbnRlbnRdPVwib3B0Lm5hbWUgPz8gb3B0LmxhYmVsID8/IG9wdC52YWx1ZVwiPlxuICAgICAgICAgIHt7IG9wdC5uYW1lID8/IG9wdC5sYWJlbCA/PyBvcHQudmFsdWUgfX1cbiAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgPC9tYXQtc2VsZWN0PlxuXG4gICAgICA8ZGl2PlxuICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICA8cGF0aCBkPVwiTTQgNkw4IDEwTDEyIDZcIiBzdHJva2U9XCIjMEEwQTBBXCIgc3Ryb2tlLXdpZHRoPVwiMS4zMzMzM1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxuICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvZGl2PlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+Il19