UNPKG

ngx-bootstrap-multiselect-dropdown

Version:

Simple multiselect dropdown based on bootstrap 4 dropdown component.

322 lines (321 loc) 30.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, forwardRef, Input, Output, EventEmitter, HostListener } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { DropdownSettings } from './dropdown-settings'; /** @type {?} */ export const DROPDOWN_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgxBootstrapMultiselectDropdownComponent)), multi: true }; export class NgxBootstrapMultiselectDropdownComponent { constructor() { this.items = []; this.onDataSelect = new EventEmitter(); this.onDataOperationSelect = new EventEmitter(); this.onSelectAllData = new EventEmitter(); this.onDeselectAllData = new EventEmitter(); this.filteredItems = []; this.filterValue = ''; this.isVisible = false; this.selectedItems = []; // Used to keep track if items currently selected. Dropdown item ids are stored // ControlValueAccessor methods this.onChange = (/** * @param {?} selectedObject * @return {?} */ (selectedObject) => { }); this.onTouched = (/** * @return {?} */ () => { }); } // Used to keep track if items currently selected. Dropdown item ids are stored // Close dropdown when clicking outside component /** * @return {?} */ clickOutsideComponent() { if (this.isVisible) this.isVisible = false; } // Prevent event reaching clickOutsideComponent /** * @param {?} event * @return {?} */ handleComponentClick(event) { event.stopPropagation(); } // Return selected items by filtering items array based on values in selectedItems array /** * @return {?} */ getSelectedItems() { this.setSelectedText(); return this.items .filter((/** * @param {?} _ * @return {?} */ _ => this.selectedItems.findIndex((/** * @param {?} x * @return {?} */ x => x === _[this.innerSettings.dataIdProperty])) > -1)) // Return only items with id values in selectedItems .slice(); } // Set text when selecting item from dropdown /** * @return {?} */ setSelectedText() { this.selectedText = this.selectedItems.length ? `${this.selectedItems.length} item${this.selectedItems.length > 1 ? 's' : ''} selected` : this.innerSettings.noneSelectedBtnText; } // Toggle dropdown visibility /** * @return {?} */ showDropdown() { this.isVisible = this.isVisible ? false : true; } // Filter items based on item name property value /** * @param {?} value * @return {?} */ onFilterSearch(value) { this.filterValue = value; // Save filter value so it appears when toggling dropdown this.filteredItems = this.items.filter((/** * @param {?} _ * @return {?} */ _ => _[this.innerSettings.dataNameProperty] && _[this.innerSettings.dataNameProperty].toLowerCase().startsWith(value))); } // Set selected dropdown item as active. Activated on dropdown item click /** * @param {?} selectedObject * @return {?} */ onSelect(selectedObject) { if (this.disabled) return; this.onTouched(); this.writeValue(selectedObject); this.onDataSelect.emit(selectedObject); } // Set all dropdown items as active. Activated on select all button item click /** * @return {?} */ onSelectAll() { if (this.disabled) return; this.onTouched(); this.selectedItems = this.items.map((/** * @param {?} _ * @return {?} */ _ => _[this.innerSettings.dataIdProperty])); this.writeValue(this.selectedItems); this.onSelectAllData.emit(); } // Remove active from all dropdown items. Activated on deselect all button item click /** * @return {?} */ onDeselectAll() { if (this.disabled) return; this.onTouched(); this.selectedItems = []; this.writeValue([]); this.onDeselectAllData.emit(); } // Check if number of selected items is equal or greater than limit /** * @return {?} */ isSelectionLimitReached() { return this.innerSettings.selectionLimit && this.innerSettings.selectionLimit <= this.selectedItems.length; } // Check if drowdown item is active /** * @param {?} item * @return {?} */ isActive(item) { return this.selectedItems.findIndex((/** * @param {?} x * @return {?} */ x => x === item[this.innerSettings.dataIdProperty])) > -1; } // Check if input values exist in selectedItems array. If item exists remove from array, else add /** * @param {?} selectedObject * @return {?} */ writeValue(selectedObject) { if (selectedObject) { /** @type {?} */ const tempArray = Array.isArray(selectedObject) ? (/** @type {?} */ (selectedObject)) : [selectedObject]; /** @type {?} */ const beforeLength = this.selectedItems.length; if (tempArray.length === 0) { this.selectedItems = []; } else { this.items = this.items.map((/** * @param {?} _ * @return {?} */ _ => { /** @type {?} */ var index = tempArray.findIndex((/** * @param {?} x * @return {?} */ x => _[this.innerSettings.dataIdProperty] === x[this.innerSettings.dataIdProperty])); if (index > -1) { /** @type {?} */ const index = this.selectedItems.findIndex((/** * @param {?} x * @return {?} */ x => x === _[this.innerSettings.dataIdProperty])); if (index > -1) { this.selectedItems.splice(index, 1); } else { if (!this.isSelectionLimitReached()) { this.selectedItems.push(_[this.innerSettings.dataIdProperty]); } } } return _; })).slice(); } /** @type {?} */ const afterLength = this.selectedItems.length; if (afterLength > beforeLength) { this.onDataOperationSelect.emit({ operation: "added", item: selectedObject, selectedCount: this.selectedItems.length }); } else if (afterLength < beforeLength) { this.onDataOperationSelect.emit({ operation: "removed", item: selectedObject, selectedCount: this.selectedItems.length }); } } this.onChange(this.getSelectedItems()); } /** * @return {?} */ ngOnInit() { this.innerSettings = new DropdownSettings(this.settings); // Set initial setting values this.filteredItems = this.items; // Set initial filtered values this.setSelectedText(); // Set initial button text } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } } NgxBootstrapMultiselectDropdownComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-bootstrap-multiselect', template: ` <div class="dropdown" (click)="handleComponentClick($event)" > <button style="text-align: right" [disabled]="disabled" type="button" (click)="showDropdown()" [ngClass]="innerSettings.btnClasses" [style.width]="innerSettings.btnWidth"> <span style="float: left">{{selectedText}}</span> </button> <div *ngIf="isVisible" class="dropdown-menu pointer" [ngClass]="innerSettings.dropdownClasses" aria-labelledby="triggerId" style="display: inline-block"> <div class="dropdown-header" *ngIf="innerSettings.headerText">{{innerSettings.headerText}}</div> <div *ngIf="innerSettings.showSelectAllBtn && !innerSettings.selectionLimit" class="dropdown-item" (click)="onSelectAll()">{{innerSettings.selectAllBtnText}}</div> <div *ngIf="innerSettings.showDeselectAllBtn" class="dropdown-item" (click)="onDeselectAll()">{{innerSettings.deselectAllBtnText}}</div> <div *ngIf="innerSettings.enableFilter" class="p-2"><input autocomplete="off" list="autocompleteOff" type="text" placeholder="Filter values" [value]="filterValue" (keyup)="onFilterSearch($event?.target?.value)" class="form-control form-control-sm" /></div> <div class="dropdown-divider" *ngIf="innerSettings.showSelectAllBtn || innerSettings.showDeselectAllBtn || innerSettings.enableFilter"></div> <div [style.height]="innerSettings.dropdownHeight" style="overflow: auto" > <div *ngFor="let item of filteredItems; let i=index" (click)="onSelect(item)" class="dropdown-item" [ngClass]="{'active': isActive(item), 'disabled': disabled }"> {{item[innerSettings.dataNameProperty]}} </div> </div> </div> </div> `, providers: [DROPDOWN_CONTROL_VALUE_ACCESSOR], styles: ['.pointer > .dropdown-item { curson: pointer; }'] }] } ]; NgxBootstrapMultiselectDropdownComponent.propDecorators = { disabled: [{ type: Input }], items: [{ type: Input }], settings: [{ type: Input }], onDataSelect: [{ type: Output }], onDataOperationSelect: [{ type: Output }], onSelectAllData: [{ type: Output }], onDeselectAllData: [{ type: Output }], clickOutsideComponent: [{ type: HostListener, args: ['document:click',] }] }; if (false) { /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.disabled; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.items; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.settings; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onDataSelect; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onDataOperationSelect; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onSelectAllData; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onDeselectAllData; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.innerSettings; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.selectedText; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.filteredItems; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.filterValue; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.isVisible; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.selectedItems; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onChange; /** @type {?} */ NgxBootstrapMultiselectDropdownComponent.prototype.onTouched; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWJvb3RzdHJhcC1tdWx0aXNlbGVjdC1kcm9wZG93bi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwLW11bHRpc2VsZWN0LWRyb3Bkb3duLyIsInNvdXJjZXMiOlsibGliL25neC1ib290c3RyYXAtbXVsdGlzZWxlY3QtZHJvcGRvd24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUFFLGlCQUFpQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQUN2RCxNQUFNLE9BQU8sK0JBQStCLEdBQVE7SUFDbEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVTs7O0lBQUMsR0FBRyxFQUFFLENBQUMsd0NBQXdDLEVBQUM7SUFDdkUsS0FBSyxFQUFFLElBQUk7Q0FDWjtBQStCRCxNQUFNLE9BQU8sd0NBQXdDO0lBOUJyRDtRQWdDa0IsVUFBSyxHQUFVLEVBQUUsQ0FBQztRQUV4QixpQkFBWSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBQzFELDBCQUFxQixHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ25FLG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNyQyxzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRzFDLGtCQUFhLEdBQVUsRUFBRSxDQUFDO1FBQzFCLGdCQUFXLEdBQVcsRUFBRSxDQUFDO1FBQ3pCLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsa0JBQWEsR0FBVSxFQUFFLENBQUMsQ0FBQywrRUFBK0U7O1FBdUhqSCxhQUFROzs7O1FBQUcsQ0FBQyxjQUFxQixFQUFFLEVB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LGlFQUFpQzs7SUF1SGpDLDREQUF5Qzs7SUFDekMsNkRBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIGZvcndhcmRSZWYsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEcm9wZG93blNldHRpbmdzIH0gZnJvbSAnLi9kcm9wZG93bi1zZXR0aW5ncyc7XG5leHBvcnQgY29uc3QgRFJPUERPV05fQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmd4Qm9vdHN0cmFwTXVsdGlzZWxlY3REcm9wZG93bkNvbXBvbmVudCksXG4gIG11bHRpOiB0cnVlXG59O1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWJvb3RzdHJhcC1tdWx0aXNlbGVjdCcsXG4gIHRlbXBsYXRlOiBgXG4gIDxkaXYgY2xhc3M9XCJkcm9wZG93blwiIChjbGljayk9XCJoYW5kbGVDb21wb25lbnRDbGljaygkZXZlbnQpXCIgPlxuICAgIDxidXR0b24gc3R5bGU9XCJ0ZXh0LWFsaWduOiByaWdodFwiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiIFxuICAgICAgKGNsaWNrKT1cInNob3dEcm9wZG93bigpXCJcbiAgICAgIFtuZ0NsYXNzXT1cImlubmVyU2V0dGluZ3MuYnRuQ2xhc3Nlc1wiXG4gICAgICBbc3R5bGUud2lkdGhdPVwiaW5uZXJTZXR0aW5ncy5idG5XaWR0aFwiPlxuICAgICAgPHNwYW4gc3R5bGU9XCJmbG9hdDogbGVmdFwiPnt7c2VsZWN0ZWRUZXh0fX08L3NwYW4+XG4gICAgICBcbiAgICA8L2J1dHRvbj5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNWaXNpYmxlXCIgY2xhc3M9XCJkcm9wZG93bi1tZW51IHBvaW50ZXJcIiBbbmdDbGFzc109XCJpbm5lclNldHRpbmdzLmRyb3Bkb3duQ2xhc3Nlc1wiIGFyaWEtbGFiZWxsZWRieT1cInRyaWdnZXJJZFwiIHN0eWxlPVwiZGlzcGxheTogaW5saW5lLWJsb2NrXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24taGVhZGVyXCIgKm5nSWY9XCJpbm5lclNldHRpbmdzLmhlYWRlclRleHRcIj57e2lubmVyU2V0dGluZ3MuaGVhZGVyVGV4dH19PC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaW5uZXJTZXR0aW5ncy5zaG93U2VsZWN0QWxsQnRuICYmICFpbm5lclNldHRpbmdzLnNlbGVjdGlvbkxpbWl0XCIgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgKGNsaWNrKT1cIm9uU2VsZWN0QWxsKClcIj57e2lubmVyU2V0dGluZ3Muc2VsZWN0QWxsQnRuVGV4dH19PC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaW5uZXJTZXR0aW5ncy5zaG93RGVzZWxlY3RBbGxCdG5cIiBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIiAoY2xpY2spPVwib25EZXNlbGVjdEFsbCgpXCI+e3tpbm5lclNldHRpbmdzLmRlc2VsZWN0QWxsQnRuVGV4dH19PC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaW5uZXJTZXR0aW5ncy5lbmFibGVGaWx0ZXJcIiBjbGFzcz1cInAtMlwiPjxpbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBsaXN0PVwiYXV0b2NvbXBsZXRlT2ZmXCIgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIkZpbHRlciB2YWx1ZXNcIiBbdmFsdWVdPVwiZmlsdGVyVmFsdWVcIiAoa2V5dXApPVwib25GaWx0ZXJTZWFyY2goJGV2ZW50Py50YXJnZXQ/LnZhbHVlKVwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIC8+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tZGl2aWRlclwiICpuZ0lmPVwiaW5uZXJTZXR0aW5ncy5zaG93U2VsZWN0QWxsQnRuIHx8IGlubmVyU2V0dGluZ3Muc2hvd0Rlc2VsZWN0QWxsQnRuIHx8IGlubmVyU2V0dGluZ3MuZW5hYmxlRmlsdGVyXCI+PC9kaXY+XG4gICAgICA8ZGl2IFtzdHlsZS5oZWlnaHRdPVwiaW5uZXJTZXR0aW5ncy5kcm9wZG93bkhlaWdodFwiIHN0eWxlPVwib3ZlcmZsb3c6IGF1dG9cIiA+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZmlsdGVyZWRJdGVtczsgbGV0IGk9aW5kZXhcIiAoY2xpY2spPVwib25TZWxlY3QoaXRlbSlcIiBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGlzQWN0aXZlKGl0ZW0pLCAnZGlzYWJsZWQnOiBkaXNhYmxlZCB9XCI+XG4gICAgICAgICAge3tpdGVtW2lubmVyU2V0dGluZ3MuZGF0YU5hbWVQcm9wZXJ0eV19fSAgICAgICAgICAgIFxuICAgICAgICA8L2Rpdj4gICAgXG4gICAgICA8L2Rpdj4gIFxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbJy5wb2ludGVyID4gLmRyb3Bkb3duLWl0ZW0geyBjdXJzb246IHBvaW50ZXI7IH0nXSxcbiAgcHJvdmlkZXJzOiBbRFJPUERPV05fQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUl1cbn0pXG5leHBvcnQgY2xhc3MgTmd4Qm9vdHN0cmFwTXVsdGlzZWxlY3REcm9wZG93bkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBASW5wdXQoKSBwdWJsaWMgZGlzYWJsZWQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHB1YmxpYyBpdGVtczogYW55W10gPSBbXTtcbiAgQElucHV0KCkgcHVibGljIHNldHRpbmdzOiBhbnk7XG4gIEBPdXRwdXQoKSBvbkRhdGFTZWxlY3Q6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvbkRhdGFPcGVyYXRpb25TZWxlY3Q6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvblNlbGVjdEFsbERhdGEgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkRlc2VsZWN0QWxsRGF0YSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgcHVibGljIGlubmVyU2V0dGluZ3M6IERyb3Bkb3duU2V0dGluZ3M7XG4gIHB1YmxpYyBzZWxlY3RlZFRleHQ6IHN0cmluZztcbiAgcHVibGljIGZpbHRlcmVkSXRlbXM6IGFueVtdID0gW107XG4gIHB1YmxpYyBmaWx0ZXJWYWx1ZTogc3RyaW5nID0gJyc7XG4gIHB1YmxpYyBpc1Zpc2libGUgPSBmYWxzZTtcbiAgcHVibGljIHNlbGVjdGVkSXRlbXM6IGFueVtdID0gW107IC8vIFVzZWQgdG8ga2VlcCB0cmFjayBpZiBpdGVtcyBjdXJyZW50bHkgc2VsZWN0ZWQuIERyb3Bkb3duIGl0ZW0gaWRzIGFyZSBzdG9yZWRcblxuICAvLyBDbG9zZSBkcm9wZG93biB3aGVuIGNsaWNraW5nIG91dHNpZGUgY29tcG9uZW50XG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJykgY2xpY2tPdXRzaWRlQ29tcG9uZW50KCkge1xuICAgIGlmKHRoaXMuaXNWaXNpYmxlKSB0aGlzLmlzVmlzaWJsZSA9IGZhbHNlO1xuICB9XG5cbiAgLy8gUHJldmVudCBldmVudCByZWFjaGluZyBjbGlja091dHNpZGVDb21wb25lbnQgXG4gIGhhbmRsZUNvbXBvbmVudENsaWNrKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBcbiAgfVxuXG4gIC8vIFJldHVybiBzZWxlY3RlZCBpdGVtcyBieSBmaWx0ZXJpbmcgaXRlbXMgYXJyYXkgYmFzZWQgb24gdmFsdWVzIGluIHNlbGVjdGVkSXRlbXMgYXJyYXlcbiAgZ2V0U2VsZWN0ZWRJdGVtcygpIHsgXG4gICAgdGhpcy5zZXRTZWxlY3RlZFRleHQoKTtcbiAgICByZXR1cm4gdGhpcy5pdGVtc1xuICAgICAgLmZpbHRlcihfID0+IHRoaXMuc2VsZWN0ZWRJdGVtcy5maW5kSW5kZXgoeCA9PiB4ID09PSBfW3RoaXMuaW5uZXJTZXR0aW5ncy5kYXRhSWRQcm9wZXJ0eV0pID4gLTEpIC8vIFJldHVybiBvbmx5IGl0ZW1zIHdpdGggaWQgdmFsdWVzIGluIHNlbGVjdGVkSXRlbXNcbiAgICAgIC5zbGljZSgpO1xuICB9XG5cbiAgLy8gU2V0IHRleHQgd2hlbiBzZWxlY3RpbmcgaXRlbSBmcm9tIGRyb3Bkb3duXG4gIHNldFNlbGVjdGVkVGV4dCgpIHtcbiAgICB0aGlzLnNlbGVjdGVkVGV4dCA9IHRoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGggXG4gICAgICA/IGAke3RoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGh9IGl0ZW0ke3RoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGggPiAxID8gJ3MnIDogJyd9IHNlbGVjdGVkYCBcbiAgICAgIDogdGhpcy5pbm5lclNldHRpbmdzLm5vbmVTZWxlY3RlZEJ0blRleHQ7XG4gIH1cblxuICAvLyBUb2dnbGUgZHJvcGRvd24gdmlzaWJpbGl0eVxuICBzaG93RHJvcGRvd24oKSB7XG4gICAgdGhpcy5pc1Zpc2libGUgPSB0aGlzLmlzVmlzaWJsZSA/IGZhbHNlIDogdHJ1ZTtcbiAgfVxuXG4gIC8vIEZpbHRlciBpdGVtcyBiYXNlZCBvbiBpdGVtIG5hbWUgcHJvcGVydHkgdmFsdWVcbiAgb25GaWx0ZXJTZWFyY2godmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuZmlsdGVyVmFsdWUgPSB2YWx1ZTsgLy8gU2F2ZSBmaWx0ZXIgdmFsdWUgc28gaXQgYXBwZWFycyB3aGVuIHRvZ2dsaW5nIGRyb3Bkb3duXG4gICAgdGhpcy5maWx0ZXJlZEl0ZW1zID0gdGhpcy5pdGVtcy5maWx0ZXIoXyA9PiBfW3RoaXMuaW5uZXJTZXR0aW5ncy5kYXRhTmFtZVByb3BlcnR5XSAmJiBfW3RoaXMuaW5uZXJTZXR0aW5ncy5kYXRhTmFtZVByb3BlcnR5XS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgodmFsdWUpKTtcbiAgfVxuXG4gIC8vIFNldCBzZWxlY3RlZCBkcm9wZG93biBpdGVtIGFzIGFjdGl2ZS4gQWN0aXZhdGVkIG9uIGRyb3Bkb3duIGl0ZW0gY2xpY2tcbiAgb25TZWxlY3Qoc2VsZWN0ZWRPYmplY3Q6IGFueSkge1xuICAgIGlmKHRoaXMuZGlzYWJsZWQpIHJldHVybjtcblxuICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgdGhpcy53cml0ZVZhbHVlKHNlbGVjdGVkT2JqZWN0KTsgICAgXG4gICAgdGhpcy5vbkRhdGFTZWxlY3QuZW1pdChzZWxlY3RlZE9iamVjdCk7XG4gIH1cblxuICAvLyBTZXQgYWxsIGRyb3Bkb3duIGl0ZW1zIGFzIGFjdGl2ZS4gQWN0aXZhdGVkIG9uIHNlbGVjdCBhbGwgYnV0dG9uIGl0ZW0gY2xpY2tcbiAgb25TZWxlY3RBbGwoKSB7XG4gICAgaWYodGhpcy5kaXNhYmxlZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB0aGlzLnNlbGVjdGVkSXRlbXMgPSB0aGlzLml0ZW1zLm1hcChfID0+IF9bdGhpcy5pbm5lclNldHRpbmdzLmRhdGFJZFByb3BlcnR5XSk7XG4gICAgdGhpcy53cml0ZVZhbHVlKHRoaXMuc2VsZWN0ZWRJdGVtcyk7ICAgIFxuICAgIHRoaXMub25TZWxlY3RBbGxEYXRhLmVtaXQoKTtcbiAgfVxuXG4gIC8vIFJlbW92ZSBhY3RpdmUgZnJvbSBhbGwgZHJvcGRvd24gaXRlbXMuIEFjdGl2YXRlZCBvbiBkZXNlbGVjdCBhbGwgYnV0dG9uIGl0ZW0gY2xpY2tcbiAgb25EZXNlbGVjdEFsbCgpIHtcbiAgICBpZih0aGlzLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IFtdO1xuICAgIHRoaXMud3JpdGVWYWx1ZShbXSk7ICAgIFxuICAgIHRoaXMub25EZXNlbGVjdEFsbERhdGEuZW1pdCgpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgbnVtYmVyIG9mIHNlbGVjdGVkIGl0ZW1zIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBsaW1pdFxuICBpc1NlbGVjdGlvbkxpbWl0UmVhY2hlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbm5lclNldHRpbmdzLnNlbGVjdGlvbkxpbWl0ICYmIHRoaXMuaW5uZXJTZXR0aW5ncy5zZWxlY3Rpb25MaW1pdCA8PSB0aGlzLnNlbGVjdGVkSXRlbXMubGVuZ3RoO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgZHJvd2Rvd24gaXRlbSBpcyBhY3RpdmVcbiAgaXNBY3RpdmUoaXRlbTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJdGVtcy5maW5kSW5kZXgoeCA9PiB4ID09PSBpdGVtW3RoaXMuaW5uZXJTZXR0aW5ncy5kYXRhSWRQcm9wZXJ0eV0pID4gLTE7XG4gIH1cbiAgXG4gIC8vIENoZWNrIGlmIGlucHV0IHZhbHVlcyBleGlzdCBpbiBzZWxlY3RlZEl0ZW1zIGFycmF5LiBJZiBpdGVtIGV4aXN0cyByZW1vdmUgZnJvbSBhcnJheSwgZWxzZSBhZGRcbiAgd3JpdGVWYWx1ZShzZWxlY3RlZE9iamVjdDogYW55KSB7ICAgXG4gICAgaWYoc2VsZWN0ZWRPYmplY3QpIHsgICBcbiAgICAgIGNvbnN0IHRlbXBBcnJheSA9IEFycmF5LmlzQXJyYXkoc2VsZWN0ZWRPYmplY3QpID8gc2VsZWN0ZWRPYmplY3QgYXMgYW55W10gOiBbc2VsZWN0ZWRPYmplY3RdO1xuICAgICAgY29uc3QgYmVmb3JlTGVuZ3RoID0gdGhpcy5zZWxlY3RlZEl0ZW1zLmxlbmd0aDtcbiAgICAgIGlmKHRlbXBBcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zID0gW107XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5pdGVtcyA9IHRoaXMuaXRlbXMubWFwKF8gPT4ge1xuICAgICAgICAgIHZhciBpbmRleCA9IHRlbXBBcnJheS5maW5kSW5kZXgoeCA9PiBfW3RoaXMuaW5uZXJTZXR0aW5ncy5kYXRhSWRQcm9wZXJ0eV0gPT09IHhbdGhpcy5pbm5lclNldHRpbmdzLmRhdGFJZFByb3BlcnR5XSk7XG4gICAgICAgICAgaWYoaW5kZXggPiAtMSkgeyBcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5zZWxlY3RlZEl0ZW1zLmZpbmRJbmRleCh4ID0+IHggPT09IF9bdGhpcy5pbm5lclNldHRpbmdzLmRhdGFJZFByb3BlcnR5XSk7XG4gICAgICAgICAgICBpZihpbmRleCA+IC0xKSB7IFxuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbXMuc3BsaWNlKGluZGV4LCAxKTsgXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZighdGhpcy5pc1NlbGVjdGlvbkxpbWl0UmVhY2hlZCgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnB1c2goX1t0aGlzLmlubmVyU2V0dGluZ3MuZGF0YUlkUHJvcGVydHldKTsgXG4gICAgICAgICAgICAgIH0gIFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgcmV0dXJuIF87XG4gICAgICAgIH0pLnNsaWNlKCk7ICAgICBcbiAgICAgIH0gIFxuICAgICAgY29uc3QgYWZ0ZXJMZW5ndGggPSB0aGlzLnNlbGVjdGVkSXRlbXMubGVuZ3RoO1xuICAgICAgaWYgKGFmdGVyTGVuZ3RoID4gYmVmb3JlTGVuZ3RoKSB7XG4gICAgICAgIHRoaXMub25EYXRhT3BlcmF0aW9uU2VsZWN0LmVtaXQoeyBvcGVyYXRpb246IFwiYWRkZWRcIiwgaXRlbTogc2VsZWN0ZWRPYmplY3QsIHNlbGVjdGVkQ291bnQ6IHRoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGggfSk7XG4gICAgICB9IGVsc2UgaWYgKGFmdGVyTGVuZ3RoIDwgYmVmb3JlTGVuZ3RoKSB7XG4gICAgICAgIHRoaXMub25EYXRhT3BlcmF0aW9uU2VsZWN0LmVtaXQoeyBvcGVyYXRpb246IFwicmVtb3ZlZFwiLCBpdGVtOiBzZWxlY3RlZE9iamVjdCwgc2VsZWN0ZWRDb3VudDogdGhpcy5zZWxlY3RlZEl0ZW1zLmxlbmd0aCB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5vbkNoYW5nZSh0aGlzLmdldFNlbGVjdGVkSXRlbXMoKSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHsgXG4gICAgdGhpcy5pbm5lclNldHRpbmdzID0gbmV3IERyb3Bkb3duU2V0dGluZ3ModGhpcy5zZXR0aW5ncyk7IC8vIFNldCBpbml0aWFsIHNldHRpbmcgdmFsdWVzXG4gICAgdGhpcy5maWx0ZXJlZEl0ZW1zID0gdGhpcy5pdGVtczsgLy8gU2V0IGluaXRpYWwgZmlsdGVyZWQgdmFsdWVzXG4gICAgdGhpcy5zZXRTZWxlY3RlZFRleHQoKTsgLy8gU2V0IGluaXRpYWwgYnV0dG9uIHRleHRcbiAgfVxuXG4gIC8vIENvbnRyb2xWYWx1ZUFjY2Vzc29yIG1ldGhvZHNcbiAgb25DaGFuZ2UgPSAoc2VsZWN0ZWRPYmplY3Q6IGFueVtdKSA9PiB7fTtcbiAgb25Ub3VjaGVkID0gKCkgPT4ge307XG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KSB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfSBcbn1cblxuIl19