@nova-ui/bits
Version:
SolarWinds Nova Framework
183 lines • 24.2 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { Subject } from "rxjs";
import { distinctUntilChanged } from "rxjs/operators";
export class TableVirtualScrollLinearStrategy {
constructor(rowHeight) {
this.rowHeight = rowHeight;
this.indexChange = new Subject();
// giving a contact point, so user can do some stuff of "scrolling" (changing the range)
this.scrolledIndexChange = this.indexChange
.asObservable()
.pipe(distinctUntilChanged());
}
attach(viewport) {
this.viewport = viewport;
}
detach() {
this.indexChange.complete();
this.viewport = undefined;
}
onContentScrolled() {
if (this.viewport) {
this.updateContent(this.viewport);
}
}
onDataLengthChanged() {
if (this.viewport) {
this.updateContent(this.viewport);
}
}
onContentRendered() { }
onRenderedOffsetChanged() { }
scrollToIndex(index, behavior) { }
/**
* Sets the size of the items in the virtually scrolling list.
* @param length
*/
setDataLength(length) {
this.rowCount = length;
this.updateViewportDataLength(length);
this.onDataLengthChanged();
}
/**
* Sets scroll height.
* @param rowHeight
*/
setRowHeight(rowHeight) {
this.rowHeight = rowHeight;
if (this.viewport) {
this.updateContent(this.viewport);
}
}
/**
* Updates content and emits updated indexes.
* @param viewport
*/
updateContent(viewport) {
if (!viewport) {
return;
}
const rowCount = this.rowCount || 0;
const renderedRange = viewport.getRenderedRange();
const newRange = { ...renderedRange };
const viewportSize = viewport.getViewportSize();
const scrollOffset = viewport.measureScrollOffset() || 0;
let firstVisibleIndex = scrollOffset / this.rowHeight || 0;
// If user scrolls to the bottom of the list and data changes to a smaller list
// We have to recalculate the first visible index based on new data length and viewport size.
const maxVisibleItems = Math.ceil(viewportSize / this.rowHeight);
// We have to recalculate the first visible index based on new data length and viewport size.
firstVisibleIndex = Math.max(0, Math.min(firstVisibleIndex, rowCount - maxVisibleItems));
// We must update scroll offset to handle start/end buffers
// Current range must also be adjusted to cover the new position (bottom of new list).
newRange.start = Math.floor(firstVisibleIndex);
newRange.end = Math.max(0, Math.min(rowCount, newRange.start + maxVisibleItems));
viewport.setRenderedRange(newRange);
this.indexChange.next(Math.floor(firstVisibleIndex));
}
updateViewportDataLength(rowCount) {
if (!this.viewport) {
return;
}
// Note: Updating _dataLength property of cdk-viewport to maintain default functionalities (getDataLength())
// of the cdk-viewport also with the table. Originally this property is updated by
// the VirtualFor listener while we're using it unconventionally we should take care of this property ourselves
// Ref: https://github.com/angular/components/blob/9.2.x/src/cdk/scrolling/virtual-scroll-viewport.ts#L227
this.viewport["_dataLength"] = rowCount;
}
}
/**
* @deprecated in v11 - Use TableVirtualScrollLinearStrategy instead - Removal: NUI-5796
*/
export class TableVirtualScrollStrategy {
set maxItems(maxItems) {
this._maxItems = isNaN(maxItems) ? 10 : +maxItems;
}
get maxItems() {
return this._maxItems;
}
constructor(rowHeight, headerOffset) {
this.rowHeight = rowHeight;
this.headerOffset = headerOffset;
this.indexChange = new Subject();
/** Buffer for items before needing to render more items. */
this.bufferSize = 5;
/** The size of the items in the virtually scrolling list. */
this.itemsSize = 0;
// giving a contact point, so user can do some stuff of "scrolling" (changing the range)
this.scrolledIndexChange = this.indexChange
.asObservable()
.pipe(distinctUntilChanged());
}
attach(viewport) {
this.viewport = viewport;
this.viewport.setTotalContentSize(this.maxItems * this.rowHeight);
}
detach() {
this.indexChange.complete();
// @ts-ignore: Keeping previous behavior
this.viewport = null;
}
onContentScrolled() {
this.updateContent(this.viewport);
}
onDataLengthChanged() {
if (this.viewport) {
this.updateContent(this.viewport);
}
}
onContentRendered() { }
onRenderedOffsetChanged() { }
scrollToIndex(index, behavior) { }
/**
* Sets the size of the items in the virtually scrolling list.
* @param length
*/
setDataLength(length) {
this.itemsSize = length;
this.onDataLengthChanged();
}
/**
* Sets scroll height.
* @param rowHeight
* @param headerOffset
*/
setScrollHeight(rowHeight, headerOffset) {
this.rowHeight = rowHeight;
this.headerOffset = headerOffset;
this.updateContent(this.viewport);
}
/**
* Updates content and emits updated indexes.
* @param viewport
*/
updateContent(viewport) {
if (viewport) {
// Measuring the new scroll index.
const newIndex = Math.max(0, Math.round(viewport.measureScrollOffset() / this.rowHeight));
const start = newIndex;
const end = newIndex + this.maxItems;
viewport.setRenderedRange({ start, end });
this.indexChange.next(newIndex);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtdmlydHVhbC1zY3JvbGwtc3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RhYmxlL3RhYmxlLXZpcnR1YWwtc2Nyb2xsL3RhYmxlLXZpcnR1YWwtc2Nyb2xsLXN0cmF0ZWd5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQU1qQixPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRELE1BQU0sT0FBTyxnQ0FBZ0M7SUFVekMsWUFBb0IsU0FBaUI7UUFBakIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQVRwQixnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFVakQsd0ZBQXdGO1FBQ3hGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVzthQUN0QyxZQUFZLEVBQUU7YUFDZCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTSxNQUFNLENBQUMsUUFBa0M7UUFDNUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7SUFDN0IsQ0FBQztJQUVNLE1BQU07UUFDVCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO0lBQzlCLENB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cmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7XG4gICAgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0LFxuICAgIFZpcnR1YWxTY3JvbGxTdHJhdGVneSxcbn0gZnJvbSBcIkBhbmd1bGFyL2Nkay9zY3JvbGxpbmdcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFRhYmxlVmlydHVhbFNjcm9sbExpbmVhclN0cmF0ZWd5IGltcGxlbWVudHMgVmlydHVhbFNjcm9sbFN0cmF0ZWd5IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluZGV4Q2hhbmdlID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuXG4gICAgcHJpdmF0ZSB2aWV3cG9ydD86IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydDtcblxuICAgIC8qKiBUaGUgc2l6ZSBvZiB0aGUgaXRlbXMgaW4gdGhlIHZpcnR1YWxseSBzY3JvbGxpbmcgbGlzdC4gKi9cbiAgICBwcml2YXRlIHJvd0NvdW50PzogbnVtYmVyO1xuXG4gICAgcHVibGljIHNjcm9sbGVkSW5kZXhDaGFuZ2U6IE9ic2VydmFibGU8bnVtYmVyPjtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcm93SGVpZ2h0OiBudW1iZXIpIHtcbiAgICAgICAgLy8gZ2l2aW5nIGEgY29udGFjdCBwb2ludCwgc28gdXNlciBjYW4gZG8gc29tZSBzdHVmZiBvZiBcInNjcm9sbGluZ1wiIChjaGFuZ2luZyB0aGUgcmFuZ2UpXG4gICAgICAgIHRoaXMuc2Nyb2xsZWRJbmRleENoYW5nZSA9IHRoaXMuaW5kZXhDaGFuZ2VcbiAgICAgICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGF0dGFjaCh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KTogdm9pZCB7XG4gICAgICAgIHRoaXMudmlld3BvcnQgPSB2aWV3cG9ydDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGV0YWNoKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluZGV4Q2hhbmdlLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMudmlld3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29udGVudFNjcm9sbGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy52aWV3cG9ydCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVDb250ZW50KHRoaXMudmlld3BvcnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uRGF0YUxlbmd0aENoYW5nZWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnZpZXdwb3J0KSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNvbnRlbnQodGhpcy52aWV3cG9ydCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db250ZW50UmVuZGVyZWQoKTogdm9pZCB7fVxuXG4gICAgcHVibGljIG9uUmVuZGVyZWRPZmZzZXRDaGFuZ2VkKCk6IHZvaWQge31cblxuICAgIHB1YmxpYyBzY3JvbGxUb0luZGV4KGluZGV4OiBudW1iZXIsIGJlaGF2aW9yOiBTY3JvbGxCZWhhdmlvcik6IHZvaWQge31cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHNpemUgb2YgdGhlIGl0ZW1zIGluIHRoZSB2aXJ0dWFsbHkgc2Nyb2xsaW5nIGxpc3QuXG4gICAgICogQHBhcmFtIGxlbmd0aFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXREYXRhTGVuZ3RoKGxlbmd0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMucm93Q291bnQgPSBsZW5ndGg7XG4gICAgICAgIHRoaXMudXBkYXRlVmlld3BvcnREYXRhTGVuZ3RoKGxlbmd0aCk7XG4gICAgICAgIHRoaXMub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgc2Nyb2xsIGhlaWdodC5cbiAgICAgKiBAcGFyYW0gcm93SGVpZ2h0XG4gICAgICovXG4gICAgcHVibGljIHNldFJvd0hlaWdodChyb3dIZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnJvd0hlaWdodCA9IHJvd0hlaWdodDtcbiAgICAgICAgaWYgKHRoaXMudmlld3BvcnQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ29udGVudCh0aGlzLnZpZXdwb3J0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgY29udGVudCBhbmQgZW1pdHMgdXBkYXRlZCBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB2aWV3cG9ydFxuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlQ29udGVudCh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KSB7XG4gICAgICAgIGlmICghdmlld3BvcnQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJvd0NvdW50ID0gdGhpcy5yb3dDb3VudCB8fCAwO1xuICAgICAgICBjb25zdCByZW5kZXJlZFJhbmdlID0gdmlld3BvcnQuZ2V0UmVuZGVyZWRSYW5nZSgpO1xuICAgICAgICBjb25zdCBuZXdSYW5nZSA9IHsgLi4ucmVuZGVyZWRSYW5nZSB9O1xuICAgICAgICBjb25zdCB2aWV3cG9ydFNpemUgPSB2aWV3cG9ydC5nZXRWaWV3cG9ydFNpemUoKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsT2Zmc2V0ID0gdmlld3BvcnQubWVhc3VyZVNjcm9sbE9mZnNldCgpIHx8IDA7XG4gICAgICAgIGxldCBmaXJzdFZpc2libGVJbmRleCA9IHNjcm9sbE9mZnNldCAvIHRoaXMucm93SGVpZ2h0IHx8IDA7XG5cbiAgICAgICAgLy8gSWYgdXNlciBzY3JvbGxzIHRvIHRoZSBib3R0b20gb2YgdGhlIGxpc3QgYW5kIGRhdGEgY2hhbmdlcyB0byBhIHNtYWxsZXIgbGlzdFxuICAgICAgICAvLyBXZSBoYXZlIHRvIHJlY2FsY3VsYXRlIHRoZSBmaXJzdCB2aXNpYmxlIGluZGV4IGJhc2VkIG9uIG5ldyBkYXRhIGxlbmd0aCBhbmQgdmlld3BvcnQgc2l6ZS5cbiAgICAgICAgY29uc3QgbWF4VmlzaWJsZUl0ZW1zID0gTWF0aC5jZWlsKHZpZXdwb3J0U2l6ZSAvIHRoaXMucm93SGVpZ2h0KTtcblxuICAgICAgICAvLyBXZSBoYXZlIHRvIHJlY2FsY3VsYXRlIHRoZSBmaXJzdCB2aXNpYmxlIGluZGV4IGJhc2VkIG9uIG5ldyBkYXRhIGxlbmd0aCBhbmQgdmlld3BvcnQgc2l6ZS5cbiAgICAgICAgZmlyc3RWaXNpYmxlSW5kZXggPSBNYXRoLm1heChcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBNYXRoLm1pbihmaXJzdFZpc2libGVJbmRleCwgcm93Q291bnQgLSBtYXhWaXNpYmxlSXRlbXMpXG4gICAgICAgICk7XG4gICAgICAgIC8vIFdlIG11c3QgdXBkYXRlIHNjcm9sbCBvZmZzZXQgdG8gaGFuZGxlIHN0YXJ0L2VuZCBidWZmZXJzXG4gICAgICAgIC8vIEN1cnJlbnQgcmFuZ2UgbXVzdCBhbHNvIGJlIGFkanVzdGVkIHRvIGNvdmVyIHRoZSBuZXcgcG9zaXRpb24gKGJvdHRvbSBvZiBuZXcgbGlzdCkuXG4gICAgICAgIG5ld1JhbmdlLnN0YXJ0ID0gTWF0aC5mbG9vcihmaXJzdFZpc2libGVJbmRleCk7XG5cbiAgICAgICAgbmV3UmFuZ2UuZW5kID0gTWF0aC5tYXgoXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgTWF0aC5taW4ocm93Q291bnQsIG5ld1JhbmdlLnN0YXJ0ICsgbWF4VmlzaWJsZUl0ZW1zKVxuICAgICAgICApO1xuXG4gICAgICAgIHZpZXdwb3J0LnNldFJlbmRlcmVkUmFuZ2UobmV3UmFuZ2UpO1xuICAgICAgICB0aGlzLmluZGV4Q2hhbmdlLm5leHQoTWF0aC5mbG9vcihmaXJzdFZpc2libGVJbmRleCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlVmlld3BvcnREYXRhTGVuZ3RoKHJvd0NvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdwb3J0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm90ZTogVXBkYXRpbmcgX2RhdGFMZW5ndGggcHJvcGVydHkgb2YgY2RrLXZpZXdwb3J0IHRvIG1haW50YWluIGRlZmF1bHQgZnVuY3Rpb25hbGl0aWVzIChnZXREYXRhTGVuZ3RoKCkpXG4gICAgICAgIC8vIG9mIHRoZSBjZGstdmlld3BvcnQgYWxzbyB3aXRoIHRoZSB0YWJsZS4gT3JpZ2luYWxseSB0aGlzIHByb3BlcnR5IGlzIHVwZGF0ZWQgYnlcbiAgICAgICAgLy8gdGhlIFZpcnR1YWxGb3IgbGlzdGVuZXIgd2hpbGUgd2UncmUgdXNpbmcgaXQgdW5jb252ZW50aW9uYWxseSB3ZSBzaG91bGQgdGFrZSBjYXJlIG9mIHRoaXMgcHJvcGVydHkgb3Vyc2VsdmVzXG4gICAgICAgIC8vIFJlZjogaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvY29tcG9uZW50cy9ibG9iLzkuMi54L3NyYy9jZGsvc2Nyb2xsaW5nL3ZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0LnRzI0wyMjdcbiAgICAgICAgdGhpcy52aWV3cG9ydFtcIl9kYXRhTGVuZ3RoXCJdID0gcm93Q291bnQ7XG4gICAgfVxufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkIGluIHYxMSAtIFVzZSBUYWJsZVZpcnR1YWxTY3JvbGxMaW5lYXJTdHJhdGVneSBpbnN0ZWFkIC0gUmVtb3ZhbDogTlVJLTU3OTZcbiAqL1xuZXhwb3J0IGNsYXNzIFRhYmxlVmlydHVhbFNjcm9sbFN0cmF0ZWd5IGltcGxlbWVudHMgVmlydHVhbFNjcm9sbFN0cmF0ZWd5IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluZGV4Q2hhbmdlID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuXG4gICAgcHJpdmF0ZSB2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xuXG4gICAgcHVibGljIHNjcm9sbGVkSW5kZXhDaGFuZ2U6IE9ic2VydmFibGU8bnVtYmVyPjtcblxuICAgIC8qKiBCdWZmZXIgZm9yIGl0ZW1zIGJlZm9yZSBuZWVkaW5nIHRvIHJlbmRlciBtb3JlIGl0ZW1zLiAqL1xuICAgIHByaXZhdGUgYnVmZmVyU2l6ZSA9IDU7XG5cbiAgICAvKiogVGhlIHNpemUgb2YgdGhlIGl0ZW1zIGluIHRoZSB2aXJ0dWFsbHkgc2Nyb2xsaW5nIGxpc3QuICovXG4gICAgcHJpdmF0ZSBpdGVtc1NpemUgPSAwO1xuXG4gICAgcHJpdmF0ZSBfbWF4SXRlbXM6IG51bWJlcjtcblxuICAgIHB1YmxpYyBzZXQgbWF4SXRlbXMobWF4SXRlbXM6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9tYXhJdGVtcyA9IGlzTmFOKG1heEl0ZW1zKSA/IDEwIDogK21heEl0ZW1zO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbWF4SXRlbXMoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heEl0ZW1zO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcm93SGVpZ2h0OiBudW1iZXIsIHByaXZhdGUgaGVhZGVyT2Zmc2V0OiBudW1iZXIpIHtcbiAgICAgICAgLy8gZ2l2aW5nIGEgY29udGFjdCBwb2ludCwgc28gdXNlciBjYW4gZG8gc29tZSBzdHVmZiBvZiBcInNjcm9sbGluZ1wiIChjaGFuZ2luZyB0aGUgcmFuZ2UpXG4gICAgICAgIHRoaXMuc2Nyb2xsZWRJbmRleENoYW5nZSA9IHRoaXMuaW5kZXhDaGFuZ2VcbiAgICAgICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGF0dGFjaCh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KTogdm9pZCB7XG4gICAgICAgIHRoaXMudmlld3BvcnQgPSB2aWV3cG9ydDtcbiAgICAgICAgdGhpcy52aWV3cG9ydC5zZXRUb3RhbENvbnRlbnRTaXplKHRoaXMubWF4SXRlbXMgKiB0aGlzLnJvd0hlaWdodCk7XG4gICAgfVxuXG4gICAgcHVibGljIGRldGFjaCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbmRleENoYW5nZS5jb21wbGV0ZSgpO1xuICAgICAgICAvLyBAdHMtaWdub3JlOiBLZWVwaW5nIHByZXZpb3VzIGJlaGF2aW9yXG4gICAgICAgIHRoaXMudmlld3BvcnQgPSBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNvbnRlbnRTY3JvbGxlZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51cGRhdGVDb250ZW50KHRoaXMudmlld3BvcnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkRhdGFMZW5ndGhDaGFuZ2VkKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy52aWV3cG9ydCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVDb250ZW50KHRoaXMudmlld3BvcnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29udGVudFJlbmRlcmVkKCk6IHZvaWQge31cblxuICAgIHB1YmxpYyBvblJlbmRlcmVkT2Zmc2V0Q2hhbmdlZCgpOiB2b2lkIHt9XG5cbiAgICBwdWJsaWMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyLCBiZWhhdmlvcjogU2Nyb2xsQmVoYXZpb3IpOiB2b2lkIHt9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzaXplIG9mIHRoZSBpdGVtcyBpbiB0aGUgdmlydHVhbGx5IHNjcm9sbGluZyBsaXN0LlxuICAgICAqIEBwYXJhbSBsZW5ndGhcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0RGF0YUxlbmd0aChsZW5ndGg6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLml0ZW1zU2l6ZSA9IGxlbmd0aDtcbiAgICAgICAgdGhpcy5vbkRhdGFMZW5ndGhDaGFuZ2VkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBzY3JvbGwgaGVpZ2h0LlxuICAgICAqIEBwYXJhbSByb3dIZWlnaHRcbiAgICAgKiBAcGFyYW0gaGVhZGVyT2Zmc2V0XG4gICAgICovXG4gICAgcHVibGljIHNldFNjcm9sbEhlaWdodChyb3dIZWlnaHQ6IG51bWJlciwgaGVhZGVyT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XG4gICAgICAgIHRoaXMuaGVhZGVyT2Zmc2V0ID0gaGVhZGVyT2Zmc2V0O1xuICAgICAgICB0aGlzLnVwZGF0ZUNvbnRlbnQodGhpcy52aWV3cG9ydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyBjb250ZW50IGFuZCBlbWl0cyB1cGRhdGVkIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHZpZXdwb3J0XG4gICAgICovXG4gICAgcHJpdmF0ZSB1cGRhdGVDb250ZW50KHZpZXdwb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQpIHtcbiAgICAgICAgaWYgKHZpZXdwb3J0KSB7XG4gICAgICAgICAgICAvLyBNZWFzdXJpbmcgdGhlIG5ldyBzY3JvbGwgaW5kZXguXG4gICAgICAgICAgICBjb25zdCBuZXdJbmRleCA9IE1hdGgubWF4KFxuICAgICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAgICAgTWF0aC5yb3VuZCh2aWV3cG9ydC5tZWFzdXJlU2Nyb2xsT2Zmc2V0KCkgLyB0aGlzLnJvd0hlaWdodClcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3SW5kZXg7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBuZXdJbmRleCArIHRoaXMubWF4SXRlbXM7XG5cbiAgICAgICAgICAgIHZpZXdwb3J0LnNldFJlbmRlcmVkUmFuZ2UoeyBzdGFydCwgZW5kIH0pO1xuXG4gICAgICAgICAgICB0aGlzLmluZGV4Q2hhbmdlLm5leHQobmV3SW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19