UNPKG

ng-table-virtual-scroll

Version:
221 lines 33.5 kB
import { VIRTUAL_SCROLL_STRATEGY } from '@angular/cdk/scrolling'; import { CdkTable } from '@angular/cdk/table'; import { ContentChild, Directive, forwardRef, Input } from '@angular/core'; import { combineLatest, from, Subject } from 'rxjs'; import { delayWhen, distinctUntilChanged, map, startWith, switchMap, take, takeUntil, tap } from 'rxjs/operators'; import { FixedSizeTableVirtualScrollStrategy } from './fixed-size-table-virtual-scroll-strategy'; import { CdkTableVirtualScrollDataSource, isTVSDataSource, TableVirtualScrollDataSource } from './table-data-source'; import * as i0 from "@angular/core"; export function _tableVirtualScrollDirectiveStrategyFactory(tableDir) { return tableDir.scrollStrategy; } function combineSelectors(...pairs) { return pairs.map((selectors) => `${selectors.join(' ')}, ${selectors.join('')}`).join(', '); } const stickyHeaderSelector = combineSelectors(['.mat-mdc-header-row', '.mat-mdc-table-sticky'], ['.mat-header-row', '.mat-table-sticky'], ['.cdk-header-row', '.cdk-table-sticky']); const stickyFooterSelector = combineSelectors(['.mat-mdc-footer-row', '.mat-mdc-table-sticky'], ['.mat-footer-row', '.mat-table-sticky'], ['.cdk-footer-row', '.cdk-table-sticky']); function isMatTable(table) { return table instanceof CdkTable && table['stickyCssClass'].includes('mat'); } function isCdkTable(table) { return table instanceof CdkTable && table['stickyCssClass'].includes('cdk'); } const defaults = { rowHeight: 48, headerHeight: 56, headerEnabled: true, footerHeight: 48, footerEnabled: false, bufferMultiplier: 0.7 }; export class TableItemSizeDirective { constructor(zone) { this.zone = zone; this.destroyed$ = new Subject(); // eslint-disable-next-line @angular-eslint/no-input-rename this.rowHeight = defaults.rowHeight; this.headerEnabled = defaults.headerEnabled; this.headerHeight = defaults.headerHeight; this.footerEnabled = defaults.footerEnabled; this.footerHeight = defaults.footerHeight; this.bufferMultiplier = defaults.bufferMultiplier; this.scrollStrategy = new FixedSizeTableVirtualScrollStrategy(); this.dataSourceChanges = new Subject(); this.resetStickyPositions = new Subject(); this.stickyEnabled = { header: false, footer: false }; } ngOnDestroy() { this.destroyed$.next(); this.destroyed$.complete(); this.dataSourceChanges.complete(); } ngAfterContentInit() { const switchDataSourceOrigin = this.table['_switchDataSource']; this.table['_switchDataSource'] = (dataSource) => { switchDataSourceOrigin.call(this.table, dataSource); this.connectDataSource(dataSource); }; const updateStickyColumnStylesOrigin = this.table.updateStickyColumnStyles; this.table.updateStickyColumnStyles = () => { const stickyColumnStylesNeedReset = this.table['_stickyColumnStylesNeedReset']; updateStickyColumnStylesOrigin.call(this.table); if (stickyColumnStylesNeedReset) { this.resetStickyPositions.next(); } }; this.connectDataSource(this.table.dataSource); combineLatest([ this.scrollStrategy.stickyChange, this.resetStickyPositions.pipe(startWith(void 0), delayWhen(() => this.getScheduleObservable()), tap(() => { this.stickyPositions = null; })) ]) .pipe(takeUntil(this.destroyed$)) .subscribe(([stickyOffset]) => { if (!this.stickyPositions) { this.initStickyPositions(); } if (this.stickyEnabled.header) { this.setStickyHeader(stickyOffset); } if (this.stickyEnabled.footer) { this.setStickyFooter(stickyOffset); } }); } connectDataSource(dataSource) { this.dataSourceChanges.next(); if (!isTVSDataSource(dataSource)) { throw new Error('[tvsItemSize] requires TableVirtualScrollDataSource or CdkTableVirtualScrollDataSource be set as [dataSource] of the table'); } if (isMatTable(this.table) && !(dataSource instanceof TableVirtualScrollDataSource)) { throw new Error('[tvsItemSize] requires TableVirtualScrollDataSource be set as [dataSource] of [mat-table]'); } if (isCdkTable(this.table) && !(dataSource instanceof CdkTableVirtualScrollDataSource)) { throw new Error('[tvsItemSize] requires CdkTableVirtualScrollDataSource be set as [dataSource] of [cdk-table]'); } dataSource .dataToRender$ .pipe(distinctUntilChanged(), takeUntil(this.dataSourceChanges), takeUntil(this.destroyed$), tap(data => this.scrollStrategy.dataLength = data.length), switchMap(data => this.scrollStrategy .renderedRangeStream .pipe(map(({ start, end }) => typeof start !== 'number' || typeof end !== 'number' ? data : data.slice(start, end))))) .subscribe(data => { this.zone.run(() => { dataSource.dataOfRange$.next(data); }); }); } ngOnChanges() { const config = { rowHeight: +this.rowHeight || defaults.rowHeight, headerHeight: this.headerEnabled ? +this.headerHeight || defaults.headerHeight : 0, footerHeight: this.footerEnabled ? +this.footerHeight || defaults.footerHeight : 0, bufferMultiplier: +this.bufferMultiplier || defaults.bufferMultiplier }; this.scrollStrategy.setConfig(config); } setStickyEnabled() { if (!this.scrollStrategy.viewport) { this.stickyEnabled = { header: false, footer: false }; return; } const isEnabled = (rowDefs) => rowDefs .map(def => def.sticky) .reduce((prevState, state) => prevState && state, true); this.stickyEnabled = { header: isEnabled(this.table['_headerRowDefs']), footer: isEnabled(this.table['_footerRowDefs']), }; } setStickyHeader(offset) { this.scrollStrategy.viewport.elementRef.nativeElement.querySelectorAll(stickyHeaderSelector) .forEach((el) => { const parent = el.parentElement; let baseOffset = 0; if (this.stickyPositions.has(parent)) { baseOffset = this.stickyPositions.get(parent); } el.style.top = `${baseOffset - offset}px`; }); } setStickyFooter(offset) { this.scrollStrategy.viewport.elementRef.nativeElement.querySelectorAll(stickyFooterSelector) .forEach((el) => { const parent = el.parentElement; let baseOffset = 0; if (this.stickyPositions.has(parent)) { baseOffset = this.stickyPositions.get(parent); } el.style.bottom = `${-baseOffset + offset}px`; }); } initStickyPositions() { this.stickyPositions = new Map(); this.setStickyEnabled(); if (this.stickyEnabled.header) { this.scrollStrategy.viewport.elementRef.nativeElement.querySelectorAll(stickyHeaderSelector) .forEach(el => { const parent = el.parentElement; if (!this.stickyPositions.has(parent)) { this.stickyPositions.set(parent, parent.offsetTop); } }); } if (this.stickyEnabled.footer) { this.scrollStrategy.viewport.elementRef.nativeElement.querySelectorAll(stickyFooterSelector) .forEach(el => { const parent = el.parentElement; if (!this.stickyPositions.has(parent)) { this.stickyPositions.set(parent, -parent.offsetTop); } }); } } getScheduleObservable() { // Use onStable when in the context of an ongoing change detection cycle so that we // do not accidentally trigger additional cycles. return this.zone.isStable ? from(Promise.resolve(undefined)) : this.zone.onStable.pipe(take(1)); } } TableItemSizeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TableItemSizeDirective, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); TableItemSizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: TableItemSizeDirective, selector: "cdk-virtual-scroll-viewport[tvsItemSize]", inputs: { rowHeight: ["tvsItemSize", "rowHeight"], headerEnabled: "headerEnabled", headerHeight: "headerHeight", footerEnabled: "footerEnabled", footerHeight: "footerHeight", bufferMultiplier: "bufferMultiplier" }, providers: [{ provide: VIRTUAL_SCROLL_STRATEGY, useFactory: _tableVirtualScrollDirectiveStrategyFactory, deps: [forwardRef(() => TableItemSizeDirective)] }], queries: [{ propertyName: "table", first: true, predicate: CdkTable, descendants: true }], usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TableItemSizeDirective, decorators: [{ type: Directive, args: [{ selector: 'cdk-virtual-scroll-viewport[tvsItemSize]', providers: [{ provide: VIRTUAL_SCROLL_STRATEGY, useFactory: _tableVirtualScrollDirectiveStrategyFactory, deps: [forwardRef(() => TableItemSizeDirective)] }] }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { rowHeight: [{ type: Input, args: ['tvsItemSize'] }], headerEnabled: [{ type: Input }], headerHeight: [{ type: Input }], footerEnabled: [{ type: Input }], footerHeight: [{ type: Input }], bufferMultiplier: [{ type: Input }], table: [{ type: ContentChild, args: [CdkTable, { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtaXRlbS1zaXplLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhYmxlLXZpcnR1YWwtc2Nyb2xsL3NyYy9saWIvdGFibGUtaXRlbS1zaXplLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQVksUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxFQUVMLFlBQVksRUFDWixTQUFTLEVBQ1QsVUFBVSxFQUNWLEtBQUssRUFJTixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xILE9BQU8sRUFBRSxtQ0FBbUMsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQ2pHLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxlQUFlLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7QUFFckgsTUFBTSxVQUFVLDJDQUEyQyxDQUFDLFFBQWdDO0lBQzFGLE9BQU8sUUFBUSxDQUFDLGNBQWMsQ0FBQztBQUNqQyxDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFHLEtBQWlCO0lBQzVDLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENB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cnQgeyBWSVJUVUFMX1NDUk9MTF9TVFJBVEVHWSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHsgQ2FuU3RpY2ssIENka1RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3RhYmxlJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRGlyZWN0aXZlLFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1hdFRhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCwgZnJvbSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXlXaGVuLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBGaXhlZFNpemVUYWJsZVZpcnR1YWxTY3JvbGxTdHJhdGVneSB9IGZyb20gJy4vZml4ZWQtc2l6ZS10YWJsZS12aXJ0dWFsLXNjcm9sbC1zdHJhdGVneSc7XG5pbXBvcnQgeyBDZGtUYWJsZVZpcnR1YWxTY3JvbGxEYXRhU291cmNlLCBpc1RWU0RhdGFTb3VyY2UsIFRhYmxlVmlydHVhbFNjcm9sbERhdGFTb3VyY2UgfSBmcm9tICcuL3RhYmxlLWRhdGEtc291cmNlJztcblxuZXhwb3J0IGZ1bmN0aW9uIF90YWJsZVZpcnR1YWxTY3JvbGxEaXJlY3RpdmVTdHJhdGVneUZhY3RvcnkodGFibGVEaXI6IFRhYmxlSXRlbVNpemVEaXJlY3RpdmUpIHtcbiAgcmV0dXJuIHRhYmxlRGlyLnNjcm9sbFN0cmF0ZWd5O1xufVxuXG5mdW5jdGlvbiBjb21iaW5lU2VsZWN0b3JzKC4uLnBhaXJzOiBzdHJpbmdbXVtdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhaXJzLm1hcCgoc2VsZWN0b3JzKSA9PiBgJHtzZWxlY3RvcnMuam9pbignICcpfSwgJHtzZWxlY3RvcnMuam9pbignJyl9YCkuam9pbignLCAnKTtcbn1cblxuY29uc3Qgc3RpY2t5SGVhZGVyU2VsZWN0b3IgPSBjb21iaW5lU2VsZWN0b3JzKFxuICBbJy5tYXQtbWRjLWhlYWRlci1yb3cnLCAnLm1hdC1tZGMtdGFibGUtc3RpY2t5J10sXG4gIFsnLm1hdC1oZWFkZXItcm93JywgJy5tYXQtdGFibGUtc3RpY2t5J10sXG4gIFsnLmNkay1oZWFkZXItcm93JywgJy5jZGstdGFibGUtc3RpY2t5J11cbik7XG5cbmNvbnN0IHN0aWNreUZvb3RlclNlbGVjdG9yID0gY29tYmluZVNlbGVjdG9ycyhcbiAgWycubWF0LW1kYy1mb290ZXItcm93JywgJy5tYXQtbWRjLXRhYmxlLXN0aWNreSddLFxuICBbJy5tYXQtZm9vdGVyLXJvdycsICcubWF0LXRhYmxlLXN0aWNreSddLFxuICBbJy5jZGstZm9vdGVyLXJvdycsICcuY2RrLXRhYmxlLXN0aWNreSddXG4pO1xuXG5mdW5jdGlvbiBpc01hdFRhYmxlPFQ+KHRhYmxlOiB1bmtub3duKTogdGFibGUgaXMgTWF0VGFibGU8VD4ge1xuICByZXR1cm4gdGFibGUgaW5zdGFuY2VvZiBDZGtUYWJsZSAmJiB0YWJsZVsnc3RpY2t5Q3NzQ2xhc3MnXS5pbmNsdWRlcygnbWF0Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQ2RrVGFibGU8VD4odGFibGU6IHVua25vd24pOiB0YWJsZSBpcyBDZGtUYWJsZTxUPiB7XG4gIHJldHVybiB0YWJsZSBpbnN0YW5jZW9mIENka1RhYmxlICYmIHRhYmxlWydzdGlja3lDc3NDbGFzcyddLmluY2x1ZGVzKCdjZGsnKTtcbn1cblxuY29uc3QgZGVmYXVsdHMgPSB7XG4gIHJvd0hlaWdodDogNDgsXG4gIGhlYWRlckhlaWdodDogNTYsXG4gIGhlYWRlckVuYWJsZWQ6IHRydWUsXG4gIGZvb3RlckhlaWdodDogNDgsXG4gIGZvb3RlckVuYWJsZWQ6IGZhbHNlLFxuICBidWZmZXJNdWx0aXBsaWVyOiAwLjdcbn07XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFt0dnNJdGVtU2l6ZV0nLFxuICBwcm92aWRlcnM6IFt7XG4gICAgcHJvdmlkZTogVklSVFVBTF9TQ1JPTExfU1RSQVRFR1ksXG4gICAgdXNlRmFjdG9yeTogX3RhYmxlVmlydHVhbFNjcm9sbERpcmVjdGl2ZVN0cmF0ZWd5RmFjdG9yeSxcbiAgICBkZXBzOiBbZm9yd2FyZFJlZigoKSA9PiBUYWJsZUl0ZW1TaXplRGlyZWN0aXZlKV1cbiAgfV1cbn0pXG5leHBvcnQgY2xhc3MgVGFibGVJdGVtU2l6ZURpcmVjdGl2ZTxUID0gdW5rbm93bj4gaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1pbnB1dC1yZW5hbWVcbiAgQElucHV0KCd0dnNJdGVtU2l6ZScpXG4gIHJvd0hlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMucm93SGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGhlYWRlckVuYWJsZWQ6IGJvb2xlYW4gPSBkZWZhdWx0cy5oZWFkZXJFbmFibGVkO1xuXG4gIEBJbnB1dCgpXG4gIGhlYWRlckhlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMuaGVhZGVySGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGZvb3RlckVuYWJsZWQ6IGJvb2xlYW4gPSBkZWZhdWx0cy5mb290ZXJFbmFibGVkO1xuXG4gIEBJbnB1dCgpXG4gIGZvb3RlckhlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMuZm9vdGVySGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGJ1ZmZlck11bHRpcGxpZXI6IHN0cmluZyB8IG51bWJlciA9IGRlZmF1bHRzLmJ1ZmZlck11bHRpcGxpZXI7XG5cbiAgQENvbnRlbnRDaGlsZChDZGtUYWJsZSwgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHRhYmxlOiBDZGtUYWJsZTxUPjtcblxuICBzY3JvbGxTdHJhdGVneSA9IG5ldyBGaXhlZFNpemVUYWJsZVZpcnR1YWxTY3JvbGxTdHJhdGVneSgpO1xuXG4gIGRhdGFTb3VyY2VDaGFuZ2VzID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIHN0aWNreVBvc2l0aW9uczogTWFwPEhUTUxFbGVtZW50LCBudW1iZXI+O1xuICBwcml2YXRlIHJlc2V0U3RpY2t5UG9zaXRpb25zID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBzdGlja3lFbmFibGVkID0ge1xuICAgIGhlYWRlcjogZmFsc2UsXG4gICAgZm9vdGVyOiBmYWxzZVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogTmdab25lKSB7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3llZCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveWVkJC5jb21wbGV0ZSgpO1xuICAgIHRoaXMuZGF0YVNvdXJjZUNoYW5nZXMuY29tcGxldGUoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICBjb25zdCBzd2l0Y2hEYXRhU291cmNlT3JpZ2luID0gdGhpcy50YWJsZVsnX3N3aXRjaERhdGFTb3VyY2UnXTtcbiAgICB0aGlzLnRhYmxlWydfc3dpdGNoRGF0YVNvdXJjZSddID0gKGRhdGFTb3VyY2U6IGFueSkgPT4ge1xuICAgICAgc3dpdGNoRGF0YVNvdXJjZU9yaWdpbi5jYWxsKHRoaXMudGFibGUsIGRhdGFTb3VyY2UpO1xuICAgICAgdGhpcy5jb25uZWN0RGF0YVNvdXJjZShkYXRhU291cmNlKTtcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlU3RpY2t5Q29sdW1uU3R5bGVzT3JpZ2luID0gdGhpcy50YWJsZS51cGRhdGVTdGlja3lDb2x1bW5TdHlsZXM7XG4gICAgdGhpcy50YWJsZS51cGRhdGVTdGlja3lDb2x1bW5TdHlsZXMgPSAoKSA9PiB7XG4gICAgICBjb25zdCBzdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQgPSB0aGlzLnRhYmxlWydfc3RpY2t5Q29sdW1uU3R5bGVzTmVlZFJlc2V0J107XG4gICAgICB1cGRhdGVTdGlja3lDb2x1bW5TdHlsZXNPcmlnaW4uY2FsbCh0aGlzLnRhYmxlKTtcbiAgICAgIGlmIChzdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQpIHtcbiAgICAgICAgdGhpcy5yZXNldFN0aWNreVBvc2l0aW9ucy5uZXh0KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuY29ubmVjdERhdGFTb3VyY2UodGhpcy50YWJsZS5kYXRhU291cmNlKTtcblxuICAgIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5zY3JvbGxTdHJhdGVneS5zdGlja3lDaGFuZ2UsXG4gICAgICB0aGlzLnJlc2V0U3RpY2t5UG9zaXRpb25zLnBpcGUoXG4gICAgICAgIHN0YXJ0V2l0aCh2b2lkIDApLFxuICAgICAgICBkZWxheVdoZW4oKCkgPT4gdGhpcy5nZXRTY2hlZHVsZU9ic2VydmFibGUoKSksXG4gICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zdGlja3lQb3NpdGlvbnMgPSBudWxsO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgIF0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKFtzdGlja3lPZmZzZXRdKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5zdGlja3lQb3NpdGlvbnMpIHtcbiAgICAgICAgICB0aGlzLmluaXRTdGlja3lQb3NpdGlvbnMoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdGlja3lFbmFibGVkLmhlYWRlcikge1xuICAgICAgICAgIHRoaXMuc2V0U3RpY2t5SGVhZGVyKHN0aWNreU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RpY2t5RW5hYmxlZC5mb290ZXIpIHtcbiAgICAgICAgICB0aGlzLnNldFN0aWNreUZvb3RlcihzdGlja3lPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3REYXRhU291cmNlKGRhdGFTb3VyY2U6IHVua25vd24pIHtcbiAgICB0aGlzLmRhdGFTb3VyY2VDaGFuZ2VzLm5leHQoKTtcbiAgICBpZiAoIWlzVFZTRGF0YVNvdXJjZShkYXRhU291cmNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdHZzSXRlbVNpemVdIHJlcXVpcmVzIFRhYmxlVmlydHVhbFNjcm9sbERhdGFTb3VyY2Ugb3IgQ2RrVGFibGVWaXJ0dWFsU2Nyb2xsRGF0YVNvdXJjZSBiZSBzZXQgYXMgW2RhdGFTb3VyY2VdIG9mIHRoZSB0YWJsZScpO1xuICAgIH1cbiAgICBpZiAoaXNNYXRUYWJsZSh0aGlzLnRhYmxlKSAmJiAhKGRhdGFTb3VyY2UgaW5zdGFuY2VvZiBUYWJsZVZpcnR1YWxTY3JvbGxEYXRhU291cmNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdHZzSXRlbVNpemVdIHJlcXVpcmVzIFRhYmxlVmlydHVhbFNjcm9sbERhdGFTb3VyY2UgYmUgc2V0IGFzIFtkYXRhU291cmNlXSBvZiBbbWF0LXRhYmxlXScpO1xuICAgIH1cbiAgICBpZiAoaXNDZGtUYWJsZSh0aGlzLnRhYmxlKSAmJiAhKGRhdGFTb3VyY2UgaW5zdGFuY2VvZiBDZGtUYWJsZVZpcnR1YWxTY3JvbGxEYXRhU291cmNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdHZzSXRlbVNpemVdIHJlcXVpcmVzIENka1RhYmxlVmlydHVhbFNjcm9sbERhdGFTb3VyY2UgYmUgc2V0IGFzIFtkYXRhU291cmNlXSBvZiBbY2RrLXRhYmxlXScpO1xuICAgIH1cblxuICAgIGRhdGFTb3VyY2VcbiAgICAgIC5kYXRhVG9SZW5kZXIkXG4gICAgICAucGlwZShcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGF0YVNvdXJjZUNoYW5nZXMpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKSxcbiAgICAgICAgdGFwKGRhdGEgPT4gdGhpcy5zY3JvbGxTdHJhdGVneS5kYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgpLFxuICAgICAgICBzd2l0Y2hNYXAoZGF0YSA9PlxuICAgICAgICAgIHRoaXMuc2Nyb2xsU3RyYXRlZ3lcbiAgICAgICAgICAgIC5yZW5kZXJlZFJhbmdlU3RyZWFtXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgbWFwKCh7XG4gICAgICAgICAgICAgICAgICAgICBzdGFydCxcbiAgICAgICAgICAgICAgICAgICAgIGVuZFxuICAgICAgICAgICAgICAgICAgIH0pID0+IHR5cGVvZiBzdGFydCAhPT0gJ251bWJlcicgfHwgdHlwZW9mIGVuZCAhPT0gJ251bWJlcicgPyBkYXRhIDogZGF0YS5zbGljZShzdGFydCwgZW5kKSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgZGF0YVNvdXJjZS5kYXRhT2ZSYW5nZSQubmV4dChkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIHJvd0hlaWdodDogK3RoaXMucm93SGVpZ2h0IHx8IGRlZmF1bHRzLnJvd0hlaWdodCxcbiAgICAgIGhlYWRlckhlaWdodDogdGhpcy5oZWFkZXJFbmFibGVkID8gK3RoaXMuaGVhZGVySGVpZ2h0IHx8IGRlZmF1bHRzLmhlYWRlckhlaWdodCA6IDAsXG4gICAgICBmb290ZXJIZWlnaHQ6IHRoaXMuZm9vdGVyRW5hYmxlZCA/ICt0aGlzLmZvb3RlckhlaWdodCB8fCBkZWZhdWx0cy5mb290ZXJIZWlnaHQgOiAwLFxuICAgICAgYnVmZmVyTXVsdGlwbGllcjogK3RoaXMuYnVmZmVyTXVsdGlwbGllciB8fCBkZWZhdWx0cy5idWZmZXJNdWx0aXBsaWVyXG4gICAgfTtcbiAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnNldENvbmZpZyhjb25maWcpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdGlja3lFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5zY3JvbGxTdHJhdGVneS52aWV3cG9ydCkge1xuICAgICAgdGhpcy5zdGlja3lFbmFibGVkID0ge1xuICAgICAgICBoZWFkZXI6IGZhbHNlLFxuICAgICAgICBmb290ZXI6IGZhbHNlXG4gICAgICB9O1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzRW5hYmxlZCA9IChyb3dEZWZzOiBDYW5TdGlja1tdKSA9PiByb3dEZWZzXG4gICAgICAubWFwKGRlZiA9PiBkZWYuc3RpY2t5KVxuICAgICAgLnJlZHVjZSgocHJldlN0YXRlLCBzdGF0ZSkgPT4gcHJldlN0YXRlICYmIHN0YXRlLCB0cnVlKTtcblxuICAgIHRoaXMuc3RpY2t5RW5hYmxlZCA9IHtcbiAgICAgIGhlYWRlcjogaXNFbmFibGVkKHRoaXMudGFibGVbJ19oZWFkZXJSb3dEZWZzJ10pLFxuICAgICAgZm9vdGVyOiBpc0VuYWJsZWQodGhpcy50YWJsZVsnX2Zvb3RlclJvd0RlZnMnXSksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RpY2t5SGVhZGVyKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy5zY3JvbGxTdHJhdGVneS52aWV3cG9ydC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzdGlja3lIZWFkZXJTZWxlY3RvcilcbiAgICAgIC5mb3JFYWNoKChlbDogSFRNTEVsZW1lbnQpID0+IHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgICAgbGV0IGJhc2VPZmZzZXQgPSAwO1xuICAgICAgICBpZiAodGhpcy5zdGlja3lQb3NpdGlvbnMuaGFzKHBhcmVudCkpIHtcbiAgICAgICAgICBiYXNlT2Zmc2V0ID0gdGhpcy5zdGlja3lQb3NpdGlvbnMuZ2V0KHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWwuc3R5bGUudG9wID0gYCR7YmFzZU9mZnNldCAtIG9mZnNldH1weGA7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RpY2t5Rm9vdGVyKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy5zY3JvbGxTdHJhdGVneS52aWV3cG9ydC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzdGlja3lGb290ZXJTZWxlY3RvcilcbiAgICAgIC5mb3JFYWNoKChlbDogSFRNTEVsZW1lbnQpID0+IHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgICAgbGV0IGJhc2VPZmZzZXQgPSAwO1xuICAgICAgICBpZiAodGhpcy5zdGlja3lQb3NpdGlvbnMuaGFzKHBhcmVudCkpIHtcbiAgICAgICAgICBiYXNlT2Zmc2V0ID0gdGhpcy5zdGlja3lQb3NpdGlvbnMuZ2V0KHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWwuc3R5bGUuYm90dG9tID0gYCR7LWJhc2VPZmZzZXQgKyBvZmZzZXR9cHhgO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRTdGlja3lQb3NpdGlvbnMoKSB7XG4gICAgdGhpcy5zdGlja3lQb3NpdGlvbnMgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBudW1iZXI+KCk7XG5cbiAgICB0aGlzLnNldFN0aWNreUVuYWJsZWQoKTtcblxuICAgIGlmICh0aGlzLnN0aWNreUVuYWJsZWQuaGVhZGVyKSB7XG4gICAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnZpZXdwb3J0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHN0aWNreUhlYWRlclNlbGVjdG9yKVxuICAgICAgICAuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgY29uc3QgcGFyZW50ID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RpY2t5UG9zaXRpb25zLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnN0aWNreVBvc2l0aW9ucy5zZXQocGFyZW50LCBwYXJlbnQub2Zmc2V0VG9wKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0aWNreUVuYWJsZWQuZm9vdGVyKSB7XG4gICAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnZpZXdwb3J0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHN0aWNreUZvb3RlclNlbGVjdG9yKVxuICAgICAgICAuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgY29uc3QgcGFyZW50ID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RpY2t5UG9zaXRpb25zLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnN0aWNreVBvc2l0aW9ucy5zZXQocGFyZW50LCAtcGFyZW50Lm9mZnNldFRvcCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuXG4gIHByaXZhdGUgZ2V0U2NoZWR1bGVPYnNlcnZhYmxlKCkge1xuICAgIC8vIFVzZSBvblN0YWJsZSB3aGVuIGluIHRoZSBjb250ZXh0IG9mIGFuIG9uZ29pbmcgY2hhbmdlIGRldGVjdGlvbiBjeWNsZSBzbyB0aGF0IHdlXG4gICAgLy8gZG8gbm90IGFjY2lkZW50YWxseSB0cmlnZ2VyIGFkZGl0aW9uYWwgY3ljbGVzLlxuICAgIHJldHVybiB0aGlzLnpvbmUuaXNTdGFibGVcbiAgICAgID8gZnJvbShQcm9taXNlLnJlc29sdmUodW5kZWZpbmVkKSlcbiAgICAgIDogdGhpcy56b25lLm9uU3RhYmxlLnBpcGUodGFrZSgxKSk7XG4gIH1cbn1cbiJdfQ==