UNPKG

angular-grid-layout-ngx13

Version:

Grid Layout with draggable and resizable items for Angular

175 lines 34.7 kB
import { ChangeDetectionStrategy, Component, ContentChildren, ElementRef, Inject, Input, ViewChild } from '@angular/core'; import { BehaviorSubject, iif, merge, NEVER, Subject } from 'rxjs'; import { exhaustMap, filter, map, startWith, switchMap, take, takeUntil } from 'rxjs/operators'; import { ktdMouseOrTouchDown, ktdMouseOrTouchEnd, ktdPointerClient } from '../utils/pointer.utils'; import { GRID_ITEM_GET_RENDER_DATA_TOKEN } from '../grid.definitions'; import { KTD_GRID_DRAG_HANDLE } from '../directives/drag-handle'; import { KTD_GRID_RESIZE_HANDLE } from '../directives/resize-handle'; import { ktdOutsideZone } from '../utils/operators'; import { coerceBooleanProperty } from '../coercion/boolean-property'; import { coerceNumberProperty } from '../coercion/number-property'; import * as i0 from "@angular/core"; import * as i1 from "../grid.service"; export class KtdGridItemComponent { constructor(elementRef, gridService, renderer, ngZone, getItemRenderData) { this.elementRef = elementRef; this.gridService = gridService; this.renderer = renderer; this.ngZone = ngZone; this.getItemRenderData = getItemRenderData; /** CSS transition style. Note that for more performance is preferable only make transition on transform property. */ this.transition = 'transform 500ms ease, width 500ms ease, height 500ms ease'; this._dragStartThreshold = 0; this._draggable = true; this._draggable$ = new BehaviorSubject(this._draggable); this._resizable = true; this._resizable$ = new BehaviorSubject(this._resizable); this.dragStartSubject = new Subject(); this.resizeStartSubject = new Subject(); this.subscriptions = []; this.dragStart$ = this.dragStartSubject.asObservable(); this.resizeStart$ = this.resizeStartSubject.asObservable(); } /** Id of the grid item. This property is strictly compulsory. */ get id() { return this._id; } set id(val) { this._id = val; } /** Minimum amount of pixels that the user should move before it starts the drag sequence. */ get dragStartThreshold() { return this._dragStartThreshold; } set dragStartThreshold(val) { this._dragStartThreshold = coerceNumberProperty(val); } /** Whether the item is draggable or not. Defaults to true. */ get draggable() { return this._draggable; } set draggable(val) { this._draggable = coerceBooleanProperty(val); this._draggable$.next(this._draggable); } /** Whether the item is resizable or not. Defaults to true. */ get resizable() { return this._resizable; } set resizable(val) { this._resizable = coerceBooleanProperty(val); this._resizable$.next(this._resizable); } ngOnInit() { const gridItemRenderData = this.getItemRenderData(this.id); this.setStyles(gridItemRenderData); } ngAfterContentInit() { this.subscriptions.push(this._dragStart$().subscribe(this.dragStartSubject), this._resizeStart$().subscribe(this.resizeStartSubject)); } ngOnDestroy() { this.subscriptions.forEach(sub => sub.unsubscribe()); } setStyles({ top, left, width, height }) { // transform is 6x times faster than top/left this.renderer.setStyle(this.elementRef.nativeElement, 'transform', `translateX(${left}) translateY(${top})`); this.renderer.setStyle(this.elementRef.nativeElement, 'display', `block`); this.renderer.setStyle(this.elementRef.nativeElement, 'transition', this.transition); if (width != null) { this.renderer.setStyle(this.elementRef.nativeElement, 'width', width); } if (height != null) { this.renderer.setStyle(this.elementRef.nativeElement, 'height', height); } } _dragStart$() { return this._draggable$.pipe(switchMap((draggable) => { if (!draggable) { return NEVER; } else { return this._dragHandles.changes.pipe(startWith(this._dragHandles), switchMap((dragHandles) => { return iif(() => dragHandles.length > 0, merge(...dragHandles.toArray().map(dragHandle => ktdMouseOrTouchDown(dragHandle.element.nativeElement, 1))), ktdMouseOrTouchDown(this.elementRef.nativeElement, 1)).pipe(exhaustMap((startEvent) => { // If the event started from an element with the native HTML drag&drop, it'll interfere // with our own dragging (e.g. `img` tags do it by default). Prevent the default action // to stop it from happening. Note that preventing on `dragstart` also seems to work, but // it's flaky and it fails if the user drags it away quickly. Also note that we only want // to do this for `mousedown` since doing the same for `touchstart` will stop any `click` // events from firing on touch devices. if (startEvent.target && startEvent.target.draggable && startEvent.type === 'mousedown') { startEvent.preventDefault(); } const startPointer = ktdPointerClient(startEvent); return this.gridService.mouseOrTouchMove$(document).pipe(takeUntil(ktdMouseOrTouchEnd(document, 1)), ktdOutsideZone(this.ngZone), filter((moveEvent) => { moveEvent.preventDefault(); const movePointer = ktdPointerClient(moveEvent); const distanceX = Math.abs(startPointer.clientX - movePointer.clientX); const distanceY = Math.abs(startPointer.clientY - movePointer.clientY); // When this conditions returns true mean that we are over threshold. return distanceX + distanceY >= this.dragStartThreshold; }), take(1), // Return the original start event map(() => startEvent)); })); })); } })); } _resizeStart$() { return this._resizable$.pipe(switchMap((resizable) => { if (!resizable) { // Side effect to hide the resizeElem if resize is disabled. this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'none'); return NEVER; } else { return this._resizeHandles.changes.pipe(startWith(this._resizeHandles), switchMap((resizeHandles) => { if (resizeHandles.length > 0) { // Side effect to hide the resizeElem if there are resize handles. this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'none'); return merge(...resizeHandles.toArray().map(resizeHandle => ktdMouseOrTouchDown(resizeHandle.element.nativeElement, 1))); } else { this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'block'); return ktdMouseOrTouchDown(this.resizeElem.nativeElement, 1); } })); } })); } } KtdGridItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: KtdGridItemComponent, deps: [{ token: i0.ElementRef }, { token: i1.KtdGridService }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: GRID_ITEM_GET_RENDER_DATA_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); KtdGridItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: KtdGridItemComponent, selector: "ktd-grid-item", inputs: { minW: "minW", minH: "minH", maxW: "maxW", maxH: "maxH", transition: "transition", id: "id", dragStartThreshold: "dragStartThreshold", draggable: "draggable", resizable: "resizable" }, queries: [{ propertyName: "_dragHandles", predicate: KTD_GRID_DRAG_HANDLE, descendants: true }, { propertyName: "_resizeHandles", predicate: KTD_GRID_RESIZE_HANDLE, descendants: true }], viewQueries: [{ propertyName: "resizeElem", first: true, predicate: ["resizeElem"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<ng-content></ng-content>\n<div #resizeElem class=\"grid-item-resize-icon\"></div>\n", styles: [":host{display:none;position:absolute;z-index:1;overflow:hidden}:host div{position:absolute;-webkit-user-select:none;user-select:none;z-index:10}:host div.grid-item-resize-icon{cursor:se-resize;width:20px;height:20px;bottom:0;right:0;color:inherit}:host div.grid-item-resize-icon:after{content:\"\";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid;border-bottom:2px solid}.display-none{display:none!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: KtdGridItemComponent, decorators: [{ type: Component, args: [{ selector: 'ktd-grid-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n<div #resizeElem class=\"grid-item-resize-icon\"></div>\n", styles: [":host{display:none;position:absolute;z-index:1;overflow:hidden}:host div{position:absolute;-webkit-user-select:none;user-select:none;z-index:10}:host div.grid-item-resize-icon{cursor:se-resize;width:20px;height:20px;bottom:0;right:0;color:inherit}:host div.grid-item-resize-icon:after{content:\"\";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid;border-bottom:2px solid}.display-none{display:none!important}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.KtdGridService }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: undefined, decorators: [{ type: Inject, args: [GRID_ITEM_GET_RENDER_DATA_TOKEN] }] }]; }, propDecorators: { _dragHandles: [{ type: ContentChildren, args: [KTD_GRID_DRAG_HANDLE, { descendants: true }] }], _resizeHandles: [{ type: ContentChildren, args: [KTD_GRID_RESIZE_HANDLE, { descendants: true }] }], resizeElem: [{ type: ViewChild, args: ['resizeElem', { static: true, read: ElementRef }] }], minW: [{ type: Input }], minH: [{ type: Input }], maxW: [{ type: Input }], maxH: [{ type: Input }], transition: [{ type: Input }], id: [{ type: Input }], dragStartThreshold: [{ type: Input }], draggable: [{ type: Input }], resizable: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItZ3JpZC1sYXlvdXQvc3JjL2xpYi9ncmlkLWl0ZW0vZ3JpZC1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItZ3JpZC1sYXlvdXQvc3JjL2xpYi9ncmlkLWl0ZW0vZ3JpZC1pdGVtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDZSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUNoRyxTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzdGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNuRyxPQUFPLEVBQUUsK0JBQStCLEVBQWtDLE1BQU0scUJBQXFCLENBQUM7QUFDdEcsT0FBTyxFQUFFLG9CQUFvQixFQUFxQixNQUFNLDJCQUEyQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxzQkFBc0IsRUFBdUIsTUFBTSw2QkFBNkIsQ0FBQztBQUUxRixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFnQixxQkFBcUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ25GLE9BQU8sRUFBRSxvQkFBb0IsRUFBZSxNQUFNLDZCQUE2QixDQUFD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WixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUdHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBT0YsRUFBRTtzQkFETCxLQUFLO2dCQWFGLGtCQUFrQjtzQkFEckIsS0FBSztnQkFZRixTQUFTO3NCQURaLEtBQUs7Z0JBZUYsU0FBUztzQkFEWixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBZnRlckNvbnRlbnRJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGRyZW4sIEVsZW1lbnRSZWYsIEluamVjdCwgSW5wdXQsIE5nWm9uZSwgT25EZXN0cm95LCBPbkluaXQsIFF1ZXJ5TGlzdCwgUmVuZGVyZXIyLFxuICAgIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgaWlmLCBtZXJnZSwgTkVWRVIsIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZXhoYXVzdE1hcCwgZmlsdGVyLCBtYXAsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBrdGRNb3VzZU9yVG91Y2hEb3duLCBrdGRNb3VzZU9yVG91Y2hFbmQsIGt0ZFBvaW50ZXJDbGllbnQgfSBmcm9tICcuLi91dGlscy9wb2ludGVyLnV0aWxzJztcbmltcG9ydCB7IEdSSURfSVRFTV9HRVRfUkVOREVSX0RBVEFfVE9LRU4sIEt0ZEdyaWRJdGVtUmVuZGVyRGF0YVRva2VuVHlwZSB9IGZyb20gJy4uL2dyaWQuZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgS1REX0dSSURfRFJBR19IQU5ETEUsIEt0ZEdyaWREcmFnSGFuZGxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9kcmFnLWhhbmRsZSc7XG5pbXBvcnQgeyBLVERfR1JJRF9SRVNJWkVfSEFORExFLCBLdGRHcmlkUmVzaXplSGFuZGxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9yZXNpemUtaGFuZGxlJztcbmltcG9ydCB7IEt0ZEdyaWRTZXJ2aWNlIH0gZnJvbSAnLi4vZ3JpZC5zZXJ2aWNlJztcbmltcG9ydCB7IGt0ZE91dHNpZGVab25lIH0gZnJvbSAnLi4vdXRpbHMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgY29lcmNlQm9vbGVhblByb3BlcnR5IH0gZnJvbSAnLi4vY29lcmNpb24vYm9vbGVhbi1wcm9wZXJ0eSc7XG5pbXBvcnQgeyBjb2VyY2VOdW1iZXJQcm9wZXJ0eSwgTnVtYmVySW5wdXQgfSBmcm9tICcuLi9jb2VyY2lvbi9udW1iZXItcHJvcGVydHknO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2t0ZC1ncmlkLWl0ZW0nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9ncmlkLWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2dyaWQtaXRlbS5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIEt0ZEdyaWRJdGVtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudEluaXQge1xuICAgIC8qKiBFbGVtZW50cyB0aGF0IGNhbiBiZSB1c2VkIHRvIGRyYWcgdGhlIGdyaWQgaXRlbS4gKi9cbiAgICBAQ29udGVudENoaWxkcmVuKEtURF9HUklEX0RSQUdfSEFORExFLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfZHJhZ0hhbmRsZXM6IFF1ZXJ5TGlzdDxLdGRHcmlkRHJhZ0hhbmRsZT47XG4gICAgQENvbnRlbnRDaGlsZHJlbihLVERfR1JJRF9SRVNJWkVfSEFORExFLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfcmVzaXplSGFuZGxlczogUXVlcnlMaXN0PEt0ZEdyaWRSZXNpemVIYW5kbGU+O1xuICAgIEBWaWV3Q2hpbGQoJ3Jlc2l6ZUVsZW0nLCB7c3RhdGljOiB0cnVlLCByZWFkOiBFbGVtZW50UmVmfSkgcmVzaXplRWxlbTogRWxlbWVudFJlZjtcblxuICAgIC8qKiBNaW4gYW5kIG1heCBzaXplIGlucHV0IHByb3BlcnRpZXMuIEFueSBvZiB0aGVzZSB3b3VsZCAnb3ZlcnJpZGUnIHRoZSBtaW4vbWF4IHZhbHVlcyBzcGVjaWZpZWQgaW4gdGhlIGxheW91dC4gKi9cbiAgICBASW5wdXQoKSBtaW5XPzogbnVtYmVyO1xuICAgIEBJbnB1dCgpIG1pbkg/OiBudW1iZXI7XG4gICAgQElucHV0KCkgbWF4Vz86IG51bWJlcjtcbiAgICBASW5wdXQoKSBtYXhIPzogbnVtYmVyO1xuXG4gICAgLyoqIENTUyB0cmFuc2l0aW9uIHN0eWxlLiBOb3RlIHRoYXQgZm9yIG1vcmUgcGVyZm9ybWFuY2UgaXMgcHJlZmVyYWJsZSBvbmx5IG1ha2UgdHJhbnNpdGlvbiBvbiB0cmFuc2Zvcm0gcHJvcGVydHkuICovXG4gICAgQElucHV0KCkgdHJhbnNpdGlvbjogc3RyaW5nID0gJ3RyYW5zZm9ybSA1MDBtcyBlYXNlLCB3aWR0aCA1MDBtcyBlYXNlLCBoZWlnaHQgNTAwbXMgZWFzZSc7XG5cbiAgICBkcmFnU3RhcnQkOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PjtcbiAgICByZXNpemVTdGFydCQ6IE9ic2VydmFibGU8TW91c2VFdmVudCB8IFRvdWNoRXZlbnQ+O1xuXG4gICAgLyoqIElkIG9mIHRoZSBncmlkIGl0ZW0uIFRoaXMgcHJvcGVydHkgaXMgc3RyaWN0bHkgY29tcHVsc29yeS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBpZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5faWQ7XG4gICAgfVxuXG4gICAgc2V0IGlkKHZhbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2lkID0gdmFsO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2lkOiBzdHJpbmc7XG5cbiAgICAvKiogTWluaW11bSBhbW91bnQgb2YgcGl4ZWxzIHRoYXQgdGhlIHVzZXIgc2hvdWxkIG1vdmUgYmVmb3JlIGl0IHN0YXJ0cyB0aGUgZHJhZyBzZXF1ZW5jZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBkcmFnU3RhcnRUaHJlc2hvbGQoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX2RyYWdTdGFydFRocmVzaG9sZDsgfVxuXG4gICAgc2V0IGRyYWdTdGFydFRocmVzaG9sZCh2YWw6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9kcmFnU3RhcnRUaHJlc2hvbGQgPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWwpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2RyYWdTdGFydFRocmVzaG9sZDogbnVtYmVyID0gMDtcblxuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGl0ZW0gaXMgZHJhZ2dhYmxlIG9yIG5vdC4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBkcmFnZ2FibGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmFnZ2FibGU7XG4gICAgfVxuXG4gICAgc2V0IGRyYWdnYWJsZSh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZHJhZ2dhYmxlID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbCk7XG4gICAgICAgIHRoaXMuX2RyYWdnYWJsZSQubmV4dCh0aGlzLl9kcmFnZ2FibGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2RyYWdnYWJsZTogYm9vbGVhbiA9IHRydWU7XG4gICAgcHJpdmF0ZSBfZHJhZ2dhYmxlJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0aGlzLl9kcmFnZ2FibGUpO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGl0ZW0gaXMgcmVzaXphYmxlIG9yIG5vdC4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCByZXNpemFibGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNpemFibGU7XG4gICAgfVxuXG4gICAgc2V0IHJlc2l6YWJsZSh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fcmVzaXphYmxlID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbCk7XG4gICAgICAgIHRoaXMuX3Jlc2l6YWJsZSQubmV4dCh0aGlzLl9yZXNpemFibGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc2l6YWJsZTogYm9vbGVhbiA9IHRydWU7XG4gICAgcHJpdmF0ZSBfcmVzaXphYmxlJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0aGlzLl9yZXNpemFibGUpO1xuXG4gICAgcHJpdmF0ZSBkcmFnU3RhcnRTdWJqZWN0OiBTdWJqZWN0PE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PiA9IG5ldyBTdWJqZWN0PE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PigpO1xuICAgIHByaXZhdGUgcmVzaXplU3RhcnRTdWJqZWN0OiBTdWJqZWN0PE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PiA9IG5ldyBTdWJqZWN0PE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PigpO1xuXG4gICAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBncmlkU2VydmljZTogS3RkR3JpZFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgICAgICAgICAgQEluamVjdChHUklEX0lURU1fR0VUX1JFTkRFUl9EQVRBX1RPS0VOKSBwcml2YXRlIGdldEl0ZW1SZW5kZXJEYXRhOiBLdGRHcmlkSXRlbVJlbmRlckRhdGFUb2tlblR5cGUpIHtcbiAgICAgICAgdGhpcy5kcmFnU3RhcnQkID0gdGhpcy5kcmFnU3RhcnRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgICAgICB0aGlzLnJlc2l6ZVN0YXJ0JCA9IHRoaXMucmVzaXplU3RhcnRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBjb25zdCBncmlkSXRlbVJlbmRlckRhdGEgPSB0aGlzLmdldEl0ZW1SZW5kZXJEYXRhKHRoaXMuaWQpITtcbiAgICAgICAgdGhpcy5zZXRTdHlsZXMoZ3JpZEl0ZW1SZW5kZXJEYXRhKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgdGhpcy5fZHJhZ1N0YXJ0JCgpLnN1YnNjcmliZSh0aGlzLmRyYWdTdGFydFN1YmplY3QpLFxuICAgICAgICAgICAgdGhpcy5fcmVzaXplU3RhcnQkKCkuc3Vic2NyaWJlKHRoaXMucmVzaXplU3RhcnRTdWJqZWN0KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goc3ViID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgICB9XG5cbiAgICBzZXRTdHlsZXMoe3RvcCwgbGVmdCwgd2lkdGgsIGhlaWdodH06IHsgdG9wOiBzdHJpbmcsIGxlZnQ6IHN0cmluZywgd2lkdGg/OiBzdHJpbmcsIGhlaWdodD86IHN0cmluZyB9KSB7XG4gICAgICAgIC8vIHRyYW5zZm9ybSBpcyA2eCB0aW1lcyBmYXN0ZXIgdGhhbiB0b3AvbGVmdFxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAndHJhbnNmb3JtJywgYHRyYW5zbGF0ZVgoJHtsZWZ0fSkgdHJhbnNsYXRlWSgke3RvcH0pYCk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdkaXNwbGF5JywgYGJsb2NrYCk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2l0aW9uJywgdGhpcy50cmFuc2l0aW9uKTtcbiAgICAgICAgaWYgKHdpZHRoICE9IG51bGwpIHsgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3dpZHRoJywgd2lkdGgpOyB9XG4gICAgICAgIGlmIChoZWlnaHQgIT0gbnVsbCkge3RoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdoZWlnaHQnLCBoZWlnaHQpOyB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZHJhZ1N0YXJ0JCgpOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmFnZ2FibGUkLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKGRyYWdnYWJsZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZHJhZ2dhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBORVZFUjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZHJhZ0hhbmRsZXMuY2hhbmdlcy5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRXaXRoKHRoaXMuX2RyYWdIYW5kbGVzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoZHJhZ0hhbmRsZXM6IFF1ZXJ5TGlzdDxLdGRHcmlkRHJhZ0hhbmRsZT4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWlmKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKSA9PiBkcmFnSGFuZGxlcy5sZW5ndGggPiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZSguLi5kcmFnSGFuZGxlcy50b0FycmF5KCkubWFwKGRyYWdIYW5kbGUgPT4ga3RkTW91c2VPclRvdWNoRG93bihkcmFnSGFuZGxlLmVsZW1lbnQubmF0aXZlRWxlbWVudCwgMSkpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3RkTW91c2VPclRvdWNoRG93bih0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgMSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aGF1c3RNYXAoKHN0YXJ0RXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBldmVudCBzdGFydGVkIGZyb20gYW4gZWxlbWVudCB3aXRoIHRoZSBuYXRpdmUgSFRNTCBkcmFnJmRyb3AsIGl0J2xsIGludGVyZmVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCBvdXIgb3duIGRyYWdnaW5nIChlLmcuIGBpbWdgIHRhZ3MgZG8gaXQgYnkgZGVmYXVsdCkuIFByZXZlbnQgdGhlIGRlZmF1bHQgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBzdG9wIGl0IGZyb20gaGFwcGVuaW5nLiBOb3RlIHRoYXQgcHJldmVudGluZyBvbiBgZHJhZ3N0YXJ0YCBhbHNvIHNlZW1zIHRvIHdvcmssIGJ1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQncyBmbGFreSBhbmQgaXQgZmFpbHMgaWYgdGhlIHVzZXIgZHJhZ3MgaXQgYXdheSBxdWlja2x5LiBBbHNvIG5vdGUgdGhhdCB3ZSBvbmx5IHdhbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIGRvIHRoaXMgZm9yIGBtb3VzZWRvd25gIHNpbmNlIGRvaW5nIHRoZSBzYW1lIGZvciBgdG91Y2hzdGFydGAgd2lsbCBzdG9wIGFueSBgY2xpY2tgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBldmVudHMgZnJvbSBmaXJpbmcgb24gdG91Y2ggZGV2aWNlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGFydEV2ZW50LnRhcmdldCAmJiAoc3RhcnRFdmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmRyYWdnYWJsZSAmJiBzdGFydEV2ZW50LnR5cGUgPT09ICdtb3VzZWRvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGFydFBvaW50ZXIgPSBrdGRQb2ludGVyQ2xpZW50KHN0YXJ0RXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZFNlcnZpY2UubW91c2VPclRvdWNoTW92ZSQoZG9jdW1lbnQpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZVVudGlsKGt0ZE1vdXNlT3JUb3VjaEVuZChkb2N1bWVudCwgMSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt0ZE91dHNpZGVab25lKHRoaXMubmdab25lKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoKG1vdmVFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3ZlRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW92ZVBvaW50ZXIgPSBrdGRQb2ludGVyQ2xpZW50KG1vdmVFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlWCA9IE1hdGguYWJzKHN0YXJ0UG9pbnRlci5jbGllbnRYIC0gbW92ZVBvaW50ZXIuY2xpZW50WCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlWSA9IE1hdGguYWJzKHN0YXJ0UG9pbnRlci5jbGllbnRZIC0gbW92ZVBvaW50ZXIuY2xpZW50WSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhpcyBjb25kaXRpb25zIHJldHVybnMgdHJ1ZSBtZWFuIHRoYXQgd2UgYXJlIG92ZXIgdGhyZXNob2xkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlzdGFuY2VYICsgZGlzdGFuY2VZID49IHRoaXMuZHJhZ1N0YXJ0VGhyZXNob2xkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBvcmlnaW5hbCBzdGFydCBldmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiBzdGFydEV2ZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc2l6ZVN0YXJ0JCgpOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNpemFibGUkLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHJlc2l6YWJsZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghcmVzaXphYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNpZGUgZWZmZWN0IHRvIGhpZGUgdGhlIHJlc2l6ZUVsZW0gaWYgcmVzaXplIGlzIGRpc2FibGVkLlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMucmVzaXplRWxlbS5uYXRpdmVFbGVtZW50LCAnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBORVZFUjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzaXplSGFuZGxlcy5jaGFuZ2VzLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFdpdGgodGhpcy5fcmVzaXplSGFuZGxlcyksXG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHJlc2l6ZUhhbmRsZXM6IFF1ZXJ5TGlzdDxLdGRHcmlkUmVzaXplSGFuZGxlPikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVIYW5kbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2lkZSBlZmZlY3QgdG8gaGlkZSB0aGUgcmVzaXplRWxlbSBpZiB0aGVyZSBhcmUgcmVzaXplIGhhbmRsZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5yZXNpemVFbGVtLm5hdGl2ZUVsZW1lbnQsICdkaXNwbGF5JywgJ25vbmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lcmdlKC4uLnJlc2l6ZUhhbmRsZXMudG9BcnJheSgpLm1hcChyZXNpemVIYW5kbGUgPT4ga3RkTW91c2VPclRvdWNoRG93bihyZXNpemVIYW5kbGUuZWxlbWVudC5uYXRpdmVFbGVtZW50LCAxKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5yZXNpemVFbGVtLm5hdGl2ZUVsZW1lbnQsICdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBrdGRNb3VzZU9yVG91Y2hEb3duKHRoaXMucmVzaXplRWxlbS5uYXRpdmVFbGVtZW50LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbWluVzogTnVtYmVySW5wdXQ7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gICAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX21pbkg6IE51bWJlcklucHV0O1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxuICAgIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9tYXhXOiBOdW1iZXJJbnB1dDtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbWF4SDogTnVtYmVySW5wdXQ7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gICAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2RyYWdnYWJsZTogQm9vbGVhbklucHV0O1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxuICAgIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9yZXNpemFibGU6IEJvb2xlYW5JbnB1dDtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZHJhZ1N0YXJ0VGhyZXNob2xkOiBOdW1iZXJJbnB1dDtcblxufVxuIiwiPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPGRpdiAjcmVzaXplRWxlbSBjbGFzcz1cImdyaWQtaXRlbS1yZXNpemUtaWNvblwiPjwvZGl2PlxuIl19