UNPKG

svogv

Version:

A decorator based approach for model driven forms, including an advanced DataGrid and a TreeView component.

203 lines 24.5 kB
import { EventEmitter } from '@angular/core'; import '../../../utils/object-extensions'; import { DataGridHeaderModel } from './datagridheader.model'; import { Display, Hidden, UiHint } from '../../../decorators'; /** * Sort direction, controlled by simple string comparision or a callback. */ export var Direction; (function (Direction) { Direction[Direction["Ascending"] = 0] = "Ascending"; Direction[Direction["Descending"] = 1] = "Descending"; })(Direction || (Direction = {})); /** * The controlling class for Grid applications. * * This class takes an array of elements and handles: * - visible headers, managed by @Hidden() decorator * - create header titles, managed by @Display() decorator * - sorting * - filtering * - count total rows * - paging */ export class DataGridModel { constructor(items, type, pageSize = 10) { /** * The search value filters the rows. Provide the property name and the filter instruction. Search is pure client. */ this.searchValue = {}; this.currentPageIndex = 1; /** * Event fired if user clicks Edit button. */ this.onEdit = new EventEmitter(); /** * Event fired if user clicks Delete button. */ this.onDelete = new EventEmitter(); /** * Current sort direction per column. */ this.sortDirection = {}; this._items = items; this.pageSize = pageSize; const typeInstance = new type(); if (typeInstance) { // make header from decorators, omit if null this.createHeadersForType(typeInstance); } } /** * Returns the number of rows regardless the actual filter (the total). */ get totalRows() { return this._items.length; } get totalFilteredRows() { return this.itemsFiltered ? this.itemsFiltered.length : 0; } get currentRowStart() { return this.totalRows > this.pageSize ? this.startRow + 1 : this.totalRows === 0 ? 0 : 1; } get currentRowEnd() { return this.startRow + this.pageSize < this.totalRows ? this.startRow + this.pageSize : this.totalRows; } get startRow() { if (this.currentPageIndex === 0) { return 0; } return (this.currentPageIndex - 1) * this.pageSize; } get maxPageIndex() { const index = Math.ceil(this.totalFilteredRows / this.pageSize); return index; } set items(value) { this._items = value; } get items() { return this._items; } get itemsFiltered() { // not actually a filter present if (!this.searchValue || (Object.keys(this.searchValue).length === 0 && this.searchValue.constructor === Object)) { return this.items; } return this.items.filter((item) => { // tslint:disable-next-line:forin for (const s in this.searchValue) { const pattern = new RegExp(this.searchValue[s]); if (pattern.test(item[s])) { return true; } } return false; }); } get itemsOnCurrentPage() { return this.itemsFiltered.slice(this.startRow, this.startRow + this.pageSize); } /** * Get all headers (column names) and their properties. */ get headers() { return this._headers.filter((h) => !h.hidden); } /** * Returns the columns currently not shown. {@link addColumn and @see removeColumn for more}information. */ get headersNotVisible() { return this._headers.filter((h) => h.hidden); } /** * Simple sort fucntion that makes a array sort call for the specified column. * @param colName The column which has to be sorted after. * // tslint:disable-next-line:max-line-length * @param dir The order, descended is *desc*, any other string is ascending. * If nothing is provided, the direction toggles. Initital value is *ascending*. */ sortColumn(colName, dir, sortCallback) { if (!dir) { // if nothing is provided, toggle current dir = this.sortDirection[colName] === Direction.Ascending ? Direction.Descending : Direction.Ascending; } // remember last and update UI this.sortDirection[colName] = dir; if (sortCallback) { this.items.sort(sortCallback); } else { this.items.sort((a, b) => { if (dir === Direction.Descending) { return a[colName] > b[colName] ? 1 : -1; } else { return a[colName] > b[colName] ? -1 : 1; } }); } } /** * Make a column invisible. This is just changing the render process, the column is still * in the headers collection and can be made visible again by calling {@link addColumn}later. */ removeColumn(colname) { const col = this._headers.find((h) => h.prop === colname); if (col) { col.hidden = true; } } /** * Add a column to the current grid, that has been removed recently. * It's just adding columns that already exists in the headers collection. * If the column name provided does not exists, the method does nothing. */ addColumn(colname) { const col = this._headers.find((h) => h.prop === colname); if (col) { col.hidden = false; } } /** * Called by infrastructure to inform caller of edit wish * @param item The item to edit */ editItem(item) { this.onEdit.emit(item); } /** * Called by infrastructure to inform caller of delete wish * @param item The item to delete */ deleteItem(item) { this.onDelete.emit(item); } createHeadersForType(type) { // assume simple object structure, iterating an array of viewmodels // has at least one row, so we can read the headers // first we read the properties this._headers = new Array(); for (const p in type) { if (!type.hasOwnProperty(p)) { continue; } const propName = Display.Name(type, p, p); const propDesc = Display.Desc(type, p, p); // check if hidden, show if no hidden decorator const isHidden = Hidden.IsHidden(type, p, false); const header = new DataGridHeaderModel(propName, propDesc, p, isHidden); // sorting header.isSortable = type[`__isSortable__${p}`] === undefined ? true : !!type[`__isSortable__${p}`]; header.sortCallback = type[`__sortCallback__${p}`] || undefined; // look for templates and pipes provided by user, if none, we have templates for all ES types header.templateHint = type[`__templatehint__${p}`] || typeof type[p]; header.templateHintParams = type[`__templatehintParams__${p}`]; header.pipe = type[`__uipipe__${p}`]; header.pipeParams = type[`__pipeparams__${p}`]; header.uiHint = UiHint.HintRule(type, p, {}); this._headers.push(header); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWdyaWQubW9kZWwuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vcHJvamVjdHMvc3ZvZ3Yvc3JjLyIsInNvdXJjZXMiOlsibGliL3dpZGdldHMvZGF0YWdyaWQvbW9kZWxzL2RhdGFncmlkLm1vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBUSxZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFFOUQsT0FBTyxrQ0FBa0MsQ0FBQztBQUMxQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUU5RDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIsbURBQVMsQ0FBQTtJQUNULHFEQUFVLENBQUE7QUFDWixDQUFDLEVBSFcsU0FBUyxLQUFULFNBQVMsUUFHcEI7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUFrR3hCLFlBQVksS0FBVSxFQUFFLElBQWEsRUFBRSxRQUFRLEdBQUcsRUFBRTtRQXpCcEQ7O1dBRUc7UUFDSSxnQkFBVyxHQUE0QixFQUFFLENBQUM7UUFFMUMscUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBRzVCOztXQUVHO1FBQ0ksV0FBTSxHQUFvQixJQUFJLFlBQVksRUFBSyxDQUFDO1FBRXZEOztXQUVHO1FBQ0ksYUFBUSxHQUFvQixJQUFJLFlBQVksRUFBSyxDQUFDO1FBRXpEOztXQUVHO1FBQ0ksa0JBQWEsR0FBb0MsRUFBRSxDQUFDO1FBS3pELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLE1BQU0sWUFBWSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDaEMsSUFBSSxZQUFZLEVBQUU7WUFDaEIsNENBQTRDO1lBQzVD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LEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDNUI7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUeXBlLCBFdmVudEVtaXR0ZXIsIERpcmVjdGl2ZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgJy4uLy4uLy4uL3V0aWxzL29iamVjdC1leHRlbnNpb25zJztcbmltcG9ydCB7IERhdGFHcmlkSGVhZGVyTW9kZWwgfSBmcm9tICcuL2RhdGFncmlkaGVhZGVyLm1vZGVsJztcbmltcG9ydCB7IERpc3BsYXksIEhpZGRlbiwgVWlIaW50IH0gZnJvbSAnLi4vLi4vLi4vZGVjb3JhdG9ycyc7XG5cbi8qKlxuICogU29ydCBkaXJlY3Rpb24sIGNvbnRyb2xsZWQgYnkgc2ltcGxlIHN0cmluZyBjb21wYXJpc2lvbiBvciBhIGNhbGxiYWNrLlxuICovXG5leHBvcnQgZW51bSBEaXJlY3Rpb24ge1xuICBBc2NlbmRpbmcsXG4gIERlc2NlbmRpbmdcbn1cblxuLyoqXG4gKiBUaGUgY29udHJvbGxpbmcgY2xhc3MgZm9yIEdyaWQgYXBwbGljYXRpb25zLlxuICpcbiAqIFRoaXMgY2xhc3MgdGFrZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIGhhbmRsZXM6XG4gKiAtIHZpc2libGUgaGVhZGVycywgbWFuYWdlZCBieSBASGlkZGVuKCkgZGVjb3JhdG9yXG4gKiAtIGNyZWF0ZSBoZWFkZXIgdGl0bGVzLCBtYW5hZ2VkIGJ5IEBEaXNwbGF5KCkgZGVjb3JhdG9yXG4gKiAtIHNvcnRpbmdcbiAqIC0gZmlsdGVyaW5nXG4gKiAtIGNvdW50IHRvdGFsIHJvd3NcbiAqIC0gcGFnaW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhR3JpZE1vZGVsPFQ+IHtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJvd3MgcmVnYXJkbGVzcyB0aGUgYWN0dWFsIGZpbHRlciAodGhlIHRvdGFsKS5cbiAgICovXG4gIGdldCB0b3RhbFJvd3MoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5faXRlbXMubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IHRvdGFsRmlsdGVyZWRSb3dzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaXRlbXNGaWx0ZXJlZCA/IHRoaXMuaXRlbXNGaWx0ZXJlZC5sZW5ndGggOiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgY3VycmVudFJvd1N0YXJ0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudG90YWxSb3dzID4gdGhpcy5wYWdlU2l6ZSA/IHRoaXMuc3RhcnRSb3cgKyAxIDogdGhpcy50b3RhbFJvd3MgPT09IDAgPyAwIDogMTtcbiAgfVxuICBwcml2YXRlIGdldCBjdXJyZW50Um93RW5kKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRSb3cgKyB0aGlzLnBhZ2VTaXplIDwgdGhpcy50b3RhbFJvd3MgPyB0aGlzLnN0YXJ0Um93ICsgdGhpcy5wYWdlU2l6ZSA6IHRoaXMudG90YWxSb3dzO1xuICB9XG5cbiAgZ2V0IHN0YXJ0Um93KCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuY3VycmVudFBhZ2VJbmRleCA9PT0gMCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiAodGhpcy5jdXJyZW50UGFnZUluZGV4IC0gMSkgKiB0aGlzLnBhZ2VTaXplO1xuICB9XG5cbiAgZ2V0IG1heFBhZ2VJbmRleCgpOiBudW1iZXIge1xuICAgIGNvbnN0IGluZGV4ID0gTWF0aC5jZWlsKHRoaXMudG90YWxGaWx0ZXJlZFJvd3MgLyB0aGlzLnBhZ2VTaXplKTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBzZXQgaXRlbXModmFsdWU6IFRbXSkge1xuICAgIHRoaXMuX2l0ZW1zID0gdmFsdWU7XG4gIH1cbiAgZ2V0IGl0ZW1zKCk6IFRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2l0ZW1zO1xuICB9XG5cbiAgZ2V0IGl0ZW1zRmlsdGVyZWQoKTogVFtdIHtcbiAgICAvLyBub3QgYWN0dWFsbHkgYSBmaWx0ZXIgcHJlc2VudFxuICAgIGlmICghdGhpcy5zZWFyY2hWYWx1ZSB8fCAoT2JqZWN0LmtleXModGhpcy5zZWFyY2hWYWx1ZSkubGVuZ3RoID09PSAwICYmIHRoaXMuc2VhcmNoVmFsdWUuY29uc3RydWN0b3IgPT09IE9iamVjdCkpIHtcbiAgICAgIHJldHVybiB0aGlzLml0ZW1zO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pdGVtcy5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpmb3JpblxuICAgICAgZm9yIChjb25zdCBzIGluIHRoaXMuc2VhcmNoVmFsdWUpIHtcbiAgICAgICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAodGhpcy5zZWFyY2hWYWx1ZVtzXSk7XG4gICAgICAgIGlmIChwYXR0ZXJuLnRlc3QoaXRlbVtzXSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGl0ZW1zT25DdXJyZW50UGFnZSgpOiBUW10ge1xuICAgIHJldHVybiB0aGlzLml0ZW1zRmlsdGVyZWQuc2xpY2UodGhpcy5zdGFydFJvdywgdGhpcy5zdGFydFJvdyArIHRoaXMucGFnZVNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgaGVhZGVycyAoY29sdW1uIG5hbWVzKSBhbmQgdGhlaXIgcHJvcGVydGllcy5cbiAgICovXG4gIHB1YmxpYyBnZXQgaGVhZGVycygpOiBEYXRhR3JpZEhlYWRlck1vZGVsW10ge1xuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzLmZpbHRlcigoaCkgPT4gIWguaGlkZGVuKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb2x1bW5zIGN1cnJlbnRseSBub3Qgc2hvd24uIHtAbGluayBhZGRDb2x1bW4gYW5kIEBzZWUgcmVtb3ZlQ29sdW1uIGZvciBtb3JlfWluZm9ybWF0aW9uLlxuICAgKi9cbiAgcHVibGljIGdldCBoZWFkZXJzTm90VmlzaWJsZSgpOiBEYXRhR3JpZEhlYWRlck1vZGVsW10ge1xuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzLmZpbHRlcigoaCkgPT4gaC5oaWRkZW4pO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgc2VhcmNoIHZhbHVlIGZpbHRlcnMgdGhlIHJvd3MuIFByb3ZpZGUgdGhlIHByb3BlcnR5IG5hbWUgYW5kIHRoZSBmaWx0ZXIgaW5zdHJ1Y3Rpb24uIFNlYXJjaCBpcyBwdXJlIGNsaWVudC5cbiAgICovXG4gIHB1YmxpYyBzZWFyY2hWYWx1ZTogeyBbcHJvcDogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICBwdWJsaWMgY3VycmVudFBhZ2VJbmRleCA9IDE7XG4gIHB1YmxpYyBwYWdlU2l6ZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBFdmVudCBmaXJlZCBpZiB1c2VyIGNsaWNrcyBFZGl0IGJ1dHRvbi5cbiAgICovXG4gIHB1YmxpYyBvbkVkaXQ6IEV2ZW50RW1pdHRlcjxUPiA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcblxuICAvKipcbiAgICogRXZlbnQgZmlyZWQgaWYgdXNlciBjbGlja3MgRGVsZXRlIGJ1dHRvbi5cbiAgICovXG4gIHB1YmxpYyBvbkRlbGV0ZTogRXZlbnRFbWl0dGVyPFQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxUPigpO1xuXG4gIC8qKlxuICAgKiBDdXJyZW50IHNvcnQgZGlyZWN0aW9uIHBlciBjb2x1bW4uXG4gICAqL1xuICBwdWJsaWMgc29ydERpcmVjdGlvbjogeyBbY29sdW1uOiBzdHJpbmddOiBEaXJlY3Rpb24gfSA9IHt9O1xuICBwcml2YXRlIF9pdGVtczogVFtdO1xuXG4gIHByaXZhdGUgX2hlYWRlcnM6IERhdGFHcmlkSGVhZGVyTW9kZWxbXTtcbiAgY29uc3RydWN0b3IoaXRlbXM6IFRbXSwgdHlwZTogVHlwZTxUPiwgcGFnZVNpemUgPSAxMCkge1xuICAgIHRoaXMuX2l0ZW1zID0gaXRlbXM7XG4gICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplO1xuICAgIGNvbnN0IHR5cGVJbnN0YW5jZSA9IG5ldyB0eXBlKCk7XG4gICAgaWYgKHR5cGVJbnN0YW5jZSkge1xuICAgICAgLy8gbWFrZSBoZWFkZXIgZnJvbSBkZWNvcmF0b3JzLCBvbWl0IGlmIG51bGxcbiAgICAgIHRoaXMuY3JlYXRlSGVhZGVyc0ZvclR5cGUodHlwZUluc3RhbmNlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2ltcGxlIHNvcnQgZnVjbnRpb24gdGhhdCBtYWtlcyBhIGFycmF5IHNvcnQgY2FsbCBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uXG4gICAqIEBwYXJhbSBjb2xOYW1lIFRoZSBjb2x1bW4gd2hpY2ggaGFzIHRvIGJlIHNvcnRlZCBhZnRlci5cbiAgICogLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgKiBAcGFyYW0gZGlyIFRoZSBvcmRlciwgZGVzY2VuZGVkIGlzICpkZXNjKiwgYW55IG90aGVyIHN0cmluZyBpcyBhc2NlbmRpbmcuXG4gICAqICAgICAgICAgICAgSWYgbm90aGluZyBpcyBwcm92aWRlZCwgdGhlIGRpcmVjdGlvbiB0b2dnbGVzLiBJbml0aXRhbCB2YWx1ZSBpcyAqYXNjZW5kaW5nKi5cbiAgICovXG4gIHB1YmxpYyBzb3J0Q29sdW1uKGNvbE5hbWU6IHN0cmluZywgZGlyOiBEaXJlY3Rpb24sIHNvcnRDYWxsYmFjaz86IChhLCBiKSA9PiAxIHwgLTEgfCAwKSB7XG4gICAgaWYgKCFkaXIpIHtcbiAgICAgIC8vIGlmIG5vdGhpbmcgaXMgcHJvdmlkZWQsIHRvZ2dsZSBjdXJyZW50XG4gICAgICBkaXIgPSB0aGlzLnNvcnREaXJlY3Rpb25bY29sTmFtZV0gPT09IERpcmVjdGlvbi5Bc2NlbmRpbmcgPyBEaXJlY3Rpb24uRGVzY2VuZGluZyA6IERpcmVjdGlvbi5Bc2NlbmRpbmc7XG4gICAgfVxuICAgIC8vIHJlbWVtYmVyIGxhc3QgYW5kIHVwZGF0ZSBVSVxuICAgIHRoaXMuc29ydERpcmVjdGlvbltjb2xOYW1lXSA9IGRpcjtcbiAgICBpZiAoc29ydENhbGxiYWNrKSB7XG4gICAgICB0aGlzLml0ZW1zLnNvcnQoc29ydENhbGxiYWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pdGVtcy5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xuICAgICAgICBpZiAoZGlyID09PSBEaXJlY3Rpb24uRGVzY2VuZGluZykge1xuICAgICAgICAgIHJldHVybiBhW2NvbE5hbWVdID4gYltjb2xOYW1lXSA/IDEgOiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gYVtjb2xOYW1lXSA+IGJbY29sTmFtZV0gPyAtMSA6IDE7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIGEgY29sdW1uIGludmlzaWJsZS4gVGhpcyBpcyBqdXN0IGNoYW5naW5nIHRoZSByZW5kZXIgcHJvY2VzcywgdGhlIGNvbHVtbiBpcyBzdGlsbFxuICAgKiBpbiB0aGUgaGVhZGVycyBjb2xsZWN0aW9uIGFuZCBjYW4gYmUgbWFkZSB2aXNpYmxlIGFnYWluIGJ5IGNhbGxpbmcge0BsaW5rIGFkZENvbHVtbn1sYXRlci5cbiAgICovXG4gIHB1YmxpYyByZW1vdmVDb2x1bW4oY29sbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgY29sID0gdGhpcy5faGVhZGVycy5maW5kKChoKSA9PiBoLnByb3AgPT09IGNvbG5hbWUpO1xuICAgIGlmIChjb2wpIHtcbiAgICAgIGNvbC5oaWRkZW4gPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBjb2x1bW4gdG8gdGhlIGN1cnJlbnQgZ3JpZCwgdGhhdCBoYXMgYmVlbiByZW1vdmVkIHJlY2VudGx5LlxuICAgKiBJdCdzIGp1c3QgYWRkaW5nIGNvbHVtbnMgdGhhdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgaGVhZGVycyBjb2xsZWN0aW9uLlxuICAgKiBJZiB0aGUgY29sdW1uIG5hbWUgcHJvdmlkZWQgZG9lcyBub3QgZXhpc3RzLCB0aGUgbWV0aG9kIGRvZXMgbm90aGluZy5cbiAgICovXG4gIHB1YmxpYyBhZGRDb2x1bW4oY29sbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgY29sID0gdGhpcy5faGVhZGVycy5maW5kKChoKSA9PiBoLnByb3AgPT09IGNvbG5hbWUpO1xuICAgIGlmIChjb2wpIHtcbiAgICAgIGNvbC5oaWRkZW4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGJ5IGluZnJhc3RydWN0dXJlIHRvIGluZm9ybSBjYWxsZXIgb2YgZWRpdCB3aXNoXG4gICAqIEBwYXJhbSBpdGVtIFRoZSBpdGVtIHRvIGVkaXRcbiAgICovXG4gIHB1YmxpYyBlZGl0SXRlbShpdGVtOiBUKSB7XG4gICAgdGhpcy5vbkVkaXQuZW1pdChpdGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgYnkgaW5mcmFzdHJ1Y3R1cmUgdG8gaW5mb3JtIGNhbGxlciBvZiBkZWxldGUgd2lzaFxuICAgKiBAcGFyYW0gaXRlbSBUaGUgaXRlbSB0byBkZWxldGVcbiAgICovXG4gIHB1YmxpYyBkZWxldGVJdGVtKGl0ZW06IFQpIHtcbiAgICB0aGlzLm9uRGVsZXRlLmVtaXQoaXRlbSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUhlYWRlcnNGb3JUeXBlKHR5cGU6IGFueSk6IHZvaWQge1xuICAgIC8vIGFzc3VtZSBzaW1wbGUgb2JqZWN0IHN0cnVjdHVyZSwgaXRlcmF0aW5nIGFuIGFycmF5IG9mIHZpZXdtb2RlbHNcbiAgICAvLyBoYXMgYXQgbGVhc3Qgb25lIHJvdywgc28gd2UgY2FuIHJlYWQgdGhlIGhlYWRlcnNcbiAgICAvLyBmaXJzdCB3ZSByZWFkIHRoZSBwcm9wZXJ0aWVzXG4gICAgdGhpcy5faGVhZGVycyA9IG5ldyBBcnJheTxEYXRhR3JpZEhlYWRlck1vZGVsPigpO1xuICAgIGZvciAoY29uc3QgcCBpbiB0eXBlKSB7XG4gICAgICBpZiAoIXR5cGUuaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBwcm9wTmFtZSA9IERpc3BsYXkuTmFtZSh0eXBlLCBwLCBwKTtcbiAgICAgIGNvbnN0IHByb3BEZXNjID0gRGlzcGxheS5EZXNjKHR5cGUsIHAsIHApO1xuICAgICAgLy8gY2hlY2sgaWYgaGlkZGVuLCBzaG93IGlmIG5vIGhpZGRlbiBkZWNvcmF0b3JcbiAgICAgIGNvbnN0IGlzSGlkZGVuID0gSGlkZGVuLklzSGlkZGVuKHR5cGUsIHAsIGZhbHNlKTtcbiAgICAgIGNvbnN0IGhlYWRlciA9IG5ldyBEYXRhR3JpZEhlYWRlck1vZGVsKHByb3BOYW1lLCBwcm9wRGVzYywgcCwgaXNIaWRkZW4pO1xuICAgICAgLy8gc29ydGluZ1xuICAgICAgaGVhZGVyLmlzU29ydGFibGUgPSB0eXBlW2BfX2lzU29ydGFibGVfXyR7cH1gXSA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6ICEhdHlwZVtgX19pc1NvcnRhYmxlX18ke3B9YF07XG4gICAgICBoZWFkZXIuc29ydENhbGxiYWNrID0gdHlwZVtgX19zb3J0Q2FsbGJhY2tfXyR7cH1gXSB8fCB1bmRlZmluZWQ7XG4gICAgICAvLyBsb29rIGZvciB0ZW1wbGF0ZXMgYW5kIHBpcGVzIHByb3ZpZGVkIGJ5IHVzZXIsIGlmIG5vbmUsIHdlIGhhdmUgdGVtcGxhdGVzIGZvciBhbGwgRVMgdHlwZXNcbiAgICAgIGhlYWRlci50ZW1wbGF0ZUhpbnQgPSB0eXBlW2BfX3RlbXBsYXRlaGludF9fJHtwfWBdIHx8IHR5cGVvZiB0eXBlW3BdO1xuICAgICAgaGVhZGVyLnRlbXBsYXRlSGludFBhcmFtcyA9IHR5cGVbYF9fdGVtcGxhdGVoaW50UGFyYW1zX18ke3B9YF07XG4gICAgICBoZWFkZXIucGlwZSA9IHR5cGVbYF9fdWlwaXBlX18ke3B9YF07XG4gICAgICBoZWFkZXIucGlwZVBhcmFtcyA9IHR5cGVbYF9fcGlwZXBhcmFtc19fJHtwfWBdO1xuICAgICAgaGVhZGVyLnVpSGludCA9IFVpSGludC5IaW50UnVsZSh0eXBlLCBwLCB7fSk7XG4gICAgICB0aGlzLl9oZWFkZXJzLnB1c2goaGVhZGVyKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==