UNPKG

@ux-aspects/ux-aspects

Version:

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

184 lines 31.8 kB
import { Injectable } from '@angular/core'; import { BaseResizableTableService, ResizableTableType } from '../resizable-table-base.service'; import * as i0 from "@angular/core"; export class ResizableTableService extends BaseResizableTableService { constructor() { super(...arguments); /** Define the type of resizing we should use */ this.type = ResizableTableType.Standard; } /** 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); // check if there is any overflow this.columns = this.ensureNoOverflow(this.columns); // ensure all the columns fit this._columns.forEach((column, idx) => { if (!column.disabled) { this.resizeColumn(idx, 0, false); } }); // 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 > 100) { // 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 = (100 - 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, false); } }); } 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, isDragging = true) { // get the sibling column that will also be resized const sibling = this.getSiblingColumn(index); // if there is no sibling that can be resized then stop here if (!sibling) { return; } // 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); columns = this.setColumnWidth(sibling, Math.round(this.getColumnWidth(sibling, ColumnUnit.Pixel) - delta), ColumnUnit.Pixel, columns); // if the move is not possible then stop here if (!this.isWidthValid(index, this.getColumnWidth(index, ColumnUnit.Pixel, columns)) || !this.isWidthValid(sibling, this.getColumnWidth(sibling, ColumnUnit.Pixel, columns))) { return; } // check that we add up to exactly 100% const total = columns.reduce((count, column) => column + count, 0); // if the columns to not add to 100 ensure we make them if (total !== 100) { // get the column with a variable width const target = this.getVariableColumn(100 - total); if (target && !isDragging) { columns[this._columns.toArray().indexOf(target)] += (100 - total); } else { columns[index] += (100 - total); } } // store the new sizes this.columns = columns; // emit the resize event for each column this.onResize$.next(); } getVariableColumn(delta) { // get all variable width columns that are not disabled const variableColumns = this._columns.filter(column => !column.isFixedWidth && !column.disabled); // find one that is greater than its min width by enough return variableColumns.reverse().find(column => this.getColumnWidth(column.getCellIndex(), ColumnUnit.Pixel) >= column.minWidth + delta); } getColumn(index) { return this._columns ? this._columns.toArray()[index] : null; } getColumnDisabled(index) { return this.getColumn(index) ? this.getColumn(index).disabled : false; } /** Determine whether a column is above or below its minimum width */ isWidthValid(index, width) { // get the column at a given position const column = this.getColumnInstance(index); // determine if the specified width is greater than the min width return column && width >= column.minWidth; } /** 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.getColumnInstance(idx); if (!sibling || !sibling.disabled) { return idx; } } return null; } /** Get the column class from our query list */ getColumnInstance(index) { return this._columns ? this._columns.toArray()[index] : null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableTableService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableTableService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ResizableTableService, 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLXRhYmxlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy90YWJsZS90YWJsZS1jb2x1bW4tcmVzaXplL3RhYmxlLWNvbHVtbi1yZXNpemUtc3RhbmRhcmQvcmVzaXphYmxlLXRhYmxlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUV0RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFHaEcsTUFBTSxPQUFPLHFCQUFzQixTQUFRLHlCQUF5QjtJQURwRTs7UUFHSSxnREFBZ0Q7UUFDaEQsU0FBSSxHQUF1QixrQkFBa0IsQ0FBQyxRQUFRLENBQUM7S0FrTzFEO0lBN05HLG9DQUFvQztJQUNwQyxVQUFVLENBQUMsT0FBaUQ7UUFFeEQsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBRXhCLGtCQUFrQjtRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFekYsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVuRCw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxF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QWlCLENBQUMsS0FBYTtRQUNuQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNqRSxDQUFDOytHQW5PUSxxQkFBcUI7bUhBQXJCLHFCQUFxQjs7NEZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVTs7QUF3T1gsTUFBTSxDQUFOLElBQVksVUFHWDtBQUhELFdBQVksVUFBVTtJQUNsQiw2Q0FBSyxDQUFBO0lBQ0wsdURBQVUsQ0FBQTtBQUNkLENBQUMsRUFIVyxVQUFVLEtBQVYsVUFBVSxRQUdyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIFF1ZXJ5TGlzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVzaXphYmxlVGFibGVDb2x1bW5Db21wb25lbnQgfSBmcm9tICcuLi9yZXNpemFibGUtdGFibGUtY29sdW1uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCYXNlUmVzaXphYmxlVGFibGVTZXJ2aWNlLCBSZXNpemFibGVUYWJsZVR5cGUgfSBmcm9tICcuLi9yZXNpemFibGUtdGFibGUtYmFzZS5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlc2l6YWJsZVRhYmxlU2VydmljZSBleHRlbmRzIEJhc2VSZXNpemFibGVUYWJsZVNlcnZpY2Uge1xuXG4gICAgLyoqIERlZmluZSB0aGUgdHlwZSBvZiByZXNpemluZyB3ZSBzaG91bGQgdXNlICovXG4gICAgdHlwZTogUmVzaXphYmxlVGFibGVUeXBlID0gUmVzaXphYmxlVGFibGVUeXBlLlN0YW5kYXJkO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBRdWVyeUxpc3Qgb2YgY29sdW1ucyAqL1xuICAgIHByaXZhdGUgX2NvbHVtbnM6IFF1ZXJ5TGlzdDxSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudD47XG5cbiAgICAvKiogU3RvcmUgdGhlIHNpemUgb2YgZWFjaCBjb2x1bW4gKi9cbiAgICBzZXRDb2x1bW5zKGNvbHVtbnM6IFF1ZXJ5TGlzdDxSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudD4pOiB2b2lkIHtcblxuICAgICAgICAvLyBzdG9yZSB0aGUgY3VycmVudCBjb2x1bW5zXG4gICAgICAgIHRoaXMuX2NvbHVtbnMgPSBjb2x1bW5zO1xuXG4gICAgICAgIC8vIHN0b3JlIHRoZSBzaXplc1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zLm1hcChjb2x1bW4gPT4gKGNvbHVtbi5nZXROYXR1cmFsV2lkdGgoKSAvIHRoaXMudGFibGVXaWR0aCkgKiAxMDApO1xuXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZXJlIGlzIGFueSBvdmVyZmxvd1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmVuc3VyZU5vT3ZlcmZsb3codGhpcy5jb2x1bW5zKTtcblxuICAgICAgICAvLyBlbnN1cmUgYWxsIHRoZSBjb2x1bW5zIGZpdFxuICAgICAgICB0aGlzLl9jb2x1bW5zLmZvckVhY2goKGNvbHVtbiwgaWR4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNvbHVtbi5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplQ29sdW1uKGlkeCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBpbmRpY2F0ZSB3ZSBhcmUgbm93IGluaXRpYWxpc2VkXG4gICAgICAgIGlmICh0aGlzLmlzSW5pdGlhbGlzZWQkLnZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5pc0luaXRpYWxpc2VkJC5uZXh0KHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFNldCBhbGwgcmVzaXphYmxlIGNvbHVtbnMgdG8gdGhlIHNhbWUgd2lkdGggKi9cbiAgICBzZXRVbmlmb3JtV2lkdGhzKCk6IHZvaWQge1xuXG4gICAgICAgIC8vIHNldCBhbnkgZGlzYWJsZWQgY29sdW1ucyB0byB0aGVpciBzcGVjaWZpZWQgd2lkdGhcbiAgICAgICAgdGhpcy5jb2x1bW5zID0gdGhpcy5fY29sdW1ucy5tYXAoY29sdW1uID0+IGNvbHVtbi5kaXNhYmxlZCA/IChjb2x1bW4uZ2V0TmF0dXJhbFdpZHRoKCkgLyB0aGlzLnRhYmxlV2lkdGgpICogMTAwIDogMCk7XG5cbiAgICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIHdlJ3ZlIHJlYWNoZWQgMTAwJSBvZiB0aGUgdGFibGUgd2lkdGhcbiAgICAgICAgY29uc3QgdG90YWxXaWR0aCA9IHRoaXMuY29sdW1ucy5yZWR1Y2UoKHBhcnRpYWwsIGNvbHVtbldpZHRoKSA9PiBwYXJ0aWFsICsgY29sdW1uV2lkdGgpO1xuXG4gICAgICAgIGlmICh0b3RhbFdpZHRoID4gMTAwKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgb3ZlcmZsb3dcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuZW5zdXJlTm9PdmVyZmxvdyh0aGlzLmNvbHVtbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBsaXN0IG9mIHJlc2l6YWJsZSBjb2x1bW5zXG4gICAgICAgICAgICBjb25zdCByZXNpemFibGVDb2x1bW5zID0gdGhpcy5fY29sdW1ucy50b0FycmF5KCkuZmlsdGVyKGNvbHVtbiA9PiAhY29sdW1uLmRpc2FibGVkKTtcblxuICAgICAgICAgICAgLy8gd29yayBvdXQgd2hhdCB3ZSBuZWVkIHRvIGFkZCB0byBlYWNoIGNvbHVtbiB0byBtYWtlIHVwIHRoZSBmdWxsIHdpZHRoXG4gICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9ICgxMDAgLSB0b3RhbFdpZHRoKSAvIHJlc2l6YWJsZUNvbHVtbnMubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBzZXQgdGhlIG5vbi1kaXNhYmxlZCBjb2x1bW5zIHRvIHRoZSBuZXcgd2lkdGhcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuX2NvbHVtbnMubWFwKChjb2x1bW4sIGlkeCkgPT4gY29sdW1uLmRpc2FibGVkID8gdGhpcy5jb2x1bW5zW2lkeF0gOiBuZXdXaWR0aCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkbyB0aGUgcmVzaXppbmdcbiAgICAgICAgdGhpcy5fY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGlkeCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjb2x1bW4uZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUNvbHVtbihpZHgsIDAsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBlbnN1cmVOb092ZXJmbG93KGNvbHVtbnM6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPik6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPiB7XG5cbiAgICAgICAgLy8gZ2V0IHRoZSB0b3RhbCB3aWR0aFxuICAgICAgICBjb25zdCB0b3RhbCA9IGNvbHVtbnMucmVkdWNlKCh3aWR0aCwgY29sdW1uKSA9PiB3aWR0aCArIGNvbHVtbik7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBubyBvdmVyZmxvdyB0aGVuIHdlIGRvbid0IG5lZWQgdG8gZG8gYW55dGhpbmdcbiAgICAgICAgaWYgKHRvdGFsIDw9IDEwMCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbnM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGVyZSBpcyBvdmVyZmxvdyBpZGVudGlmeSB3aGljaCBjb2x1bW5zIGNhbiBiZSByZXNpemVkXG4gICAgICAgIGNvbnN0IHZhcmlhYmxlQ29sdW1ucyA9IHRoaXMuX2NvbHVtbnMuZmlsdGVyKGNvbHVtbiA9PiAhY29sdW1uLmRpc2FibGVkICYmIHRoaXMuZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKSA+IGNvbHVtbi5taW5XaWR0aCk7XG5cbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIG5vIGNvbHVtbnMgdGhhdCBjYW4gYmUgcmVzaXplZCB0aGVuIHN0b3AgaGVyZVxuICAgICAgICBpZiAodmFyaWFibGVDb2x1bW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbnM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkZXRlcm1pbmUgdGhlIHRvdGFsIHdpZHRoIG9mIHRoZSB2YXJpYWJsZSBjb2x1bW5zXG4gICAgICAgIGNvbnN0IHRvdGFsV2lkdGggPSB0aGlzLl9jb2x1bW5zLnJlZHVjZSgod2lkdGgsIGNvbHVtbikgPT4gd2lkdGggKyB0aGlzLmdldENvbHVtbldpZHRoKGNvbHVtbi5nZXRDZWxsSW5kZXgoKSwgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucyksIDApO1xuXG4gICAgICAgIC8vIGRldGVybWluZSB0byB0aGUgd2lkdGggb2YgYWxsIHRoZSB2YXJpYWJsZSBjb2x1bW5zXG4gICAgICAgIGNvbnN0IHZhcmlhYmxlQ29sdW1uc1dpZHRoID0gdmFyaWFibGVDb2x1bW5zLnJlZHVjZSgod2lkdGgsIGNvbHVtbikgPT4gd2lkdGggKyB0aGlzLmdldENvbHVtbldpZHRoKGNvbHVtbi5nZXRDZWxsSW5kZXgoKSwgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucyksIDApO1xuXG4gICAgICAgIC8vIGRldGVybWluZSBob3cgbXVjaCB0aGUgY29sdW1ucyBhcmUgY3VycmVudGx5IHRvbyBsYXJnZSAoaWdub3JpbmcgZml4ZWQgY29sdW1ucylcbiAgICAgICAgY29uc3QgdGFyZ2V0V2lkdGggPSB0aGlzLnRhYmxlV2lkdGggLSAodG90YWxXaWR0aCAtIHZhcmlhYmxlQ29sdW1uc1dpZHRoKTtcblxuICAgICAgICAvLyBkZXRlcm1pbmUgaG93IG11Y2ggd2UgbmVlZCB0byByZWR1Y2UgYSBjb2x1bW4gYnlcbiAgICAgICAgY29uc3QgZGlmZmVyZW5jZSA9IHZhcmlhYmxlQ29sdW1uc1dpZHRoIC0gdGFyZ2V0V2lkdGg7XG5cbiAgICAgICAgLy8gZmluZCB0aGUgY29sdW1uIHdpdGggdGhlIGxhcmdlc3Qgc2l6ZVxuICAgICAgICBjb25zdCB0YXJnZXQgPSB2YXJpYWJsZUNvbHVtbnMucmVkdWNlKCh3aWRlc3QsIGNvbHVtbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29sdW1uV2lkdGggPSB0aGlzLmdldENvbHVtbldpZHRoKGNvbHVtbi5nZXRDZWxsSW5kZXgoKSwgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucyk7XG4gICAgICAgICAgICBjb25zdCB3aWRlc3RXaWR0aCA9IHRoaXMuZ2V0Q29sdW1uV2lkdGgod2lkZXN0LmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKTtcblxuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbldpZHRoID4gd2lkZXN0V2lkdGggPyBjb2x1bW4gOiB3aWRlc3Q7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHBlcmZvcm0gdGhlIHJlc2l6ZVxuICAgICAgICBjb2x1bW5zID0gdGhpcy5zZXRDb2x1bW5XaWR0aCh0YXJnZXQuZ2V0Q2VsbEluZGV4KCksIHRoaXMuZ2V0Q29sdW1uV2lkdGgodGFyZ2V0LmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKSAtIGRpZmZlcmVuY2UsIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpO1xuXG4gICAgICAgIC8vIGNoZWNrIGlmIHdlIGFyZSBzdGlsbCBvdmVyIHRoZSBsaW1pdCAoYWxsb3cgc29tZSB2YXJpYW5jZSBmb3IgamF2YXNjcmlwdCBkb3VibGUgcHJlY2lzaW9uKVxuICAgICAgICBpZiAoY29sdW1ucy5yZWR1Y2UoKHdpZHRoLCBjb2x1bW4pID0+IHdpZHRoICsgY29sdW1uKSA+IDEwMC4wMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5zdXJlTm9PdmVyZmxvdyhjb2x1bW5zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb2x1bW5zO1xuICAgIH1cblxuICAgIC8qKiBBbGxvdyBzZXR0aW5nIHRoZSBjb2x1bW4gc2l6ZSBpbiBhbnkgdW5pdCAqL1xuICAgIHNldENvbHVtbldpZHRoKGluZGV4OiBudW1iZXIsIHZhbHVlOiBudW1iZXIsIHVuaXQ6IENvbHVtblVuaXQsIGNvbHVtbnM6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPiA9IHRoaXMuY29sdW1ucyk6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPiB7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IGFycmF5IHNvIHdlIGtlZXAgdGhlIGluc3RhbmNlIGFycmF5IGltbXV0YWJsZVxuICAgICAgICBjb25zdCBzaXplcyA9IFsuLi5jb2x1bW5zXTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXQpIHtcblxuICAgICAgICAgICAgY2FzZSBDb2x1bW5Vbml0LlBlcmNlbnRhZ2U6XG4gICAgICAgICAgICAgICAgc2l6ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgQ29sdW1uVW5pdC5QaXhlbDpcbiAgICAgICAgICAgICAgICBzaXplc1tpbmRleF0gPSAodmFsdWUgLyB0aGlzLnRhYmxlV2lkdGgpICogMTAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdXBkYXRlIHRoZSBpbnN0YW5jZSB2YXJpYWJsZVxuICAgICAgICByZXR1cm4gc2l6ZXM7XG4gICAgfVxuXG4gICAgLyoqIFJlc2l6ZSBhIGNvbHVtbiBieSBhIHNwZWNpZmljIHBpeGVsIGFtb3VudCAqL1xuICAgIHJlc2l6ZUNvbHVtbihpbmRleDogbnVtYmVyLCBkZWx0YTogbnVtYmVyLCBpc0RyYWdnaW5nOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuXG4gICAgICAgIC8vIGdldCB0aGUgc2libGluZyBjb2x1bW4gdGhhdCB3aWxsIGFsc28gYmUgcmVzaXplZFxuICAgICAgICBjb25zdCBzaWJsaW5nID0gdGhpcy5nZXRTaWJsaW5nQ29sdW1uKGluZGV4KTtcblxuICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBzaWJsaW5nIHRoYXQgY2FuIGJlIHJlc2l6ZWQgdGhlbiBzdG9wIGhlcmVcbiAgICAgICAgaWYgKCFzaWJsaW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjcmVhdGUgYSBuZXcgYXJyYXkgZm9yIHRoZSBzaXplc1xuICAgICAgICBsZXQgY29sdW1ucyA9IFsuLi50aGlzLmNvbHVtbnNdIGFzIG51bWJlcltdO1xuXG4gICAgICAgIC8vIHJlc2l6ZSB0aGUgY29sdW1uIHRvIHRoZSBkZXNpcmVkIHNpemVcbiAgICAgICAgY29sdW1ucyA9IHRoaXMuc2V0Q29sdW1uV2lkdGgoaW5kZXgsIE1hdGgucm91bmQodGhpcy5nZXRDb2x1bW5XaWR0aChpbmRleCwgQ29sdW1uVW5pdC5QaXhlbCkgKyBkZWx0YSksIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpIGFzIG51bWJlcltdO1xuICAgICAgICBjb2x1bW5zID0gdGhpcy5zZXRDb2x1bW5XaWR0aChzaWJsaW5nLCBNYXRoLnJvdW5kKHRoaXMuZ2V0Q29sdW1uV2lkdGgoc2libGluZywgQ29sdW1uVW5pdC5QaXhlbCkgLSBkZWx0YSksIENvbHVtblVuaXQuUGl4ZWwsIGNvbHVtbnMpIGFzIG51bWJlcltdO1xuXG4gICAgICAgIC8vIGlmIHRoZSBtb3ZlIGlzIG5vdCBwb3NzaWJsZSB0aGVuIHN0b3AgaGVyZVxuICAgICAgICBpZiAoIXRoaXMuaXNXaWR0aFZhbGlkKGluZGV4LCB0aGlzLmdldENvbHVtbldpZHRoKGluZGV4LCBDb2x1bW5Vbml0LlBpeGVsLCBjb2x1bW5zKSkgfHwgIXRoaXMuaXNXaWR0aFZhbGlkKHNpYmxpbmcsIHRoaXMuZ2V0Q29sdW1uV2lkdGgoc2libGluZywgQ29sdW1uVW5pdC5QaXhlbCwgY29sdW1ucykpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGVjayB0aGF0IHdlIGFkZCB1cCB0byBleGFjdGx5IDEwMCVcbiAgICAgICAgY29uc3QgdG90YWwgPSBjb2x1bW5zLnJlZHVjZSgoY291bnQsIGNvbHVtbikgPT4gY29sdW1uICsgY291bnQsIDApO1xuXG4gICAgICAgIC8vIGlmIHRoZSBjb2x1bW5zIHRvIG5vdCBhZGQgdG8gMTAwIGVuc3VyZSB3ZSBtYWtlIHRoZW1cbiAgICAgICAgaWYgKHRvdGFsICE9PSAxMDApIHtcblxuICAgICAgICAgICAgLy8gZ2V0IHRoZSBjb2x1bW4gd2l0aCBhIHZhcmlhYmxlIHdpZHRoXG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmdldFZhcmlhYmxlQ29sdW1uKDEwMCAtIHRvdGFsKTtcblxuICAgICAgICAgICAgaWYgKHRhcmdldCAmJiAhaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIGNvbHVtbnNbdGhpcy5fY29sdW1ucy50b0FycmF5KCkuaW5kZXhPZih0YXJnZXQpXSArPSAoMTAwIC0gdG90YWwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb2x1bW5zW2luZGV4XSArPSAoMTAwIC0gdG90YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RvcmUgdGhlIG5ldyBzaXplc1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zO1xuXG4gICAgICAgIC8vIGVtaXQgdGhlIHJlc2l6ZSBldmVudCBmb3IgZWFjaCBjb2x1bW5cbiAgICAgICAgdGhpcy5vblJlc2l6ZSQubmV4dCgpO1xuICAgIH1cblxuICAgIGdldFZhcmlhYmxlQ29sdW1uKGRlbHRhOiBudW1iZXIpOiBSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudCB8IG51bGwge1xuXG4gICAgICAgIC8vIGdldCBhbGwgdmFyaWFibGUgd2lkdGggY29sdW1ucyB0aGF0IGFyZSBub3QgZGlzYWJsZWRcbiAgICAgICAgY29uc3QgdmFyaWFibGVDb2x1bW5zID0gdGhpcy5fY29sdW1ucy5maWx0ZXIoY29sdW1uID0+ICFjb2x1bW4uaXNGaXhlZFdpZHRoICYmICFjb2x1bW4uZGlzYWJsZWQpO1xuXG4gICAgICAgIC8vIGZpbmQgb25lIHRoYXQgaXMgZ3JlYXRlciB0aGFuIGl0cyBtaW4gd2lkdGggYnkgZW5vdWdoXG4gICAgICAgIHJldHVybiB2YXJpYWJsZUNvbHVtbnMucmV2ZXJzZSgpLmZpbmQoY29sdW1uID0+IHRoaXMuZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmdldENlbGxJbmRleCgpLCBDb2x1bW5Vbml0LlBpeGVsKSA+PSBjb2x1bW4ubWluV2lkdGggKyBkZWx0YSk7XG4gICAgfVxuXG4gICAgZ2V0Q29sdW1uKGluZGV4OiBudW1iZXIpOiBSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29sdW1ucyA/IHRoaXMuX2NvbHVtbnMudG9BcnJheSgpW2luZGV4XSA6IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0Q29sdW1uRGlzYWJsZWQoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb2x1bW4oaW5kZXgpID8gdGhpcy5nZXRDb2x1bW4oaW5kZXgpLmRpc2FibGVkIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSB3aGV0aGVyIGEgY29sdW1uIGlzIGFib3ZlIG9yIGJlbG93IGl0cyBtaW5pbXVtIHdpZHRoICovXG4gICAgcHJpdmF0ZSBpc1dpZHRoVmFsaWQoaW5kZXg6IG51bWJlciwgd2lkdGg6IG51bWJlcik6IGJvb2xlYW4ge1xuXG4gICAgICAgIC8vIGdldCB0aGUgY29sdW1uIGF0IGEgZ2l2ZW4gcG9zaXRpb25cbiAgICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5nZXRDb2x1bW5JbnN0YW5jZShpbmRleCk7XG5cbiAgICAgICAgLy8gZGV0ZXJtaW5lIGlmIHRoZSBzcGVjaWZpZWQgd2lkdGggaXMgZ3JlYXRlciB0aGFuIHRoZSBtaW4gd2lkdGhcbiAgICAgICAgcmV0dXJuIGNvbHVtbiAmJiB3aWR0aCA+PSBjb2x1bW4ubWluV2lkdGg7XG4gICAgfVxuXG4gICAgLyoqIEdldCB0aGUgbmV4dCBjb2x1bW4gaW4gdGhlIHNlcXVlbmNlIG9mIGNvbHVtbnMgKi9cbiAgICBwcml2YXRlIGdldFNpYmxpbmdDb2x1bW4oaW5kZXg6IG51bWJlcik6IG51bWJlciB8IG51bGwge1xuXG4gICAgICAgIC8vIGZpbmQgdGhlIGZpcnN0IHNpYmxpbmcgdGhhdCBpcyBub3QgZGlzYWJsZWRcbiAgICAgICAgZm9yIChsZXQgaWR4ID0gaW5kZXggKyAxOyBpZHggPCB0aGlzLmNvbHVtbnMubGVuZ3RoOyBpZHgrKykge1xuXG4gICAgICAgICAgICBjb25zdCBzaWJsaW5nID0gdGhpcy5nZXRDb2x1bW5JbnN0YW5jZShpZHgpO1xuXG4gICAgICAgICAgICBpZiAoIXNpYmxpbmcgfHwgIXNpYmxpbmcuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWR4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEdldCB0aGUgY29sdW1uIGNsYXNzIGZyb20gb3VyIHF1ZXJ5IGxpc3QgKi9cbiAgICBwcml2YXRlIGdldENvbHVtbkluc3RhbmNlKGluZGV4OiBudW1iZXIpOiBSZXNpemFibGVUYWJsZUNvbHVtbkNvbXBvbmVudCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29sdW1ucyA/IHRoaXMuX2NvbHVtbnMudG9BcnJheSgpW2luZGV4XSA6IG51bGw7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBlbnVtIENvbHVtblVuaXQge1xuICAgIFBpeGVsLFxuICAgIFBlcmNlbnRhZ2Vcbn0iXX0=