UNPKG

ng-table-virtual-scroll

Version:
117 lines 18.4 kB
import { Injectable } from '@angular/core'; import { distinctUntilChanged } from 'rxjs/operators'; import { BehaviorSubject, Subject } from 'rxjs'; import * as i0 from "@angular/core"; export class FixedSizeTableVirtualScrollStrategy { constructor() { this.indexChange = new Subject(); this.stickyChange = new Subject(); this.renderedRangeStream = new BehaviorSubject({ start: 0, end: 0 }); this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged()); this._dataLength = 0; } get dataLength() { return this._dataLength; } set dataLength(value) { if (value !== this._dataLength) { this._dataLength = value; this.onDataLengthChanged(); } } attach(viewport) { this.viewport = viewport; this.viewport.renderedRangeStream.subscribe(this.renderedRangeStream); this.stickyChange.next(0); this.onDataLengthChanged(); } detach() { this.indexChange.complete(); this.stickyChange.complete(); this.renderedRangeStream.complete(); } onContentScrolled() { this.updateContent(); } onDataLengthChanged() { if (this.viewport) { const contentSize = this.dataLength * this.rowHeight + this.headerHeight + this.footerHeight; this.viewport.setTotalContentSize(contentSize); const viewportSize = this.viewport.getViewportSize(); if (this.viewport.measureScrollOffset() + viewportSize >= contentSize) { this.viewport.scrollToOffset(contentSize - viewportSize); } } this.updateContent(); } onContentRendered() { } onRenderedOffsetChanged() { // no-op } scrollToIndex(index, behavior) { if (!this.viewport || !this.rowHeight) { return; } this.viewport.scrollToOffset((index - 1) * this.rowHeight + this.headerHeight, behavior); } setConfig(configs) { const { rowHeight, headerHeight, footerHeight, bufferMultiplier } = configs; if (this.rowHeight === rowHeight && this.headerHeight === headerHeight && this.footerHeight === footerHeight && this.bufferMultiplier === bufferMultiplier) { return; } this.rowHeight = rowHeight; this.headerHeight = headerHeight; this.footerHeight = footerHeight; this.bufferMultiplier = bufferMultiplier; this.onDataLengthChanged(); } updateContent() { if (!this.viewport || !this.rowHeight) { return; } const renderedOffset = this.viewport.getOffsetToRenderedContentStart(); const start = renderedOffset / this.rowHeight; const itemsDisplayed = Math.ceil(this.viewport.getViewportSize() / this.rowHeight); const bufferItems = Math.ceil(itemsDisplayed * this.bufferMultiplier); const end = start + itemsDisplayed + 2 * bufferItems; const bufferOffset = renderedOffset + bufferItems * this.rowHeight; const scrollOffset = this.viewport.measureScrollOffset(); // How far the scroll offset is from the lower buffer, which is usually where items start being displayed const relativeScrollOffset = scrollOffset - bufferOffset; const rowsScrolled = relativeScrollOffset / this.rowHeight; const displayed = scrollOffset / this.rowHeight; this.indexChange.next(displayed); // Only bother updating the displayed information if we've scrolled more than a row const rowSensitivity = 1.0; if (Math.abs(rowsScrolled) < rowSensitivity) { this.viewport.setRenderedContentOffset(renderedOffset); this.viewport.setRenderedRange({ start, end }); return; } // Special case for the start of the table. // At the top of the table, the first few rows are first rendered because they're visible, and then still rendered // Because they move into the buffer. So we only need to change what's rendered once the user scrolls far enough down. if (renderedOffset === 0 && rowsScrolled < 0) { this.viewport.setRenderedContentOffset(renderedOffset); this.viewport.setRenderedRange({ start, end }); return; } const rowsToMove = Math.sign(rowsScrolled) * Math.floor(Math.abs(rowsScrolled)); const adjustedRenderedOffset = Math.max(0, renderedOffset + rowsToMove * this.rowHeight); this.viewport.setRenderedContentOffset(adjustedRenderedOffset); const adjustedStart = Math.max(0, start + rowsToMove); const adjustedEnd = adjustedStart + itemsDisplayed + 2 * bufferItems; this.viewport.setRenderedRange({ start: adjustedStart, end: adjustedEnd }); this.stickyChange.next(adjustedRenderedOffset); } } FixedSizeTableVirtualScrollStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: FixedSizeTableVirtualScrollStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); FixedSizeTableVirtualScrollStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: FixedSizeTableVirtualScrollStrategy }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: FixedSizeTableVirtualScrollStrategy, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4ZWQtc2l6ZS10YWJsZS12aXJ0dWFsLXNjcm9sbC1zdHJhdGVneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhYmxlLXZpcnR1YWwtc2Nyb2xsL3NyYy9saWIvZml4ZWQtc2l6ZS10YWJsZS12aXJ0dWFsLXNjcm9sbC1zdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQVloRCxNQUFNLE9BQU8sbUNBQW1DO0lBRGhEO1FBTVUsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBQ3JDLGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUlyQyx3QkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBWSxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7UUFFekUsd0JBQW1CLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBYW5FLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO0tBK0d6QjtJQTFIQyxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksVUFBVSxDQUFDLEtBQWE7UUFDMUIsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUM5QixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUN6QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztTQUM1QjtJQUNILENBQUM7SUFJTSxNQUFNLENBQUMsUUFBa0M7UUFDOUMsSUFBSSxDQUFDLFFBQVEsR0FB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QUN2RCxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7WUFDN0MsT0FBTztTQUNSO1FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUNoRixNQUFNLHNCQUFzQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLGNBQWMsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pGLElBQUksQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUUvRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFDdEQsTUFBTSxXQUFXLEdBQUcsYUFBYSxHQUFHLGNBQWMsR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBRXpFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDakQsQ0FBQzs7Z0lBdklVLG1DQUFtQztvSUFBbkMsbUNBQW1DOzJGQUFuQyxtQ0FBbUM7a0JBRC9DLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0LCBWaXJ0dWFsU2Nyb2xsU3RyYXRlZ3kgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IExpc3RSYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVFNWU3RyYXRlZ3lDb25maWdzIHtcbiAgcm93SGVpZ2h0OiBudW1iZXI7XG4gIGhlYWRlckhlaWdodDogbnVtYmVyO1xuICBmb290ZXJIZWlnaHQ6IG51bWJlcjtcbiAgYnVmZmVyTXVsdGlwbGllcjogbnVtYmVyO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRml4ZWRTaXplVGFibGVWaXJ0dWFsU2Nyb2xsU3RyYXRlZ3kgaW1wbGVtZW50cyBWaXJ0dWFsU2Nyb2xsU3RyYXRlZ3kge1xuICBwcml2YXRlIHJvd0hlaWdodCE6IG51bWJlcjtcbiAgcHJpdmF0ZSBoZWFkZXJIZWlnaHQhOiBudW1iZXI7XG4gIHByaXZhdGUgZm9vdGVySGVpZ2h0ITogbnVtYmVyO1xuICBwcml2YXRlIGJ1ZmZlck11bHRpcGxpZXIhOiBudW1iZXI7XG4gIHByaXZhdGUgaW5kZXhDaGFuZ2UgPSBuZXcgU3ViamVjdDxudW1iZXI+KCk7XG4gIHB1YmxpYyBzdGlja3lDaGFuZ2UgPSBuZXcgU3ViamVjdDxudW1iZXI+KCk7XG5cbiAgcHVibGljIHZpZXdwb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ7XG5cbiAgcHVibGljIHJlbmRlcmVkUmFuZ2VTdHJlYW0gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PExpc3RSYW5nZT4oe3N0YXJ0OiAwLCBlbmQ6IDB9KTtcblxuICBwdWJsaWMgc2Nyb2xsZWRJbmRleENoYW5nZSA9IHRoaXMuaW5kZXhDaGFuZ2UucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcblxuICBnZXQgZGF0YUxlbmd0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9kYXRhTGVuZ3RoO1xuICB9XG5cbiAgc2V0IGRhdGFMZW5ndGgodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh2YWx1ZSAhPT0gdGhpcy5fZGF0YUxlbmd0aCkge1xuICAgICAgdGhpcy5fZGF0YUxlbmd0aCA9IHZhbHVlO1xuICAgICAgdGhpcy5vbkRhdGFMZW5ndGhDaGFuZ2VkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZGF0YUxlbmd0aCA9IDA7XG5cbiAgcHVibGljIGF0dGFjaCh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KTogdm9pZCB7XG4gICAgdGhpcy52aWV3cG9ydCA9IHZpZXdwb3J0O1xuICAgIHRoaXMudmlld3BvcnQucmVuZGVyZWRSYW5nZVN0cmVhbS5zdWJzY3JpYmUodGhpcy5yZW5kZXJlZFJhbmdlU3RyZWFtKTtcbiAgICB0aGlzLnN0aWNreUNoYW5nZS5uZXh0KDApO1xuICAgIHRoaXMub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xuICB9XG5cbiAgcHVibGljIGRldGFjaCgpOiB2b2lkIHtcbiAgICB0aGlzLmluZGV4Q2hhbmdlLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5zdGlja3lDaGFuZ2UuY29tcGxldGUoKTtcbiAgICB0aGlzLnJlbmRlcmVkUmFuZ2VTdHJlYW0uY29tcGxldGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbnRlbnRTY3JvbGxlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUNvbnRlbnQoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkRhdGFMZW5ndGhDaGFuZ2VkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZpZXdwb3J0KSB7XG4gICAgICBjb25zdCBjb250ZW50U2l6ZSA9IHRoaXMuZGF0YUxlbmd0aCAqIHRoaXMucm93SGVpZ2h0ICsgdGhpcy5oZWFkZXJIZWlnaHQgKyB0aGlzLmZvb3RlckhlaWdodDtcbiAgICAgIHRoaXMudmlld3BvcnQuc2V0VG90YWxDb250ZW50U2l6ZShjb250ZW50U2l6ZSk7XG4gICAgICBjb25zdCB2aWV3cG9ydFNpemUgPSB0aGlzLnZpZXdwb3J0LmdldFZpZXdwb3J0U2l6ZSgpO1xuICAgICAgaWYgKHRoaXMudmlld3BvcnQubWVhc3VyZVNjcm9sbE9mZnNldCgpICsgdmlld3BvcnRTaXplID49IGNvbnRlbnRTaXplKSB7XG4gICAgICAgIHRoaXMudmlld3BvcnQuc2Nyb2xsVG9PZmZzZXQoY29udGVudFNpemUgLSB2aWV3cG9ydFNpemUpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUNvbnRlbnQoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbnRlbnRSZW5kZXJlZCgpOiB2b2lkIHtcbiAgfVxuXG4gIHB1YmxpYyBvblJlbmRlcmVkT2Zmc2V0Q2hhbmdlZCgpOiB2b2lkIHtcbiAgICAvLyBuby1vcFxuICB9XG5cbiAgcHVibGljIHNjcm9sbFRvSW5kZXgoaW5kZXg6IG51bWJlciwgYmVoYXZpb3I/OiBTY3JvbGxCZWhhdmlvcik6IHZvaWQge1xuICAgIGlmICghdGhpcy52aWV3cG9ydCB8fCAhdGhpcy5yb3dIZWlnaHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy52aWV3cG9ydC5zY3JvbGxUb09mZnNldCgoaW5kZXggLSAxICkgKiB0aGlzLnJvd0hlaWdodCArIHRoaXMuaGVhZGVySGVpZ2h0LCBiZWhhdmlvcik7XG4gIH1cblxuICBwdWJsaWMgc2V0Q29uZmlnKGNvbmZpZ3M6IFRTVlN0cmF0ZWd5Q29uZmlncykge1xuICAgIGNvbnN0IHtyb3dIZWlnaHQsIGhlYWRlckhlaWdodCwgZm9vdGVySGVpZ2h0LCBidWZmZXJNdWx0aXBsaWVyfSA9IGNvbmZpZ3M7XG4gICAgaWYgKFxuICAgICAgdGhpcy5yb3dIZWlnaHQgPT09IHJvd0hlaWdodFxuICAgICAgJiYgdGhpcy5oZWFkZXJIZWlnaHQgPT09IGhlYWRlckhlaWdodFxuICAgICAgJiYgdGhpcy5mb290ZXJIZWlnaHQgPT09IGZvb3RlckhlaWdodFxuICAgICAgJiYgdGhpcy5idWZmZXJNdWx0aXBsaWVyID09PSBidWZmZXJNdWx0aXBsaWVyXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucm93SGVpZ2h0ID0gcm93SGVpZ2h0O1xuICAgIHRoaXMuaGVhZGVySGVpZ2h0ID0gaGVhZGVySGVpZ2h0O1xuICAgIHRoaXMuZm9vdGVySGVpZ2h0ID0gZm9vdGVySGVpZ2h0O1xuICAgIHRoaXMuYnVmZmVyTXVsdGlwbGllciA9IGJ1ZmZlck11bHRpcGxpZXI7XG4gICAgdGhpcy5vbkRhdGFMZW5ndGhDaGFuZ2VkKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUNvbnRlbnQoKSB7XG4gICAgaWYgKCF0aGlzLnZpZXdwb3J0IHx8ICF0aGlzLnJvd0hlaWdodCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbmRlcmVkT2Zmc2V0ID0gdGhpcy52aWV3cG9ydC5nZXRPZmZzZXRUb1JlbmRlcmVkQ29udGVudFN0YXJ0KCk7XG4gICAgY29uc3Qgc3RhcnQgPSByZW5kZXJlZE9mZnNldCAvIHRoaXMucm93SGVpZ2h0O1xuICAgIGNvbnN0IGl0ZW1zRGlzcGxheWVkID0gTWF0aC5jZWlsKHRoaXMudmlld3BvcnQuZ2V0Vmlld3BvcnRTaXplKCkgLyB0aGlzLnJvd0hlaWdodCk7XG4gICAgY29uc3QgYnVmZmVySXRlbXMgPSBNYXRoLmNlaWwoaXRlbXNEaXNwbGF5ZWQgKiB0aGlzLmJ1ZmZlck11bHRpcGxpZXIpO1xuICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgaXRlbXNEaXNwbGF5ZWQgKyAyICogYnVmZmVySXRlbXM7XG5cblxuICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IHJlbmRlcmVkT2Zmc2V0ICsgYnVmZmVySXRlbXMgKiB0aGlzLnJvd0hlaWdodDtcbiAgICBjb25zdCBzY3JvbGxPZmZzZXQgPSB0aGlzLnZpZXdwb3J0Lm1lYXN1cmVTY3JvbGxPZmZzZXQoKTtcblxuICAgIC8vIEhvdyBmYXIgdGhlIHNjcm9sbCBvZmZzZXQgaXMgZnJvbSB0aGUgbG93ZXIgYnVmZmVyLCB3aGljaCBpcyB1c3VhbGx5IHdoZXJlIGl0ZW1zIHN0YXJ0IGJlaW5nIGRpc3BsYXllZFxuICAgIGNvbnN0IHJlbGF0aXZlU2Nyb2xsT2Zmc2V0ID0gc2Nyb2xsT2Zmc2V0IC0gYnVmZmVyT2Zmc2V0O1xuICAgIGNvbnN0IHJvd3NTY3JvbGxlZCA9IHJlbGF0aXZlU2Nyb2xsT2Zmc2V0IC8gdGhpcy5yb3dIZWlnaHQ7XG5cbiAgICBjb25zdCBkaXNwbGF5ZWQgPSBzY3JvbGxPZmZzZXQgLyB0aGlzLnJvd0hlaWdodDtcbiAgICB0aGlzLmluZGV4Q2hhbmdlLm5leHQoZGlzcGxheWVkKTtcblxuICAgIC8vIE9ubHkgYm90aGVyIHVwZGF0aW5nIHRoZSBkaXNwbGF5ZWQgaW5mb3JtYXRpb24gaWYgd2UndmUgc2Nyb2xsZWQgbW9yZSB0aGFuIGEgcm93XG4gICAgY29uc3Qgcm93U2Vuc2l0aXZpdHkgPSAxLjA7XG4gICAgaWYgKE1hdGguYWJzKHJvd3NTY3JvbGxlZCkgPCByb3dTZW5zaXRpdml0eSkge1xuICAgICAgdGhpcy52aWV3cG9ydC5zZXRSZW5kZXJlZENvbnRlbnRPZmZzZXQocmVuZGVyZWRPZmZzZXQpO1xuICAgICAgdGhpcy52aWV3cG9ydC5zZXRSZW5kZXJlZFJhbmdlKHtzdGFydCwgZW5kfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlIGZvciB0aGUgc3RhcnQgb2YgdGhlIHRhYmxlLlxuICAgIC8vIEF0IHRoZSB0b3Agb2YgdGhlIHRhYmxlLCB0aGUgZmlyc3QgZmV3IHJvd3MgYXJlIGZpcnN0IHJlbmRlcmVkIGJlY2F1c2UgdGhleSdyZSB2aXNpYmxlLCBhbmQgdGhlbiBzdGlsbCByZW5kZXJlZFxuICAgIC8vIEJlY2F1c2UgdGhleSBtb3ZlIGludG8gdGhlIGJ1ZmZlci4gU28gd2Ugb25seSBuZWVkIHRvIGNoYW5nZSB3aGF0J3MgcmVuZGVyZWQgb25jZSB0aGUgdXNlciBzY3JvbGxzIGZhciBlbm91Z2ggZG93bi5cbiAgICBpZiAocmVuZGVyZWRPZmZzZXQgPT09IDAgJiYgcm93c1Njcm9sbGVkIDwgMCkge1xuICAgICAgdGhpcy52aWV3cG9ydC5zZXRSZW5kZXJlZENvbnRlbnRPZmZzZXQocmVuZGVyZWRPZmZzZXQpO1xuICAgICAgdGhpcy52aWV3cG9ydC5zZXRSZW5kZXJlZFJhbmdlKHtzdGFydCwgZW5kfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgcm93c1RvTW92ZSA9IE1hdGguc2lnbihyb3dzU2Nyb2xsZWQpICogTWF0aC5mbG9vcihNYXRoLmFicyhyb3dzU2Nyb2xsZWQpKTtcbiAgICBjb25zdCBhZGp1c3RlZFJlbmRlcmVkT2Zmc2V0ID0gTWF0aC5tYXgoMCwgcmVuZGVyZWRPZmZzZXQgKyByb3dzVG9Nb3ZlICogdGhpcy5yb3dIZWlnaHQpO1xuICAgIHRoaXMudmlld3BvcnQuc2V0UmVuZGVyZWRDb250ZW50T2Zmc2V0KGFkanVzdGVkUmVuZGVyZWRPZmZzZXQpO1xuXG4gICAgY29uc3QgYWRqdXN0ZWRTdGFydCA9IE1hdGgubWF4KDAsIHN0YXJ0ICsgcm93c1RvTW92ZSk7XG4gICAgY29uc3QgYWRqdXN0ZWRFbmQgPSBhZGp1c3RlZFN0YXJ0ICsgaXRlbXNEaXNwbGF5ZWQgKyAyICogYnVmZmVySXRlbXM7XG4gICAgdGhpcy52aWV3cG9ydC5zZXRSZW5kZXJlZFJhbmdlKHtzdGFydDogYWRqdXN0ZWRTdGFydCwgZW5kOiBhZGp1c3RlZEVuZH0pO1xuXG4gICAgdGhpcy5zdGlja3lDaGFuZ2UubmV4dChhZGp1c3RlZFJlbmRlcmVkT2Zmc2V0KTtcbiAgfVxufVxuIl19