UNPKG

costimize-mat-select-autocomplete

Version:

Angular material select component with autocomplete and select all features

407 lines 72.3 kB
import { ChangeDetectorRef, Component, forwardRef, Input, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { MatButtonToggleGroup } from '@angular/material/button-toggle';
import { CdkVirtualScrollViewport, ScrollDispatcher } from '@angular/cdk/scrolling';
import { MatOption } from '@angular/material/core';
import { distinctUntilChanged, filter } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/scrolling";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/common";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/button";
import * as i6 from "@angular/material/form-field";
import * as i7 from "@angular/material/select";
import * as i8 from "@angular/material/core";
import * as i9 from "@angular/material/checkbox";
import * as i10 from "@angular/material/button-toggle";
import * as i11 from "@angular/material/tooltip";
export class SelectAutocompleteComponent {
    constructor(cd, sd) {
        this.cd = cd;
        this.sd = sd;
        this.selectPlaceholder = 'search...';
        this.options = [];
        this.errorMsg = 'Field is required';
        this.showErrorMsg = false;
        this.multiple = true;
        this.favourites = false;
        this.filterButtons = [];
        this.appearance = 'standard';
        this.filteredOptions = [];
        this.selectAllChecked = false;
        this.customSelectAllChecked = false;
        this.displayString = '';
        this.formControl = new UntypedFormControl([]);
        this.searchInputFormControl = new UntypedFormControl('');
        this.lastEmittedValue = undefined;
        this.trackByFn = (index, item) => item.value;
        this.onTouch = () => {
        };
        this.propagateChange = (_) => {
        };
    }
    ngOnInit() {
        if (this.selectAll) {
            this.filterButtons.push({
                name: this.selectAll,
                filterCallback: () => true
            });
        }
        this.filteredOptions = this.options;
    }
    ngAfterViewInit() {
        this.searchInputFormControlSubscription = this.searchInputFormControl.valueChanges
            .pipe(distinctUntilChanged())
            .subscribe(newValue => {
            this.filterItem(newValue);
        });
        this.sd
            .scrolled()
            .pipe(filter(scrollable => this.cdkVirtualScrollViewPort === scrollable))
            .subscribe(() => {
            let needUpdate = false;
            this.matOptions.forEach(option => {
                const selected = this.multiple ? this.selected.includes(option.value) : this.selected === option.value;
                if (selected && !option.selected) {
                    option.select();
                    needUpdate = true;
                }
                else if (!selected && option.selected) {
                    option.deselect();
                    needUpdate = true;
                }
            });
            if (needUpdate) {
                this.cd.detectChanges();
            }
        });
    }
    ngOnChanges(changes) {
        if (changes.options) {
            this.filteredOptions = changes.options.currentValue;
            this.writeValue(this.selected, true);
        }
    }
    toggleDropdown() {
        this.selectElem.toggle();
    }
    toggleSelectAll(event) {
        this.deselectButtons();
        this.customSelectAllChecked = false;
        if (event.checked) {
            this.selected = this.getFilteredOptionsValues();
        }
        else {
            this.selected = [];
        }
        this.patchValue(this.selected);
    }
    filterItem(value) {
        this.filteredOptions = this.options.filter(item => {
            let valueIndex = 0;
            const splitItem = item.display.split(/(?=[A-Z])|(-)|(\.)|(\s+)|(_)/).filter(Boolean);
            for (let word of splitItem) {
                let wordIndex = 0;
                word = word.charAt(0).toUpperCase() + word.slice(1);
                if (value.charAt(0).toUpperCase() === word.charAt(0) && valueIndex === 1) {
                    valueIndex = 0;
                }
                while (wordIndex < word.length) {
                    if (valueIndex < value.length && value[valueIndex].toUpperCase() === word[wordIndex]) {
                        valueIndex++;
                        wordIndex++;
                        while (valueIndex < value.length && value[valueIndex].toLowerCase() === word[wordIndex]) {
                            valueIndex++;
                            wordIndex++;
                        }
                    }
                    else {
                        wordIndex++;
                    }
                }
            }
            return valueIndex === value.length;
        });
        this.selectAllChecked = !this.customSelectAllChecked
            && this.multiple
            && this.filteredOptions.length > 0
            && !this.filteredOptions.some(item => !this.selected.includes(item.value));
        this.cdkVirtualScrollViewPort.scrollToIndex(1);
        this.cdkVirtualScrollViewPort.checkViewportSize();
    }
    getFilteredOptionsValues() {
        return this.filteredOptions.map(option => option.value);
    }
    getDisplayString() {
        if (this.customSelectAllChecked) {
            return this.selectAll;
        }
        let displayString = '';
        if (this.selected && this.selected.length) {
            if (this.multiple && this.selected.length === 1) {
                displayString = this.options.find(option => option.value === this.selected[0]).display;
            }
            else if (this.multiple) {
                displayString = this.selected.length + '/' + this.options.length;
            }
            else {
                displayString = this.options.find(option => option.value === this.selected).display;
            }
        }
        return displayString;
    }
    onSelectionChange(change) {
        if (!change.isUserInput) {
            return;
        }
        const value = change.source.value;
        if (this.multiple) {
            if (change.source.selected) {
                this.selected.push(value);
                if (this.selected.length === this.options.length) {
                    this.selectAllChecked = true;
                }
            }
            else {
                const elementIndex = this.selected.indexOf(change.source.value);
                this.selected.splice(elementIndex, 1);
                this.selectAllChecked = false;
            }
        }
        else {
            this.selected = value;
        }
    }
    changeSelectedValues(clickedButtonEvent, filterCallback) {
        this.selectedOptions = [];
        this.selectAllChecked = false;
        this.customSelectAllChecked = false;
        if (clickedButtonEvent.source.checked) {
            this.toggleGroup.value = [clickedButtonEvent.source.value];
            this.selectedOptions = this.filteredOptions.filter(option => filterCallback(option.value, option.display));
            if (clickedButtonEvent.value === this.selectAll) {
                this.customSelectAllChecked = true;
                this.selectedOptions = this.options.filter(option => filterCallback(option.value, option.display));
                this.filterItem('');
            }
            this.toggleDropdown();
        }
        this.selected = this.selectedOptions.map(item => item.value);
        this.patchValue(this.selected);
    }
    writeValue(selectedElements, clearLastEmittedValue = true) {
        this.deselectButtons();
        const allElementsValues = this.options.map(it => it.value);
        if (this.multiple && selectedElements) {
            this.customSelectAllChecked = false;
            const filteredElements = selectedElements.filter(it => allElementsValues.includes(it));
            this.selected = filteredElements;
            this.selectAllChecked = selectedElements.length === allElementsValues.length;
            this.patchValue(filteredElements);
        }
        else if (this.multiple && selectedElements == null) {
            if (this.selectAll) {
                this.selectAllChecked = false;
                this.customSelectAllChecked = true;
                setTimeout(() => this.toggleGroup.value = [this.selectAll]);
                this.selected = allElementsValues;
                this.patchValue(allElementsValues);
            }
            else {
                this.customSelectAllChecked = false;
                this.selected = [];
                this.patchValue([]);
            }
        }
        else if (!this.multiple
            && (selectedElements == null || selectedElements.length === 0 || !allElementsValues.includes(selectedElements))) {
            this.customSelectAllChecked = false;
            this.selected = null;
            this.patchValue([]);
        }
        else {
            this.customSelectAllChecked = false;
            this.selected = selectedElements;
            this.patchValue(selectedElements);
        }
        this.displayString = this.getDisplayString();
        if (clearLastEmittedValue) {
            this.lastEmittedValue = undefined;
        }
        this.emitValueIfChanged();
        this.reorderOptionsSelectedFirst();
        if (this.favourites)
            this.reorderOptionsFavouritesFirst();
    }
    registerOnChange(fn) {
        this.propagateChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouch = fn;
    }
    setDisabledState(isDisabled) {
        if (isDisabled) {
            this.formControl.disable({ emitEvent: false });
        }
        else {
            this.formControl.enable({ emitEvent: false });
        }
    }
    onClickOpen() {
        try {
            document.getElementById('costimize-dropdown-input').focus();
        }
        catch (error) {
        }
        this.cdkVirtualScrollViewPort.scrollToIndex(0);
        this.cdkVirtualScrollViewPort.checkViewportSize();
    }
    onClickClose() {
        this.searchInputFormControl.setValue('');
        this.onTouch();
        if (this.customSelectAllChecked) {
            this.displayString = this.getDisplayString();
            this.emitValueIfChanged();
        }
        else {
            this.writeValue(this.selected, false);
        }
        this.cdkVirtualScrollViewPort.scrollToIndex(0);
        this.cdkVirtualScrollViewPort.checkViewportSize();
    }
    emitValueIfChanged() {
        const valueToEmit = this.getValueToPropagate();
        if (this.valueChanged(valueToEmit, this.lastEmittedValue)) {
            this.propagateChange(valueToEmit);
            this.lastEmittedValue = valueToEmit;
        }
    }
    deselectButtons() {
        if (this.toggleGroup) {
            this.toggleGroup.value = null;
        }
    }
    reorderOptionsFavouritesFirst() {
        const favouriteOptions = [], notFavouriteOptions = [];
        this.options.forEach(option => {
            if (option.favourite) {
                favouriteOptions.push(option);
            }
            else {
                notFavouriteOptions.push(option);
            }
        });
        this.options = [...favouriteOptions, ...notFavouriteOptions];
        this.filteredOptions = [...this.options];
    }
    reorderOptionsSelectedFirst() {
        const selectedOptions = [], notSelectedOptions = [];
        this.options.forEach(option => {
            if (this.selected && this.optionIsSelected(option, this.selected)) {
                selectedOptions.push(option);
            }
            else {
                notSelectedOptions.push(option);
            }
        });
        this.options = [...selectedOptions, ...notSelectedOptions];
        this.filteredOptions = [...this.options];
    }
    optionIsSelected(option, selected) {
        return (this.multiple && selected.some(it => it === option.value)) ||
            (!this.multiple && selected === option.value);
    }
    patchValue(newValue) {
        if (this.multiple && newValue != null) {
            this.formControl.patchValue([...newValue]);
        }
        else {
            this.formControl.patchValue(newValue);
            if (this.favourites) {
                this.isSelectedFavourite = this.filteredOptions.find(option => option.value == newValue)?.favourite;
            }
        }
    }
    ngOnDestroy() {
        this.searchInputFormControlSubscription.unsubscribe();
    }
    getValueToPropagate() {
        if (this.customSelectAllChecked) {
            return null;
        }
        else {
            return this.multiple ? [...this.selected] : this.selected;
        }
    }
    valueChanged(newValue, oldValue) {
        return oldValue === undefined ||
            (!this.multiple && newValue !== oldValue) ||
            (this.multiple && !this.arraysHaveTheSameElements(newValue, oldValue));
    }
    arraysHaveTheSameElements(array1, array2) {
        if (array1 === array2) { // if they are both null
            return true;
        }
        else if (array1?.length === array2?.length) {
            const sortedArray2 = [...array2].sort();
            return ![...array1].sort().some((array1Value, index) => array1Value !== sortedArray2[index]);
        }
        else {
            return false;
        }
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectAutocompleteComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.ScrollDispatcher }], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SelectAutocompleteComponent, selector: "mat-select-autocomplete", inputs: { selectPlaceholder: "selectPlaceholder", placeholder: "placeholder", options: "options", errorMsg: "errorMsg", showErrorMsg: "showErrorMsg", selectedOptions: "selectedOptions", multiple: "multiple", favourites: "favourites", filterButtons: "filterButtons", selectAll: "selectAll", appearance: "appearance" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef((() => SelectAutocompleteComponent)),
                multi: true
            }
        ], viewQueries: [{ propertyName: "selectElem", first: true, predicate: ["selectElem"], descendants: true }, { propertyName: "toggleGroup", first: true, predicate: MatButtonToggleGroup, descendants: true }, { propertyName: "cdkVirtualScrollViewPort", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "matOptions", predicate: MatOption, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-form-field appearance=\"{{ appearance }}\">\r\n  <mat-label>{{placeholder}}</mat-label>\r\n  <mat-select\r\n    panelClass=\"custom-select-pane\"\r\n    #selectElem\r\n    [formControl]=\"formControl\"\r\n    [multiple]=\"multiple\"\r\n    (openedChange)=\"$event ? onClickOpen() : onClickClose()\"\r\n  >\r\n    <div class=\"box-search\">\r\n      <mat-checkbox\r\n        *ngIf=\"multiple\"\r\n        color=\"primary\"\r\n        class=\"box-select-all\"\r\n        matTooltip=\"Select all listed items\"\r\n        [(ngModel)]=\"selectAllChecked\"\r\n        (change)=\"toggleSelectAll($event)\"\r\n      ></mat-checkbox>\r\n      <input\r\n        id=\"costimize-dropdown-input\"\r\n        type='text'\r\n        [ngClass]=\"{ 'pl-1': !multiple }\"\r\n        [formControl]=\"searchInputFormControl\"\r\n        [placeholder]=\"selectPlaceholder\"\r\n        autocomplete=\"off\"\r\n        (keydown)=\"$event.stopPropagation()\"\r\n      />\r\n      <div\r\n        class=\"box-search-icon\"\r\n        (click)=\"searchInputFormControl.setValue('')\"\r\n      >\r\n        <button mat-icon-button class=\"search-button\">\r\n          <mat-icon class=\"mat-24\" aria-label=\"Search icon\">clear</mat-icon>\r\n        </button>\r\n      </div>\r\n    </div>\r\n    <mat-select-trigger class=\"option-container\">\r\n      <span class=\"ellipsis-text\">{{ displayString }}</span>\r\n      <mat-icon *ngIf=\"favourites && isSelectedFavourite\" class=\"input-icon icon-container fav-icon\">star_border</mat-icon>\r\n    </mat-select-trigger>\r\n    <div *ngIf=\"multiple && filterButtons.length > 0\" class=\"filter-buttons\">\r\n      <mat-button-toggle-group multiple=\"true\" class=\"filter-buttons-group\">\r\n        <mat-button-toggle class=\"filter-button\" *ngFor=\"let button of filterButtons;\"\r\n                           [value]=\"button.name\"\r\n                           (change)=\"changeSelectedValues($event, button.filterCallback)\">{{button.name}}\r\n        </mat-button-toggle>\r\n      </mat-button-toggle-group>\r\n    </div>\r\n    <cdk-virtual-scroll-viewport [itemSize]=\"24\" [style.height.px]=\"240\" class=\"cdk-viewport-format\">\r\n      <mat-option\r\n        *cdkVirtualFor=\"let option of filteredOptions; trackBy: trackByFn\"\r\n        [disabled]=\"customSelectAllChecked\"\r\n        [value]=\"option.value\"\r\n        (onSelectionChange)=\"onSelectionChange($event)\"\r\n      >\r\n        <div class=\"option-container\">\r\n          <span>{{ option.display }}</span>\r\n          <span class=\"icon-container\" *ngIf=\"favourites && option?.favourite\">\r\n            <mat-icon class=\"fav-icon\">star_border</mat-icon>\r\n          </span>\r\n        </div>\r\n      </mat-option>\r\n    </cdk-virtual-scroll-viewport>\r\n  </mat-select>\r\n  <mat-hint style=\"color:red\" *ngIf=\"showErrorMsg\">{{ errorMsg }}</mat-hint>\r\n</mat-form-field>\r\n", styles: [".box-search{margin:8px;border-radius:2px;box-shadow:0 2px 2px #00000029,0 0 0 1px #00000014;transition:box-shadow .2s cubic-bezier(.4,0,.2,1);background-color:transparent!important;display:flex;height:36px;justify-content:center;align-items:center}mat-select{font-size:14px!important}::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled){background-color:transparent!important;height:39px;display:flex;justify-content:center;align-items:center;padding:0;font-size:14px}::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled):hover .mdc-line-ripple:before{border-bottom-color:#0000006b}.mat-icon{height:21px}.mat-mdc-focus-indicator{display:flex;justify-content:center;align-items:center}::ng-deep .mat-mdc-form-field:hover .mat-mdc-form-field-focus-overlay{opacity:0}::ng-deep .mat-mdc-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent!important}::ng-deep .cdk-overlay-pane:not(.mat-mdc-select-panel-above) .mdc-menu-surface.mat-mdc-select-panel{font-size:14px;position:relative;bottom:40px}::ng-deep .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__background{height:16px;width:16px}::ng-deep .mat-pseudo-checkbox{height:16px!important;width:16px!important}::ng-deep .mat-mdc-select-arrow svg{padding-right:5px}::ng-deep .cdk-overlay-pane:not(.mat-mdc-select-panel-above) .mdc-menu-surface.mat-mdc-select-panel{padding:0}.mat-mdc-icon-button.mat-mdc-button-base{width:36px;height:36px;padding:0}::ng-deep .mat-mdc-option .mat-pseudo-checkbox-minimal{display:none!important}.box-search input{flex:1;border:none;outline:none}.box-select-all{width:36px;line-height:33px;color:gray;text-align:center}.search-button{line-height:33px;color:gray}::ng-deep .mat-mdc-icon-button:hover{--mat-mdc-button-persistent-ripple-color: rgba(0, 0, 0, 0) !important}.pl-1{padding-left:1rem}.filter-buttons ::ng-deep .mat-button-toggle-label-content{text-align:center;line-height:34px!important}.filter-buttons .mat-button-toggle-group{line-height:20px!important;border:none;flex-wrap:wrap;width:100%}.filter-buttons .mat-button-toggle{border:solid 1px rgba(0,0,0,.1215686275);border-radius:4px;margin:5px 10px;height:34px;line-height:20px!important;width:100%}::-webkit-scrollbar{width:0;background:transparent}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(input){min-width:calc(100% + 64px)}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(input) .mat-mdc-option{word-break:break-all}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(.mat-mdc-checkbox input){min-width:calc(100% + 96px)}::ng-deep .mdc-menu-surface.mat-mdc-select-panel{min-width:-moz-fit-content;min-width:fit-content}.cdk-viewport-format{overflow-x:hidden;overflow-y:auto;border:1px solid transparent;display:block}.cdk-viewport-format mat-option{font-size:14px;display:flex}::ng-deep .custom-select-pane.mat-mdc-select-panel.mdc-menu-surface{max-height:500px}.input-icon{font-size:18px;vertical-align:middle}.option-container{display:flex;justify-content:space-between;align-items:center;width:100%}.icon-container{margin-left:auto}.fav-icon{margin:0!important;color:#f90}::ng-deep .mdc-list-item__primary-text{width:100%}.ellipsis-text{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", 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]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: i7.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i7.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i8.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i10.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i10.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectAutocompleteComponent, decorators: [{
            type: Component,
            args: [{ selector: 'mat-select-autocomplete', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef((() => SelectAutocompleteComponent)),
                            multi: true
                        }
                    ], template: "<mat-form-field appearance=\"{{ appearance }}\">\r\n  <mat-label>{{placeholder}}</mat-label>\r\n  <mat-select\r\n    panelClass=\"custom-select-pane\"\r\n    #selectElem\r\n    [formControl]=\"formControl\"\r\n    [multiple]=\"multiple\"\r\n    (openedChange)=\"$event ? onClickOpen() : onClickClose()\"\r\n  >\r\n    <div class=\"box-search\">\r\n      <mat-checkbox\r\n        *ngIf=\"multiple\"\r\n        color=\"primary\"\r\n        class=\"box-select-all\"\r\n        matTooltip=\"Select all listed items\"\r\n        [(ngModel)]=\"selectAllChecked\"\r\n        (change)=\"toggleSelectAll($event)\"\r\n      ></mat-checkbox>\r\n      <input\r\n        id=\"costimize-dropdown-input\"\r\n        type='text'\r\n        [ngClass]=\"{ 'pl-1': !multiple }\"\r\n        [formControl]=\"searchInputFormControl\"\r\n        [placeholder]=\"selectPlaceholder\"\r\n        autocomplete=\"off\"\r\n        (keydown)=\"$event.stopPropagation()\"\r\n      />\r\n      <div\r\n        class=\"box-search-icon\"\r\n        (click)=\"searchInputFormControl.setValue('')\"\r\n      >\r\n        <button mat-icon-button class=\"search-button\">\r\n          <mat-icon class=\"mat-24\" aria-label=\"Search icon\">clear</mat-icon>\r\n        </button>\r\n      </div>\r\n    </div>\r\n    <mat-select-trigger class=\"option-container\">\r\n      <span class=\"ellipsis-text\">{{ displayString }}</span>\r\n      <mat-icon *ngIf=\"favourites && isSelectedFavourite\" class=\"input-icon icon-container fav-icon\">star_border</mat-icon>\r\n    </mat-select-trigger>\r\n    <div *ngIf=\"multiple && filterButtons.length > 0\" class=\"filter-buttons\">\r\n      <mat-button-toggle-group multiple=\"true\" class=\"filter-buttons-group\">\r\n        <mat-button-toggle class=\"filter-button\" *ngFor=\"let button of filterButtons;\"\r\n                           [value]=\"button.name\"\r\n                           (change)=\"changeSelectedValues($event, button.filterCallback)\">{{button.name}}\r\n        </mat-button-toggle>\r\n      </mat-button-toggle-group>\r\n    </div>\r\n    <cdk-virtual-scroll-viewport [itemSize]=\"24\" [style.height.px]=\"240\" class=\"cdk-viewport-format\">\r\n      <mat-option\r\n        *cdkVirtualFor=\"let option of filteredOptions; trackBy: trackByFn\"\r\n        [disabled]=\"customSelectAllChecked\"\r\n        [value]=\"option.value\"\r\n        (onSelectionChange)=\"onSelectionChange($event)\"\r\n      >\r\n        <div class=\"option-container\">\r\n          <span>{{ option.display }}</span>\r\n          <span class=\"icon-container\" *ngIf=\"favourites && option?.favourite\">\r\n            <mat-icon class=\"fav-icon\">star_border</mat-icon>\r\n          </span>\r\n        </div>\r\n      </mat-option>\r\n    </cdk-virtual-scroll-viewport>\r\n  </mat-select>\r\n  <mat-hint style=\"color:red\" *ngIf=\"showErrorMsg\">{{ errorMsg }}</mat-hint>\r\n</mat-form-field>\r\n", styles: [".box-search{margin:8px;border-radius:2px;box-shadow:0 2px 2px #00000029,0 0 0 1px #00000014;transition:box-shadow .2s cubic-bezier(.4,0,.2,1);background-color:transparent!important;display:flex;height:36px;justify-content:center;align-items:center}mat-select{font-size:14px!important}::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled){background-color:transparent!important;height:39px;display:flex;justify-content:center;align-items:center;padding:0;font-size:14px}::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled):hover .mdc-line-ripple:before{border-bottom-color:#0000006b}.mat-icon{height:21px}.mat-mdc-focus-indicator{display:flex;justify-content:center;align-items:center}::ng-deep .mat-mdc-form-field:hover .mat-mdc-form-field-focus-overlay{opacity:0}::ng-deep .mat-mdc-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent!important}::ng-deep .cdk-overlay-pane:not(.mat-mdc-select-panel-above) .mdc-menu-surface.mat-mdc-select-panel{font-size:14px;position:relative;bottom:40px}::ng-deep .mat-mdc-checkbox .mdc-checkbox .mdc-checkbox__background{height:16px;width:16px}::ng-deep .mat-pseudo-checkbox{height:16px!important;width:16px!important}::ng-deep .mat-mdc-select-arrow svg{padding-right:5px}::ng-deep .cdk-overlay-pane:not(.mat-mdc-select-panel-above) .mdc-menu-surface.mat-mdc-select-panel{padding:0}.mat-mdc-icon-button.mat-mdc-button-base{width:36px;height:36px;padding:0}::ng-deep .mat-mdc-option .mat-pseudo-checkbox-minimal{display:none!important}.box-search input{flex:1;border:none;outline:none}.box-select-all{width:36px;line-height:33px;color:gray;text-align:center}.search-button{line-height:33px;color:gray}::ng-deep .mat-mdc-icon-button:hover{--mat-mdc-button-persistent-ripple-color: rgba(0, 0, 0, 0) !important}.pl-1{padding-left:1rem}.filter-buttons ::ng-deep .mat-button-toggle-label-content{text-align:center;line-height:34px!important}.filter-buttons .mat-button-toggle-group{line-height:20px!important;border:none;flex-wrap:wrap;width:100%}.filter-buttons .mat-button-toggle{border:solid 1px rgba(0,0,0,.1215686275);border-radius:4px;margin:5px 10px;height:34px;line-height:20px!important;width:100%}::-webkit-scrollbar{width:0;background:transparent}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(input){min-width:calc(100% + 64px)}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(input) .mat-mdc-option{word-break:break-all}::ng-deep .mdc-menu-surface.mat-mdc-select-panel:has(.mat-mdc-checkbox input){min-width:calc(100% + 96px)}::ng-deep .mdc-menu-surface.mat-mdc-select-panel{min-width:-moz-fit-content;min-width:fit-content}.cdk-viewport-format{overflow-x:hidden;overflow-y:auto;border:1px solid transparent;display:block}.cdk-viewport-format mat-option{font-size:14px;display:flex}::ng-deep .custom-select-pane.mat-mdc-select-panel.mdc-menu-surface{max-height:500px}.input-icon{font-size:18px;vertical-align:middle}.option-container{display:flex;justify-content:space-between;align-items:center;width:100%}.icon-container{margin-left:auto}.fav-icon{margin:0!important;color:#f90}::ng-deep .mdc-list-item__primary-text{width:100%}.ellipsis-text{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
        }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.ScrollDispatcher }]; }, propDecorators: { selectPlaceholder: [{
                type: Input
            }], placeholder: [{
                type: Input
            }], options: [{
                type: Input
            }], errorMsg: [{
                type: Input
            }], showErrorMsg: [{
                type: Input
            }], selectedOptions: [{
                type: Input
            }], multiple: [{
                type: Input
            }], favourites: [{
                type: Input
            }], filterButtons: [{
                type: Input
            }], selectAll: [{
                type: Input
            }], appearance: [{
                type: Input
            }], selectElem: [{
                type: ViewChild,
                args: ['selectElem']
            }], toggleGroup: [{
                type: ViewChild,
                args: [MatButtonToggleGroup]
            }], cdkVirtualScrollViewPort: [{
                type: ViewChild,
                args: [CdkVirtualScrollViewport]
            }], matOptions: [{
                type: ViewChildren,
                args: [MatOption]
            }] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LWF1dG9jb21wbGV0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zZWxlY3QtYXV0b2NvbXBsZXRlL3NyYy9saWIvc2VsZWN0LWF1dG9jb21wbGV0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zZWxlY3QtYXV0b2NvbXBsZXRlL3NyYy9saWIvc2VsZWN0LWF1dG9jb21wbGV0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsS0FBSyxFQUlMLFNBQVMsRUFFVCxTQUFTLEVBQ1QsWUFBWSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRixPQUFPLEVBQXdCLG9CQUFvQixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFDNUYsT0FBTyxFQUFDLHdCQUF3QixFQUFFLGdCQUFnQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDbEYsT0FBTyxFQUFDLFNBQVMsRUFBMkIsTUFBTSx3QkFBd0IsQ0FBQztBQUMzRSxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsTUFBTSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7Ozs7QUFrQjVELE1BQU0sT0FBTywyQkFBMkI7SUE0QnRDLFlBQW9CLEVBQXFCLEVBQVcsRUFBb0I7UUFBcEQsT0FBRSxHQUFGLEVBQUUsQ0FBbUI7UUFBVyxPQUFFLEdBQUYsRUFBRSxDQUFrQjtRQTNCL0Qsc0JBQWlCLEdBQUcsV0FBVyxDQUFDO1FBRWhDLFlBQU8sR0FBdUIsRUFBRSxDQUFDO1FBQ2pDLGFBQVEsR0FBRyxtQkFBbUIsQ0FBQztRQUMvQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUVyQixhQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ2hC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LEtBQUs7Z0JBQ21CLFVBQVU7c0JBQWxDLFNBQVM7dUJBQUMsWUFBWTtnQkFDVSxXQUFXO3NCQUEzQyxTQUFTO3VCQUFDLG9CQUFvQjtnQkFDTSx3QkFBd0I7c0JBQTVELFNBQVM7dUJBQUMsd0JBQXdCO2dCQUNWLFVBQVU7c0JBQWxDLFlBQVk7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBDb21wb25lbnQsXHJcbiAgZm9yd2FyZFJlZixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBRdWVyeUxpc3QsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBWaWV3Q2hpbGQsXHJcbiAgVmlld0NoaWxkcmVuXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7Q29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SLCBVbnR5cGVkRm9ybUNvbnRyb2x9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHtNYXRCdXR0b25Ub2dnbGVDaGFuZ2UsIE1hdEJ1dHRvblRvZ2dsZUdyb3VwfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24tdG9nZ2xlJztcclxuaW1wb3J0IHtDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQsIFNjcm9sbERpc3BhdGNoZXJ9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xyXG5pbXBvcnQge01hdE9wdGlvbiwgTWF0T3B0aW9uU2VsZWN0aW9uQ2hhbmdlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcclxuaW1wb3J0IHtkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtEcm9wZG93bktleVZhbHVlfSBmcm9tICcuL0Ryb3Bkb3duS2V5VmFsdWUnO1xyXG5pbXBvcnQge01hdENoZWNrYm94Q2hhbmdlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGVja2JveCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHJcbiAgc2VsZWN0b3I6ICdtYXQtc2VsZWN0LWF1dG9jb21wbGV0ZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NlbGVjdC1hdXRvY29tcGxldGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3NlbGVjdC1hdXRvY29tcGxldGUuY29tcG9uZW50LnNjc3MnXSxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFNlbGVjdEF1dG9jb21wbGV0ZUNvbXBvbmVudCksXHJcbiAgICAgIG11bHRpOiB0cnVlXHJcbiAgICB9XHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2VsZWN0QXV0b2NvbXBsZXRlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIHNlbGVjdFBsYWNlaG9sZGVyID0gJ3NlYXJjaC4uLic7XHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZztcclxuICBASW5wdXQoKSBvcHRpb25zOiBEcm9wZG93bktleVZhbHVlW10gPSBbXTtcclxuICBASW5wdXQoKSBlcnJvck1zZyA9ICdGaWVsZCBpcyByZXF1aXJlZCc7XHJcbiAgQElucHV0KCkgc2hvd0Vycm9yTXNnID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2VsZWN0ZWRPcHRpb25zO1xyXG4gIEBJbnB1dCgpIG11bHRpcGxlID0gdHJ1ZTtcclxuICBASW5wdXQoKSBmYXZvdXJpdGVzID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZmlsdGVyQnV0dG9uczogQXJyYXk8eyBuYW1lOiBzdHJpbmcsIGZpbHRlckNhbGxiYWNrOiAoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IGJvb2xlYW4gfT4gPSBbXTtcclxuICBASW5wdXQoKSBzZWxlY3RBbGw6IHN0cmluZztcclxuICBASW5wdXQoKSBhcHBlYXJhbmNlOiAnc3RhbmRhcmQnIHwgJ2ZpbGwnIHwgJ291dGxpbmUnID0gJ3N0YW5kYXJkJztcclxuICBAVmlld0NoaWxkKCdzZWxlY3RFbGVtJykgc2VsZWN0RWxlbTtcclxuICBAVmlld0NoaWxkKE1hdEJ1dHRvblRvZ2dsZUdyb3VwKSB0b2dnbGVHcm91cDogTWF0QnV0dG9uVG9nZ2xlR3JvdXA7XHJcbiAgQFZpZXdDaGlsZChDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQpIGNka1ZpcnR1YWxTY3JvbGxWaWV3UG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xyXG4gIEBWaWV3Q2hpbGRyZW4oTWF0T3B0aW9uKSBtYXRPcHRpb25zOiBRdWVyeUxpc3Q8TWF0T3B0aW9uPjtcclxuXHJcbiAgZmlsdGVyZWRPcHRpb25zOiBEcm9wZG93bktleVZhbHVlW10gPSBbXTtcclxuICBzZWxlY3RBbGxDaGVja2VkID0gZmFsc2U7XHJcbiAgY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCA9IGZhbHNlO1xyXG4gIGRpc3BsYXlTdHJpbmcgPSAnJztcclxuICBmb3JtQ29udHJvbDogVW50eXBlZEZvcm1Db250cm9sID0gbmV3IFVudHlwZWRGb3JtQ29udHJvbChbXSk7XHJcbiAgc2VsZWN0ZWQ6IHN0cmluZ1tdIHwgc3RyaW5nIHwgbnVsbDtcclxuICBpc1NlbGVjdGVkRmF2b3VyaXRlOiBib29sZWFuO1xyXG4gIHNlYXJjaElucHV0Rm9ybUNvbnRyb2wgPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKCcnKTtcclxuICBzZWFyY2hJbnB1dEZvcm1Db250cm9sU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgbGFzdEVtaXR0ZWRWYWx1ZTogc3RyaW5nW10gfCBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZiwgcmVhZG9ubHkgc2Q6IFNjcm9sbERpc3BhdGNoZXIpIHtcclxuXHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnNlbGVjdEFsbCkge1xyXG4gICAgICB0aGlzLmZpbHRlckJ1dHRvbnMucHVzaCh7XHJcbiAgICAgICAgbmFtZTogdGhpcy5zZWxlY3RBbGwsXHJcbiAgICAgICAgZmlsdGVyQ2FsbGJhY2s6ICgpID0+IHRydWVcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNlYXJjaElucHV0Rm9ybUNvbnRyb2xTdWJzY3JpcHRpb24gPSB0aGlzLnNlYXJjaElucHV0Rm9ybUNvbnRyb2wudmFsdWVDaGFuZ2VzXHJcbiAgICAgIC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXHJcbiAgICAgIC5zdWJzY3JpYmUobmV3VmFsdWUgPT4ge1xyXG4gICAgICAgIHRoaXMuZmlsdGVySXRlbShuZXdWYWx1ZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc2RcclxuICAgICAgLnNjcm9sbGVkKClcclxuICAgICAgLnBpcGUoZmlsdGVyKHNjcm9sbGFibGUgPT4gdGhpcy5jZGtWaXJ0dWFsU2Nyb2xsVmlld1BvcnQgPT09IHNjcm9sbGFibGUpKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICBsZXQgbmVlZFVwZGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLm1hdE9wdGlvbnMuZm9yRWFjaChvcHRpb24gPT4ge1xyXG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLm11bHRpcGxlID8gdGhpcy5zZWxlY3RlZC5pbmNsdWRlcyhvcHRpb24udmFsdWUpIDogdGhpcy5zZWxlY3RlZCA9PT0gb3B0aW9uLnZhbHVlO1xyXG5cclxuICAgICAgICAgIGlmIChzZWxlY3RlZCAmJiAhb3B0aW9uLnNlbGVjdGVkKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbi5zZWxlY3QoKTtcclxuICAgICAgICAgICAgbmVlZFVwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCFzZWxlY3RlZCAmJiBvcHRpb24uc2VsZWN0ZWQpIHtcclxuICAgICAgICAgICAgb3B0aW9uLmRlc2VsZWN0KCk7XHJcbiAgICAgICAgICAgIG5lZWRVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAobmVlZFVwZGF0ZSkge1xyXG4gICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGlmIChjaGFuZ2VzLm9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSBjaGFuZ2VzLm9wdGlvbnMuY3VycmVudFZhbHVlO1xyXG4gICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5zZWxlY3RlZCwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0b2dnbGVEcm9wZG93bigpIHtcclxuICAgIHRoaXMuc2VsZWN0RWxlbS50b2dnbGUoKTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZVNlbGVjdEFsbChldmVudDogTWF0Q2hlY2tib3hDaGFuZ2UpIHtcclxuICAgIHRoaXMuZGVzZWxlY3RCdXR0b25zKCk7XHJcbiAgICB0aGlzLmN1c3RvbVNlbGVjdEFsbENoZWNrZWQgPSBmYWxzZTtcclxuICAgIGlmIChldmVudC5jaGVja2VkKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLmdldEZpbHRlcmVkT3B0aW9uc1ZhbHVlcygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZCA9IFtdO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucGF0Y2hWYWx1ZSh0aGlzLnNlbGVjdGVkKTtcclxuICB9XHJcblxyXG4gIGZpbHRlckl0ZW0odmFsdWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKGl0ZW0gPT4ge1xyXG4gICAgICBsZXQgdmFsdWVJbmRleCA9IDA7XHJcbiAgICAgIGNvbnN0IHNwbGl0SXRlbSA9IGl0ZW0uZGlzcGxheS5zcGxpdCgvKD89W0EtWl0pfCgtKXwoXFwuKXwoXFxzKyl8KF8pLykuZmlsdGVyKEJvb2xlYW4pO1xyXG4gICAgICBmb3IgKGxldCB3b3JkIG9mIHNwbGl0SXRlbSkge1xyXG4gICAgICAgIGxldCB3b3JkSW5kZXggPSAwO1xyXG4gICAgICAgIHdvcmQgPSB3b3JkLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgd29yZC5zbGljZSgxKTtcclxuXHJcbiAgICAgICAgaWYgKHZhbHVlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpID09PSB3b3JkLmNoYXJBdCgwKSAmJiB2YWx1ZUluZGV4ID09PSAxKSB7XHJcbiAgICAgICAgICB2YWx1ZUluZGV4ID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHdoaWxlICh3b3JkSW5kZXggPCB3b3JkLmxlbmd0aCkge1xyXG4gICAgICAgICAgaWYgKHZhbHVlSW5kZXggPCB2YWx1ZS5sZW5ndGggJiYgdmFsdWVbdmFsdWVJbmRleF0udG9VcHBlckNhc2UoKSA9PT0gd29yZFt3b3JkSW5kZXhdKSB7XHJcbiAgICAgICAgICAgIHZhbHVlSW5kZXgrKztcclxuICAgICAgICAgICAgd29yZEluZGV4Kys7XHJcbiAgICAgICAgICAgIHdoaWxlICh2YWx1ZUluZGV4IDwgdmFsdWUubGVuZ3RoICYmIHZhbHVlW3ZhbHVlSW5kZXhdLnRvTG93ZXJDYXNlKCkgPT09IHdvcmRbd29yZEluZGV4XSkge1xyXG4gICAgICAgICAgICAgIHZhbHVlSW5kZXgrKztcclxuICAgICAgICAgICAgICB3b3JkSW5kZXgrKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgd29yZEluZGV4Kys7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbHVlSW5kZXggPT09IHZhbHVlLmxlbmd0aDtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5zZWxlY3RBbGxDaGVja2VkID0gIXRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZFxyXG4gICAgICAmJiB0aGlzLm11bHRpcGxlXHJcbiAgICAgICYmIHRoaXMuZmlsdGVyZWRPcHRpb25zLmxlbmd0aCA+IDBcclxuICAgICAgJiYgIXRoaXMuZmlsdGVyZWRPcHRpb25zLnNvbWUoaXRlbSA9PiAhdGhpcy5zZWxlY3RlZC5pbmNsdWRlcyhpdGVtLnZhbHVlKSk7XHJcbiAgICB0aGlzLmNka1ZpcnR1YWxTY3JvbGxWaWV3UG9ydC5zY3JvbGxUb0luZGV4KDEpO1xyXG4gICAgdGhpcy5jZGtWaXJ0dWFsU2Nyb2xsVmlld1BvcnQuY2hlY2tWaWV3cG9ydFNpemUoKTtcclxuICB9XHJcblxyXG4gIGdldEZpbHRlcmVkT3B0aW9uc1ZhbHVlcygpIHtcclxuICAgIHJldHVybiB0aGlzLmZpbHRlcmVkT3B0aW9ucy5tYXAob3B0aW9uID0+IG9wdGlvbi52YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBnZXREaXNwbGF5U3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5jdXN0b21TZWxlY3RBbGxDaGVja2VkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdEFsbDtcclxuICAgIH1cclxuICAgIGxldCBkaXNwbGF5U3RyaW5nID0gJyc7XHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZCAmJiB0aGlzLnNlbGVjdGVkLmxlbmd0aCkge1xyXG4gICAgICBpZiAodGhpcy5tdWx0aXBsZSAmJiB0aGlzLnNlbGVjdGVkLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIGRpc3BsYXlTdHJpbmcgPSB0aGlzLm9wdGlvbnMuZmluZChvcHRpb24gPT4gb3B0aW9uLnZhbHVlID09PSB0aGlzLnNlbGVjdGVkWzBdKS5kaXNwbGF5O1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMubXVsdGlwbGUpIHtcclxuICAgICAgICBkaXNwbGF5U3RyaW5nID0gdGhpcy5zZWxlY3RlZC5sZW5ndGggKyAnLycgKyB0aGlzLm9wdGlvbnMubGVuZ3RoO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGRpc3BsYXlTdHJpbmcgPSB0aGlzLm9wdGlvbnMuZmluZChvcHRpb24gPT4gb3B0aW9uLnZhbHVlID09PSB0aGlzLnNlbGVjdGVkKS5kaXNwbGF5O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZGlzcGxheVN0cmluZztcclxuICB9XHJcblxyXG4gIG9uU2VsZWN0aW9uQ2hhbmdlKGNoYW5nZTogTWF0T3B0aW9uU2VsZWN0aW9uQ2hhbmdlKSB7XHJcbiAgICBpZiAoIWNoYW5nZS5pc1VzZXJJbnB1dCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdmFsdWUgPSBjaGFuZ2Uuc291cmNlLnZhbHVlO1xyXG4gICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcclxuICAgICAgaWYgKGNoYW5nZS5zb3VyY2Uuc2VsZWN0ZWQpIHtcclxuICAgICAgICAodGhpcy5zZWxlY3RlZCBhcyBzdHJpbmdbXSkucHVzaCh2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQubGVuZ3RoID09PSB0aGlzLm9wdGlvbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICB0aGlzLnNlbGVjdEFsbENoZWNrZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBlbGVtZW50SW5kZXggPSB0aGlzLnNlbGVjdGVkLmluZGV4T2YoY2hhbmdlLnNvdXJjZS52YWx1ZSk7XHJcbiAgICAgICAgKHRoaXMuc2VsZWN0ZWQgYXMgc3RyaW5nW10pLnNwbGljZShlbGVtZW50SW5kZXgsIDEpO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0QWxsQ2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdHJhY2tCeUZuID0gKGluZGV4LCBpdGVtKSA9PiBpdGVtLnZhbHVlO1xyXG5cclxuICBwdWJsaWMgY2hhbmdlU2VsZWN0ZWRWYWx1ZXMoY2xpY2tlZEJ1dHRvbkV2ZW50OiBNYXRCdXR0b25Ub2dnbGVDaGFuZ2UsIGZpbHRlckNhbGxiYWNrOiAoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRPcHRpb25zID0gW107XHJcbiAgICB0aGlzLnNlbGVjdEFsbENoZWNrZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgaWYgKGNsaWNrZWRCdXR0b25FdmVudC5zb3VyY2UuY2hlY2tlZCkge1xyXG4gICAgICB0aGlzLnRvZ2dsZUdyb3VwLnZhbHVlID0gW2NsaWNrZWRCdXR0b25FdmVudC5zb3VyY2UudmFsdWVdO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkT3B0aW9ucyA9IHRoaXMuZmlsdGVyZWRPcHRpb25zLmZpbHRlcihvcHRpb24gPT4gZmlsdGVyQ2FsbGJhY2sob3B0aW9uLnZhbHVlLCBvcHRpb24uZGlzcGxheSkpO1xyXG4gICAgICBpZiAoY2xpY2tlZEJ1dHRvbkV2ZW50LnZhbHVlID09PSB0aGlzLnNlbGVjdEFsbCkge1xyXG4gICAgICAgIHRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiBmaWx0ZXJDYWxsYmFjayhvcHRpb24udmFsdWUsIG9wdGlvbi5kaXNwbGF5KSk7XHJcbiAgICAgICAgdGhpcy5maWx0ZXJJdGVtKCcnKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnRvZ2dsZURyb3Bkb3duKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zZWxlY3RlZCA9IHRoaXMuc2VsZWN0ZWRPcHRpb25zLm1hcChpdGVtID0+IGl0ZW0udmFsdWUpO1xyXG4gICAgdGhpcy5wYXRjaFZhbHVlKHRoaXMuc2VsZWN0ZWQpO1xyXG4gIH1cclxuXHJcbiAgd3JpdGVWYWx1ZShzZWxlY3RlZEVsZW1lbnRzOiBzdHJpbmcgfCBzdHJpbmdbXSB8IG51bGwsIGNsZWFyTGFzdEVtaXR0ZWRWYWx1ZTogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcclxuICAgIHRoaXMuZGVzZWxlY3RCdXR0b25zKCk7XHJcbiAgICBjb25zdCBhbGxFbGVtZW50c1ZhbHVlcyA9IHRoaXMub3B0aW9ucy5tYXAoaXQgPT4gaXQudmFsdWUpO1xyXG4gICAgaWYgKHRoaXMubXVsdGlwbGUgJiYgc2VsZWN0ZWRFbGVtZW50cykge1xyXG4gICAgICB0aGlzLmN1c3RvbVNlbGVjdEFsbENoZWNrZWQgPSBmYWxzZTtcclxuICAgICAgY29uc3QgZmlsdGVyZWRFbGVtZW50cyA9IChzZWxlY3RlZEVsZW1lbnRzIGFzIHN0cmluZ1tdKS5maWx0ZXIoaXQgPT4gYWxsRWxlbWVudHNWYWx1ZXMuaW5jbHVkZXMoaXQpKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZCA9IGZpbHRlcmVkRWxlbWVudHM7XHJcbiAgICAgIHRoaXMuc2VsZWN0QWxsQ2hlY2tlZCA9IHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSBhbGxFbGVtZW50c1ZhbHVlcy5sZW5ndGg7XHJcbiAgICAgIHRoaXMucGF0Y2hWYWx1ZShmaWx0ZXJlZEVsZW1lbnRzKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5tdWx0aXBsZSAmJiBzZWxlY3RlZEVsZW1lbnRzID09IG51bGwpIHtcclxuICAgICAgaWYgKHRoaXMuc2VsZWN0QWxsKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RBbGxDaGVja2VkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jdXN0b21TZWxlY3RBbGxDaGVja2VkID0gdHJ1ZTtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMudG9nZ2xlR3JvdXAudmFsdWUgPSBbdGhpcy5zZWxlY3RBbGxdKTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkID0gYWxsRWxlbWVudHNWYWx1ZXM7XHJcbiAgICAgICAgdGhpcy5wYXRjaFZhbHVlKGFsbEVsZW1lbnRzVmFsdWVzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmN1c3RvbVNlbGVjdEFsbENoZWNrZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkID0gW107XHJcbiAgICAgICAgdGhpcy5wYXRjaFZhbHVlKFtdKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgIXRoaXMubXVsdGlwbGVcclxuICAgICAgJiYgKHNlbGVjdGVkRWxlbWVudHMgPT0gbnVsbCB8fCBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMCB8fCAhYWxsRWxlbWVudHNWYWx1ZXMuaW5jbHVkZXMoc2VsZWN0ZWRFbGVtZW50cyBhcyBzdHJpbmcpKVxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkID0gbnVsbDtcclxuICAgICAgdGhpcy5wYXRjaFZhbHVlKFtdKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkID0gc2VsZWN0ZWRFbGVtZW50cztcclxuICAgICAgdGhpcy5wYXRjaFZhbHVlKHNlbGVjdGVkRWxlbWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZGlzcGxheVN0cmluZyA9IHRoaXMuZ2V0RGlzcGxheVN0cmluZygpO1xyXG4gICAgaWYgKGNsZWFyTGFzdEVtaXR0ZWRWYWx1ZSkge1xyXG4gICAgICB0aGlzLmxhc3RFbWl0dGVkVmFsdWUgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICB0aGlzLmVtaXRWYWx1ZUlmQ2hhbmdlZCgpO1xyXG4gICAgdGhpcy5yZW9yZGVyT3B0aW9uc1NlbGVjdGVkRmlyc3QoKTtcclxuICAgIGlmKHRoaXMuZmF2b3VyaXRlcyl0aGlzLnJlb3JkZXJPcHRpb25zRmF2b3VyaXRlc0ZpcnN0KClcclxuICB9XHJcblxyXG4gIG9uVG91Y2ggPSAoKSA9PiB7XHJcbiAgfTtcclxuICBwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7XHJcbiAgfTtcclxuXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoID0gZm47XHJcbiAgfVxyXG5cclxuICBzZXREaXNhYmxlZFN0YXRlPyhpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBpZiAoaXNEaXNhYmxlZCkge1xyXG4gICAgICB0aGlzLmZvcm1Db250cm9sLmRpc2FibGUoe2VtaXRFdmVudDogZmFsc2V9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuZW5hYmxlKHtlbWl0RXZlbnQ6IGZhbHNlfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkNsaWNrT3BlbigpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb3N0aW1pemUtZHJvcGRvd24taW5wdXQnKS5mb2N1cygpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgIH1cclxuICAgIHRoaXMuY2RrVmlydHVhbFNjcm9sbFZpZXdQb3J0LnNjcm9sbFRvSW5kZXgoMCk7XHJcbiAgICB0aGlzLmNka1ZpcnR1YWxTY3JvbGxWaWV3UG9ydC5jaGVja1ZpZXdwb3J0U2l6ZSgpO1xyXG4gIH1cclxuXHJcbiAgb25DbGlja0Nsb3NlKCkge1xyXG4gICAgdGhpcy5zZWFyY2hJbnB1dEZvcm1Db250cm9sLnNldFZhbHVlKCcnKTtcclxuICAgIHRoaXMub25Ub3VjaCgpO1xyXG4gICAgaWYgKHRoaXMuY3VzdG9tU2VsZWN0QWxsQ2hlY2tlZCkge1xyXG4gICAgICB0aGlzLmRpc3BsYXlTdHJpbmcgPSB0aGlzLmdldERpc3BsYXlTdHJpbmcoKTtcclxuICAgICAgdGhpcy5lbWl0VmFsdWVJZkNoYW5nZWQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMud3JpdGVWYWx1ZSh0aGlzLnNlbGVjdGVkLCBmYWxzZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNka1ZpcnR1YWxTY3JvbGxWaWV3UG9ydC5zY3JvbGxUb0luZGV4KDApO1xyXG4gICAgdGhpcy5jZGtWaXJ0dWFsU2Nyb2xsVmlld1BvcnQuY2hlY2tWaWV3cG9ydFNpemUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZW1pdFZhbHVlSWZDaGFuZ2VkKCkge1xyXG4gICAgY29uc3QgdmFsdWVUb0VtaXQgPSB0aGlzLmdldFZhbHVlVG9Qcm9wYWdhdGUoKTtcclxuICAgIGlmICh0aGlzLnZhbHVlQ2hhbmdlZCh2YWx1ZVRvRW1pdCwgdGhpcy5sYXN0RW1pdHRlZFZhbHVlKSkge1xyXG4gICAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh2YWx1ZVRvRW1pdCk7XHJcbiAgICAgIHRoaXMubGFzdEVtaXR0ZWRWYWx1ZSA9IHZhbHVlVG9FbWl0O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZXNlbGVjdEJ1dHRvbnMoKSB7XHJcbiAgICBpZiAodGhpcy50b2dnbGVHcm91cCkge1xyXG4gICAgICB0aGlzLnRvZ2dsZUdyb3VwLnZhbHVlID0gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVvcmRlck9wdGlvbnNGYXZvdXJpdGVzRmlyc3QoKSB7XHJcbiAgICBjb25zdCBmYXZvdXJpdGVPcHRpb25zID0gW10sIG5vdEZhdm91cml0ZU9wdGlvbnMgPSBbXTtcclxuICAgIHRoaXMub3B0aW9ucy5mb3JFYWNoKG9wdGlvbiA9PiB7XHJcbiAgICAgIGlmIChvcHRpb24uZmF2b3VyaXRlKSB7XHJcbiAgICAgICAgZmF2b3VyaXRlT3B0aW9ucy5wdXNoKG9wdGlvbik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbm90RmF2b3VyaXRlT3B0aW9ucy5wdXNoKG9wdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMub3B0aW9ucyA9IFsuLi5mYXZvdXJpdGVPcHRpb25zLCAuLi5ub3RGYXZvdXJpdGVPcHRpb25zXTtcclxuICAgIHRoaXMuZmlsdGVyZWRPcHRpb25zID0gWy4uLnRoaXMub3B0aW9uc107XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlb3JkZXJPcHRpb25zU2VsZWN0ZWRGaXJzdCgpIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkT3B0aW9ucyA9IFtdLCBub3RTZWxlY3RlZE9wdGlvbnMgPSBbXTtcclxuICAgIHRoaXMub3B0aW9ucy5mb3JFYWNoKG9wdGlvbiA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkICYmIHRoaXMub3B0aW9uSXNTZWxlY3RlZChvcHRpb24sIHRoaXMuc2VsZWN0ZWQpKSB7XHJcbiAgICAgICAgc2VsZWN0ZWRPcHRpb25zLnB1c2gob3B0aW9uKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBub3RTZWxlY3RlZE9wdGlvbnMucHVzaChvcHRpb24pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLm9wdGlvbnMgPSBbLi4uc2VsZWN0ZWRPcHRpb25zLCAuLi5ub3RTZWxlY3RlZE9wdGlvbnNdO1xyXG4gICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSBbLi4udGhpcy5vcHRpb25zXTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb3B0aW9uSXNTZWxlY3RlZChvcHRpb246IERyb3Bkb3duS2V5VmFsdWUsIHNlbGVjdGVkOiBzdHJpbmdbXSB8IHN0cmluZykge1xyXG4gICAgcmV0dXJuICh0aGlzLm11bHRpcGxlICYmIChzZWxlY3RlZCBhcyBzdHJpbmdbXSkuc29tZShpdCA9PiBpdCA9PT0gb3B0aW9uLnZhbHVlKSkgfHxcclxuICAgICAgKCF0aGlzLm11bHRpcGxlICYmIChzZWxlY3RlZCBhcyBzdHJpbmcpID09PSBvcHRpb24udmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXRjaFZhbHVlKG5ld1ZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSB8IG51bGwpIHtcclxuICAgIGlmICh0aGlzLm11bHRpcGxlICYmIG5ld1ZhbHVlICE9IG51bGwpIHtcclxuICAgICAgdGhpcy5mb3JtQ29udHJvbC5wYXRjaFZhbHVlKFsuLi5uZXdWYWx1ZV0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5mb3JtQ29udHJvbC5wYXRjaFZhbHVlKG5ld1ZhbHVlKTtcclxuICAgICAgaWYodGhpcy5mYXZvdXJpdGVzKSB7XHJcbiAgICAgICAgdGhpcy5pc1NlbGVjdGVkRmF2b3VyaXRlID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMuZmluZCggb3B0aW9uID0+IG9wdGlvbi52YWx1ZSA9PSBuZXdWYWx1ZSk/LmZhdm91cml0ZVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuc2VhcmNoSW5wdXRGb3JtQ29udHJvbFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRWYWx1ZVRvUHJvcGFnYXRlKCk6IHN0cmluZyB8IHN0cmluZ1tdIHwgbnVsbCB7XHJcbiAgICBpZiAodGhpcy5jdXN0b21TZWxlY3RBbGxDaGVja2VkKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMubXVsdGlwbGUgPyBbLi4udGhpcy5zZWxlY3RlZF0gOiB0aGlzLnNlbGVjdGVkO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWx1ZUNoYW5nZWQobmV3VmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdIHwgbnVsbCwgb2xkVmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIG9sZFZhbHVlID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgKCF0aGlzLm11bHRpcGxlICYmIG5ld1ZhbHVlICE9PSBvbGRWYWx1ZSkgfHxcclxuICAgICAgKHRoaXMubXVsdGlwbGUgJiYgIXRoaXMuYXJyYXlzSGF2ZVRoZVNhbWVFbGVtZW50cygobmV3VmFsdWUgYXMgc3RyaW5nW10gfCBudWxsKSwgKG9sZFZhbHVlIGFzIHN0cmluZ1tdIHwgbnVsbCkpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXJyYXlzSGF2ZVRoZVNhbWVFbGVtZW50cyhhcnJheTE6IHN0cmluZ1tdIHwgbnVsbCwgYXJyYXkyOiBzdHJpbmdbXSB8IG51bGwpOiBib29sZWFuIHtcclxuICAgIGlmIChhcnJheTEgPT09IGFycmF5MikgeyAvLyBpZiB0aGV5IGFyZSBib3RoIG51bGxcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2UgaWYgKGFycmF5MT8ubGVuZ3RoID09PSBhcnJheTI/Lmxlbmd0aCkge1xyXG4gICAgICBjb25zdCBzb3J0ZWRBcnJheTIgPSBbLi4uYXJyYXkyXS5zb3J0KCk7XHJcbiAgICAgIHJldHVybiAhWy4uLmFycmF5MV0uc29ydCgpLnNvbWUoKGFycmF5MVZhbHVlLCBpbmRleCkgPT4gYXJyYXkxVmFsdWUgIT09IHNvcnRlZEFycmF5MltpbmRleF0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn1cclxuIiwiPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJ7eyBhcHBlYXJhbmNlIH19XCI+XHJcbiAgPG1hdC1sYWJlbD57e3BsYWNlaG9sZGVyfX08L21hdC1sYWJlbD5cclxuICA8bWF0LXNlbGVjdFxyXG4gICAgcGFuZWxDbGFzcz1cImN1c3RvbS1zZWxlY3QtcGFuZVwiXHJcbiAgICAjc2VsZWN0RWxlbVxyXG4gICAgW2Zvcm1Db250cm9sXT1cImZvcm1Db250cm9sXCJcclxuICAgIFttdWx0aXBsZV09XCJtdWx0aXBsZVwiXHJcbiAgICAob3BlbmVkQ2hhbmdlKT1cIiRldmVudCA/IG9uQ2xpY2tPcGVuKCkgOiBvbkNsaWNrQ2xvc2UoKVwiXHJcbiAgPlxyXG4gICAgPGRpdiBjbGFzcz1cImJveC1zZWFyY2hcIj5cclxuICAgICAgPG1hdC1jaGVja2JveFxyXG4gICAgICAgICpuZ0lmPVwibXVsdGlwbGVcIlxyXG4gICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgY2xhc3M9XCJib3gtc2VsZWN0LWFsbFwiXHJcbiAgICAgICAgbWF0VG9vbHRpcD1cIlNlbGVjdCBhbGwgbGlzdGVkIGl0ZW1zXCJcclxuICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdEFsbENoZWNrZWRcIlxyXG4gICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlU2VsZWN0QWxsKCRldmVudClcIlxyXG4gICAgICA+PC9tYXQtY2hlY2tib3g+XHJcbiAgICAgIDxpbnB1dFxyXG4gICAgICAgIGlkPVwiY29zdGltaXplLWRyb3Bkb3duLWlucHV0XCJcclxuICAgICAgICB0eXBlPSd0ZXh0J1xyXG4gICAgICAgIFtuZ0NsYXNzXT1cInsgJ3BsLTEnOiAhbXVsdGlwbGUgfVwiXHJcbiAgICAgICAgW2Zvcm1Db250cm9sXT1cInNlYXJjaElucHV0Rm9ybUNvbnRyb2xcIlxyXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJzZWxlY3RQbGFjZWhvbGRlclwiXHJcbiAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcclxuICAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAvPlxyXG4gICAgICA8ZGl2XHJcbiAgICAgICAgY2xhc3M9XCJib3gtc2VhcmNoLWljb25cIlxyXG4gICAgICAgIChjbGljayk9XCJzZWFyY2hJbnB1dEZvcm1Db250cm9sLnNldFZhbHVlKCcnKVwiXHJcbiAgICAgID5cclxuICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cInNlYXJjaC1idXR0b25cIj5cclxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1hdC0yNFwiIGFyaWEtbGFiZWw9XCJTZWFyY2ggaWNvblwiPmNsZWFyPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxtYXQtc2VsZWN0LXRyaWdnZXIgY2xhc3M9XCJvcHRpb24tY29udGFpbmVyXCI+XHJcbiAgICAgIDxzcGFuIGNsYXNzPVwiZWxsaXBzaXMtdGV4dFwiPnt7IGRpc3BsYXlTdHJpbmcgfX08L3NwYW4+XHJcbiAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImZhdm91cml0ZXMgJiYgaXNTZWxlY3RlZEZhdm91cml0ZVwiIGNsYXNzPVwiaW5wdXQtaWNvbiBpY29uLWNvbnRhaW5lciBmYXYtaWNvblwiPnN0YXJfYm9yZGVyPC9tYXQtaWNvbj5cclxuICAgIDwvbWF0LXNlbGVjdC10cmlnZ2VyPlxyXG4gICAgPGRpdiAqbmdJZj1cIm11bHRpcGxlICYmIGZpbHRlckJ1dHRvbnMubGVuZ3RoID4gMFwiIGNsYXNzPVwiZmlsdGVyLWJ1dHRvbnNcIj5cclxuICAgICAgPG1hdC1idXR0b24tdG9nZ2xlLWdyb3VwIG11bHRpcGxlPVwidHJ1ZVwiIGNsYXNzPVwiZmlsdGVyLWJ1dHRvbnMtZ3JvdXBcIj5cclxuICAgICAgICA8bWF0LWJ1dHRvbi10b2dnbGUgY2xhc3M9XCJmaWx0ZXItYnV0dG9uXCIgKm5nRm9yPVwibGV0IGJ1dHRvbiBvZiBmaWx0ZXJCdXR0b25zO1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJidXR0b24ubmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiY2hhbmdlU2VsZWN0ZWRWYWx1ZXMoJGV2ZW50LCBidXR0b24uZmlsdGVyQ2FsbGJhY2spXCI+e3tidXR0b24ubmFtZX19XHJcbiAgICAgICAgPC9tYXQtYnV0dG9uLXRvZ2dsZT5cclxuICAgICAgPC9tYXQtYnV0dG9uLXRvZ2dsZS1ncm91cD5cclxuICAgIDwvZGl2PlxyXG4gICAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydCBbaXRlbVNpemVdPVwiMjRcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cIjI0MFwiIGNsYXNzPVwiY2RrLXZpZXdwb3J0LWZvcm1hdFwiPlxyXG4gICAgICA8bWF0LW9wdGlvblxyXG4gICAgICAgICpjZGtWaXJ0dWFsRm9yPVwibGV0IG9wdGlvbiBvZiBmaWx0ZXJlZE9wdGlvbnM7IHRyYWNrQnk6IHRyYWNrQnlGblwiXHJcbiAgICAgICAgW2Rpc2FibGVkXT1cImN1c3RvbVNlbGVjdEFsbENoZWNrZWRcIlxyXG4gICAgICAgIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIlxyXG4gICAgICAgIChvblNlbGVjdGlvbkNoYW5nZSk9XCJvblNlbGVjdGlvbkNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJvcHRpb24tY29udGFpbmVyXCI+XHJcbiAgICAgICAgICA8c3Bhbj57eyBvcHRpb24uZGlzcGxheSB9fTwvc3Bhbj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi1jb250YWluZXJcIiAqbmdJZj1cImZhdm91cml0ZXMgJiYgb3B0aW9uPy5mYXZvdXJpdGVcIj5cclxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiZmF2LWljb25cIj5zdGFyX2JvcmRlcjwvbWF0LWljb24+XHJcbiAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgIDwvY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0PlxyXG4gIDwvbWF0LXNlbGVjdD5cclxuICA8bWF0LWhpbnQgc3R5bGU9XCJjb2xvcjpyZWRcIiAqbmdJZj1cInNob3dFcnJvck1zZ1wiPnt7IGVycm9yTXNnIH19PC9tYXQtaGludD5cclxuPC9tYXQtZm9ybS1maWVsZD5cclxuIl19