@nova-ui/bits
Version:
SolarWinds Nova Framework
134 lines • 27.8 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 { Component, EventEmitter, Input, Output, ViewEncapsulation, } from "@angular/core";
import _isEmpty from "lodash/isEmpty";
import { Subject } from "rxjs";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../../common/directives/set-focus/set-focus.directive";
import * as i3 from "@angular/forms";
import * as i4 from "../button/button.component";
// <example-url>./../examples/index.html#/search</example-url>
/**
* Search component provides input box with 'search' and 'cancel' buttons on the right side of the box.
* Handles setting focus to its inner input fields on cancel.
* Fires 'search', 'cancel', 'inputChanged' and 'focusChange' events.
* Indicates spinner to the left of input text depending on 'busy' property.
*/
export class SearchComponent {
constructor() {
// mark this filter to be monitored by our datasource for any changes in order reset other filters(eg: pagination)
// before any new search is performed
this.detectFilterChanges = true;
/** @ignore */
this.onDestroy$ = new Subject();
/**
* Input to apply error state styles
*/
this.isInErrorState = false;
/**
* Event fired on each 'cancel' button click. Emits empty string.
*/
this.cancel = new EventEmitter();
/**
* Event fired on external focus changes (e.g. initiated by user via UI).
* Use it if you bind an external input to 'captureFocus' property for matching them both.
*/
this.focusChange = new EventEmitter();
/**
* Event fired when input field value is changed (via either keyboard or typeahead select item).
* Pay attention, that host property bound to 'value' is not being changed by component on this event,
* it is the responsibility of host component. The same with clearing of 'busy' status - if you want
* to clear it on inputChange - handle it in host component
*/
this.inputChange = new EventEmitter();
/**
* Event fired on 'search' button click or 'ENTER' key pressed
*/
this.search = new EventEmitter();
this.searchIconColor = "gray";
this.defaultPlaceholder = $localize `Search`;
}
getFilters() {
return {
type: "string",
value: this.value,
};
}
getPlaceholder() {
return this.placeholder || this.defaultPlaceholder + "...";
}
onCancel() {
this.value = "";
this.cancel.emit(this.value);
this.captureFocus = true;
this.focusChange.emit(true);
}
onFocusChange(event) {
this.captureFocus = event;
this.focusChange.emit(event);
}
onInputChange() {
this.inputChange.emit(this.value);
}
onKeyup(event) {
if (event.key === "Enter") {
this.onSearch();
}
}
isButtonDisabled() {
return _isEmpty(this.value);
}
onSearch() {
this.search.emit(this.value);
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SearchComponent, selector: "nui-search", inputs: { captureFocus: "captureFocus", name: "name", isInErrorState: "isInErrorState", placeholder: "placeholder", value: "value" }, outputs: { cancel: "cancel", focusChange: "focusChange", inputChange: "inputChange", search: "search" }, host: { attributes: { "role": "search" }, classAttribute: "nui-search" }, ngImport: i0, template: "<div class=\"nui-search__group input-group\" [class.has-error]=\"isInErrorState\">\n <div class=\"nui-search__input\">\n <div class=\"nui-search__button input-group-btn\">\n <button\n nui-button\n type=\"button\"\n *ngIf=\"!!value\"\n class=\"nui-search__button-cancel\"\n displayStyle=\"action\"\n icon=\"close\"\n (click)=\"onCancel()\"\n ></button>\n <button\n nui-button\n type=\"button\"\n class=\"nui-search__button-search\"\n displayStyle=\"action\"\n icon=\"search\"\n [disabled]=\"isButtonDisabled()\"\n (click)=\"onSearch()\"\n ></button>\n </div>\n <input\n class=\"nui-search__input-control form-control\"\n type=\"text\"\n [attr.name]=\"name\"\n [nuiSetFocus]=\"captureFocus\"\n (focusChange)=\"onFocusChange($event)\"\n autocomplete=\"off\"\n (input)=\"onInputChange()\"\n [(ngModel)]=\"value\"\n [placeholder]=\"getPlaceholder()\"\n (keyup)=\"onKeyup($event)\"\n [attr.aria-invalid]=\"isInErrorState\"\n />\n </div>\n</div>\n", styles: [".nui .nui-search__group{position:relative;max-width:400px;min-width:180px;width:100%}.nui .nui-search__group[class*=col-]{float:none;padding-left:0;padding-right:0}.nui .nui-search__group .form-control{position:relative;margin-bottom:0;width:100%;z-index:2}.nui .nui-search__input{display:flex;position:relative}.nui .nui-search__input:before,.nui .nui-search__input:after{content:\" \";display:table;width:0px}.nui .nui-search__input:after{clear:both}.nui .nui-search__input-spinner{left:6px;position:absolute;top:50%;transform:translateY(-50%);z-index:2}.nui .nui-search__input-control.form-control{border-radius:3px;font-weight:400;padding-right:60px;transition:padding-left .3s ease;z-index:0}.nui .nui-search__input-control.form-control::-moz-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));opacity:1;font-weight:400}.nui .nui-search__input-control.form-control:-ms-input-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));font-weight:400}.nui .nui-search__input-control.form-control::-webkit-input-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));font-weight:400}.nui .nui-search__input-control.form-control:hover,.nui .nui-search__input-control.form-control:active{z-index:1}.nui .nui-search__input-control.form-control:focus{z-index:1;outline:none;box-shadow:0 0 0 2px #00c4d280}.nui .nui-search__input .dropdown-menu{border-color:var(--nui-color-line-active,#0079aa);box-shadow:0 0 5px 0 var(--nui-shadow-color, rgba(17, 17, 17, .3));margin-top:-1px;max-height:300px;overflow-y:auto}.nui .nui-search__input .dropdown-menu>li.active>a{background-color:var(--nui-color-bg-light-hover,#f2f2f2);cursor:pointer}.nui .nui-search__input .dropdown-menu>li>a{padding:5px 10px}.nui .nui-search__button{align-items:center;display:flex;font-size:0;justify-content:flex-end;position:absolute;right:0;z-index:2}.nui .nui-search__button:hover~.nui-search__input-control{border-color:var(--nui-color-line-default-hover,#b3b3b3)}.nui .nui-search__button:hover~.nui-search__input-control:focus{border-color:var(--nui-color-line-active,#0079aa)}.nui .nui-search__button>.nui-button:focus,.nui .nui-search__button>.nui-button:focus:active{outline:none}.nui .nui-search__button>.btn{position:relative}.nui .nui-search__button .btn-action[disabled] .nui-icon path,.nui .nui-search__button .btn-action[disabled] .nui-icon polygon{fill:var(--nui-color-icon-default,rgba(17, 17, 17, .5))}.nui .nui-search__button-cancel{border:none;border-bottom-right-radius:0;border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);border-top-right-radius:0;position:absolute;z-index:1}.nui .nui-search__button-cancel.nui-button.btn-action{min-height:28px;padding:5px}.nui .nui-search__button-search{border:none;border-top-left-radius:0;border-bottom-left-radius:0;z-index:2}.nui .nui-search.unlimited-width .nui-search__group{max-width:unset}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.SetFocusDirective, selector: "[nuiSetFocus]", inputs: ["nuiSetFocus", "preventScroll"], outputs: ["focusChange"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.ButtonComponent, selector: "[nui-button]", inputs: ["displayStyle", "icon", "iconColor", "iconRight", "isBusy", "isEmpty", "ariaLabel", "isRepeat", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SearchComponent, decorators: [{
type: Component,
args: [{ selector: "nui-search", host: {
class: "nui-search",
role: "search",
}, encapsulation: ViewEncapsulation.None, template: "<div class=\"nui-search__group input-group\" [class.has-error]=\"isInErrorState\">\n <div class=\"nui-search__input\">\n <div class=\"nui-search__button input-group-btn\">\n <button\n nui-button\n type=\"button\"\n *ngIf=\"!!value\"\n class=\"nui-search__button-cancel\"\n displayStyle=\"action\"\n icon=\"close\"\n (click)=\"onCancel()\"\n ></button>\n <button\n nui-button\n type=\"button\"\n class=\"nui-search__button-search\"\n displayStyle=\"action\"\n icon=\"search\"\n [disabled]=\"isButtonDisabled()\"\n (click)=\"onSearch()\"\n ></button>\n </div>\n <input\n class=\"nui-search__input-control form-control\"\n type=\"text\"\n [attr.name]=\"name\"\n [nuiSetFocus]=\"captureFocus\"\n (focusChange)=\"onFocusChange($event)\"\n autocomplete=\"off\"\n (input)=\"onInputChange()\"\n [(ngModel)]=\"value\"\n [placeholder]=\"getPlaceholder()\"\n (keyup)=\"onKeyup($event)\"\n [attr.aria-invalid]=\"isInErrorState\"\n />\n </div>\n</div>\n", styles: [".nui .nui-search__group{position:relative;max-width:400px;min-width:180px;width:100%}.nui .nui-search__group[class*=col-]{float:none;padding-left:0;padding-right:0}.nui .nui-search__group .form-control{position:relative;margin-bottom:0;width:100%;z-index:2}.nui .nui-search__input{display:flex;position:relative}.nui .nui-search__input:before,.nui .nui-search__input:after{content:\" \";display:table;width:0px}.nui .nui-search__input:after{clear:both}.nui .nui-search__input-spinner{left:6px;position:absolute;top:50%;transform:translateY(-50%);z-index:2}.nui .nui-search__input-control.form-control{border-radius:3px;font-weight:400;padding-right:60px;transition:padding-left .3s ease;z-index:0}.nui .nui-search__input-control.form-control::-moz-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));opacity:1;font-weight:400}.nui .nui-search__input-control.form-control:-ms-input-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));font-weight:400}.nui .nui-search__input-control.form-control::-webkit-input-placeholder{color:var(--input-color-placeholder,rgba(17, 17, 17, .6));font-weight:400}.nui .nui-search__input-control.form-control:hover,.nui .nui-search__input-control.form-control:active{z-index:1}.nui .nui-search__input-control.form-control:focus{z-index:1;outline:none;box-shadow:0 0 0 2px #00c4d280}.nui .nui-search__input .dropdown-menu{border-color:var(--nui-color-line-active,#0079aa);box-shadow:0 0 5px 0 var(--nui-shadow-color, rgba(17, 17, 17, .3));margin-top:-1px;max-height:300px;overflow-y:auto}.nui .nui-search__input .dropdown-menu>li.active>a{background-color:var(--nui-color-bg-light-hover,#f2f2f2);cursor:pointer}.nui .nui-search__input .dropdown-menu>li>a{padding:5px 10px}.nui .nui-search__button{align-items:center;display:flex;font-size:0;justify-content:flex-end;position:absolute;right:0;z-index:2}.nui .nui-search__button:hover~.nui-search__input-control{border-color:var(--nui-color-line-default-hover,#b3b3b3)}.nui .nui-search__button:hover~.nui-search__input-control:focus{border-color:var(--nui-color-line-active,#0079aa)}.nui .nui-search__button>.nui-button:focus,.nui .nui-search__button>.nui-button:focus:active{outline:none}.nui .nui-search__button>.btn{position:relative}.nui .nui-search__button .btn-action[disabled] .nui-icon path,.nui .nui-search__button .btn-action[disabled] .nui-icon polygon{fill:var(--nui-color-icon-default,rgba(17, 17, 17, .5))}.nui .nui-search__button-cancel{border:none;border-bottom-right-radius:0;border-right:1px solid;border-right-color:var(--nui-color-line-default,#d9d9d9);border-top-right-radius:0;position:absolute;z-index:1}.nui .nui-search__button-cancel.nui-button.btn-action{min-height:28px;padding:5px}.nui .nui-search__button-search{border:none;border-top-left-radius:0;border-bottom-left-radius:0;z-index:2}.nui .nui-search.unlimited-width .nui-search__group{max-width:unset}\n"] }]
}], ctorParameters: () => [], propDecorators: { captureFocus: [{
type: Input
}], name: [{
type: Input
}], isInErrorState: [{
type: Input
}], placeholder: [{
type: Input
}], value: [{
type: Input
}], cancel: [{
type: Output
}], focusChange: [{
type: Output
}], inputChange: [{
type: Output
}], search: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc2VhcmNoL3NlYXJjaC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NlYXJjaC9zZWFyY2guY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFDSCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04saUJBQWlCLEdBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7OztBQWUvQiw4REFBOEQ7QUFFOUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQXdEeEI7UUF2REEsa0hBQWtIO1FBQ2xILHFDQUFxQztRQUM5Qix3QkFBbUIsR0FBRyxJQUFJLENBQUM7UUFPbEMsY0FBYztRQUNQLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBVXhDOztXQUVHO1FBQ2EsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFTaEQ7O1dBRUc7UUFDYyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUNyRDs7O1dBR0c7UUFDYyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFDM0Q7Ozs7O1dBS0c7UUFDYyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUQ7O1dBRUc7UUFDYyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUU5QyxvQkFBZSxHQUFXLE1BQU0sQ0FBQztRQUdwQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFBLFFBQVEsQ0FBQztJQUNoRCxDQUFDO0lBRU0sVUFBVTtRQUNiLE9BQU87WUFDSCxJQUFJLEVBQUUsUUFBUTtZQUNkLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNwQixDQUFDO0lBQ04sQ0FBQztJQUVNLGNBQWM7UUFDakIsT0FBTyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7SUFDL0QsQ0FBQztJQUVNLFFBQVE7UUFDWCxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVNLGFBQWEsQ0FBQyxLQUFjO1FBQy9CLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFTSxhQUFhO1FBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRU0sT0FBTyxDQUFDLEtBQW9CO1FBQy9CLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxPQUFPLEVBQUU7WUFDdkIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ25CO0lBQ0wsQ0FBQztJQUVNLGdCQUFnQjtRQUNuQixPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVNLFFBQVE7UUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVNLFdBQVc7UUFDZCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDL0IsQ0FBQzsrR0F4R1EsZUFBZTttR0FBZixlQUFlLDJXQ3BENUIsdTBDQXFDQTs7NEZEZWEsZUFBZTtrQkFuQjNCLFNBQVM7K0JBQ0ksWUFBWSxRQUNoQjt3QkFDRixLQUFLLEVBQUUsWUFBWTt3QkFDbkIsSUFBSSxFQUFFLFFBQVE7cUJBQ2pCLGlCQUdjLGlCQUFpQixDQUFDLElBQUk7d0RBMkI1QixZQUFZO3NCQUFwQixLQUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFJVSxjQUFjO3NCQUE3QixLQUFLO2dCQUlHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBSUcsS0FBSztzQkFBYixLQUFLO2dCQUlXLE1BQU07c0JBQXRCLE1BQU07Z0JBS1UsV0FBVztzQkFBM0IsTUFBTTtnQkFPVSxXQUFXO3NCQUEzQixNQUFNO2dCQUlVLE1BQU07c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPdXRwdXQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgX2lzRW1wdHkgZnJvbSBcImxvZGFzaC9pc0VtcHR5XCI7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcblxuaW1wb3J0IHsgSUZpbHRlciwgSUZpbHRlclB1YiB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9kYXRhLXNvdXJjZS9wdWJsaWMtYXBpXCI7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm51aS1zZWFyY2hcIixcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiBcIm51aS1zZWFyY2hcIixcbiAgICAgICAgcm9sZTogXCJzZWFyY2hcIixcbiAgICB9LFxuICAgIHRlbXBsYXRlVXJsOiBcIi4vc2VhcmNoLmNvbXBvbmVudC5odG1sXCIsXG4gICAgc3R5bGVVcmxzOiBbXCIuL3NlYXJjaC5jb21wb25lbnQubGVzc1wiXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcblxuLy8gPGV4YW1wbGUtdXJsPi4vLi4vZXhhbXBsZXMvaW5kZXguaHRtbCMvc2VhcmNoPC9leGFtcGxlLXVybD5cblxuLyoqXG4gKiBTZWFyY2ggY29tcG9uZW50IHByb3ZpZGVzIGlucHV0IGJveCB3aXRoICdzZWFyY2gnIGFuZCAnY2FuY2VsJyBidXR0b25zIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBib3guXG4gKiBIYW5kbGVzIHNldHRpbmcgZm9jdXMgdG8gaXRzIGlubmVyIGlucHV0IGZpZWxkcyBvbiBjYW5jZWwuXG4gKiBGaXJlcyAnc2VhcmNoJywgJ2NhbmNlbCcsICdpbnB1dENoYW5nZWQnIGFuZCAnZm9jdXNDaGFuZ2UnIGV2ZW50cy5cbiAqIEluZGljYXRlcyBzcGlubmVyIHRvIHRoZSBsZWZ0IG9mIGlucHV0IHRleHQgZGVwZW5kaW5nIG9uICdidXN5JyBwcm9wZXJ0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlYXJjaENvbXBvbmVudCBpbXBsZW1lbnRzIElGaWx0ZXJQdWIsIE9uRGVzdHJveSB7XG4gICAgLy8gbWFyayB0aGlzIGZpbHRlciB0byBiZSBtb25pdG9yZWQgYnkgb3VyIGRhdGFzb3VyY2UgZm9yIGFueSBjaGFuZ2VzIGluIG9yZGVyIHJlc2V0IG90aGVyIGZpbHRlcnMoZWc6IHBhZ2luYXRpb24pXG4gICAgLy8gYmVmb3JlIGFueSBuZXcgc2VhcmNoIGlzIHBlcmZvcm1lZFxuICAgIHB1YmxpYyBkZXRlY3RGaWx0ZXJDaGFuZ2VzID0gdHJ1ZTtcblxuICAgIC8qKlxuICAgICAqIGRlZmF1bHQgdGV4dCBvZiBwbGFjZWhvbGRlciBpZiBubyBjdXN0b20gb25lcyBpcyBwcm92aWRlZFxuICAgICAqL1xuICAgIHB1YmxpYyBkZWZhdWx0UGxhY2Vob2xkZXI6IHN0cmluZztcblxuICAgIC8qKiBAaWdub3JlICovXG4gICAgcHVibGljIG9uRGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgLyoqXG4gICAgICogQ29udHJvbHMgZm9jdXMgb2YgaW5wdXQgZmllbGQgKHRydWUgbWVhbnMgZm9jdXNlZCkuXG4gICAgICovXG4gICAgQElucHV0KCkgY2FwdHVyZUZvY3VzOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgaW5wdXQgdGhlIGVsZW1lbnQuXG4gICAgICovXG4gICAgQElucHV0KCkgbmFtZTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIElucHV0IHRvIGFwcGx5IGVycm9yIHN0YXRlIHN0eWxlc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBpc0luRXJyb3JTdGF0ZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIHRoYXQgd2lsbCBiZSBwbGFjZWQgYXMgYSB3YXRlcm1hcmsgaW5zaWRlIG9mIHRoZSBzZWFyY2ggd2hlbiBpdCdzIGVtcHR5LlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbCB2YWx1ZSBvZiBpbnB1dCBmaWVsZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSB2YWx1ZTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEV2ZW50IGZpcmVkIG9uIGVhY2ggJ2NhbmNlbCcgYnV0dG9uIGNsaWNrLiBFbWl0cyBlbXB0eSBzdHJpbmcuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBjYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBmaXJlZCBvbiBleHRlcm5hbCBmb2N1cyBjaGFuZ2VzIChlLmcuIGluaXRpYXRlZCBieSB1c2VyIHZpYSBVSSkuXG4gICAgICogVXNlIGl0IGlmIHlvdSBiaW5kIGFuIGV4dGVybmFsIGlucHV0IHRvICdjYXB0dXJlRm9jdXMnIHByb3BlcnR5IGZvciBtYXRjaGluZyB0aGVtIGJvdGguXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBmb2N1c0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBmaXJlZCB3aGVuIGlucHV0IGZpZWxkIHZhbHVlIGlzIGNoYW5nZWQgKHZpYSBlaXRoZXIga2V5Ym9hcmQgb3IgdHlwZWFoZWFkIHNlbGVjdCBpdGVtKS5cbiAgICAgKiBQYXkgYXR0ZW50aW9uLCB0aGF0IGhvc3QgcHJvcGVydHkgYm91bmQgdG8gJ3ZhbHVlJyBpcyBub3QgYmVpbmcgY2hhbmdlZCBieSBjb21wb25lbnQgb24gdGhpcyBldmVudCxcbiAgICAgKiBpdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgaG9zdCBjb21wb25lbnQuIFRoZSBzYW1lIHdpdGggY2xlYXJpbmcgb2YgJ2J1c3knIHN0YXR1cyAtIGlmIHlvdSB3YW50XG4gICAgICogdG8gY2xlYXIgaXQgb24gaW5wdXRDaGFuZ2UgLSBoYW5kbGUgaXQgaW4gaG9zdCBjb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIGlucHV0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZmlyZWQgb24gJ3NlYXJjaCcgYnV0dG9uIGNsaWNrIG9yICdFTlRFUicga2V5IHByZXNzZWRcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIHNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgcHVibGljIHNlYXJjaEljb25Db2xvcjogc3RyaW5nID0gXCJncmF5XCI7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0UGxhY2Vob2xkZXIgPSAkbG9jYWxpemVgU2VhcmNoYDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RmlsdGVycygpOiBJRmlsdGVyPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRQbGFjZWhvbGRlcigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5wbGFjZWhvbGRlciB8fCB0aGlzLmRlZmF1bHRQbGFjZWhvbGRlciArIFwiLi4uXCI7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ2FuY2VsKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnZhbHVlID0gXCJcIjtcbiAgICAgICAgdGhpcy5jYW5jZWwuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICAgdGhpcy5jYXB0dXJlRm9jdXMgPSB0cnVlO1xuICAgICAgICB0aGlzLmZvY3VzQ2hhbmdlLmVtaXQodHJ1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uRm9jdXNDaGFuZ2UoZXZlbnQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jYXB0dXJlRm9jdXMgPSBldmVudDtcbiAgICAgICAgdGhpcy5mb2N1c0NoYW5nZS5lbWl0KGV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25JbnB1dENoYW5nZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbnB1dENoYW5nZS5lbWl0KHRoaXMudmFsdWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbktleXVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IFwiRW50ZXJcIikge1xuICAgICAgICAgICAgdGhpcy5vblNlYXJjaCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGlzQnV0dG9uRGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBfaXNFbXB0eSh0aGlzLnZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWFyY2goKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VhcmNoLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uRGVzdHJveSQubmV4dCgpO1xuICAgICAgICB0aGlzLm9uRGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibnVpLXNlYXJjaF9fZ3JvdXAgaW5wdXQtZ3JvdXBcIiBbY2xhc3MuaGFzLWVycm9yXT1cImlzSW5FcnJvclN0YXRlXCI+XG4gICAgPGRpdiBjbGFzcz1cIm51aS1zZWFyY2hfX2lucHV0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJudWktc2VhcmNoX19idXR0b24gaW5wdXQtZ3JvdXAtYnRuXCI+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgbnVpLWJ1dHRvblxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiISF2YWx1ZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJudWktc2VhcmNoX19idXR0b24tY2FuY2VsXCJcbiAgICAgICAgICAgICAgICBkaXNwbGF5U3R5bGU9XCJhY3Rpb25cIlxuICAgICAgICAgICAgICAgIGljb249XCJjbG9zZVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIlxuICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIG51aS1idXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm51aS1zZWFyY2hfX2J1dHRvbi1zZWFyY2hcIlxuICAgICAgICAgICAgICAgIGRpc3BsYXlTdHlsZT1cImFjdGlvblwiXG4gICAgICAgICAgICAgICAgaWNvbj1cInNlYXJjaFwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzQnV0dG9uRGlzYWJsZWQoKVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uU2VhcmNoKClcIlxuICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBjbGFzcz1cIm51aS1zZWFyY2hfX2lucHV0LWNvbnRyb2wgZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgIFthdHRyLm5hbWVdPVwibmFtZVwiXG4gICAgICAgICAgICBbbnVpU2V0Rm9jdXNdPVwiY2FwdHVyZUZvY3VzXCJcbiAgICAgICAgICAgIChmb2N1c0NoYW5nZSk9XCJvbkZvY3VzQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJvbklucHV0Q2hhbmdlKClcIlxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2YWx1ZVwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZ2V0UGxhY2Vob2xkZXIoKVwiXG4gICAgICAgICAgICAoa2V5dXApPVwib25LZXl1cCgkZXZlbnQpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaW52YWxpZF09XCJpc0luRXJyb3JTdGF0ZVwiXG4gICAgICAgIC8+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==