@nova-ui/bits
Version:
SolarWinds Nova Framework
207 lines • 29.9 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 { Overlay, OverlayConfig, OverlayContainer, } from "@angular/cdk/overlay";
import { CdkPortal } from "@angular/cdk/portal";
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from "@angular/core";
import set from "lodash/set";
import some from "lodash/some";
import { Subject } from "rxjs";
import { filter, takeUntil } from "rxjs/operators";
import { DOCUMENT_CLICK_EVENT } from "../../../constants/event.constants";
import { EventBusService } from "../../../services/event-bus.service";
import { OverlayCustomContainer } from "../overlay-custom-container";
import { OverlayPositionService } from "../overlay-position.service";
import { OverlayService } from "../overlay.service";
import * as i0 from "@angular/core";
import * as i1 from "../overlay-position.service";
import * as i2 from "../overlay.service";
import * as i3 from "@angular/cdk/overlay";
import * as i4 from "../../../services/event-bus.service";
import * as i5 from "@angular/cdk/portal";
import * as i6 from "@angular/common";
export const POPUP_V2_VIEWPORT_MARGINS_DEFAULT = 30;
const isMouseEvent = (event) => event instanceof MouseEvent;
// <example-url>./../examples/index.html#/overlay</example-url>
/* @dynamic */
export class OverlayComponent {
/** Indicates open/close state */
get showing() {
return this.overlayService?.showing;
}
constructor(overlayPositionService, overlayService, cdkOverlay, eventBusService) {
this.overlayPositionService = overlayPositionService;
this.overlayService = overlayService;
this.cdkOverlay = cdkOverlay;
this.eventBusService = eventBusService;
/** Emits MouseEvent when click occurs outside Select/Combobox */
this.clickOutside = new EventEmitter();
/** Emits when content of the Popup is empty */
this.empty$ = new Subject();
this.show$ = this.overlayService.show$;
this.hide$ = this.overlayService.hide$;
}
ngOnChanges(changes) {
const overlayPropsToMap = ["toggleReference", "customContainer"];
if (changes) {
overlayPropsToMap.forEach((key) => {
if (changes[key]) {
set(this.overlayService, key, changes[key].currentValue);
}
});
}
}
ngAfterViewInit() {
this.overlayService.contentTemplate = this.contentTemplate;
}
ngAfterContentChecked() {
this.empty$.next(this.isPopupContentEmpty());
}
ngOnDestroy() {
this.overlayService.ngOnDestroy();
}
/** Shows Popup */
show() {
this.setOverlayConfig();
this.overlayService.show();
this.handleOutsideClicks();
setTimeout(() => this.empty$.next(this.isPopupContentEmpty())); // timeout to get the height of rendered content items
}
/** Hides Popup */
hide() {
this.overlayService.hide();
this.positionStrategySubscription?.unsubscribe();
}
/** Toggles Popup */
toggle() {
this.overlayService.showing ? this.hide() : this.show();
}
getOverlayRef() {
return this.overlayService.getOverlayRef();
}
updateSize(size) {
this.overlayService.updateSize(size);
}
/** Stream of clicks outside. */
overlayClickOutside() {
return this.eventBusService.getStream(DOCUMENT_CLICK_EVENT).pipe(filter(isMouseEvent), filter((event) => {
const clickTarget = event.target;
const notOrigin = !some(event.composedPath(), (p) => p === this.toggleReference); // the toggle elem
const notOverlay = this.overlayService
.getOverlayRef()
?.overlayElement?.contains(clickTarget) === false; // the popup
return notOrigin && notOverlay;
}));
}
handleOutsideClicks() {
const clicksOutsideStream$ = this.overlayConfig?.hasBackdrop
? this.overlayService.getOverlayRef().backdropClick()
: this.overlayClickOutside();
clicksOutsideStream$
.pipe(takeUntil(this.hide$))
.subscribe((v) => this.clickOutside.emit(v));
}
setOverlayConfig() {
const overlayConfig = this.overlayService.overlayConfig;
const positionStrategy = this.cdkOverlay
.position()
.flexibleConnectedTo(this.toggleReference)
.withPush(false)
.withViewportMargin(this.viewportMargin || POPUP_V2_VIEWPORT_MARGINS_DEFAULT)
.withPositions([
{
originX: "start",
originY: "bottom",
overlayX: "start",
overlayY: "top",
},
{
originX: "start",
originY: "top",
overlayX: "start",
overlayY: "bottom",
},
]);
this.positionStrategySubscription =
this.overlayPositionService.updateOffsetOnPositionChanges(positionStrategy, () => this.getOverlayRef());
this.overlayService.overlayConfig = {
...overlayConfig,
positionStrategy,
...this.overlayConfig,
};
}
getContentHeight() {
const lastElementChild = this.overlayService.getOverlayRef()?.hostElement?.lastElementChild;
// to maintain current signature we will return 0 to avoid unnecessary undefined/null checks
return lastElementChild?.clientHeight || 0;
}
isPopupContentEmpty() {
return this.getContentHeight() <= 10; // 10 is for 5 + 5 paddings
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlayComponent, deps: [{ token: i1.OverlayPositionService }, { token: i2.OverlayService }, { token: i3.Overlay }, { token: i4.EventBusService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: OverlayComponent, selector: "nui-overlay", inputs: { overlayConfig: "overlayConfig", toggleReference: "toggleReference", viewportMargin: "viewportMargin", customContainer: "customContainer", roleAttr: "roleAttr" }, outputs: { clickOutside: "clickOutside" }, providers: [
Overlay,
OverlayService,
OverlayPositionService,
{ provide: OverlayContainer, useClass: OverlayCustomContainer },
], viewQueries: [{ propertyName: "contentTemplate", first: true, predicate: CdkPortal, descendants: true }], usesOnChanges: true, ngImport: i0, template: ` <ng-template cdk-portal>
<div
id="nui-overlay"
class="nui-overlay"
[attr.role]="roleAttr || null"
[ngClass]="{ empty: empty$ | async }"
>
<ng-content></ng-content>
</div>
</ng-template>`, isInline: true, styles: [".nui-overlay{display:block;overflow-x:hidden;overflow-y:auto;width:100%}.with-popup-styles .nui-overlay{padding:5px 0;border-radius:3px;box-shadow:0 0 5px 0 var(--nui-shadow-color, rgba(17, 17, 17, .3));background-color:var(--nui-color-bg-content_popover,#fff)}.with-popup-styles .nui-overlay.empty{padding:0}\n"], dependencies: [{ kind: "directive", type: i5.TemplatePortalDirective, selector: "[cdk-portal], [portal]", exportAs: ["cdkPortal"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlayComponent, decorators: [{
type: Component,
args: [{ selector: "nui-overlay", template: ` <ng-template cdk-portal>
<div
id="nui-overlay"
class="nui-overlay"
[attr.role]="roleAttr || null"
[ngClass]="{ empty: empty$ | async }"
>
<ng-content></ng-content>
</div>
</ng-template>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
Overlay,
OverlayService,
OverlayPositionService,
{ provide: OverlayContainer, useClass: OverlayCustomContainer },
], encapsulation: ViewEncapsulation.None, styles: [".nui-overlay{display:block;overflow-x:hidden;overflow-y:auto;width:100%}.with-popup-styles .nui-overlay{padding:5px 0;border-radius:3px;box-shadow:0 0 5px 0 var(--nui-shadow-color, rgba(17, 17, 17, .3));background-color:var(--nui-color-bg-content_popover,#fff)}.with-popup-styles .nui-overlay.empty{padding:0}\n"] }]
}], ctorParameters: () => [{ type: i1.OverlayPositionService }, { type: i2.OverlayService }, { type: i3.Overlay }, { type: i4.EventBusService }], propDecorators: { overlayConfig: [{
type: Input
}], toggleReference: [{
type: Input
}], viewportMargin: [{
type: Input
}], customContainer: [{
type: Input
}], roleAttr: [{
type: Input
}], clickOutside: [{
type: Output
}], contentTemplate: [{
type: ViewChild,
args: [CdkPortal]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL292ZXJsYXkvb3ZlcmxheS1jb21wb25lbnQvb3ZlcmxheS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFDSCxPQUFPLEVBQ1AsYUFBYSxFQUNiLGdCQUFnQixHQUduQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBR0gsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFFTixTQUFTLEVBQ1QsaUJBQWlCLEdBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sR0FBRyxNQUFNLFlBQVksQ0FBQztBQUM3QixPQUFPLElBQUksTUFBTSxhQUFhLENBQUM7QUFDL0IsT0FBTyxFQUFjLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDekQsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJB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Q0FBQztJQUMvQyxDQUFDO0lBRU8sbUJBQW1CO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsMkJBQTJCO0lBQ3JFLENBQUM7K0dBMUxRLGdCQUFnQjttR0FBaEIsZ0JBQWdCLDZQQVRkO1lBQ1AsT0FBTztZQUNQLGNBQWM7WUFDZCxzQkFBc0I7WUFDdEIsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLHNCQUFzQixFQUFFO1NBQ2xFLDJFQStCVSxTQUFTLHFFQS9DVjs7Ozs7Ozs7O21CQVNLOzs0RkFXTixnQkFBZ0I7a0JBdEI1QixTQUFTOytCQUNJLGFBQWEsWUFDYjs7Ozs7Ozs7O21CQVNLLG1CQUNFLHVCQUF1QixDQUFDLE1BQU0sYUFDcEM7d0JBQ1AsT0FBTzt3QkFDUCxjQUFjO3dCQUNkLHNCQUFzQjt3QkFDdEIsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLHNCQUFzQixFQUFFO3FCQUNsRSxpQkFFYyxpQkFBaUIsQ0FBQyxJQUFJOzRLQVdyQixhQUFhO3NCQUE1QixLQUFLO2dCQUdVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBR0csY0FBYztzQkFBdEIsS0FBSztnQkFHRyxlQUFlO3NCQUF2QixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR29CLFlBQVk7c0JBQXJDLE1BQU07Z0JBSUEsZUFBZTtzQkFEckIsU0FBUzt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7XG4gICAgT3ZlcmxheSxcbiAgICBPdmVybGF5Q29uZmlnLFxuICAgIE92ZXJsYXlDb250YWluZXIsXG4gICAgT3ZlcmxheVJlZixcbiAgICBPdmVybGF5U2l6ZUNvbmZpZyxcbn0gZnJvbSBcIkBhbmd1bGFyL2Nkay9vdmVybGF5XCI7XG5pbXBvcnQgeyBDZGtQb3J0YWwgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL3BvcnRhbFwiO1xuaW1wb3J0IHtcbiAgICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbnB1dCxcbiAgICBPbkNoYW5nZXMsXG4gICAgT25EZXN0cm95LFxuICAgIE91dHB1dCxcbiAgICBTaW1wbGVDaGFuZ2VzLFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCBzZXQgZnJvbSBcImxvZGFzaC9zZXRcIjtcbmltcG9ydCBzb21lIGZyb20gXCJsb2Rhc2gvc29tZVwiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGZpbHRlciwgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbmltcG9ydCB7IERPQ1VNRU5UX0NMSUNLX0VWRU5UIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy9ldmVudC5jb25zdGFudHNcIjtcbmltcG9ydCB7IEV2ZW50QnVzU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9zZXJ2aWNlcy9ldmVudC1idXMuc2VydmljZVwiO1xuaW1wb3J0IHsgT3ZlcmxheUN1c3RvbUNvbnRhaW5lciB9IGZyb20gXCIuLi9vdmVybGF5LWN1c3RvbS1jb250YWluZXJcIjtcbmltcG9ydCB7IE92ZXJsYXlQb3NpdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vb3ZlcmxheS1wb3NpdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBPdmVybGF5U2VydmljZSB9IGZyb20gXCIuLi9vdmVybGF5LnNlcnZpY2VcIjtcbmltcG9ydCB7IElPdmVybGF5Q29tcG9uZW50LCBPdmVybGF5Q29udGFpbmVyVHlwZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgUE9QVVBfVjJfVklFV1BPUlRfTUFSR0lOU19ERUZBVUxUID0gMzA7XG5cbmNvbnN0IGlzTW91c2VFdmVudCA9IChldmVudDogRXZlbnQpOiBldmVudCBpcyBNb3VzZUV2ZW50ID0+XG4gICAgZXZlbnQgaW5zdGFuY2VvZiBNb3VzZUV2ZW50O1xuXG4vLyA8ZXhhbXBsZS11cmw+Li8uLi9leGFtcGxlcy9pbmRleC5odG1sIy9vdmVybGF5PC9leGFtcGxlLXVybD5cblxuLyogQGR5bmFtaWMgKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm51aS1vdmVybGF5XCIsXG4gICAgdGVtcGxhdGU6IGAgPG5nLXRlbXBsYXRlIGNkay1wb3J0YWw+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGlkPVwibnVpLW92ZXJsYXlcIlxuICAgICAgICAgICAgY2xhc3M9XCJudWktb3ZlcmxheVwiXG4gICAgICAgICAgICBbYXR0ci5yb2xlXT1cInJvbGVBdHRyIHx8IG51bGxcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBlbXB0eTogZW1wdHkkIHwgYXN5bmMgfVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5gLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBPdmVybGF5LFxuICAgICAgICBPdmVybGF5U2VydmljZSxcbiAgICAgICAgT3ZlcmxheVBvc2l0aW9uU2VydmljZSxcbiAgICAgICAgeyBwcm92aWRlOiBPdmVybGF5Q29udGFpbmVyLCB1c2VDbGFzczogT3ZlcmxheUN1c3RvbUNvbnRhaW5lciB9LFxuICAgIF0sXG4gICAgc3R5bGVVcmxzOiBbXCJvdmVybGF5LmNvbXBvbmVudC5sZXNzXCJdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIE92ZXJsYXlDb21wb25lbnRcbiAgICBpbXBsZW1lbnRzXG4gICAgICAgIE9uRGVzdHJveSxcbiAgICAgICAgSU92ZXJsYXlDb21wb25lbnQsXG4gICAgICAgIEFmdGVyQ29udGVudENoZWNrZWQsXG4gICAgICAgIEFmdGVyVmlld0luaXQsXG4gICAgICAgIE9uQ2hhbmdlc1xue1xuICAgIC8qKiBTZXRzIG92ZXJsYXkgY29uZmlnIGluIGFjY29yZGFuY2Ugd2l0aCBbTWF0ZXJpYWwgQ0RLXXtAbGluayBodHRwczovL21hdGVyaWFsLmFuZ3VsYXIuaW8vY2RrL292ZXJsYXkvYXBpI092ZXJsYXlDb25maWd9ICovXG4gICAgQElucHV0KCkgcHVibGljIG92ZXJsYXlDb25maWc6IE92ZXJsYXlDb25maWc7XG5cbiAgICAvKiogRWxlbWVudCB0byB3aGljaCB0aGUgUG9wdXAgaXMgYXR0YWNoZWQgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdG9nZ2xlUmVmZXJlbmNlOiBIVE1MRWxlbWVudDtcblxuICAgIC8qKiBQb3B1cCB2aWV3cG9ydCBtYXJnaW5zICovXG4gICAgQElucHV0KCkgdmlld3BvcnRNYXJnaW46IG51bWJlcjtcblxuICAgIC8qKiBTZXRzIGN1c3RvbSBjb250YWluZXIgZm9yIENESyBPdmVybGF5LiBTZWxlY3RvciBPUiBFbGVtZW50UmVmICovXG4gICAgQElucHV0KCkgY3VzdG9tQ29udGFpbmVyOiBPdmVybGF5Q29udGFpbmVyVHlwZTtcblxuICAgIC8qKiBTZXRzIHRoZSByb2xlIGF0dHJpYnV0ZSAqL1xuICAgIEBJbnB1dCgpIHJvbGVBdHRyOiBzdHJpbmc7XG5cbiAgICAvKiogRW1pdHMgTW91c2VFdmVudCB3aGVuIGNsaWNrIG9jY3VycyBvdXRzaWRlIFNlbGVjdC9Db21ib2JveCAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgcmVhZG9ubHkgY2xpY2tPdXRzaWRlID0gbmV3IEV2ZW50RW1pdHRlcjxNb3VzZUV2ZW50PigpO1xuXG4gICAgLyoqIFRoZSBwbGFjZSB3aGVyZSB0aGUgUG9wdXAgd2lsbCBiZSBhdHRhY2hlZCAqL1xuICAgIEBWaWV3Q2hpbGQoQ2RrUG9ydGFsKVxuICAgIHB1YmxpYyBjb250ZW50VGVtcGxhdGU6IENka1BvcnRhbDtcblxuICAgIC8qKiBFbWl0cyBvbiB0aGUgUG9wdXAgc2hvdyAqL1xuICAgIHB1YmxpYyByZWFkb25seSBzaG93JDogU3ViamVjdDx2b2lkPjtcblxuICAgIC8qKiBFbWl0cyBvbiB0aGUgUG9wdXAgaGlkZSAqL1xuICAgIHB1YmxpYyByZWFkb25seSBoaWRlJDogU3ViamVjdDx2b2lkPjtcblxuICAgIC8qKiBFbWl0cyB3aGVuIGNvbnRlbnQgb2YgdGhlIFBvcHVwIGlzIGVtcHR5ICovXG4gICAgcHVibGljIHJlYWRvbmx5IGVtcHR5JCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG5cbiAgICAvKiogSW5kaWNhdGVzIG9wZW4vY2xvc2Ugc3RhdGUgKi9cbiAgICBwdWJsaWMgZ2V0IHNob3dpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm92ZXJsYXlTZXJ2aWNlPy5zaG93aW5nO1xuICAgIH1cblxuICAgIHByaXZhdGUgcG9zaXRpb25TdHJhdGVneVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBvdmVybGF5UG9zaXRpb25TZXJ2aWNlOiBPdmVybGF5UG9zaXRpb25TZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgb3ZlcmxheVNlcnZpY2U6IE92ZXJsYXlTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgY2RrT3ZlcmxheTogT3ZlcmxheSxcbiAgICAgICAgcHJpdmF0ZSBldmVudEJ1c1NlcnZpY2U6IEV2ZW50QnVzU2VydmljZVxuICAgICkge1xuICAgICAgICB0aGlzLnNob3ckID0gdGhpcy5vdmVybGF5U2VydmljZS5zaG93JDtcbiAgICAgICAgdGhpcy5oaWRlJCA9IHRoaXMub3ZlcmxheVNlcnZpY2UuaGlkZSQ7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3ZlcmxheVByb3BzVG9NYXAgPSBbXCJ0b2dnbGVSZWZlcmVuY2VcIiwgXCJjdXN0b21Db250YWluZXJcIl07XG5cbiAgICAgICAgaWYgKGNoYW5nZXMpIHtcbiAgICAgICAgICAgIG92ZXJsYXlQcm9wc1RvTWFwLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjaGFuZ2VzW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0KHRoaXMub3ZlcmxheVNlcnZpY2UsIGtleSwgY2hhbmdlc1trZXldLmN1cnJlbnRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm92ZXJsYXlTZXJ2aWNlLmNvbnRlbnRUZW1wbGF0ZSA9IHRoaXMuY29udGVudFRlbXBsYXRlO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ0FmdGVyQ29udGVudENoZWNrZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZW1wdHkkLm5leHQodGhpcy5pc1BvcHVwQ29udGVudEVtcHR5KCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vdmVybGF5U2VydmljZS5uZ09uRGVzdHJveSgpO1xuICAgIH1cblxuICAgIC8qKiBTaG93cyBQb3B1cCAqL1xuICAgIHB1YmxpYyBzaG93KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldE92ZXJsYXlDb25maWcoKTtcbiAgICAgICAgdGhpcy5vdmVybGF5U2VydmljZS5zaG93KCk7XG4gICAgICAgIHRoaXMuaGFuZGxlT3V0c2lkZUNsaWNrcygpO1xuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5lbXB0eSQubmV4dCh0aGlzLmlzUG9wdXBDb250ZW50RW1wdHkoKSkpOyAvLyB0aW1lb3V0IHRvIGdldCB0aGUgaGVpZ2h0IG9mIHJlbmRlcmVkIGNvbnRlbnQgaXRlbXNcbiAgICB9XG5cbiAgICAvKiogSGlkZXMgUG9wdXAgKi9cbiAgICBwdWJsaWMgaGlkZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vdmVybGF5U2VydmljZS5oaWRlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25TdHJhdGVneVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICAvKiogVG9nZ2xlcyBQb3B1cCAqL1xuICAgIHB1YmxpYyB0b2dnbGUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2Uuc2hvd2luZyA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldE92ZXJsYXlSZWYoKTogT3ZlcmxheVJlZiB7XG4gICAgICAgIHJldHVybiB0aGlzLm92ZXJsYXlTZXJ2aWNlLmdldE92ZXJsYXlSZWYoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlU2l6ZShzaXplOiBPdmVybGF5U2l6ZUNvbmZpZyk6IHZvaWQge1xuICAgICAgICB0aGlzLm92ZXJsYXlTZXJ2aWNlLnVwZGF0ZVNpemUoc2l6ZSk7XG4gICAgfVxuXG4gICAgLyoqIFN0cmVhbSBvZiBjbGlja3Mgb3V0c2lkZS4gKi9cbiAgICBwcml2YXRlIG92ZXJsYXlDbGlja091dHNpZGUoKTogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmV2ZW50QnVzU2VydmljZS5nZXRTdHJlYW0oRE9DVU1FTlRfQ0xJQ0tfRVZFTlQpLnBpcGUoXG4gICAgICAgICAgICBmaWx0ZXIoaXNNb3VzZUV2ZW50KSxcbiAgICAgICAgICAgIGZpbHRlcigoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjbGlja1RhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgICAgICBjb25zdCBub3RPcmlnaW4gPSAhc29tZShcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuY29tcG9zZWRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIChwKSA9PiBwID09PSB0aGlzLnRvZ2dsZVJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICk7IC8vIHRoZSB0b2dnbGUgZWxlbVxuICAgICAgICAgICAgICAgIGNvbnN0IG5vdE92ZXJsYXkgPVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm92ZXJsYXlTZXJ2aWNlXG4gICAgICAgICAgICAgICAgICAgICAgICAuZ2V0T3ZlcmxheVJlZigpXG4gICAgICAgICAgICAgICAgICAgICAgICA/Lm92ZXJsYXlFbGVtZW50Py5jb250YWlucyhjbGlja1RhcmdldCkgPT09IGZhbHNlOyAvLyB0aGUgcG9wdXBcblxuICAgICAgICAgICAgICAgIHJldHVybiBub3RPcmlnaW4gJiYgbm90T3ZlcmxheTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVPdXRzaWRlQ2xpY2tzKCkge1xuICAgICAgICBjb25zdCBjbGlja3NPdXRzaWRlU3RyZWFtJCA9IHRoaXMub3ZlcmxheUNvbmZpZz8uaGFzQmFja2Ryb3BcbiAgICAgICAgICAgID8gdGhpcy5vdmVybGF5U2VydmljZS5nZXRPdmVybGF5UmVmKCkuYmFja2Ryb3BDbGljaygpXG4gICAgICAgICAgICA6IHRoaXMub3ZlcmxheUNsaWNrT3V0c2lkZSgpO1xuXG4gICAgICAgIGNsaWNrc091dHNpZGVTdHJlYW0kXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5oaWRlJCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCh2KSA9PiB0aGlzLmNsaWNrT3V0c2lkZS5lbWl0KHYpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldE92ZXJsYXlDb25maWcoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG92ZXJsYXlDb25maWcgPSB0aGlzLm92ZXJsYXlTZXJ2aWNlLm92ZXJsYXlDb25maWc7XG5cbiAgICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMuY2RrT3ZlcmxheVxuICAgICAgICAgICAgLnBvc2l0aW9uKClcbiAgICAgICAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMudG9nZ2xlUmVmZXJlbmNlKVxuICAgICAgICAgICAgLndpdGhQdXNoKGZhbHNlKVxuICAgICAgICAgICAgLndpdGhWaWV3cG9ydE1hcmdpbihcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdwb3J0TWFyZ2luIHx8IFBPUFVQX1YyX1ZJRVdQT1JUX01BUkdJTlNfREVGQVVMVFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLndpdGhQb3NpdGlvbnMoW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luWDogXCJzdGFydFwiLFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5ZOiBcImJvdHRvbVwiLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WDogXCJzdGFydFwiLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WTogXCJ0b3BcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luWDogXCJzdGFydFwiLFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5ZOiBcInRvcFwiLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WDogXCJzdGFydFwiLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WTogXCJib3R0b21cIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgdGhpcy5wb3NpdGlvblN0cmF0ZWd5U3Vic2NyaXB0aW9uID1cbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVBvc2l0aW9uU2VydmljZS51cGRhdGVPZmZzZXRPblBvc2l0aW9uQ2hhbmdlcyhcbiAgICAgICAgICAgICAgICBwb3NpdGlvblN0cmF0ZWd5LFxuICAgICAgICAgICAgICAgICgpID0+IHRoaXMuZ2V0T3ZlcmxheVJlZigpXG4gICAgICAgICAgICApO1xuXG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2Uub3ZlcmxheUNvbmZpZyA9IHtcbiAgICAgICAgICAgIC4uLm92ZXJsYXlDb25maWcsXG4gICAgICAgICAgICBwb3NpdGlvblN0cmF0ZWd5LFxuICAgICAgICAgICAgLi4udGhpcy5vdmVybGF5Q29uZmlnLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29udGVudEhlaWdodCgpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBsYXN0RWxlbWVudENoaWxkID1cbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheVJlZigpPy5ob3N0RWxlbWVudD8ubGFzdEVsZW1lbnRDaGlsZDtcblxuICAgICAgICAvLyB0byBtYWludGFpbiBjdXJyZW50IHNpZ25hdHVyZSB3ZSB3aWxsIHJldHVybiAwIHRvIGF2b2lkIHVubmVjZXNzYXJ5IHVuZGVmaW5lZC9udWxsIGNoZWNrc1xuICAgICAgICByZXR1cm4gbGFzdEVsZW1lbnRDaGlsZD8uY2xpZW50SGVpZ2h0IHx8IDA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1BvcHVwQ29udGVudEVtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb250ZW50SGVpZ2h0KCkgPD0gMTA7IC8vIDEwIGlzIGZvciA1ICsgNSBwYWRkaW5nc1xuICAgIH1cbn1cbiJdfQ==