UNPKG

@ux-aspects/ux-aspects

Version:

Open source user interface framework for building modern, responsive, mobile big data applications

155 lines 26.6 kB
import { Injectable } from '@angular/core'; import { BaseResizableTableService, ResizableTableType } from '../resizable-table-base.service'; import * as i0 from "@angular/core"; export class ResizableExpandingTableService extends BaseResizableTableService { constructor() { super(...arguments); /** Define the type of resizing we should use */ this.type = ResizableTableType.Expand; } /** Store the size of each column */ setColumns(columns) { // store the current columns this._columns = columns; // store the sizes this.columns = columns.map(column => (column.getNaturalWidth() / this.tableWidth) * 100); // ensure all the columns fit this._columns.forEach((column, idx) => { if (!column.disabled) { this.columns = this.setColumnWidth(idx, this.columns[idx], ColumnUnit.Percentage, this.columns); } }); // indicate we are now initialised if (this.isInitialised$.value === false) { this.isInitialised$.next(true); } } /** Set all resizable columns to the same width */ setUniformWidths() { // set any disabled columns to their specified width this.columns = this._columns.map(column => column.disabled ? (column.getNaturalWidth() / this.tableWidth) * 100 : 0); // check to see if we've reached 100% of the table width const totalWidth = this.columns.reduce((partial, columnWidth) => partial + columnWidth); if (totalWidth > 98) { // remove overflow this.columns = this.ensureNoOverflow(this.columns); } else { // get the list of resizable columns const resizableColumns = this._columns.toArray().filter(column => !column.disabled); // work out what we need to add to each column to make up the full width const newWidth = (98 - totalWidth) / resizableColumns.length; // set the non-disabled columns to the new width this.columns = this._columns.map((column, idx) => column.disabled ? this.columns[idx] : newWidth); } // do the resizing this._columns.forEach((column, idx) => { if (!column.disabled) { this.resizeColumn(idx, 0); } }); } ensureNoOverflow(columns) { // get the total width const total = columns.reduce((width, column) => width + column); // if we have no overflow then we don't need to do anything if (total <= 100) { return columns; } // if there is overflow identify which columns can be resized const variableColumns = this._columns.filter(column => !column.disabled && this.getColumnWidth(column.getCellIndex(), ColumnUnit.Pixel, columns) > column.minWidth); // if there are no columns that can be resized then stop here if (variableColumns.length === 0) { return columns; } // determine the total width of the variable columns const totalWidth = this._columns.reduce((width, column) => width + this.getColumnWidth(column.getCellIndex(), ColumnUnit.Pixel, columns), 0); // determine to the width of all the variable columns const variableColumnsWidth = variableColumns.reduce((width, column) => width + this.getColumnWidth(column.getCellIndex(), ColumnUnit.Pixel, columns), 0); // determine how much the columns are currently too large (ignoring fixed columns) const targetWidth = this.tableWidth - (totalWidth - variableColumnsWidth); // determine how much we need to reduce a column by const difference = variableColumnsWidth - targetWidth; // find the column with the largest size const target = variableColumns.reduce((widest, column) => { const columnWidth = this.getColumnWidth(column.getCellIndex(), ColumnUnit.Pixel, columns); const widestWidth = this.getColumnWidth(widest.getCellIndex(), ColumnUnit.Pixel, columns); return columnWidth > widestWidth ? column : widest; }); // perform the resize columns = this.setColumnWidth(target.getCellIndex(), this.getColumnWidth(target.getCellIndex(), ColumnUnit.Pixel, columns) - difference, ColumnUnit.Pixel, columns); // check if we are still over the limit (allow some variance for javascript double precision) if (columns.reduce((width, column) => width + column) > 100.01) { return this.ensureNoOverflow(columns); } return columns; } /** Allow setting the column size in any unit */ setColumnWidth(index, value, unit, columns = this.columns) { // create a new array so we keep the instance array immutable const sizes = [...columns]; switch (unit) { case ColumnUnit.Percentage: sizes[index] = value; break; case ColumnUnit.Pixel: sizes[index] = (value / this.tableWidth) * 100; break; } // update the instance variable return sizes; } /** Resize a column by a specific pixel amount */ resizeColumn(index, delta) { // get the sibling column that will also be resized const sibling = this.getSiblingColumn(index); // create a new array for the sizes let columns = [...this.columns]; // resize the column to the desired size columns = this.setColumnWidth(index, Math.round(this.getColumnWidth(index, ColumnUnit.Pixel) + delta), ColumnUnit.Pixel); columns = this.setColumnWidth(sibling, Math.round(this.getColumnWidth(sibling, ColumnUnit.Pixel)), ColumnUnit.Pixel, columns); // if the move is not possible then stop here if (!this.isWidthValid(index, this.getColumnWidth(index, ColumnUnit.Pixel, columns))) { return; } // store the new sizes this.columns = columns; // emit the resize event for each column this.onResize$.next(); } /** Get the next column in the sequence of columns */ getSiblingColumn(index) { // find the first sibling that is not disabled for (let idx = index + 1; idx < this.columns.length; idx++) { const sibling = this.getColumn(idx); if (!sibling || !sibling.disabled) { return idx; } } return null; } /** Return true if this column is above the minimum width */ isWidthValid(index, width) { // get the column at a given position const column = this.getColumn(index); // determine if the specified width is greater than the min width return column && width >= column.minWidth; } getColumn(index) { return this._columns ? this._columns.toArray()[index] : null; } getColumnDisabled(index) { return this.getColumn(index) ? this.getColumn(index).disabled : false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableExpandingTableService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableExpandingTableService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableExpandingTableService, decorators: [{ type: Injectable }] }); export var ColumnUnit; (function (ColumnUnit) { ColumnUnit[ColumnUnit["Pixel"] = 0] = "Pixel"; ColumnUnit[ColumnUnit["Percentage"] = 1] = "Percentage"; })(ColumnUnit || (ColumnUnit = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLWV4cGFuZGluZy10YWJsZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUtY29sdW1uLXJlc2l6ZS90YWJsZS1jb2x1bW4tcmVzaXplLWV4cGFuZGluZy9yZXNpemFibGUtZXhwYW5kaW5nLXRhYmxlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFJaEcsTUFBTSxPQUFPLDhCQUErQixTQUFRLHlCQUF5QjtJQUQ3RTs7UUFHSSxnREFBZ0Q7UUFDaEQsU0FBSSxHQUF1QixrQkFBa0IsQ0FBQyxNQUFNLENBQUM7S0E0THhEO0lBdkxHLG9DQUFvQztJQUNwQyxVQUFVLENBQUMsT0FBaUQ7UUFFeEQsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBRXhCLGtCQUFrQjtRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFekYsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxVQUFVLENBQUMsVUFBVSxF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SW5qZWN0YWJsZSwgUXVlcnlMaXN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCYXNlUmVzaXphYmxlVGFibGVTZXJ2aWNlLCBSZXNpemFibGVUYWJsZVR5cGUgfSBmcm9tICcuLi9yZXNpemFibGUtdGFibGUtYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IFJlc2l6YWJsZVRhYmxlQ29sdW1uQ29tcG9uZW50IH0gZnJvbSAnLi4vcmVzaXphYmxlLXRhYmxlLWNvbHVtbi5jb21wb25lbnQnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVzaXphYmxlRXhwYW5kaW5nVGFibGVTZXJ2aWNlIGV4dGVuZHMgQmFzZVJlc2l6YWJsZVRhYmxlU2VydmljZSB7XG5cbiAgICAvKiogRGVmaW5lIHRoZSB0eXBlIG9mIHJlc2l6aW5nIHdlIHNob3VsZCB1c2UgKi9cbiAgICB0eXBlOiBSZXNpemFibGVUYWJsZVR5cGUgPSBSZXNpemFibGVUYWJsZVR5cGUuRXhwYW5kO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBRdWVyeUxpc3Qgb2YgY29sdW1ucyAqL1xuICAgIHByaXZhdGUgX2NvbHVtbnM6IFF1ZXJ5TGlzdDxSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudD47XG5cbiAgICAvKiogU3RvcmUgdGhlIHNpemUgb2YgZWFjaCBjb2x1bW4gKi9cbiAgICBzZXRDb2x1bW5zKGNvbHVtbnM6IFF1ZXJ5TGlzdDxSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudD4pOiB2b2lkIHtcblxuICAgICAgICAvLyBzdG9yZSB0aGUgY3VycmVudCBjb2x1bW5zXG4gICAgICAgIHRoaXMuX2NvbHVtbnMgPSBjb2x1bW5zO1xuXG4gICAgICAgIC8vIHN0b3JlIHRoZSBzaXplc1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zLm1hcChjb2x1bW4gPT4gKGNvbHVtbi5nZXROYXR1cmFsV2lkdGgoKSAvIHRoaXMudGFibGVXaWR0aCkgKiAxMDApO1xuXG4gICAgICAgIC8vIGVuc3VyZSBhbGwgdGhlIGNvbHVtbnMgZml0XG4gICAgICAgIHRoaXMuX2NvbHVtbnMuZm9yRWFjaCgoY29sdW1uLCBpZHgpID0+IHtcbiAgICAgICAgICAgIGlmICghY29sdW1uLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5zID0gdGhpcy5zZXRDb2x1bW5XaWR0aChpZHgsIHRoaXMuY29sdW1uc1tpZHhdLCBDb2x1bW5Vbml0LlBlcmNlbnRhZ2UsIHRoaXMuY29sdW1ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGluZGljYXRlIHdlIGFyZSBub3cgaW5pdGlhbGlzZWRcbiAgICAgICAgaWYgKHRoaXMuaXNJbml0aWFsaXNlZCQudmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmlzSW5pdGlhbGlzZWQkLm5leHQodHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogU2V0IGFsbCByZXNpemFibGUgY29sdW1ucyB0byB0aGUgc2FtZSB3aWR0aCAqL1xuICAgIHNldFVuaWZvcm1XaWR0aHMoKTogdm9pZCB7XG5cbiAgICAgICAgLy8gc2V0IGFueSBkaXNhYmxlZCBjb2x1bW5zIHRvIHRoZWlyIHNwZWNpZmllZCB3aWR0aFxuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLl9jb2x1bW5zLm1hcChjb2x1bW4gPT4gY29sdW1uLmRpc2FibGVkID8gKGNvbHVtbi5nZXROYXR1cmFsV2lkdGgoKSAvIHRoaXMudGFibGVXaWR0aCkgKiAxMDAgOiAwKTtcblxuICAgICAgICAvLyBjaGVjayB0byBzZWUgaWYgd2UndmUgcmVhY2hlZCAxMDAlIG9mIHRoZSB0YWJsZSB3aWR0aFxuICAgICAgICBjb25zdCB0b3RhbFdpZHRoID0gdGhpcy5jb2x1bW5zLnJlZHVjZSgocGFydGlhbCwgY29sdW1uV2lkdGgpID0+IHBhcnRpYWwgKyBjb2x1bW5XaWR0aCk7XG5cbiAgICAgICAgaWYgKHRvdGFsV2lkdGggPiA5OCkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIG92ZXJmbG93XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmVuc3VyZU5vT3ZlcmZsb3codGhpcy5jb2x1bW5zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGdldCB0aGUgbGlzdCBvZiByZXNpemFibGUgY29sdW1uc1xuICAgICAgICAgICAgY29uc3QgcmVzaXphYmxlQ29sdW1ucyA9IHRoaXMuX2NvbHVtbnMudG9BcnJheSgpLmZpbHRlcihjb2x1bW4gPT4gIWNvbHVtbi5kaXNhYmxlZCk7XG5cbiAgICAgICAgICAgIC8vIHdvcmsgb3V0IHdoYXQgd2UgbmVlZCB0byBhZGQgdG8gZWFjaCBjb2x1bW4gdG8gbWFrZSB1cCB0aGUgZnVsbCB3aWR0aFxuICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSAoOTggLSB0b3RhbFdpZHRoKSAvIHJlc2l6YWJsZUNvbHVtbnMubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBzZXQgdGhlIG5vbi1kaXNhYmxlZCBjb2x1bW5zIHRvIHRoZSBuZXcgd2lkdGhcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuX2NvbHVtbnMubWFwKChjb2x1bW4sIGlkeCkgPT4gY29sdW1uLmRpc2FibGVkID8gdGhpcy5jb2x1bW5zW2lkeF0gOiBuZXdXaWR0aCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkbyB0aGUgcmVzaXppbmdcbiAgICAgICAgdGhpcy5fY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGlkeCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjb2x1bW4uZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUNvbHVtbihpZHgsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIGVuc3VyZU5vT3ZlcmZsb3coY29sdW1uczogUmVhZG9ubHlBcnJheTxudW1iZXI+KTogUmVhZG9ubHlBcnJheTxudW1iZXI+IHtcblxuICAgICAgICAvLyBnZXQgdGhlIHRvdGFsIHdpZHRoXG4gICAgICAgIGNvbnN0IHRvdGFsID0gY29sdW1ucy5yZWR1Y2UoKHdpZHRoLCBjb2x1bW4pID0+IHdpZHRoICsgY29sdW1uKTtcblxuICAgICAgICAvLyBpZiB3ZSBoYXZlIG5vIG92ZXJmbG93IHRoZW4gd2UgZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZ1xuICAgICAgICBpZiAodG90YWwgPD0gMTAwKSB7XG4gICAgICAgICAgICByZXR1cm4gY29sdW1ucztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG92ZXJmbG93IGlkZW50aWZ5IHdoaWNoIGNvbHVtbnMgY2FuIGJlIHJlc2l6ZWRcbiAgICAgICAgY29uc3QgdmFyaWFibGVDb2x1bW5zID0gdGhpcy5fY29sdW1ucy5maWx0ZXIoY29sdW1uID0+ICFjb2x1bW4uZGlzYWJsZWQgJiYgdGhpcy5nZXRDb2x1bW5XaWR0aChjb2x1bW4uZ2V0Q2VsbEluZGV4KCksIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpID4gY29sdW1uLm1pbldpZHRoKTtcblxuICAgICAgICAvLyBpZiB0aGVyZSBhcmUgbm8gY29sdW1ucyB0aGF0IGNhbiBiZSByZXNpemVkIHRoZW4gc3RvcCBoZXJlXG4gICAgICAgIGlmICh2YXJpYWJsZUNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gY29sdW1ucztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRldGVybWluZSB0aGUgdG90YWwgd2lkdGggb2YgdGhlIHZhcmlhYmxlIGNvbHVtbnNcbiAgICAgICAgY29uc3QgdG90YWxXaWR0aCA9IHRoaXMuX2NvbHVtbnMucmVkdWNlKCh3aWR0aCwgY29sdW1uKSA9PiB3aWR0aCArIHRoaXMuZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKSwgMCk7XG5cbiAgICAgICAgLy8gZGV0ZXJtaW5lIHRvIHRoZSB3aWR0aCBvZiBhbGwgdGhlIHZhcmlhYmxlIGNvbHVtbnNcbiAgICAgICAgY29uc3QgdmFyaWFibGVDb2x1bW5zV2lkdGggPSB2YXJpYWJsZUNvbHVtbnMucmVkdWNlKCh3aWR0aCwgY29sdW1uKSA9PiB3aWR0aCArIHRoaXMuZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKSwgMCk7XG5cbiAgICAgICAgLy8gZGV0ZXJtaW5lIGhvdyBtdWNoIHRoZSBjb2x1bW5zIGFyZSBjdXJyZW50bHkgdG9vIGxhcmdlIChpZ25vcmluZyBmaXhlZCBjb2x1bW5zKVxuICAgICAgICBjb25zdCB0YXJnZXRXaWR0aCA9IHRoaXMudGFibGVXaWR0aCAtICh0b3RhbFdpZHRoIC0gdmFyaWFibGVDb2x1bW5zV2lkdGgpO1xuXG4gICAgICAgIC8vIGRldGVybWluZSBob3cgbXVjaCB3ZSBuZWVkIHRvIHJlZHVjZSBhIGNvbHVtbiBieVxuICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gdmFyaWFibGVDb2x1bW5zV2lkdGggLSB0YXJnZXRXaWR0aDtcblxuICAgICAgICAvLyBmaW5kIHRoZSBjb2x1bW4gd2l0aCB0aGUgbGFyZ2VzdCBzaXplXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHZhcmlhYmxlQ29sdW1ucy5yZWR1Y2UoKHdpZGVzdCwgY29sdW1uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb2x1bW5XaWR0aCA9IHRoaXMuZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKTtcbiAgICAgICAgICAgIGNvbnN0IHdpZGVzdFdpZHRoID0gdGhpcy5nZXRDb2x1bW5XaWR0aCh3aWRlc3QuZ2V0Q2VsbEluZGV4KCksIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpO1xuXG4gICAgICAgICAgICByZXR1cm4gY29sdW1uV2lkdGggPiB3aWRlc3RXaWR0aCA/IGNvbHVtbiA6IHdpZGVzdDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcGVyZm9ybSB0aGUgcmVzaXplXG4gICAgICAgIGNvbHVtbnMgPSB0aGlzLnNldENvbHVtbldpZHRoKHRhcmdldC5nZXRDZWxsSW5kZXgoKSwgdGhpcy5nZXRDb2x1bW5XaWR0aCh0YXJnZXQuZ2V0Q2VsbEluZGV4KCksIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpIC0gZGlmZmVyZW5jZSwgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucyk7XG5cbiAgICAgICAgLy8gY2hlY2sgaWYgd2UgYXJlIHN0aWxsIG92ZXIgdGhlIGxpbWl0IChhbGxvdyBzb21lIHZhcmlhbmNlIGZvciBqYXZhc2NyaXB0IGRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgIGlmIChjb2x1bW5zLnJlZHVjZSgod2lkdGgsIGNvbHVtbikgPT4gd2lkdGggKyBjb2x1bW4pID4gMTAwLjAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbnN1cmVOb092ZXJmbG93KGNvbHVtbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbHVtbnM7XG4gICAgfVxuXG5cbiAgICAvKiogQWxsb3cgc2V0dGluZyB0aGUgY29sdW1uIHNpemUgaW4gYW55IHVuaXQgKi9cbiAgICBzZXRDb2x1bW5XaWR0aChpbmRleDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyLCB1bml0OiBDb2x1bW5Vbml0LCBjb2x1bW5zOiBSZWFkb25seUFycmF5PG51bWJlcj4gPSB0aGlzLmNvbHVtbnMpOiBSZWFkb25seUFycmF5PG51bWJlcj4ge1xuICAgICAgICAvLyBjcmVhdGUgYSBuZXcgYXJyYXkgc28gd2Uga2VlcCB0aGUgaW5zdGFuY2UgYXJyYXkgaW1tdXRhYmxlXG4gICAgICAgIGNvbnN0IHNpemVzID0gWy4uLmNvbHVtbnNdO1xuXG4gICAgICAgIHN3aXRjaCAodW5pdCkge1xuXG4gICAgICAgICAgICBjYXNlIENvbHVtblVuaXQuUGVyY2VudGFnZTpcbiAgICAgICAgICAgICAgICBzaXplc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSBDb2x1bW5Vbml0LlBpeGVsOlxuICAgICAgICAgICAgICAgIHNpemVzW2luZGV4XSA9ICh2YWx1ZSAvIHRoaXMudGFibGVXaWR0aCkgKiAxMDA7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgdGhlIGluc3RhbmNlIHZhcmlhYmxlXG4gICAgICAgIHJldHVybiBzaXplcztcbiAgICB9XG5cbiAgICAvKiogUmVzaXplIGEgY29sdW1uIGJ5IGEgc3BlY2lmaWMgcGl4ZWwgYW1vdW50ICovXG4gICAgcmVzaXplQ29sdW1uKGluZGV4OiBudW1iZXIsIGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcblxuICAgICAgICAvLyBnZXQgdGhlIHNpYmxpbmcgY29sdW1uIHRoYXQgd2lsbCBhbHNvIGJlIHJlc2l6ZWRcbiAgICAgICAgY29uc3Qgc2libGluZyA9IHRoaXMuZ2V0U2libGluZ0NvbHVtbihpbmRleCk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IGFycmF5IGZvciB0aGUgc2l6ZXNcbiAgICAgICAgbGV0IGNvbHVtbnMgPSBbLi4udGhpcy5jb2x1bW5zXSBhcyBudW1iZXJbXTtcblxuICAgICAgICAvLyByZXNpemUgdGhlIGNvbHVtbiB0byB0aGUgZGVzaXJlZCBzaXplXG4gICAgICAgIGNvbHVtbnMgPSB0aGlzLnNldENvbHVtbldpZHRoKGluZGV4LCBNYXRoLnJvdW5kKHRoaXMuZ2V0Q29sdW1uV2lkdGgoaW5kZXgsIENvbHVtblVuaXQuUGl4ZWwpICsgZGVsdGEpLCBDb2x1bW5Vbml0LlBpeGVsKSBhcyBudW1iZXJbXTtcbiAgICAgICAgY29sdW1ucyA9IHRoaXMuc2V0Q29sdW1uV2lkdGgoc2libGluZywgTWF0aC5yb3VuZCh0aGlzLmdldENvbHVtbldpZHRoKHNpYmxpbmcsIENvbHVtblVuaXQuUGl4ZWwpKSwgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucykgYXMgbnVtYmVyW107XG5cbiAgICAgICAgLy8gaWYgdGhlIG1vdmUgaXMgbm90IHBvc3NpYmxlIHRoZW4gc3RvcCBoZXJlXG4gICAgICAgIGlmICghdGhpcy5pc1dpZHRoVmFsaWQoaW5kZXgsIHRoaXMuZ2V0Q29sdW1uV2lkdGgoaW5kZXgsIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RvcmUgdGhlIG5ldyBzaXplc1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zO1xuXG4gICAgICAgIC8vIGVtaXQgdGhlIHJlc2l6ZSBldmVudCBmb3IgZWFjaCBjb2x1bW5cbiAgICAgICAgdGhpcy5vblJlc2l6ZSQubmV4dCgpO1xuICAgIH1cblxuICAgIC8qKiBHZXQgdGhlIG5leHQgY29sdW1uIGluIHRoZSBzZXF1ZW5jZSBvZiBjb2x1bW5zICovXG4gICAgcHJpdmF0ZSBnZXRTaWJsaW5nQ29sdW1uKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcblxuICAgICAgICAvLyBmaW5kIHRoZSBmaXJzdCBzaWJsaW5nIHRoYXQgaXMgbm90IGRpc2FibGVkXG4gICAgICAgIGZvciAobGV0IGlkeCA9IGluZGV4ICsgMTsgaWR4IDwgdGhpcy5jb2x1bW5zLmxlbmd0aDsgaWR4KyspIHtcblxuICAgICAgICAgICAgY29uc3Qgc2libGluZyA9IHRoaXMuZ2V0Q29sdW1uKGlkeCk7XG5cbiAgICAgICAgICAgIGlmICghc2libGluZyB8fCAhc2libGluZy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpZHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogUmV0dXJuIHRydWUgaWYgdGhpcyBjb2x1bW4gaXMgYWJvdmUgdGhlIG1pbmltdW0gd2lkdGggKi9cbiAgICBwcml2YXRlIGlzV2lkdGhWYWxpZChpbmRleDogbnVtYmVyLCB3aWR0aDogbnVtYmVyKTogYm9vbGVhbiB7XG5cbiAgICAgICAgLy8gZ2V0IHRoZSBjb2x1bW4gYXQgYSBnaXZlbiBwb3NpdGlvblxuICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmdldENvbHVtbihpbmRleCk7XG5cbiAgICAgICAgLy8gZGV0ZXJtaW5lIGlmIHRoZSBzcGVjaWZpZWQgd2lkdGggaXMgZ3JlYXRlciB0aGFuIHRoZSBtaW4gd2lkdGhcbiAgICAgICAgcmV0dXJuIGNvbHVtbiAmJiB3aWR0aCA+PSBjb2x1bW4ubWluV2lkdGg7XG4gICAgfVxuXG4gICAgZ2V0Q29sdW1uKGluZGV4OiBudW1iZXIpOiBSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29sdW1ucyA/IHRoaXMuX2NvbHVtbnMudG9BcnJheSgpW2luZGV4XSA6IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0Q29sdW1uRGlzYWJsZWQoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb2x1bW4oaW5kZXgpID8gdGhpcy5nZXRDb2x1bW4oaW5kZXgpLmRpc2FibGVkIDogZmFsc2U7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBlbnVtIENvbHVtblVuaXQge1xuICAgIFBpeGVsLFxuICAgIFBlcmNlbnRhZ2Vcbn1cbiJdfQ==