UNPKG

systelab-components

Version:

systelab-components is a set of components that use wide accepted and adopted standard technologies like Angular and Bootstrap, as well as other popular libraries. Please read the ATTRIBUTION.md file for a complete list of dependencies.

138 lines 30.9 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { DataFilterPipe } from './datafilter.pipe'; import { CurrentSelectionStatus } from './two-list-utilities'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "../button/button.component"; import * as i4 from "./two-list-sortable-list.component"; import * as i5 from "systelab-translate"; import * as i6 from "./datafilter.pipe"; export class TwoListComponent { get available() { return this._available; } set available(list) { this._available = list; this.availableChange.emit(this._available); } get visible() { return this._visible; } set visible(list) { this._visible = list; this.visibleChange.emit(this._visible); } constructor() { this._available = []; this._visible = []; this.visibleChange = new EventEmitter(); this.availableChange = new EventEmitter(); this.dragAndDropEnabled = true; this.currentSelectionStatus = new CurrentSelectionStatus([], []); } add() { for (const element of this.currentSelectionStatus.available) { element.isVisible = true; } this.visible = this.visible.concat(new DataFilterPipe().transform(this.currentSelectionStatus.available, this.firstListSearch)); this.refresh(false); } addAll() { this.visible = this.visible.concat(new DataFilterPipe().transform(this.available, this.firstListSearch)); for (const element of this.visible) { element.isVisible = true; } this.refresh(false); } removeAll() { this.available = this.available.concat(new DataFilterPipe().transform(this.visible, this.secondListSearch)); this.visible = this.removeItemsFromList(this.visible, new DataFilterPipe().transform(this.visible, this.secondListSearch)); for (const element of this.available) { element.isVisible = false; } this.refresh(true); } remove() { for (const element of this.currentSelectionStatus.available) { element.isVisible = false; } this.available = this.available.concat(new DataFilterPipe().transform(this.currentSelectionStatus.visible, this.secondListSearch)); this.visible = this.removeItemsFromList(this.visible, new DataFilterPipe().transform(this.currentSelectionStatus.visible, this.secondListSearch)); this.refresh(true); } refresh(sortAvailable) { this.firstListSearch = ''; this.secondListSearch = ''; if (sortAvailable) { this.available = this.sort(this.available); } this.available = this.removeItemsFromList(new DataFilterPipe().transform(this.available, this.firstListSearch), this.visible); this.currentSelectionStatus.clearAll(); } sort(list) { const arrayAux = []; const theReturn = []; const length = list.length; for (const actual of this.initialAvailableColumns) { if (arrayAux.length === length) { break; } for (let j = 0; j < length; j++) { if (actual.colId === list[j].colId) { arrayAux.push(j); break; } } } for (let i = 0; i < length; i++) { theReturn[i] = list[arrayAux[i]]; } return theReturn; } setDefaultColumnValues() { this.available = this.defaultHiddenColumns; this.visible = this.defaultVisibleColumns; } removeItemsFromList(list, itemsToRemove) { return list.filter(element => !itemsToRemove.some(item => item.colId === element.colId)); } selectAvailableItem(element, ev) { const availableFilteredList = new DataFilterPipe().transform(this.available, this.firstListSearch); this.currentSelectionStatus.selectAvailable(element, availableFilteredList, ev.shiftKey, ev.ctrlKey); } moveSelectedItemsFromAvailableToVisible(element, ev) { this.available = this.removeItemsFromList(this.available, [element]); element.isVisible = true; this.visible = this.visible.concat(element); } moveSelectedItemsFromVisibleToAvailable(element) { element.isVisible = false; this.available = this.available.concat(new DataFilterPipe().transform([element], this.secondListSearch)); this.visible = this.removeItemsFromList(this.visible, new DataFilterPipe().transform([element], this.secondListSearch)); this.refresh(true); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: TwoListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.9", type: TwoListComponent, selector: "systelab-two-list", inputs: { available: "available", visible: "visible", initialAvailableColumns: "initialAvailableColumns", defaultVisibleColumns: "defaultVisibleColumns", defaultHiddenColumns: "defaultHiddenColumns", dragAndDropEnabled: "dragAndDropEnabled" }, outputs: { visibleChange: "visibleChange", availableChange: "availableChange" }, ngImport: i0, template: "<div class=\"slab-twolist h-100\">\n <div class=\"slab-twolistdiv\">\n <label>{{'COMMON_AVAILABLE_FIELDS' | translate | async }} ({{ available.length }})</label>\n <div>\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"firstListSearch\">\n </div>\n <div id=\"left-list\" class=\"slab-twolistbox\">\n <div class=\"slab-twolistboxdiv\">\n <ul class=\"slab-twolistboxrow list-group\">\n <li *ngFor=\"let item of (available | datafilter:firstListSearch); let i=index;\" [id]=\"'available'+i\"\n [ngClass]=\"{'slab-twolistboxrow slab-twolistboxrowselected':item.isSelected,'slab-twolistboxrow':!item.isSelected}\"\n [class.slab-twolistboxrow-even-row]=\"0 === i % 2\"\n [class.slab-twolistboxrow-odd-row]=\"1 === i % 2\"\n (click)=\"selectAvailableItem(item, $event)\" (dblclick)=\"moveSelectedItemsFromAvailableToVisible(item, $event)\">\n {{item.displayName}}\n </li>\n </ul>\n </div>\n </div>\n <systelab-button type=\"link\" id=\"slab-add-all\" [disabled]=\"available.length == 0\" (click)=\"addAll()\">{{'COMMON_ADD_ALL' | translate | async }} ({{ available.length }})</systelab-button>\n </div>\n <div class=\"slab-twolistbuttondiv\">\n <button type=\"button\" class=\"btn icon-angle-right\" (click)=\"add()\" title=\"{{'COMMON_ADD_SELECTED' | translate | async }}\"\n [disabled]=\"currentSelectionStatus.available.length == 0\">\n </button>\n <button type=\"button\" class=\"btn icon-angle-left\" (click)=\"remove()\" title=\"{{'COMMON_REMOVE_SELECTED' | translate | async }}\"\n [disabled]=\"currentSelectionStatus.visible.length == 0\">\n </button>\n </div>\n\n <div class=\"slab-twolistdiv\">\n <label>{{'COMMON_FIELDS_TO_SHOW' | translate | async }} ({{ visible.length }})</label>\n <div>\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"secondListSearch\">\n </div>\n <div id=\"right-list\" class=\"slab-twolistbox text-nowrap\">\n <systelab-two-list-sortable-list class=\"w-100\" [currentSelectionStatus]=\"currentSelectionStatus\"\n [(elementsList)]=\"visible\" [secondListSearch]=\"secondListSearch\" [dragAndDropEnabled]=\"dragAndDropEnabled\"\n (dbClick)=\"moveSelectedItemsFromVisibleToAvailable($event)\"></systelab-two-list-sortable-list>\n </div>\n <systelab-button type=\"link\" id=\"slab-remove-all\" [disabled]=\"visible.length == 0\" (click)=\"removeAll()\">{{'COMMON_REMOVE_ALL' | translate | async }} ({{ visible.length }})</systelab-button>\n </div>\n</div>\n", styles: [":host{width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: "component", type: i3.ButtonComponent, selector: "systelab-button", inputs: ["disabled", "type", "size"], outputs: ["action"] }, { kind: "component", type: i4.TwoListSortableListComponent, selector: "systelab-two-list-sortable-list", inputs: ["currentSelectionStatus", "secondListSearch"], outputs: ["dbClick"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.GeneralTranslatePipe, name: "translate" }, { kind: "pipe", type: i6.DataFilterPipe, name: "datafilter" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: TwoListComponent, decorators: [{ type: Component, args: [{ selector: 'systelab-two-list', template: "<div class=\"slab-twolist h-100\">\n <div class=\"slab-twolistdiv\">\n <label>{{'COMMON_AVAILABLE_FIELDS' | translate | async }} ({{ available.length }})</label>\n <div>\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"firstListSearch\">\n </div>\n <div id=\"left-list\" class=\"slab-twolistbox\">\n <div class=\"slab-twolistboxdiv\">\n <ul class=\"slab-twolistboxrow list-group\">\n <li *ngFor=\"let item of (available | datafilter:firstListSearch); let i=index;\" [id]=\"'available'+i\"\n [ngClass]=\"{'slab-twolistboxrow slab-twolistboxrowselected':item.isSelected,'slab-twolistboxrow':!item.isSelected}\"\n [class.slab-twolistboxrow-even-row]=\"0 === i % 2\"\n [class.slab-twolistboxrow-odd-row]=\"1 === i % 2\"\n (click)=\"selectAvailableItem(item, $event)\" (dblclick)=\"moveSelectedItemsFromAvailableToVisible(item, $event)\">\n {{item.displayName}}\n </li>\n </ul>\n </div>\n </div>\n <systelab-button type=\"link\" id=\"slab-add-all\" [disabled]=\"available.length == 0\" (click)=\"addAll()\">{{'COMMON_ADD_ALL' | translate | async }} ({{ available.length }})</systelab-button>\n </div>\n <div class=\"slab-twolistbuttondiv\">\n <button type=\"button\" class=\"btn icon-angle-right\" (click)=\"add()\" title=\"{{'COMMON_ADD_SELECTED' | translate | async }}\"\n [disabled]=\"currentSelectionStatus.available.length == 0\">\n </button>\n <button type=\"button\" class=\"btn icon-angle-left\" (click)=\"remove()\" title=\"{{'COMMON_REMOVE_SELECTED' | translate | async }}\"\n [disabled]=\"currentSelectionStatus.visible.length == 0\">\n </button>\n </div>\n\n <div class=\"slab-twolistdiv\">\n <label>{{'COMMON_FIELDS_TO_SHOW' | translate | async }} ({{ visible.length }})</label>\n <div>\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"secondListSearch\">\n </div>\n <div id=\"right-list\" class=\"slab-twolistbox text-nowrap\">\n <systelab-two-list-sortable-list class=\"w-100\" [currentSelectionStatus]=\"currentSelectionStatus\"\n [(elementsList)]=\"visible\" [secondListSearch]=\"secondListSearch\" [dragAndDropEnabled]=\"dragAndDropEnabled\"\n (dbClick)=\"moveSelectedItemsFromVisibleToAvailable($event)\"></systelab-two-list-sortable-list>\n </div>\n <systelab-button type=\"link\" id=\"slab-remove-all\" [disabled]=\"visible.length == 0\" (click)=\"removeAll()\">{{'COMMON_REMOVE_ALL' | translate | async }} ({{ visible.length }})</systelab-button>\n </div>\n</div>\n", styles: [":host{width:100%;height:100%}\n"] }] }], ctorParameters: () => [], propDecorators: { available: [{ type: Input }], visible: [{ type: Input }], visibleChange: [{ type: Output }], availableChange: [{ type: Output }], initialAvailableColumns: [{ type: Input }], defaultVisibleColumns: [{ type: Input }], defaultHiddenColumns: [{ type: Input }], dragAndDropEnabled: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHdvLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3lzdGVsYWItY29tcG9uZW50cy9zcmMvbGliL3R3b2xpc3QvdHdvLWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3lzdGVsYWItY29tcG9uZW50cy9zcmMvbGliL3R3b2xpc3QvdHdvLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLHNCQUFzQixFQUFlLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7O0FBWTNFLE1BQU0sT0FBTyxnQkFBZ0I7SUFHNUIsSUFDSSxTQUFTO1FBQ1osT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxJQUF3QjtRQUNyQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUdELElBQ0ksT0FBTztRQUNWLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN0QixDQUFDO0lBRUQsSUFBSSxPQUFPLENBQUMsSUFBd0I7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFlRDtRQW5DTyxlQUFVLEdBQXVCLEVBQUUsQ0FBQztRQVdwQyxhQUFRLEdBQXVCLEVBQUUsQ0FBQztRQVd4Qixr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LGNBQWMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDekcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLGNBQWMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDeEgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQixDQUFDOzhHQXBJVyxnQkFBZ0I7a0dBQWhCLGdCQUFnQiw4WENkN0IsNDBGQTJDQTs7MkZEN0JhLGdCQUFnQjtrQkFWNUIsU0FBUzsrQkFDSSxtQkFBbUI7d0RBYTVCLFNBQVM7c0JBRFosS0FBSztnQkFZRixPQUFPO3NCQURWLEtBQUs7Z0JBVVcsYUFBYTtzQkFBN0IsTUFBTTtnQkFDVSxlQUFlO3NCQUEvQixNQUFNO2dCQUVTLHVCQUF1QjtzQkFBdEMsS0FBSztnQkFDVSxxQkFBcUI7c0JBQXBDLEtBQUs7Z0JBQ1Usb0JBQW9CO3NCQUFuQyxLQUFLO2dCQUVVLGtCQUFrQjtzQkFBakMsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEYXRhRmlsdGVyUGlwZSB9IGZyb20gJy4vZGF0YWZpbHRlci5waXBlJztcbmltcG9ydCB7IEN1cnJlbnRTZWxlY3Rpb25TdGF0dXMsIFR3b0xpc3RJdGVtIH0gZnJvbSAnLi90d28tbGlzdC11dGlsaXRpZXMnO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICAgICdzeXN0ZWxhYi10d28tbGlzdCcsXG5cdHRlbXBsYXRlVXJsOiAndHdvLWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuXHRzdHlsZXM6ICAgICAgW2BcbiAgICAgICAgOmhvc3Qge1xuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIH1cblx0YF1cbn0pXG5leHBvcnQgY2xhc3MgVHdvTGlzdENvbXBvbmVudCB7XG5cblx0cHVibGljIF9hdmFpbGFibGU6IEFycmF5PFR3b0xpc3RJdGVtPiA9IFtdO1xuXHRASW5wdXQoKVxuXHRnZXQgYXZhaWxhYmxlKCkge1xuXHRcdHJldHVybiB0aGlzLl9hdmFpbGFibGU7XG5cdH1cblxuXHRzZXQgYXZhaWxhYmxlKGxpc3Q6IEFycmF5PFR3b0xpc3RJdGVtPikge1xuXHRcdHRoaXMuX2F2YWlsYWJsZSA9IGxpc3Q7XG5cdFx0dGhpcy5hdmFpbGFibGVDaGFuZ2UuZW1pdCh0aGlzLl9hdmFpbGFibGUpO1xuXHR9XG5cblx0cHVibGljIF92aXNpYmxlOiBBcnJheTxUd29MaXN0SXRlbT4gPSBbXTtcblx0QElucHV0KClcblx0Z2V0IHZpc2libGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3Zpc2libGU7XG5cdH1cblxuXHRzZXQgdmlzaWJsZShsaXN0OiBBcnJheTxUd29MaXN0SXRlbT4pIHtcblx0XHR0aGlzLl92aXNpYmxlID0gbGlzdDtcblx0XHR0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh0aGlzLl92aXNpYmxlKTtcblx0fVxuXG5cdEBPdXRwdXQoKSBwdWJsaWMgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8QXJyYXk8VHdvTGlzdEl0ZW0+PigpO1xuXHRAT3V0cHV0KCkgcHVibGljIGF2YWlsYWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8QXJyYXk8VHdvTGlzdEl0ZW0+PigpO1xuXG5cdEBJbnB1dCgpIHB1YmxpYyBpbml0aWFsQXZhaWxhYmxlQ29sdW1uczogQXJyYXk8VHdvTGlzdEl0ZW0+O1xuXHRASW5wdXQoKSBwdWJsaWMgZGVmYXVsdFZpc2libGVDb2x1bW5zOiBBcnJheTxUd29MaXN0SXRlbT47XG5cdEBJbnB1dCgpIHB1YmxpYyBkZWZhdWx0SGlkZGVuQ29sdW1uczogQXJyYXk8VHdvTGlzdEl0ZW0+O1xuXG5cdEBJbnB1dCgpIHB1YmxpYyBkcmFnQW5kRHJvcEVuYWJsZWQgPSB0cnVlO1xuXG5cdHB1YmxpYyBmaXJzdExpc3RTZWFyY2g6IHN0cmluZztcblx0cHVibGljIHNlY29uZExpc3RTZWFyY2g6IHN0cmluZztcblx0cHVibGljIGN1cnJlbnRTZWxlY3Rpb25TdGF0dXM6IEN1cnJlbnRTZWxlY3Rpb25TdGF0dXMgPSBuZXcgQ3VycmVudFNlbGVjdGlvblN0YXR1cyhbXSwgW10pO1xuXG5cdGNvbnN0cnVjdG9yKCkge1xuXHR9XG5cblx0cHVibGljIGFkZCgpIHtcblx0XHRmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGhpcy5jdXJyZW50U2VsZWN0aW9uU3RhdHVzLmF2YWlsYWJsZSkge1xuXHRcdFx0ZWxlbWVudC5pc1Zpc2libGUgPSB0cnVlO1xuXHRcdH1cblx0XHR0aGlzLnZpc2libGUgPSB0aGlzLnZpc2libGUuY29uY2F0KG5ldyBEYXRhRmlsdGVyUGlwZSgpLnRyYW5zZm9ybSh0aGlzLmN1cnJlbnRTZWxlY3Rpb25TdGF0dXMuYXZhaWxhYmxlLCB0aGlzLmZpcnN0TGlzdFNlYXJjaCkpO1xuXHRcdHRoaXMucmVmcmVzaChmYWxzZSk7XG5cdH1cblxuXHRwdWJsaWMgYWRkQWxsKCkge1xuXHRcdHRoaXMudmlzaWJsZSA9IHRoaXMudmlzaWJsZS5jb25jYXQobmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKHRoaXMuYXZhaWxhYmxlLCB0aGlzLmZpcnN0TGlzdFNlYXJjaCkpO1xuXHRcdGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLnZpc2libGUpIHtcblx0XHRcdGVsZW1lbnQuaXNWaXNpYmxlID0gdHJ1ZTtcblx0XHR9XG5cdFx0dGhpcy5yZWZyZXNoKGZhbHNlKTtcblx0fVxuXG5cdHB1YmxpYyByZW1vdmVBbGwoKSB7XG5cdFx0dGhpcy5hdmFpbGFibGUgPSB0aGlzLmF2YWlsYWJsZS5jb25jYXQobmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKHRoaXMudmlzaWJsZSwgdGhpcy5zZWNvbmRMaXN0U2VhcmNoKSk7XG5cdFx0dGhpcy52aXNpYmxlID0gdGhpcy5yZW1vdmVJdGVtc0Zyb21MaXN0KHRoaXMudmlzaWJsZSwgbmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKHRoaXMudmlzaWJsZSwgdGhpcy5zZWNvbmRMaXN0U2VhcmNoKSk7XG5cdFx0Zm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuYXZhaWxhYmxlKSB7XG5cdFx0XHRlbGVtZW50LmlzVmlzaWJsZSA9IGZhbHNlO1xuXHRcdH1cblx0XHR0aGlzLnJlZnJlc2godHJ1ZSk7XG5cdH1cblxuXHRwdWJsaWMgcmVtb3ZlKCkge1xuXHRcdGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLmN1cnJlbnRTZWxlY3Rpb25TdGF0dXMuYXZhaWxhYmxlKSB7XG5cdFx0XHRlbGVtZW50LmlzVmlzaWJsZSA9IGZhbHNlO1xuXHRcdH1cblx0XHR0aGlzLmF2YWlsYWJsZSA9IHRoaXMuYXZhaWxhYmxlLmNvbmNhdChuZXcgRGF0YUZpbHRlclBpcGUoKS50cmFuc2Zvcm0odGhpcy5jdXJyZW50U2VsZWN0aW9uU3RhdHVzLnZpc2libGUsIHRoaXMuc2Vjb25kTGlzdFNlYXJjaCkpO1xuXHRcdHRoaXMudmlzaWJsZSA9IHRoaXMucmVtb3ZlSXRlbXNGcm9tTGlzdCh0aGlzLnZpc2libGUsIG5ldyBEYXRhRmlsdGVyUGlwZSgpLnRyYW5zZm9ybSh0aGlzLmN1cnJlbnRTZWxlY3Rpb25TdGF0dXMudmlzaWJsZSwgdGhpcy5zZWNvbmRMaXN0U2VhcmNoKSk7XG5cdFx0dGhpcy5yZWZyZXNoKHRydWUpO1xuXHR9XG5cblx0cHJpdmF0ZSByZWZyZXNoKHNvcnRBdmFpbGFibGU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmZpcnN0TGlzdFNlYXJjaCA9ICcnO1xuXHRcdHRoaXMuc2Vjb25kTGlzdFNlYXJjaCA9ICcnO1xuXHRcdGlmIChzb3J0QXZhaWxhYmxlKSB7XG5cdFx0XHR0aGlzLmF2YWlsYWJsZSA9IHRoaXMuc29ydCh0aGlzLmF2YWlsYWJsZSk7XG5cdFx0fVxuXHRcdHRoaXMuYXZhaWxhYmxlID0gdGhpcy5yZW1vdmVJdGVtc0Zyb21MaXN0KG5ldyBEYXRhRmlsdGVyUGlwZSgpLnRyYW5zZm9ybSh0aGlzLmF2YWlsYWJsZSwgdGhpcy5maXJzdExpc3RTZWFyY2gpLCB0aGlzLnZpc2libGUpO1xuXHRcdHRoaXMuY3VycmVudFNlbGVjdGlvblN0YXR1cy5jbGVhckFsbCgpO1xuXHR9XG5cblx0cHJpdmF0ZSBzb3J0KGxpc3Q6IEFycmF5PFR3b0xpc3RJdGVtPikge1xuXG5cdFx0Y29uc3QgYXJyYXlBdXggPSBbXTtcblx0XHRjb25zdCB0aGVSZXR1cm46IEFycmF5PFR3b0xpc3RJdGVtPiA9IFtdO1xuXHRcdGNvbnN0IGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuXG5cdFx0Zm9yIChjb25zdCBhY3R1YWwgb2YgdGhpcy5pbml0aWFsQXZhaWxhYmxlQ29sdW1ucykge1xuXHRcdFx0aWYgKGFycmF5QXV4Lmxlbmd0aCA9PT0gbGVuZ3RoKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGg7IGorKykge1xuXHRcdFx0XHRpZiAoYWN0dWFsLmNvbElkID09PSBsaXN0W2pdLmNvbElkKSB7XG5cdFx0XHRcdFx0YXJyYXlBdXgucHVzaChqKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGVSZXR1cm5baV0gPSBsaXN0W2FycmF5QXV4W2ldXTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoZVJldHVybjtcblx0fVxuXG5cdHB1YmxpYyBzZXREZWZhdWx0Q29sdW1uVmFsdWVzKCk6IHZvaWQge1xuXHRcdHRoaXMuYXZhaWxhYmxlID0gdGhpcy5kZWZhdWx0SGlkZGVuQ29sdW1ucztcblx0XHR0aGlzLnZpc2libGUgPSB0aGlzLmRlZmF1bHRWaXNpYmxlQ29sdW1ucztcblx0fVxuXG5cdHB1YmxpYyByZW1vdmVJdGVtc0Zyb21MaXN0KGxpc3Q6IEFycmF5PGFueT4sIGl0ZW1zVG9SZW1vdmU6IEFycmF5PGFueT4pOiBBcnJheTxhbnk+IHtcblx0XHRyZXR1cm4gbGlzdC5maWx0ZXIoZWxlbWVudCA9PiAhaXRlbXNUb1JlbW92ZS5zb21lKGl0ZW0gPT4gaXRlbS5jb2xJZCA9PT0gZWxlbWVudC5jb2xJZCkpO1xuXHR9XG5cblx0cHVibGljIHNlbGVjdEF2YWlsYWJsZUl0ZW0oZWxlbWVudDogVHdvTGlzdEl0ZW0sIGV2OiBLZXlib2FyZEV2ZW50KSB7XG5cdFx0Y29uc3QgYXZhaWxhYmxlRmlsdGVyZWRMaXN0ID0gbmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKHRoaXMuYXZhaWxhYmxlLCB0aGlzLmZpcnN0TGlzdFNlYXJjaCk7XG5cdFx0dGhpcy5jdXJyZW50U2VsZWN0aW9uU3RhdHVzLnNlbGVjdEF2YWlsYWJsZShlbGVtZW50LCBhdmFpbGFibGVGaWx0ZXJlZExpc3QsIGV2LnNoaWZ0S2V5LCBldi5jdHJsS2V5KTtcblx0fVxuXG5cdHB1YmxpYyBtb3ZlU2VsZWN0ZWRJdGVtc0Zyb21BdmFpbGFibGVUb1Zpc2libGUoZWxlbWVudDogVHdvTGlzdEl0ZW0sIGV2OiBFdmVudCkge1xuXHRcdHRoaXMuYXZhaWxhYmxlID0gdGhpcy5yZW1vdmVJdGVtc0Zyb21MaXN0KHRoaXMuYXZhaWxhYmxlLCBbZWxlbWVudF0pO1xuXHRcdGVsZW1lbnQuaXNWaXNpYmxlID0gdHJ1ZTtcblx0XHR0aGlzLnZpc2libGUgPSB0aGlzLnZpc2libGUuY29uY2F0KGVsZW1lbnQpO1xuXHR9XG5cblx0cHVibGljIG1vdmVTZWxlY3RlZEl0ZW1zRnJvbVZpc2libGVUb0F2YWlsYWJsZShlbGVtZW50OiBUd29MaXN0SXRlbSkge1xuXHRcdGVsZW1lbnQuaXNWaXNpYmxlID0gZmFsc2U7XG5cdFx0dGhpcy5hdmFpbGFibGUgPSB0aGlzLmF2YWlsYWJsZS5jb25jYXQobmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKFtlbGVtZW50XSwgdGhpcy5zZWNvbmRMaXN0U2VhcmNoKSk7XG5cdFx0dGhpcy52aXNpYmxlID0gdGhpcy5yZW1vdmVJdGVtc0Zyb21MaXN0KHRoaXMudmlzaWJsZSwgbmV3IERhdGFGaWx0ZXJQaXBlKCkudHJhbnNmb3JtKFtlbGVtZW50XSwgdGhpcy5zZWNvbmRMaXN0U2VhcmNoKSk7XG5cdFx0dGhpcy5yZWZyZXNoKHRydWUpO1xuXHR9XG59XG4iLCI8ZGl2IGNsYXNzPVwic2xhYi10d29saXN0IGgtMTAwXCI+XG4gICAgPGRpdiBjbGFzcz1cInNsYWItdHdvbGlzdGRpdlwiPlxuICAgICAgICA8bGFiZWw+e3snQ09NTU9OX0FWQUlMQUJMRV9GSUVMRFMnIHwgdHJhbnNsYXRlIHwgYXN5bmMgfX0gKHt7IGF2YWlsYWJsZS5sZW5ndGggfX0pPC9sYWJlbD5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgWyhuZ01vZGVsKV09XCJmaXJzdExpc3RTZWFyY2hcIj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJsZWZ0LWxpc3RcIiBjbGFzcz1cInNsYWItdHdvbGlzdGJveFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNsYWItdHdvbGlzdGJveGRpdlwiPlxuICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cInNsYWItdHdvbGlzdGJveHJvdyBsaXN0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgaXRlbSBvZiAoYXZhaWxhYmxlIHwgZGF0YWZpbHRlcjpmaXJzdExpc3RTZWFyY2gpOyBsZXQgaT1pbmRleDtcIiBbaWRdPVwiJ2F2YWlsYWJsZScraVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3NsYWItdHdvbGlzdGJveHJvdyBzbGFiLXR3b2xpc3Rib3hyb3dzZWxlY3RlZCc6aXRlbS5pc1NlbGVjdGVkLCdzbGFiLXR3b2xpc3Rib3hyb3cnOiFpdGVtLmlzU2VsZWN0ZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5zbGFiLXR3b2xpc3Rib3hyb3ctZXZlbi1yb3ddPVwiMCA9PT0gaSAlIDJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnNsYWItdHdvbGlzdGJveHJvdy1vZGQtcm93XT1cIjEgPT09IGkgJSAyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RBdmFpbGFibGVJdGVtKGl0ZW0sICRldmVudClcIiAoZGJsY2xpY2spPVwibW92ZVNlbGVjdGVkSXRlbXNGcm9tQXZhaWxhYmxlVG9WaXNpYmxlKGl0ZW0sICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7aXRlbS5kaXNwbGF5TmFtZX19XG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHN5c3RlbGFiLWJ1dHRvbiB0eXBlPVwibGlua1wiIGlkPVwic2xhYi1hZGQtYWxsXCIgW2Rpc2FibGVkXT1cImF2YWlsYWJsZS5sZW5ndGggPT0gMFwiIChjbGljayk9XCJhZGRBbGwoKVwiPnt7J0NPTU1PTl9BRERfQUxMJyB8IHRyYW5zbGF0ZSB8IGFzeW5jIH19ICh7eyBhdmFpbGFibGUubGVuZ3RoIH19KTwvc3lzdGVsYWItYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJzbGFiLXR3b2xpc3RidXR0b25kaXZcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gaWNvbi1hbmdsZS1yaWdodFwiIChjbGljayk9XCJhZGQoKVwiIHRpdGxlPVwie3snQ09NTU9OX0FERF9TRUxFQ1RFRCcgfCB0cmFuc2xhdGUgfCBhc3luYyB9fVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImN1cnJlbnRTZWxlY3Rpb25TdGF0dXMuYXZhaWxhYmxlLmxlbmd0aCA9PSAwXCI+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBpY29uLWFuZ2xlLWxlZnRcIiAoY2xpY2spPVwicmVtb3ZlKClcIiB0aXRsZT1cInt7J0NPTU1PTl9SRU1PVkVfU0VMRUNURUQnIHwgdHJhbnNsYXRlIHwgYXN5bmMgfX1cIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJjdXJyZW50U2VsZWN0aW9uU3RhdHVzLnZpc2libGUubGVuZ3RoID09IDBcIj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwic2xhYi10d29saXN0ZGl2XCI+XG4gICAgICAgIDxsYWJlbD57eydDT01NT05fRklFTERTX1RPX1NIT1cnIHwgdHJhbnNsYXRlIHwgYXN5bmMgfX0gKHt7IHZpc2libGUubGVuZ3RoIH19KTwvbGFiZWw+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFsobmdNb2RlbCldPVwic2Vjb25kTGlzdFNlYXJjaFwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInJpZ2h0LWxpc3RcIiBjbGFzcz1cInNsYWItdHdvbGlzdGJveCB0ZXh0LW5vd3JhcFwiPlxuICAgICAgICAgICAgPHN5c3RlbGFiLXR3by1saXN0LXNvcnRhYmxlLWxpc3QgY2xhc3M9XCJ3LTEwMFwiIFtjdXJyZW50U2VsZWN0aW9uU3RhdHVzXT1cImN1cnJlbnRTZWxlY3Rpb25TdGF0dXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhlbGVtZW50c0xpc3QpXT1cInZpc2libGVcIiBbc2Vjb25kTGlzdFNlYXJjaF09XCJzZWNvbmRMaXN0U2VhcmNoXCIgW2RyYWdBbmREcm9wRW5hYmxlZF09XCJkcmFnQW5kRHJvcEVuYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRiQ2xpY2spPVwibW92ZVNlbGVjdGVkSXRlbXNGcm9tVmlzaWJsZVRvQXZhaWxhYmxlKCRldmVudClcIj48L3N5c3RlbGFiLXR3by1saXN0LXNvcnRhYmxlLWxpc3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c3lzdGVsYWItYnV0dG9uIHR5cGU9XCJsaW5rXCIgaWQ9XCJzbGFiLXJlbW92ZS1hbGxcIiBbZGlzYWJsZWRdPVwidmlzaWJsZS5sZW5ndGggPT0gMFwiIChjbGljayk9XCJyZW1vdmVBbGwoKVwiPnt7J0NPTU1PTl9SRU1PVkVfQUxMJyB8IHRyYW5zbGF0ZSB8IGFzeW5jIH19ICh7eyB2aXNpYmxlLmxlbmd0aCB9fSk8L3N5c3RlbGFiLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19