@nova-ui/bits
Version:
SolarWinds Nova Framework
154 lines • 28.9 kB
JavaScript
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from "@angular/core";
import { Subject } from "rxjs";
import { debounceTime, takeUntil } from "rxjs/operators";
import { CheckboxStatus, SelectionType } from "./public-api";
import { CheckboxComponent } from "../checkbox/checkbox.component";
import { OVERLAY_WITH_POPUP_STYLES_CLASS } from "../overlay/constants";
import { OverlayComponent } from "../overlay/overlay-component/overlay.component";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../checkbox/checkbox.component";
import * as i3 from "../menu/menu-popup/menu-popup.component";
import * as i4 from "../button/button.component";
import * as i5 from "../overlay/overlay-component/overlay.component";
/**
* @ignore
* <example-url>./../examples/index.html#/selector</example-url>
*/
/**
* __Name :__
* NUI Selector component.
*
* __Usage :__
* Component provides different options to select elements
* by emmiting appropriate event.
* Checkbox and droplist allow to select "All" or "None" items.
* Droplist has additional option to select "All pages". Component
* has indication about which selection option is active now and
* binding property to set indeterminate state.
*/
export class SelectorComponent {
constructor() {
this.ariaLabel = "Selector";
this.selectionChange = new EventEmitter();
this.checkboxChecked = false;
this.indeterminate = false;
this.onDestroy$ = new Subject();
this.overlayConfig = {
panelClass: [OVERLAY_WITH_POPUP_STYLES_CLASS],
};
this.selectionHasChanged = false;
}
ngOnChanges(changes) {
if (changes["checkboxStatus"]) {
const checkboxStatus = changes["checkboxStatus"].currentValue;
this.indeterminate =
checkboxStatus === CheckboxStatus.Indeterminate;
this.checkboxChecked = checkboxStatus === CheckboxStatus.Checked;
}
if (changes.appendToBody) {
this.customContainer = changes.appendToBody.currentValue
? undefined
: this.popupArea;
}
}
ngAfterViewInit() {
const debounceTimeValue = 10;
this.checkbox.valueChange
.pipe(debounceTime(debounceTimeValue))
.subscribe(this.onCheckboxValueChange.bind(this));
this.overlay.clickOutside
.pipe(takeUntil(this.onDestroy$))
.subscribe((_) => this.overlay.hide());
// TODO: should change programmatically in scope of NUI-5937
this.checkbox.checkboxLabel.nativeElement.setAttribute("tabindex", "-1");
}
ngOnDestroy() {
this.checkbox.valueChange.unsubscribe();
this.onDestroy$.next();
this.onDestroy$.complete();
}
getFilters() {
const response = {
type: "selector",
value: {
selectorState: {
checkboxStatus: this.checkboxStatus,
selectorItems: this.items,
},
status: this.status,
selectionHasChanged: this.selectionHasChanged,
},
};
this.selectionHasChanged = false;
return response;
}
handleSelectorClick(event) {
if (event.currentTarget !== event.target) {
return;
}
this.indeterminate = false;
this.checkboxChecked = !this.checkboxChecked;
const selection = this.checkboxChecked
? SelectionType.All
: SelectionType.None;
this.status = selection;
this.selectionChange.emit(selection);
}
onCheckboxValueChange(event) {
this.indeterminate = false;
this.checkboxChecked = !this.checkboxChecked;
this.status = this.checkboxChecked
? SelectionType.All
: SelectionType.None;
this.selectionHasChanged = true;
if (event.target.checked) {
// gives control to "selectionChange" stream
this.selectionChange.emit(SelectionType.All);
}
else {
// gives control to "selectionChange" stream
this.selectionChange.emit(SelectionType.UnselectAll);
}
}
handleItemClick(item) {
const selection = item.value || item.title;
this.checkboxChecked =
selection === SelectionType.All ||
selection === SelectionType.AllPages;
this.status = selection;
this.selectionHasChanged = true;
// propagate selection
this.selectionChange.emit(selection);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectorComponent, selector: "nui-selector", inputs: { checkboxStatus: "checkboxStatus", items: "items", appendToBody: "appendToBody", ariaLabel: "ariaLabel" }, outputs: { selectionChange: "selectionChange" }, host: { attributes: { "tabindex": "-1" }, properties: { "attr.aria-label": "ariaLabel" }, classAttribute: "nui-selector" }, viewQueries: [{ propertyName: "checkbox", first: true, predicate: ["checkbox"], descendants: true }, { propertyName: "popupArea", first: true, predicate: ["popupArea"], descendants: true, static: true }, { propertyName: "overlay", first: true, predicate: OverlayComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"btn-group\" #toggleButton>\n <button\n nui-button\n type=\"button\"\n role=\"checkbox\"\n [attr.aria-checked]=\"checkboxChecked\"\n class=\"nui-selector__checkbox-button\"\n [displayStyle]=\"'default'\"\n (click)=\"handleSelectorClick($event)\"\n >\n <div class=\"nui-selector__checkbox-container\">\n <nui-checkbox\n #checkbox\n [checked]=\"checkboxChecked\"\n [indeterminate]=\"indeterminate\"\n >\n </nui-checkbox>\n </div>\n </button>\n <button\n nui-button\n *ngIf=\"items?.length\"\n type=\"button\"\n class=\"nui-selector__toggle\"\n ariaLabel=\"Open Selector Menu\"\n [displayStyle]=\"'default'\"\n [icon]=\"'caret-down'\"\n (click)=\"overlay.toggle()\"\n ></button>\n</div>\n\n<div #popupArea></div>\n\n<nui-overlay\n #overlay\n [toggleReference]=\"toggleButton\"\n [overlayConfig]=\"overlayConfig\"\n [customContainer]=\"customContainer\"\n>\n <nui-menu-popup\n [itemsSource]=\"items\"\n (menuItemClicked)=\"handleItemClick($event)\"\n ></nui-menu-popup>\n</nui-overlay>\n", styles: [".nui .nui-selector{max-height:30px;min-width:67px}.nui .nui-selector__checkbox-button{border:1px solid #d9d9d9;border:1px solid var(--nui-color-line-default, #d9d9d9);border-top-left-radius:3px;border-bottom-left-radius:3px}.nui .nui-selector__checkbox-button.btn{min-width:35px;width:35px;padding:0;border-width:0}.nui .nui-selector__checkbox-button.btn:focus{outline:none}.nui .nui-selector .nui-button__content{width:100%}.nui .nui-selector .nui-checkbox__label{width:100%;border-radius:3px 0 0 3px;border:1px solid;border-color:var(--nui-color-line-default,#d9d9d9)}.nui .nui-selector .nui-checkbox__label .nui-checkbox__mark{margin:-1px 0}.nui .nui-selector .nui-checkbox__label:hover{background-color:var(--nui-color-bg-transparent-hover,rgba(17, 17, 17, .05))}.nui .nui-selector__toggle{margin-right:0;border:1px solid #0079aa;border:1px solid var(--nui-color-line-active, #0079aa);border-bottom-left-radius:0;border-top-left-radius:0;padding:0 19px;height:auto}.nui .nui-selector__toggle.btn:focus{outline:none}.nui .nui-selector__toggle.nui-button.icon-left .nui-icon{float:none}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.CheckboxComponent, selector: "nui-checkbox", inputs: ["ariaLabel", "ariaLabelledby", "ariaDescribedby", "name", "title", "value", "hovered", "checked", "required", "hint", "disabled", "indeterminate"], outputs: ["valueChange"] }, { kind: "component", type: i3.MenuPopupComponent, selector: "nui-menu-popup", inputs: ["itemsSource", "size"], outputs: ["menuItemClicked"] }, { kind: "component", type: i4.ButtonComponent, selector: "[nui-button]", inputs: ["displayStyle", "icon", "iconColor", "iconRight", "isBusy", "isEmpty", "ariaLabel", "isRepeat", "size"] }, { kind: "component", type: i5.OverlayComponent, selector: "nui-overlay", inputs: ["overlayConfig", "toggleReference", "viewportMargin", "customContainer", "roleAttr"], outputs: ["clickOutside"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectorComponent, decorators: [{
type: Component,
args: [{ selector: "nui-selector", host: {
class: "nui-selector",
tabindex: "-1",
"[attr.aria-label]": "ariaLabel",
}, encapsulation: ViewEncapsulation.None, template: "<div class=\"btn-group\" #toggleButton>\n <button\n nui-button\n type=\"button\"\n role=\"checkbox\"\n [attr.aria-checked]=\"checkboxChecked\"\n class=\"nui-selector__checkbox-button\"\n [displayStyle]=\"'default'\"\n (click)=\"handleSelectorClick($event)\"\n >\n <div class=\"nui-selector__checkbox-container\">\n <nui-checkbox\n #checkbox\n [checked]=\"checkboxChecked\"\n [indeterminate]=\"indeterminate\"\n >\n </nui-checkbox>\n </div>\n </button>\n <button\n nui-button\n *ngIf=\"items?.length\"\n type=\"button\"\n class=\"nui-selector__toggle\"\n ariaLabel=\"Open Selector Menu\"\n [displayStyle]=\"'default'\"\n [icon]=\"'caret-down'\"\n (click)=\"overlay.toggle()\"\n ></button>\n</div>\n\n<div #popupArea></div>\n\n<nui-overlay\n #overlay\n [toggleReference]=\"toggleButton\"\n [overlayConfig]=\"overlayConfig\"\n [customContainer]=\"customContainer\"\n>\n <nui-menu-popup\n [itemsSource]=\"items\"\n (menuItemClicked)=\"handleItemClick($event)\"\n ></nui-menu-popup>\n</nui-overlay>\n", styles: [".nui .nui-selector{max-height:30px;min-width:67px}.nui .nui-selector__checkbox-button{border:1px solid #d9d9d9;border:1px solid var(--nui-color-line-default, #d9d9d9);border-top-left-radius:3px;border-bottom-left-radius:3px}.nui .nui-selector__checkbox-button.btn{min-width:35px;width:35px;padding:0;border-width:0}.nui .nui-selector__checkbox-button.btn:focus{outline:none}.nui .nui-selector .nui-button__content{width:100%}.nui .nui-selector .nui-checkbox__label{width:100%;border-radius:3px 0 0 3px;border:1px solid;border-color:var(--nui-color-line-default,#d9d9d9)}.nui .nui-selector .nui-checkbox__label .nui-checkbox__mark{margin:-1px 0}.nui .nui-selector .nui-checkbox__label:hover{background-color:var(--nui-color-bg-transparent-hover,rgba(17, 17, 17, .05))}.nui .nui-selector__toggle{margin-right:0;border:1px solid #0079aa;border:1px solid var(--nui-color-line-active, #0079aa);border-bottom-left-radius:0;border-top-left-radius:0;padding:0 19px;height:auto}.nui .nui-selector__toggle.btn:focus{outline:none}.nui .nui-selector__toggle.nui-button.icon-left .nui-icon{float:none}\n"] }]
}], propDecorators: { checkboxStatus: [{
type: Input
}], items: [{
type: Input
}], appendToBody: [{
type: Input
}], ariaLabel: [{
type: Input
}], selectionChange: [{
type: Output
}], checkbox: [{
type: ViewChild,
args: ["checkbox"]
}], popupArea: [{
type: ViewChild,
args: ["popupArea", { static: true }]
}], overlay: [{
type: ViewChild,
args: [OverlayComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9zZWxlY3Rvci9zZWxlY3Rvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NlbGVjdG9yL3NlbGVjdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFCQSxPQUFPLEVBRUgsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFFTixTQUFTLEVBQ1QsaUJBQWlCLEdBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQU03RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUduRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQzs7Ozs7OztBQUVsRjs7O0dBR0c7QUFFSDs7Ozs7Ozs7Ozs7R0FXRztBQVlILE1BQU0sT0FBTyxpQkFBaUI7SUFYOUI7UUEyQlcsY0FBUyxHQUFXLFVBQVUsQ0FBQztRQUcvQixvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFpQixDQUFDO1FBVXBELG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2pDLGtCQUFhLEdBQWtCO1lBQ2xDLFVBQVUsRUFBRSxDQUFDLCtCQUErQixDQUFDO1NBQ2hELENBQUM7UUFJTSx3QkFBbUIsR0FBRyxLQUFLLENBQUM7S0Fz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SUMsS0FBSztzQkFEWCxLQUFLO2dCQUlDLFlBQVk7c0JBRGxCLEtBQUs7Z0JBSUMsU0FBUztzQkFEZixLQUFLO2dCQUlDLGVBQWU7c0JBRHJCLE1BQU07Z0JBSUEsUUFBUTtzQkFEZCxTQUFTO3VCQUFDLFVBQVU7Z0JBR3FCLFNBQVM7c0JBQWxELFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFFSixPQUFPO3NCQUExQyxTQUFTO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgeyBPdmVybGF5Q29uZmlnIH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9vdmVybGF5XCI7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIHRha2VVbnRpbCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuXG5pbXBvcnQgeyBDaGVja2JveFN0YXR1cywgU2VsZWN0aW9uVHlwZSB9IGZyb20gXCIuL3B1YmxpYy1hcGlcIjtcbmltcG9ydCB7XG4gICAgSUZpbHRlcixcbiAgICBJRmlsdGVyUHViLFxuICAgIElTZWxlY3RvckZpbHRlcixcbn0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL2RhdGEtc291cmNlL3B1YmxpYy1hcGlcIjtcbmltcG9ydCB7IENoZWNrYm94Q29tcG9uZW50IH0gZnJvbSBcIi4uL2NoZWNrYm94L2NoZWNrYm94LmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgQ2hlY2tib3hDaGFuZ2VFdmVudCB9IGZyb20gXCIuLi9jaGVja2JveC9wdWJsaWMtYXBpXCI7XG5pbXBvcnQgeyBJTWVudUdyb3VwLCBJTWVudUl0ZW0gfSBmcm9tIFwiLi4vbWVudS9wdWJsaWMtYXBpXCI7XG5pbXBvcnQgeyBPVkVSTEFZX1dJVEhfUE9QVVBfU1RZTEVTX0NMQVNTIH0gZnJvbSBcIi4uL292ZXJsYXkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPdmVybGF5Q29tcG9uZW50IH0gZnJvbSBcIi4uL292ZXJsYXkvb3ZlcmxheS1jb21wb25lbnQvb3ZlcmxheS5jb21wb25lbnRcIjtcblxuLyoqXG4gKiBAaWdub3JlXG4gKiA8ZXhhbXBsZS11cmw+Li8uLi9leGFtcGxlcy9pbmRleC5odG1sIy9zZWxlY3RvcjwvZXhhbXBsZS11cmw+XG4gKi9cblxuLyoqXG4gKiBfX05hbWUgOl9fXG4gKiBOVUkgU2VsZWN0b3IgY29tcG9uZW50LlxuICpcbiAqIF9fVXNhZ2UgOl9fXG4gKiBDb21wb25lbnQgcHJvdmlkZXMgZGlmZmVyZW50IG9wdGlvbnMgdG8gc2VsZWN0IGVsZW1lbnRzXG4gKiBieSBlbW1pdGluZyBhcHByb3ByaWF0ZSBldmVudC5cbiAqIENoZWNrYm94IGFuZCBkcm9wbGlzdCBhbGxvdyB0byBzZWxlY3QgXCJBbGxcIiBvciBcIk5vbmVcIiBpdGVtcy5cbiAqIERyb3BsaXN0IGhhcyBhZGRpdGlvbmFsIG9wdGlvbiB0byBzZWxlY3QgXCJBbGwgcGFnZXNcIi4gQ29tcG9uZW50XG4gKiBoYXMgaW5kaWNhdGlvbiBhYm91dCB3aGljaCBzZWxlY3Rpb24gb3B0aW9uIGlzIGFjdGl2ZSBub3cgYW5kXG4gKiBiaW5kaW5nIHByb3BlcnR5IHRvIHNldCBpbmRldGVybWluYXRlIHN0YXRlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogXCJudWktc2VsZWN0b3JcIixcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiBcIm51aS1zZWxlY3RvclwiLFxuICAgICAgICB0YWJpbmRleDogXCItMVwiLFxuICAgICAgICBcIlthdHRyLmFyaWEtbGFiZWxdXCI6IFwiYXJpYUxhYmVsXCIsXG4gICAgfSxcbiAgICB0ZW1wbGF0ZVVybDogXCIuL3NlbGVjdG9yLmNvbXBvbmVudC5odG1sXCIsXG4gICAgc3R5bGVVcmxzOiBbXCIuL3NlbGVjdG9yLmNvbXBvbmVudC5sZXNzXCJdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIFNlbGVjdG9yQ29tcG9uZW50XG4gICAgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgSUZpbHRlclB1Ylxue1xuICAgIC8qKlxuICAgICAqIHJlc2V0cyBzZWxlY3Rpb24sIG1ha2VzIGNvbXBvbmVudCBhcHBlYXJhbmNlIGluZGV0ZXJtaW5hdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBjaGVja2JveFN0YXR1czogQ2hlY2tib3hTdGF0dXM7XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpdGVtczogSU1lbnVHcm91cFtdO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgYXBwZW5kVG9Cb2R5OiBib29sZWFuO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgYXJpYUxhYmVsOiBzdHJpbmcgPSBcIlNlbGVjdG9yXCI7XG5cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgc2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTZWxlY3Rpb25UeXBlPigpO1xuXG4gICAgQFZpZXdDaGlsZChcImNoZWNrYm94XCIpXG4gICAgcHVibGljIGNoZWNrYm94OiBDaGVja2JveENvbXBvbmVudDtcblxuICAgIEBWaWV3Q2hpbGQoXCJwb3B1cEFyZWFcIiwgeyBzdGF0aWM6IHRydWUgfSkgcG9wdXBBcmVhOiBFbGVtZW50UmVmO1xuXG4gICAgQFZpZXdDaGlsZChPdmVybGF5Q29tcG9uZW50KSBwdWJsaWMgb3ZlcmxheTogT3ZlcmxheUNvbXBvbmVudDtcblxuICAgIHB1YmxpYyBjdXN0b21Db250YWluZXI6IEVsZW1lbnRSZWYgfCB1bmRlZmluZWQ7XG4gICAgcHVibGljIGNoZWNrYm94Q2hlY2tlZCA9IGZhbHNlO1xuICAgIHB1YmxpYyBpbmRldGVybWluYXRlID0gZmFsc2U7XG4gICAgcHVibGljIG9uRGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgIHB1YmxpYyBvdmVybGF5Q29uZmlnOiBPdmVybGF5Q29uZmlnID0ge1xuICAgICAgICBwYW5lbENsYXNzOiBbT1ZFUkxBWV9XSVRIX1BPUFVQX1NUWUxFU19DTEFTU10sXG4gICAgfTtcblxuICAgIHByaXZhdGUgc3RhdHVzOiBTZWxlY3Rpb25UeXBlO1xuXG4gICAgcHJpdmF0ZSBzZWxlY3Rpb25IYXNDaGFuZ2VkID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICBpZiAoY2hhbmdlc1tcImNoZWNrYm94U3RhdHVzXCJdKSB7XG4gICAgICAgICAgICBjb25zdCBjaGVja2JveFN0YXR1cyA9IGNoYW5nZXNbXCJjaGVja2JveFN0YXR1c1wiXS5jdXJyZW50VmFsdWU7XG4gICAgICAgICAgICB0aGlzLmluZGV0ZXJtaW5hdGUgPVxuICAgICAgICAgICAgICAgIGNoZWNrYm94U3RhdHVzID09PSBDaGVja2JveFN0YXR1cy5JbmRldGVybWluYXRlO1xuICAgICAgICAgICAgdGhpcy5jaGVja2JveENoZWNrZWQgPSBjaGVja2JveFN0YXR1cyA9PT0gQ2hlY2tib3hTdGF0dXMuQ2hlY2tlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhbmdlcy5hcHBlbmRUb0JvZHkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tQ29udGFpbmVyID0gY2hhbmdlcy5hcHBlbmRUb0JvZHkuY3VycmVudFZhbHVlXG4gICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA6IHRoaXMucG9wdXBBcmVhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVib3VuY2VUaW1lVmFsdWUgPSAxMDtcblxuICAgICAgICB0aGlzLmNoZWNrYm94LnZhbHVlQ2hhbmdlXG4gICAgICAgICAgICAucGlwZShkZWJvdW5jZVRpbWUoZGVib3VuY2VUaW1lVmFsdWUpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh0aGlzLm9uQ2hlY2tib3hWYWx1ZUNoYW5nZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5vdmVybGF5LmNsaWNrT3V0c2lkZVxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChfKSA9PiB0aGlzLm92ZXJsYXkuaGlkZSgpKTtcbiAgICAgICAgLy8gVE9ETzogc2hvdWxkIGNoYW5nZSBwcm9ncmFtbWF0aWNhbGx5IGluIHNjb3BlIG9mIE5VSS01OTM3XG4gICAgICAgIHRoaXMuY2hlY2tib3guY2hlY2tib3hMYWJlbC5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShcbiAgICAgICAgICAgIFwidGFiaW5kZXhcIixcbiAgICAgICAgICAgIFwiLTFcIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGVja2JveC52YWx1ZUNoYW5nZS51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLm9uRGVzdHJveSQubmV4dCgpO1xuICAgICAgICB0aGlzLm9uRGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RmlsdGVycygpOiBJRmlsdGVyPElTZWxlY3RvckZpbHRlcj4ge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHtcbiAgICAgICAgICAgIHR5cGU6IFwic2VsZWN0b3JcIixcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgc2VsZWN0b3JTdGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBjaGVja2JveFN0YXR1czogdGhpcy5jaGVja2JveFN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JJdGVtczogdGhpcy5pdGVtcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN0YXR1czogdGhpcy5zdGF0dXMsXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uSGFzQ2hhbmdlZDogdGhpcy5zZWxlY3Rpb25IYXNDaGFuZ2VkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25IYXNDaGFuZ2VkID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVTZWxlY3RvckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudC5jdXJyZW50VGFyZ2V0ICE9PSBldmVudC50YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoZWNrYm94Q2hlY2tlZCA9ICF0aGlzLmNoZWNrYm94Q2hlY2tlZDtcblxuICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmNoZWNrYm94Q2hlY2tlZFxuICAgICAgICAgICAgPyBTZWxlY3Rpb25UeXBlLkFsbFxuICAgICAgICAgICAgOiBTZWxlY3Rpb25UeXBlLk5vbmU7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc2VsZWN0aW9uO1xuXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoc2VsZWN0aW9uKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uQ2hlY2tib3hWYWx1ZUNoYW5nZShldmVudDogQ2hlY2tib3hDaGFuZ2VFdmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluZGV0ZXJtaW5hdGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGVja2JveENoZWNrZWQgPSAhdGhpcy5jaGVja2JveENoZWNrZWQ7XG5cbiAgICAgICAgdGhpcy5zdGF0dXMgPSB0aGlzLmNoZWNrYm94Q2hlY2tlZFxuICAgICAgICAgICAgPyBTZWxlY3Rpb25UeXBlLkFsbFxuICAgICAgICAgICAgOiBTZWxlY3Rpb25UeXBlLk5vbmU7XG5cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25IYXNDaGFuZ2VkID0gdHJ1ZTtcblxuICAgICAgICBpZiAoZXZlbnQudGFyZ2V0LmNoZWNrZWQpIHtcbiAgICAgICAgICAgIC8vIGdpdmVzIGNvbnRyb2wgdG8gXCJzZWxlY3Rpb25DaGFuZ2VcIiBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoU2VsZWN0aW9uVHlwZS5BbGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZ2l2ZXMgY29udHJvbCB0byBcInNlbGVjdGlvbkNoYW5nZVwiIHN0cmVhbVxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdChTZWxlY3Rpb25UeXBlLlVuc2VsZWN0QWxsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVJdGVtQ2xpY2soaXRlbTogSU1lbnVJdGVtKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IGl0ZW0udmFsdWUgfHwgKGl0ZW0udGl0bGUgYXMgU2VsZWN0aW9uVHlwZSk7XG4gICAgICAgIHRoaXMuY2hlY2tib3hDaGVja2VkID1cbiAgICAgICAgICAgIHNlbGVjdGlvbiA9PT0gU2VsZWN0aW9uVHlwZS5BbGwgfHxcbiAgICAgICAgICAgIHNlbGVjdGlvbiA9PT0gU2VsZWN0aW9uVHlwZS5BbGxQYWdlcztcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBzZWxlY3Rpb247XG5cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25IYXNDaGFuZ2VkID0gdHJ1ZTtcblxuICAgICAgICAvLyBwcm9wYWdhdGUgc2VsZWN0aW9uXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoc2VsZWN0aW9uKTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwXCIgI3RvZ2dsZUJ1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG51aS1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIHJvbGU9XCJjaGVja2JveFwiXG4gICAgICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJjaGVja2JveENoZWNrZWRcIlxuICAgICAgICBjbGFzcz1cIm51aS1zZWxlY3Rvcl9fY2hlY2tib3gtYnV0dG9uXCJcbiAgICAgICAgW2Rpc3BsYXlTdHlsZV09XCInZGVmYXVsdCdcIlxuICAgICAgICAoY2xpY2spPVwiaGFuZGxlU2VsZWN0b3JDbGljaygkZXZlbnQpXCJcbiAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJudWktc2VsZWN0b3JfX2NoZWNrYm94LWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPG51aS1jaGVja2JveFxuICAgICAgICAgICAgICAgICNjaGVja2JveFxuICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImNoZWNrYm94Q2hlY2tlZFwiXG4gICAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwiaW5kZXRlcm1pbmF0ZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L251aS1jaGVja2JveD5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgICBudWktYnV0dG9uXG4gICAgICAgICpuZ0lmPVwiaXRlbXM/Lmxlbmd0aFwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cIm51aS1zZWxlY3Rvcl9fdG9nZ2xlXCJcbiAgICAgICAgYXJpYUxhYmVsPVwiT3BlbiBTZWxlY3RvciBNZW51XCJcbiAgICAgICAgW2Rpc3BsYXlTdHlsZV09XCInZGVmYXVsdCdcIlxuICAgICAgICBbaWNvbl09XCInY2FyZXQtZG93bidcIlxuICAgICAgICAoY2xpY2spPVwib3ZlcmxheS50b2dnbGUoKVwiXG4gICAgPjwvYnV0dG9uPlxuPC9kaXY+XG5cbjxkaXYgI3BvcHVwQXJlYT48L2Rpdj5cblxuPG51aS1vdmVybGF5XG4gICAgI292ZXJsYXlcbiAgICBbdG9nZ2xlUmVmZXJlbmNlXT1cInRvZ2dsZUJ1dHRvblwiXG4gICAgW292ZXJsYXlDb25maWddPVwib3ZlcmxheUNvbmZpZ1wiXG4gICAgW2N1c3RvbUNvbnRhaW5lcl09XCJjdXN0b21Db250YWluZXJcIlxuPlxuICAgIDxudWktbWVudS1wb3B1cFxuICAgICAgICBbaXRlbXNTb3VyY2VdPVwiaXRlbXNcIlxuICAgICAgICAobWVudUl0ZW1DbGlja2VkKT1cImhhbmRsZUl0ZW1DbGljaygkZXZlbnQpXCJcbiAgICA+PC9udWktbWVudS1wb3B1cD5cbjwvbnVpLW92ZXJsYXk+XG4iXX0=