ngx-st-tables 18.0.18 → 18.0.19

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.
@@ -32,6 +32,7 @@ export class MaterialTableRowCellComponent {
32
32
  this.rowIsExpanded = input(false);
33
33
  this.rowEditing = input(false);
34
34
  this.allowDeleteInEditRow = input(true);
35
+ this.allowEditInEditRow = input(true);
35
36
  this.saveEditRowEmitter = output();
36
37
  this.cancelEditRowEmitter = output();
37
38
  this.editRowEmitter = output();
@@ -159,11 +160,11 @@ export class MaterialTableRowCellComponent {
159
160
  this.changeDetectorRef.detectChanges();
160
161
  }
161
162
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaterialTableRowCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
162
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MaterialTableRowCellComponent, selector: "st-material-table-row-cell", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, rowDataCopy: { classPropertyName: "rowDataCopy", publicName: "rowDataCopy", isSignal: true, isRequired: false, transformFunction: null }, canEditRowValidator: { classPropertyName: "canEditRowValidator", publicName: "canEditRowValidator", isSignal: true, isRequired: false, transformFunction: null }, canDeleteRowValidator: { classPropertyName: "canDeleteRowValidator", publicName: "canDeleteRowValidator", isSignal: true, isRequired: false, transformFunction: null }, selectRowOnlyOne: { classPropertyName: "selectRowOnlyOne", publicName: "selectRowOnlyOne", isSignal: true, isRequired: false, transformFunction: null }, isFirstEditableColumn: { classPropertyName: "isFirstEditableColumn", publicName: "isFirstEditableColumn", isSignal: true, isRequired: false, transformFunction: null }, autoSaveOnChange: { classPropertyName: "autoSaveOnChange", publicName: "autoSaveOnChange", isSignal: true, isRequired: false, transformFunction: null }, rowIsSelected: { classPropertyName: "rowIsSelected", publicName: "rowIsSelected", isSignal: true, isRequired: false, transformFunction: null }, rowIsExpanded: { classPropertyName: "rowIsExpanded", publicName: "rowIsExpanded", isSignal: true, isRequired: false, transformFunction: null }, rowEditing: { classPropertyName: "rowEditing", publicName: "rowEditing", isSignal: true, isRequired: false, transformFunction: null }, allowDeleteInEditRow: { classPropertyName: "allowDeleteInEditRow", publicName: "allowDeleteInEditRow", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saveEditRowEmitter: "saveEditRowEmitter", cancelEditRowEmitter: "cancelEditRowEmitter", editRowEmitter: "editRowEmitter", deleteRowEmitter: "deleteRowEmitter", selectRowChange: "selectRowChange", fieldValueChanged: "fieldValueChanged" }, viewQueries: [{ propertyName: "matInput", first: true, predicate: MatInput, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData(), rowIndex: rowIndex() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView()) ||\r\n (mobileView() && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView() && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"$event.stopPropagation(); saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation(); editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n @if (allowDeleteInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing() || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"text\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"number\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"onNumberFieldChange(column.field, $event)\"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"column.disableEdit ? column.disableEdit(rowData()) : false\"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: ["mat-form-field{padding:0 2px}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i10.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i13.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i13.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "pipe", type: i14.DateFormatPipe, name: "stDateFormatPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
163
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MaterialTableRowCellComponent, selector: "st-material-table-row-cell", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, rowDataCopy: { classPropertyName: "rowDataCopy", publicName: "rowDataCopy", isSignal: true, isRequired: false, transformFunction: null }, canEditRowValidator: { classPropertyName: "canEditRowValidator", publicName: "canEditRowValidator", isSignal: true, isRequired: false, transformFunction: null }, canDeleteRowValidator: { classPropertyName: "canDeleteRowValidator", publicName: "canDeleteRowValidator", isSignal: true, isRequired: false, transformFunction: null }, selectRowOnlyOne: { classPropertyName: "selectRowOnlyOne", publicName: "selectRowOnlyOne", isSignal: true, isRequired: false, transformFunction: null }, isFirstEditableColumn: { classPropertyName: "isFirstEditableColumn", publicName: "isFirstEditableColumn", isSignal: true, isRequired: false, transformFunction: null }, autoSaveOnChange: { classPropertyName: "autoSaveOnChange", publicName: "autoSaveOnChange", isSignal: true, isRequired: false, transformFunction: null }, rowIsSelected: { classPropertyName: "rowIsSelected", publicName: "rowIsSelected", isSignal: true, isRequired: false, transformFunction: null }, rowIsExpanded: { classPropertyName: "rowIsExpanded", publicName: "rowIsExpanded", isSignal: true, isRequired: false, transformFunction: null }, rowEditing: { classPropertyName: "rowEditing", publicName: "rowEditing", isSignal: true, isRequired: false, transformFunction: null }, allowDeleteInEditRow: { classPropertyName: "allowDeleteInEditRow", publicName: "allowDeleteInEditRow", isSignal: true, isRequired: false, transformFunction: null }, allowEditInEditRow: { classPropertyName: "allowEditInEditRow", publicName: "allowEditInEditRow", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saveEditRowEmitter: "saveEditRowEmitter", cancelEditRowEmitter: "cancelEditRowEmitter", editRowEmitter: "editRowEmitter", deleteRowEmitter: "deleteRowEmitter", selectRowChange: "selectRowChange", fieldValueChanged: "fieldValueChanged" }, viewQueries: [{ propertyName: "matInput", first: true, predicate: MatInput, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData(), rowIndex: rowIndex() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView()) ||\r\n (mobileView() && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView() && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"$event.stopPropagation(); saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n\r\n @if (allowEditInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation(); editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n }\r\n\r\n @if (allowDeleteInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing() || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"text\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"number\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"onNumberFieldChange(column.field, $event)\"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"column.disableEdit ? column.disableEdit(rowData()) : false\"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: ["mat-form-field{padding:0 2px}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i10.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i13.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i13.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "pipe", type: i14.DateFormatPipe, name: "stDateFormatPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
163
164
  }
164
165
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaterialTableRowCellComponent, decorators: [{
165
166
  type: Component,
166
- args: [{ selector: 'st-material-table-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData(), rowIndex: rowIndex() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView()) ||\r\n (mobileView() && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView() && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"$event.stopPropagation(); saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation(); editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n @if (allowDeleteInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing() || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"text\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"number\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"onNumberFieldChange(column.field, $event)\"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"column.disableEdit ? column.disableEdit(rowData()) : false\"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: ["mat-form-field{padding:0 2px}\n"] }]
167
+ args: [{ selector: 'st-material-table-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData(), rowIndex: rowIndex() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView()) ||\r\n (mobileView() && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView() && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing() && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"$event.stopPropagation(); saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n\r\n @if (allowEditInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation(); editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n }\r\n\r\n @if (allowDeleteInEditRow()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"$event.stopPropagation(); deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing() || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"text\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n type=\"number\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"onNumberFieldChange(column.field, $event)\"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"column.disableEdit ? column.disableEdit(rowData()) : false\"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [ngModel]=\"getFieldValue(column.field)\"\r\n (ngModelChange)=\"\r\n setFieldValue(column.field, $event);\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"\r\n column.disableEdit ? column.disableEdit(rowData()) : false\r\n \"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: ["mat-form-field{padding:0 2px}\n"] }]
167
168
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { matInput: [{
168
169
  type: ViewChild,
169
170
  args: [MatInput]
@@ -171,4 +172,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
171
172
  type: ViewChild,
172
173
  args: [MatSelect]
173
174
  }] } });
174
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUVULFFBQVEsRUFDUixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7OztBQVFyRCxNQUFNLE9BQU8sNkJBQTZCO0lBZ0R4QyxZQUFvQixpQkFBb0M7UUFBcEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQTVDeEQsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQThCLENBQUM7UUFDdEQsWUFBTyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQTJCLENBQUM7UUFDcEQsYUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUNwQyxnQkFBVyxHQUFHLEtBQUssRUFBMkIsQ0FBQztRQUMvQyx3QkFBbUIsR0FBRyxLQUFLLENBQXdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFD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QUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN4QyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXZCLElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUMzQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMscUJBQXNCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQ3JELENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELHFEQUFxRDtJQUM5QyxzQkFBc0I7UUFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pDLENBQUM7K0dBL0tVLDZCQUE2QjttR0FBN0IsNkJBQTZCLGt1RUFDN0IsUUFBUSw0RUFDUixTQUFTLGdEQ3pCdEIseTdZQTJXQTs7NEZEcFZhLDZCQUE2QjtrQkFOekMsU0FBUzsrQkFDRSw0QkFBNEIsbUJBR3JCLHVCQUF1QixDQUFDLE1BQU07c0ZBRzFCLFFBQVE7c0JBQTVCLFNBQVM7dUJBQUMsUUFBUTtnQkFDRyxTQUFTO3NCQUE5QixTQUFTO3VCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgaW5wdXQsXHJcbiAgb3V0cHV0LFxyXG4gIHNpZ25hbCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBjb21wdXRlZCxcclxuICBlZmZlY3QsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN0TWF0ZXJpYWxUYWJsZUNvbHVtbk1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3N0LW1hdGVyaWFsLXRhYmxlLWNvbHVtbi5tb2RlbCc7XHJcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQgeyBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdzdC1tYXRlcmlhbC10YWJsZS1yb3ctY2VsbCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21hdGVyaWFsLXRhYmxlLXJvdy1jZWxsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9tYXRlcmlhbC10YWJsZS1yb3ctY2VsbC5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWF0ZXJpYWxUYWJsZVJvd0NlbGxDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBWaWV3Q2hpbGQoTWF0SW5wdXQpIG1hdElucHV0PzogTWF0SW5wdXQ7XHJcbiAgQFZpZXdDaGlsZChNYXRTZWxlY3QpIG1hdFNlbGVjdD86IE1hdFNlbGVjdDtcclxuXHJcbiAgY29sdW1uID0gaW5wdXQucmVxdWlyZWQ8U3RNYXRlcmlhbFRhYmxlQ29sdW1uTW9kZWw+KCk7XHJcbiAgcm93RGF0YSA9IGlucHV0LnJlcXVpcmVkPHsgW3Byb3A6IHN0cmluZ106IGFueSB9PigpO1xyXG4gIHJvd0luZGV4ID0gaW5wdXQucmVxdWlyZWQ8bnVtYmVyPigpO1xyXG4gIHJvd0RhdGFDb3B5ID0gaW5wdXQ8eyBbcHJvcDogc3RyaW5nXTogYW55IH0+KCk7XHJcbiAgY2FuRWRpdFJvd1ZhbGlkYXRvciA9IGlucHV0PChyb3c6IGFueSkgPT4gYm9vbGVhbj4oKCkgPT4gdHJ1ZSk7XHJcbiAgY2FuRGVsZXRlUm93VmFsaWRhdG9yID0gaW5wdXQ8KHJvdzogYW55KSA9PiBib29sZWFuPigoKSA9PiB0cnVlKTtcclxuICBzZWxlY3RSb3dPbmx5T25lID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIGlzRmlyc3RFZGl0YWJsZUNvbHVtbiA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBhdXRvU2F2ZU9uQ2hhbmdlID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHJvd0lzU2VsZWN0ZWQgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcbiAgcm93SXNFeHBhbmRlZCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuICByb3dFZGl0aW5nID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIGFsbG93RGVsZXRlSW5FZGl0Um93ID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XHJcblxyXG4gIHNhdmVFZGl0Um93RW1pdHRlciA9IG91dHB1dDx2b2lkPigpO1xyXG4gIGNhbmNlbEVkaXRSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcbiAgZWRpdFJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuICBkZWxldGVSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcbiAgc2VsZWN0Um93Q2hhbmdlID0gb3V0cHV0PGJvb2xlYW4+KCk7XHJcbiAgZmllbGRWYWx1ZUNoYW5nZWQgPSBvdXRwdXQ8eyBmaWVsZDogc3RyaW5nOyB2YWx1ZTogYW55IH0+KCk7XHJcblxyXG4gIG1vYmlsZVZpZXcgPSBzaWduYWwoZmFsc2UpO1xyXG5cclxuICAvLyBDb21wdXRlZCBmb3IgYWN0aW9uIGljb24gY29sb3JzXHJcbiAgYWN0aW9uSWNvbkNvbG9yRGVmOiB7IFtrZXk6IHN0cmluZ106ICdwcmltYXJ5JyB8ICd3YXJuJyB9ID0ge1xyXG4gICAgZWRpdDogJ3ByaW1hcnknLFxyXG4gICAgZGVsZXRlOiAnd2FybicsXHJcbiAgfTtcclxuXHJcbiAgZHluYW1pY1NlbGVjdE9wdGlvbnMgPSBzaWduYWw8eyB2YWx1ZTogYW55OyBsYWJlbDogc3RyaW5nIH1bXT4oW10pO1xyXG5cclxuICAvLyBVc2UgY29tcHV0ZWQgdG8gZGV0ZXJtaW5lIGlmIGR5bmFtaWMgc2VsZWN0IGRhdGEgbmVlZHMgdG8gYmUgbG9hZGVkXHJcbiAgcHJpdmF0ZSBuZWVkc0R5bmFtaWNTZWxlY3QgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBjb25zdCBjb2wgPSB0aGlzLmNvbHVtbigpO1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgY29sPy5hbGxvd0VkaXRDb2x1bW4gJiZcclxuICAgICAgY29sPy5yb3dFZGl0VHlwZSA9PT0gJ2N1c3RvbS1keW5hbWljLXNlbGVjdCcgJiZcclxuICAgICAgISFjb2w/LmR5bmFtaWNSb3dFZGl0T3B0aW9uc1xyXG4gICAgKTtcclxuICB9KTtcclxuXHJcbiAgcHJpdmF0ZSByZXNpemVPYnNlcnZlcj86IFJlc2l6ZU9ic2VydmVyO1xyXG4gIHByaXZhdGUgcHJldmlvdXNSb3dFZGl0aW5nID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XHJcbiAgICAvLyBVc2UgUmVzaXplT2JzZXJ2ZXIgaW5zdGVhZCBvZiB3aW5kb3cgcmVzaXplIGV2ZW50XHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcclxuICAgICAgY29uc3QgaXNNb2JpbGUgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDw9IDExMDA7XHJcbiAgICAgIGlmICh0aGlzLm1vYmlsZVZpZXcoKSAhPT0gaXNNb2JpbGUpIHtcclxuICAgICAgICB0aGlzLm1vYmlsZVZpZXcuc2V0KGlzTW9iaWxlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSk7XHJcblxyXG4gICAgLy8gSW5pdGlhbGl6ZSBtb2JpbGUgdmlldyBzdGF0ZVxyXG4gICAgdGhpcy5tb2JpbGVWaWV3LnNldChkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDw9IDExMDApO1xyXG5cclxuICAgIC8vIEVmZmVjdCB0byBoYW5kbGUgcm93RWRpdGluZyBjaGFuZ2VzXHJcbiAgICBlZmZlY3QoKCkgPT4ge1xyXG4gICAgICBjb25zdCBpc0VkaXRpbmcgPSB0aGlzLnJvd0VkaXRpbmcoKTtcclxuICAgICAgY29uc3Qgd2FzTm90RWRpdGluZyA9ICF0aGlzLnByZXZpb3VzUm93RWRpdGluZztcclxuICAgICAgdGhpcy5wcmV2aW91c1Jvd0VkaXRpbmcgPSBpc0VkaXRpbmc7XHJcblxyXG4gICAgICBpZiAoaXNFZGl0aW5nKSB7XHJcbiAgICAgICAgdGhpcy5nZXREeW5hbWljU2VsZWN0RGF0YSgpO1xyXG5cclxuICAgICAgICAvLyBGb2N1cyBmaXJzdCBlZGl0YWJsZSBmaWVsZCB3aGVuIGVudGVyaW5nIGVkaXQgbW9kZVxyXG4gICAgICAgIGlmICh3YXNOb3RFZGl0aW5nICYmIHRoaXMuaXNGaXJzdEVkaXRhYmxlQ29sdW1uKCkpIHtcclxuICAgICAgICAgIHRoaXMuZm9jdXNGaXJzdEVkaXRhYmxlRmllbGQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgLy8gSWYgcm93IGlzIGFscmVhZHkgaW4gZWRpdCBtb2RlIG9uIGluaXQgKGUuZy4sIG5ld2x5IGFkZGVkIHJvdyksIGZvY3VzIHRoZSBmaWVsZFxyXG4gICAgaWYgKHRoaXMucm93RWRpdGluZygpICYmIHRoaXMuaXNGaXJzdEVkaXRhYmxlQ29sdW1uKCkpIHtcclxuICAgICAgdGhpcy5mb2N1c0ZpcnN0RWRpdGFibGVGaWVsZCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZvY3VzRmlyc3RFZGl0YWJsZUZpZWxkKCkge1xyXG4gICAgLy8gVXNlIHNldFRpbWVvdXQgdG8gZW5zdXJlIHRoZSB2aWV3IGlzIGZ1bGx5IHJlbmRlcmVkXHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgaWYgKHRoaXMubWF0SW5wdXQpIHtcclxuICAgICAgICAvLyBGb2N1cyBNYXRJbnB1dFxyXG4gICAgICAgIHRoaXMubWF0SW5wdXQuZm9jdXMoKTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLm1hdFNlbGVjdCkge1xyXG4gICAgICAgIC8vIE9wZW4gTWF0U2VsZWN0IGRyb3Bkb3duXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3QuZm9jdXMoKTtcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcGVuKCk7XHJcbiAgICAgIH1cclxuICAgIH0sIDE1MCk7XHJcbiAgfVxyXG5cclxuICBzYXZlUm93KCkge1xyXG4gICAgdGhpcy5zYXZlRWRpdFJvd0VtaXR0ZXIuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgY2FuY2VsUm93KCkge1xyXG4gICAgdGhpcy5jYW5jZWxFZGl0Um93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBlZGl0Um93KCkge1xyXG4gICAgdGhpcy5lZGl0Um93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBkZWxldGVSb3coKSB7XHJcbiAgICB0aGlzLmRlbGV0ZVJvd0VtaXR0ZXIuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0Um93KGV2ZW50OiB7IGNoZWNrZWQ6IGJvb2xlYW4gfSkge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0Um93Q2hhbmdlLmVtaXQoZXZlbnQuY2hlY2tlZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkZpZWxkQ2hhbmdlKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmF1dG9TYXZlT25DaGFuZ2UoKSkge1xyXG4gICAgICB0aGlzLmZpZWxkVmFsdWVDaGFuZ2VkLmVtaXQoeyBmaWVsZCwgdmFsdWUgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbk51bWJlckZpZWxkQ2hhbmdlKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IG51bVZhbHVlID0gdmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSBudWxsID8gbnVsbCA6IE51bWJlcih2YWx1ZSk7XHJcbiAgICBjb25zdCB0YXJnZXREYXRhID0gdGhpcy5hdXRvU2F2ZU9uQ2hhbmdlKClcclxuICAgICAgPyB0aGlzLnJvd0RhdGEoKVxyXG4gICAgICA6IHRoaXMucm93RGF0YUNvcHkoKTtcclxuXHJcbiAgICBpZiAodGFyZ2V0RGF0YSkge1xyXG4gICAgICB0YXJnZXREYXRhW2ZpZWxkXSA9IG51bVZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmF1dG9TYXZlT25DaGFuZ2UoKSkge1xyXG4gICAgICB0aGlzLmZpZWxkVmFsdWVDaGFuZ2VkLmVtaXQoeyBmaWVsZCwgdmFsdWU6IG51bVZhbHVlIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gR2V0dGVyIG1ldGhvZCBmb3IgbmdNb2RlbCBiaW5kaW5nIC0gQW5ndWxhciAxOCBkb2Vzbid0IHN1cHBvcnQgdGVybmFyeSBpbiB0d28td2F5IGJpbmRpbmdcclxuICBnZXRGaWVsZFZhbHVlKGZpZWxkOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuYXV0b1NhdmVPbkNoYW5nZSgpXHJcbiAgICAgID8gdGhpcy5yb3dEYXRhKClbZmllbGRdXHJcbiAgICAgIDogdGhpcy5yb3dEYXRhQ29weSgpIVtmaWVsZF07XHJcbiAgfVxyXG5cclxuICAvLyBTZXR0ZXIgbWV0aG9kIGZvciBuZ01vZGVsIGJpbmRpbmdcclxuICBzZXRGaWVsZFZhbHVlKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIGNvbnN0IHRhcmdldERhdGEgPSB0aGlzLmF1dG9TYXZlT25DaGFuZ2UoKVxyXG4gICAgICA/IHRoaXMucm93RGF0YSgpXHJcbiAgICAgIDogdGhpcy5yb3dEYXRhQ29weSgpO1xyXG5cclxuICAgIGlmICh0YXJnZXREYXRhKSB7XHJcbiAgICAgIHRhcmdldERhdGFbZmllbGRdID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldER5bmFtaWNTZWxlY3REYXRhKCkge1xyXG4gICAgaWYgKHRoaXMubmVlZHNEeW5hbWljU2VsZWN0KCkpIHtcclxuICAgICAgdGhpcy5keW5hbWljU2VsZWN0T3B0aW9ucy5zZXQoXHJcbiAgICAgICAgdGhpcy5jb2x1bW4oKS5keW5hbWljUm93RWRpdE9wdGlvbnMhKHRoaXMucm93RGF0YSgpKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gUHVibGljIG1ldGhvZCB0byBtYW51YWxseSB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cclxuICBwdWJsaWMgdHJpZ2dlckNoYW5nZURldGVjdGlvbigpOiB2b2lkIHtcclxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxufVxyXG4iLCJAc3dpdGNoIChjb2x1bW4oKS50eXBlIHx8ICdzdHJpbmcnKSB7XHJcbiAgQGNhc2UgKCdjdXN0b20tdGVtcGxhdGUnKSB7XHJcbiAgICBAaWYgKHJvd0VkaXRpbmcoKSAmJiBjb2x1bW4oKS5hbGxvd0VkaXRDb2x1bW4pIHtcclxuICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgICA+PC9uZy1jb250YWluZXI+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbHVtbigpLmN1c3RvbVRlbXBsYXRlIVwiXHJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZGF0YTogcm93RGF0YSgpLCByb3dJbmRleDogcm93SW5kZXgoKSB9XCJcclxuICAgICAgPjwvbmctY29udGFpbmVyPlxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zJykge1xyXG4gICAgQGlmIChjb2x1bW4oKS5hY3Rpb25zKSB7XHJcbiAgICAgIEBpZiAoXHJcbiAgICAgICAgKCFjb2x1bW4oKS5hY3Rpb25zSW5NZW51ICYmICFtb2JpbGVWaWV3KCkpIHx8XHJcbiAgICAgICAgKG1vYmlsZVZpZXcoKSAmJiBjb2x1bW4oKS5hY3Rpb25zIS5sZW5ndGggPD0gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJ7IGZsb2F0OiBjb2x1bW4oKS5mbGV4UmlnaHQgPyAncmlnaHQnIDogJ25vbmUnIH1cIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWN0aW9uLWljb24tYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICBbY29sb3JdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgID8gYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgIDogYWN0aW9uLmljb25Db2xvclxyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJhY3Rpb24udG9vbHRpcE5hbWUgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcERpc2FibGVkXT1cIiFhY3Rpb24udG9vbHRpcE5hbWVcIlxyXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSwgcm93SW5kZXgoKSlcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7IGFjdGlvbi5pY29uTmFtZSB9fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgQGlmIChhY3Rpb24udXJsKSB7XHJcbiAgICAgICAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJhY3Rpb24udXJsXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1pY29uLWJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgW2NvbG9yXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBhY3Rpb25JY29uQ29sb3JEZWZbYWN0aW9uLmljb25OYW1lXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFjdGlvbi5pY29uQ29sb3JcclxuICAgICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImFjdGlvbi50b29sdGlwTmFtZSB8fCAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBEaXNhYmxlZF09XCIhYWN0aW9uLnRvb2x0aXBOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57eyBhY3Rpb24uaWNvbk5hbWUgfX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG4gICAgICBAaWYgKFxyXG4gICAgICAgIGNvbHVtbigpLmFjdGlvbnNJbk1lbnUgfHwgKG1vYmlsZVZpZXcoKSAmJiBjb2x1bW4oKS5hY3Rpb25zIS5sZW5ndGggPiAxKVxyXG4gICAgICApIHtcclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPm1vcmVfdmVydDwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiPlxyXG4gICAgICAgICAgQGZvciAoYWN0aW9uIG9mIGNvbHVtbigpLmFjdGlvbnM7IHRyYWNrIGFjdGlvbikge1xyXG4gICAgICAgICAgICBAaWYgKChhY3Rpb24uc2hvdyAmJiBhY3Rpb24uc2hvdyhyb3dEYXRhKCkpKSB8fCAhYWN0aW9uLnNob3cpIHtcclxuICAgICAgICAgICAgICBAaWYgKCFhY3Rpb24udXJsICYmIGFjdGlvbi5hY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgIG1hdC1tZW51LWl0ZW1cclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgYWN0aW9uLmFjdGlvbiEocm93RGF0YSgpKVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgIHt7IGFjdGlvbi50b29sdGlwTmFtZSB9fVxyXG4gICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIEBpZiAoYWN0aW9uLnVybCkge1xyXG4gICAgICAgICAgICAgICAgPGEgW3JvdXRlckxpbmtdPVwiYWN0aW9uLnVybFwiPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtbWVudS1pdGVtPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7IGFjdGlvbi50b29sdGlwTmFtZSB9fVxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1tZW51PlxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ3N0cmluZycpIHtcclxuICAgIDxuZy1jb250YWluZXJcclxuICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJiYXNlRmllbGRDZWxsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogY29sdW1uKCkgfVwiXHJcbiAgICA+PC9uZy1jb250YWluZXI+XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ251bWJlcicpIHtcclxuICAgIDxuZy1jb250YWluZXJcclxuICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJiYXNlRmllbGRDZWxsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogY29sdW1uKCkgfVwiXHJcbiAgICA+PC9uZy1jb250YWluZXI+XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2Jvb2xlYW4nKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdkYXRlJykge1xyXG4gICAgQGlmIChyb3dFZGl0aW5nKCkgJiYgY29sdW1uKCkuYWxsb3dFZGl0Q29sdW1uKSB7XHJcbiAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImJhc2VGaWVsZENlbGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4oKSB9XCJcclxuICAgICAgPjwvbmctY29udGFpbmVyPlxyXG4gICAgfSBAZWxzZSB7XHJcbiAgICAgIHt7IHJvd0RhdGEoKVtjb2x1bW4oKS5maWVsZF0gfCBzdERhdGVGb3JtYXRQaXBlIH19XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LWVkaXRpbmcnKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwicm93IGp1c3RpZnktY29udGVudC1lbmRcIj5cclxuICAgICAgQGlmIChyb3dFZGl0aW5nKCkpIHtcclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgY29sb3I9XCJhY2NlbnRcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgc2F2ZVJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidTYXZlIHJvdydcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5kb25lPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgY29sb3I9XCJ3YXJuXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGNhbmNlbFJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidDYW5jZWwgcm93J1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBlZGl0Um93KClcIlxyXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0VkaXQgcm93J1wiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgIGNhbkVkaXRSb3dWYWxpZGF0b3IoKSA/ICFjYW5FZGl0Um93VmFsaWRhdG9yKCkocm93RGF0YSgpKSA6IGZhbHNlXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5lZGl0PC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICBAaWYgKGFsbG93RGVsZXRlSW5FZGl0Um93KCkpIHtcclxuICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICBjb2xvcj1cIndhcm5cIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBkZWxldGVSb3coKVwiXHJcbiAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidEZWxldGUgcm93J1wiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgICBjYW5EZWxldGVSb3dWYWxpZGF0b3IoKVxyXG4gICAgICAgICAgICAgICAgPyAhY2FuRGVsZXRlUm93VmFsaWRhdG9yKCkocm93RGF0YSgpKVxyXG4gICAgICAgICAgICAgICAgOiBmYWxzZVxyXG4gICAgICAgICAgICBcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgPC9kaXY+XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LXNlbGVjdGluZycpIHtcclxuICAgIDwhLS0gICAgQGlmIChzZWxlY3RSb3dPbmx5T25lKCkpIHstLT5cclxuICAgIDwhLS0gICAgICA8bWF0LXJhZGlvLWJ1dHRvbi0tPlxyXG4gICAgPCEtLSAgICAgICAgY29sb3I9XCJwcmltYXJ5XCItLT5cclxuICAgIDwhLS0gICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIi0tPlxyXG4gICAgPCEtLSAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RSb3coeyBjaGVja2VkOiB0cnVlIH0pXCItLT5cclxuICAgIDwhLS0gICAgICAgIFtjaGVja2VkXT1cInJvd0lzU2VsZWN0ZWQoKVwiLS0+XHJcbiAgICA8IS0tICAgICAgPjwvbWF0LXJhZGlvLWJ1dHRvbj4tLT5cclxuICAgIDwhLS0gICAgfSBAZWxzZSB7LS0+XHJcbiAgICA8bWF0LWNoZWNrYm94XHJcbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAoY2hhbmdlKT1cInNlbGVjdFJvdygkZXZlbnQpXCJcclxuICAgICAgW2NoZWNrZWRdPVwicm93SXNTZWxlY3RlZCgpXCJcclxuICAgID48L21hdC1jaGVja2JveD5cclxuICAgIDwhLS0gICAgfS0tPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zLXJvdy1leHRlbmRpbmcnKSB7XHJcbiAgICBAaWYgKHJvd0lzRXhwYW5kZWQoKSkge1xyXG4gICAgICA8bWF0LWljb24+a2V5Ym9hcmRfYXJyb3dfdXA8L21hdC1pY29uPlxyXG4gICAgfSBAZWxzZSB7XHJcbiAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbjxuZy10ZW1wbGF0ZSAjYmFzZUZpZWxkQ2VsbCBsZXQtY29sdW1uPlxyXG4gIEBpZiAoKHJvd0VkaXRpbmcoKSB8fCBhdXRvU2F2ZU9uQ2hhbmdlKCkpICYmIGNvbHVtbi5hbGxvd0VkaXRDb2x1bW4pIHtcclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnc3RyaW5nJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcclxuICAgICAgICAgICAgc2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQsICRldmVudCk7XHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cIiFhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgc2F2ZVJvdygpXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY29sdW1uLmRpc2FibGVFZGl0ID8gY29sdW1uLmRpc2FibGVFZGl0KHJvd0RhdGEoKSkgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgIC8+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ251bWJlcicpIHtcclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGNvbHVtbi53aWR0aCB8fCAnYXV0bycgfVwiXHJcbiAgICAgID5cclxuICAgICAgICA8aW5wdXRcclxuICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbk51bWJlckZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIhYXV0b1NhdmVPbkNoYW5nZSgpICYmIHNhdmVSb3coKVwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY29sdW1uLmRpc2FibGVFZGl0ID8gY29sdW1uLmRpc2FibGVFZGl0KHJvd0RhdGEoKSkgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgfVxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdkYXRlJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFttYXREYXRlcGlja2VyXT1cInBpY2tlcjFcIlxyXG4gICAgICAgICAgW25nTW9kZWxdPVwiZ2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQpXCJcclxuICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxyXG4gICAgICAgICAgICBzZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZCwgJGV2ZW50KTtcclxuICAgICAgICAgICAgYXV0b1NhdmVPbkNoYW5nZSgpICYmIG9uRmllbGRDaGFuZ2UoY29sdW1uLmZpZWxkLCAkZXZlbnQpXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiIWF1dG9TYXZlT25DaGFuZ2UoKSAmJiBzYXZlUm93KClcIlxyXG4gICAgICAgICAgW3JlcXVpcmVkXT1cImNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWRcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgIGNvbHVtbi5kaXNhYmxlRWRpdCA/IGNvbHVtbi5kaXNhYmxlRWRpdChyb3dEYXRhKCkpIDogZmFsc2VcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgLz5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXItdG9nZ2xlXHJcbiAgICAgICAgICBtYXRJY29uU3VmZml4XHJcbiAgICAgICAgICBbZm9yXT1cInBpY2tlcjFcIlxyXG4gICAgICAgID48L21hdC1kYXRlcGlja2VyLXRvZ2dsZT5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI3BpY2tlcjE+PC9tYXQtZGF0ZXBpY2tlcj5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgPG1hdC1jaGVja2JveFxyXG4gICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXHJcbiAgICAgICAgICBzZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZCwgJGV2ZW50KTtcclxuICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgIFwiXHJcbiAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgW2Rpc2FibGVkXT1cImNvbHVtbi5kaXNhYmxlRWRpdCA/IGNvbHVtbi5kaXNhYmxlRWRpdChyb3dEYXRhKCkpIDogZmFsc2VcIlxyXG4gICAgICA+PC9tYXQtY2hlY2tib3g+XHJcbiAgICB9XHJcblxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdjdXN0b20nKSB7XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggfHwgJ2F1dG8nIH1cIlxyXG4gICAgICA+XHJcbiAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcclxuICAgICAgICAgICAgc2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQsICRldmVudCk7XHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxyXG4gICAgICAgICAgICBjb2x1bW4uZGlzYWJsZUVkaXQgPyBjb2x1bW4uZGlzYWJsZUVkaXQocm93RGF0YSgpKSA6IGZhbHNlXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiXCI+PC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgQGZvciAob3B0aW9uIG9mIGNvbHVtbi5jdXN0b21Sb3dFZGl0T3B0aW9uczsgdHJhY2sgb3B0aW9uKSB7XHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cclxuICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cclxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuXHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ2N1c3RvbS1keW5hbWljLXNlbGVjdCcpIHtcclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGNvbHVtbi53aWR0aCB8fCAnYXV0bycgfVwiXHJcbiAgICAgID5cclxuICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgW25nTW9kZWxdPVwiZ2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQpXCJcclxuICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxyXG4gICAgICAgICAgICBzZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZCwgJGV2ZW50KTtcclxuICAgICAgICAgICAgYXV0b1NhdmVPbkNoYW5nZSgpICYmIG9uRmllbGRDaGFuZ2UoY29sdW1uLmZpZWxkLCAkZXZlbnQpXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgICAgW3JlcXVpcmVkXT1cImNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWRcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgIGNvbHVtbi5kaXNhYmxlRWRpdCA/IGNvbHVtbi5kaXNhYmxlRWRpdChyb3dEYXRhKCkpIDogZmFsc2VcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgQGlmICghY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZCkge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZHluYW1pY1NlbGVjdE9wdGlvbnMoKTsgdHJhY2sgb3B0aW9uKSB7XHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cclxuICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cclxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICB9IEBlbHNlIHtcclxuICAgIDxkaXY+XHJcbiAgICAgIEBpZiAoY29sdW1uLnRyYW5zbGF0ZVZhbHVlKSB7XHJcbiAgICAgICAge3sgY29sdW1uLnRyYW5zbGF0ZVZhbHVlIVtyb3dEYXRhKClbY29sdW1uLmZpZWxkXV0gfHwgJycgfX1cclxuICAgICAgfVxyXG4gICAgICBAaWYgKGNvbHVtbi5jdXN0b21WYWx1ZURpc3BsYXkpIHtcclxuICAgICAgICB7eyBjb2x1bW4uY3VzdG9tVmFsdWVEaXNwbGF5KHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdKSB9fVxyXG4gICAgICB9XHJcbiAgICAgIEBpZiAoIWNvbHVtbi50cmFuc2xhdGVWYWx1ZSAmJiAhY29sdW1uLmN1c3RvbVZhbHVlRGlzcGxheSkge1xyXG4gICAgICAgIHt7IHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdIH19XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuPC9uZy10ZW1wbGF0ZT5cclxuIl19
175
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUVULFFBQVEsRUFDUixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7OztBQVFyRCxNQUFNLE9BQU8sNkJBQTZCO0lBaUR4QyxZQUFvQixpQkFBb0M7UUFBcEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQTdDeEQsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQThCLENBQUM7UUFDdEQsWUFBTyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQTJCLENBQUM7UUFDcEQsYUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUNwQyxnQkFBVyxHQUFHLEtBQUssRUFBMkIsQ0FBQztRQUMvQyx3QkFBbUIsR0FBRyxLQUFLLENBQXdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFD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Q0FBQyxLQUFhLEVBQUUsS0FBVTtRQUNyQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUV2QixJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FDM0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLHFCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUNyRCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxxREFBcUQ7SUFDOUMsc0JBQXNCO1FBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QyxDQUFDOytHQWhMVSw2QkFBNkI7bUdBQTdCLDZCQUE2QixpNEVBQzdCLFFBQVEsNEVBQ1IsU0FBUyxnREN6QnRCLDBnWkErV0E7OzRGRHhWYSw2QkFBNkI7a0JBTnpDLFNBQVM7K0JBQ0UsNEJBQTRCLG1CQUdyQix1QkFBdUIsQ0FBQyxNQUFNO3NGQUcxQixRQUFRO3NCQUE1QixTQUFTO3VCQUFDLFFBQVE7Z0JBQ0csU0FBUztzQkFBOUIsU0FBUzt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBDb21wb25lbnQsXHJcbiAgT25EZXN0cm95LFxyXG4gIGlucHV0LFxyXG4gIG91dHB1dCxcclxuICBzaWduYWwsXHJcbiAgVmlld0NoaWxkLFxyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgY29tcHV0ZWQsXHJcbiAgZWZmZWN0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdE1hdGVyaWFsVGFibGVDb2x1bW5Nb2RlbCB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9zdC1tYXRlcmlhbC10YWJsZS1jb2x1bW4ubW9kZWwnO1xyXG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcclxuaW1wb3J0IHsgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc3QtbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9tYXRlcmlhbC10YWJsZS1yb3ctY2VsbC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnNjc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hdGVyaWFsVGFibGVSb3dDZWxsQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICBAVmlld0NoaWxkKE1hdElucHV0KSBtYXRJbnB1dD86IE1hdElucHV0O1xyXG4gIEBWaWV3Q2hpbGQoTWF0U2VsZWN0KSBtYXRTZWxlY3Q/OiBNYXRTZWxlY3Q7XHJcblxyXG4gIGNvbHVtbiA9IGlucHV0LnJlcXVpcmVkPFN0TWF0ZXJpYWxUYWJsZUNvbHVtbk1vZGVsPigpO1xyXG4gIHJvd0RhdGEgPSBpbnB1dC5yZXF1aXJlZDx7IFtwcm9wOiBzdHJpbmddOiBhbnkgfT4oKTtcclxuICByb3dJbmRleCA9IGlucHV0LnJlcXVpcmVkPG51bWJlcj4oKTtcclxuICByb3dEYXRhQ29weSA9IGlucHV0PHsgW3Byb3A6IHN0cmluZ106IGFueSB9PigpO1xyXG4gIGNhbkVkaXRSb3dWYWxpZGF0b3IgPSBpbnB1dDwocm93OiBhbnkpID0+IGJvb2xlYW4+KCgpID0+IHRydWUpO1xyXG4gIGNhbkRlbGV0ZVJvd1ZhbGlkYXRvciA9IGlucHV0PChyb3c6IGFueSkgPT4gYm9vbGVhbj4oKCkgPT4gdHJ1ZSk7XHJcbiAgc2VsZWN0Um93T25seU9uZSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBpc0ZpcnN0RWRpdGFibGVDb2x1bW4gPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcbiAgYXV0b1NhdmVPbkNoYW5nZSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuICByb3dJc1NlbGVjdGVkID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHJvd0lzRXhwYW5kZWQgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcbiAgcm93RWRpdGluZyA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBhbGxvd0RlbGV0ZUluRWRpdFJvdyA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xyXG4gIGFsbG93RWRpdEluRWRpdFJvdyA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xyXG5cclxuICBzYXZlRWRpdFJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuICBjYW5jZWxFZGl0Um93RW1pdHRlciA9IG91dHB1dDx2b2lkPigpO1xyXG4gIGVkaXRSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcbiAgZGVsZXRlUm93RW1pdHRlciA9IG91dHB1dDx2b2lkPigpO1xyXG4gIHNlbGVjdFJvd0NoYW5nZSA9IG91dHB1dDxib29sZWFuPigpO1xyXG4gIGZpZWxkVmFsdWVDaGFuZ2VkID0gb3V0cHV0PHsgZmllbGQ6IHN0cmluZzsgdmFsdWU6IGFueSB9PigpO1xyXG5cclxuICBtb2JpbGVWaWV3ID0gc2lnbmFsKGZhbHNlKTtcclxuXHJcbiAgLy8gQ29tcHV0ZWQgZm9yIGFjdGlvbiBpY29uIGNvbG9yc1xyXG4gIGFjdGlvbkljb25Db2xvckRlZjogeyBba2V5OiBzdHJpbmddOiAncHJpbWFyeScgfCAnd2FybicgfSA9IHtcclxuICAgIGVkaXQ6ICdwcmltYXJ5JyxcclxuICAgIGRlbGV0ZTogJ3dhcm4nLFxyXG4gIH07XHJcblxyXG4gIGR5bmFtaWNTZWxlY3RPcHRpb25zID0gc2lnbmFsPHsgdmFsdWU6IGFueTsgbGFiZWw6IHN0cmluZyB9W10+KFtdKTtcclxuXHJcbiAgLy8gVXNlIGNvbXB1dGVkIHRvIGRldGVybWluZSBpZiBkeW5hbWljIHNlbGVjdCBkYXRhIG5lZWRzIHRvIGJlIGxvYWRlZFxyXG4gIHByaXZhdGUgbmVlZHNEeW5hbWljU2VsZWN0ID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgY29sID0gdGhpcy5jb2x1bW4oKTtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIGNvbD8uYWxsb3dFZGl0Q29sdW1uICYmXHJcbiAgICAgIGNvbD8ucm93RWRpdFR5cGUgPT09ICdjdXN0b20tZHluYW1pYy1zZWxlY3QnICYmXHJcbiAgICAgICEhY29sPy5keW5hbWljUm93RWRpdE9wdGlvbnNcclxuICAgICk7XHJcbiAgfSk7XHJcblxyXG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI/OiBSZXNpemVPYnNlcnZlcjtcclxuICBwcml2YXRlIHByZXZpb3VzUm93RWRpdGluZyA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xyXG4gICAgLy8gVXNlIFJlc2l6ZU9ic2VydmVyIGluc3RlYWQgb2Ygd2luZG93IHJlc2l6ZSBldmVudFxyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGlzTW9iaWxlID0gZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aCA8PSAxMTAwO1xyXG4gICAgICBpZiAodGhpcy5tb2JpbGVWaWV3KCkgIT09IGlzTW9iaWxlKSB7XHJcbiAgICAgICAgdGhpcy5tb2JpbGVWaWV3LnNldChpc01vYmlsZSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHkpO1xyXG5cclxuICAgIC8vIEluaXRpYWxpemUgbW9iaWxlIHZpZXcgc3RhdGVcclxuICAgIHRoaXMubW9iaWxlVmlldy5zZXQoZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aCA8PSAxMTAwKTtcclxuXHJcbiAgICAvLyBFZmZlY3QgdG8gaGFuZGxlIHJvd0VkaXRpbmcgY2hhbmdlc1xyXG4gICAgZWZmZWN0KCgpID0+IHtcclxuICAgICAgY29uc3QgaXNFZGl0aW5nID0gdGhpcy5yb3dFZGl0aW5nKCk7XHJcbiAgICAgIGNvbnN0IHdhc05vdEVkaXRpbmcgPSAhdGhpcy5wcmV2aW91c1Jvd0VkaXRpbmc7XHJcbiAgICAgIHRoaXMucHJldmlvdXNSb3dFZGl0aW5nID0gaXNFZGl0aW5nO1xyXG5cclxuICAgICAgaWYgKGlzRWRpdGluZykge1xyXG4gICAgICAgIHRoaXMuZ2V0RHluYW1pY1NlbGVjdERhdGEoKTtcclxuXHJcbiAgICAgICAgLy8gRm9jdXMgZmlyc3QgZWRpdGFibGUgZmllbGQgd2hlbiBlbnRlcmluZyBlZGl0IG1vZGVcclxuICAgICAgICBpZiAod2FzTm90RWRpdGluZyAmJiB0aGlzLmlzRmlyc3RFZGl0YWJsZUNvbHVtbigpKSB7XHJcbiAgICAgICAgICB0aGlzLmZvY3VzRmlyc3RFZGl0YWJsZUZpZWxkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIC8vIElmIHJvdyBpcyBhbHJlYWR5IGluIGVkaXQgbW9kZSBvbiBpbml0IChlLmcuLCBuZXdseSBhZGRlZCByb3cpLCBmb2N1cyB0aGUgZmllbGRcclxuICAgIGlmICh0aGlzLnJvd0VkaXRpbmcoKSAmJiB0aGlzLmlzRmlyc3RFZGl0YWJsZUNvbHVtbigpKSB7XHJcbiAgICAgIHRoaXMuZm9jdXNGaXJzdEVkaXRhYmxlRmllbGQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmb2N1c0ZpcnN0RWRpdGFibGVGaWVsZCgpIHtcclxuICAgIC8vIFVzZSBzZXRUaW1lb3V0IHRvIGVuc3VyZSB0aGUgdmlldyBpcyBmdWxseSByZW5kZXJlZFxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLm1hdElucHV0KSB7XHJcbiAgICAgICAgLy8gRm9jdXMgTWF0SW5wdXRcclxuICAgICAgICB0aGlzLm1hdElucHV0LmZvY3VzKCk7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5tYXRTZWxlY3QpIHtcclxuICAgICAgICAvLyBPcGVuIE1hdFNlbGVjdCBkcm9wZG93blxyXG4gICAgICAgIHRoaXMubWF0U2VsZWN0LmZvY3VzKCk7XHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3BlbigpO1xyXG4gICAgICB9XHJcbiAgICB9LCAxNTApO1xyXG4gIH1cclxuXHJcbiAgc2F2ZVJvdygpIHtcclxuICAgIHRoaXMuc2F2ZUVkaXRSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGNhbmNlbFJvdygpIHtcclxuICAgIHRoaXMuY2FuY2VsRWRpdFJvd0VtaXR0ZXIuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgZWRpdFJvdygpIHtcclxuICAgIHRoaXMuZWRpdFJvd0VtaXR0ZXIuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgZGVsZXRlUm93KCkge1xyXG4gICAgdGhpcy5kZWxldGVSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIHNlbGVjdFJvdyhldmVudDogeyBjaGVja2VkOiBib29sZWFuIH0pIHtcclxuICAgIGlmIChldmVudCkge1xyXG4gICAgICB0aGlzLnNlbGVjdFJvd0NoYW5nZS5lbWl0KGV2ZW50LmNoZWNrZWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25GaWVsZENoYW5nZShmaWVsZDogc3RyaW5nLCB2YWx1ZTogYW55KSB7XHJcbiAgICBpZiAodGhpcy5hdXRvU2F2ZU9uQ2hhbmdlKCkpIHtcclxuICAgICAgdGhpcy5maWVsZFZhbHVlQ2hhbmdlZC5lbWl0KHsgZmllbGQsIHZhbHVlIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25OdW1iZXJGaWVsZENoYW5nZShmaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBudW1WYWx1ZSA9IHZhbHVlID09PSAnJyB8fCB2YWx1ZSA9PT0gbnVsbCA/IG51bGwgOiBOdW1iZXIodmFsdWUpO1xyXG4gICAgY29uc3QgdGFyZ2V0RGF0YSA9IHRoaXMuYXV0b1NhdmVPbkNoYW5nZSgpXHJcbiAgICAgID8gdGhpcy5yb3dEYXRhKClcclxuICAgICAgOiB0aGlzLnJvd0RhdGFDb3B5KCk7XHJcblxyXG4gICAgaWYgKHRhcmdldERhdGEpIHtcclxuICAgICAgdGFyZ2V0RGF0YVtmaWVsZF0gPSBudW1WYWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5hdXRvU2F2ZU9uQ2hhbmdlKCkpIHtcclxuICAgICAgdGhpcy5maWVsZFZhbHVlQ2hhbmdlZC5lbWl0KHsgZmllbGQsIHZhbHVlOiBudW1WYWx1ZSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIEdldHRlciBtZXRob2QgZm9yIG5nTW9kZWwgYmluZGluZyAtIEFuZ3VsYXIgMTggZG9lc24ndCBzdXBwb3J0IHRlcm5hcnkgaW4gdHdvLXdheSBiaW5kaW5nXHJcbiAgZ2V0RmllbGRWYWx1ZShmaWVsZDogc3RyaW5nKTogYW55IHtcclxuICAgIHJldHVybiB0aGlzLmF1dG9TYXZlT25DaGFuZ2UoKVxyXG4gICAgICA/IHRoaXMucm93RGF0YSgpW2ZpZWxkXVxyXG4gICAgICA6IHRoaXMucm93RGF0YUNvcHkoKSFbZmllbGRdO1xyXG4gIH1cclxuXHJcbiAgLy8gU2V0dGVyIG1ldGhvZCBmb3IgbmdNb2RlbCBiaW5kaW5nXHJcbiAgc2V0RmllbGRWYWx1ZShmaWVsZDogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XHJcbiAgICBjb25zdCB0YXJnZXREYXRhID0gdGhpcy5hdXRvU2F2ZU9uQ2hhbmdlKClcclxuICAgICAgPyB0aGlzLnJvd0RhdGEoKVxyXG4gICAgICA6IHRoaXMucm93RGF0YUNvcHkoKTtcclxuXHJcbiAgICBpZiAodGFyZ2V0RGF0YSkge1xyXG4gICAgICB0YXJnZXREYXRhW2ZpZWxkXSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXREeW5hbWljU2VsZWN0RGF0YSgpIHtcclxuICAgIGlmICh0aGlzLm5lZWRzRHluYW1pY1NlbGVjdCgpKSB7XHJcbiAgICAgIHRoaXMuZHluYW1pY1NlbGVjdE9wdGlvbnMuc2V0KFxyXG4gICAgICAgIHRoaXMuY29sdW1uKCkuZHluYW1pY1Jvd0VkaXRPcHRpb25zISh0aGlzLnJvd0RhdGEoKSlcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFB1YmxpYyBtZXRob2QgdG8gbWFudWFsbHkgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uXHJcbiAgcHVibGljIHRyaWdnZXJDaGFuZ2VEZXRlY3Rpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcclxuICB9XHJcbn1cclxuIiwiQHN3aXRjaCAoY29sdW1uKCkudHlwZSB8fCAnc3RyaW5nJykge1xyXG4gIEBjYXNlICgnY3VzdG9tLXRlbXBsYXRlJykge1xyXG4gICAgQGlmIChyb3dFZGl0aW5nKCkgJiYgY29sdW1uKCkuYWxsb3dFZGl0Q29sdW1uKSB7XHJcbiAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImJhc2VGaWVsZENlbGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4oKSB9XCJcclxuICAgICAgPjwvbmctY29udGFpbmVyPlxyXG4gICAgfSBAZWxzZSB7XHJcbiAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4oKS5jdXN0b21UZW1wbGF0ZSFcIlxyXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGRhdGE6IHJvd0RhdGEoKSwgcm93SW5kZXg6IHJvd0luZGV4KCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBjYXNlICgnYWN0aW9ucycpIHtcclxuICAgIEBpZiAoY29sdW1uKCkuYWN0aW9ucykge1xyXG4gICAgICBAaWYgKFxyXG4gICAgICAgICghY29sdW1uKCkuYWN0aW9uc0luTWVudSAmJiAhbW9iaWxlVmlldygpKSB8fFxyXG4gICAgICAgIChtb2JpbGVWaWV3KCkgJiYgY29sdW1uKCkuYWN0aW9ucyEubGVuZ3RoIDw9IDEpXHJcbiAgICAgICkge1xyXG4gICAgICAgIDxkaXYgW25nU3R5bGVdPVwieyBmbG9hdDogY29sdW1uKCkuZmxleFJpZ2h0ID8gJ3JpZ2h0JyA6ICdub25lJyB9XCI+XHJcbiAgICAgICAgICBAZm9yIChhY3Rpb24gb2YgY29sdW1uKCkuYWN0aW9uczsgdHJhY2sgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIEBpZiAoKGFjdGlvbi5zaG93ICYmIGFjdGlvbi5zaG93KHJvd0RhdGEoKSkpIHx8ICFhY3Rpb24uc2hvdykge1xyXG4gICAgICAgICAgICAgIEBpZiAoIWFjdGlvbi51cmwgJiYgYWN0aW9uLmFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1pY29uLWJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgICAgW2NvbG9yXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbkljb25Db2xvckRlZlthY3Rpb24uaWNvbk5hbWVdXHJcbiAgICAgICAgICAgICAgICAgICAgICA/IGFjdGlvbkljb25Db2xvckRlZlthY3Rpb24uaWNvbk5hbWVdXHJcbiAgICAgICAgICAgICAgICAgICAgICA6IGFjdGlvbi5pY29uQ29sb3JcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiYWN0aW9uLnRvb2x0aXBOYW1lIHx8ICcnXCJcclxuICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBEaXNhYmxlZF09XCIhYWN0aW9uLnRvb2x0aXBOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIlxyXG4gICAgICAgICAgICAgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBhY3Rpb24uYWN0aW9uIShyb3dEYXRhKCksIHJvd0luZGV4KCkpXHJcbiAgICAgICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57eyBhY3Rpb24uaWNvbk5hbWUgfX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIEBpZiAoYWN0aW9uLnVybCkge1xyXG4gICAgICAgICAgICAgICAgPGEgW3JvdXRlckxpbmtdPVwiYWN0aW9uLnVybFwiPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhY3Rpb24taWNvbi1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIFtjb2xvcl09XCJcclxuICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkljb25Db2xvckRlZlthY3Rpb24uaWNvbk5hbWVdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBhY3Rpb24uaWNvbkNvbG9yXHJcbiAgICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJhY3Rpb24udG9vbHRpcE5hbWUgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwRGlzYWJsZWRdPVwiIWFjdGlvbi50b29sdGlwTmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+e3sgYWN0aW9uLmljb25OYW1lIH19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIH1cclxuICAgICAgQGlmIChcclxuICAgICAgICBjb2x1bW4oKS5hY3Rpb25zSW5NZW51IHx8IChtb2JpbGVWaWV3KCkgJiYgY29sdW1uKCkuYWN0aW9ucyEubGVuZ3RoID4gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJtZW51XCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxtYXQtbWVudSAjbWVudT1cIm1hdE1lbnVcIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBtYXQtbWVudS1pdGVtXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSlcIlxyXG4gICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBAaWYgKGFjdGlvbi51cmwpIHtcclxuICAgICAgICAgICAgICAgIDxhIFtyb3V0ZXJMaW5rXT1cImFjdGlvbi51cmxcIj5cclxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LW1lbnUtaXRlbT5cclxuICAgICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9tYXQtbWVudT5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdzdHJpbmcnKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdudW1iZXInKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdib29sZWFuJykge1xyXG4gICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImJhc2VGaWVsZENlbGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4oKSB9XCJcclxuICAgID48L25nLWNvbnRhaW5lcj5cclxuICB9XHJcblxyXG4gIEBjYXNlICgnZGF0ZScpIHtcclxuICAgIEBpZiAocm93RWRpdGluZygpICYmIGNvbHVtbigpLmFsbG93RWRpdENvbHVtbikge1xyXG4gICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJiYXNlRmllbGRDZWxsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogY29sdW1uKCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH0gQGVsc2Uge1xyXG4gICAgICB7eyByb3dEYXRhKClbY29sdW1uKCkuZmllbGRdIHwgc3REYXRlRm9ybWF0UGlwZSB9fVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zLXJvdy1lZGl0aW5nJykge1xyXG4gICAgPGRpdiBjbGFzcz1cInJvdyBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XHJcbiAgICAgIEBpZiAocm93RWRpdGluZygpKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwiYWNjZW50XCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IHNhdmVSb3coKVwiXHJcbiAgICAgICAgICBbbWF0VG9vbHRpcF09XCInU2F2ZSByb3cnXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24+ZG9uZTwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBjYW5jZWxSb3coKVwiXHJcbiAgICAgICAgICBbbWF0VG9vbHRpcF09XCInQ2FuY2VsIHJvdydcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG5cclxuICAgICAgICBAaWYgKGFsbG93RWRpdEluRWRpdFJvdygpKSB7XHJcbiAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgZWRpdFJvdygpXCJcclxuICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0VkaXQgcm93J1wiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY2FuRWRpdFJvd1ZhbGlkYXRvcigpID8gIWNhbkVkaXRSb3dWYWxpZGF0b3IoKShyb3dEYXRhKCkpIDogZmFsc2VcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDxtYXQtaWNvbj5lZGl0PC9tYXQtaWNvbj5cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgQGlmIChhbGxvd0RlbGV0ZUluRWRpdFJvdygpKSB7XHJcbiAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgZGVsZXRlUm93KClcIlxyXG4gICAgICAgICAgICBbbWF0VG9vbHRpcF09XCInRGVsZXRlIHJvdydcIlxyXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgICAgY2FuRGVsZXRlUm93VmFsaWRhdG9yKClcclxuICAgICAgICAgICAgICAgID8gIWNhbkRlbGV0ZVJvd1ZhbGlkYXRvcigpKHJvd0RhdGEoKSlcclxuICAgICAgICAgICAgICAgIDogZmFsc2VcclxuICAgICAgICAgICAgXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zLXJvdy1zZWxlY3RpbmcnKSB7XHJcbiAgICA8IS0tICAgIEBpZiAoc2VsZWN0Um93T25seU9uZSgpKSB7LS0+XHJcbiAgICA8IS0tICAgICAgPG1hdC1yYWRpby1idXR0b24tLT5cclxuICAgIDwhLS0gICAgICAgIGNvbG9yPVwicHJpbWFyeVwiLS0+XHJcbiAgICA8IS0tICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCItLT5cclxuICAgIDwhLS0gICAgICAgIChjaGFuZ2UpPVwic2VsZWN0Um93KHsgY2hlY2tlZDogdHJ1ZSB9KVwiLS0+XHJcbiAgICA8IS0tICAgICAgICBbY2hlY2tlZF09XCJyb3dJc1NlbGVjdGVkKClcIi0tPlxyXG4gICAgPCEtLSAgICAgID48L21hdC1yYWRpby1idXR0b24+LS0+XHJcbiAgICA8IS0tICAgIH0gQGVsc2Ugey0tPlxyXG4gICAgPG1hdC1jaGVja2JveFxyXG4gICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcclxuICAgICAgKGNoYW5nZSk9XCJzZWxlY3RSb3coJGV2ZW50KVwiXHJcbiAgICAgIFtjaGVja2VkXT1cInJvd0lzU2VsZWN0ZWQoKVwiXHJcbiAgICA+PC9tYXQtY2hlY2tib3g+XHJcbiAgICA8IS0tICAgIH0tLT5cclxuICB9XHJcblxyXG4gIEBjYXNlICgnYWN0aW9ucy1yb3ctZXh0ZW5kaW5nJykge1xyXG4gICAgQGlmIChyb3dJc0V4cGFuZGVkKCkpIHtcclxuICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2Fycm93X3VwPC9tYXQtaWNvbj5cclxuICAgIH0gQGVsc2Uge1xyXG4gICAgICA8bWF0LWljb24+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG48bmctdGVtcGxhdGUgI2Jhc2VGaWVsZENlbGwgbGV0LWNvbHVtbj5cclxuICBAaWYgKChyb3dFZGl0aW5nKCkgfHwgYXV0b1NhdmVPbkNoYW5nZSgpKSAmJiBjb2x1bW4uYWxsb3dFZGl0Q29sdW1uKSB7XHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGNvbHVtbi53aWR0aCB8fCAnYXV0bycgfVwiXHJcbiAgICAgID5cclxuICAgICAgICA8aW5wdXRcclxuICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICBbbmdNb2RlbF09XCJnZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZClcIlxyXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXHJcbiAgICAgICAgICAgIHNldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkLCAkZXZlbnQpO1xyXG4gICAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgb25GaWVsZENoYW5nZShjb2x1bW4uZmllbGQsICRldmVudClcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIhYXV0b1NhdmVPbkNoYW5nZSgpICYmIHNhdmVSb3coKVwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgIGNvbHVtbi5kaXNhYmxlRWRpdCA/IGNvbHVtbi5kaXNhYmxlRWRpdChyb3dEYXRhKCkpIDogZmFsc2VcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgfVxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdudW1iZXInKSB7XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggfHwgJ2F1dG8nIH1cIlxyXG4gICAgICA+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgdHlwZT1cIm51bWJlclwiXHJcbiAgICAgICAgICBbbmdNb2RlbF09XCJnZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZClcIlxyXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25OdW1iZXJGaWVsZENoYW5nZShjb2x1bW4uZmllbGQsICRldmVudClcIlxyXG4gICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiIWF1dG9TYXZlT25DaGFuZ2UoKSAmJiBzYXZlUm93KClcIlxyXG4gICAgICAgICAgW3JlcXVpcmVkXT1cImNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWRcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXHJcbiAgICAgICAgICAgIGNvbHVtbi5kaXNhYmxlRWRpdCA/IGNvbHVtbi5kaXNhYmxlRWRpdChyb3dEYXRhKCkpIDogZmFsc2VcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgLz5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnZGF0ZScpIHtcclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGNvbHVtbi53aWR0aCB8fCAnYXV0bycgfVwiXHJcbiAgICAgID5cclxuICAgICAgICA8aW5wdXRcclxuICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICBbbWF0RGF0ZXBpY2tlcl09XCJwaWNrZXIxXCJcclxuICAgICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcclxuICAgICAgICAgICAgc2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQsICRldmVudCk7XHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cIiFhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgc2F2ZVJvdygpXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxyXG4gICAgICAgICAgICBjb2x1bW4uZGlzYWJsZUVkaXQgPyBjb2x1bW4uZGlzYWJsZUVkaXQocm93RGF0YSgpKSA6IGZhbHNlXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgIC8+XHJcbiAgICAgICAgPG1hdC1kYXRlcGlja2VyLXRvZ2dsZVxyXG4gICAgICAgICAgbWF0SWNvblN1ZmZpeFxyXG4gICAgICAgICAgW2Zvcl09XCJwaWNrZXIxXCJcclxuICAgICAgICA+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XHJcbiAgICAgICAgPG1hdC1kYXRlcGlja2VyICNwaWNrZXIxPjwvbWF0LWRhdGVwaWNrZXI+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgIDxtYXQtY2hlY2tib3hcclxuICAgICAgICBbbmdNb2RlbF09XCJnZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZClcIlxyXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxyXG4gICAgICAgICAgc2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQsICRldmVudCk7XHJcbiAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgb25GaWVsZENoYW5nZShjb2x1bW4uZmllbGQsICRldmVudClcclxuICAgICAgICBcIlxyXG4gICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJjb2x1bW4uZGlzYWJsZUVkaXQgPyBjb2x1bW4uZGlzYWJsZUVkaXQocm93RGF0YSgpKSA6IGZhbHNlXCJcclxuICAgICAgPjwvbWF0LWNoZWNrYm94PlxyXG4gICAgfVxyXG5cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnY3VzdG9tJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxtYXQtc2VsZWN0XHJcbiAgICAgICAgICBbbmdNb2RlbF09XCJnZXRGaWVsZFZhbHVlKGNvbHVtbi5maWVsZClcIlxyXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXHJcbiAgICAgICAgICAgIHNldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkLCAkZXZlbnQpO1xyXG4gICAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgb25GaWVsZENoYW5nZShjb2x1bW4uZmllbGQsICRldmVudClcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY29sdW1uLmRpc2FibGVFZGl0ID8gY29sdW1uLmRpc2FibGVFZGl0KHJvd0RhdGEoKSkgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBjb2x1bW4uY3VzdG9tUm93RWRpdE9wdGlvbnM7IHRyYWNrIG9wdGlvbikge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcblxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdjdXN0b20tZHluYW1pYy1zZWxlY3QnKSB7XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggfHwgJ2F1dG8nIH1cIlxyXG4gICAgICA+XHJcbiAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgIFtuZ01vZGVsXT1cImdldEZpZWxkVmFsdWUoY29sdW1uLmZpZWxkKVwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcclxuICAgICAgICAgICAgc2V0RmllbGRWYWx1ZShjb2x1bW4uZmllbGQsICRldmVudCk7XHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxyXG4gICAgICAgICAgICBjb2x1bW4uZGlzYWJsZUVkaXQgPyBjb2x1bW4uZGlzYWJsZUVkaXQocm93RGF0YSgpKSA6IGZhbHNlXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIEBpZiAoIWNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJcIj48L21hdC1vcHRpb24+XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgQGZvciAob3B0aW9uIG9mIGR5bmFtaWNTZWxlY3RPcHRpb25zKCk7IHRyYWNrIG9wdGlvbikge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcbiAgfSBAZWxzZSB7XHJcbiAgICA8ZGl2PlxyXG4gICAgICBAaWYgKGNvbHVtbi50cmFuc2xhdGVWYWx1ZSkge1xyXG4gICAgICAgIHt7IGNvbHVtbi50cmFuc2xhdGVWYWx1ZSFbcm93RGF0YSgpW2NvbHVtbi5maWVsZF1dIHx8ICcnIH19XHJcbiAgICAgIH1cclxuICAgICAgQGlmIChjb2x1bW4uY3VzdG9tVmFsdWVEaXNwbGF5KSB7XHJcbiAgICAgICAge3sgY29sdW1uLmN1c3RvbVZhbHVlRGlzcGxheShyb3dEYXRhKClbY29sdW1uLmZpZWxkXSkgfX1cclxuICAgICAgfVxyXG4gICAgICBAaWYgKCFjb2x1bW4udHJhbnNsYXRlVmFsdWUgJiYgIWNvbHVtbi5jdXN0b21WYWx1ZURpc3BsYXkpIHtcclxuICAgICAgICB7eyByb3dEYXRhKClbY29sdW1uLmZpZWxkXSB9fVxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==