carbon-components-angular
Version:
Next generation components
290 lines • 36.2 kB
JavaScript
import { Directive, EventEmitter, HostBinding, Input, Output } from "@angular/core";
import { arrow, autoUpdate, computePosition, flip, offset } from "@floating-ui/dom";
import * as i0 from "@angular/core";
export class PopoverContainer {
constructor(elementRef, ngZone, renderer, changeDetectorRef) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.changeDetectorRef = changeDetectorRef;
this._align = "bottom";
this.alignmentClassPrefix = "cds--popover--";
/**
* Emits an event when the dialog is closed
*/
this.onClose = new EventEmitter();
/**
* Emits an event when the dialog is opened
*/
this.onOpen = new EventEmitter();
/**
* Emits an event when the state of `isOpen` changes. Allows `isOpen` to be double bound
*/
this.isOpenChange = new EventEmitter();
/**
* Show caret at the alignment position
*/
this.caret = true;
/**
* Enable drop shadow around the popover container
*/
this.dropShadow = true;
/**
* Enable high contrast for popover container
*/
this.highContrast = false;
/**
* **Experimental**: Use floating-ui to position the tooltip
* This is not toggleable - should be assigned once
*/
this.autoAlign = false;
this.containerClass = true;
this.isOpen = false;
}
/**
* Set alignment of popover
* As of v5, `oldPlacements` are now deprecated in favor of Placements
*
* When `autoAlign` is set to `true`, alignment may change for best placement
*/
set align(alignment) {
// If alignment is not passed, the default value will be `undefined`.
if (!alignment) {
return;
}
const previousAlignment = this._align;
switch (alignment) {
case "top-left":
this._align = "top-start";
break;
case "top-right":
this._align = "top-end";
break;
case "bottom-left":
this._align = "bottom-start";
break;
case "bottom-right":
this._align = "bottom-end";
break;
case "left-top":
this._align = "left-start";
break;
case "left-bottom":
this._align = "left-end";
break;
case "right-top":
this._align = "right-start";
break;
case "right-bottom":
this._align = "right-end";
break;
default:
this._align = alignment;
break;
}
this.updateAlignmentClass(this._align, previousAlignment);
}
/**
* Handles emitting open/close event
* @param open - Is the popover container open
* @param event - Event
*/
handleChange(open, event) {
// We only emit the event when parameter has an event to keep existing behavior
if ((this.isOpen !== open) && event) {
this.isOpenChange.emit(open);
}
if (open) {
if (event) {
this.onOpen.emit(event);
}
// when auto alignment is enabled, use auto update to set the placement for the element
if (this.autoAlign) {
if (this.caretRef) {
// Get caret offset/height property
// Getting computed styles once every open, otherwise expensive.
const computedStyle = getComputedStyle(this.caretRef);
const offset = computedStyle.getPropertyValue("--cds-popover-offset");
const height = computedStyle.getPropertyValue("--cds-popover-caret-height");
this.caretOffset = (offset?.includes("px") ? Number(offset.split("px", 1)[0]) : Number(offset.split("rem", 1)[0]) * 16) || 10;
this.caretHeight = (height?.includes("px") ? Number(height.split("px", 1)[0]) : Number(height.split("rem", 1)[0]) * 16) || 6;
}
if (this.elementRef.nativeElement && this.popoverContentRef) {
this.unmountFloatingElement = autoUpdate(this.elementRef.nativeElement, this.popoverContentRef, this.recomputePosition.bind(this));
}
}
}
else {
this.cleanUp();
if (event) {
this.onClose.emit(event);
}
}
this.isOpen = open;
this.changeDetectorRef.markForCheck();
}
roundByDPR(value) {
const dpr = window.devicePixelRatio || 1;
return Math.round(value * dpr) / dpr;
}
/**
* Compute position of tooltip when autoAlign is enabled
*/
recomputePosition() {
// Run outside of angular zone to avoid unnecessary change detection and rely on floating-ui
this.ngZone.runOutsideAngular(async () => {
const offsetMiddleware = this.alignmentAxisOffset !== undefined && this.alignmentAxisOffset !== null
? offset({
mainAxis: this.caretOffset,
alignmentAxis: this.alignmentAxisOffset
})
: offset(this.caretOffset);
const { x, y, placement, middlewareData } = await computePosition(this.elementRef.nativeElement, this.popoverContentRef, {
placement: this._align,
strategy: "fixed",
middleware: [
offsetMiddleware,
flip({ fallbackAxisSideDirection: "start" }),
arrow({ element: this.caretRef, padding: 16 })
]
});
const previousAlignment = this._align;
this._align = placement;
this.updateAlignmentClass(this._align, previousAlignment);
// Using CSSOM to manipulate CSS to avoid content security policy inline-src
// https://github.com/w3c/webappsec-csp/issues/212
Object.assign(this.popoverContentRef.style, {
position: "fixed",
top: "0",
left: "0",
// Using transform instead of top/left position to improve performance
transform: `translate(${this.roundByDPR(x)}px,${this.roundByDPR(y)}px)`
});
if (middlewareData.arrow) {
const { x: arrowX, y: arrowY } = middlewareData.arrow;
const staticSide = {
top: "bottom",
right: "left",
bottom: "top",
left: "right"
}[placement.split("-")[0]];
this.caretRef.style.left = arrowX != null ? `${arrowX}px` : "";
this.caretRef.style.top = arrowY != null ? `${arrowY}px` : "";
this.caretRef.style.right = "";
this.caretRef.style.bottom = "";
if (staticSide) {
this.caretRef.style[staticSide] = `${-this.caretHeight}px`;
}
}
});
}
/**
* Close the popover and reopen it with updated values without emitting an event
* @param changes
*/
ngOnChanges(changes) {
// Close and reopen the popover, handle alignment/programmatic open/close
const originalState = this.isOpen;
this.handleChange(false);
// Ignore first change since content is not initialized
if (changes.autoAlign && !changes.autoAlign.firstChange) {
// Reset the inline styles
this.popoverContentRef = this.elementRef.nativeElement.querySelector(".cds--popover-content");
this.popoverContentRef.setAttribute("style", "");
this.caretRef = this.elementRef.nativeElement.querySelector("span.cds--popover-caret");
}
this.handleChange(originalState);
}
/**
* Handle initialization of element
*/
ngAfterViewInit() {
this.initializeReferences();
}
initializeReferences() {
this.updateAlignmentClass(this._align);
// Initialize html references since they will not change and are required for popover components
this.popoverContentRef = this.elementRef.nativeElement.querySelector(".cds--popover-content");
this.caretRef = this.elementRef.nativeElement.querySelector("span.cds--popover-caret");
// Handle initial isOpen
this.handleChange(this.isOpen);
}
/**
* Clean up
*/
ngOnDestroy() {
this.cleanUp();
}
/**
* Clean up `autoUpdate` if auto alignment is enabled
*/
cleanUp() {
if (this.unmountFloatingElement) {
this.unmountFloatingElement();
}
this.unmountFloatingElement = undefined;
}
/**
* Replace existing previous alignment class with new
* @param previousAlignment
*/
updateAlignmentClass(newAlignment, previousAlignment) {
if (this.elementRef.nativeElement && previousAlignment !== newAlignment) {
const regexp = new RegExp("right|top|left|bottom");
// Since we are constantly switching, it's safer to delete all matching class names
this.elementRef.nativeElement.classList.forEach(className => {
if (regexp.test(className)) {
this.renderer.removeClass(this.elementRef.nativeElement, `${className}`);
}
});
this.renderer.addClass(this.elementRef.nativeElement, `${this.alignmentClassPrefix}${newAlignment}`);
}
}
}
PopoverContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PopoverContainer, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
PopoverContainer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: PopoverContainer, selector: "[cdsPopover], [ibmPopover]", inputs: { align: "align", caret: "caret", dropShadow: "dropShadow", highContrast: "highContrast", autoAlign: "autoAlign", isOpen: "isOpen", alignmentAxisOffset: "alignmentAxisOffset" }, outputs: { onClose: "onClose", onOpen: "onOpen", isOpenChange: "isOpenChange" }, host: { properties: { "class.cds--popover--caret": "this.caret", "class.cds--popover--drop-shadow": "this.dropShadow", "class.cds--popover--high-contrast": "this.highContrast", "class.cds--popover--auto-align": "this.autoAlign", "class.cds--popover-container": "this.containerClass", "class.cds--popover--open": "this.isOpen" } }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PopoverContainer, decorators: [{
type: Directive,
args: [{
selector: "[cdsPopover], [ibmPopover]"
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { align: [{
type: Input
}], onClose: [{
type: Output
}], onOpen: [{
type: Output
}], isOpenChange: [{
type: Output
}], caret: [{
type: HostBinding,
args: ["class.cds--popover--caret"]
}, {
type: Input
}], dropShadow: [{
type: HostBinding,
args: ["class.cds--popover--drop-shadow"]
}, {
type: Input
}], highContrast: [{
type: HostBinding,
args: ["class.cds--popover--high-contrast"]
}, {
type: Input
}], autoAlign: [{
type: HostBinding,
args: ["class.cds--popover--auto-align"]
}, {
type: Input
}], containerClass: [{
type: HostBinding,
args: ["class.cds--popover-container"]
}], isOpen: [{
type: Input
}, {
type: HostBinding,
args: ["class.cds--popover--open"]
}], alignmentAxisOffset: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcG9wb3Zlci9wb3BvdmVyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR04sU0FBUyxFQUVULFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUlMLE1BQU0sRUFHTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ04sS0FBSyxFQUNMLFVBQVUsRUFDVixlQUFlLEVBQ2YsSUFBSSxFQUNKLE1BQU0sRUFFTixNQUFNLGtCQUFrQixDQUFDOztBQWUxQixNQUFNLE9BQU8sZ0JBQWdCO0lBNEY1QixZQUNXLFVBQXNCLEVBQ3RCLE1BQWMsRUFDZCxRQUFtQixFQUNuQixpQkFBb0M7UUFIcEMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBbEQvQyxXQUFNLEdBQWMsUUFBUSxDQUFDO1FBQ3BCLHlCQUFvQixHQUFHLGdCQUFnQixDQUFDO1FBRWpEOztXQUVHO1FBQ08sWUFBTyxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzVEOztXQUVHO1FBQ08sV0FBTSxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzNEOztXQUVHO1FBQ08saUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBQ3JEOztXQUVHO1FBQ2dELFVBQUssR0FBRyxJQUFJLENBQUM7UUFDaEU7O1dBRUc7UUFDc0QsZUFBVSxHQUFHLElBQUksQ0FBQztRQUMzRTs7V0FFRztRQUN3RCxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNoRjs7O1dBR0c7UUFDcUQsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUM3QixtQkFBYyxHQUFHLElBQUksQ0FBQztRQUNqQixXQUFNLEdBQUcsS0FBSyxDQUFDO0lBa0I5RCxDQUFDO0lBaEdKOzs7OztPQUtHO0lBQ0gsSUFBYSxLQUFLLENBQUMsU0FBbUM7UUFDckQscUVBQXFFO1FBQ3JFLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZixPQUFPO1NBQ1A7UUFFRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDdEMsUUFBUSxTQUFTLEVBQUU7WUFDbEIsS0FBSyxVQUFVO2dCQUNkLElBQUksQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO2dCQUMxQixNQUFNO1lBQ1AsS0FBSyxXQUFXO2dCQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO2dCQUN4QixNQUFNO1lBQ1AsS0FBSyxhQUFhO2dCQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztnQkFDN0IsTUFBTTtZQUNQLEtBQUssY0FBYztnQkFDbEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUM7Z0JBQzNCLE1BQU07WUFDUCxLQUFLLFVBQVU7Z0JBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUM7Z0JBQzNCLE1BQU07WUFDUCxLQUFLLGFBQWE7Z0JBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDO2dCQUN6QixNQUFNO1lBQ1AsS0FBSyxXQUFXO2dCQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsYUFBYSxDQUFDO2dCQUM1QixNQUFNO1lBQ1AsS0FBSyxjQUFjO2dCQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztnQkFDMUIsTUFBTTtZQUNQO2dCQUNDLElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBc0IsQ0FBQztnQkFDckMsTUFBTTtTQUNQO1FBQ0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBdUREOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsSUFBYSxFQUFFLEtBQWE7UUFDeEMsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssRUFBRTtZQUNwQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM3QjtRQUVELElBQUksSUFBSSxFQUFFO1lBQ1QsSUFBSSxLQUFLLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDeEI7WUFFRCx1RkFBdUY7WUFDdkYsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUNuQixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7b0JBQ2xCLG1DQUFtQztvQkFDbkMsZ0VBQWdFO29CQUNoRSxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3RELE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO29CQUN0RSxNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsNEJBQTRCLENBQUMsQ0FBQztvQkFDNUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQzlILElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUM3SDtnQkFDRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtvQkFDNUQsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFVBQVUsQ0FDdkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQzdCLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDakMsQ0FBQztpQkFDRjthQUNEO1NBQ0Q7YUFBTTtZQUNOLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxFQUFFO2dCQUNWLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3pCO1NBQ0Q7UUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFLO1FBQ2YsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztRQUN6QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxpQkFBaUI7UUFDaEIsNEZBQTRGO1FBQzVGLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDeEMsTUFBTSxnQkFBZ0IsR0FDckIsSUFBSSxDQUFDLG1CQUFtQixLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssSUFBSTtnQkFDMUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztvQkFDUixRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVc7b0JBQzFCLGFBQWEsRUFBRSxJQUFJLENBQUMsbUJBQW1CO2lCQUN2QyxDQUFDO2dCQUNGLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRTdCLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsR0FBRyxNQUFNLGVBQWUsQ0FDaEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQzdCLElBQUksQ0FBQyxpQkFBaUIsRUFDdEI7Z0JBQ0MsU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUN0QixRQUFRLEVBQUUsT0FBTztnQkFDakIsVUFBVSxFQUFFO29CQUNYLGdCQUFnQjtvQkFDaEIsSUFBSSxDQUFDLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxFQUFFLENBQUM7b0JBQzVDLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQztpQkFDOUM7YUFDRCxDQUFDLENBQUM7WUFFSixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDdEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFDeEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUUxRCw0RUFBNEU7WUFDNUUsa0RBQWtEO1lBQ2xELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRTtnQkFDM0MsUUFBUSxFQUFFLE9BQU87Z0JBQ2pCLEdBQUcsRUFBRSxHQUFHO2dCQUNSLElBQUksRUFBRSxHQUFHO2dCQUNULHNFQUFzRTtnQkFDdEUsU0FBUyxFQUFFLGFBQWEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLO2FBQ3ZFLENBQUMsQ0FBQztZQUVILElBQUksY0FBYyxDQUFDLEtBQUssRUFBRTtnQkFDekIsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUM7Z0JBRXRELE1BQU0sVUFBVSxHQUFHO29CQUNsQixHQUFHLEVBQUUsUUFBUTtvQkFDYixLQUFLLEVBQUUsTUFBTTtvQkFDYixNQUFNLEVBQUUsS0FBSztvQkFDYixJQUFJLEVBQUUsT0FBTztpQkFDYixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFM0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztnQkFFaEMsSUFBSSxVQUFVLEVBQUU7b0JBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQztpQkFDM0Q7YUFDRDtRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILFdBQVcsQ0FBQyxPQUFzQjtRQUNqQyx5RUFBeUU7UUFDekUsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNsQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXpCLHVEQUF1RDtRQUN2RCxJQUFJLE9BQU8sQ0FBQyxTQUFTLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRTtZQUN4RCwwQkFBMEI7WUFDMUIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQzlGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLHlCQUF5QixDQUFDLENBQUM7U0FDdkY7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNILGVBQWU7UUFDZCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsb0JBQW9CO1FBQ25CLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdkMsZ0dBQWdHO1FBQ2hHLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUM5RixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBRXZGLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1YsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNILE9BQU87UUFDTixJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUNoQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztTQUM5QjtRQUNELElBQUksQ0FBQyxzQkFBc0IsR0FBRyxTQUFTLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7T0FHRztJQUNILG9CQUFvQixDQUFDLFlBQW9CLEVBQUUsaUJBQTBCO1FBQ3BFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLElBQUksaUJBQWlCLEtBQUssWUFBWSxFQUFFO1lBQ3hFLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDbkQsbUZBQW1GO1lBQ25GLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQzNELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDM0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQyxDQUFDO2lCQUN6RTtZQUNGLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsWUFBWSxFQUFFLENBQUMsQ0FBQztTQUNyRztJQUNGLENBQUM7OzZHQTFSVyxnQkFBZ0I7aUdBQWhCLGdCQUFnQjsyRkFBaEIsZ0JBQWdCO2tCQUg1QixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSw0QkFBNEI7aUJBQ3RDOzhLQVFhLEtBQUs7c0JBQWpCLEtBQUs7Z0JBNkNJLE9BQU87c0JBQWhCLE1BQU07Z0JBSUcsTUFBTTtzQkFBZixNQUFNO2dCQUlHLFlBQVk7c0JBQXJCLE1BQU07Z0JBSTRDLEtBQUs7c0JBQXZELFdBQVc7dUJBQUMsMkJBQTJCOztzQkFBRyxLQUFLO2dCQUlTLFVBQVU7c0JBQWxFLFdBQVc7dUJBQUMsaUNBQWlDOztzQkFBRyxLQUFLO2dCQUlLLFlBQVk7c0JBQXRFLFdBQVc7dUJBQUMsbUNBQW1DOztzQkFBRyxLQUFLO2dCQUtBLFNBQVM7c0JBQWhFLFdBQVc7dUJBQUMsZ0NBQWdDOztzQkFBRyxLQUFLO2dCQUNSLGNBQWM7c0JBQTFELFdBQVc7dUJBQUMsOEJBQThCO2dCQUNPLE1BQU07c0JBQXZELEtBQUs7O3NCQUFJLFdBQVc7dUJBQUMsMEJBQTBCO2dCQUt2QyxtQkFBbUI7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRBZnRlclZpZXdJbml0LFxuXHRDaGFuZ2VEZXRlY3RvclJlZixcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRFdmVudEVtaXR0ZXIsXG5cdEhvc3RCaW5kaW5nLFxuXHRJbnB1dCxcblx0Tmdab25lLFxuXHRPbkNoYW5nZXMsXG5cdE9uRGVzdHJveSxcblx0T3V0cHV0LFxuXHRSZW5kZXJlcjIsXG5cdFNpbXBsZUNoYW5nZXNcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG5cdGFycm93LFxuXHRhdXRvVXBkYXRlLFxuXHRjb21wdXRlUG9zaXRpb24sXG5cdGZsaXAsXG5cdG9mZnNldCxcblx0UGxhY2VtZW50XG59IGZyb20gXCJAZmxvYXRpbmctdWkvZG9tXCI7XG5cbi8vIERlcHJlY2F0ZWQgcG9wb3ZlciBhbGlnbm1lbnRzXG50eXBlIG9sZFBsYWNlbWVudCA9IFwidG9wLWxlZnRcIlxuXHR8IFwidG9wLXJpZ2h0XCJcblx0fCBcImJvdHRvbS1sZWZ0XCJcblx0fCBcImJvdHRvbS1yaWdodFwiXG5cdHwgXCJsZWZ0LWJvdHRvbVwiXG5cdHwgXCJsZWZ0LXRvcFwiXG5cdHwgXCJyaWdodC1ib3R0b21cIlxuXHR8IFwicmlnaHQtdG9wXCI7XG5cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogXCJbY2RzUG9wb3Zlcl0sIFtpYm1Qb3BvdmVyXVwiXG59KVxuZXhwb3J0IGNsYXNzIFBvcG92ZXJDb250YWluZXIgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cdC8qKlxuXHQgKiBTZXQgYWxpZ25tZW50IG9mIHBvcG92ZXJcblx0ICogQXMgb2YgdjUsIGBvbGRQbGFjZW1lbnRzYCBhcmUgbm93IGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgUGxhY2VtZW50c1xuXHQgKlxuXHQgKiBXaGVuIGBhdXRvQWxpZ25gIGlzIHNldCB0byBgdHJ1ZWAsIGFsaWdubWVudCBtYXkgY2hhbmdlIGZvciBiZXN0IHBsYWNlbWVudFxuXHQgKi9cblx0QElucHV0KCkgc2V0IGFsaWduKGFsaWdubWVudDogb2xkUGxhY2VtZW50IHwgUGxhY2VtZW50KSB7XG5cdFx0Ly8gSWYgYWxpZ25tZW50IGlzIG5vdCBwYXNzZWQsIHRoZSBkZWZhdWx0IHZhbHVlIHdpbGwgYmUgYHVuZGVmaW5lZGAuXG5cdFx0aWYgKCFhbGlnbm1lbnQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBwcmV2aW91c0FsaWdubWVudCA9IHRoaXMuX2FsaWduO1xuXHRcdHN3aXRjaCAoYWxpZ25tZW50KSB7XG5cdFx0XHRjYXNlIFwidG9wLWxlZnRcIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcInRvcC1zdGFydFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJ0b3AtcmlnaHRcIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcInRvcC1lbmRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiYm90dG9tLWxlZnRcIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcImJvdHRvbS1zdGFydFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJib3R0b20tcmlnaHRcIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcImJvdHRvbS1lbmRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwibGVmdC10b3BcIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcImxlZnQtc3RhcnRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwibGVmdC1ib3R0b21cIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcImxlZnQtZW5kXCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcInJpZ2h0LXRvcFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwicmlnaHQtc3RhcnRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwicmlnaHQtYm90dG9tXCI6XG5cdFx0XHRcdHRoaXMuX2FsaWduID0gXCJyaWdodC1lbmRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IGFsaWdubWVudCBhcyBQbGFjZW1lbnQ7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHR0aGlzLnVwZGF0ZUFsaWdubWVudENsYXNzKHRoaXMuX2FsaWduLCBwcmV2aW91c0FsaWdubWVudCk7XG5cdH1cblxuXHRfYWxpZ246IFBsYWNlbWVudCA9IFwiYm90dG9tXCI7XG5cdHJlYWRvbmx5IGFsaWdubWVudENsYXNzUHJlZml4ID0gXCJjZHMtLXBvcG92ZXItLVwiO1xuXG5cdC8qKlxuXHQgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkXG5cdCAqL1xuXHRAT3V0cHV0KCkgb25DbG9zZTogRXZlbnRFbWl0dGVyPEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGRpYWxvZyBpcyBvcGVuZWRcblx0ICovXG5cdEBPdXRwdXQoKSBvbk9wZW46IEV2ZW50RW1pdHRlcjxFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cdC8qKlxuXHQgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBzdGF0ZSBvZiBgaXNPcGVuYCBjaGFuZ2VzLiBBbGxvd3MgYGlzT3BlbmAgdG8gYmUgZG91YmxlIGJvdW5kXG5cdCAqL1xuXHRAT3V0cHV0KCkgaXNPcGVuQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXHQvKipcblx0ICogU2hvdyBjYXJldCBhdCB0aGUgYWxpZ25tZW50IHBvc2l0aW9uXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXBvcG92ZXItLWNhcmV0XCIpIEBJbnB1dCgpIGNhcmV0ID0gdHJ1ZTtcblx0LyoqXG5cdCAqIEVuYWJsZSBkcm9wIHNoYWRvdyBhcm91bmQgdGhlIHBvcG92ZXIgY29udGFpbmVyXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXBvcG92ZXItLWRyb3Atc2hhZG93XCIpIEBJbnB1dCgpIGRyb3BTaGFkb3cgPSB0cnVlO1xuXHQvKipcblx0ICogRW5hYmxlIGhpZ2ggY29udHJhc3QgZm9yIHBvcG92ZXIgY29udGFpbmVyXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXBvcG92ZXItLWhpZ2gtY29udHJhc3RcIikgQElucHV0KCkgaGlnaENvbnRyYXN0ID0gZmFsc2U7XG5cdC8qKlxuXHQgKiAqKkV4cGVyaW1lbnRhbCoqOiBVc2UgZmxvYXRpbmctdWkgdG8gcG9zaXRpb24gdGhlIHRvb2x0aXBcblx0ICogVGhpcyBpcyBub3QgdG9nZ2xlYWJsZSAtIHNob3VsZCBiZSBhc3NpZ25lZCBvbmNlXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXBvcG92ZXItLWF1dG8tYWxpZ25cIikgQElucHV0KCkgYXV0b0FsaWduID0gZmFsc2U7XG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci1jb250YWluZXJcIikgY29udGFpbmVyQ2xhc3MgPSB0cnVlO1xuXHRASW5wdXQoKSBASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXBvcG92ZXItLW9wZW5cIikgaXNPcGVuID0gZmFsc2U7XG5cdC8qKlxuXHQgKiAqKkV4cGVyaW1lbnRhbDoqKiBQcm92aWRlIGFuIG9mZnNldCB2YWx1ZSBmb3IgYWxpZ25tZW50IGF4aXMuXG5cdCAqIE9ubHkgdGFrZXMgZWZmZWN0IHdoZW4gYGF1dG9hbGlnbmAgaXMgZW5hYmxlZC5cblx0ICovXG5cdEBJbnB1dCgpIGFsaWdubWVudEF4aXNPZmZzZXQ/OiBudW1iZXI7XG5cblx0cHJvdGVjdGVkIHBvcG92ZXJDb250ZW50UmVmOiBIVE1MRWxlbWVudDtcblx0cHJvdGVjdGVkIGNhcmV0UmVmOiBIVE1MRWxlbWVudDtcblx0cHJvdGVjdGVkIGNhcmV0T2Zmc2V0OiBudW1iZXI7XG5cdHByb3RlY3RlZCBjYXJldEhlaWdodDogbnVtYmVyO1xuXHRwcm90ZWN0ZWQgdW5tb3VudEZsb2F0aW5nRWxlbWVudDogRnVuY3Rpb247XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJvdGVjdGVkIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG5cdFx0cHJvdGVjdGVkIG5nWm9uZTogTmdab25lLFxuXHRcdHByb3RlY3RlZCByZW5kZXJlcjogUmVuZGVyZXIyLFxuXHRcdHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcblx0KSB7fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIGVtaXR0aW5nIG9wZW4vY2xvc2UgZXZlbnRcblx0ICogQHBhcmFtIG9wZW4gLSBJcyB0aGUgcG9wb3ZlciBjb250YWluZXIgb3BlblxuXHQgKiBAcGFyYW0gZXZlbnQgLSBFdmVudFxuXHQgKi9cblx0aGFuZGxlQ2hhbmdlKG9wZW46IGJvb2xlYW4sIGV2ZW50PzogRXZlbnQpIHtcblx0XHQvLyBXZSBvbmx5IGVtaXQgdGhlIGV2ZW50IHdoZW4gcGFyYW1ldGVyIGhhcyBhbiBldmVudCB0byBrZWVwIGV4aXN0aW5nIGJlaGF2aW9yXG5cdFx0aWYgKCh0aGlzLmlzT3BlbiAhPT0gb3BlbikgJiYgZXZlbnQpIHtcblx0XHRcdHRoaXMuaXNPcGVuQ2hhbmdlLmVtaXQob3Blbik7XG5cdFx0fVxuXG5cdFx0aWYgKG9wZW4pIHtcblx0XHRcdGlmIChldmVudCkge1xuXHRcdFx0XHR0aGlzLm9uT3Blbi5lbWl0KGV2ZW50KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gd2hlbiBhdXRvIGFsaWdubWVudCBpcyBlbmFibGVkLCB1c2UgYXV0byB1cGRhdGUgdG8gc2V0IHRoZSBwbGFjZW1lbnQgZm9yIHRoZSBlbGVtZW50XG5cdFx0XHRpZiAodGhpcy5hdXRvQWxpZ24pIHtcblx0XHRcdFx0aWYgKHRoaXMuY2FyZXRSZWYpIHtcblx0XHRcdFx0XHQvLyBHZXQgY2FyZXQgb2Zmc2V0L2hlaWdodCBwcm9wZXJ0eVxuXHRcdFx0XHRcdC8vIEdldHRpbmcgY29tcHV0ZWQgc3R5bGVzIG9uY2UgZXZlcnkgb3Blbiwgb3RoZXJ3aXNlIGV4cGVuc2l2ZS5cblx0XHRcdFx0XHRjb25zdCBjb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmNhcmV0UmVmKTtcblx0XHRcdFx0XHRjb25zdCBvZmZzZXQgPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLWNkcy1wb3BvdmVyLW9mZnNldFwiKTtcblx0XHRcdFx0XHRjb25zdCBoZWlnaHQgPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLWNkcy1wb3BvdmVyLWNhcmV0LWhlaWdodFwiKTtcblx0XHRcdFx0XHR0aGlzLmNhcmV0T2Zmc2V0ID0gKG9mZnNldD8uaW5jbHVkZXMoXCJweFwiKSA/IE51bWJlcihvZmZzZXQuc3BsaXQoXCJweFwiLCAxKVswXSkgOiBOdW1iZXIob2Zmc2V0LnNwbGl0KFwicmVtXCIsIDEpWzBdKSAqIDE2KSB8fCAxMDtcblx0XHRcdFx0XHR0aGlzLmNhcmV0SGVpZ2h0ID0gKGhlaWdodD8uaW5jbHVkZXMoXCJweFwiKSA/IE51bWJlcihoZWlnaHQuc3BsaXQoXCJweFwiLCAxKVswXSkgOiBOdW1iZXIoaGVpZ2h0LnNwbGl0KFwicmVtXCIsIDEpWzBdKSAqIDE2KSB8fCA2O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCAmJiB0aGlzLnBvcG92ZXJDb250ZW50UmVmKSB7XG5cdFx0XHRcdFx0dGhpcy51bm1vdW50RmxvYXRpbmdFbGVtZW50ID0gYXV0b1VwZGF0ZShcblx0XHRcdFx0XHRcdHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LFxuXHRcdFx0XHRcdFx0dGhpcy5wb3BvdmVyQ29udGVudFJlZixcblx0XHRcdFx0XHRcdHRoaXMucmVjb21wdXRlUG9zaXRpb24uYmluZCh0aGlzKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5jbGVhblVwKCk7XG5cdFx0XHRpZiAoZXZlbnQpIHtcblx0XHRcdFx0dGhpcy5vbkNsb3NlLmVtaXQoZXZlbnQpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLmlzT3BlbiA9IG9wZW47XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0fVxuXG5cdHJvdW5kQnlEUFIodmFsdWUpIHtcblx0XHRjb25zdCBkcHIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuXHRcdHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogZHByKSAvIGRwcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb21wdXRlIHBvc2l0aW9uIG9mIHRvb2x0aXAgd2hlbiBhdXRvQWxpZ24gaXMgZW5hYmxlZFxuXHQgKi9cblx0cmVjb21wdXRlUG9zaXRpb24oKSB7XG5cdFx0Ly8gUnVuIG91dHNpZGUgb2YgYW5ndWxhciB6b25lIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNoYW5nZSBkZXRlY3Rpb24gYW5kIHJlbHkgb24gZmxvYXRpbmctdWlcblx0XHR0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcihhc3luYyAoKSA9PiB7XG5cdFx0XHRjb25zdCBvZmZzZXRNaWRkbGV3YXJlID1cblx0XHRcdFx0dGhpcy5hbGlnbm1lbnRBeGlzT2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5hbGlnbm1lbnRBeGlzT2Zmc2V0ICE9PSBudWxsXG5cdFx0XHRcdFx0PyBvZmZzZXQoe1xuXHRcdFx0XHRcdFx0bWFpbkF4aXM6IHRoaXMuY2FyZXRPZmZzZXQsXG5cdFx0XHRcdFx0XHRhbGlnbm1lbnRBeGlzOiB0aGlzLmFsaWdubWVudEF4aXNPZmZzZXRcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdDogb2Zmc2V0KHRoaXMuY2FyZXRPZmZzZXQpO1xuXG5cdFx0XHRjb25zdCB7IHgsIHksIHBsYWNlbWVudCwgbWlkZGxld2FyZURhdGEgfSA9IGF3YWl0IGNvbXB1dGVQb3NpdGlvbihcblx0XHRcdFx0dGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdHRoaXMucG9wb3ZlckNvbnRlbnRSZWYsXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRwbGFjZW1lbnQ6IHRoaXMuX2FsaWduLFxuXHRcdFx0XHRcdHN0cmF0ZWd5OiBcImZpeGVkXCIsXG5cdFx0XHRcdFx0bWlkZGxld2FyZTogW1xuXHRcdFx0XHRcdFx0b2Zmc2V0TWlkZGxld2FyZSxcblx0XHRcdFx0XHRcdGZsaXAoeyBmYWxsYmFja0F4aXNTaWRlRGlyZWN0aW9uOiBcInN0YXJ0XCIgfSksXG5cdFx0XHRcdFx0XHRhcnJvdyh7IGVsZW1lbnQ6IHRoaXMuY2FyZXRSZWYsIHBhZGRpbmc6IDE2IH0pXG5cdFx0XHRcdFx0XVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0Y29uc3QgcHJldmlvdXNBbGlnbm1lbnQgPSB0aGlzLl9hbGlnbjtcblx0XHRcdHRoaXMuX2FsaWduID0gcGxhY2VtZW50O1xuXHRcdFx0dGhpcy51cGRhdGVBbGlnbm1lbnRDbGFzcyh0aGlzLl9hbGlnbiwgcHJldmlvdXNBbGlnbm1lbnQpO1xuXG5cdFx0XHQvLyBVc2luZyBDU1NPTSB0byBtYW5pcHVsYXRlIENTUyB0byBhdm9pZCBjb250ZW50IHNlY3VyaXR5IHBvbGljeSBpbmxpbmUtc3JjXG5cdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vdzNjL3dlYmFwcHNlYy1jc3AvaXNzdWVzLzIxMlxuXHRcdFx0T2JqZWN0LmFzc2lnbih0aGlzLnBvcG92ZXJDb250ZW50UmVmLnN0eWxlLCB7XG5cdFx0XHRcdHBvc2l0aW9uOiBcImZpeGVkXCIsXG5cdFx0XHRcdHRvcDogXCIwXCIsXG5cdFx0XHRcdGxlZnQ6IFwiMFwiLFxuXHRcdFx0XHQvLyBVc2luZyB0cmFuc2Zvcm0gaW5zdGVhZCBvZiB0b3AvbGVmdCBwb3NpdGlvbiB0byBpbXByb3ZlIHBlcmZvcm1hbmNlXG5cdFx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgke3RoaXMucm91bmRCeURQUih4KX1weCwke3RoaXMucm91bmRCeURQUih5KX1weClgXG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKG1pZGRsZXdhcmVEYXRhLmFycm93KSB7XG5cdFx0XHRcdGNvbnN0IHsgeDogYXJyb3dYLCB5OiBhcnJvd1kgfSA9IG1pZGRsZXdhcmVEYXRhLmFycm93O1xuXG5cdFx0XHRcdGNvbnN0IHN0YXRpY1NpZGUgPSB7XG5cdFx0XHRcdFx0dG9wOiBcImJvdHRvbVwiLFxuXHRcdFx0XHRcdHJpZ2h0OiBcImxlZnRcIixcblx0XHRcdFx0XHRib3R0b206IFwidG9wXCIsXG5cdFx0XHRcdFx0bGVmdDogXCJyaWdodFwiXG5cdFx0XHRcdH1bcGxhY2VtZW50LnNwbGl0KFwiLVwiKVswXV07XG5cblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS5sZWZ0ID0gYXJyb3dYICE9IG51bGwgPyBgJHthcnJvd1h9cHhgIDogXCJcIjtcblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS50b3AgPSBhcnJvd1kgIT0gbnVsbCA/IGAke2Fycm93WX1weGAgOiBcIlwiO1xuXHRcdFx0XHR0aGlzLmNhcmV0UmVmLnN0eWxlLnJpZ2h0ID0gXCJcIjtcblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS5ib3R0b20gPSBcIlwiO1xuXG5cdFx0XHRcdGlmIChzdGF0aWNTaWRlKSB7XG5cdFx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZVtzdGF0aWNTaWRlXSA9IGAkey10aGlzLmNhcmV0SGVpZ2h0fXB4YDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsb3NlIHRoZSBwb3BvdmVyIGFuZCByZW9wZW4gaXQgd2l0aCB1cGRhdGVkIHZhbHVlcyB3aXRob3V0IGVtaXR0aW5nIGFuIGV2ZW50XG5cdCAqIEBwYXJhbSBjaGFuZ2VzXG5cdCAqL1xuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG5cdFx0Ly8gQ2xvc2UgYW5kIHJlb3BlbiB0aGUgcG9wb3ZlciwgaGFuZGxlIGFsaWdubWVudC9wcm9ncmFtbWF0aWMgb3Blbi9jbG9zZVxuXHRcdGNvbnN0IG9yaWdpbmFsU3RhdGUgPSB0aGlzLmlzT3Blbjtcblx0XHR0aGlzLmhhbmRsZUNoYW5nZShmYWxzZSk7XG5cblx0XHQvLyBJZ25vcmUgZmlyc3QgY2hhbmdlIHNpbmNlIGNvbnRlbnQgaXMgbm90IGluaXRpYWxpemVkXG5cdFx0aWYgKGNoYW5nZXMuYXV0b0FsaWduICYmICFjaGFuZ2VzLmF1dG9BbGlnbi5maXJzdENoYW5nZSkge1xuXHRcdFx0Ly8gUmVzZXQgdGhlIGlubGluZSBzdHlsZXNcblx0XHRcdHRoaXMucG9wb3ZlckNvbnRlbnRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLmNkcy0tcG9wb3Zlci1jb250ZW50XCIpO1xuXHRcdFx0dGhpcy5wb3BvdmVyQ29udGVudFJlZi5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBcIlwiKTtcblx0XHRcdHRoaXMuY2FyZXRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwic3Bhbi5jZHMtLXBvcG92ZXItY2FyZXRcIik7XG5cdFx0fVxuXG5cdFx0dGhpcy5oYW5kbGVDaGFuZ2Uob3JpZ2luYWxTdGF0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlIGluaXRpYWxpemF0aW9uIG9mIGVsZW1lbnRcblx0ICovXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcblx0XHR0aGlzLmluaXRpYWxpemVSZWZlcmVuY2VzKCk7XG5cdH1cblxuXHRpbml0aWFsaXplUmVmZXJlbmNlcygpOiB2b2lkIHtcblx0XHR0aGlzLnVwZGF0ZUFsaWdubWVudENsYXNzKHRoaXMuX2FsaWduKTtcblxuXHRcdC8vIEluaXRpYWxpemUgaHRtbCByZWZlcmVuY2VzIHNpbmNlIHRoZXkgd2lsbCBub3QgY2hhbmdlIGFuZCBhcmUgcmVxdWlyZWQgZm9yIHBvcG92ZXIgY29tcG9uZW50c1xuXHRcdHRoaXMucG9wb3ZlckNvbnRlbnRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLmNkcy0tcG9wb3Zlci1jb250ZW50XCIpO1xuXHRcdHRoaXMuY2FyZXRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwic3Bhbi5jZHMtLXBvcG92ZXItY2FyZXRcIik7XG5cblx0XHQvLyBIYW5kbGUgaW5pdGlhbCBpc09wZW5cblx0XHR0aGlzLmhhbmRsZUNoYW5nZSh0aGlzLmlzT3Blbik7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYW4gdXBcblx0ICovXG5cdG5nT25EZXN0cm95KCk6IHZvaWQge1xuXHRcdHRoaXMuY2xlYW5VcCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFuIHVwIGBhdXRvVXBkYXRlYCBpZiBhdXRvIGFsaWdubWVudCBpcyBlbmFibGVkXG5cdCAqL1xuXHRjbGVhblVwKCkge1xuXHRcdGlmICh0aGlzLnVubW91bnRGbG9hdGluZ0VsZW1lbnQpIHtcblx0XHRcdHRoaXMudW5tb3VudEZsb2F0aW5nRWxlbWVudCgpO1xuXHRcdH1cblx0XHR0aGlzLnVubW91bnRGbG9hdGluZ0VsZW1lbnQgPSB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKipcblx0ICogUmVwbGFjZSBleGlzdGluZyBwcmV2aW91cyBhbGlnbm1lbnQgY2xhc3Mgd2l0aCBuZXdcblx0ICogQHBhcmFtIHByZXZpb3VzQWxpZ25tZW50XG5cdCAqL1xuXHR1cGRhdGVBbGlnbm1lbnRDbGFzcyhuZXdBbGlnbm1lbnQ6IHN0cmluZywgcHJldmlvdXNBbGlnbm1lbnQ/OiBzdHJpbmcpIHtcblx0XHRpZiAodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgJiYgcHJldmlvdXNBbGlnbm1lbnQgIT09IG5ld0FsaWdubWVudCkge1xuXHRcdFx0Y29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChcInJpZ2h0fHRvcHxsZWZ0fGJvdHRvbVwiKTtcblx0XHRcdC8vIFNpbmNlIHdlIGFyZSBjb25zdGFudGx5IHN3aXRjaGluZywgaXQncyBzYWZlciB0byBkZWxldGUgYWxsIG1hdGNoaW5nIGNsYXNzIG5hbWVzXG5cdFx0XHR0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuXHRcdFx0XHRpZiAocmVnZXhwLnRlc3QoY2xhc3NOYW1lKSkge1xuXHRcdFx0XHRcdHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIGAke2NsYXNzTmFtZX1gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBgJHt0aGlzLmFsaWdubWVudENsYXNzUHJlZml4fSR7bmV3QWxpZ25tZW50fWApO1xuXHRcdH1cblx0fVxufVxuIl19