ngx-advanced-material-table
Version:
Advanced Angular Material Table component, along with many features such as filter and display/hide columns
94 lines • 23.6 kB
JavaScript
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ColumnType, } from '../../interfaces/column-definition.interface';
import { Value } from '../../helpers/values.helper';
import { DialogActionType } from '../../interfaces/enums/dialog-action.enum';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/dialog";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/form-field";
import * as i6 from "@angular/cdk/scrolling";
import * as i7 from "@angular/material/checkbox";
import * as i8 from "@angular/material/button-toggle";
import * as i9 from "@angular/material/input";
import * as i10 from "@angular/common";
import * as i11 from "../../pipes/filter.pipe";
export class FilterColumnsComponent {
constructor(dialogRef, fb, context) {
this.dialogRef = dialogRef;
this.fb = fb;
this.context = context;
this.searchFiltersValue = '';
this.distinctColumnValues = [];
this.cancelResponse = { action: DialogActionType.Cancel };
this.columnType = ColumnType;
this.selectedColumn = this.context.selectedColumn;
this.distinctColumnValues = this.sortColumns(this.context.distinctData);
this.initialSortingDirection = this.selectedColumn.SortDirection;
this.filterForm = this.fb.group({
SearchFilters: [''],
});
}
ngOnInit() {
this.filterForm.controls.SearchFilters.valueChanges.subscribe(() => this.onSearchFiltersValueChanged());
}
onSearchFiltersValueChanged() {
this.searchFiltersValue = this.filterForm.controls.SearchFilters.value;
}
onSelectFilter(change) {
this.distinctColumnValues.forEach((x) => {
if (x.name === change.source.value) {
x.checked = change.checked;
}
});
}
onSortingValueChange(value) {
if (this.selectedColumn.SortDirection === value) {
this.selectedColumn.SortDirection = undefined;
}
else {
this.selectedColumn.SortDirection = value;
}
}
onApplyFiltersButton() {
this.selectedColumn.FilterValues = [];
this.selectedColumn.FilterValues = this.distinctColumnValues.filter((x) => x.checked === true).map((x) => x.name);
const response = {
action: DialogActionType.Ok,
sortingHasChanged: this.initialSortingDirection !== this.selectedColumn.SortDirection,
selectedColumn: this.selectedColumn,
};
this.dialogRef.close(response);
}
sortColumns(columns) {
if (columns.length === 0) {
return [];
}
if (columns[0].name instanceof Date) {
columns.sort((a, b) => (a.name > b.name ? 1 : -1));
}
else if (Value.isNumber(columns[0].name)) {
columns.sort((a, b) => a.name - b.name);
}
else if (Value.isString(columns[0].name)) {
columns.sort((a, b) => a.name.localeCompare(b.name));
}
return columns;
}
}
FilterColumnsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: FilterColumnsComponent, deps: [{ token: i1.MatDialogRef }, { token: i2.FormBuilder }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
FilterColumnsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: FilterColumnsComponent, selector: "filter-columns", ngImport: i0, template: "<div class=\"filter-columns\">\n <button mat-icon-button class=\"close-icon\" [mat-dialog-close]=\"cancelResponse\">\n <mat-icon>close</mat-icon>\n </button>\n\n <h3 mat-dialog-title i18n=\"@@filter-columns-label-filterRowsHeading\">Filter rows</h3>\n\n <mat-dialog-content>\n <form id=\"formFilterRoutesPlanning\" role=\"form\" [formGroup]=\"filterForm\">\n <mat-form-field>\n <mat-label i18n=\"@@formControl-label-filterGrid\">Search filters</mat-label>\n <input matInput type=\"text\" formControlName=\"SearchFilters\" id=\"FilterString\" />\n </mat-form-field>\n </form>\n\n <cdk-virtual-scroll-viewport itemSize=\"15\" class=\"filter-column-viewport\">\n <span *ngIf=\"distinctColumnValues.length === 0\" i18n=\"@@routeplanning-filter-column-no-values\">No available values</span>\n\n <div\n class=\"filter-column-item\"\n *cdkVirtualFor=\"let value of distinctColumnValues | filterCriteria: searchFiltersValue; let i = index\"\n >\n <mat-checkbox [value]=\"value.name\" [checked]=\"value.checked\" (change)=\"onSelectFilter($event)\">\n <span> {{ value.displayedName }}</span>\n </mat-checkbox>\n </div>\n </cdk-virtual-scroll-viewport>\n\n <mat-button-toggle-group name=\"sortDirection\" value=\"{{ selectedColumn.SortDirection }}\">\n <mat-button-toggle id=\"filter-columns-sort-ascending\" value=\"asc\" (change)=\"onSortingValueChange($event.value)\">\n <span i18n=\"@@filterColumns-btn-ascsort\">Ascending</span>\n <mat-icon>arrow_upward</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle id=\"filter-columns-sort-descending\" value=\"desc\" (change)=\"onSortingValueChange($event.value)\">\n <span i18n=\"@@filterColumns-btn-descsort\">Descending</span>\n <mat-icon>arrow_downward</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </mat-dialog-content>\n\n <mat-dialog-actions>\n <button mat-raised-button id=\"filter-columns-close\" [mat-dialog-close]=\"cancelResponse\">\n <span i18n=\"@@action-btn-cancel\">Cancel</span>\n </button>\n <button mat-raised-button id=\"filter-columns-filter\" (click)=\"onApplyFiltersButton()\" color=\"accent\">\n <span i18n=\"@@action-btn-filter\">Filter</span>\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".filter-columns{position:relative!important}.filter-columns .close-icon{position:absolute;top:-20px;right:-20px}.filter-columns mat-form-field{width:100%}.filter-columns .filter-column-viewport{height:13em;border:1px solid lightgray}.filter-columns .filter-column-item{height:25px;padding:.2em .5em}.filter-columns mat-button-toggle-group{margin-top:16px;width:100%}.filter-columns mat-button-toggle-group mat-button-toggle{flex:1 1 auto}.filter-columns mat-dialog-actions button{flex:1 1 auto}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "id", "labelPosition", "name", "required", "checked", "disabled", "indeterminate", "aria-describedby", "value"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i8.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-labelledby", "tabIndex", "appearance", "checked", "disabled", "id", "name", "aria-label", "value"], outputs: ["change"], exportAs: ["matButtonToggle"] }], directives: [{ type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.MatLabel, selector: "mat-label" }, { type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { type: i8.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }], pipes: { "filterCriteria": i11.FilterColumnValuesPipe } });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: FilterColumnsComponent, decorators: [{
type: Component,
args: [{
selector: 'filter-columns',
templateUrl: './filter-columns.component.html',
styleUrls: ['./filter-columns.component.scss'],
}]
}], ctorParameters: function () { return [{ type: i1.MatDialogRef }, { type: i2.FormBuilder }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DIALOG_DATA]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLWNvbHVtbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWFkdmFuY2VkLW1hdGVyaWFsLXRhYmxlL3NyYy9saWIvY29tcG9uZW50cy9maWx0ZXItY29sdW1ucy9maWx0ZXItY29sdW1ucy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYWR2YW5jZWQtbWF0ZXJpYWwtdGFibGUvc3JjL2xpYi9jb21wb25lbnRzL2ZpbHRlci1jb2x1bW5zL2ZpbHRlci1jb2x1bW5zLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTFELE9BQU8sRUFBZ0IsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFekUsT0FBTyxFQUVILFVBQVUsR0FJYixNQUFNLDhDQUE4QyxDQUFDO0FBQ3RELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQzs7Ozs7Ozs7Ozs7OztBQU83RSxNQUFNLE9BQU8sc0JBQXNCO0lBUy9CLFlBQ1csU0FBK0MsRUFDOUMsRUFBZSxFQUNTLE9BQTJCO1FBRnBELGNBQVMsR0FBVCxTQUFTLENBQXNDO1FBQzlDLE9BQUUsR0FBRixFQUFFLENBQWE7UUFDUyxZQUFPLEdBQVAsT0FBTyxDQUFvQjtRQVYvRCx1QkFBa0IsR0FBVyxFQUFFLENBQUM7UUFHaEMseUJBQW9CLEdBQXVCLEVBQUUsQ0FBQztRQUM5QyxtQkFBYyxHQUEyQixFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3RSxlQUFVLEdBQUcsVUFBVSxDQUFDO1FBT3BCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUM7UUFDbEQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN4RSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUM7UUFDakUsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUM1QixhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7U0FDdEIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDO0lBQzVHLENBQUM7SUFFRCwyQkFBMkI7UUFDdkIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7SUFDM0UsQ0FBQztJQUVELGNBQWMsQ0FBQyxNQUF5QjtRQUNwQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDcEMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFO2dCQUNoQyxDQUFDLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7YUFDOUI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxLQUFxQjtRQUN0QyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxLQUFLLEtBQUssRUFBRTtZQUM3QyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7U0FDakQ7YUFBTTtZQUNILElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztTQUM3QztJQUNMLENBQUM7SUFFRCxvQkFBb0I7UUFDaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEgsTUFBTSxRQUFRLEdBQTJCO1lBQ3JDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzNCLGlCQUFpQixFQUFFLElBQUksQ0FBQyx1QkFBdUIsS0FBSyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWE7WUFDckYsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO1NBQ3RDLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRU8sV0FBVyxDQUFDLE9BQTJCO1FBQzNDLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDdEIsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUVELElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksWUFBWSxJQUFJLEVBQUU7WUFDakMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN0RDthQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFFLENBQUMsQ0FBQyxJQUFlLEdBQUksQ0FBQyxDQUFDLElBQWUsQ0FBQyxDQUFDO1NBQ25FO2FBQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN4QyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUUsQ0FBQyxDQUFDLElBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQWMsQ0FBQyxDQUFDLENBQUM7U0FDOUU7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNuQixDQUFDOztvSEF6RVEsc0JBQXNCLHlFQVluQixlQUFlO3dHQVpsQixzQkFBc0Isc0RDbkJuQyw4Z0ZBaURBOzRGRDlCYSxzQkFBc0I7a0JBTGxDLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLGdCQUFnQjtvQkFDMUIsV0FBVyxFQUFFLGlDQUFpQztvQkFDOUMsU0FBUyxFQUFFLENBQUMsaUNBQWlDLENBQUM7aUJBQ2pEOzswQkFhUSxNQUFNOzJCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAsIEZvcm1CdWlsZGVyIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGlhbG9nUmVmLCBNQVRfRElBTE9HX0RBVEEgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0Q2hlY2tib3hDaGFuZ2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGVja2JveCc7XG5pbXBvcnQge1xuICAgIElDb2x1bW5EZWZpbml0aW9uLFxuICAgIENvbHVtblR5cGUsXG4gICAgSURpc3RpbmN0Q29sdW1ucyxcbiAgICBJRmlsdGVyQ29sdW1uc1Jlc3BvbnNlLFxuICAgIElGaWx0ZXJDb2x1bW5zRGF0YSxcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9jb2x1bW4tZGVmaW5pdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVmFsdWUgfSBmcm9tICcuLi8uLi9oZWxwZXJzL3ZhbHVlcy5oZWxwZXInO1xuaW1wb3J0IHsgRGlhbG9nQWN0aW9uVHlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZW51bXMvZGlhbG9nLWFjdGlvbi5lbnVtJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdmaWx0ZXItY29sdW1ucycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ZpbHRlci1jb2x1bW5zLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9maWx0ZXItY29sdW1ucy5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBGaWx0ZXJDb2x1bW5zQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBmaWx0ZXJGb3JtOiBGb3JtR3JvdXA7XG4gICAgc2VhcmNoRmlsdGVyc1ZhbHVlOiBzdHJpbmcgPSAnJztcbiAgICBzZWxlY3RlZENvbHVtbjogSUNvbHVtbkRlZmluaXRpb247XG4gICAgaW5pdGlhbFNvcnRpbmdEaXJlY3Rpb24/OiAnYXNjJyB8ICdkZXNjJztcbiAgICBkaXN0aW5jdENvbHVtblZhbHVlczogSURpc3RpbmN0Q29sdW1uc1tdID0gW107XG4gICAgY2FuY2VsUmVzcG9uc2U6IElGaWx0ZXJDb2x1bW5zUmVzcG9uc2UgPSB7IGFjdGlvbjogRGlhbG9nQWN0aW9uVHlwZS5DYW5jZWwgfTtcbiAgICBjb2x1bW5UeXBlID0gQ29sdW1uVHlwZTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8RmlsdGVyQ29sdW1uc0NvbXBvbmVudD4sXG4gICAgICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgICAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSkgcHVibGljIGNvbnRleHQ6IElGaWx0ZXJDb2x1bW5zRGF0YVxuICAgICkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29sdW1uID0gdGhpcy5jb250ZXh0LnNlbGVjdGVkQ29sdW1uO1xuICAgICAgICB0aGlzLmRpc3RpbmN0Q29sdW1uVmFsdWVzID0gdGhpcy5zb3J0Q29sdW1ucyh0aGlzLmNvbnRleHQuZGlzdGluY3REYXRhKTtcbiAgICAgICAgdGhpcy5pbml0aWFsU29ydGluZ0RpcmVjdGlvbiA9IHRoaXMuc2VsZWN0ZWRDb2x1bW4uU29ydERpcmVjdGlvbjtcbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICBTZWFyY2hGaWx0ZXJzOiBbJyddLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtLmNvbnRyb2xzLlNlYXJjaEZpbHRlcnMudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uU2VhcmNoRmlsdGVyc1ZhbHVlQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICBvblNlYXJjaEZpbHRlcnNWYWx1ZUNoYW5nZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VhcmNoRmlsdGVyc1ZhbHVlID0gdGhpcy5maWx0ZXJGb3JtLmNvbnRyb2xzLlNlYXJjaEZpbHRlcnMudmFsdWU7XG4gICAgfVxuXG4gICAgb25TZWxlY3RGaWx0ZXIoY2hhbmdlOiBNYXRDaGVja2JveENoYW5nZSkge1xuICAgICAgICB0aGlzLmRpc3RpbmN0Q29sdW1uVmFsdWVzLmZvckVhY2goKHgpID0+IHtcbiAgICAgICAgICAgIGlmICh4Lm5hbWUgPT09IGNoYW5nZS5zb3VyY2UudmFsdWUpIHtcbiAgICAgICAgICAgICAgICB4LmNoZWNrZWQgPSBjaGFuZ2UuY2hlY2tlZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25Tb3J0aW5nVmFsdWVDaGFuZ2UodmFsdWU6ICdhc2MnIHwgJ2Rlc2MnKSB7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkQ29sdW1uLlNvcnREaXJlY3Rpb24gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ29sdW1uLlNvcnREaXJlY3Rpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ29sdW1uLlNvcnREaXJlY3Rpb24gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uQXBwbHlGaWx0ZXJzQnV0dG9uKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29sdW1uLkZpbHRlclZhbHVlcyA9IFtdO1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29sdW1uLkZpbHRlclZhbHVlcyA9IHRoaXMuZGlzdGluY3RDb2x1bW5WYWx1ZXMuZmlsdGVyKCh4KSA9PiB4LmNoZWNrZWQgPT09IHRydWUpLm1hcCgoeCkgPT4geC5uYW1lKTtcblxuICAgICAgICBjb25zdCByZXNwb25zZTogSUZpbHRlckNvbHVtbnNSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGFjdGlvbjogRGlhbG9nQWN0aW9uVHlwZS5PayxcbiAgICAgICAgICAgIHNvcnRpbmdIYXNDaGFuZ2VkOiB0aGlzLmluaXRpYWxTb3J0aW5nRGlyZWN0aW9uICE9PSB0aGlzLnNlbGVjdGVkQ29sdW1uLlNvcnREaXJlY3Rpb24sXG4gICAgICAgICAgICBzZWxlY3RlZENvbHVtbjogdGhpcy5zZWxlY3RlZENvbHVtbixcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZShyZXNwb25zZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzb3J0Q29sdW1ucyhjb2x1bW5zOiBJRGlzdGluY3RDb2x1bW5zW10pOiBJRGlzdGluY3RDb2x1bW5zW10ge1xuICAgICAgICBpZiAoY29sdW1ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb2x1bW5zWzBdLm5hbWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICBjb2x1bW5zLnNvcnQoKGEsIGIpID0+IChhLm5hbWUgPiBiLm5hbWUgPyAxIDogLTEpKTtcbiAgICAgICAgfSBlbHNlIGlmIChWYWx1ZS5pc051bWJlcihjb2x1bW5zWzBdLm5hbWUpKSB7XG4gICAgICAgICAgICBjb2x1bW5zLnNvcnQoKGEsIGIpID0+IChhLm5hbWUgYXMgbnVtYmVyKSAtIChiLm5hbWUgYXMgbnVtYmVyKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoVmFsdWUuaXNTdHJpbmcoY29sdW1uc1swXS5uYW1lKSkge1xuICAgICAgICAgICAgY29sdW1ucy5zb3J0KChhLCBiKSA9PiAoYS5uYW1lIGFzIHN0cmluZykubG9jYWxlQ29tcGFyZShiLm5hbWUgYXMgc3RyaW5nKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sdW1ucztcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZmlsdGVyLWNvbHVtbnNcIj5cbiAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cImNsb3NlLWljb25cIiBbbWF0LWRpYWxvZy1jbG9zZV09XCJjYW5jZWxSZXNwb25zZVwiPlxuICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGgzIG1hdC1kaWFsb2ctdGl0bGUgaTE4bj1cIkBAZmlsdGVyLWNvbHVtbnMtbGFiZWwtZmlsdGVyUm93c0hlYWRpbmdcIj5GaWx0ZXIgcm93czwvaDM+XG5cbiAgICA8bWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICA8Zm9ybSBpZD1cImZvcm1GaWx0ZXJSb3V0ZXNQbGFubmluZ1wiIHJvbGU9XCJmb3JtXCIgW2Zvcm1Hcm91cF09XCJmaWx0ZXJGb3JtXCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbCBpMThuPVwiQEBmb3JtQ29udHJvbC1sYWJlbC1maWx0ZXJHcmlkXCI+U2VhcmNoIGZpbHRlcnM8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJTZWFyY2hGaWx0ZXJzXCIgaWQ9XCJGaWx0ZXJTdHJpbmdcIiAvPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPC9mb3JtPlxuXG4gICAgICAgIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQgaXRlbVNpemU9XCIxNVwiIGNsYXNzPVwiZmlsdGVyLWNvbHVtbi12aWV3cG9ydFwiPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJkaXN0aW5jdENvbHVtblZhbHVlcy5sZW5ndGggPT09IDBcIiBpMThuPVwiQEByb3V0ZXBsYW5uaW5nLWZpbHRlci1jb2x1bW4tbm8tdmFsdWVzXCI+Tm8gYXZhaWxhYmxlIHZhbHVlczwvc3Bhbj5cblxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZmlsdGVyLWNvbHVtbi1pdGVtXCJcbiAgICAgICAgICAgICAgICAqY2RrVmlydHVhbEZvcj1cImxldCB2YWx1ZSBvZiBkaXN0aW5jdENvbHVtblZhbHVlcyB8IGZpbHRlckNyaXRlcmlhOiBzZWFyY2hGaWx0ZXJzVmFsdWU7IGxldCBpID0gaW5kZXhcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW3ZhbHVlXT1cInZhbHVlLm5hbWVcIiBbY2hlY2tlZF09XCJ2YWx1ZS5jaGVja2VkXCIgKGNoYW5nZSk9XCJvblNlbGVjdEZpbHRlcigkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPiB7eyB2YWx1ZS5kaXNwbGF5ZWROYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0PlxuXG4gICAgICAgIDxtYXQtYnV0dG9uLXRvZ2dsZS1ncm91cCBuYW1lPVwic29ydERpcmVjdGlvblwiIHZhbHVlPVwie3sgc2VsZWN0ZWRDb2x1bW4uU29ydERpcmVjdGlvbiB9fVwiPlxuICAgICAgICAgICAgPG1hdC1idXR0b24tdG9nZ2xlIGlkPVwiZmlsdGVyLWNvbHVtbnMtc29ydC1hc2NlbmRpbmdcIiB2YWx1ZT1cImFzY1wiIChjaGFuZ2UpPVwib25Tb3J0aW5nVmFsdWVDaGFuZ2UoJGV2ZW50LnZhbHVlKVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGkxOG49XCJAQGZpbHRlckNvbHVtbnMtYnRuLWFzY3NvcnRcIj5Bc2NlbmRpbmc8L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmFycm93X3Vwd2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L21hdC1idXR0b24tdG9nZ2xlPlxuICAgICAgICAgICAgPG1hdC1idXR0b24tdG9nZ2xlIGlkPVwiZmlsdGVyLWNvbHVtbnMtc29ydC1kZXNjZW5kaW5nXCIgdmFsdWU9XCJkZXNjXCIgKGNoYW5nZSk9XCJvblNvcnRpbmdWYWx1ZUNoYW5nZSgkZXZlbnQudmFsdWUpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gaTE4bj1cIkBAZmlsdGVyQ29sdW1ucy1idG4tZGVzY3NvcnRcIj5EZXNjZW5kaW5nPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L21hdC1idXR0b24tdG9nZ2xlPlxuICAgICAgICA8L21hdC1idXR0b24tdG9nZ2xlLWdyb3VwPlxuICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuXG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBpZD1cImZpbHRlci1jb2x1bW5zLWNsb3NlXCIgW21hdC1kaWFsb2ctY2xvc2VdPVwiY2FuY2VsUmVzcG9uc2VcIj5cbiAgICAgICAgICAgIDxzcGFuIGkxOG49XCJAQGFjdGlvbi1idG4tY2FuY2VsXCI+Q2FuY2VsPC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBpZD1cImZpbHRlci1jb2x1bW5zLWZpbHRlclwiIChjbGljayk9XCJvbkFwcGx5RmlsdGVyc0J1dHRvbigpXCIgY29sb3I9XCJhY2NlbnRcIj5cbiAgICAgICAgICAgIDxzcGFuIGkxOG49XCJAQGFjdGlvbi1idG4tZmlsdGVyXCI+RmlsdGVyPC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbjwvZGl2PlxuIl19