ngx-mat-dropdown
Version:
Angular Dropdown with search/filter option
581 lines • 56.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/mat-select-search/mat-select-search.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Inject, Input, ViewChild, HostBinding, Optional } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { delay, take, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { MatOption } from '@angular/material/core';
export class MatSelectSearchComponent {
/**
* @param {?} matSelect
* @param {?} changeDetectorRef
* @param {?=} matOption
*/
constructor(matSelect, changeDetectorRef, matOption = null) {
this.matSelect = matSelect;
this.changeDetectorRef = changeDetectorRef;
this.matOption = matOption;
/**
* Label of the search placeholder
*/
this.placeholderLabel = 'Search';
this.multiple = false;
this.showSearch = true;
/**
* Label to be shown when no entries are found. Set to null if no message should be shown.
*/
this.noEntriesFoundLabel = 'No Data';
this.onChange = (/**
* @param {?} _
* @return {?}
*/
(_) => { });
this.onTouched = (/**
* @param {?} _
* @return {?}
*/
(_) => { });
/**
* Whether the backdrop class has been set
*/
this.overlayClassSet = false;
/**
* Event that emits when the current value changes
*/
this.change = new EventEmitter();
this.AllClicked = new EventEmitter();
/**
* Subject that emits when the component has been destroyed.
*/
this._onDestroy = new Subject();
}
//@ViewChild('innerSelectall', { read: ElementRef }) innerSelectall: ElementRef;
/**
* @return {?}
*/
get isInsideMatOption() {
return !!this.matOption;
}
/**
* Current search value
* @return {?}
*/
get value() {
return this._value;
}
/**
* @return {?}
*/
ngOnInit() {
// set custom panel class
/** @type {?} */
const panelClass = 'mat-select-search-panel';
if (this.matSelect.panelClass) {
if (Array.isArray(this.matSelect.panelClass)) {
this.matSelect.panelClass.push(panelClass);
}
else if (typeof this.matSelect.panelClass === 'string') {
this.matSelect.panelClass = [this.matSelect.panelClass, panelClass];
}
else if (typeof this.matSelect.panelClass === 'object') {
this.matSelect.panelClass[panelClass] = true;
}
}
else {
this.matSelect.panelClass = panelClass;
}
// set custom mat-option class if the component was placed inside a mat-option
if (this.matOption) {
this.matOption.disabled = true;
this.matOption._getHostElement().classList.add('contains-mat-select-search');
}
// when the select dropdown panel is opened or closed
this.matSelect.openedChange
// .pipe(takeUntil(this._onDestroy))
.pipe(delay(1), takeUntil(this._onDestroy))
.subscribe((/**
* @param {?} opened
* @return {?}
*/
(opened) => {
if (opened) {
// focus the search field when opening
this.getWidth();
this._focus();
}
else {
// clear it when closing
this._reset();
}
}));
// set the first item active after the options changed
this.matSelect.openedChange
.pipe(take(1))
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
() => {
this._options = this.matSelect.options;
this._options.changes
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
() => {
/** @type {?} */
const keyManager = this.matSelect._keyManager;
if (keyManager && this.matSelect.panelOpen) {
// avoid "expression has been changed" error
setTimeout((/**
* @return {?}
*/
() => {
keyManager.setFirstItemActive();
this.getWidth();
// set no entries found class on mat option
if (this.matOption) {
if (this._noEntriesFound()) {
this.matOption._getHostElement().classList.add('mat-select-search-no-entries-found');
}
else {
this.matOption._getHostElement().classList.remove('mat-select-search-no-entries-found');
}
}
}), 1);
}
}));
}));
// detect changes when the input changes
this.change
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
() => {
this.changeDetectorRef.detectChanges();
}));
this.initMultipleHandling();
}
/**
* @return {?}
*/
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
/**
* @return {?}
*/
ngAfterViewInit() {
setTimeout((/**
* @return {?}
*/
() => {
this.setOverlayClass();
}));
this.matSelect.openedChange
.pipe(take(1), takeUntil(this._onDestroy)).subscribe((/**
* @return {?}
*/
() => {
this.matSelect.options.changes
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
() => {
this.changeDetectorRef.markForCheck();
}));
}));
}
/**
* @param {?} event
* @return {?}
*/
_handleKeydown(event) {
if (event.keyCode === 32) {
// do not propagate spaces to MatSelect, as this would select the currently active option
event.stopPropagation();
}
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
/** @type {?} */
const valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.change.emit({ type: 'Text', val: value });
}
}
/**
* @param {?} value
* @return {?}
*/
onInputChange(value) {
/** @type {?} */
const valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.onChange({ type: 'Text', val: value });
this.change.emit({ type: 'Text', val: value });
}
}
/**
* @param {?} value
* @return {?}
*/
onBlur(value) {
this.writeValue(value);
this.onTouched();
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @return {?}
*/
_focus() {
if (!this.searchSelectInput || !this.matSelect.panel) {
return;
}
// save and restore scrollTop of panel, since it will be reset by focus()
// note: this is hacky
/** @type {?} */
const panel = this.matSelect.panel.nativeElement;
/** @type {?} */
const scrollTop = panel.scrollTop;
// focus
this.searchSelectInput.nativeElement.focus();
panel.scrollTop = scrollTop;
}
/**
* Resets the current search value
* {boolean} focus whether to focus after resetting
*
* @param {?=} focus
* @return {?}
*/
_reset(focus) {
if (!this.searchSelectInput) {
return;
}
this.searchSelectInput.nativeElement.value = '';
this.onInputChange('');
if (focus) {
this._focus();
}
}
/**
* Sets the overlay class to correct offsetY
* so that the selected option is at the position of the select box when opening
* @private
* @return {?}
*/
setOverlayClass() {
if (this.overlayClassSet) {
return;
}
/** @type {?} */
const overlayClasses = ['cdk-overlay-pane-select-search'];
if (!this.matOption) {
// add offset to panel if component is not placed inside mat-option
overlayClasses.push('cdk-overlay-pane-select-search-with-offset');
}
this.matSelect.overlayDir.attach
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
() => {
// note: this is hacky, but currently there is no better way to do this
// note: this is hacky, but currently there is no better way to do this
/** @type {?} */
let element;
/** @type {?} */
let overlayElement;
if (this.searchSelectInput) {
element = this.searchSelectInput.nativeElement;
while (element = element.parentElement) {
if (element.classList.contains('cdk-overlay-pane')) {
overlayElement = element;
break;
}
}
}
if (overlayElement) {
overlayClasses.forEach((/**
* @param {?} overlayClass
* @return {?}
*/
overlayClass => {
overlayElement.classList.add(overlayClass);
}));
}
}));
this.overlayClassSet = true;
}
/**
* Initializes handling <mat-select [multiple]="true">
* Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
* @private
* @return {?}
*/
initMultipleHandling() {
// if <mat-select [multiple]="true">
// store previously selected values and restore them when they are deselected
// because the option is not available while we are currently filtering
this.matSelect.valueChange
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @param {?} values
* @return {?}
*/
(values) => {
if (this.matSelect.multiple) {
/** @type {?} */
let restoreSelectedValues = false;
if (this._value && this._value.length
&& this.previousSelectedValues && Array.isArray(this.previousSelectedValues)) {
if (!values || !Array.isArray(values)) {
values = [];
}
/** @type {?} */
const optionValues = this.matSelect.options.map((/**
* @param {?} option
* @return {?}
*/
option => option.value));
this.previousSelectedValues.forEach((/**
* @param {?} previousValue
* @return {?}
*/
previousValue => {
if (values.indexOf(previousValue) === -1 && optionValues.indexOf(previousValue) === -1) {
// if a value that was selected before is deselected and not found in the options, it was deselected
// due to the filtering, so we restore it.
values.push(previousValue);
restoreSelectedValues = true;
}
}));
}
if (restoreSelectedValues) {
this.matSelect._onChange(values);
}
this.previousSelectedValues = values;
}
}));
}
/**
* @private
* @return {?}
*/
getWidth() {
if (!this.innerSelectSearch || !this.innerSelectSearch.nativeElement) {
return;
}
/** @type {?} */
let element = this.innerSelectSearch.nativeElement;
/** @type {?} */
let panelElement;
while (element = element.parentElement) {
if (element.classList.contains('mat-select-panel')) {
panelElement = element;
break;
}
}
if (panelElement) {
this.innerSelectSearch.nativeElement.style.width = panelElement.clientWidth + 'px';
}
////innerSelectall
//if (!this.innerSelectall || !this.innerSelectall.nativeElement) {
// return;
//}
//let Selectallelement: HTMLElement = this.innerSelectall.nativeElement;
//let SelectallpanelElement: HTMLElement;
//while (Selectallelement = Selectallelement.parentElement) {
// if (Selectallelement.classList.contains('mat-select-panel')) {
// SelectallpanelElement = Selectallelement;
// break;
// }
//}
//if (SelectallpanelElement) {
// this.innerSelectall.nativeElement.style.width = SelectallpanelElement.clientWidth + 'px';
//}
}
/**
* @return {?}
*/
_noEntriesFound() {
if (!this._options) {
return;
}
if (this.matOption) {
return this.noEntriesFoundLabel && this.value && this._options.length === 1;
}
else {
return this.noEntriesFoundLabel && this.value && this._options.length === 0;
}
}
/**
* @param {?} change
* @param {?} check
* @return {?}
*/
toggleSelection(change, check) {
if (change.checked) {
//this.model.update.emit(this.values);
this.onChange({ type: 'Check', val: change.checked });
this.change.emit({ type: 'Check', val: change.checked });
}
else {
this.onChange({ type: 'Check', val: change.checked });
this.change.emit({ type: 'Check', val: change.checked });
}
}
/**
* @param {?} check
* @return {?}
*/
ischecked(check) {
console.log(this.matSelect.options, this.matSelect.value);
/** @type {?} */
let selected = this.matSelect.selected;
return this.matSelect.options && selected && selected.length > 0 && this.matSelect.options.length == selected.length;
}
/**
* @return {?}
*/
isIndeterminate() {
/** @type {?} */
let selected = this.matSelect.selected;
return this.matSelect.options && selected.length > 0 && selected.length < this.matSelect.options.length;
}
}
MatSelectSearchComponent.decorators = [
{ type: Component, args: [{
selector: 'mat-select-search',
template: "\r\n<input *ngIf=\"showSearch\" matInput class=\"mat-select-search-input mat-select-search-hidden\" />\r\n<input matInput class=\"mat-select-checkbox mat-select-search-hidden\"*ngIf=\"multiple\" />\r\n\r\n<div #innerSelectSearch class=\"mat-select-search-inner\" *ngIf=\"showSearch\"\r\n [ngClass]=\"{'mat-select-search-inner-multiple': matSelect.multiple}\">\r\n <input matInput autocomplete=\"off\"\r\n class=\"mat-select-search-input\"\r\n #searchSelectInput\r\n (keydown)=\"_handleKeydown($event)\"\r\n (input)=\"onInputChange($event.target.value)\"\r\n (blur)=\"onBlur($event.target.value)\"\r\n placeholder=\"Search\" />\r\n <button mat-button *ngIf=\"value\"\r\n mat-icon-button\r\n aria-label=\"Clear\"\r\n (click)=\"_reset(true)\"\r\n class=\"mat-select-search-clear\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n</div>\r\n\r\n<div *ngIf=\"noEntriesFoundLabel && value && _options?.length === 0\"\r\n class=\"mat-select-search-no-entries-found\">\r\n {{noEntriesFoundLabel}}\r\n</div>\r\n",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => MatSelectSearchComponent)),
multi: true
}
],
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;width:calc(100% + 3px);border-bottom:1px solid #ccc;background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}.mat-select-search-inner.mat-select-search-inner-multiple{width:100%}::ng-deep .mat-select-search-panel{transform:none!important;overflow-x:hidden}.mat-select-search-input{padding:10px 30px 10px 10px;box-sizing:border-box}.mat-select-checkbox{padding:10px;box-sizing:border-box}.mat-select-search-no-entries-found{padding:10px}.mat-select-search-clear{position:absolute;right:4px;top:5px}:host.mat-select-search-inside-mat-option .mat-select-search-input{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-checkbox{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-search-clear{top:3px}::ng-deep .cdk-overlay-pane-select-search.cdk-overlay-pane-select-search-with-offset{margin-top:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search{position:static;padding:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-option-pseudo-checkbox{display:none}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search.mat-select-search-no-entries-found{height:6em}.mat-select-all-inner{position:absolute;top:52px;width:calc(100% + 3px);background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}"]
}] }
];
/** @nocollapse */
MatSelectSearchComponent.ctorParameters = () => [
{ type: MatSelect, decorators: [{ type: Inject, args: [MatSelect,] }] },
{ type: ChangeDetectorRef },
{ type: MatOption, decorators: [{ type: Optional }, { type: Inject, args: [MatOption,] }] }
];
MatSelectSearchComponent.propDecorators = {
placeholderLabel: [{ type: Input }],
multiple: [{ type: Input, args: ['multiple',] }],
showSearch: [{ type: Input, args: ['showSearch',] }],
noEntriesFoundLabel: [{ type: Input }],
searchSelectInput: [{ type: ViewChild, args: ['searchSelectInput', { read: ElementRef },] }],
innerSelectSearch: [{ type: ViewChild, args: ['innerSelectSearch', { read: ElementRef },] }],
isInsideMatOption: [{ type: HostBinding, args: ['class.mat-select-search-inside-mat-option',] }]
};
if (false) {
/**
* Label of the search placeholder
* @type {?}
*/
MatSelectSearchComponent.prototype.placeholderLabel;
/** @type {?} */
MatSelectSearchComponent.prototype.multiple;
/** @type {?} */
MatSelectSearchComponent.prototype.showSearch;
/**
* Label to be shown when no entries are found. Set to null if no message should be shown.
* @type {?}
*/
MatSelectSearchComponent.prototype.noEntriesFoundLabel;
/**
* Reference to the search input field
* @type {?}
*/
MatSelectSearchComponent.prototype.searchSelectInput;
/** @type {?} */
MatSelectSearchComponent.prototype.innerSelectSearch;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype._value;
/** @type {?} */
MatSelectSearchComponent.prototype.onChange;
/** @type {?} */
MatSelectSearchComponent.prototype.onTouched;
/**
* Reference to the MatSelect options
* @type {?}
*/
MatSelectSearchComponent.prototype._options;
/**
* Previously selected values when using <mat-select [multiple]="true">
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.previousSelectedValues;
/**
* Whether the backdrop class has been set
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.overlayClassSet;
/**
* Event that emits when the current value changes
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.change;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.AllClicked;
/**
* Subject that emits when the component has been destroyed.
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype._onDestroy;
/** @type {?} */
MatSelectSearchComponent.prototype.matSelect;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.changeDetectorRef;
/** @type {?} */
MatSelectSearchComponent.prototype.matOption;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW1hdC1kcm9wZG93bi8iLCJzb3VyY2VzIjpbImxpYi9tYXQtc2VsZWN0LXNlYXJjaC9tYXQtc2VsZWN0LXNlYXJjaC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUgsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQzFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUM5RCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFFBQVEsRUFDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFHLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3RELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBZW5ELE1BQU0sT0FBTyx3QkFBd0I7Ozs7OztJQTJDakMsWUFBc0MsU0FBb0IsRUFDOUMsaUJBQW9DLEVBQXdDLFlBQXVCLElBQUk7UUFEN0UsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUM5QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQXdDLGNBQVMsR0FBVCxTQUFTLENBQWtCOzs7O1FBekMxRyxxQkFBZ0IsR0FBRyxRQUFRLENBQUM7UUFDbEIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUN4QixlQUFVLEdBQVksSUFBSSxDQUFDOzs7O1FBRXZDLHdCQUFtQixHQUFHLFNBQVMsQ0FBQztRQWdCekMsYUFBUTs7OztRQUFhLENBQUMsQ0FBTSxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUM7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Qzs7Ozs7SUFFekMsOENBQWlEOzs7Ozs7SUFFakQsOENBQXlDOztJQUc3Qiw2Q0FBOEM7Ozs7O0lBQ3RELHFEQUE0Qzs7SUFBRSw2Q0FBaUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgUXVlcnlMaXN0LFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBPcHRpb25hbFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7ICBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyAgIE1hdENoZWNrYm94Q2hhbmdlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xyXG5cclxuaW1wb3J0IHsgZGVsYXksIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBNYXRPcHRpb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdtYXQtc2VsZWN0LXNlYXJjaCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LnNjc3MnXSxcclxuICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdFNlbGVjdFNlYXJjaENvbXBvbmVudCksXHJcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgXSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRTZWxlY3RTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG5cclxuICAgIC8qKiBMYWJlbCBvZiB0aGUgc2VhcmNoIHBsYWNlaG9sZGVyICovXHJcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlckxhYmVsID0gJ1NlYXJjaCc7XHJcbiAgICBASW5wdXQoJ211bHRpcGxlJykgbXVsdGlwbGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgnc2hvd1NlYXJjaCcpIHNob3dTZWFyY2g6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLyoqIExhYmVsIHRvIGJlIHNob3duIHdoZW4gbm8gZW50cmllcyBhcmUgZm91bmQuIFNldCB0byBudWxsIGlmIG5vIG1lc3NhZ2Ugc2hvdWxkIGJlIHNob3duLiAqL1xyXG4gICAgQElucHV0KCkgbm9FbnRyaWVzRm91bmRMYWJlbCA9ICdObyBEYXRhJztcclxuXHJcbiAgICAvKiogUmVmZXJlbmNlIHRvIHRoZSBzZWFyY2ggaW5wdXQgZmllbGQgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ3NlYXJjaFNlbGVjdElucHV0JywgeyByZWFkOiBFbGVtZW50UmVmIH0pIHNlYXJjaFNlbGVjdElucHV0OiBFbGVtZW50UmVmO1xyXG4gICAgQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RTZWFyY2gnLCB7IHJlYWQ6IEVsZW1lbnRSZWZ9KSBpbm5lclNlbGVjdFNlYXJjaDogRWxlbWVudFJlZjtcclxuICAgIC8vQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RhbGwnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgaW5uZXJTZWxlY3RhbGw6IEVsZW1lbnRSZWY7XHJcbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1hdC1zZWxlY3Qtc2VhcmNoLWluc2lkZS1tYXQtb3B0aW9uJylcclxuICAgIGdldCBpc0luc2lkZU1hdE9wdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gISF0aGlzLm1hdE9wdGlvbjtcclxuICAgIH1cclxuICAgIC8qKiBDdXJyZW50IHNlYXJjaCB2YWx1ZSAqL1xyXG4gICAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBfdmFsdWU6IHN0cmluZztcclxuXHJcbiAgICBvbkNoYW5nZTogRnVuY3Rpb24gPSAoXzogYW55KSA9PiB7IH07XHJcbiAgICBvblRvdWNoZWQ6IEZ1bmN0aW9uID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8qKiBSZWZlcmVuY2UgdG8gdGhlIE1hdFNlbGVjdCBvcHRpb25zICovXHJcbiAgICBwdWJsaWMgX29wdGlvbnM6IFF1ZXJ5TGlzdDxNYXRPcHRpb24+O1xyXG5cclxuICAgIC8qKiBQcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlcyB3aGVuIHVzaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+Ki9cclxuICAgIHByaXZhdGUgcHJldmlvdXNTZWxlY3RlZFZhbHVlczogYW55W107XHJcblxyXG4gICAgLyoqIFdoZXRoZXIgdGhlIGJhY2tkcm9wIGNsYXNzIGhhcyBiZWVuIHNldCAqL1xyXG4gICAgcHJpdmF0ZSBvdmVybGF5Q2xhc3NTZXQgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogRXZlbnQgdGhhdCBlbWl0cyB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGNoYW5nZXMgKi9cclxuICAgIHByaXZhdGUgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBBbGxDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG4gICAgLyoqIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gZGVzdHJveWVkLiAqL1xyXG4gICAgcHJpdmF0ZSBfb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcblxyXG4gICAgY29uc3RydWN0b3IoQEluamVjdChNYXRTZWxlY3QpIHB1YmxpYyBtYXRTZWxlY3Q6IE1hdFNlbGVjdCxcclxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZiwgQE9wdGlvbmFsKCkgQEluamVjdChNYXRPcHRpb24pIHB1YmxpYyBtYXRPcHRpb246IE1hdE9wdGlvbiA9IG51bGwpIHtcclxuXHJcblxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIC8vIHNldCBjdXN0b20gcGFuZWwgY2xhc3NcclxuICAgICAgICBjb25zdCBwYW5lbENsYXNzID0gJ21hdC1zZWxlY3Qtc2VhcmNoLXBhbmVsJztcclxuICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcykge1xyXG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcy5wdXNoKHBhbmVsQ2xhc3MpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IFt0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzLCBwYW5lbENsYXNzXTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubWF0U2VsZWN0LnBhbmVsQ2xhc3NbcGFuZWxDbGFzc10gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IHBhbmVsQ2xhc3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBjdXN0b20gbWF0LW9wdGlvbiBjbGFzcyBpZiB0aGUgY29tcG9uZW50IHdhcyBwbGFjZWQgaW5zaWRlIGEgbWF0LW9wdGlvblxyXG4gICAgICAgIGlmICh0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLm1hdE9wdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ2NvbnRhaW5zLW1hdC1zZWxlY3Qtc2VhcmNoJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHdoZW4gdGhlIHNlbGVjdCBkcm9wZG93biBwYW5lbCBpcyBvcGVuZWQgb3IgY2xvc2VkXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3BlbmVkQ2hhbmdlXHJcbiAgICAgICAgICAgIC8vIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIGRlbGF5KDEpLFxyXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSlcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChvcGVuZWQpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChvcGVuZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBmb2N1cyB0aGUgc2VhcmNoIGZpZWxkIHdoZW4gb3BlbmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0V2lkdGgoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFyIGl0IHdoZW4gY2xvc2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBzZXQgdGhlIGZpcnN0IGl0ZW0gYWN0aXZlIGFmdGVyIHRoZSBvcHRpb25zIGNoYW5nZWRcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcGVuZWRDaGFuZ2VcclxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuY2hhbmdlc1xyXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBrZXlNYW5hZ2VyID0gdGhpcy5tYXRTZWxlY3QuX2tleU1hbmFnZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlNYW5hZ2VyICYmIHRoaXMubWF0U2VsZWN0LnBhbmVsT3Blbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgXCJleHByZXNzaW9uIGhhcyBiZWVuIGNoYW5nZWRcIiBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5TWFuYWdlci5zZXRGaXJzdEl0ZW1BY3RpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFdpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBubyBlbnRyaWVzIGZvdW5kIGNsYXNzIG9uIG1hdCBvcHRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25vRW50cmllc0ZvdW5kKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gZGV0ZWN0IGNoYW5nZXMgd2hlbiB0aGUgaW5wdXQgY2hhbmdlc1xyXG4gICAgICAgIHRoaXMuY2hhbmdlXHJcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbml0TXVsdGlwbGVIYW5kbGluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5uZXh0KCk7XHJcbiAgICAgICAgdGhpcy5fb25EZXN0cm95LmNvbXBsZXRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnNldE92ZXJsYXlDbGFzcygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMubWF0U2VsZWN0Lm9wZW5lZENoYW5nZVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KVxyXG4gICAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmNoYW5nZXNcclxuICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIFxyXG4gICAgX2hhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMzIpIHtcclxuICAgICAgICAgICAgLy8gZG8gbm90IHByb3BhZ2F0ZSBzcGFjZXMgdG8gTWF0U2VsZWN0LCBhcyB0aGlzIHdvdWxkIHNlbGVjdCB0aGUgY3VycmVudGx5IGFjdGl2ZSBvcHRpb25cclxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgdmFsdWVDaGFuZ2VkID0gdmFsdWUgIT09IHRoaXMuX3ZhbHVlO1xyXG4gICAgICAgIGlmICh2YWx1ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh7IHR5cGU6ICdUZXh0JywgdmFsOiB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25JbnB1dENoYW5nZSh2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlQ2hhbmdlZCA9IHZhbHVlICE9PSB0aGlzLl92YWx1ZTtcclxuICAgICAgICBpZiAodmFsdWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uQmx1cih2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHZhbHVlKTtcclxuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbikge1xyXG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgICB9XHJcblxyXG4gICBcclxuICAgIHB1YmxpYyBfZm9jdXMoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlYXJjaFNlbGVjdElucHV0IHx8ICF0aGlzLm1hdFNlbGVjdC5wYW5lbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNhdmUgYW5kIHJlc3RvcmUgc2Nyb2xsVG9wIG9mIHBhbmVsLCBzaW5jZSBpdCB3aWxsIGJlIHJlc2V0IGJ5IGZvY3VzKClcclxuICAgICAgICAvLyBub3RlOiB0aGlzIGlzIGhhY2t5XHJcbiAgICAgICAgY29uc3QgcGFuZWwgPSB0aGlzLm1hdFNlbGVjdC5wYW5lbC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IHBhbmVsLnNjcm9sbFRvcDtcclxuXHJcbiAgICAgICAgLy8gZm9jdXNcclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgcGFuZWwuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBjdXJyZW50IHNlYXJjaCB2YWx1ZVxyXG4gICAgICoge2Jvb2xlYW59IGZvY3VzIHdoZXRoZXIgdG8gZm9jdXMgYWZ0ZXIgcmVzZXR0aW5nXHJcbiAgICAgKiBcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9yZXNldChmb2N1cz86IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAoIXRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgICAgICB0aGlzLm9uSW5wdXRDaGFuZ2UoJycpO1xyXG4gICAgICAgIGlmIChmb2N1cykge1xyXG4gICAgICAgICAgICB0aGlzLl9mb2N1cygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIG92ZXJsYXkgY2xhc3MgIHRvIGNvcnJlY3Qgb2Zmc2V0WVxyXG4gICAgICogc28gdGhhdCB0aGUgc2VsZWN0ZWQgb3B0aW9uIGlzIGF0IHRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0IGJveCB3aGVuIG9wZW5pbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzZXRPdmVybGF5Q2xhc3MoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3ZlcmxheUNsYXNzU2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgb3ZlcmxheUNsYXNzZXM6IHN0cmluZ1tdID0gWydjZGstb3ZlcmxheS1wYW5lLXNlbGVjdC1zZWFyY2gnXTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICAvLyBhZGQgb2Zmc2V0IHRvIHBhbmVsIGlmIGNvbXBvbmVudCBpcyBub3QgcGxhY2VkIGluc2lkZSBtYXQtb3B0aW9uXHJcbiAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLnB1c2goJ2Nkay1vdmVybGF5LXBhbmUtc2VsZWN0LXNlYXJjaC13aXRoLW9mZnNldCcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3ZlcmxheURpci5hdHRhY2hcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gbm90ZTogdGhpcyBpcyBoYWNreSwgYnV0IGN1cnJlbnRseSB0aGVyZSBpcyBubyBiZXR0ZXIgd2F5IHRvIGRvIHRoaXNcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3ZlcmxheUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5zZWFyY2hTZWxlY3RJbnB1dC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnY2RrLW92ZXJsYXktcGFuZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGF5RWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChvdmVybGF5RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLmZvckVhY2gob3ZlcmxheUNsYXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxheUVsZW1lbnQuY2xhc3NMaXN0LmFkZChvdmVybGF5Q2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5vdmVybGF5Q2xhc3NTZXQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIGhhbmRsaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+XHJcbiAgICAgKiBOb3RlOiB0byBpbXByb3ZlIHRoaXMgY29kZSwgbWF0LXNlbGVjdCBzaG91bGQgYmUgZXh0ZW5kZWQgdG8gYWxsb3cgZGlzYWJsaW5nIHJlc2V0dGluZyB0aGUgc2VsZWN0aW9uIHdoaWxlIGZpbHRlcmluZy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbml0TXVsdGlwbGVIYW5kbGluZygpIHtcclxuICAgICAgICAvLyBpZiA8bWF0LXNlbGVjdCBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxyXG4gICAgICAgIC8vIHN0b3JlIHByZXZpb3VzbHkgc2VsZWN0ZWQgdmFsdWVzIGFuZCByZXN0b3JlIHRoZW0gd2hlbiB0aGV5IGFyZSBkZXNlbGVjdGVkXHJcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgb3B0aW9uIGlzIG5vdCBhdmFpbGFibGUgd2hpbGUgd2UgYXJlIGN1cnJlbnRseSBmaWx0ZXJpbmdcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC52YWx1ZUNoYW5nZVxyXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsdWVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QubXVsdGlwbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdG9yZVNlbGVjdGVkVmFsdWVzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlICYmIHRoaXMuX3ZhbHVlLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMgJiYgQXJyYXkuaXNBcnJheSh0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvblZhbHVlcyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubWFwKG9wdGlvbiA9PiBvcHRpb24udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMuZm9yRWFjaChwcmV2aW91c1ZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMuaW5kZXhPZihwcmV2aW91c1ZhbHVlKSA9PT0gLTEgJiYgb3B0aW9uVmFsdWVzLmluZGV4T2YocHJldmlvdXNWYWx1ZSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYSB2YWx1ZSB0aGF0IHdhcyBzZWxlY3RlZCBiZWZvcmUgaXMgZGVzZWxlY3RlZCBhbmQgbm90IGZvdW5kIGluIHRoZSBvcHRpb25zLCBpdCB3YXMgZGVzZWxlY3RlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1ZSB0byB0aGUgZmlsdGVyaW5nLCBzbyB3ZSByZXN0b3JlIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHByZXZpb3VzVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RvcmVTZWxlY3RlZFZhbHVlcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3RvcmVTZWxlY3RlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5fb25DaGFuZ2UodmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcyA9IHZhbHVlcztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRXaWR0aCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2ggfHwgIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudDtcclxuICAgICAgICBsZXQgcGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ21hdC1zZWxlY3QtcGFuZWwnKSkge1xyXG4gICAgICAgICAgICAgICAgcGFuZWxFbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwYW5lbEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5pbm5lclNlbGVjdFNlYXJjaC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gcGFuZWxFbGVtZW50LmNsaWVudFdpZHRoICsgJ3B4JztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vLy9pbm5lclNlbGVjdGFsbFxyXG4gICAgICAgIC8vaWYgKCF0aGlzLmlubmVyU2VsZWN0YWxsIHx8ICF0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAvLyAgICByZXR1cm47XHJcbiAgICAgICAgLy99XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxsZWxlbWVudDogSFRNTEVsZW1lbnQgPSB0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxscGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICAvL3doaWxlIChTZWxlY3RhbGxlbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgLy8gICAgaWYgKFNlbGVjdGFsbGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdtYXQtc2VsZWN0LXBhbmVsJykpIHtcclxuICAgICAgICAvLyAgICAgICAgU2VsZWN0YWxscGFuZWxFbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudDtcclxuICAgICAgICAvLyAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgLy8gICAgfVxyXG4gICAgICAgIC8vfVxyXG4gICAgICAgIC8vaWYgKFNlbGVjdGFsbHBhbmVsRWxlbWVudCkge1xyXG4gICAgICAgIC8vICAgIHRoaXMuaW5uZXJTZWxlY3RhbGwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aCA9IFNlbGVjdGFsbHBhbmVsRWxlbWVudC5jbGllbnRXaWR0aCArICdweCc7XHJcbiAgICAgICAgLy99XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIF9ub0VudHJpZXNGb3VuZCgpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXRoaXMuX29wdGlvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9FbnRyaWVzRm91bmRMYWJlbCAmJiB0aGlzLnZhbHVlICYmIHRoaXMuX29wdGlvbnMubGVuZ3RoID09PSAxO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vRW50cmllc0ZvdW5kTGFiZWwgJiYgdGhpcy52YWx1ZSAmJiB0aGlzLl9vcHRpb25zLmxlbmd0aCA9PT0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0b2dnbGVTZWxlY3Rpb24oY2hhbmdlOiBNYXRDaGVja2JveENoYW5nZSwgY2hlY2spOiB2b2lkIHtcclxuICAgICAgICBpZiAoY2hhbmdlLmNoZWNrZWQpIHtcclxuICAgICAgICAgICAgLy90aGlzLm1vZGVsLnVwZGF0ZS5lbWl0KHRoaXMudmFsdWVzKTtcclxuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZSh7IHR5cGU6ICdDaGVjaycsIHZhbDogY2hhbmdlLmNoZWNrZWQgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KHsgdHlwZTogJ0NoZWNrJywgdmFsOiBjaGFuZ2UuY2hlY2tlZCB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaXNjaGVja2VkKGNoZWNrKTogYm9vbGVhbiB7XHJcbiAgICAgICAgY29uc29sZS5sb2codGhpcy5tYXRTZWxlY3Qub3B0aW9ucywgdGhpcy5tYXRTZWxlY3QudmFsdWUpO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZDogYW55ID0gdGhpcy5tYXRTZWxlY3Quc2VsZWN0ZWQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMgJiYgc2VsZWN0ZWQgJiYgc2VsZWN0ZWQubGVuZ3RoID4gMCAmJiB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmxlbmd0aCA9PSBzZWxlY3RlZC5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBpc0luZGV0ZXJtaW5hdGUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IHNlbGVjdGVkOiBhbnkgPSB0aGlzLm1hdFNlbGVjdC5zZWxlY3RlZDtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXRTZWxlY3Qub3B0aW9ucyAmJiBzZWxlY3RlZC5sZW5ndGggPiAwICYmIHNlbGVjdGVkLmxlbmd0aCA8IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubGVuZ3RoO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==