UNPKG

@dimkel/ng-cdk-table-virtual-scroll

Version:
215 lines 32.1 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, startWith, switchMap, take, takeUntil, tap } from 'rxjs/operators'; import { FixedSizeTableVirtualScrollStrategy } from './fixed-size-table-virtual-scroll-strategy'; import { 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']); 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 (dataSource instanceof TableVirtualScrollDataSource) { const tvsDataSource = dataSource; tvsDataSource.dataToRender$ .pipe(distinctUntilChanged(), takeUntil(this.dataSourceChanges), takeUntil(this.destroyed$), tap(data => this.scrollStrategy.dataLength = data.length), switchMap(() => this.scrollStrategy.renderedRangeStream), takeUntil(this.destroyed$)) .subscribe(({ start, end }) => { const data = tvsDataSource.data.slice(start, end); tvsDataSource.dataOfRange$.next(data); }); } else { throw new Error('[tvsItemSize] requires TableVirtualScrollDataSource be set as [dataSource] of [cdk-table]'); } } ngOnChanges() { const viewportHeight = this.visibleRowsCount ? this.visibleRowsCount * (+this.rowHeight || defaults.rowHeight) : undefined; 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); if (viewportHeight && this.scrollStrategy.viewport) { this.scrollStrategy.viewport.elementRef.nativeElement.style.height = `${viewportHeight}px`; this.scrollStrategy.viewport.checkViewportSize(); } } 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", visibleRowsCount: "visibleRowsCount" }, 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 }], visibleRowsCount: [{ type: Input }], table: [{ type: ContentChild, args: [CdkTable, { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtaXRlbS1zaXplLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhYmxlLXZpcnR1YWwtc2Nyb2xsL3NyYy9saWIvdGFibGUtaXRlbS1zaXplLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQVksUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxFQUVMLFlBQVksRUFDWixTQUFTLEVBQ1QsVUFBVSxFQUNWLEtBQUssRUFJTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0csT0FBTyxFQUFFLG1DQUFtQyxFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDakcsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBRW5FLE1BQU0sVUFBVSwyQ0FBMkMsQ0FBQyxRQUFnQztJQUMxRixPQUFPLFFBQVEsQ0FBQyxjQUFjLENBQUM7QUFDakMsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsR0FBRyxLQUFpQjtJQUM1QyxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDOUYsQ0FBQztBQUVELE1BQU0sb0JBQW9CLEdBQUcsZ0JBQWdCLENBQzNDLENBQUMscUJBQXFCLEVBQUUsdUJBQXVCLENBQUMsRUFDaEQsQ0FBQyxpQkFBaUIsRUFBRSxtQkFBbUIsQ0FBQyxFQUN4QyxDQUFDLGlCQUFpQixFQUFFLG1CQUFtQixDQUFDLENBQ3pDLENBQUM7QUFFRixNQUFNLG9CQUFvQixHQUFHLGdCQUFnQixDQUMzQyxDQUFDLHFCQUFxQixFQUFFLHVCQUF1QixDQUFDLEVBQ2hELENBQUMsaUJBQWlCLEVBQUUsbUJBQW1CLENBQUMsRUFDeEMsQ0FBQyxpQkFBaUIsRUFBRSxtQkFBbUIsQ0FBQyxDQUN6QyxDQUFDO0FBRUYsTUFBTSxRQUFRLEdBQUc7SUFDZixTQUFTLEVBQUUsRUFBRTtJQUNiLFlBQVksRUFBRSxFQUFFO0lBQ2hCLGFBQWEsRUFBRSxJQUFJO0lBQ25CLFlBQVksRUFBRSxFQUFFO0lBQ2hCLGFBQWEsRUFBRSxLQUFLO0lBQ3BCLGdCQUFnQixFQUFFLEdBQUc7Q0FDdEIsQ0FBQztBQVVGLE1BQU0sT0FBTyxzQkFBc0I7SUF1Q2pDLFlBQW9CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFRO1FBdEN4QixlQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUV6QywyREFBMkQ7UUFFM0QsY0FBUyxHQUFvQixRQUFRLENBQUMsU0FBUyxDQUFDO1FBR2hELGtCQUFhLEdBQVksUUFBUSxDQUFDLGFBQWEsQ0FBQztRQUdoRCxpQkFBWSxHQUFvQixRQUFRLENBQUMsWUFBWSxDQUFDO1FBR3RELGtCQUFhLEdBQVksUUFBUSxDQUFDLGFBQWEsQ0FBQztRQUdoRCxpQkFBWSxHQUFvQixRQUFRLENBQUMsWUFBWSxDQUFDO1FBR3RELHFCQUFnQixHQUFvQixRQUFRLENBQUMsZ0JBQWdCLENBQUM7UUFROUQsbUJBQWMsR0FBRyxJQUFJLG1DQUFtQyxFQUFFLENBQUM7UUFFM0Qsc0JBQWlCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUdoQyx5QkFBb0IsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQzNDLGtCQUFhLEdBQUc7WUFDdEIsTUFBTSxFQUFFLEtBQUs7WUFDYixNQUFNLEVBQUUsS0FBSztTQUNkLENBQUM7SUFHRixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixNQUFNLHNCQUFzQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxVQUFlLEVBQUUsRUFBRTtZQUNwRCxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDO1FBRUYsTUFBTSw4QkFBOEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDO1FBQzNFLElBQUksQ0FBQyxLQUFLLENBQUMsd0JBQXdCLEdBQUcsR0FBRyxFQUFFO1lBQ3pDLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQy9FLDhCQUE4QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEQsSUFBSSwyQkFBMkIsRUFBRTtnQkFDL0IsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxDQUFDO2FBQ2xDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFOUMsYUFBYSxDQUFDO1lBQ1osSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZO1lBQ2hDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQzVCLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUNqQixTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUMsRUFDN0MsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDUCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUM5QixDQUFDLENBQUMsQ0FDSDtTQUNGLENBQUM7YUFDQyxJQUFJLENBQ0gsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FDM0I7YUFDQSxTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUU7WUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQ3pCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2FBQzVCO1lBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRTtnQkFDN0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUNwQztZQUNELElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDcEM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxVQUFtQjtRQUNuQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDOUIsSUFBSSxVQUFVLFlBQVksNEJBQTRCLEVBQUU7WUFDdEQsTUFBTSxhQUFhLEdBQUcsVUFBNkMsQ0FBQztZQUNwRSxhQUFhLENBQUMsYUFBYTtpQkFDeEIsSUFBSSxDQUNILG9CQUFvQixFQUFFLEVBQ3RCLFNBQVMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFDakMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDMUIsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUN6RCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxFQUN4RCxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUMzQjtpQkFDQSxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFO2dCQUM1QixNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ2xELGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1NBQ047YUFBTTtZQUNMLE1BQU0sSUFBSSxLQUFLLENBQUMsMkZBQTJGLENBQUMsQ0FBQztTQUM5RztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFM0gsTUFBTSxNQUFNLEdBQUc7WUFDYixTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLFFBQVEsQ0FBQyxTQUFTO1lBQ2hELFlBQVksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRixZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEYsZ0JBQWdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksUUFBUSxDQUFDLGdCQUFnQjtTQUN0RSxDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdEMsSUFBSSxjQUFjLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUU7WUFDbEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsY0FBYyxJQUFJLENBQUM7WUFDM0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztTQUNsRDtJQUNILENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFO1lBQ2pDLElBQUksQ0FBQyxhQUFhLEdBQUc7Z0JBQ25CLE1BQU0sRUFBRSxLQUFLO2dCQUNiLE1BQU0sRUFBRSxLQUFLO2FBQ2QsQ0FBQztZQUNGLE9BQU87U0FDUjtRQUVELE1BQU0sU0FBUyxHQUFHLENBQUMsT0FBbUIsRUFBRSxFQUFFLENBQUMsT0FBTzthQUMvQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO2FBQ3RCLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFNBQVMsSUFBSSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLGFBQWEsR0FBRztZQUNuQixNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMvQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztTQUNoRCxDQUFDO0lBQ0osQ0FBQztJQUVPLGVBQWUsQ0FBQyxNQUFjO1FBQ3BDLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLENBQUM7YUFDekYsT0FBTyxDQUFDLENBQUMsRUFBZSxFQUFFLEVBQUU7WUFDM0IsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztZQUNoQyxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7WUFDbkIsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDcEMsVUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQy9DO1lBQ0QsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sZUFBZSxDQUFDLE1BQWM7UUFDcEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxvQkFBb0IsQ0FBQzthQUN6RixPQUFPLENBQUMsQ0FBQyxFQUFlLEVBQUUsRUFBRTtZQUMzQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ2hDLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNuQixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNwQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDL0M7WUFDRCxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLG1CQUFtQjtRQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO1FBRXRELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBRXhCLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDN0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxvQkFBb0IsQ0FBQztpQkFDekYsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUNaLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDckMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztpQkFDcEQ7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNOO1FBRUQsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRTtZQUM3QixJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDO2lCQUN6RixPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQ1osTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO29CQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7aUJBQ3JEO1lBQ0gsQ0FBQyxDQUFDLENBQUM7U0FDTjtJQUNILENBQUM7SUFHTyxxQkFBcUI7UUFDM0IsbUZBQW1GO1FBQ25GLGlEQUFpRDtRQUNqRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDOzttSEEvTVUsc0JBQXNCO3VHQUF0QixzQkFBc0IsZ1VBTnRCLENBQUM7WUFDVixPQUFPLEVBQUUsdUJBQXVCO1lBQ2hDLFVBQVUsRUFBRSwyQ0FBMkM7WUFDdkQsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHNCQUFzQixDQUFDLENBQUM7U0FDakQsQ0FBQyw2REEyQlksUUFBUTsyRkF6Qlgsc0JBQXNCO2tCQVJsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSwwQ0FBMEM7b0JBQ3BELFNBQVMsRUFBRSxDQUFDOzRCQUNWLE9BQU8sRUFBRSx1QkFBdUI7NEJBQ2hDLFVBQVUsRUFBRSwyQ0FBMkM7NEJBQ3ZELElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsdUJBQXVCLENBQUMsQ0FBQzt5QkFDakQsQ0FBQztpQkFDSDs2RkFNQyxTQUFTO3NCQURSLEtBQUs7dUJBQUMsYUFBYTtnQkFJcEIsYUFBYTtzQkFEWixLQUFLO2dCQUlOLFlBQVk7c0JBRFgsS0FBSztnQkFJTixhQUFhO3NCQURaLEtBQUs7Z0JBSU4sWUFBWTtzQkFEWCxLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLEtBQUs7c0JBREosWUFBWTt1QkFBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVklSVFVBTF9TQ1JPTExfU1RSQVRFR1kgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IENhblN0aWNrLCBDZGtUYWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay90YWJsZSc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDb250ZW50Q2hpbGQsXG4gIERpcmVjdGl2ZSxcbiAgZm9yd2FyZFJlZixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3lcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0LCBmcm9tLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheVdoZW4sIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBGaXhlZFNpemVUYWJsZVZpcnR1YWxTY3JvbGxTdHJhdGVneSB9IGZyb20gJy4vZml4ZWQtc2l6ZS10YWJsZS12aXJ0dWFsLXNjcm9sbC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUYWJsZVZpcnR1YWxTY3JvbGxEYXRhU291cmNlIH0gZnJvbSAnLi90YWJsZS1kYXRhLXNvdXJjZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBfdGFibGVWaXJ0dWFsU2Nyb2xsRGlyZWN0aXZlU3RyYXRlZ3lGYWN0b3J5KHRhYmxlRGlyOiBUYWJsZUl0ZW1TaXplRGlyZWN0aXZlKSB7XG4gIHJldHVybiB0YWJsZURpci5zY3JvbGxTdHJhdGVneTtcbn1cblxuZnVuY3Rpb24gY29tYmluZVNlbGVjdG9ycyguLi5wYWlyczogc3RyaW5nW11bXSk6IHN0cmluZyB7XG4gIHJldHVybiBwYWlycy5tYXAoKHNlbGVjdG9ycykgPT4gYCR7c2VsZWN0b3JzLmpvaW4oJyAnKX0sICR7c2VsZWN0b3JzLmpvaW4oJycpfWApLmpvaW4oJywgJyk7XG59XG5cbmNvbnN0IHN0aWNreUhlYWRlclNlbGVjdG9yID0gY29tYmluZVNlbGVjdG9ycyhcbiAgWycubWF0LW1kYy1oZWFkZXItcm93JywgJy5tYXQtbWRjLXRhYmxlLXN0aWNreSddLFxuICBbJy5tYXQtaGVhZGVyLXJvdycsICcubWF0LXRhYmxlLXN0aWNreSddLFxuICBbJy5jZGstaGVhZGVyLXJvdycsICcuY2RrLXRhYmxlLXN0aWNreSddXG4pO1xuXG5jb25zdCBzdGlja3lGb290ZXJTZWxlY3RvciA9IGNvbWJpbmVTZWxlY3RvcnMoXG4gIFsnLm1hdC1tZGMtZm9vdGVyLXJvdycsICcubWF0LW1kYy10YWJsZS1zdGlja3knXSxcbiAgWycubWF0LWZvb3Rlci1yb3cnLCAnLm1hdC10YWJsZS1zdGlja3knXSxcbiAgWycuY2RrLWZvb3Rlci1yb3cnLCAnLmNkay10YWJsZS1zdGlja3knXVxuKTtcblxuY29uc3QgZGVmYXVsdHMgPSB7XG4gIHJvd0hlaWdodDogNDgsXG4gIGhlYWRlckhlaWdodDogNTYsXG4gIGhlYWRlckVuYWJsZWQ6IHRydWUsXG4gIGZvb3RlckhlaWdodDogNDgsXG4gIGZvb3RlckVuYWJsZWQ6IGZhbHNlLFxuICBidWZmZXJNdWx0aXBsaWVyOiAwLjdcbn07XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFt0dnNJdGVtU2l6ZV0nLFxuICBwcm92aWRlcnM6IFt7XG4gICAgcHJvdmlkZTogVklSVFVBTF9TQ1JPTExfU1RSQVRFR1ksXG4gICAgdXNlRmFjdG9yeTogX3RhYmxlVmlydHVhbFNjcm9sbERpcmVjdGl2ZVN0cmF0ZWd5RmFjdG9yeSxcbiAgICBkZXBzOiBbZm9yd2FyZFJlZigoKSA9PiBUYWJsZUl0ZW1TaXplRGlyZWN0aXZlKV1cbiAgfV1cbn0pXG5leHBvcnQgY2xhc3MgVGFibGVJdGVtU2l6ZURpcmVjdGl2ZTxUID0gdW5rbm93bj4gaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1pbnB1dC1yZW5hbWVcbiAgQElucHV0KCd0dnNJdGVtU2l6ZScpXG4gIHJvd0hlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMucm93SGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGhlYWRlckVuYWJsZWQ6IGJvb2xlYW4gPSBkZWZhdWx0cy5oZWFkZXJFbmFibGVkO1xuXG4gIEBJbnB1dCgpXG4gIGhlYWRlckhlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMuaGVhZGVySGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGZvb3RlckVuYWJsZWQ6IGJvb2xlYW4gPSBkZWZhdWx0cy5mb290ZXJFbmFibGVkO1xuXG4gIEBJbnB1dCgpXG4gIGZvb3RlckhlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gZGVmYXVsdHMuZm9vdGVySGVpZ2h0O1xuXG4gIEBJbnB1dCgpXG4gIGJ1ZmZlck11bHRpcGxpZXI6IHN0cmluZyB8IG51bWJlciA9IGRlZmF1bHRzLmJ1ZmZlck11bHRpcGxpZXI7XG5cbiAgQElucHV0KClcbiAgdmlzaWJsZVJvd3NDb3VudD86IG51bWJlcjtcblxuICBAQ29udGVudENoaWxkKENka1RhYmxlLCB7IHN0YXRpYzogZmFsc2UgfSlcbiAgdGFibGU6IENka1RhYmxlPFQ+O1xuXG4gIHNjcm9sbFN0cmF0ZWd5ID0gbmV3IEZpeGVkU2l6ZVRhYmxlVmlydHVhbFNjcm9sbFN0cmF0ZWd5KCk7XG5cbiAgZGF0YVNvdXJjZUNoYW5nZXMgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHByaXZhdGUgc3RpY2t5UG9zaXRpb25zOiBNYXA8SFRNTEVsZW1lbnQsIG51bWJlcj47XG4gIHByaXZhdGUgcmVzZXRTdGlja3lQb3NpdGlvbnMgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHN0aWNreUVuYWJsZWQgPSB7XG4gICAgaGVhZGVyOiBmYWxzZSxcbiAgICBmb290ZXI6IGZhbHNlXG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB6b25lOiBOZ1pvbmUpIHtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5kYXRhU291cmNlQ2hhbmdlcy5jb21wbGV0ZSgpO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIGNvbnN0IHN3aXRjaERhdGFTb3VyY2VPcmlnaW4gPSB0aGlzLnRhYmxlWydfc3dpdGNoRGF0YVNvdXJjZSddO1xuICAgIHRoaXMudGFibGVbJ19zd2l0Y2hEYXRhU291cmNlJ10gPSAoZGF0YVNvdXJjZTogYW55KSA9PiB7XG4gICAgICBzd2l0Y2hEYXRhU291cmNlT3JpZ2luLmNhbGwodGhpcy50YWJsZSwgZGF0YVNvdXJjZSk7XG4gICAgICB0aGlzLmNvbm5lY3REYXRhU291cmNlKGRhdGFTb3VyY2UpO1xuICAgIH07XG5cbiAgICBjb25zdCB1cGRhdGVTdGlja3lDb2x1bW5TdHlsZXNPcmlnaW4gPSB0aGlzLnRhYmxlLnVwZGF0ZVN0aWNreUNvbHVtblN0eWxlcztcbiAgICB0aGlzLnRhYmxlLnVwZGF0ZVN0aWNreUNvbHVtblN0eWxlcyA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHN0aWNreUNvbHVtblN0eWxlc05lZWRSZXNldCA9IHRoaXMudGFibGVbJ19zdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQnXTtcbiAgICAgIHVwZGF0ZVN0aWNreUNvbHVtblN0eWxlc09yaWdpbi5jYWxsKHRoaXMudGFibGUpO1xuICAgICAgaWYgKHN0aWNreUNvbHVtblN0eWxlc05lZWRSZXNldCkge1xuICAgICAgICB0aGlzLnJlc2V0U3RpY2t5UG9zaXRpb25zLm5leHQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5jb25uZWN0RGF0YVNvdXJjZSh0aGlzLnRhYmxlLmRhdGFTb3VyY2UpO1xuXG4gICAgY29tYmluZUxhdGVzdChbXG4gICAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnN0aWNreUNoYW5nZSxcbiAgICAgIHRoaXMucmVzZXRTdGlja3lQb3NpdGlvbnMucGlwZShcbiAgICAgICAgc3RhcnRXaXRoKHZvaWQgMCksXG4gICAgICAgIGRlbGF5V2hlbigoKSA9PiB0aGlzLmdldFNjaGVkdWxlT2JzZXJ2YWJsZSgpKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnN0aWNreVBvc2l0aW9ucyA9IG51bGw7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgXSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoW3N0aWNreU9mZnNldF0pID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnN0aWNreVBvc2l0aW9ucykge1xuICAgICAgICAgIHRoaXMuaW5pdFN0aWNreVBvc2l0aW9ucygpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0aWNreUVuYWJsZWQuaGVhZGVyKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGlja3lIZWFkZXIoc3RpY2t5T2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdGlja3lFbmFibGVkLmZvb3Rlcikge1xuICAgICAgICAgIHRoaXMuc2V0U3RpY2t5Rm9vdGVyKHN0aWNreU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgY29ubmVjdERhdGFTb3VyY2UoZGF0YVNvdXJjZTogdW5rbm93bikge1xuICAgIHRoaXMuZGF0YVNvdXJjZUNoYW5nZXMubmV4dCgpO1xuICAgIGlmIChkYXRhU291cmNlIGluc3RhbmNlb2YgVGFibGVWaXJ0dWFsU2Nyb2xsRGF0YVNvdXJjZSkge1xuICAgICAgY29uc3QgdHZzRGF0YVNvdXJjZSA9IGRhdGFTb3VyY2UgYXMgVGFibGVWaXJ0dWFsU2Nyb2xsRGF0YVNvdXJjZTxUPjtcbiAgICAgIHR2c0RhdGFTb3VyY2UuZGF0YVRvUmVuZGVyJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRhdGFTb3VyY2VDaGFuZ2VzKSxcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKSxcbiAgICAgICAgICB0YXAoZGF0YSA9PiB0aGlzLnNjcm9sbFN0cmF0ZWd5LmRhdGFMZW5ndGggPSBkYXRhLmxlbmd0aCksXG4gICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuc2Nyb2xsU3RyYXRlZ3kucmVuZGVyZWRSYW5nZVN0cmVhbSksXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJClcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCh7IHN0YXJ0LCBlbmQgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB0dnNEYXRhU291cmNlLmRhdGEuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgICAgICAgdHZzRGF0YVNvdXJjZS5kYXRhT2ZSYW5nZSQubmV4dChkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignW3R2c0l0ZW1TaXplXSByZXF1aXJlcyBUYWJsZVZpcnR1YWxTY3JvbGxEYXRhU291cmNlIGJlIHNldCBhcyBbZGF0YVNvdXJjZV0gb2YgW2Nkay10YWJsZV0nKTtcbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHRoaXMudmlzaWJsZVJvd3NDb3VudCA/IHRoaXMudmlzaWJsZVJvd3NDb3VudCAqICgrdGhpcy5yb3dIZWlnaHQgfHwgZGVmYXVsdHMucm93SGVpZ2h0KSA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIHJvd0hlaWdodDogK3RoaXMucm93SGVpZ2h0IHx8IGRlZmF1bHRzLnJvd0hlaWdodCxcbiAgICAgIGhlYWRlckhlaWdodDogdGhpcy5oZWFkZXJFbmFibGVkID8gK3RoaXMuaGVhZGVySGVpZ2h0IHx8IGRlZmF1bHRzLmhlYWRlckhlaWdodCA6IDAsXG4gICAgICBmb290ZXJIZWlnaHQ6IHRoaXMuZm9vdGVyRW5hYmxlZCA/ICt0aGlzLmZvb3RlckhlaWdodCB8fCBkZWZhdWx0cy5mb290ZXJIZWlnaHQgOiAwLFxuICAgICAgYnVmZmVyTXVsdGlwbGllcjogK3RoaXMuYnVmZmVyTXVsdGlwbGllciB8fCBkZWZhdWx0cy5idWZmZXJNdWx0aXBsaWVyXG4gICAgfTtcbiAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnNldENvbmZpZyhjb25maWcpO1xuXG4gICAgaWYgKHZpZXdwb3J0SGVpZ2h0ICYmIHRoaXMuc2Nyb2xsU3RyYXRlZ3kudmlld3BvcnQpIHtcbiAgICAgIHRoaXMuc2Nyb2xsU3RyYXRlZ3kudmlld3BvcnQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3ZpZXdwb3J0SGVpZ2h0fXB4YDtcbiAgICAgIHRoaXMuc2Nyb2xsU3RyYXRlZ3kudmlld3BvcnQuY2hlY2tWaWV3cG9ydFNpemUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFN0aWNreUVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLnNjcm9sbFN0cmF0ZWd5LnZpZXdwb3J0KSB7XG4gICAgICB0aGlzLnN0aWNreUVuYWJsZWQgPSB7XG4gICAgICAgIGhlYWRlcjogZmFsc2UsXG4gICAgICAgIGZvb3RlcjogZmFsc2VcbiAgICAgIH07XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNFbmFibGVkID0gKHJvd0RlZnM6IENhblN0aWNrW10pID0+IHJvd0RlZnNcbiAgICAgIC5tYXAoZGVmID0+IGRlZi5zdGlja3kpXG4gICAgICAucmVkdWNlKChwcmV2U3RhdGUsIHN0YXRlKSA9PiBwcmV2U3RhdGUgJiYgc3RhdGUsIHRydWUpO1xuXG4gICAgdGhpcy5zdGlja3lFbmFibGVkID0ge1xuICAgICAgaGVhZGVyOiBpc0VuYWJsZWQodGhpcy50YWJsZVsnX2hlYWRlclJvd0RlZnMnXSksXG4gICAgICBmb290ZXI6IGlzRW5hYmxlZCh0aGlzLnRhYmxlWydfZm9vdGVyUm93RGVmcyddKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdGlja3lIZWFkZXIob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnZpZXdwb3J0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHN0aWNreUhlYWRlclNlbGVjdG9yKVxuICAgICAgLmZvckVhY2goKGVsOiBIVE1MRWxlbWVudCkgPT4ge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICBsZXQgYmFzZU9mZnNldCA9IDA7XG4gICAgICAgIGlmICh0aGlzLnN0aWNreVBvc2l0aW9ucy5oYXMocGFyZW50KSkge1xuICAgICAgICAgIGJhc2VPZmZzZXQgPSB0aGlzLnN0aWNreVBvc2l0aW9ucy5nZXQocGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbC5zdHlsZS50b3AgPSBgJHtiYXNlT2Zmc2V0IC0gb2Zmc2V0fXB4YDtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdGlja3lGb290ZXIob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnNjcm9sbFN0cmF0ZWd5LnZpZXdwb3J0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHN0aWNreUZvb3RlclNlbGVjdG9yKVxuICAgICAgLmZvckVhY2goKGVsOiBIVE1MRWxlbWVudCkgPT4ge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICBsZXQgYmFzZU9mZnNldCA9IDA7XG4gICAgICAgIGlmICh0aGlzLnN0aWNreVBvc2l0aW9ucy5oYXMocGFyZW50KSkge1xuICAgICAgICAgIGJhc2VPZmZzZXQgPSB0aGlzLnN0aWNreVBvc2l0aW9ucy5nZXQocGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbC5zdHlsZS5ib3R0b20gPSBgJHstYmFzZU9mZnNldCArIG9mZnNldH1weGA7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdFN0aWNreVBvc2l0aW9ucygpIHtcbiAgICB0aGlzLnN0aWNreVBvc2l0aW9ucyA9IG5ldyBNYXA8SFRNTEVsZW1lbnQsIG51bWJlcj4oKTtcblxuICAgIHRoaXMuc2V0U3RpY2t5RW5hYmxlZCgpO1xuXG4gICAgaWYgKHRoaXMuc3RpY2t5RW5hYmxlZC5oZWFkZXIpIHtcbiAgICAgIHRoaXMuc2Nyb2xsU3RyYXRlZ3kudmlld3BvcnQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc3RpY2t5SGVhZGVyU2VsZWN0b3IpXG4gICAgICAgIC5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgIGlmICghdGhpcy5zdGlja3lQb3NpdGlvbnMuaGFzKHBhcmVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RpY2t5UG9zaXRpb25zLnNldChwYXJlbnQsIHBhcmVudC5vZmZzZXRUb3ApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RpY2t5RW5hYmxlZC5mb290ZXIpIHtcbiAgICAgIHRoaXMuc2Nyb2xsU3RyYXRlZ3kudmlld3BvcnQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc3RpY2t5Rm9vdGVyU2VsZWN0b3IpXG4gICAgICAgIC5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgIGlmICghdGhpcy5zdGlja3lQb3NpdGlvbnMuaGFzKHBhcmVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RpY2t5UG9zaXRpb25zLnNldChwYXJlbnQsIC1wYXJlbnQub2Zmc2V0VG9wKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG5cbiAgcHJpdmF0ZSBnZXRTY2hlZHVsZU9ic2VydmFibGUoKSB7XG4gICAgLy8gVXNlIG9uU3RhYmxlIHdoZW4gaW4gdGhlIGNvbnRleHQgb2YgYW4gb25nb2luZyBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlIHNvIHRoYXQgd2VcbiAgICAvLyBkbyBub3QgYWNjaWRlbnRhbGx5IHRyaWdnZXIgYWRkaXRpb25hbCBjeWNsZXMuXG4gICAgcmV0dXJuIHRoaXMuem9uZS5pc1N0YWJsZVxuICAgICAgPyBmcm9tKFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpKVxuICAgICAgOiB0aGlzLnpvbmUub25TdGFibGUucGlwZSh0YWtlKDEpKTtcbiAgfVxufVxuIl19