UNPKG

@hxui/angular

Version:

An Angular library based on the [HXUI design system](https://hxui.io).

281 lines 36.5 kB
import { Overlay } from '@angular/cdk/overlay'; import { TemplatePortal } from '@angular/cdk/portal'; import { ContentChild, Directive, ElementRef, EventEmitter, Input, Output, Renderer2, ViewContainerRef } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { DropdownMenuDirective } from './dropdown-menu.directive'; import { DropdownConfig } from './dropdown.config'; import * as i0 from "@angular/core"; import * as i1 from "@angular/cdk/overlay"; import * as i2 from "./dropdown.config"; export class DropdownDirective { constructor(_elementRef, _viewContainerRef, overlay, _config, renderer) { this._elementRef = _elementRef; this._viewContainerRef = _viewContainerRef; this.overlay = overlay; this._config = _config; this.renderer = renderer; this._destroyed = new Subject(); this.isOpen = false; this.placement = 'bottom'; this._autoClose = this._config.autoClose; this.isOpenChange = new EventEmitter(); this.onShown = new EventEmitter(); this.onHidden = new EventEmitter(); this.isDisabled = false; this.showDelay = this._config.showDelay; this.hideDelay = this._config.hideDelay; this.offsetY = 0; this.offsetX = 0; this.createClipPathMask = false; } set autoClose(value) { this._autoClose = value; } get autoClose() { return this._autoClose; } ngOnDestroy() { if (this._overlayRef) { this._overlayRef.dispose(); this._overlayRef = null; } this._destroyed.next(true); this._destroyed.complete(); } /** * Toggles an element’s popover. This is considered a “manual” triggering of * the popover. */ toggle(value) { if (this.isOpen || value === false) { return this.hide(); } return this.show(); } show(delay = this.showDelay) { if (this.isDisabled || this.isOpen) { return; } const overlayRef = this._createOverlay(); this._detach(); overlayRef.attach(this._portal); if (this.createClipPathMask) { this._addClipPathMaskStyles(); } this._setWidthsRelativeTo(overlayRef); this.isOpen = true; this.isOpenChange.emit(this.isOpen); this.onShown.emit(); } hide(delay = this.hideDelay) { this._detach(); this.isOpen = false; this.isOpenChange.emit(this.isOpen); this.onHidden.emit(); } _createOverlay() { if (this._overlayRef) { return this._overlayRef; } this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef); const positionStrategy = this.overlay .position() .flexibleConnectedTo(this._elementRef) .withFlexibleDimensions(false) .withDefaultOffsetX(this.offsetX) .withDefaultOffsetY(this.offsetY) .withPositions([ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' } ]) .withTransformOriginOn('.hxa-dropdown-control'); this._overlayRef = this.overlay.create({ positionStrategy: positionStrategy, panelClass: [ 'hxui-reset', 'hxa-dropdown-panel', 'is-open', this.minWidthRelativeTo ? 'is-fluid-min-width' : 'not-fuild-min-width' ], hasBackdrop: true, backdropClass: 'cdk-overlay-transparent-backdrop' }); this._updatePosition(); this._overlayRef .detachments() .pipe(takeUntil(this._destroyed)) .subscribe(() => this._detach()); this._overlayRef.backdropClick().subscribe(() => this.hide()); const position = this._overlayRef.getConfig() .positionStrategy; position.positionChanges.pipe(takeUntil(this._destroyed)).subscribe(pos => { if (pos.connectionPair.originX === 'start') { this.placement = 'left'; } else if (pos.connectionPair.originX === 'end') { this.placement = 'right'; } else if (pos.connectionPair.originY === 'top') { this.placement = 'top'; } else if (pos.connectionPair.originY === 'bottom') { this.placement = 'bottom'; } }); return this._overlayRef; } _detach() { if (this._overlayRef && this._overlayRef.hasAttached()) { this._overlayRef.detach(); } } _setWidthsRelativeTo(overlayRef) { if (this.maxWidthRelativeTo && this.minWidthRelativeTo) { const elem = document.getElementById(this.maxWidthRelativeTo); overlayRef.updateSize({ minWidth: elem.clientWidth, maxWidth: elem.clientWidth }); } else if (this.maxWidthRelativeTo) { const elem = document.getElementById(this.maxWidthRelativeTo); overlayRef.updateSize({ maxWidth: elem.clientWidth }); } else if (this.minWidthRelativeTo) { const elem = document.getElementById(this.minWidthRelativeTo); overlayRef.updateSize({ minWidth: elem.clientWidth }); } } _updatePosition() { const position = this._overlayRef.getConfig() .positionStrategy; const origin = this._getOrigin(); const overlay = this._getOverlayPosition(); position.withPositions([ { ...origin.main, ...overlay.main }, { ...origin.fallback, ...overlay.fallback } ]); } /** * Returns the origin position and a fallback position based on the user's position preference. * The fallback position is the inverse of the origin (e.g. `'bottom' -> 'top'`). */ _getOrigin() { const placement = this.placement; let originPlacement; if (placement === 'top' || placement === 'bottom') { originPlacement = { originX: 'start', originY: placement === 'top' ? 'top' : 'bottom' }; } else if (placement === 'left') { originPlacement = { originX: 'start', originY: 'center' }; } else if (placement === 'right') { originPlacement = { originX: 'end', originY: 'center' }; } else { console.error('Position error', placement); } const { x, y } = this._invertPosition(originPlacement.originX, originPlacement.originY); return { main: originPlacement, fallback: { originX: x, originY: y } }; } /** Returns the overlay position and a fallback position based on the user's preference */ _getOverlayPosition() { const placement = this.placement; let overlayPlacement; if (placement === 'top') { overlayPlacement = { overlayX: 'start', overlayY: 'bottom' }; } else if (placement === 'bottom') { overlayPlacement = { overlayX: 'start', overlayY: 'top' }; } else if (placement === 'left') { overlayPlacement = { overlayX: 'end', overlayY: 'center' }; } else if (placement === 'right') { overlayPlacement = { overlayX: 'start', overlayY: 'center' }; } else { console.error('Could not find a position', placement); } const { x, y } = this._invertPosition(overlayPlacement.overlayX, overlayPlacement.overlayY); return { main: overlayPlacement, fallback: { overlayX: x, overlayY: y } }; } _invertPosition(x, y) { if (this.placement === 'top' || this.placement === 'bottom') { if (y === 'top') { y = 'bottom'; } else if (y === 'bottom') { y = 'top'; } } else { if (x === 'end') { x = 'start'; } else if (x === 'start') { x = 'end'; } } return { x, y }; } // Create a clip path mask in the backdrop. The mask is a rectangle, the size of the viewcontainer // This enables the user to interact with the contents of the viewcontainer without closing the dropdown _addClipPathMaskStyles() { const HTMLEl = this._overlayRef.backdropElement; const viewRefNativeEl = this._viewContainerRef.element.nativeElement; const elRect = viewRefNativeEl.getBoundingClientRect(); if (elRect) { const clipPathStyle = `polygon(0% 0%, 0% 100%, ${elRect.left}px 100%, ${elRect.left}px ${elRect.top}px, ${elRect.right}px ${elRect.top}px, ${elRect.right}px ${elRect.bottom}px, ${elRect.left}px ${elRect.bottom}px, ${elRect.left}px 100%, 100% 100%, 100% 0%)`; this.renderer.setStyle(HTMLEl, 'clip-path', clipPathStyle); } } } DropdownDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DropdownDirective, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: i2.DropdownConfig }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); DropdownDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: DropdownDirective, selector: "[hxaDropdown],[hxDropdown]", inputs: { placement: "placement", autoClose: "autoClose", isDisabled: "isDisabled", showDelay: "showDelay", hideDelay: "hideDelay", maxWidthRelativeTo: "maxWidthRelativeTo", minWidthRelativeTo: "minWidthRelativeTo", offsetY: "offsetY", offsetX: "offsetX", createClipPathMask: "createClipPathMask" }, outputs: { isOpenChange: "isOpenChange", onShown: "onShown", onHidden: "onHidden" }, queries: [{ propertyName: "menu", first: true, predicate: DropdownMenuDirective, descendants: true }], exportAs: ["hx-dropdown", "hxa-dropdown"], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DropdownDirective, decorators: [{ type: Directive, args: [{ selector: '[hxaDropdown],[hxDropdown]', exportAs: 'hx-dropdown, hxa-dropdown' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i2.DropdownConfig }, { type: i0.Renderer2 }]; }, propDecorators: { menu: [{ type: ContentChild, args: [DropdownMenuDirective] }], placement: [{ type: Input }], autoClose: [{ type: Input }], isOpenChange: [{ type: Output }], onShown: [{ type: Output }], onHidden: [{ type: Output }], isDisabled: [{ type: Input }], showDelay: [{ type: Input }], hideDelay: [{ type: Input }], maxWidthRelativeTo: [{ type: Input }], minWidthRelativeTo: [{ type: Input }], offsetY: [{ type: Input }], offsetX: [{ type: Input }], createClipPathMask: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHgtdWkvc3JjL2xpYi9kcm9wZG93bi9kcm9wZG93bi5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUlMLE9BQU8sRUFJUixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULGdCQUFnQixFQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7QUFNbkQsTUFBTSxPQUFPLGlCQUFpQjtJQW1ENUIsWUFDVSxXQUF1QixFQUN2QixpQkFBbUMsRUFDcEMsT0FBZ0IsRUFDaEIsT0FBdUIsRUFDdEIsUUFBbUI7UUFKbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNwQyxZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ2hCLFlBQU8sR0FBUCxPQUFPLENBQWdCO1FBQ3RCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFuRFosZUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDckMsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUd0QixjQUFTLEdBQXdDLFFBQVEsQ0FBQztRQUVsRCxlQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENB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QkFJTixrQkFBa0I7c0JBRGpCLEtBQUs7Z0JBSU4sT0FBTztzQkFETixLQUFLO2dCQUlOLE9BQU87c0JBRE4sS0FBSztnQkFJTixrQkFBa0I7c0JBRGpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSxcclxuICBIb3Jpem9udGFsQ29ubmVjdGlvblBvcyxcclxuICBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb24sXHJcbiAgT3ZlcmxheSxcclxuICBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uLFxyXG4gIE92ZXJsYXlSZWYsXHJcbiAgVmVydGljYWxDb25uZWN0aW9uUG9zXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xyXG5pbXBvcnQge1xyXG4gIENvbnRlbnRDaGlsZCxcclxuICBEaXJlY3RpdmUsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE91dHB1dCxcclxuICBSZW5kZXJlcjIsXHJcbiAgVmlld0NvbnRhaW5lclJlZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgRHJvcGRvd25NZW51RGlyZWN0aXZlIH0gZnJvbSAnLi9kcm9wZG93bi1tZW51LmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IERyb3Bkb3duQ29uZmlnIH0gZnJvbSAnLi9kcm9wZG93bi5jb25maWcnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbaHhhRHJvcGRvd25dLFtoeERyb3Bkb3duXScsXHJcbiAgZXhwb3J0QXM6ICdoeC1kcm9wZG93biwgaHhhLWRyb3Bkb3duJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRHJvcGRvd25EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIEBDb250ZW50Q2hpbGQoRHJvcGRvd25NZW51RGlyZWN0aXZlKSBtZW51OiBEcm9wZG93bk1lbnVEaXJlY3RpdmU7XHJcblxyXG4gIF9vdmVybGF5UmVmOiBPdmVybGF5UmVmIHwgbnVsbDtcclxuICBwcml2YXRlIF9wb3J0YWw6IFRlbXBsYXRlUG9ydGFsO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3llZCA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgcHVibGljIGlzT3BlbiA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHBsYWNlbWVudDogJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JyB8ICdyaWdodCcgPSAnYm90dG9tJztcclxuXHJcbiAgcHJpdmF0ZSBfYXV0b0Nsb3NlID0gdGhpcy5fY29uZmlnLmF1dG9DbG9zZTtcclxuICBASW5wdXQoKVxyXG4gIHNldCBhdXRvQ2xvc2UodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2F1dG9DbG9zZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dG9DbG9zZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9hdXRvQ2xvc2U7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KCkgaXNPcGVuQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcblxyXG4gIEBPdXRwdXQoKSBvblNob3duOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICBAT3V0cHV0KCkgb25IaWRkZW46IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaXNEaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNob3dEZWxheSA9IHRoaXMuX2NvbmZpZy5zaG93RGVsYXk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaGlkZURlbGF5ID0gdGhpcy5fY29uZmlnLmhpZGVEZWxheTtcclxuXHJcbiAgQElucHV0KClcclxuICBtYXhXaWR0aFJlbGF0aXZlVG86IHN0cmluZztcclxuXHJcbiAgQElucHV0KClcclxuICBtaW5XaWR0aFJlbGF0aXZlVG86IHN0cmluZztcclxuXHJcbiAgQElucHV0KClcclxuICBvZmZzZXRZID0gMDtcclxuXHJcbiAgQElucHV0KClcclxuICBvZmZzZXRYID0gMDtcclxuXHJcbiAgQElucHV0KClcclxuICBjcmVhdGVDbGlwUGF0aE1hc2sgPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBfdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZixcclxuICAgIHB1YmxpYyBvdmVybGF5OiBPdmVybGF5LFxyXG4gICAgcHVibGljIF9jb25maWc6IERyb3Bkb3duQ29uZmlnLFxyXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmKSB7XHJcbiAgICAgIHRoaXMuX292ZXJsYXlSZWYuZGlzcG9zZSgpO1xyXG4gICAgICB0aGlzLl9vdmVybGF5UmVmID0gbnVsbDtcclxuICAgIH1cclxuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KHRydWUpO1xyXG4gICAgdGhpcy5fZGVzdHJveWVkLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGVzIGFuIGVsZW1lbnTigJlzIHBvcG92ZXIuIFRoaXMgaXMgY29uc2lkZXJlZCBhIOKAnG1hbnVhbOKAnSB0cmlnZ2VyaW5nIG9mXHJcbiAgICogdGhlIHBvcG92ZXIuXHJcbiAgICovXHJcbiAgdG9nZ2xlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXNPcGVuIHx8IHZhbHVlID09PSBmYWxzZSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5oaWRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc2hvdygpO1xyXG4gIH1cclxuXHJcbiAgc2hvdyhkZWxheTogbnVtYmVyID0gdGhpcy5zaG93RGVsYXkpIHtcclxuICAgIGlmICh0aGlzLmlzRGlzYWJsZWQgfHwgdGhpcy5pc09wZW4pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG92ZXJsYXlSZWYgPSB0aGlzLl9jcmVhdGVPdmVybGF5KCk7XHJcbiAgICB0aGlzLl9kZXRhY2goKTtcclxuICAgIG92ZXJsYXlSZWYuYXR0YWNoKHRoaXMuX3BvcnRhbCk7XHJcblxyXG4gICAgaWYgKHRoaXMuY3JlYXRlQ2xpcFBhdGhNYXNrKSB7XHJcbiAgICAgIHRoaXMuX2FkZENsaXBQYXRoTWFza1N0eWxlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3NldFdpZHRoc1JlbGF0aXZlVG8ob3ZlcmxheVJlZik7XHJcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICB0aGlzLmlzT3BlbkNoYW5nZS5lbWl0KHRoaXMuaXNPcGVuKTtcclxuICAgIHRoaXMub25TaG93bi5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBoaWRlKGRlbGF5OiBudW1iZXIgPSB0aGlzLmhpZGVEZWxheSkge1xyXG4gICAgdGhpcy5fZGV0YWNoKCk7XHJcbiAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5pc09wZW5DaGFuZ2UuZW1pdCh0aGlzLmlzT3Blbik7XHJcbiAgICB0aGlzLm9uSGlkZGVuLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NyZWF0ZU92ZXJsYXkoKTogT3ZlcmxheVJlZiB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZikge1xyXG4gICAgICByZXR1cm4gdGhpcy5fb3ZlcmxheVJlZjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9wb3J0YWwgPSBuZXcgVGVtcGxhdGVQb3J0YWwoXHJcbiAgICAgIHRoaXMubWVudS50ZW1wbGF0ZVJlZixcclxuICAgICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZlxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBwb3NpdGlvblN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5XHJcbiAgICAgIC5wb3NpdGlvbigpXHJcbiAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMuX2VsZW1lbnRSZWYpXHJcbiAgICAgIC53aXRoRmxleGlibGVEaW1lbnNpb25zKGZhbHNlKVxyXG4gICAgICAud2l0aERlZmF1bHRPZmZzZXRYKHRoaXMub2Zmc2V0WClcclxuICAgICAgLndpdGhEZWZhdWx0T2Zmc2V0WSh0aGlzLm9mZnNldFkpXHJcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcclxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnLCBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH1cclxuICAgICAgXSlcclxuICAgICAgLndpdGhUcmFuc2Zvcm1PcmlnaW5PbignLmh4YS1kcm9wZG93bi1jb250cm9sJyk7XHJcblxyXG4gICAgdGhpcy5fb3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xyXG4gICAgICBwb3NpdGlvblN0cmF0ZWd5OiBwb3NpdGlvblN0cmF0ZWd5LFxyXG4gICAgICBwYW5lbENsYXNzOiBbXHJcbiAgICAgICAgJ2h4dWktcmVzZXQnLFxyXG4gICAgICAgICdoeGEtZHJvcGRvd24tcGFuZWwnLFxyXG4gICAgICAgICdpcy1vcGVuJyxcclxuICAgICAgICB0aGlzLm1pbldpZHRoUmVsYXRpdmVUbyA/ICdpcy1mbHVpZC1taW4td2lkdGgnIDogJ25vdC1mdWlsZC1taW4td2lkdGgnXHJcbiAgICAgIF0sXHJcbiAgICAgIGhhc0JhY2tkcm9wOiB0cnVlLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiAnY2RrLW92ZXJsYXktdHJhbnNwYXJlbnQtYmFja2Ryb3AnXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xyXG5cclxuICAgIHRoaXMuX292ZXJsYXlSZWZcclxuICAgICAgLmRldGFjaG1lbnRzKClcclxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fZGV0YWNoKCkpO1xyXG5cclxuICAgIHRoaXMuX292ZXJsYXlSZWYuYmFja2Ryb3BDbGljaygpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhpZGUoKSk7XHJcblxyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9vdmVybGF5UmVmLmdldENvbmZpZygpXHJcbiAgICAgIC5wb3NpdGlvblN0cmF0ZWd5IGFzIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneTtcclxuICAgIHBvc2l0aW9uLnBvc2l0aW9uQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKS5zdWJzY3JpYmUocG9zID0+IHtcclxuICAgICAgaWYgKHBvcy5jb25uZWN0aW9uUGFpci5vcmlnaW5YID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAnbGVmdCc7XHJcbiAgICAgIH0gZWxzZSBpZiAocG9zLmNvbm5lY3Rpb25QYWlyLm9yaWdpblggPT09ICdlbmQnKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAncmlnaHQnO1xyXG4gICAgICB9IGVsc2UgaWYgKHBvcy5jb25uZWN0aW9uUGFpci5vcmlnaW5ZID09PSAndG9wJykge1xyXG4gICAgICAgIHRoaXMucGxhY2VtZW50ID0gJ3RvcCc7XHJcbiAgICAgIH0gZWxzZSBpZiAocG9zLmNvbm5lY3Rpb25QYWlyLm9yaWdpblkgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAnYm90dG9tJztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX292ZXJsYXlSZWY7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9kZXRhY2goKSB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZiAmJiB0aGlzLl9vdmVybGF5UmVmLmhhc0F0dGFjaGVkKCkpIHtcclxuICAgICAgdGhpcy5fb3ZlcmxheVJlZi5kZXRhY2goKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NldFdpZHRoc1JlbGF0aXZlVG8ob3ZlcmxheVJlZjogT3ZlcmxheVJlZikge1xyXG4gICAgaWYgKHRoaXMubWF4V2lkdGhSZWxhdGl2ZVRvICYmIHRoaXMubWluV2lkdGhSZWxhdGl2ZVRvKSB7XHJcbiAgICAgIGNvbnN0IGVsZW06IEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1heFdpZHRoUmVsYXRpdmVUbyk7XHJcbiAgICAgIG92ZXJsYXlSZWYudXBkYXRlU2l6ZSh7XHJcbiAgICAgICAgbWluV2lkdGg6IGVsZW0uY2xpZW50V2lkdGgsXHJcbiAgICAgICAgbWF4V2lkdGg6IGVsZW0uY2xpZW50V2lkdGhcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4V2lkdGhSZWxhdGl2ZVRvKSB7XHJcbiAgICAgIGNvbnN0IGVsZW06IEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1heFdpZHRoUmVsYXRpdmVUbyk7XHJcbiAgICAgIG92ZXJsYXlSZWYudXBkYXRlU2l6ZSh7IG1heFdpZHRoOiBlbGVtLmNsaWVudFdpZHRoIH0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm1pbldpZHRoUmVsYXRpdmVUbykge1xyXG4gICAgICBjb25zdCBlbGVtOiBFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5taW5XaWR0aFJlbGF0aXZlVG8pO1xyXG4gICAgICBvdmVybGF5UmVmLnVwZGF0ZVNpemUoeyBtaW5XaWR0aDogZWxlbS5jbGllbnRXaWR0aCB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3VwZGF0ZVBvc2l0aW9uKCkge1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9vdmVybGF5UmVmIS5nZXRDb25maWcoKVxyXG4gICAgICAucG9zaXRpb25TdHJhdGVneSBhcyBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3k7XHJcbiAgICBjb25zdCBvcmlnaW4gPSB0aGlzLl9nZXRPcmlnaW4oKTtcclxuICAgIGNvbnN0IG92ZXJsYXkgPSB0aGlzLl9nZXRPdmVybGF5UG9zaXRpb24oKTtcclxuXHJcbiAgICBwb3NpdGlvbi53aXRoUG9zaXRpb25zKFtcclxuICAgICAgeyAuLi5vcmlnaW4ubWFpbiwgLi4ub3ZlcmxheS5tYWluIH0sXHJcbiAgICAgIHsgLi4ub3JpZ2luLmZhbGxiYWNrLCAuLi5vdmVybGF5LmZhbGxiYWNrIH1cclxuICAgIF0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgb3JpZ2luIHBvc2l0aW9uIGFuZCBhIGZhbGxiYWNrIHBvc2l0aW9uIGJhc2VkIG9uIHRoZSB1c2VyJ3MgcG9zaXRpb24gcHJlZmVyZW5jZS5cclxuICAgKiBUaGUgZmFsbGJhY2sgcG9zaXRpb24gaXMgdGhlIGludmVyc2Ugb2YgdGhlIG9yaWdpbiAoZS5nLiBgJ2JvdHRvbScgLT4gJ3RvcCdgKS5cclxuICAgKi9cclxuICBwcml2YXRlIF9nZXRPcmlnaW4oKToge1xyXG4gICAgbWFpbjogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xyXG4gICAgZmFsbGJhY2s6IE9yaWdpbkNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuICB9IHtcclxuICAgIGNvbnN0IHBsYWNlbWVudCA9IHRoaXMucGxhY2VtZW50O1xyXG4gICAgbGV0IG9yaWdpblBsYWNlbWVudDogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xyXG5cclxuICAgIGlmIChwbGFjZW1lbnQgPT09ICd0b3AnIHx8IHBsYWNlbWVudCA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0ge1xyXG4gICAgICAgIG9yaWdpblg6ICdzdGFydCcsXHJcbiAgICAgICAgb3JpZ2luWTogcGxhY2VtZW50ID09PSAndG9wJyA/ICd0b3AnIDogJ2JvdHRvbSdcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSBpZiAocGxhY2VtZW50ID09PSAnbGVmdCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdyaWdodCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Bvc2l0aW9uIGVycm9yJywgcGxhY2VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuX2ludmVydFBvc2l0aW9uKFxyXG4gICAgICBvcmlnaW5QbGFjZW1lbnQub3JpZ2luWCxcclxuICAgICAgb3JpZ2luUGxhY2VtZW50Lm9yaWdpbllcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbWFpbjogb3JpZ2luUGxhY2VtZW50LFxyXG4gICAgICBmYWxsYmFjazogeyBvcmlnaW5YOiB4LCBvcmlnaW5ZOiB5IH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKiogUmV0dXJucyB0aGUgb3ZlcmxheSBwb3NpdGlvbiBhbmQgYSBmYWxsYmFjayBwb3NpdGlvbiBiYXNlZCBvbiB0aGUgdXNlcidzIHByZWZlcmVuY2UgKi9cclxuICBwcml2YXRlIF9nZXRPdmVybGF5UG9zaXRpb24oKToge1xyXG4gICAgbWFpbjogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuICAgIGZhbGxiYWNrOiBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uO1xyXG4gIH0ge1xyXG4gICAgY29uc3QgcGxhY2VtZW50ID0gdGhpcy5wbGFjZW1lbnQ7XHJcbiAgICBsZXQgb3ZlcmxheVBsYWNlbWVudDogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuXHJcbiAgICBpZiAocGxhY2VtZW50ID09PSAndG9wJykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH07XHJcbiAgICB9IGVsc2UgaWYgKHBsYWNlbWVudCA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudCA9IHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdsZWZ0Jykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ2VuZCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdyaWdodCcpIHtcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudCA9IHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS5lcnJvcignQ291bGQgbm90IGZpbmQgYSBwb3NpdGlvbicsIHBsYWNlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgeyB4LCB5IH0gPSB0aGlzLl9pbnZlcnRQb3NpdGlvbihcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudC5vdmVybGF5WCxcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudC5vdmVybGF5WVxyXG4gICAgKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBtYWluOiBvdmVybGF5UGxhY2VtZW50LFxyXG4gICAgICBmYWxsYmFjazogeyBvdmVybGF5WDogeCwgb3ZlcmxheVk6IHkgfVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2ludmVydFBvc2l0aW9uKFxyXG4gICAgeDogSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXHJcbiAgICB5OiBWZXJ0aWNhbENvbm5lY3Rpb25Qb3NcclxuICApIHtcclxuICAgIGlmICh0aGlzLnBsYWNlbWVudCA9PT0gJ3RvcCcgfHwgdGhpcy5wbGFjZW1lbnQgPT09ICdib3R0b20nKSB7XHJcbiAgICAgIGlmICh5ID09PSAndG9wJykge1xyXG4gICAgICAgIHkgPSAnYm90dG9tJztcclxuICAgICAgfSBlbHNlIGlmICh5ID09PSAnYm90dG9tJykge1xyXG4gICAgICAgIHkgPSAndG9wJztcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHggPT09ICdlbmQnKSB7XHJcbiAgICAgICAgeCA9ICdzdGFydCc7XHJcbiAgICAgIH0gZWxzZSBpZiAoeCA9PT0gJ3N0YXJ0Jykge1xyXG4gICAgICAgIHggPSAnZW5kJztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IHgsIHkgfTtcclxuICB9XHJcblxyXG4gIC8vIENyZWF0ZSBhIGNsaXAgcGF0aCBtYXNrIGluIHRoZSBiYWNrZHJvcC4gVGhlIG1hc2sgaXMgYSByZWN0YW5nbGUsIHRoZSBzaXplIG9mIHRoZSB2aWV3Y29udGFpbmVyXHJcbiAgLy8gVGhpcyBlbmFibGVzIHRoZSB1c2VyIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbnRlbnRzIG9mIHRoZSB2aWV3Y29udGFpbmVyIHdpdGhvdXQgY2xvc2luZyB0aGUgZHJvcGRvd25cclxuICBwcml2YXRlIF9hZGRDbGlwUGF0aE1hc2tTdHlsZXMoKSB7XHJcbiAgICBjb25zdCBIVE1MRWwgPSB0aGlzLl9vdmVybGF5UmVmLmJhY2tkcm9wRWxlbWVudDtcclxuICAgIGNvbnN0IHZpZXdSZWZOYXRpdmVFbCA9IHRoaXMuX3ZpZXdDb250YWluZXJSZWYuZWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgZWxSZWN0ID0gdmlld1JlZk5hdGl2ZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgaWYgKGVsUmVjdCkge1xyXG4gICAgICBjb25zdCBjbGlwUGF0aFN0eWxlID0gYHBvbHlnb24oMCUgMCUsIDAlIDEwMCUsICR7ZWxSZWN0LmxlZnR9cHggMTAwJSwgJHtlbFJlY3QubGVmdH1weCAke2VsUmVjdC50b3B9cHgsICR7ZWxSZWN0LnJpZ2h0fXB4ICR7ZWxSZWN0LnRvcH1weCwgJHtlbFJlY3QucmlnaHR9cHggJHtlbFJlY3QuYm90dG9tfXB4LCAke2VsUmVjdC5sZWZ0fXB4ICR7ZWxSZWN0LmJvdHRvbX1weCwgJHtlbFJlY3QubGVmdH1weCAxMDAlLCAxMDAlIDEwMCUsIDEwMCUgMCUpYDtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShIVE1MRWwsICdjbGlwLXBhdGgnLCBjbGlwUGF0aFN0eWxlKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19