UNPKG

material-dynamic-table

Version:

Dynamic table component for angular built on top of angular material table. It offers sorting, pagination, filtering per column and the ability to specify content types and components used for displaying them.

214 lines 31.8 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { Directive, Injector, } from '@angular/core'; import { ComponentPortal } from '@angular/cdk/portal'; import { merge, Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { closest } from './closest'; import { HEADER_ROW_SELECTOR } from './selectors'; import { ResizeRef } from './resize-ref'; import * as i0 from "@angular/core"; const OVERLAY_ACTIVE_CLASS = 'cdk-resizable-overlay-thumb-active'; /** * Base class for Resizable directives which are applied to column headers to make those columns * resizable. */ export class Resizable { constructor() { this.minWidthPxInternal = 0; this.maxWidthPxInternal = Number.MAX_SAFE_INTEGER; this.enabled = false; this.destroyed = new Subject(); this._viewInitialized = false; this._isDestroyed = false; } /** The minimum width to allow the column to be sized to. */ get minWidthPx() { return this.minWidthPxInternal; } set minWidthPx(value) { this.minWidthPxInternal = value; this.columnResize.setResized(); if (this.elementRef.nativeElement && this._viewInitialized) { this._applyMinWidthPx(); } } get settings() { return this.enabled; } set settings(value) { this.enabled = !!value; if (typeof value === 'object') { if (value.minWidth) { this.minWidthPx = value.minWidth; } if (value.maxWidth) { this.maxWidthPx = value.maxWidth; } } } /** The maximum width to allow the column to be sized to. */ get maxWidthPx() { return this.maxWidthPxInternal; } set maxWidthPx(value) { this.maxWidthPxInternal = value; this.columnResize.setResized(); if (this.elementRef.nativeElement && this._viewInitialized) { this._applyMaxWidthPx(); } } ngAfterViewInit() { this._listenForRowHoverEvents(); this._listenForResizeEvents(); this._appendInlineHandle(); this.styleScheduler.scheduleEnd(() => { if (this._isDestroyed) return; this._viewInitialized = true; this._applyMinWidthPx(); this._applyMaxWidthPx(); }); } ngOnDestroy() { this._isDestroyed = true; this.destroyed.next(); this.destroyed.complete(); this.inlineHandle?.remove(); this.overlayRef?.dispose(); } _createOverlayForHandle() { // Use of overlays allows us to properly capture click events spanning parts // of two table cells and is also useful for displaying a resize thumb // over both cells and extending it down the table as needed. const isRtl = this.directionality.value === 'rtl'; const positionStrategy = this.overlay .position() .flexibleConnectedTo(this.elementRef.nativeElement) .withFlexibleDimensions(false) .withGrowAfterOpen(false) .withPush(false) .withDefaultOffsetX(isRtl ? 1 : 0) .withPositions([ { originX: isRtl ? 'start' : 'end', originY: 'top', overlayX: 'center', overlayY: 'top', }, ]); return this.overlay.create({ // Always position the overlay based on left-indexed coordinates. direction: 'ltr', disposeOnNavigation: true, positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition(), width: '16px', }); } _listenForRowHoverEvents() { const element = this.elementRef.nativeElement; const takeUntilDestroyed = takeUntil(this.destroyed); this.eventDispatcher .resizeOverlayVisibleForHeaderRow(closest(element, HEADER_ROW_SELECTOR)) .pipe(takeUntilDestroyed) .subscribe(hoveringRow => { if (hoveringRow && this.enabled) { if (!this.overlayRef) { this.overlayRef = this._createOverlayForHandle(); } this._showHandleOverlay(); } else if (this.overlayRef) { // todo - can't detach during an active resize - need to work that out this.overlayRef.detach(); } }); } _listenForResizeEvents() { const takeUntilDestroyed = takeUntil(this.destroyed); merge(this.resizeNotifier.resizeCanceled, this.resizeNotifier.triggerResize) .pipe(takeUntilDestroyed, filter(columnSize => columnSize.columnId === this.columnDef.name)) .subscribe(({ size, previousSize, completeImmediately }) => { this.elementRef.nativeElement.classList.add(OVERLAY_ACTIVE_CLASS); this._applySize(size, previousSize); if (completeImmediately) { this._completeResizeOperation(); } }); merge(this.resizeNotifier.resizeCanceled, this.resizeNotifier.resizeCompleted) .pipe(takeUntilDestroyed) .subscribe(columnSize => { this._cleanUpAfterResize(columnSize); }); } _completeResizeOperation() { this.ngZone.run(() => { this.resizeNotifier.resizeCompleted.next({ columnId: this.columnDef.name, size: this.elementRef.nativeElement.offsetWidth, }); }); } _cleanUpAfterResize(columnSize) { this.elementRef.nativeElement.classList.remove(OVERLAY_ACTIVE_CLASS); if (this.overlayRef && this.overlayRef.hasAttached()) { this._updateOverlayHandleHeight(); this.overlayRef.updatePosition(); if (columnSize.columnId === this.columnDef.name) { this.inlineHandle.focus(); } } } _createHandlePortal() { const injector = Injector.create({ parent: this.injector, providers: [ { provide: ResizeRef, useValue: new ResizeRef(this.elementRef, this.overlayRef, this.minWidthPx, this.maxWidthPx), }, ], }); return new ComponentPortal(this.getOverlayHandleComponentType(), this.viewContainerRef, injector); } _showHandleOverlay() { this._updateOverlayHandleHeight(); this.overlayRef.attach(this._createHandlePortal()); // Needed to ensure that all of the lifecycle hooks inside the overlay run immediately. this.changeDetectorRef.markForCheck(); } _updateOverlayHandleHeight() { this.overlayRef.updateSize({ height: this.elementRef.nativeElement.offsetHeight }); } _applySize(sizeInPixels, previousSize) { const sizeToApply = Math.min(Math.max(sizeInPixels, this.minWidthPx, 0), this.maxWidthPx); this.resizeStrategy.applyColumnSize(this.columnDef.cssClassFriendlyName, this.elementRef.nativeElement, sizeToApply, previousSize); } _applyMinWidthPx() { this.resizeStrategy.applyMinColumnSize(this.columnDef.cssClassFriendlyName, this.elementRef.nativeElement, this.minWidthPx); } _applyMaxWidthPx() { this.resizeStrategy.applyMaxColumnSize(this.columnDef.cssClassFriendlyName, this.elementRef.nativeElement, this.maxWidthPx); } _appendInlineHandle() { this.styleScheduler.schedule(() => { this.inlineHandle = this.document.createElement('div'); this.inlineHandle.tabIndex = 0; this.inlineHandle.className = this.getInlineHandleCssClassName(); // TODO: Apply correct aria role (probably slider) after a11y spec questions resolved. this.elementRef.nativeElement.appendChild(this.inlineHandle); }); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: Resizable, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: Resizable, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: Resizable, decorators: [{ type: Directive }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbWF0ZXJpYWwtZHluYW1pYy10YWJsZS9zcmMvbGliL2NvbHVtbi1yZXNpemUvcmVzaXphYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFFTCxTQUFTLEVBRVQsUUFBUSxHQU1ULE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUd0RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFcEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBS2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7O0FBR3pDLE1BQU0sb0JBQW9CLEdBQUcsb0NBQW9DLENBQUM7QUFFbEU7OztHQUdHO0FBRUgsTUFBTSxPQUFnQixTQUFTO0lBRC9CO1FBR1ksdUJBQWtCLEdBQVcsQ0FBQyxDQUFDO1FBQy9CLHVCQUFrQixHQUFXLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUNyRCxZQUFPLEdBQVksS0FBSyxDQUFDO1FBSWhCLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBaUIzQyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDekIsaUJBQVksR0FBRyxLQUFLLENBQUM7S0FpUDlCO0lBL09DLDREQUE0RDtJQUM1RCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztJQUNqQyxDQUFDO0lBQ0QsSUFBSSxVQUFVLENBQUMsS0FBYTtRQUMxQixJQUFJLENBQUMsa0JBQWtCLEdBQUcs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QUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBRWpFLHNGQUFzRjtZQUV0RixJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztrSUExUW1CLFNBQVM7c0hBQVQsU0FBUzs7NEZBQVQsU0FBUztrQkFEOUIsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBAbGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKlxyXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxyXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIERpcmVjdGl2ZSxcclxuICBFbGVtZW50UmVmLFxyXG4gIEluamVjdG9yLFxyXG4gIE5nWm9uZSxcclxuICBPbkRlc3Ryb3ksXHJcbiAgVHlwZSxcclxuICBWaWV3Q29udGFpbmVyUmVmLFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcclxuaW1wb3J0IHsgQ29tcG9uZW50UG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XHJcbmltcG9ydCB7IE92ZXJsYXksIE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XHJcbmltcG9ydCB7IENka0NvbHVtbkRlZiwgX0NvYWxlc2NlZFN0eWxlU2NoZWR1bGVyIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3RhYmxlJztcclxuaW1wb3J0IHsgbWVyZ2UsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBjbG9zZXN0IH0gZnJvbSAnLi9jbG9zZXN0JztcclxuXHJcbmltcG9ydCB7IEhFQURFUl9ST1dfU0VMRUNUT1IgfSBmcm9tICcuL3NlbGVjdG9ycyc7XHJcbmltcG9ydCB7IFJlc2l6ZU92ZXJsYXlIYW5kbGUgfSBmcm9tICcuL2Nkay1vdmVybGF5LWhhbmRsZSc7XHJcbmltcG9ydCB7IENvbHVtblJlc2l6ZSB9IGZyb20gJy4vY29sdW1uLXJlc2l6ZSc7XHJcbmltcG9ydCB7IENvbHVtblNpemVBY3Rpb24sIENvbHVtblJlc2l6ZU5vdGlmaWVyU291cmNlIH0gZnJvbSAnLi9jb2x1bW4tcmVzaXplLW5vdGlmaWVyJztcclxuaW1wb3J0IHsgSGVhZGVyUm93RXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi9ldmVudC1kaXNwYXRjaGVyJztcclxuaW1wb3J0IHsgUmVzaXplUmVmIH0gZnJvbSAnLi9yZXNpemUtcmVmJztcclxuaW1wb3J0IHsgUmVzaXplU3RyYXRlZ3kgfSBmcm9tICcuL3Jlc2l6ZS1zdHJhdGVneSc7XHJcblxyXG5jb25zdCBPVkVSTEFZX0FDVElWRV9DTEFTUyA9ICdjZGstcmVzaXphYmxlLW92ZXJsYXktdGh1bWItYWN0aXZlJztcclxuXHJcbi8qKlxyXG4gKiBCYXNlIGNsYXNzIGZvciBSZXNpemFibGUgZGlyZWN0aXZlcyB3aGljaCBhcmUgYXBwbGllZCB0byBjb2x1bW4gaGVhZGVycyB0byBtYWtlIHRob3NlIGNvbHVtbnNcclxuICogcmVzaXphYmxlLlxyXG4gKi9cclxuQERpcmVjdGl2ZSgpXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBSZXNpemFibGU8SGFuZGxlQ29tcG9uZW50IGV4dGVuZHMgUmVzaXplT3ZlcmxheUhhbmRsZT5cclxuICBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XHJcbiAgcHJvdGVjdGVkIG1pbldpZHRoUHhJbnRlcm5hbDogbnVtYmVyID0gMDtcclxuICBwcm90ZWN0ZWQgbWF4V2lkdGhQeEludGVybmFsOiBudW1iZXIgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcclxuICBwcm90ZWN0ZWQgZW5hYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwcm90ZWN0ZWQgaW5saW5lSGFuZGxlPzogSFRNTEVsZW1lbnQ7XHJcbiAgcHJvdGVjdGVkIG92ZXJsYXlSZWY/OiBPdmVybGF5UmVmO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSBkZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgY29sdW1uRGVmOiBDZGtDb2x1bW5EZWY7XHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IGNvbHVtblJlc2l6ZTogQ29sdW1uUmVzaXplO1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSBkaXJlY3Rpb25hbGl0eTogRGlyZWN0aW9uYWxpdHk7XHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IGRvY3VtZW50OiBEb2N1bWVudDtcclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgZWxlbWVudFJlZjogRWxlbWVudFJlZjtcclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgZXZlbnREaXNwYXRjaGVyOiBIZWFkZXJSb3dFdmVudERpc3BhdGNoZXI7XHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IGluamVjdG9yOiBJbmplY3RvcjtcclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgbmdab25lOiBOZ1pvbmU7XHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IG92ZXJsYXk6IE92ZXJsYXk7XHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IHJlc2l6ZU5vdGlmaWVyOiBDb2x1bW5SZXNpemVOb3RpZmllclNvdXJjZTtcclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgcmVzaXplU3RyYXRlZ3k6IFJlc2l6ZVN0cmF0ZWd5O1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSBzdHlsZVNjaGVkdWxlcjogX0NvYWxlc2NlZFN0eWxlU2NoZWR1bGVyO1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmO1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWY7XHJcblxyXG4gIHByaXZhdGUgX3ZpZXdJbml0aWFsaXplZCA9IGZhbHNlO1xyXG4gIHByaXZhdGUgX2lzRGVzdHJveWVkID0gZmFsc2U7XHJcblxyXG4gIC8qKiBUaGUgbWluaW11bSB3aWR0aCB0byBhbGxvdyB0aGUgY29sdW1uIHRvIGJlIHNpemVkIHRvLiAqL1xyXG4gIGdldCBtaW5XaWR0aFB4KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5taW5XaWR0aFB4SW50ZXJuYWw7XHJcbiAgfVxyXG4gIHNldCBtaW5XaWR0aFB4KHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMubWluV2lkdGhQeEludGVybmFsID0gdmFsdWU7XHJcblxyXG4gICAgdGhpcy5jb2x1bW5SZXNpemUuc2V0UmVzaXplZCgpO1xyXG4gICAgaWYgKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ICYmIHRoaXMuX3ZpZXdJbml0aWFsaXplZCkge1xyXG4gICAgICB0aGlzLl9hcHBseU1pbldpZHRoUHgoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBzZXR0aW5ncygpOiBib29sZWFuIHwgeyBtaW5XaWR0aDogbnVtYmVyLCBtYXhXaWR0aDogbnVtYmVyIH0ge1xyXG4gICAgcmV0dXJuIHRoaXMuZW5hYmxlZDtcclxuICB9XHJcbiAgc2V0IHNldHRpbmdzKHZhbHVlOiBib29sZWFuIHwgeyBtaW5XaWR0aDogbnVtYmVyLCBtYXhXaWR0aDogbnVtYmVyIH0pIHtcclxuICAgIHRoaXMuZW5hYmxlZCA9ICEhdmFsdWU7XHJcblxyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgaWYgKHZhbHVlLm1pbldpZHRoKSB7XHJcbiAgICAgICAgdGhpcy5taW5XaWR0aFB4ID0gdmFsdWUubWluV2lkdGg7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHZhbHVlLm1heFdpZHRoKSB7XHJcbiAgICAgICAgdGhpcy5tYXhXaWR0aFB4ID0gdmFsdWUubWF4V2lkdGg7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBUaGUgbWF4aW11bSB3aWR0aCB0byBhbGxvdyB0aGUgY29sdW1uIHRvIGJlIHNpemVkIHRvLiAqL1xyXG4gIGdldCBtYXhXaWR0aFB4KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5tYXhXaWR0aFB4SW50ZXJuYWw7XHJcbiAgfVxyXG4gIHNldCBtYXhXaWR0aFB4KHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMubWF4V2lkdGhQeEludGVybmFsID0gdmFsdWU7XHJcblxyXG4gICAgdGhpcy5jb2x1bW5SZXNpemUuc2V0UmVzaXplZCgpO1xyXG4gICAgaWYgKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ICYmIHRoaXMuX3ZpZXdJbml0aWFsaXplZCkge1xyXG4gICAgICB0aGlzLl9hcHBseU1heFdpZHRoUHgoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMuX2xpc3RlbkZvclJvd0hvdmVyRXZlbnRzKCk7XHJcbiAgICB0aGlzLl9saXN0ZW5Gb3JSZXNpemVFdmVudHMoKTtcclxuICAgIHRoaXMuX2FwcGVuZElubGluZUhhbmRsZSgpO1xyXG5cclxuICAgIHRoaXMuc3R5bGVTY2hlZHVsZXIuc2NoZWR1bGVFbmQoKCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5faXNEZXN0cm95ZWQpIHJldHVybjtcclxuICAgICAgdGhpcy5fdmlld0luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgdGhpcy5fYXBwbHlNaW5XaWR0aFB4KCk7XHJcbiAgICAgIHRoaXMuX2FwcGx5TWF4V2lkdGhQeCgpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2lzRGVzdHJveWVkID0gdHJ1ZTtcclxuICAgIHRoaXMuZGVzdHJveWVkLm5leHQoKTtcclxuICAgIHRoaXMuZGVzdHJveWVkLmNvbXBsZXRlKCk7XHJcbiAgICB0aGlzLmlubGluZUhhbmRsZT8ucmVtb3ZlKCk7XHJcbiAgICB0aGlzLm92ZXJsYXlSZWY/LmRpc3Bvc2UoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRJbmxpbmVIYW5kbGVDc3NDbGFzc05hbWUoKTogc3RyaW5nO1xyXG5cclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0T3ZlcmxheUhhbmRsZUNvbXBvbmVudFR5cGUoKTogVHlwZTxIYW5kbGVDb21wb25lbnQ+O1xyXG5cclxuICBwcml2YXRlIF9jcmVhdGVPdmVybGF5Rm9ySGFuZGxlKCk6IE92ZXJsYXlSZWYge1xyXG4gICAgLy8gVXNlIG9mIG92ZXJsYXlzIGFsbG93cyB1cyB0byBwcm9wZXJseSBjYXB0dXJlIGNsaWNrIGV2ZW50cyBzcGFubmluZyBwYXJ0c1xyXG4gICAgLy8gb2YgdHdvIHRhYmxlIGNlbGxzIGFuZCBpcyBhbHNvIHVzZWZ1bCBmb3IgZGlzcGxheWluZyBhIHJlc2l6ZSB0aHVtYlxyXG4gICAgLy8gb3ZlciBib3RoIGNlbGxzIGFuZCBleHRlbmRpbmcgaXQgZG93biB0aGUgdGFibGUgYXMgbmVlZGVkLlxyXG5cclxuICAgIGNvbnN0IGlzUnRsID0gdGhpcy5kaXJlY3Rpb25hbGl0eS52YWx1ZSA9PT0gJ3J0bCc7XHJcbiAgICBjb25zdCBwb3NpdGlvblN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5XHJcbiAgICAgIC5wb3NpdGlvbigpXHJcbiAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ISlcclxuICAgICAgLndpdGhGbGV4aWJsZURpbWVuc2lvbnMoZmFsc2UpXHJcbiAgICAgIC53aXRoR3Jvd0FmdGVyT3BlbihmYWxzZSlcclxuICAgICAgLndpdGhQdXNoKGZhbHNlKVxyXG4gICAgICAud2l0aERlZmF1bHRPZmZzZXRYKGlzUnRsID8gMSA6IDApXHJcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBvcmlnaW5YOiBpc1J0bCA/ICdzdGFydCcgOiAnZW5kJyxcclxuICAgICAgICAgIG9yaWdpblk6ICd0b3AnLFxyXG4gICAgICAgICAgb3ZlcmxheVg6ICdjZW50ZXInLFxyXG4gICAgICAgICAgb3ZlcmxheVk6ICd0b3AnLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzLm92ZXJsYXkuY3JlYXRlKHtcclxuICAgICAgLy8gQWx3YXlzIHBvc2l0aW9uIHRoZSBvdmVybGF5IGJhc2VkIG9uIGxlZnQtaW5kZXhlZCBjb29yZGluYXRlcy5cclxuICAgICAgZGlyZWN0aW9uOiAnbHRyJyxcclxuICAgICAgZGlzcG9zZU9uTmF2aWdhdGlvbjogdHJ1ZSxcclxuICAgICAgcG9zaXRpb25TdHJhdGVneSxcclxuICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMub3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLnJlcG9zaXRpb24oKSxcclxuICAgICAgd2lkdGg6ICcxNnB4JyxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfbGlzdGVuRm9yUm93SG92ZXJFdmVudHMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQhO1xyXG4gICAgY29uc3QgdGFrZVVudGlsRGVzdHJveWVkID0gdGFrZVVudGlsPGJvb2xlYW4+KHRoaXMuZGVzdHJveWVkKTtcclxuXHJcbiAgICB0aGlzLmV2ZW50RGlzcGF0Y2hlclxyXG4gICAgICAucmVzaXplT3ZlcmxheVZpc2libGVGb3JIZWFkZXJSb3coY2xvc2VzdChlbGVtZW50LCBIRUFERVJfUk9XX1NFTEVDVE9SKSEpXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZClcclxuICAgICAgLnN1YnNjcmliZShob3ZlcmluZ1JvdyA9PiB7XHJcbiAgICAgICAgaWYgKGhvdmVyaW5nUm93ICYmIHRoaXMuZW5hYmxlZCkge1xyXG4gICAgICAgICAgaWYgKCF0aGlzLm92ZXJsYXlSZWYpIHtcclxuICAgICAgICAgICAgdGhpcy5vdmVybGF5UmVmID0gdGhpcy5fY3JlYXRlT3ZlcmxheUZvckhhbmRsZSgpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHRoaXMuX3Nob3dIYW5kbGVPdmVybGF5KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm92ZXJsYXlSZWYpIHtcclxuICAgICAgICAgIC8vIHRvZG8gLSBjYW4ndCBkZXRhY2ggZHVyaW5nIGFuIGFjdGl2ZSByZXNpemUgLSBuZWVkIHRvIHdvcmsgdGhhdCBvdXRcclxuICAgICAgICAgIHRoaXMub3ZlcmxheVJlZi5kZXRhY2goKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfbGlzdGVuRm9yUmVzaXplRXZlbnRzKCkge1xyXG4gICAgY29uc3QgdGFrZVVudGlsRGVzdHJveWVkID0gdGFrZVVudGlsPENvbHVtblNpemVBY3Rpb24+KHRoaXMuZGVzdHJveWVkKTtcclxuXHJcbiAgICBtZXJnZSh0aGlzLnJlc2l6ZU5vdGlmaWVyLnJlc2l6ZUNhbmNlbGVkLCB0aGlzLnJlc2l6ZU5vdGlmaWVyLnRyaWdnZXJSZXNpemUpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCxcclxuICAgICAgICBmaWx0ZXIoY29sdW1uU2l6ZSA9PiBjb2x1bW5TaXplLmNvbHVtbklkID09PSB0aGlzLmNvbHVtbkRlZi5uYW1lKSxcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKCh7IHNpemUsIHByZXZpb3VzU2l6ZSwgY29tcGxldGVJbW1lZGlhdGVseSB9KSA9PiB7XHJcbiAgICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQhLmNsYXNzTGlzdC5hZGQoT1ZFUkxBWV9BQ1RJVkVfQ0xBU1MpO1xyXG4gICAgICAgIHRoaXMuX2FwcGx5U2l6ZShzaXplLCBwcmV2aW91c1NpemUpO1xyXG5cclxuICAgICAgICBpZiAoY29tcGxldGVJbW1lZGlhdGVseSkge1xyXG4gICAgICAgICAgdGhpcy5fY29tcGxldGVSZXNpemVPcGVyYXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIG1lcmdlKHRoaXMucmVzaXplTm90aWZpZXIucmVzaXplQ2FuY2VsZWQsIHRoaXMucmVzaXplTm90aWZpZXIucmVzaXplQ29tcGxldGVkKVxyXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQpXHJcbiAgICAgIC5zdWJzY3JpYmUoY29sdW1uU2l6ZSA9PiB7XHJcbiAgICAgICAgdGhpcy5fY2xlYW5VcEFmdGVyUmVzaXplKGNvbHVtblNpemUpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NvbXBsZXRlUmVzaXplT3BlcmF0aW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcclxuICAgICAgdGhpcy5yZXNpemVOb3RpZmllci5yZXNpemVDb21wbGV0ZWQubmV4dCh7XHJcbiAgICAgICAgY29sdW1uSWQ6IHRoaXMuY29sdW1uRGVmLm5hbWUsXHJcbiAgICAgICAgc2l6ZTogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQhLm9mZnNldFdpZHRoLFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2xlYW5VcEFmdGVyUmVzaXplKGNvbHVtblNpemU6IENvbHVtblNpemVBY3Rpb24pOiB2b2lkIHtcclxuICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IS5jbGFzc0xpc3QucmVtb3ZlKE9WRVJMQVlfQUNUSVZFX0NMQVNTKTtcclxuXHJcbiAgICBpZiAodGhpcy5vdmVybGF5UmVmICYmIHRoaXMub3ZlcmxheVJlZi5oYXNBdHRhY2hlZCgpKSB7XHJcbiAgICAgIHRoaXMuX3VwZGF0ZU92ZXJsYXlIYW5kbGVIZWlnaHQoKTtcclxuICAgICAgdGhpcy5vdmVybGF5UmVmLnVwZGF0ZVBvc2l0aW9uKCk7XHJcblxyXG4gICAgICBpZiAoY29sdW1uU2l6ZS5jb2x1bW5JZCA9PT0gdGhpcy5jb2x1bW5EZWYubmFtZSkge1xyXG4gICAgICAgIHRoaXMuaW5saW5lSGFuZGxlIS5mb2N1cygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9jcmVhdGVIYW5kbGVQb3J0YWwoKTogQ29tcG9uZW50UG9ydGFsPEhhbmRsZUNvbXBvbmVudD4ge1xyXG4gICAgY29uc3QgaW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUoe1xyXG4gICAgICBwYXJlbnQ6IHRoaXMuaW5qZWN0b3IsXHJcbiAgICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFJlc2l6ZVJlZixcclxuICAgICAgICAgIHVzZVZhbHVlOiBuZXcgUmVzaXplUmVmKFxyXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYsXHJcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVJlZiEsXHJcbiAgICAgICAgICAgIHRoaXMubWluV2lkdGhQeCxcclxuICAgICAgICAgICAgdGhpcy5tYXhXaWR0aFB4LFxyXG4gICAgICAgICAgKSxcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBDb21wb25lbnRQb3J0YWwoXHJcbiAgICAgIHRoaXMuZ2V0T3ZlcmxheUhhbmRsZUNvbXBvbmVudFR5cGUoKSxcclxuICAgICAgdGhpcy52aWV3Q29udGFpbmVyUmVmLFxyXG4gICAgICBpbmplY3RvcixcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zaG93SGFuZGxlT3ZlcmxheSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX3VwZGF0ZU92ZXJsYXlIYW5kbGVIZWlnaHQoKTtcclxuICAgIHRoaXMub3ZlcmxheVJlZiEuYXR0YWNoKHRoaXMuX2NyZWF0ZUhhbmRsZVBvcnRhbCgpKTtcclxuXHJcbiAgICAvLyBOZWVkZWQgdG8gZW5zdXJlIHRoYXQgYWxsIG9mIHRoZSBsaWZlY3ljbGUgaG9va3MgaW5zaWRlIHRoZSBvdmVybGF5IHJ1biBpbW1lZGlhdGVseS5cclxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF91cGRhdGVPdmVybGF5SGFuZGxlSGVpZ2h0KCkge1xyXG4gICAgdGhpcy5vdmVybGF5UmVmIS51cGRhdGVTaXplKHsgaGVpZ2h0OiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCEub2Zmc2V0SGVpZ2h0IH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfYXBwbHlTaXplKHNpemVJblBpeGVsczogbnVtYmVyLCBwcmV2aW91c1NpemU/OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNpemVUb0FwcGx5ID0gTWF0aC5taW4oTWF0aC5tYXgoc2l6ZUluUGl4ZWxzLCB0aGlzLm1pbldpZHRoUHgsIDApLCB0aGlzLm1heFdpZHRoUHgpO1xyXG5cclxuICAgIHRoaXMucmVzaXplU3RyYXRlZ3kuYXBwbHlDb2x1bW5TaXplKFxyXG4gICAgICB0aGlzLmNvbHVtbkRlZi5jc3NDbGFzc0ZyaWVuZGx5TmFtZSxcclxuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQhLFxyXG4gICAgICBzaXplVG9BcHBseSxcclxuICAgICAgcHJldmlvdXNTaXplLFxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2FwcGx5TWluV2lkdGhQeCgpOiB2b2lkIHtcclxuICAgIHRoaXMucmVzaXplU3RyYXRlZ3kuYXBwbHlNaW5Db2x1bW5TaXplKFxyXG4gICAgICB0aGlzLmNvbHVtbkRlZi5jc3NDbGFzc0ZyaWVuZGx5TmFtZSxcclxuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXHJcbiAgICAgIHRoaXMubWluV2lkdGhQeCxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9hcHBseU1heFdpZHRoUHgoKTogdm9pZCB7XHJcbiAgICB0aGlzLnJlc2l6ZVN0cmF0ZWd5LmFwcGx5TWF4Q29sdW1uU2l6ZShcclxuICAgICAgdGhpcy5jb2x1bW5EZWYuY3NzQ2xhc3NGcmllbmRseU5hbWUsXHJcbiAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LFxyXG4gICAgICB0aGlzLm1heFdpZHRoUHgsXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfYXBwZW5kSW5saW5lSGFuZGxlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zdHlsZVNjaGVkdWxlci5zY2hlZHVsZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMuaW5saW5lSGFuZGxlID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgdGhpcy5pbmxpbmVIYW5kbGUudGFiSW5kZXggPSAwO1xyXG4gICAgICB0aGlzLmlubGluZUhhbmRsZS5jbGFzc05hbWUgPSB0aGlzLmdldElubGluZUhhbmRsZUNzc0NsYXNzTmFtZSgpO1xyXG5cclxuICAgICAgLy8gVE9ETzogQXBwbHkgY29ycmVjdCBhcmlhIHJvbGUgKHByb2JhYmx5IHNsaWRlcikgYWZ0ZXIgYTExeSBzcGVjIHF1ZXN0aW9ucyByZXNvbHZlZC5cclxuXHJcbiAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IS5hcHBlbmRDaGlsZCh0aGlzLmlubGluZUhhbmRsZSk7XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIl19