UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

249 lines 33.6 kB
import { IncrementingCounter } from '../../utility/incrementing-counter'; import { TaskElementType } from './task-content-element-type'; import { BehaviorSubject } from 'rxjs'; /** * A configuration for one subgrid - a basic layouting unit */ export class Subgrid { subgridId; cols; _asyncRenderingConfig; /** * the css `gridAreas` configuration, that determines the layout of the grids content */ gridAreas; /** * The elements that are contained in the subgrid */ _content = []; /** * The elements that are contained in the subgrid and have already been rendered to the user */ _renderedContent$; /** * A 2D representation of the grid element IDs */ _grid = []; /** * Counter to assure element ID uniqueness */ _runningTitleCount = new IncrementingCounter(); /** * Grid area identifiers that are already in use */ _existingIdentifiers = new Set(); _asyncRenderingTimeout; _keptElements; _newElements; /** * @param subgridId a unique identifier of the subgrid in the task layout * @param cols Number of columns of the subgrid * @param _asyncRenderingConfig configuration object for async rendering of data fields */ constructor(subgridId, cols, _asyncRenderingConfig) { this.subgridId = subgridId; this.cols = cols; this._asyncRenderingConfig = _asyncRenderingConfig; this._renderedContent$ = new BehaviorSubject([]); } get content() { return this._renderedContent$.value; } /** * Completes the underlying stream and clears any running timeouts */ destroy() { this._renderedContent$.complete(); if (this._asyncRenderingTimeout !== undefined) { window.clearTimeout(this._asyncRenderingTimeout); } } /** * @returns the columns configuration for the grid layout */ getGridColumns() { return 'repeat(' + this.cols + ', 1fr)'; } getRunningTitleCount() { return this._runningTitleCount; } /** * Converts a {@link DataField} into a {@link DatafieldGridLayoutElement} and adds it to the content of this subgrid. * * Beware that this method DOES NOT add the element into the resulting grid. This must be done independently by calling the * [addRow]{@link Subgrid#addRow} method. * @param field the field that should be added to the subgrid * @param type the type of the field * @returns the created grid element */ addField(field, type) { const element = this.fieldElement(field, type); this.addElement(element); return element; } /** * Converts a {@link DataGroup} into a {@link DatafieldGridLayoutElement} and adds it to the content of this subgrid. * * Beware that this method DOES NOT add the element into the resulting grid. This must be done independently by calling the * [addRow]{@link Subgrid#addRow} method. * @param dataGroup the data group whose title should be added to the grid * @returns the created grid element */ addTitle(dataGroup) { const element = this.groupTitleElement(dataGroup); this.addElement(element); return element; } addElement(element) { this._content.push(element); } /** * Adds a row of CSS `gridAreaId`s into the grid that is held in this subgrid. * @param row the field Ids. The width of the row should match the number of columns of the grid. If not an error is thrown. */ addRow(row) { if (row.length !== this.cols) { throw new Error(`The provided grid layout row '${JSON.stringify(row)}' does not match the number of columns of this subgrid (${this.cols})`); } this._grid.push(row); } /** * Converts the provided configuration into data that can be fed into CSS grid layout */ finalize() { this.fillEmptySpace(); this.createGridAreasString(); } /** * Fills empty tiles in the grid with blank elements */ fillEmptySpace() { const runningBlanksCount = new IncrementingCounter(); this._grid.forEach(row => { for (let i = 0; i < row.length; i++) { if (row[i] !== '') { continue; } const filler = this.fillerElement(runningBlanksCount); row[i] = filler.gridAreaId; this._content.push(filler); } }); } /** * @param field the field whose representation should be created * @param type the type of the data field * @returns an object that represents the provided data field in the layout */ fieldElement(field, type) { return { gridAreaId: this.assureUniqueness(field.stringId), type, item: field }; } /** * @param fillerCounter the counter that is used to track the number of already created filler elements * @returns a filler element object with a unique ID. The provided counter is incremented by one. */ fillerElement(fillerCounter) { return { gridAreaId: this.assureUniqueness('blank' + fillerCounter.next()), type: TaskElementType.BLANK }; } /** * @param dataGroup the data group whose title element should be created * @returns an object that represents a title element of the provided data group. The provided counter is incremented by one. */ groupTitleElement(dataGroup) { return { title: dataGroup.title, gridAreaId: this.assureUniqueness('group' + this._runningTitleCount.next()), type: TaskElementType.DATA_GROUP_TITLE }; } /** * Assures that the provided identifier will be unique. * @param identifier the base for the identifier * @returns the base identifier, if it already is unique. A unique variation on the base identifier if it is already in use. */ assureUniqueness(identifier) { const alphaNumIdentifier = 'x' + identifier?.replace(/[^0-9a-z]/gi, ''); if (!this._existingIdentifiers.has(alphaNumIdentifier)) { this._existingIdentifiers.add(alphaNumIdentifier); return alphaNumIdentifier; } let variation; const counter = new IncrementingCounter(); do { variation = `x${counter.next()}${alphaNumIdentifier}`; } while (this._existingIdentifiers.has(variation)); this._existingIdentifiers.add(variation); return variation; } /** * Joins the grid of element into a string accepted by `[gdAreas]` input property of Angular flex layout */ createGridAreasString() { this.gridAreas = this._grid.map(row => row.join(' ')).join(' | '); } /** * Marks all contained elements as kept and displays them. */ displayAllFields() { this._keptElements = [...this._content]; this._newElements = []; this._renderedContent$.next(this._keptElements); } /** * Determines which elements from the provided subgrid are contained in this subgrid. * Marks these elements as kept and displays them. Marks the remaining elements as new. * * New elements can be displayed asynchronously over time by calling the * [renderContentOverTime]{@link Subgrid#renderContentOverTime} method. * @param subgrid the "previous" subgrid that is used to compute the element "difference" */ determineKeptFields(subgrid) { this._keptElements = []; this._newElements = []; this._content.forEach(element => { if (subgrid.content.some(el => el.gridAreaId === element.gridAreaId)) { this._keptElements.push(element); } else { this._newElements.push(element); } }); this._renderedContent$.next(this._keptElements); } /** * If elements are not sorted into new and kept, marks all elements as new. * The [determineKeptFields]{@link Subgrid#determineKeptFields} method can be used to mark elements as kept. * * Then pushes the new elements with the kept elements into the output array over time as specified by the * {@link AsyncRenderingConfiguration} provided in the subgrids constructor. * * @param callback the function that is called once all new elements were pushed into the output array * @param first whether this is the first subgrid that si rendered. If this is the first subgrid then on the initial rendering of * elements a batch of new fields alongside the loader elements is displayed so that some content is immediately available. * Otherwise The initial batch contains only loader elements. Being first effectively shortens the rendering by one batch, since the * first loader-only batch is skipped. */ renderContentOverTime(callback, first = false) { if (this._newElements === undefined) { this._newElements = Array.from(this._content); this._keptElements = []; } this.spreadFieldRenderingOverTime(callback, first ? 1 : 0); } spreadFieldRenderingOverTime(callback, iteration = 0) { this._asyncRenderingTimeout = undefined; const fieldsInCurrentIteration = this._newElements.slice(0, iteration * this._asyncRenderingConfig.batchSize); const placeholdersInCurrentIteration = this._newElements.slice(iteration * this._asyncRenderingConfig.batchSize, iteration * this._asyncRenderingConfig.batchSize + this._asyncRenderingConfig.numberOfPlaceholders); fieldsInCurrentIteration.push(...placeholdersInCurrentIteration.map(field => ({ gridAreaId: field.gridAreaId, type: TaskElementType.LOADER }))); this._renderedContent$.next([...this._keptElements, ...fieldsInCurrentIteration]); if (this._asyncRenderingConfig.batchSize * iteration < this._newElements.length) { this._asyncRenderingTimeout = window.setTimeout(() => { this.spreadFieldRenderingOverTime(callback, iteration + 1); }, this._asyncRenderingConfig.batchDelay); } else { callback(); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ViZ3JpZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy1jb3JlL3NyYy9saWIvdGFzay1jb250ZW50L21vZGVsL3N1YmdyaWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBSTVELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFHckM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sT0FBTztJQWtDVTtJQUEwQjtJQUF3QjtJQWpDNUU7O09BRUc7SUFDSCxTQUFTLENBQVM7SUFDbEI7O09BRUc7SUFDTyxRQUFRLEdBQXNDLEVBQUUsQ0FBQztJQUMzRDs7T0FFRztJQUNPLGlCQUFpQixDQUFxRDtJQUNoRjs7T0FFRztJQUNPLEtBQUssR0FBeUIsRUFBRSxDQUFDO0lBQzNDOztPQUVHO0lBQ08sa0JBQWtCLEdBQXdCLElBQUksbUJBQW1CLEVBQUUsQ0FBQztJQUM5RTs7T0FFRztJQUNPLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDekMsc0JBQXNCLENBQVM7SUFDL0IsYUFBYSxDQUFvQztJQUNqRCxZQUFZLENBQW9DO0lBRTFEOzs7O09BSUc7SUFDSCxZQUEwQixTQUFpQixFQUFTLElBQVksRUFBWSxxQkFBa0Q7UUFBcEcsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7UUFBWSwwQkFBcUIsR0FBckIscUJBQXFCLENBQTZCO1FBQzFILElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBb0MsRUFBRSxDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FB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QUFHLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtZQUM3RSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pELElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUMsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDN0M7YUFBTTtZQUNILFFBQVEsRUFBRSxDQUFDO1NBQ2Q7SUFDTCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50fSBmcm9tICcuL2RhdGFmaWVsZC1ncmlkLWxheW91dC1lbGVtZW50JztcbmltcG9ydCB7SW5jcmVtZW50aW5nQ291bnRlcn0gZnJvbSAnLi4vLi4vdXRpbGl0eS9pbmNyZW1lbnRpbmctY291bnRlcic7XG5pbXBvcnQge1Rhc2tFbGVtZW50VHlwZX0gZnJvbSAnLi90YXNrLWNvbnRlbnQtZWxlbWVudC10eXBlJztcbmltcG9ydCB7RGF0YUZpZWxkfSBmcm9tICcuLi8uLi9kYXRhLWZpZWxkcy9tb2RlbHMvYWJzdHJhY3QtZGF0YS1maWVsZCc7XG5pbXBvcnQge0ZpZWxkVHlwZVJlc291cmNlfSBmcm9tICcuL2ZpZWxkLXR5cGUtcmVzb3VyY2UnO1xuaW1wb3J0IHtEYXRhR3JvdXB9IGZyb20gJy4uLy4uL3Jlc291cmNlcy9pbnRlcmZhY2UvZGF0YS1ncm91cHMnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBc3luY1JlbmRlcmluZ0NvbmZpZ3VyYXRpb259IGZyb20gJy4vYXN5bmMtcmVuZGVyaW5nLWNvbmZpZ3VyYXRpb24nO1xuXG4vKipcbiAqIEEgY29uZmlndXJhdGlvbiBmb3Igb25lIHN1YmdyaWQgLSBhIGJhc2ljIGxheW91dGluZyB1bml0XG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJncmlkIHtcbiAgICAvKipcbiAgICAgKiB0aGUgY3NzIGBncmlkQXJlYXNgIGNvbmZpZ3VyYXRpb24sIHRoYXQgZGV0ZXJtaW5lcyB0aGUgbGF5b3V0IG9mIHRoZSBncmlkcyBjb250ZW50XG4gICAgICovXG4gICAgZ3JpZEFyZWFzOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIGVsZW1lbnRzIHRoYXQgYXJlIGNvbnRhaW5lZCBpbiB0aGUgc3ViZ3JpZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBfY29udGVudDogQXJyYXk8RGF0YWZpZWxkR3JpZExheW91dEVsZW1lbnQ+ID0gW107XG4gICAgLyoqXG4gICAgICogVGhlIGVsZW1lbnRzIHRoYXQgYXJlIGNvbnRhaW5lZCBpbiB0aGUgc3ViZ3JpZCBhbmQgaGF2ZSBhbHJlYWR5IGJlZW4gcmVuZGVyZWQgdG8gdGhlIHVzZXJcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX3JlbmRlcmVkQ29udGVudCQ6IEJlaGF2aW9yU3ViamVjdDxBcnJheTxEYXRhZmllbGRHcmlkTGF5b3V0RWxlbWVudD4+O1xuICAgIC8qKlxuICAgICAqIEEgMkQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdyaWQgZWxlbWVudCBJRHNcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2dyaWQ6IEFycmF5PEFycmF5PHN0cmluZz4+ID0gW107XG4gICAgLyoqXG4gICAgICogQ291bnRlciB0byBhc3N1cmUgZWxlbWVudCBJRCB1bmlxdWVuZXNzXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9ydW5uaW5nVGl0bGVDb3VudDogSW5jcmVtZW50aW5nQ291bnRlciA9IG5ldyBJbmNyZW1lbnRpbmdDb3VudGVyKCk7XG4gICAgLyoqXG4gICAgICogR3JpZCBhcmVhIGlkZW50aWZpZXJzIHRoYXQgYXJlIGFscmVhZHkgaW4gdXNlXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9leGlzdGluZ0lkZW50aWZpZXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcHJvdGVjdGVkIF9hc3luY1JlbmRlcmluZ1RpbWVvdXQ6IG51bWJlcjtcbiAgICBwcm90ZWN0ZWQgX2tlcHRFbGVtZW50czogQXJyYXk8RGF0YWZpZWxkR3JpZExheW91dEVsZW1lbnQ+O1xuICAgIHByb3RlY3RlZCBfbmV3RWxlbWVudHM6IEFycmF5PERhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50PjtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBzdWJncmlkSWQgYSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgc3ViZ3JpZCBpbiB0aGUgdGFzayBsYXlvdXRcbiAgICAgKiBAcGFyYW0gY29scyBOdW1iZXIgb2YgY29sdW1ucyBvZiB0aGUgc3ViZ3JpZFxuICAgICAqIEBwYXJhbSBfYXN5bmNSZW5kZXJpbmdDb25maWcgY29uZmlndXJhdGlvbiBvYmplY3QgZm9yIGFzeW5jIHJlbmRlcmluZyBvZiBkYXRhIGZpZWxkc1xuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgc3ViZ3JpZElkOiBzdHJpbmcsIHB1YmxpYyBjb2xzOiBudW1iZXIsIHByb3RlY3RlZCBfYXN5bmNSZW5kZXJpbmdDb25maWc6IEFzeW5jUmVuZGVyaW5nQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxBcnJheTxEYXRhZmllbGRHcmlkTGF5b3V0RWxlbWVudD4+KFtdKTtcbiAgICB9XG5cbiAgICBnZXQgY29udGVudCgpOiBBcnJheTxEYXRhZmllbGRHcmlkTGF5b3V0RWxlbWVudD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVuZGVyZWRDb250ZW50JC52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wbGV0ZXMgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGFuZCBjbGVhcnMgYW55IHJ1bm5pbmcgdGltZW91dHNcbiAgICAgKi9cbiAgICBwdWJsaWMgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fcmVuZGVyZWRDb250ZW50JC5jb21wbGV0ZSgpO1xuICAgICAgICBpZiAodGhpcy5fYXN5bmNSZW5kZXJpbmdUaW1lb3V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fYXN5bmNSZW5kZXJpbmdUaW1lb3V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRoZSBjb2x1bW5zIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBncmlkIGxheW91dFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRHcmlkQ29sdW1ucygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gJ3JlcGVhdCgnICsgdGhpcy5jb2xzICsgJywgMWZyKSc7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFJ1bm5pbmdUaXRsZUNvdW50KCk6IEluY3JlbWVudGluZ0NvdW50ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fcnVubmluZ1RpdGxlQ291bnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSB7QGxpbmsgRGF0YUZpZWxkfSBpbnRvIGEge0BsaW5rIERhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50fSBhbmQgYWRkcyBpdCB0byB0aGUgY29udGVudCBvZiB0aGlzIHN1YmdyaWQuXG4gICAgICpcbiAgICAgKiBCZXdhcmUgdGhhdCB0aGlzIG1ldGhvZCBET0VTIE5PVCBhZGQgdGhlIGVsZW1lbnQgaW50byB0aGUgcmVzdWx0aW5nIGdyaWQuIFRoaXMgbXVzdCBiZSBkb25lIGluZGVwZW5kZW50bHkgYnkgY2FsbGluZyB0aGVcbiAgICAgKiBbYWRkUm93XXtAbGluayBTdWJncmlkI2FkZFJvd30gbWV0aG9kLlxuICAgICAqIEBwYXJhbSBmaWVsZCB0aGUgZmllbGQgdGhhdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHN1YmdyaWRcbiAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgZmllbGRcbiAgICAgKiBAcmV0dXJucyB0aGUgY3JlYXRlZCBncmlkIGVsZW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkRmllbGQoZmllbGQ6IERhdGFGaWVsZDx1bmtub3duPiwgdHlwZTogRmllbGRUeXBlUmVzb3VyY2UpOiBEYXRhZmllbGRHcmlkTGF5b3V0RWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmZpZWxkRWxlbWVudChmaWVsZCwgdHlwZSk7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSB7QGxpbmsgRGF0YUdyb3VwfSBpbnRvIGEge0BsaW5rIERhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50fSBhbmQgYWRkcyBpdCB0byB0aGUgY29udGVudCBvZiB0aGlzIHN1YmdyaWQuXG4gICAgICpcbiAgICAgKiBCZXdhcmUgdGhhdCB0aGlzIG1ldGhvZCBET0VTIE5PVCBhZGQgdGhlIGVsZW1lbnQgaW50byB0aGUgcmVzdWx0aW5nIGdyaWQuIFRoaXMgbXVzdCBiZSBkb25lIGluZGVwZW5kZW50bHkgYnkgY2FsbGluZyB0aGVcbiAgICAgKiBbYWRkUm93XXtAbGluayBTdWJncmlkI2FkZFJvd30gbWV0aG9kLlxuICAgICAqIEBwYXJhbSBkYXRhR3JvdXAgdGhlIGRhdGEgZ3JvdXAgd2hvc2UgdGl0bGUgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBncmlkXG4gICAgICogQHJldHVybnMgdGhlIGNyZWF0ZWQgZ3JpZCBlbGVtZW50XG4gICAgICovXG4gICAgcHVibGljIGFkZFRpdGxlKGRhdGFHcm91cDogRGF0YUdyb3VwKTogRGF0YWZpZWxkR3JpZExheW91dEVsZW1lbnQge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5ncm91cFRpdGxlRWxlbWVudChkYXRhR3JvdXApO1xuICAgICAgICB0aGlzLmFkZEVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBhZGRFbGVtZW50KGVsZW1lbnQ6IERhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2NvbnRlbnQucHVzaChlbGVtZW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcm93IG9mIENTUyBgZ3JpZEFyZWFJZGBzIGludG8gdGhlIGdyaWQgdGhhdCBpcyBoZWxkIGluIHRoaXMgc3ViZ3JpZC5cbiAgICAgKiBAcGFyYW0gcm93IHRoZSBmaWVsZCBJZHMuIFRoZSB3aWR0aCBvZiB0aGUgcm93IHNob3VsZCBtYXRjaCB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgb2YgdGhlIGdyaWQuIElmIG5vdCBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAgICovXG4gICAgcHVibGljIGFkZFJvdyhyb3c6IEFycmF5PHN0cmluZz4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHJvdy5sZW5ndGggIT09IHRoaXMuY29scykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgcHJvdmlkZWQgZ3JpZCBsYXlvdXQgcm93ICcke0pTT04uc3RyaW5naWZ5KHJvdylcbiAgICAgICAgICAgIH0nIGRvZXMgbm90IG1hdGNoIHRoZSBudW1iZXIgb2YgY29sdW1ucyBvZiB0aGlzIHN1YmdyaWQgKCR7dGhpcy5jb2xzfSlgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ncmlkLnB1c2gocm93KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbiBpbnRvIGRhdGEgdGhhdCBjYW4gYmUgZmVkIGludG8gQ1NTIGdyaWQgbGF5b3V0XG4gICAgICovXG4gICAgcHVibGljIGZpbmFsaXplKCkge1xuICAgICAgICB0aGlzLmZpbGxFbXB0eVNwYWNlKCk7XG4gICAgICAgIHRoaXMuY3JlYXRlR3JpZEFyZWFzU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlsbHMgZW1wdHkgdGlsZXMgaW4gdGhlIGdyaWQgd2l0aCBibGFuayBlbGVtZW50c1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBmaWxsRW1wdHlTcGFjZSgpIHtcbiAgICAgICAgY29uc3QgcnVubmluZ0JsYW5rc0NvdW50ID0gbmV3IEluY3JlbWVudGluZ0NvdW50ZXIoKTtcbiAgICAgICAgdGhpcy5fZ3JpZC5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChyb3dbaV0gIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBmaWxsZXIgPSB0aGlzLmZpbGxlckVsZW1lbnQocnVubmluZ0JsYW5rc0NvdW50KTtcbiAgICAgICAgICAgICAgICByb3dbaV0gPSBmaWxsZXIuZ3JpZEFyZWFJZDtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb250ZW50LnB1c2goZmlsbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZpZWxkIHRoZSBmaWVsZCB3aG9zZSByZXByZXNlbnRhdGlvbiBzaG91bGQgYmUgY3JlYXRlZFxuICAgICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBkYXRhIGZpZWxkXG4gICAgICogQHJldHVybnMgYW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJvdmlkZWQgZGF0YSBmaWVsZCBpbiB0aGUgbGF5b3V0XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGZpZWxkRWxlbWVudChmaWVsZDogRGF0YUZpZWxkPHVua25vd24+LCB0eXBlOiBGaWVsZFR5cGVSZXNvdXJjZSk6IERhdGFmaWVsZEdyaWRMYXlvdXRFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHtncmlkQXJlYUlkOiB0aGlzLmFzc3VyZVVuaXF1ZW5lc3MoZmllbGQuc3RyaW5nSWQpLCB0eXBlLCBpdGVtOiBmaWVsZH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZpbGxlckNvdW50ZXIgdGhlIGNvdW50ZXIgdGhhdCBpcyB1c2VkIHRvIHRyYWNrIHRoZSBudW1iZXIgb2YgYWxyZWFkeSBjcmVhdGVkIGZpbGxlciBlbGVtZW50c1xuICAgICAqIEByZXR1cm5zIGEgZmlsbGVyIGVsZW1lbnQgb2JqZWN0IHdpdGggYSB1bmlxdWUgSUQuIFRoZSBwcm92aWRlZCBjb3VudGVyIGlzIGluY3JlbWVudGVkIGJ5IG9uZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZmlsbGVyRWxlbWVudChmaWxsZXJDb3VudGVyOiBJbmNyZW1lbnRpbmdDb3VudGVyKTogRGF0YWZpZWxkR3JpZExheW91dEVsZW1lbnQge1xuICAgICAgICByZXR1cm4ge2dyaWRBcmVhSWQ6IHRoaXMuYXNzdXJlVW5pcXVlbmVzcygnYmxhbmsnICsgZmlsbGVyQ291bnRlci5uZXh0KCkpLCB0eXBlOiBUYXNrRWxlbWVudFR5cGUuQkxBTkt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBkYXRhR3JvdXAgdGhlIGRhdGEgZ3JvdXAgd2hvc2UgdGl0bGUgZWxlbWVudCBzaG91bGQgYmUgY3JlYXRlZFxuICAgICAqIEByZXR1cm5zIGFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSB0aXRsZSBlbGVtZW50IG9mIHRoZSBwcm92aWRlZCBkYXRhIGdyb3VwLiBUaGUgcHJvdmlkZWQgY291bnRlciBpcyBpbmNyZW1lbnRlZCBieSBvbmUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGdyb3VwVGl0bGVFbGVtZW50KGRhdGFHcm91cDogRGF0YUdyb3VwKTogRGF0YWZpZWxkR3JpZExheW91dEVsZW1lbnQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGl0bGU6IGRhdGFHcm91cC50aXRsZSxcbiAgICAgICAgICAgIGdyaWRBcmVhSWQ6IHRoaXMuYXNzdXJlVW5pcXVlbmVzcygnZ3JvdXAnICsgdGhpcy5fcnVubmluZ1RpdGxlQ291bnQubmV4dCgpKSxcbiAgICAgICAgICAgIHR5cGU6IFRhc2tFbGVtZW50VHlwZS5EQVRBX0dST1VQX1RJVExFXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzdXJlcyB0aGF0IHRoZSBwcm92aWRlZCBpZGVudGlmaWVyIHdpbGwgYmUgdW5pcXVlLlxuICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIHRoZSBiYXNlIGZvciB0aGUgaWRlbnRpZmllclxuICAgICAqIEByZXR1cm5zIHRoZSBiYXNlIGlkZW50aWZpZXIsIGlmIGl0IGFscmVhZHkgaXMgdW5pcXVlLiBBIHVuaXF1ZSB2YXJpYXRpb24gb24gdGhlIGJhc2UgaWRlbnRpZmllciBpZiBpdCBpcyBhbHJlYWR5IGluIHVzZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYXNzdXJlVW5pcXVlbmVzcyhpZGVudGlmaWVyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBhbHBoYU51bUlkZW50aWZpZXIgPSAneCcgKyBpZGVudGlmaWVyPy5yZXBsYWNlKC9bXjAtOWEtel0vZ2ksICcnKTtcbiAgICAgICAgaWYgKCF0aGlzLl9leGlzdGluZ0lkZW50aWZpZXJzLmhhcyhhbHBoYU51bUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB0aGlzLl9leGlzdGluZ0lkZW50aWZpZXJzLmFkZChhbHBoYU51bUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgcmV0dXJuIGFscGhhTnVtSWRlbnRpZmllcjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdmFyaWF0aW9uO1xuICAgICAgICBjb25zdCBjb3VudGVyID0gbmV3IEluY3JlbWVudGluZ0NvdW50ZXIoKTtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgdmFyaWF0aW9uID0gYHgke2NvdW50ZXIubmV4dCgpfSR7YWxwaGFOdW1JZGVudGlmaWVyfWA7XG4gICAgICAgIH0gd2hpbGUgKHRoaXMuX2V4aXN0aW5nSWRlbnRpZmllcnMuaGFzKHZhcmlhdGlvbikpO1xuICAgICAgICB0aGlzLl9leGlzdGluZ0lkZW50aWZpZXJzLmFkZCh2YXJpYXRpb24pO1xuICAgICAgICByZXR1cm4gdmFyaWF0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEpvaW5zIHRoZSBncmlkIG9mIGVsZW1lbnQgaW50byBhIHN0cmluZyBhY2NlcHRlZCBieSBgW2dkQXJlYXNdYCBpbnB1dCBwcm9wZXJ0eSBvZiBBbmd1bGFyIGZsZXggbGF5b3V0XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNyZWF0ZUdyaWRBcmVhc1N0cmluZygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5ncmlkQXJlYXMgPSB0aGlzLl9ncmlkLm1hcChyb3cgPT4gcm93LmpvaW4oJyAnKSkuam9pbignIHwgJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFya3MgYWxsIGNvbnRhaW5lZCBlbGVtZW50cyBhcyBrZXB0IGFuZCBkaXNwbGF5cyB0aGVtLlxuICAgICAqL1xuICAgIHB1YmxpYyBkaXNwbGF5QWxsRmllbGRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9rZXB0RWxlbWVudHMgPSBbLi4udGhpcy5fY29udGVudF07XG4gICAgICAgIHRoaXMuX25ld0VsZW1lbnRzID0gW107XG4gICAgICAgIHRoaXMuX3JlbmRlcmVkQ29udGVudCQubmV4dCh0aGlzLl9rZXB0RWxlbWVudHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgd2hpY2ggZWxlbWVudHMgZnJvbSB0aGUgcHJvdmlkZWQgc3ViZ3JpZCBhcmUgY29udGFpbmVkIGluIHRoaXMgc3ViZ3JpZC5cbiAgICAgKiBNYXJrcyB0aGVzZSBlbGVtZW50cyBhcyBrZXB0IGFuZCBkaXNwbGF5cyB0aGVtLiBNYXJrcyB0aGUgcmVtYWluaW5nIGVsZW1lbnRzIGFzIG5ldy5cbiAgICAgKlxuICAgICAqIE5ldyBlbGVtZW50cyBjYW4gYmUgZGlzcGxheWVkIGFzeW5jaHJvbm91c2x5IG92ZXIgdGltZSBieSBjYWxsaW5nIHRoZVxuICAgICAqIFtyZW5kZXJDb250ZW50T3ZlclRpbWVde0BsaW5rIFN1YmdyaWQjcmVuZGVyQ29udGVudE92ZXJUaW1lfSBtZXRob2QuXG4gICAgICogQHBhcmFtIHN1YmdyaWQgdGhlIFwicHJldmlvdXNcIiBzdWJncmlkIHRoYXQgaXMgdXNlZCB0byBjb21wdXRlIHRoZSBlbGVtZW50IFwiZGlmZmVyZW5jZVwiXG4gICAgICovXG4gICAgcHVibGljIGRldGVybWluZUtlcHRGaWVsZHMoc3ViZ3JpZDogU3ViZ3JpZCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9rZXB0RWxlbWVudHMgPSBbXTtcbiAgICAgICAgdGhpcy5fbmV3RWxlbWVudHMgPSBbXTtcblxuICAgICAgICB0aGlzLl9jb250ZW50LmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgICBpZiAoc3ViZ3JpZC5jb250ZW50LnNvbWUoZWwgPT4gZWwuZ3JpZEFyZWFJZCA9PT0gZWxlbWVudC5ncmlkQXJlYUlkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2tlcHRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uZXdFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnQkLm5leHQodGhpcy5fa2VwdEVsZW1lbnRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiBlbGVtZW50cyBhcmUgbm90IHNvcnRlZCBpbnRvIG5ldyBhbmQga2VwdCwgbWFya3MgYWxsIGVsZW1lbnRzIGFzIG5ldy5cbiAgICAgKiBUaGUgW2RldGVybWluZUtlcHRGaWVsZHNde0BsaW5rIFN1YmdyaWQjZGV0ZXJtaW5lS2VwdEZpZWxkc30gbWV0aG9kIGNhbiBiZSB1c2VkIHRvIG1hcmsgZWxlbWVudHMgYXMga2VwdC5cbiAgICAgKlxuICAgICAqIFRoZW4gcHVzaGVzIHRoZSBuZXcgZWxlbWVudHMgd2l0aCB0aGUga2VwdCBlbGVtZW50cyBpbnRvIHRoZSBvdXRwdXQgYXJyYXkgb3ZlciB0aW1lIGFzIHNwZWNpZmllZCBieSB0aGVcbiAgICAgKiB7QGxpbmsgQXN5bmNSZW5kZXJpbmdDb25maWd1cmF0aW9ufSBwcm92aWRlZCBpbiB0aGUgc3ViZ3JpZHMgY29uc3RydWN0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgdGhlIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIG9uY2UgYWxsIG5ldyBlbGVtZW50cyB3ZXJlIHB1c2hlZCBpbnRvIHRoZSBvdXRwdXQgYXJyYXlcbiAgICAgKiBAcGFyYW0gZmlyc3Qgd2hldGhlciB0aGlzIGlzIHRoZSBmaXJzdCBzdWJncmlkIHRoYXQgc2kgcmVuZGVyZWQuIElmIHRoaXMgaXMgdGhlIGZpcnN0IHN1YmdyaWQgdGhlbiBvbiB0aGUgaW5pdGlhbCByZW5kZXJpbmcgb2ZcbiAgICAgKiBlbGVtZW50cyBhIGJhdGNoIG9mIG5ldyBmaWVsZHMgYWxvbmdzaWRlIHRoZSBsb2FkZXIgZWxlbWVudHMgaXMgZGlzcGxheWVkIHNvIHRoYXQgc29tZSBjb250ZW50IGlzIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS5cbiAgICAgKiBPdGhlcndpc2UgVGhlIGluaXRpYWwgYmF0Y2ggY29udGFpbnMgb25seSBsb2FkZXIgZWxlbWVudHMuIEJlaW5nIGZpcnN0IGVmZmVjdGl2ZWx5IHNob3J0ZW5zIHRoZSByZW5kZXJpbmcgYnkgb25lIGJhdGNoLCBzaW5jZSB0aGVcbiAgICAgKiBmaXJzdCBsb2FkZXItb25seSBiYXRjaCBpcyBza2lwcGVkLlxuICAgICAqL1xuICAgIHB1YmxpYyByZW5kZXJDb250ZW50T3ZlclRpbWUoY2FsbGJhY2s6ICgpID0+IHZvaWQsIGZpcnN0PSBmYWxzZSkge1xuICAgICAgICBpZiAodGhpcy5fbmV3RWxlbWVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fbmV3RWxlbWVudHMgPSBBcnJheS5mcm9tKHRoaXMuX2NvbnRlbnQpO1xuICAgICAgICAgICAgdGhpcy5fa2VwdEVsZW1lbnRzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zcHJlYWRGaWVsZFJlbmRlcmluZ092ZXJUaW1lKGNhbGxiYWNrLCBmaXJzdCA/IDEgOiAwKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3ByZWFkRmllbGRSZW5kZXJpbmdPdmVyVGltZShjYWxsYmFjazogKCkgPT4gdm9pZCwgaXRlcmF0aW9uID0gMCkge1xuICAgICAgICB0aGlzLl9hc3luY1JlbmRlcmluZ1RpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGZpZWxkc0luQ3VycmVudEl0ZXJhdGlvbiA9IHRoaXMuX25ld0VsZW1lbnRzLnNsaWNlKDAsIGl0ZXJhdGlvbiAqIHRoaXMuX2FzeW5jUmVuZGVyaW5nQ29uZmlnLmJhdGNoU2l6ZSk7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyc0luQ3VycmVudEl0ZXJhdGlvbiA9IHRoaXMuX25ld0VsZW1lbnRzLnNsaWNlKGl0ZXJhdGlvbiAqIHRoaXMuX2FzeW5jUmVuZGVyaW5nQ29uZmlnLmJhdGNoU2l6ZSxcbiAgICAgICAgICAgIGl0ZXJhdGlvbiAqIHRoaXMuX2FzeW5jUmVuZGVyaW5nQ29uZmlnLmJhdGNoU2l6ZSArIHRoaXMuX2FzeW5jUmVuZGVyaW5nQ29uZmlnLm51bWJlck9mUGxhY2Vob2xkZXJzKTtcblxuICAgICAgICBmaWVsZHNJbkN1cnJlbnRJdGVyYXRpb24ucHVzaChcbiAgICAgICAgICAgIC4uLnBsYWNlaG9sZGVyc0luQ3VycmVudEl0ZXJhdGlvbi5tYXAoZmllbGQgPT4gKHtncmlkQXJlYUlkOiBmaWVsZC5ncmlkQXJlYUlkLCB0eXBlOiBUYXNrRWxlbWVudFR5cGUuTE9BREVSfSkpKTtcblxuICAgICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnQkLm5leHQoWy4uLnRoaXMuX2tlcHRFbGVtZW50cywgLi4uZmllbGRzSW5DdXJyZW50SXRlcmF0aW9uXSk7XG4gICAgICAgIGlmICh0aGlzLl9hc3luY1JlbmRlcmluZ0NvbmZpZy5iYXRjaFNpemUgKiBpdGVyYXRpb24gPCB0aGlzLl9uZXdFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuX2FzeW5jUmVuZGVyaW5nVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwcmVhZEZpZWxkUmVuZGVyaW5nT3ZlclRpbWUoY2FsbGJhY2ssIGl0ZXJhdGlvbiArIDEpO1xuICAgICAgICAgICAgfSwgdGhpcy5fYXN5bmNSZW5kZXJpbmdDb25maWcuYmF0Y2hEZWxheSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19