/** * Copyright (c) 2018 Bithost GmbH All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { A, DOWN_ARROW, END, ENTER, ESCAPE, HOME, NINE, SPACE, UP_ARROW, Z, ZERO } from '@angular/cdk/keycodes'; import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, forwardRef, Inject, Input, Optional, Output, ViewChild } from '@angular/core'; import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatOption } from '@angular/material/core'; import { MatFormField } from '@angular/material/form-field'; import { MatSelect } from '@angular/material/select'; import { BehaviorSubject, combineLatest, of, Subject } from 'rxjs'; import { delay, filter, map, startWith, switchMap, take, takeUntil, tap } from 'rxjs/operators'; import { MatSelectSearchClearDirective } from './mat-select-search-clear.directive'; import { configurableDefaultOptions, MAT_SELECTSEARCH_DEFAULT_OPTIONS } from './default-options'; import { MatSelectNoEntriesFoundDirective } from './mat-select-no-entries-found.directive'; import * as i0 from "@angular/core"; import * as i1 from "@angular/cdk/scrolling"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "@angular/material/button"; import * as i5 from "@angular/material/checkbox"; import * as i6 from "@angular/material/icon"; import * as i7 from "@angular/material/progress-spinner"; import * as i8 from "@angular/material/tooltip"; import * as i9 from "@angular/material/divider"; import * as i10 from "@angular/material/select"; import * as i11 from "@angular/material/core"; import * as i12 from "@angular/material/form-field"; /* tslint:disable:member-ordering component-selector */ /** * Component providing an input field for searching MatSelect options. * * Example usage: * * interface Bank { * id: string; * name: string; * } * * @Component({ * selector: 'my-app-data-selection', * template: ` * * * * * * * {{bank.name}} * * * * ` * }) * export class DataSelectionComponent implements OnInit, OnDestroy { * * // control for the selected bank * public bankCtrl: FormControl = new FormControl(); * // control for the MatSelect filter keyword * public bankFilterCtrl: FormControl = new FormControl(); * * // list of banks * private banks: Bank[] = [{name: 'Bank A', id: 'A'}, {name: 'Bank B', id: 'B'}, {name: 'Bank C', id: 'C'}]; * // list of banks filtered by search keyword * public filteredBanks: ReplaySubject = new ReplaySubject(1); * * // Subject that emits when the component has been destroyed. * private _onDestroy = new Subject(); * * * ngOnInit() { * // load the initial bank list * this.filteredBanks.next(this.banks.slice()); * // listen for search field value changes * this.bankFilterCtrl.valueChanges * .pipe(takeUntil(this._onDestroy)) * .subscribe(() => { * this.filterBanks(); * }); * } * * ngOnDestroy() { * this._onDestroy.next(); * this._onDestroy.complete(); * } * * private filterBanks() { * if (!this.banks) { * return; * } * * // get the search keyword * let search = this.bankFilterCtrl.value; * if (!search) { * this.filteredBanks.next(this.banks.slice()); * return; * } else { * search = search.toLowerCase(); * } * * // filter the banks * this.filteredBanks.next( * this.banks.filter(bank => bank.name.toLowerCase().indexOf(search) > -1) * ); * } * } */ export class MatSelectSearchComponent { constructor(matSelect, changeDetectorRef, _viewportRuler, matOption = null, matFormField = null, defaultOptions) { this.matSelect = matSelect; this.changeDetectorRef = changeDetectorRef; this._viewportRuler = _viewportRuler; this.matOption = matOption; this.matFormField = matFormField; /** Label of the search placeholder */ this.placeholderLabel = 'Suche'; /** Type of the search input field */ this.type = 'text'; /** Font-based icon used for displaying Close-Icon */ this.closeIcon = 'close'; /** Label to be shown when no entries are found. Set to null if no message should be shown. */ this.noEntriesFoundLabel = 'Keine Optionen gefunden'; /** * Whether or not the search field should be cleared after the dropdown menu is closed. * Useful for server-side filtering. See [#3](https://github.com/bithost-gmbh/ngx-mat-select-search/issues/3) */ this.clearSearchInput = true; /** Whether to show the search-in-progress indicator */ this.searching = false; /** Disables initial focusing of the input field */ this.disableInitialFocus = false; /** Enable clear input on escape pressed */ this.enableClearOnEscapePressed = false; /** * Prevents home / end key being propagated to mat-select, * allowing to move the cursor within the search input instead of navigating the options */ this.preventHomeEndKeyPropagation = false; /** Disables scrolling to active options when option list changes. Useful for server-side search */ this.disableScrollToActiveOnOptionsChanged = false; /** Adds 508 screen reader support for search box */ this.ariaLabel = 'dropdown search'; /** Whether to show Select All Checkbox (for mat-select[multi=true]) */ this.showToggleAllCheckbox = false; /** select all checkbox checked state */ this.toggleAllCheckboxChecked = false; /** select all checkbox indeterminate state */ this.toggleAllCheckboxIndeterminate = false; /** Display a message in a tooltip on the toggle-all checkbox */ this.toggleAllCheckboxTooltipMessage = ''; /** Define the position of the tooltip on the toggle-all checkbox. */ this.toggleAllCheckboxTooltipPosition = 'below'; /** Show/Hide the search clear button of the search input */ this.hideClearSearchButton = false; /** * Always restore selected options on selectionChange for mode multi (e.g. for lazy loading/infinity scrolling). * Defaults to false, so selected options are only restored while filtering is active. */ this.alwaysRestoreSelectedOptionsMulti = false; /** Output emitter to send to parent component with the toggle all boolean */ this.toggleAll = new EventEmitter(); this.onTouched = (_) => { }; this._options$ = new BehaviorSubject(null); this.optionsList$ = this._options$.pipe(switchMap(_options => _options ? _options.changes.pipe(map(options => options.toArray()), startWith(_options.toArray())) : of(null))); this.optionsLength$ = this.optionsList$.pipe(map(options => options ? options.length : 0)); this._formControl = new FormControl(''); /** whether to show the no entries found message */ this._showNoEntriesFound$ = combineLatest([ this._formControl.valueChanges, this.optionsLength$ ]).pipe(map(([value, optionsLength]) => this.noEntriesFoundLabel && value && optionsLength === this.getOptionsLengthOffset())); /** Subject that emits when the component has been destroyed. */ this._onDestroy = new Subject(); this.applyDefaultOptions(defaultOptions); } /** Current search value */ get value() { return this._formControl.value; } /** Reference to the MatSelect options */ set _options(_options) { this._options$.next(_options); } get _options() { return this._options$.getValue(); } applyDefaultOptions(defaultOptions) { if (!defaultOptions) { return; } for (const key of configurableDefaultOptions) { if (defaultOptions.hasOwnProperty(key)) { this[key] = defaultOptions[key]; } } } ngOnInit() { // 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'); this.matOption._getHostElement().setAttribute('aria-hidden', 'true'); } else { console.error(' must be placed inside a element'); } // when the select dropdown panel is opened or closed this.matSelect.openedChange .pipe(delay(1), takeUntil(this._onDestroy)) .subscribe((opened) => { if (opened) { this.updateInputWidth(); // focus the search field when opening if (!this.disableInitialFocus) { this._focus(); } } else { // clear it when closing if (this.clearSearchInput) { this._reset(); } } }); // set the first item active after the options changed this.matSelect.openedChange .pipe(take(1), switchMap((_) => { this._options = this.matSelect.options; // Closure variable for tracking the most recent first option. // In order to avoid avoid causing the list to // scroll to the top when options are added to the bottom of // the list (eg: infinite scroll), we compare only // the changes to the first options to determine if we // should set the first item as active. // This prevents unnecessary scrolling to the top of the list // when options are appended, but allows the first item // in the list to be set as active by default when there // is no active selection let previousFirstOption = this._options.toArray()[this.getOptionsLengthOffset()]; return this._options.changes .pipe(tap(() => { // avoid "expression has been changed" error setTimeout(() => { // Convert the QueryList to an array const options = this._options.toArray(); // The true first item is offset by 1 const currentFirstOption = options[this.getOptionsLengthOffset()]; const keyManager = this.matSelect._keyManager; if (keyManager && this.matSelect.panelOpen && currentFirstOption) { // set first item active and input width // Check to see if the first option in these changes is different from the previous. const firstOptionIsChanged = !previousFirstOption || !this.matSelect.compareWith(previousFirstOption.value, currentFirstOption.value); // CASE: The first option is different now. // Indiciates we should set it as active and scroll to the top. if (firstOptionIsChanged || !keyManager.activeItem || !options.find(option => this.matSelect.compareWith(option.value, keyManager.activeItem.value))) { keyManager.setActiveItem(this.getOptionsLengthOffset()); } // wait for panel width changes setTimeout(() => { this.updateInputWidth(); }); } // Update our reference previousFirstOption = currentFirstOption; }); })); })) .pipe(takeUntil(this._onDestroy)) .subscribe(); // add or remove css class depending on whether to show the no entries found message // note: this is hacky this._showNoEntriesFound$.pipe(takeUntil(this._onDestroy)).subscribe(showNoEntriesFound => { // set no entries found class on mat option if (this.matOption) { if (showNoEntriesFound) { this.matOption._getHostElement().classList.add('mat-select-search-no-entries-found'); } else { this.matOption._getHostElement().classList.remove('mat-select-search-no-entries-found'); } } }); // resize the input width when the viewport is resized, i.e. the trigger width could potentially be resized this._viewportRuler.change() .pipe(takeUntil(this._onDestroy)) .subscribe(() => { if (this.matSelect.panelOpen) { this.updateInputWidth(); } }); this.initMultipleHandling(); this.optionsList$.pipe(takeUntil(this._onDestroy)).subscribe(() => { // update view when available options change this.changeDetectorRef.markForCheck(); }); } _emitSelectAllBooleanToParent(state) { this.toggleAll.emit(state); } ngOnDestroy() { this._onDestroy.next(); this._onDestroy.complete(); } _isToggleAllCheckboxVisible() { return this.matSelect.multiple && this.showToggleAllCheckbox; } /** * Handles the key down event with MatSelect. * Allows e.g. selecting with enter key, navigation with arrow keys, etc. * @param event */ _handleKeydown(event) { // Prevent propagation for all alphanumeric characters in order to avoid selection issues if ((event.key && event.key.length === 1) || (event.keyCode >= A && event.keyCode <= Z) || (event.keyCode >= ZERO && event.keyCode <= NINE) || (event.keyCode === SPACE) || (this.preventHomeEndKeyPropagation && (event.keyCode === HOME || event.keyCode === END))) { event.stopPropagation(); } if (this.matSelect.multiple && event.key && event.keyCode === ENTER) { // Regain focus after multiselect, so we can further type setTimeout(() => this._focus()); } // Special case if click Escape, if input is empty, close the dropdown, if not, empty out the search field if (this.enableClearOnEscapePressed === true && event.keyCode === ESCAPE && this.value) { this._reset(true); event.stopPropagation(); } } /** * Handles the key up event with MatSelect. * Allows e.g. the announcing of the currently activeDescendant by screen readers. */ _handleKeyup(event) { if (event.keyCode === UP_ARROW || event.keyCode === DOWN_ARROW) { const ariaActiveDescendantId = this.matSelect._getAriaActiveDescendant(); const index = this._options.toArray().findIndex(item => item.id === ariaActiveDescendantId); if (index !== -1) { this.unselectActiveDescendant(); this.activeDescendant = this._options.toArray()[index]._getHostElement(); this.activeDescendant.setAttribute('aria-selected', 'true'); this.searchSelectInput.nativeElement.setAttribute('aria-activedescendant', ariaActiveDescendantId); } } } writeValue(value) { this._lastExternalInputValue = value; this._formControl.setValue(value); this.changeDetectorRef.markForCheck(); } onBlur() { this.unselectActiveDescendant(); this.onTouched(); } registerOnChange(fn) { this._formControl.valueChanges.pipe(filter(value => value !== this._lastExternalInputValue), tap(() => this._lastExternalInputValue = undefined), takeUntil(this._onDestroy)).subscribe(fn); } registerOnTouched(fn) { this.onTouched = fn; } /** * Focuses the search input field */ _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 const panel = this.matSelect.panel.nativeElement; const scrollTop = panel.scrollTop; // focus this.searchSelectInput.nativeElement.focus(); panel.scrollTop = scrollTop; } /** * Resets the current search value * @param focus whether to focus after resetting */ _reset(focus) { this._formControl.setValue(''); if (focus) { this._focus(); } } /** * Initializes handling * Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering. */ initMultipleHandling() { if (!this.matSelect.ngControl) { if (this.matSelect.multiple) { // note: the access to matSelect.ngControl (instead of matSelect.value / matSelect.valueChanges) // is necessary to properly work in multi-selection mode. console.error('the mat-select containing ngx-mat-select-search must have a ngModel or formControl directive when multiple=true'); } return; } // if // store previously selected values and restore them when they are deselected // because the option is not available while we are currently filtering this.previousSelectedValues = this.matSelect.ngControl.value; this.matSelect.ngControl.valueChanges .pipe(takeUntil(this._onDestroy)) .subscribe((values) => { let restoreSelectedValues = false; if (this.matSelect.multiple) { if ((this.alwaysRestoreSelectedOptionsMulti || (this._formControl.value && this._formControl.value.length)) && this.previousSelectedValues && Array.isArray(this.previousSelectedValues)) { if (!values || !Array.isArray(values)) { values = []; } const optionValues = this.matSelect.options.map(option => option.value); this.previousSelectedValues.forEach(previousValue => { if (!values.some(v => this.matSelect.compareWith(v, previousValue)) && !optionValues.some(v => this.matSelect.compareWith(v, previousValue))) { // 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; } }); } } this.previousSelectedValues = values; if (restoreSelectedValues) { this.matSelect._onChange(values); } }); } /** * Set the width of the innerSelectSearch to fit even custom scrollbars * And support all Operation Systems */ updateInputWidth() { if (!this.innerSelectSearch || !this.innerSelectSearch.nativeElement) { return; } let element = this.innerSelectSearch.nativeElement; 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'; } } /** * Determine the offset to length that can be caused by the optional matOption used as a search input. */ getOptionsLengthOffset() { if (this.matOption) { return 1; } else { return 0; } } unselectActiveDescendant() { this.activeDescendant?.removeAttribute('aria-selected'); this.searchSelectInput.nativeElement.removeAttribute('aria-activedescendant'); } } MatSelectSearchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: MatSelectSearchComponent, deps: [{ token: MatSelect }, { token: i0.ChangeDetectorRef }, { token: i1.ViewportRuler }, { token: MatOption, optional: true }, { token: MatFormField, optional: true }, { token: MAT_SELECTSEARCH_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component }); MatSelectSearchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.2", type: MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: { placeholderLabel: "placeholderLabel", type: "type", closeIcon: "closeIcon", closeSvgIcon: "closeSvgIcon", noEntriesFoundLabel: "noEntriesFoundLabel", clearSearchInput: "clearSearchInput", searching: "searching", disableInitialFocus: "disableInitialFocus", enableClearOnEscapePressed: "enableClearOnEscapePressed", preventHomeEndKeyPropagation: "preventHomeEndKeyPropagation", disableScrollToActiveOnOptionsChanged: "disableScrollToActiveOnOptionsChanged", ariaLabel: "ariaLabel", showToggleAllCheckbox: "showToggleAllCheckbox", toggleAllCheckboxChecked: "toggleAllCheckboxChecked", toggleAllCheckboxIndeterminate: "toggleAllCheckboxIndeterminate", toggleAllCheckboxTooltipMessage: "toggleAllCheckboxTooltipMessage", toggleAllCheckboxTooltipPosition: "toggleAllCheckboxTooltipPosition", hideClearSearchButton: "hideClearSearchButton", alwaysRestoreSelectedOptionsMulti: "alwaysRestoreSelectedOptionsMulti" }, outputs: { toggleAll: "toggleAll" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MatSelectSearchComponent), multi: true } ], queries: [{ propertyName: "clearIcon", first: true, predicate: MatSelectSearchClearDirective, descendants: true }, { propertyName: "noEntriesFound", first: true, predicate: MatSelectNoEntriesFoundDirective, descendants: true }], viewQueries: [{ propertyName: "searchSelectInput", first: true, predicate: ["searchSelectInput"], descendants: true, read: ElementRef, static: true }, { propertyName: "innerSelectSearch", first: true, predicate: ["innerSelectSearch"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "\n\n\n\n\n\n\n
\n \n\n \n \n\n \n\n \n
\n\n \n\n\n
\n \n {{noEntriesFoundLabel}}\n
\n\n", styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;left:0;width:100%;z-index:100;font-size:inherit;box-shadow:none;background-color:var(--mat-select-panel-background-color)}.mat-select-search-inner.mat-select-search-inner-multiple.mat-select-search-inner-toggle-all .mat-select-search-inner-row{display:flex;align-items:center}.mat-select-search-input{box-sizing:border-box;width:100%;border:none;font-family:inherit;font-size:inherit;color:currentColor;outline:none;background-color:var(--mat-select-panel-background-color);padding:0 44px 0 16px;height:calc(3em - 1px);line-height:calc(3em - 1px)}:host-context([dir=rtl]) .mat-select-search-input{padding-right:16px;padding-left:44px}.mat-select-search-inner-toggle-all .mat-select-search-input{padding-left:5px}.mat-select-search-no-entries-found{padding-top:8px}.mat-select-search-clear{position:absolute;right:4px;top:0}:host-context([dir=rtl]) .mat-select-search-clear{right:auto;left:4px}.mat-select-search-spinner{position:absolute;right:16px;top:calc(50% - 8px)}:host-context([dir=rtl]) .mat-select-search-spinner{right:auto;left:16px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search{position:sticky;top:-8px;z-index:1;opacity:1;margin-top:-8px;pointer-events:all}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0;margin-left:0}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mdc-list-item__primary-text{opacity:1}.mat-select-search-toggle-all-checkbox{padding-left:5px}:host-context([dir=rtl]) .mat-select-search-toggle-all-checkbox{padding-left:0;padding-right:5px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i9.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: MatSelectSearchComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-mat-select-search', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MatSelectSearchComponent), multi: true } ], changeDetection: ChangeDetectionStrategy.OnPush, template: "\n\n\n\n\n\n\n
\n \n\n \n \n\n \n\n \n
\n\n \n\n\n
\n \n {{noEntriesFoundLabel}}\n
\n\n", styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;left:0;width:100%;z-index:100;font-size:inherit;box-shadow:none;background-color:var(--mat-select-panel-background-color)}.mat-select-search-inner.mat-select-search-inner-multiple.mat-select-search-inner-toggle-all .mat-select-search-inner-row{display:flex;align-items:center}.mat-select-search-input{box-sizing:border-box;width:100%;border:none;font-family:inherit;font-size:inherit;color:currentColor;outline:none;background-color:var(--mat-select-panel-background-color);padding:0 44px 0 16px;height:calc(3em - 1px);line-height:calc(3em - 1px)}:host-context([dir=rtl]) .mat-select-search-input{padding-right:16px;padding-left:44px}.mat-select-search-inner-toggle-all .mat-select-search-input{padding-left:5px}.mat-select-search-no-entries-found{padding-top:8px}.mat-select-search-clear{position:absolute;right:4px;top:0}:host-context([dir=rtl]) .mat-select-search-clear{right:auto;left:4px}.mat-select-search-spinner{position:absolute;right:16px;top:calc(50% - 8px)}:host-context([dir=rtl]) .mat-select-search-spinner{right:auto;left:16px}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search{position:sticky;top:-8px;z-index:1;opacity:1;margin-top:-8px;pointer-events:all}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0;margin-left:0}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-option[aria-disabled=true].contains-mat-select-search .mdc-list-item__primary-text{opacity:1}.mat-select-search-toggle-all-checkbox{padding-left:5px}:host-context([dir=rtl]) .mat-select-search-toggle-all-checkbox{padding-left:0;padding-right:5px}\n"] }] }], ctorParameters: function () { return [{ type: i10.MatSelect, decorators: [{ type: Inject, args: [MatSelect] }] }, { type: i0.ChangeDetectorRef }, { type: i1.ViewportRuler }, { type: i11.MatOption, decorators: [{ type: Optional }, { type: Inject, args: [MatOption] }] }, { type: i12.MatFormField, decorators: [{ type: Optional }, { type: Inject, args: [MatFormField] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_SELECTSEARCH_DEFAULT_OPTIONS] }] }]; }, propDecorators: { placeholderLabel: [{ type: Input }], type: [{ type: Input }], closeIcon: [{ type: Input }], closeSvgIcon: [{ type: Input }], noEntriesFoundLabel: [{ type: Input }], clearSearchInput: [{ type: Input }], searching: [{ type: Input }], disableInitialFocus: [{ type: Input }], enableClearOnEscapePressed: [{ type: Input }], preventHomeEndKeyPropagation: [{ type: Input }], disableScrollToActiveOnOptionsChanged: [{ type: Input }], ariaLabel: [{ type: Input }], showToggleAllCheckbox: [{ type: Input }], toggleAllCheckboxChecked: [{ type: Input }], toggleAllCheckboxIndeterminate: [{ type: Input }], toggleAllCheckboxTooltipMessage: [{ type: Input }], toggleAllCheckboxTooltipPosition: [{ type: Input }], hideClearSearchButton: [{ type: Input }], alwaysRestoreSelectedOptionsMulti: [{ type: Input }], toggleAll: [{ type: Output }], searchSelectInput: [{ type: ViewChild, args: ['searchSelectInput', { read: ElementRef, static: true }] }], innerSelectSearch: [{ type: ViewChild, args: ['innerSelectSearch', { read: ElementRef, static: true }] }], clearIcon: [{ type: ContentChild, args: [MatSelectSearchClearDirective] }], noEntriesFound: [{ type: ContentChild, args: [MatSelectNoEntriesFoundDirective] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC9tYXQtc2VsZWN0LXNlYXJjaC9tYXQtc2VsZWN0LXNlYXJjaC5jb21wb25lbnQudHMiLCIuLi8uLi9zcmMvYXBwL21hdC1zZWxlY3Qtc2VhcmNoL21hdC1zZWxlY3Qtc2VhcmNoLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsT0FBTyxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVoSCxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUVOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0Is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QjtzQkFBdEMsS0FBSztnQkFHRywrQkFBK0I7c0JBQXZDLEtBQUs7Z0JBR0csZ0NBQWdDO3NCQUF4QyxLQUFLO2dCQUdHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFNRyxpQ0FBaUM7c0JBQXpDLEtBQUs7Z0JBR0ksU0FBUztzQkFBbEIsTUFBTTtnQkFHNkQsaUJBQWlCO3NCQUFwRixTQUFTO3VCQUFDLG1CQUFtQixFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUdFLGlCQUFpQjtzQkFBcEYsU0FBUzt1QkFBQyxtQkFBbUIsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHckIsU0FBUztzQkFBckQsWUFBWTt1QkFBQyw2QkFBNkI7Z0JBR0ssY0FBYztzQkFBN0QsWUFBWTt1QkFBQyxnQ0FBZ0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOCBCaXRob3N0IEdtYkggQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEEsIERPV05fQVJST1csIEVORCwgRU5URVIsIEVTQ0FQRSwgSE9NRSwgTklORSwgU1BBQ0UsIFVQX0FSUk9XLCBaLCBaRVJPIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IFZpZXdwb3J0UnVsZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdE9wdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXksIGZpbHRlciwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBNYXRTZWxlY3RTZWFyY2hDbGVhckRpcmVjdGl2ZSB9IGZyb20gJy4vbWF0LXNlbGVjdC1zZWFyY2gtY2xlYXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IGNvbmZpZ3VyYWJsZURlZmF1bHRPcHRpb25zLCBNQVRfU0VMRUNUU0VBUkNIX0RFRkFVTFRfT1BUSU9OUywgTWF0U2VsZWN0U2VhcmNoT3B0aW9ucyB9IGZyb20gJy4vZGVmYXVsdC1vcHRpb25zJztcbmltcG9ydCB7IE1hdFNlbGVjdE5vRW50cmllc0ZvdW5kRGlyZWN0aXZlIH0gZnJvbSAnLi9tYXQtc2VsZWN0LW5vLWVudHJpZXMtZm91bmQuZGlyZWN0aXZlJztcblxuLyogdHNsaW50OmRpc2FibGU6bWVtYmVyLW9yZGVyaW5nIGNvbXBvbmVudC1zZWxlY3RvciAqL1xuLyoqXG4gKiBDb21wb25lbnQgcHJvdmlkaW5nIGFuIGlucHV0IGZpZWxkIGZvciBzZWFyY2hpbmcgTWF0U2VsZWN0IG9wdGlvbnMuXG4gKlxuICogRXhhbXBsZSB1c2FnZTpcbiAqXG4gKiBpbnRlcmZhY2UgQmFuayB7XG4gKiAgaWQ6IHN0cmluZztcbiAqICBuYW1lOiBzdHJpbmc7XG4gKiB9XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnbXktYXBwLWRhdGEtc2VsZWN0aW9uJyxcbiAqICAgdGVtcGxhdGU6IGBcbiAqICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gKiAgICAgICA8bWF0LXNlbGVjdCBbZm9ybUNvbnRyb2xdPVwiYmFua0N0cmxcIiBwbGFjZWhvbGRlcj1cIkJhbmtcIj5cbiAqICAgICAgICAgPG1hdC1vcHRpb24+XG4gKiAgICAgICAgICAgPG5neC1tYXQtc2VsZWN0LXNlYXJjaCBbZm9ybUNvbnRyb2xdPVwiYmFua0ZpbHRlckN0cmxcIj48L25neC1tYXQtc2VsZWN0LXNlYXJjaD5cbiAqICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICogICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgYmFuayBvZiBmaWx0ZXJlZEJhbmtzIHwgYXN5bmNcIiBbdmFsdWVdPVwiYmFuay5pZFwiPlxuICogICAgICAgICAgIHt7YmFuay5uYW1lfX1cbiAqICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICogICAgICAgPC9tYXQtc2VsZWN0PlxuICogICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gKiAgIGBcbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgRGF0YVNlbGVjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAqXG4gKiAgIC8vIGNvbnRyb2wgZm9yIHRoZSBzZWxlY3RlZCBiYW5rXG4gKiAgIHB1YmxpYyBiYW5rQ3RybDogRm9ybUNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woKTtcbiAqICAgLy8gY29udHJvbCBmb3IgdGhlIE1hdFNlbGVjdCBmaWx0ZXIga2V5d29yZFxuICogICBwdWJsaWMgYmFua0ZpbHRlckN0cmw6IEZvcm1Db250cm9sID0gbmV3IEZvcm1Db250cm9sKCk7XG4gKlxuICogICAvLyBsaXN0IG9mIGJhbmtzXG4gKiAgIHByaXZhdGUgYmFua3M6IEJhbmtbXSA9IFt7bmFtZTogJ0JhbmsgQScsIGlkOiAnQSd9LCB7bmFtZTogJ0JhbmsgQicsIGlkOiAnQid9LCB7bmFtZTogJ0JhbmsgQycsIGlkOiAnQyd9XTtcbiAqICAgLy8gbGlzdCBvZiBiYW5rcyBmaWx0ZXJlZCBieSBzZWFyY2gga2V5d29yZFxuICogICBwdWJsaWMgZmlsdGVyZWRCYW5rczogUmVwbGF5U3ViamVjdDxCYW5rW10+ID0gbmV3IFJlcGxheVN1YmplY3Q8QmFua1tdPigxKTtcbiAqXG4gKiAgIC8vIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gZGVzdHJveWVkLlxuICogICBwcml2YXRlIF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICpcbiAqXG4gKiAgIG5nT25Jbml0KCkge1xuICogICAgIC8vIGxvYWQgdGhlIGluaXRpYWwgYmFuayBsaXN0XG4gKiAgICAgdGhpcy5maWx0ZXJlZEJhbmtzLm5leHQodGhpcy5iYW5rcy5zbGljZSgpKTtcbiAqICAgICAvLyBsaXN0ZW4gZm9yIHNlYXJjaCBmaWVsZCB2YWx1ZSBjaGFuZ2VzXG4gKiAgICAgdGhpcy5iYW5rRmlsdGVyQ3RybC52YWx1ZUNoYW5nZXNcbiAqICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICogICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gKiAgICAgICAgIHRoaXMuZmlsdGVyQmFua3MoKTtcbiAqICAgICAgIH0pO1xuICogICB9XG4gKlxuICogICBuZ09uRGVzdHJveSgpIHtcbiAqICAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICogICAgIHRoaXMuX29uRGVzdHJveS5jb21wbGV0ZSgpO1xuICogICB9XG4gKlxuICogICBwcml2YXRlIGZpbHRlckJhbmtzKCkge1xuICogICAgIGlmICghdGhpcy5iYW5rcykge1xuICogICAgICAgcmV0dXJuO1xuICogICAgIH1cbiAqXG4gKiAgICAgLy8gZ2V0IHRoZSBzZWFyY2gga2V5d29yZFxuICogICAgIGxldCBzZWFyY2ggPSB0aGlzLmJhbmtGaWx0ZXJDdHJsLnZhbHVlO1xuICogICAgIGlmICghc2VhcmNoKSB7XG4gKiAgICAgICB0aGlzLmZpbHRlcmVkQmFua3MubmV4dCh0aGlzLmJhbmtzLnNsaWNlKCkpO1xuICogICAgICAgcmV0dXJuO1xuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICBzZWFyY2ggPSBzZWFyY2gudG9Mb3dlckNhc2UoKTtcbiAqICAgICB9XG4gKlxuICogICAgIC8vIGZpbHRlciB0aGUgYmFua3NcbiAqICAgICB0aGlzLmZpbHRlcmVkQmFua3MubmV4dChcbiAqICAgICAgIHRoaXMuYmFua3MuZmlsdGVyKGJhbmsgPT4gYmFuay5uYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihzZWFyY2gpID4gLTEpXG4gKiAgICAgKTtcbiAqICAgfVxuICogfVxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtbWF0LXNlbGVjdC1zZWFyY2gnLFxuICB0ZW1wbGF0ZVVybDogJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tYXQtc2VsZWN0LXNlYXJjaC5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdFNlbGVjdFNlYXJjaENvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTWF0U2VsZWN0U2VhcmNoQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcblxuICAvKiogTGFiZWwgb2YgdGhlIHNlYXJjaCBwbGFjZWhvbGRlciAqL1xuICBASW5wdXQoKSBwbGFjZWhvbGRlckxhYmVsID0gJ1N1Y2hlJztcblxuICAvKiogVHlwZSBvZiB0aGUgc2VhcmNoIGlucHV0IGZpZWxkICovXG4gIEBJbnB1dCgpIHR5cGUgPSAndGV4dCc7XG5cbiAgLyoqIEZvbnQtYmFzZWQgaWNvbiB1c2VkIGZvciBkaXNwbGF5aW5nIENsb3NlLUljb24gKi9cbiAgQElucHV0KCkgY2xvc2VJY29uID0gJ2Nsb3NlJztcblxuICAvKiogU3ZnLWJhc2VkIGljb24gdXNlZCBmb3IgZGlzcGxheWluZyBDbG9zZS1JY29uLiBJZiBzZXQsIGNsb3NlSWNvbiBpcyBvdmVycmlkZGVuICovXG4gIEBJbnB1dCgpIGNsb3NlU3ZnSWNvbj86IHN0cmluZztcblxuICAvKiogTGFiZWwgdG8gYmUgc2hvd24gd2hlbiBubyBlbnRyaWVzIGFyZSBmb3VuZC4gU2V0IHRvIG51bGwgaWYgbm8gbWVzc2FnZSBzaG91bGQgYmUgc2hvd24uICovXG4gIEBJbnB1dCgpIG5vRW50cmllc0ZvdW5kTGFiZWwgPSAnS2VpbmUgT3B0aW9uZW4gZ2VmdW5kZW4nO1xuXG4gIC8qKlxuICAgICogV2hldGhlciBvciBub3QgdGhlIHNlYXJjaCBmaWVsZCBzaG91bGQgYmUgY2xlYXJlZCBhZnRlciB0aGUgZHJvcGRvd24gbWVudSBpcyBjbG9zZWQuXG4gICAgKiBVc2VmdWwgZm9yIHNlcnZlci1zaWRlIGZpbHRlcmluZy4gU2VlIFsjM10oaHR0cHM6Ly9naXRodWIuY29tL2JpdGhvc3QtZ21iaC9uZ3gtbWF0LXNlbGVjdC1zZWFyY2gvaXNzdWVzLzMpXG4gICAgKi9cbiAgQElucHV0KCkgY2xlYXJTZWFyY2hJbnB1dCA9IHRydWU7XG5cbiAgLyoqIFdoZXRoZXIgdG8gc2hvdyB0aGUgc2VhcmNoLWluLXByb2dyZXNzIGluZGljYXRvciAqL1xuICBASW5wdXQoKSBzZWFyY2hpbmcgPSBmYWxzZTtcblxuICAvKiogRGlzYWJsZXMgaW5pdGlhbCBmb2N1c2luZyBvZiB0aGUgaW5wdXQgZmllbGQgKi9cbiAgQElucHV0KCkgZGlzYWJsZUluaXRpYWxGb2N1cyA9IGZhbHNlO1xuXG4gIC8qKiBFbmFibGUgY2xlYXIgaW5wdXQgb24gZXNjYXBlIHByZXNzZWQgKi9cbiAgQElucHV0KCkgZW5hYmxlQ2xlYXJPbkVzY2FwZVByZXNzZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogUHJldmVudHMgaG9tZSAvIGVuZCBrZXkgYmVpbmcgcHJvcGFnYXRlZCB0byBtYXQtc2VsZWN0LFxuICAgKiBhbGxvd2luZyB0byBtb3ZlIHRoZSBjdXJzb3Igd2l0aGluIHRoZSBzZWFyY2ggaW5wdXQgaW5zdGVhZCBvZiBuYXZpZ2F0aW5nIHRoZSBvcHRpb25zXG4gICAqL1xuICBASW5wdXQoKSBwcmV2ZW50SG9tZUVuZEtleVByb3BhZ2F0aW9uID0gZmFsc2U7XG5cbiAgLyoqIERpc2FibGVzIHNjcm9sbGluZyB0byBhY3RpdmUgb3B0aW9ucyB3aGVuIG9wdGlvbiBsaXN0IGNoYW5nZXMuIFVzZWZ1bCBmb3Igc2VydmVyLXNpZGUgc2VhcmNoICovXG4gIEBJbnB1dCgpIGRpc2FibGVTY3JvbGxUb0FjdGl2ZU9uT3B0aW9uc0NoYW5nZWQgPSBmYWxzZTtcblxuICAvKiogQWRkcyA1MDggc2NyZWVuIHJlYWRlciBzdXBwb3J0IGZvciBzZWFyY2ggYm94ICovXG4gIEBJbnB1dCgpIGFyaWFMYWJlbCA9ICdkcm9wZG93biBzZWFyY2gnO1xuXG4gIC8qKiBXaGV0aGVyIHRvIHNob3cgU2VsZWN0IEFsbCBDaGVja2JveCAoZm9yIG1hdC1zZWxlY3RbbXVsdGk9dHJ1ZV0pICovXG4gIEBJbnB1dCgpIHNob3dUb2dnbGVBbGxDaGVja2JveCA9IGZhbHNlO1xuXG4gIC8qKiBzZWxlY3QgYWxsIGNoZWNrYm94IGNoZWNrZWQgc3RhdGUgKi9cbiAgQElucHV0KCkgdG9nZ2xlQWxsQ2hlY2tib3hDaGVja2VkID0gZmFsc2U7XG5cbiAgLyoqIHNlbGVjdCBhbGwgY2hlY2tib3ggaW5kZXRlcm1pbmF0ZSBzdGF0ZSAqL1xuICBASW5wdXQoKSB0b2dnbGVBbGxDaGVja2JveEluZGV0ZXJtaW5hdGUgPSBmYWxzZTtcblxuICAvKiogRGlzcGxheSBhIG1lc3NhZ2UgaW4gYSB0b29sdGlwIG9uIHRoZSB0b2dnbGUtYWxsIGNoZWNrYm94ICovXG4gIEBJbnB1dCgpIHRvZ2dsZUFsbENoZWNrYm94VG9vbHRpcE1lc3NhZ2UgPSAnJztcblxuICAvKiogRGVmaW5lIHRoZSBwb3NpdGlvbiBvZiB0aGUgdG9vbHRpcCBvbiB0aGUgdG9nZ2xlLWFsbCBjaGVja2JveC4gKi9cbiAgQElucHV0KCkgdG9nZ2xlQWxsQ2hlY2tib3hUb29sdGlwUG9zaXRpb246ICdsZWZ0JyB8ICdyaWdodCcgfCAnYWJvdmUnIHwgJ2JlbG93JyB8ICdiZWZvcmUnIHwgJ2FmdGVyJyA9ICdiZWxvdyc7XG5cbiAgLyoqIFNob3cvSGlkZSB0aGUgc2VhcmNoIGNsZWFyIGJ1dHRvbiBvZiB0aGUgc2VhcmNoIGlucHV0ICovXG4gIEBJbnB1dCgpIGhpZGVDbGVhclNlYXJjaEJ1dHRvbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBBbHdheXMgcmVzdG9yZSBzZWxlY3RlZCBvcHRpb25zIG9uIHNlbGVjdGlvbkNoYW5nZSBmb3IgbW9kZSBtdWx0aSAoZS5nLiBmb3IgbGF6eSBsb2FkaW5nL2luZmluaXR5IHNjcm9sbGluZykuXG4gICAqIERlZmF1bHRzIHRvIGZhbHNlLCBzbyBzZWxlY3RlZCBvcHRpb25zIGFyZSBvbmx5IHJlc3RvcmVkIHdoaWxlIGZpbHRlcmluZyBpcyBhY3RpdmUuXG4gICAqL1xuICBASW5wdXQoKSBhbHdheXNSZXN0b3JlU2VsZWN0ZWRPcHRpb25zTXVsdGkgPSBmYWxzZTtcblxuICAvKiogT3V0cHV0IGVtaXR0ZXIgdG8gc2VuZCB0byBwYXJlbnQgY29tcG9uZW50IHdpdGggdGhlIHRvZ2dsZSBhbGwgYm9vbGVhbiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlQWxsID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIHNlYXJjaCBpbnB1dCBmaWVsZCAqL1xuICBAVmlld0NoaWxkKCdzZWFyY2hTZWxlY3RJbnB1dCcsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pIHNlYXJjaFNlbGVjdElucHV0OiBFbGVtZW50UmVmO1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIHNlYXJjaCBpbnB1dCBmaWVsZCAqL1xuICBAVmlld0NoaWxkKCdpbm5lclNlbGVjdFNlYXJjaCcsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pIGlubmVyU2VsZWN0U2VhcmNoOiBFbGVtZW50UmVmO1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gY3VzdG9tIHNlYXJjaCBpbnB1dCBjbGVhciBpY29uICovXG4gIEBDb250ZW50Q2hpbGQoTWF0U2VsZWN0U2VhcmNoQ2xlYXJEaXJlY3RpdmUpIGNsZWFySWNvbjogTWF0U2VsZWN0U2VhcmNoQ2xlYXJEaXJlY3RpdmU7XG5cbiAgLyoqIFJlZmVyZW5jZSB0byBjdXN0b20gbm8gZW50cmllcyBmb3VuZCBlbGVtZW50ICovXG4gIEBDb250ZW50Q2hpbGQoTWF0U2VsZWN0Tm9FbnRyaWVzRm91bmREaXJlY3RpdmUpIG5vRW50cmllc0ZvdW5kOiBNYXRTZWxlY3ROb0VudHJpZXNGb3VuZERpcmVjdGl2ZTtcblxuICAvKiogQ3VycmVudCBzZWFyY2ggdmFsdWUgKi9cbiAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2Zvcm1Db250cm9sLnZhbHVlO1xuICB9XG4gIHByaXZhdGUgX2xhc3RFeHRlcm5hbElucHV0VmFsdWU6IHN0cmluZztcblxuICBvblRvdWNoZWQ6IEZ1bmN0aW9uID0gKF86IGFueSkgPT4geyB9O1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIE1hdFNlbGVjdCBvcHRpb25zICovXG4gIHB1YmxpYyBzZXQgX29wdGlvbnMoX29wdGlvbnM6IFF1ZXJ5TGlzdDxNYXRPcHRpb24+KSB7XG4gICAgdGhpcy5fb3B0aW9ucyQubmV4dChfb3B0aW9ucyk7XG4gIH1cbiAgcHVibGljIGdldCBfb3B0aW9ucygpOiBRdWVyeUxpc3Q8TWF0T3B0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnMkLmdldFZhbHVlKCk7XG4gIH1cbiAgcHVibGljIF9vcHRpb25zJDogQmVoYXZpb3JTdWJqZWN0PFF1ZXJ5TGlzdDxNYXRPcHRpb24+PiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UXVlcnlMaXN0PE1hdE9wdGlvbj4+KG51bGwpO1xuXG4gIHByaXZhdGUgb3B0aW9uc0xpc3QkOiBPYnNlcnZhYmxlPE1hdE9wdGlvbltdPiA9IHRoaXMuX29wdGlvbnMkLnBpcGUoXG4gICAgc3dpdGNoTWFwKF9vcHRpb25zID0+IF9vcHRpb25zID9cbiAgICAgIF9vcHRpb25zLmNoYW5nZXMucGlwZShcbiAgICAgICAgbWFwKG9wdGlvbnMgPT4gb3B0aW9ucy50b0FycmF5KCkpLFxuICAgICAgICBzdGFydFdpdGg8TWF0T3B0aW9uW10+KF9vcHRpb25zLnRvQXJyYXkoKSksXG4gICAgICApIDogb2YobnVsbClcbiAgICApXG4gICk7XG5cbiAgcHJpdmF0ZSBvcHRpb25zTGVuZ3RoJDogT2JzZXJ2YWJsZTxudW1iZXI+ID0gdGhpcy5vcHRpb25zTGlzdCQucGlwZShcbiAgICBtYXAob3B0aW9ucyA9PiBvcHRpb25zID8gb3B0aW9ucy5sZW5ndGggOiAwKVxuICApO1xuXG4gIC8qKiBQcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlcyB3aGVuIHVzaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+Ki9cbiAgcHJpdmF0ZSBwcmV2aW91c1NlbGVjdGVkVmFsdWVzOiBhbnlbXTtcblxuICBwdWJsaWMgX2Zvcm1Db250cm9sOiBGb3JtQ29udHJvbDxzdHJpbmc+ID0gbmV3IEZvcm1Db250cm9sPHN0cmluZz4oJycpO1xuXG4gIC8qKiB3aGV0aGVyIHRvIHNob3cgdGhlIG5vIGVudHJpZXMgZm91bmQgbWVzc2FnZSAqL1xuICBwdWJsaWMgX3Nob3dOb0VudHJpZXNGb3VuZCQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLl9mb3JtQ29udHJvbC52YWx1ZUNoYW5nZXMsXG4gICAgdGhpcy5vcHRpb25zTGVuZ3RoJFxuICBdKS5waXBlKFxuICAgIG1hcCgoW3ZhbHVlLCBvcHRpb25zTGVuZ3RoXSkgPT4gdGhpcy5ub0VudHJpZXNGb3VuZExhYmVsICYmIHZhbHVlXG4gICAgICAmJiBvcHRpb25zTGVuZ3RoID09PSB0aGlzLmdldE9wdGlvbnNMZW5ndGhPZmZzZXQoKSlcbiAgKTtcblxuICAvKiogU3ViamVjdCB0aGF0IGVtaXRzIHdoZW4gdGhlIGNvbXBvbmVudCBoYXMgYmVlbiBkZXN0cm95ZWQuICovXG4gIHByaXZhdGUgX29uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIFJlZmVyZW5jZSB0byBhY3RpdmUgZGVzY2VuZGFudCBmb3IgQVJJQSBTdXBwb3J0LiAqL1xuICBwcml2YXRlIGFjdGl2ZURlc2NlbmRhbnQ6IEhUTUxFbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoTWF0U2VsZWN0KSBwdWJsaWMgbWF0U2VsZWN0OiBNYXRTZWxlY3QsXG4gICAgcHVibGljIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIF92aWV3cG9ydFJ1bGVyOiBWaWV3cG9ydFJ1bGVyLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTWF0T3B0aW9uKSBwdWJsaWMgbWF0T3B0aW9uOiBNYXRPcHRpb24gPSBudWxsLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTWF0Rm9ybUZpZWxkKSBwdWJsaWMgbWF0Rm9ybUZpZWxkOiBNYXRGb3JtRmllbGQgPSBudWxsLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTUFUX1NFTEVDVFNFQVJDSF9ERUZBVUxUX09QVElPTlMpIGRlZmF1bHRPcHRpb25zPzogTWF0U2VsZWN0U2VhcmNoT3B0aW9uc1xuICApIHtcbiAgICB0aGlzLmFwcGx5RGVmYXVsdE9wdGlvbnMoZGVmYXVsdE9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseURlZmF1bHRPcHRpb25zKGRlZmF1bHRPcHRpb25zOiBNYXRTZWxlY3RTZWFyY2hPcHRpb25zKSB7XG4gICAgaWYgKCFkZWZhdWx0T3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25maWd1cmFibGVEZWZhdWx0T3B0aW9ucykge1xuICAgICAgaWYgKGRlZmF1bHRPcHRpb25zLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgKHRoaXNba2V5XSBhcyBhbnkpID0gZGVmYXVsdE9wdGlvbnNba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICAvLyBzZXQgY3VzdG9tIG1hdC1vcHRpb24gY2xhc3MgaWYgdGhlIGNvbXBvbmVudCB3YXMgcGxhY2VkIGluc2lkZSBhIG1hdC1vcHRpb25cbiAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcbiAgICAgIHRoaXMubWF0T3B0aW9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ2NvbnRhaW5zLW1hdC1zZWxlY3Qtc2VhcmNoJyk7XG4gICAgICB0aGlzLm1hdE9wdGlvbi5fZ2V0SG9zdEVsZW1lbnQoKS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignPG5neC1tYXQtc2VsZWN0LXNlYXJjaD4gbXVzdCBiZSBwbGFjZWQgaW5zaWRlIGEgPG1hdC1vcHRpb24+IGVsZW1lbnQnKTtcbiAgICB9XG5cbiAgICAvLyB3aGVuIHRoZSBzZWxlY3QgZHJvcGRvd24gcGFuZWwgaXMgb3BlbmVkIG9yIGNsb3NlZFxuICAgIHRoaXMubWF0U2VsZWN0Lm9wZW5lZENoYW5nZVxuICAgICAgLnBpcGUoXG4gICAgICAgIGRlbGF5KDEpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgob3BlbmVkKSA9PiB7XG4gICAgICAgIGlmIChvcGVuZWQpIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUlucHV0V2lkdGgoKTtcbiAgICAgICAgICAvLyBmb2N1cyB0aGUgc2VhcmNoIGZpZWxkIHdoZW4gb3BlbmluZ1xuICAgICAgICAgIGlmICghdGhpcy5kaXNhYmxlSW5pdGlhbEZvY3VzKSB7XG4gICAgICAgICAgICB0aGlzLl9mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBjbGVhciBpdCB3aGVuIGNsb3NpbmdcbiAgICAgICAgICBpZiAodGhpcy5jbGVhclNlYXJjaElucHV0KSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuXG4gICAgLy8gc2V0IHRoZSBmaXJzdCBpdGVtIGFjdGl2ZSBhZnRlciB0aGUgb3B0aW9ucyBjaGFuZ2VkXG4gICAgdGhpcy5tYXRTZWxlY3Qub3BlbmVkQ2hhbmdlXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgc3dpdGNoTWFwKChfKSA9PiB7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLm1hdFNlbGVjdC5vcHRpb25zO1xuXG4gICAgICAgIC8vIENsb3N1cmUgdmFyaWFibGUgZm9yIHRyYWNraW5nIHRoZSBtb3N0IHJlY2VudCBmaXJzdCBvcHRpb24uXG4gICAgICAgIC8vIEluIG9yZGVyIHRvIGF2b2lkIGF2b2lkIGNhdXNpbmcgdGhlIGxpc3QgdG9cbiAgICAgICAgLy8gc2Nyb2xsIHRvIHRoZSB0b3Agd2hlbiBvcHRpb25zIGFyZSBhZGRlZCB0byB0aGUgYm90dG9tIG9mXG4gICAgICAgIC8vIHRoZSBsaXN0IChlZzogaW5maW5pdGUgc2Nyb2xsKSwgd2UgY29tcGFyZSBvbmx5XG4gICAgICAgIC8vIHRoZSBjaGFuZ2VzIHRvIHRoZSBmaXJzdCBvcHRpb25zIHRvIGRldGVybWluZSBpZiB3ZVxuICAgICAgICAvLyBzaG91bGQgc2V0IHRoZSBmaXJzdCBpdGVtIGFzIGFjdGl2ZS5cbiAgICAgICAgLy8gVGhpcyBwcmV2ZW50cyB1bm5lY2Vzc2FyeSBzY3JvbGxpbmcgdG8gdGhlIHRvcCBvZiB0aGUgbGlzdFxuICAgICAgICAvLyB3aGVuIG9wdGlvbnMgYXJlIGFwcGVuZGVkLCBidXQgYWxsb3dzIHRoZSBmaXJzdCBpdGVtXG4gICAgICAgIC8vIGluIHRoZSBsaXN0IHRvIGJlIHNldCBhcyBhY3RpdmUgYnkgZGVmYXVsdCB3aGVuIHRoZXJlXG4gICAgICAgIC8vIGlzIG5vIGFjdGl2ZSBzZWxlY3Rpb25cbiAgICAgICAgbGV0IHByZXZpb3VzRmlyc3RPcHRpb24gPSB0aGlzLl9vcHRpb25zLnRvQXJyYXkoKVt0aGlzLmdldE9wdGlvbnNMZW5ndGhPZmZzZXQoKV07XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuY2hhbmdlc1xuICAgICAgICAgIC5waXBlKHRhcCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBhdm9pZCBcImV4cHJlc3Npb24gaGFzIGJlZW4gY2hhbmdlZFwiIGVycm9yXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgUXVlcnlMaXN0IHRvIGFuIGFycmF5XG4gICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLl9vcHRpb25zLnRvQXJyYXkoKTtcblxuICAgICAgICAgICAgICAvLyBUaGUgdHJ1ZSBmaXJzdCBpdGVtIGlzIG9mZnNldCBieSAxXG4gICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRGaXJzdE9wdGlvbiA9IG9wdGlvbnNbdGhpcy5nZXRPcHRpb25zTGVuZ3RoT2Zmc2V0KCldO1xuXG4gICAgICAgICAgICAgIGNvbnN0IGtleU1hbmFnZXIgPSB0aGlzLm1hdFNlbGVjdC5fa2V5TWFuYWdlcjtcbiAgICAgICAgICAgICAgaWYgKGtleU1hbmFnZXIgJiYgdGhpcy5tYXRTZWxlY3QucGFuZWxPcGVuICYmIGN1cnJlbnRGaXJzdE9wdGlvbikge1xuXG4gICAgICAgICAgICAgICAgLy8gc2V0IGZpcnN0IGl0ZW0gYWN0aXZlIGFuZCBpbnB1dCB3aWR0aFxuXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBmaXJzdCBvcHRpb24gaW4gdGhlc2UgY2hhbmdlcyBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgcHJldmlvdXMuXG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3RPcHRpb25Jc0NoYW5nZWQgPSAhcHJldmlvdXNGaXJzdE9wdGlvblxuICAgICAgICAgICAgICAgICAgfHwgIXRoaXMubWF0U2VsZWN0LmNvbXBhcmVXaXRoKHByZXZpb3VzRmlyc3RPcHRpb24udmFsdWUsIGN1cnJlbnRGaXJzdE9wdGlvbi52YWx1ZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDQVNFOiBUaGUgZmlyc3Qgb3B0aW9uIGlzIGRpZmZlcmVudCBub3cuXG4gICAgICAgICAgICAgICAgLy8gSW5kaWNpYXRlcyB3ZSBzaG91bGQgc2V0IGl0IGFzIGFjdGl2ZSBhbmQgc2Nyb2xsIHRvIHRoZSB0b3AuXG4gICAgICAgICAgICAgICAgaWYgKGZpcnN0T3B0aW9uSXNDaGFuZ2VkXG4gICAgICAgICAgICAgICAgICB8fCAha2V5TWFuYWdlci5hY3RpdmVJdGVtXG4gICAgICAgICAgICAgICAgICB8fCAhb3B0aW9ucy5maW5kKG9wdGlvbiA9PiB0aGlzLm1hdFNlbGVjdC5jb21wYXJlV2l0aChvcHRpb24udmFsdWUsIGtleU1hbmFnZXIuYWN0aXZlSXRlbS52YWx1ZSkpKSB7XG4gICAgICAgICAgICAgICAgICBrZXlNYW5hZ2VyLnNldEFjdGl2ZUl0ZW0odGhpcy5nZXRPcHRpb25zTGVuZ3RoT2Zmc2V0KCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHdhaXQgZm9yIHBhbmVsIHdpZHRoIGNoYW5nZXNcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSW5wdXRXaWR0aCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gVXBkYXRlIG91ciByZWZlcmVuY2VcbiAgICAgICAgICAgICAgcHJldmlvdXNGaXJzdE9wdGlvbiA9IGN1cnJlbnRGaXJzdE9wdGlvbjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICAgICAgLnN1YnNjcmliZSgpO1xuXG4gICAgLy8gYWRkIG9yIHJlbW92ZSBjc3MgY2xhc3MgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdG8gc2hvdyB0aGUgbm8gZW50cmllcyBmb3VuZCBtZXNzYWdlXG4gICAgLy8gbm90ZTogdGhpcyBpcyBoYWNreVxuICAgIHRoaXMuX3Nob3dOb0VudHJpZXNGb3VuZCQucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpXG4gICAgKS5zdWJzY3JpYmUoc2hvd05vRW50cmllc0ZvdW5kID0+IHtcbiAgICAgIC8vIHNldCBubyBlbnRyaWVzIGZvdW5kIGNsYXNzIG9uIG1hdCBvcHRpb25cbiAgICAgIGlmICh0aGlzLm1hdE9wdGlvbikge1xuICAgICAgICBpZiAoc2hvd05vRW50cmllc0ZvdW5kKSB7XG4gICAgICAgICAgdGhpcy5tYXRPcHRpb24uX2dldEhvc3RFbGVtZW50KCkuY2xhc3NMaXN0LmFkZCgnbWF0LXNlbGVjdC1zZWFyY2gtbm8tZW50cmllcy1mb3VuZCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gcmVzaXplIHRoZSBpbnB1dCB3aWR0aCB3aGVuIHRoZSB2aWV3cG9ydCBpcyByZXNpemVkLCBpLmUuIHRoZSB0cmlnZ2VyIHdpZHRoIGNvdWxkIHBvdGVudGlhbGx5IGJlIHJlc2l6ZWRcbiAgICB0aGlzLl92aWV3cG9ydFJ1bGVyLmNoYW5nZSgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QucGFuZWxPcGVuKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVJbnB1dFdpZHRoKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgdGhpcy5pbml0TXVsdGlwbGVIYW5kbGluZygpO1xuXG4gICAgdGhpcy5vcHRpb25zTGlzdCQucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgLy8gdXBkYXRlIHZpZXcgd2hlbiBhdmFpbGFibGUgb3B0aW9ucyBjaGFuZ2VcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBfZW1pdFNlbGVjdEFsbEJvb2xlYW5Ub1BhcmVudChzdGF0ZTogYm9vbGVhbikge1xuICAgIHRoaXMudG9nZ2xlQWxsLmVtaXQoc3RhdGUpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fb25EZXN0cm95Lm5leHQoKTtcbiAgICB0aGlzLl9vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgfVxuXG4gIF9pc1RvZ2dsZUFsbENoZWNrYm94VmlzaWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tYXRTZWxlY3QubXVsdGlwbGUgJiYgdGhpcy5zaG93VG9nZ2xlQWxsQ2hlY2tib3g7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUga2V5IGRvd24gZXZlbnQgd2l0aCBNYXRTZWxlY3QuXG4gICAqIEFsbG93cyBlLmcuIHNlbGVjdGluZyB3aXRoIGVudGVyIGtleSwgbmF2aWdhdGlvbiB3aXRoIGFycm93IGtleXMsIGV0Yy5cbiAgICogQHBhcmFtIGV2ZW50XG4gICAqL1xuICBfaGFuZGxlS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIC8vIFByZXZlbnQgcHJvcGFnYXRpb24gZm9yIGFsbCBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBpbiBvcmRlciB0byBhdm9pZCBzZWxlY3Rpb24gaXNzdWVzXG4gICAgaWYgKChldmVudC5rZXkgJiYgZXZlbnQua2V5Lmxlbmd0aCA9PT0gMSkgfHxcbiAgICAgIChldmVudC5rZXlDb2RlID49IEEgJiYgZXZlbnQua2V5Q29kZSA8PSBaKSB8fFxuICAgICAgKGV2ZW50LmtleUNvZGUgPj0gWkVSTyAmJiBldmVudC5rZXlDb2RlIDw9IE5JTkUpIHx8XG4gICAgICAoZXZlbnQua2V5Q29kZSA9PT0gU1BBQ0UpXG4gICAgICB8fCAodGhpcy5wcmV2ZW50SG9tZUVuZEtleVByb3BhZ2F0aW9uICYmIChldmVudC5rZXlDb2RlID09PSBIT01FIHx8IGV2ZW50LmtleUNvZGUgPT09IEVORCkpXG4gICAgKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXRTZWxlY3QubXVsdGlwbGUgJiYgZXZlbnQua2V5ICYmIGV2ZW50LmtleUNvZGUgPT09IEVOVEVSKSB7XG4gICAgICAvLyBSZWdhaW4gZm9jdXMgYWZ0ZXIgbXVsdGlzZWxlY3QsIHNvIHdlIGNhbiBmdXJ0aGVyIHR5cGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fZm9jdXMoKSk7XG4gICAgfVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlIGlmIGNsaWNrIEVzY2FwZSwgaWYgaW5wdXQgaXMgZW1wdHksIGNsb3NlIHRoZSBkcm9wZG93biwgaWYgbm90LCBlbXB0eSBvdXQgdGhlIHNlYXJjaCBmaWVsZFxuICAgIGlmICh0aGlzLmVuYWJsZUNsZWFyT25Fc2NhcGVQcmVzc2VkID09PSB0cnVlICYmIGV2ZW50LmtleUNvZGUgPT09IEVTQ0FQRSAmJiB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLl9yZXNldCh0cnVlKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBrZXkgdXAgZXZlbnQgd2l0aCBNYXRTZWxlY3QuXG4gICAqIEFsbG93cyBlLmcuIHRoZSBhbm5vdW5jaW5nIG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlRGVzY2VuZGFudCBieSBzY3JlZW4gcmVhZGVycy5cbiAgICovXG4gIF9oYW5kbGVLZXl1cChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5rZXlDb2RlID09PSBVUF9BUlJPVyB8fCBldmVudC5rZXlDb2RlID09PSBET1dOX0FSUk9XKSB7XG4gICAgICBjb25zdCBhcmlhQWN0aXZlRGVzY2VuZGFudElkID0gdGhpcy5tYXRTZWxlY3QuX2dldEFyaWFBY3RpdmVEZXNjZW5kYW50KCk7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuX29wdGlvbnMudG9BcnJheSgpLmZpbmRJbmRleChpdGVtID0+IGl0ZW0uaWQgPT09IGFyaWFBY3RpdmVEZXNjZW5kYW50SWQpO1xuICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICB0aGlzLnVuc2VsZWN0QWN0aXZlRGVzY2VuZGFudCgpO1xuICAgICAgICB0aGlzLmFjdGl2ZURlc2NlbmRhbnQgPSB0aGlzLl9vcHRpb25zLnRvQXJyYXkoKVtpbmRleF0uX2dldEhvc3RFbGVtZW50KCk7XG4gICAgICAgIHRoaXMuYWN0aXZlRGVzY2VuZGFudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCAndHJ1ZScpO1xuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnLCBhcmlhQWN0aXZlRGVzY2VuZGFudElkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sYXN0RXh0ZXJuYWxJbnB1dFZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5fZm9ybUNvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvbkJsdXIoKSB7XG4gICAgdGhpcy51bnNlbGVjdEFjdGl2ZURlc2NlbmRhbnQoKTtcbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICB0aGlzLl9mb3JtQ29udHJvbC52YWx1ZUNoYW5nZXMucGlwZShcbiAgICAgIGZpbHRlcih2YWx1ZSA9PiB2YWx1ZSAhPT0gdGhpcy5fbGFzdEV4dGVybmFsSW5wdXRWYWx1ZSksXG4gICAgICB0YXAoKCkgPT4gdGhpcy5fbGFzdEV4dGVybmFsSW5wdXRWYWx1ZSA9IHVuZGVmaW5lZCksXG4gICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KVxuICAgICkuc3Vic2NyaWJlKGZuKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbikge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICAvKipcbiAgICogRm9jdXNlcyB0aGUgc2VhcmNoIGlucHV0IGZpZWxkXG4gICAqL1xuICBwdWJsaWMgX2ZvY3VzKCkge1xuICAgIGlmICghdGhpcy5zZWFyY2hTZWxlY3RJbnB1dCB8fCAhdGhpcy5tYXRTZWxlY3QucGFuZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gc2F2ZSBhbmQgcmVzdG9yZSBzY3JvbGxUb3Agb2YgcGFuZWwsIHNpbmNlIGl0IHdpbGwgYmUgcmVzZXQgYnkgZm9jdXMoKVxuICAgIC8vIG5vdGU6IHRoaXMgaXMgaGFja3lcbiAgICBjb25zdCBwYW5lbCA9IHRoaXMubWF0U2VsZWN0LnBhbmVsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3Qgc2Nyb2xsVG9wID0gcGFuZWwuc2Nyb2xsVG9wO1xuXG4gICAgLy8gZm9jdXNcbiAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblxuICAgIHBhbmVsLnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldHMgdGhlIGN1cnJlbnQgc2VhcmNoIHZhbHVlXG4gICAqIEBwYXJhbSBmb2N1cyB3aGV0aGVyIHRvIGZvY3VzIGFmdGVyIHJlc2V0dGluZ1xuICAgKi9cbiAgcHVibGljIF9yZXNldChmb2N1cz86IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9mb3JtQ29udHJvbC5zZXRWYWx1ZSgnJyk7XG4gICAgaWYgKGZvY3VzKSB7XG4gICAgICB0aGlzLl9mb2N1cygpO1xuICAgIH1cbiAgfVxuXG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIGhhbmRsaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+XG4gICAqIE5vdGU6IHRvIGltcHJvdmUgdGhpcyBjb2RlLCBtYXQtc2VsZWN0IHNob3VsZCBiZSBleHRlbmRlZCB0byBhbGxvdyBkaXNhYmxpbmcgcmVzZXR0aW5nIHRoZSBzZWxlY3Rpb24gd2hpbGUgZmlsdGVyaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0TXVsdGlwbGVIYW5kbGluZygpIHtcbiAgICBpZiAoIXRoaXMubWF0U2VsZWN0Lm5nQ29udHJvbCkge1xuICAgICAgaWYgKHRoaXMubWF0U2VsZWN0Lm11bHRpcGxlKSB7XG4gICAgICAgIC8vIG5vdGU6IHRoZSBhY2Nlc3MgdG8gbWF0U2VsZWN0Lm5nQ29udHJvbCAoaW5zdGVhZCBvZiBtYXRTZWxlY3QudmFsdWUgLyBtYXRTZWxlY3QudmFsdWVDaGFuZ2VzKVxuICAgICAgICAvLyBpcyBuZWNlc3NhcnkgdG8gcHJvcGVybHkgd29yayBpbiBtdWx0aS1zZWxlY3Rpb24gbW9kZS5cbiAgICAgICAgY29uc29sZS5lcnJvcigndGhlIG1hdC1zZWxlY3QgY29udGFpbmluZyBuZ3gtbWF0LXNlbGVjdC1zZWFyY2ggbXVzdCBoYXZlIGEgbmdNb2RlbCBvciBmb3JtQ29udHJvbCBkaXJlY3RpdmUgd2hlbiBtdWx0aXBsZT10cnVlJyk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGlmIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+XG4gICAgLy8gc3RvcmUgcHJldmlvdXNseSBzZWxlY3RlZCB2YWx1ZXMgYW5kIHJlc3RvcmUgdGhlbSB3aGVuIHRoZXkgYXJlIGRlc2VsZWN0ZWRcbiAgICAvLyBiZWNhdXNlIHRoZSBvcHRpb24gaXMgbm90IGF2YWlsYWJsZSB3aGlsZSB3ZSBhcmUgY3VycmVudGx5IGZpbHRlcmluZ1xuICAgIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcyA9IHRoaXMubWF0U2VsZWN0Lm5nQ29udHJvbC52YWx1ZTtcblxuICAgIHRoaXMubWF0U2VsZWN0Lm5nQ29udHJvbC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWVzKSA9PiB7XG4gICAgICAgIGxldCByZXN0b3JlU2VsZWN0ZWRWYWx1ZXMgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMubWF0U2VsZWN0Lm11bHRpcGxlKSB7XG4gICAgICAgICAgaWYgKCh0aGlzLmFsd2F5c1Jlc3RvcmVTZWxlY3RlZE9wdGlvbnNNdWx0aSB8fCAodGhpcy5fZm9ybUNvbnRyb2wudmFsdWUgJiYgdGhpcy5fZm9ybUNvbnRyb2wudmFsdWUubGVuZ3RoKSlcbiAgICAgICAgICAgICYmIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcyAmJiBBcnJheS5pc0FycmF5KHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcykpIHtcbiAgICAgICAgICAgIGlmICghdmFsdWVzIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgdmFsdWVzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBvcHRpb25WYWx1ZXMgPSB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLm1hcChvcHRpb24gPT4gb3B0aW9uLnZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcy5mb3JFYWNoKHByZXZpb3VzVmFsdWUgPT4ge1xuICAgICAgICAgICAgICBpZiAoIXZhbHVlcy5zb21lKHYgPT4gdGhpcy5tYXRTZWxlY3QuY29tcGFyZVdpdGgodiwgcHJldmlvdXNWYWx1ZSkpXG4gICAgICAgICAgICAgICAgJiYgIW9wdGlvblZhbHVlcy5zb21lKHYgPT4gdGhpcy5tYXRTZWxlY3QuY29tcGFyZVdpdGgodiwgcHJldmlvdXNWYWx1ZSkpKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgYSB2YWx1ZSB0aGF0IHdhcyBzZWxlY3RlZCBiZWZvcmUgaXMgZGVzZWxlY3RlZCBhbmQgbm90IGZvdW5kIGluIHRoZSBvcHRpb25zLCBpdCB3YXMgZGVzZWxlY3RlZFxuICAgICAgICAgICAgICAgIC8vIGR1ZSB0byB0aGUgZmlsdGVyaW5nLCBzbyB3ZSByZXN0b3JlIGl0LlxuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHByZXZpb3VzVmFsdWUpO1xuICAgICAgICAgICAgICAgIHJlc3RvcmVTZWxlY3RlZFZhbHVlcyA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMgPSB2YWx1ZXM7XG5cbiAgICAgICAgaWYgKHJlc3RvcmVTZWxlY3RlZFZhbHVlcykge1xuICAgICAgICAgIHRoaXMubWF0U2VsZWN0Ll9vbkNoYW5nZSh2YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAgU2V0IHRoZSB3aWR0aCBvZiB0aGUgaW5uZXJTZWxlY3RTZWFyY2ggdG8gZml0IGV2ZW4gY3VzdG9tIHNjcm9sbGJhcnNcbiAgICogIEFuZCBzdXBwb3J0IGFsbCBPcGVyYXRpb24gU3lzdGVtc1xuICAgKi9cbiAgcHVibGljIHVwZGF0ZUlucHV0V2lkdGgoKSB7XG4gICAgaWYgKCF0aGlzLmlubmVyU2VsZWN0U2VhcmNoIHx8ICF0aGlzLmlubmVyU2VsZWN0U2VhcmNoLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gdGhpcy5pbm5lclNlbGVjdFNlYXJjaC5uYXRpdmVFbGVtZW50O1xuICAgIGxldCBwYW5lbEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ21hdC1zZWxlY3QtcGFuZWwnKSkge1xuICAgICAgICBwYW5lbEVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBhbmVsRWxlbWVudCkge1xuICAgICAgdGhpcy5pbm5lclNlbGVjdFNlYXJjaC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gcGFuZWxFbGVtZW50LmNsaWVudFdpZHRoICsgJ3B4JztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHRoZSBvZmZzZXQgdG8gbGVuZ3RoIHRoYXQgY2FuIGJlIGNhdXNlZCBieSB0aGUgb3B0aW9uYWwgbWF0T3B0aW9uIHVzZWQgYXMgYSBzZWFyY2ggaW5wdXQuXG4gICAqL1xuICBwcml2YXRlIGdldE9wdGlvbnNMZW5ndGhPZmZzZXQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVuc2VsZWN0QWN0aXZlRGVzY2VuZGFudCgpIHtcbiAgICB0aGlzLmFjdGl2ZURlc2NlbmRhbnQ/LnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1zZWxlY3RlZCcpO1xuICAgIHRoaXMuc2VhcmNoU2VsZWN0SW5wdXQubmF0aXZlRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcpO1xuICB9XG5cbn1cbiIsIjwhLS1cbkNvcHlyaWdodCAoYykgMjAxOCBCaXRob3N0IEdtYkggQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbmZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2Vcbi0tPlxuPCEtLSBQbGFjZWhvbGRlciB0byBhZGp1c3QgdmVydGljYWwgb2Zmc2V0IG9mIHRoZSBtYXQtb3B0aW9uIGVsZW1lbnRzIC0tPlxuPGlucHV0IG1hdElucHV0IGNsYXNzPVwibWF0LXNlbGVjdC1zZWFyY2gtaW5wdXQgbWF0LXNlbGVjdC1zZWFyY2gtaGlkZGVuXCIvPlxuXG48IS0tIE5vdGU6IHRoZSAgbWF0LWRhdGVwaWNrZXItY29udGVudCBtYXQtdGFiLWhlYWRlciBhcmUgbmVlZGVkIHRvIGluaGVyaXQgdGhlIG1hdGVyaWFsIHRoZW1lIGNvbG9ycywgc2VlIFBSICMyMiAtLT5cbjxkaXZcbiAgICAgICNpbm5lclNlbGVjdFNlYXJjaFxuICAgICAgY2xhc3M9XCJtYXQtc2VsZWN0LXNlYXJjaC1pbm5lciBtYXQtdHlwb2dyYXBoeSBtYXQtZGF0ZXBpY2tlci1jb250ZW50IG1hdC10YWItaGVhZGVyXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsnbWF0LXNlbGVjdC1zZWFyY2gtaW5uZXItbXVsdGlwbGUnOiBtYXRTZWxlY3QubXVsdGlwbGUsICdtYXQtc2VsZWN0LXNlYXJjaC1pbm5lci10b2dnbGUtYWxsJzogX2lzVG9nZ2xlQWxsQ2hlY2tib3hWaXNpYmxlKCkgfVwiPlxuXG4gIDxkaXYgY2xhc3M9XCJtYXQtc2VsZWN0LXNlYXJjaC1pbm5lci1yb3dcIj5cbiAgICA8bWF0LWNoZWNrYm94ICpuZ0lmPVwiX2lzVG9nZ2xlQWxsQ2hlY2tib3hWaXNpYmxlKClcIlxuICAgICAgICAgICAgICAgICAgW2NvbG9yXT1cIm1hdEZvcm1GaWVsZD8uY29sb3JcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtYXQtc2VsZWN0LXNlYXJjaC10b2dnbGUtYWxsLWNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInRvZ2dsZUFsbENoZWNrYm94Q2hlY2tlZFwiXG4gICAgICAgICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJ0b2dnbGVBbGxDaGVja2JveEluZGV0ZXJtaW5hdGVcIlxuICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwidG9nZ2xlQWxsQ2hlY2tib3hUb29sdGlwTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICBtYXRUb29sdGlwQ2xhc3M9XCJuZ3gtbWF0LXNlbGVjdC1zZWFyY2gtdG9nZ2xlLWFsbC10b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwUG9zaXRpb25dPVwidG9nZ2xlQWxsQ2hlY2tib3hUb29sdGlwUG9zaXRpb25cIlxuICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJfZW1pdFNlbGVjdEFsbEJvb2xlYW5Ub1BhcmVudCgkZXZlbnQuY2hlY2tlZClcIlxuICAgID48L21hdC1jaGVja2JveD5cblxuICAgIDxpbnB1dCBjbGFzcz1cIm1hdC1zZWxlY3Qtc2VhcmNoLWlucHV0XCJcbiAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgW3R5cGVdPVwidHlwZVwiXG4gICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJfZm9ybUNvbnRyb2xcIlxuICAgICAgICAgICAjc2VhcmNoU2VsZWN0SW5wdXRcbiAgICAgICAgICAgKGtleWRvd24pPVwiX2hhbmRsZUtleWRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgIChrZXl1cCk9XCJfaGFuZGxlS2V5dXAoJGV2ZW50KVwiXG4gICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcbiAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyTGFiZWxcIlxuICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG4gICAgLz5cbiAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJzZWFyY2hpbmdcIlxuICAgICAgICAgICAgY2xhc3M9XCJtYXQtc2VsZWN0LXNlYXJjaC1zcGlubmVyXCJcbiAgICAgICAgICAgIGRpYW1ldGVyPVwiMTZcIj48L21hdC1zcGlubmVyPlxuXG4gICAgPGJ1dHRvbiAqbmdJZj1cIiFoaWRlQ2xlYXJTZWFyY2hCdXR0b24gJiYgdmFsdWUgJiYgIXNlYXJjaGluZ1wiXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbGVhclwiXG4gICAgICAgICAgICAoY2xpY2spPVwiX3Jlc2V0KHRydWUpXCJcbiAgICAgICAgICAgIGNsYXNzPVwibWF0LXNlbGVjdC1zZWFyY2gtY2xlYXJcIj5cbiAgICAgIDxuZy1jb250ZW50ICpuZ0lmPVwiY2xlYXJJY29uOyBlbHNlIGRlZmF1bHRJY29uXCIgc2VsZWN0PVwiW25neE1hdFNlbGVjdFNlYXJjaENsZWFyXVwiPjwvbmctY29udGVudD5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEljb24+XG4gICAgICAgIDxtYXQtaWNvbiBbc3ZnSWNvbl09XCJjbG9zZVN2Z0ljb25cIj5cbiAgICAgICAgICB7eyFjbG9zZVN2Z0ljb24gPyBjbG9zZUljb24gOiBudWxsfX1cbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9idXR0b24+XG5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCIubWF0LXNlbGVjdC1zZWFyY2gtY3VzdG9tLWhlYWRlci1jb250ZW50XCI+PC9uZy1jb250ZW50PlxuICA8L2Rpdj5cblxuICA8bWF0LWRpdmlkZXI+PC9tYXQtZGl2aWRlcj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwiX3Nob3dOb0VudHJpZXNGb3VuZCQgfCBhc3luY1wiXG4gICAgIGNsYXNzPVwibWF0LXNlbGVjdC1zZWFyY2gtbm8tZW50cmllcy1mb3VuZFwiPlxuICA8bmctY29udGVudCAqbmdJZj1cIm5vRW50cmllc0ZvdW5kOyBlbHNlIGRlZmF1bHROb0VudHJpZXNGb3VuZFwiXG4gICAgICAgICAgICAgIHNlbGVjdD1cIltuZ3hNYXRTZWxlY3ROb0VudHJpZXNGb3VuZF1cIj48L25nLWNvbnRlbnQ+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdE5vRW50cmllc0ZvdW5kPnt7bm9FbnRyaWVzRm91bmRMYWJlbH19PC9uZy10ZW1wbGF0ZT5cbjwvZGl2PlxuXG4iXX0=