UNPKG

fundamental-ngx

Version:

SAP Fundamentals, implemented in Angular

567 lines 36.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, EventEmitter, forwardRef, Input, Output, QueryList, TemplateRef, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { MenuItemDirective } from '../menu/menu-item.directive'; import { MenuKeyboardService } from '../menu/menu-keyboard.service'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; /** * Allows users to filter through results and select a value. * * Supports Angular Forms. */ var ComboboxComponent = /** @class */ (function () { function ComboboxComponent(menuKeyboardService) { this.menuKeyboardService = menuKeyboardService; /** * Values to be filtered in the search input. */ this.dropdownValues = []; /** * Filter function. Accepts an array of objects and a search term as arguments * and returns a string. See search input examples for details. */ this.filterFn = this.defaultFilter; /** * Icon to display in the right-side button. */ this.glyph = 'navigation-down-arrow'; /** * Max height of the popover. Any overflowing elements will be accessible through scrolling. */ this.maxHeight = '200px'; /** * Whether the search input should be displayed in compact mode. */ this.compact = false; /** * Whether the matching string should be highlighted during filtration. */ this.highlighting = true; /** * Whether the popover should close when a user selects a result. */ this.closeOnSelect = true; /** * Whether the input field should be populated with the result picked by the user. */ this.fillOnSelect = true; /** * Display function. Accepts an object of the same type as the * items passed to dropdownValues as argument, and outputs a string. * An arrow function can be used to access the *this* keyword in the calling component. * See search input examples for details. */ this.displayFn = this.defaultDisplay; /** * Event emitted when an item is clicked. Use *$event* to retrieve it. */ this.itemClicked = new EventEmitter(); /** * @hidden */ this.displayedValues = []; /** * @hidden */ this.isOpen = false; /** * @hidden */ this.onDestroy$ = new Subject(); /** * @hidden */ this.onChange = (/** * @return {?} */ function () { }); /** * @hidden */ this.onTouched = (/** * @return {?} */ function () { }); } /** @hidden */ /** * @hidden * @return {?} */ ComboboxComponent.prototype.ngOnInit = /** * @hidden * @return {?} */ function () { if (this.dropdownValues) { this.displayedValues = this.dropdownValues; } }; /** @hidden */ /** * @hidden * @param {?} changes * @return {?} */ ComboboxComponent.prototype.ngOnChanges = /** * @hidden * @param {?} changes * @return {?} */ function (changes) { if (this.dropdownValues && (changes.dropdownValues || changes.searchTerm)) { if (this.inputText) { this.displayedValues = this.filterFn(this.dropdownValues, this.inputText); } else { this.displayedValues = this.dropdownValues; } } }; /** * @return {?} */ ComboboxComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.onDestroy$.next(); this.onDestroy$.complete(); }; /** @hidden */ /** * @hidden * @return {?} */ ComboboxComponent.prototype.ngAfterViewInit = /** * @hidden * @return {?} */ function () { var _this = this; this.menuKeyboardService.itemClicked .pipe(takeUntil(this.onDestroy$)) .subscribe((/** * @param {?} index * @return {?} */ function (index) { return _this.onMenuClickHandler(index); })); this.menuKeyboardService.focusEscapeBeforeList = (/** * @return {?} */ function () { return _this.searchInputElement.nativeElement.focus(); }); this.menuKeyboardService.focusEscapeAfterList = (/** * @return {?} */ function () { }); }; /** @hidden */ /** * @hidden * @param {?} event * @return {?} */ ComboboxComponent.prototype.onInputKeydownHandler = /** * @hidden * @param {?} event * @return {?} */ function (event) { if (event.code === 'Enter' && this.searchFunction) { this.searchFunction(); } else if (event.code === 'ArrowDown') { event.preventDefault(); if (this.menuItems && this.menuItems.first) { this.menuItems.first.focus(); } } }; /** @hidden */ /** * @hidden * @return {?} */ ComboboxComponent.prototype.onInputKeyupHandler = /** * @hidden * @return {?} */ function () { if (this.inputText && this.inputText.length) { this.isOpen = true; } }; /** @hidden */ /** * @hidden * @param {?} event * @param {?} index * @return {?} */ ComboboxComponent.prototype.onMenuKeydownHandler = /** * @hidden * @param {?} event * @param {?} index * @return {?} */ function (event, index) { this.menuKeyboardService.keyDownHandler(event, index, this.menuItems.toArray()); }; /** @hidden */ /** * @hidden * @param {?} index * @return {?} */ ComboboxComponent.prototype.onMenuClickHandler = /** * @hidden * @param {?} index * @return {?} */ function (index) { /** @type {?} */ var selectedItem = this.displayedValues[index]; if (selectedItem) { this.handleClickActions(selectedItem); this.itemClicked.emit({ item: selectedItem, index: index }); } }; Object.defineProperty(ComboboxComponent.prototype, "inputText", { /** Get the input text of the input. */ get: /** * Get the input text of the input. * @return {?} */ function () { return this.inputTextValue; }, /** Set the input text of the input. */ set: /** * Set the input text of the input. * @param {?} value * @return {?} */ function (value) { this.inputTextValue = value; this.onChange(value); this.onTouched(); }, enumerable: true, configurable: true }); /** @hidden */ /** * @hidden * @param {?} value * @return {?} */ ComboboxComponent.prototype.writeValue = /** * @hidden * @param {?} value * @return {?} */ function (value) { this.inputTextValue = value; }; /** @hidden */ /** * @hidden * @param {?} fn * @return {?} */ ComboboxComponent.prototype.registerOnChange = /** * @hidden * @param {?} fn * @return {?} */ function (fn) { this.onChange = fn; }; /** @hidden */ /** * @hidden * @param {?} fn * @return {?} */ ComboboxComponent.prototype.registerOnTouched = /** * @hidden * @param {?} fn * @return {?} */ function (fn) { this.onTouched = fn; }; /** @hidden */ /** * @hidden * @return {?} */ ComboboxComponent.prototype.handleSearchTermChange = /** * @hidden * @return {?} */ function () { this.displayedValues = this.filterFn(this.dropdownValues, this.inputText); }; /** @hidden */ /** * @hidden * @return {?} */ ComboboxComponent.prototype.onPrimaryButtonClick = /** * @hidden * @return {?} */ function () { if (this.searchFunction) { this.searchFunction(); } }; /** @hidden */ /** * @hidden * @param {?} isDisabled * @return {?} */ ComboboxComponent.prototype.setDisabledState = /** * @hidden * @param {?} isDisabled * @return {?} */ function (isDisabled) { this.disabled = isDisabled; }; /** * @private * @param {?} str * @return {?} */ ComboboxComponent.prototype.defaultDisplay = /** * @private * @param {?} str * @return {?} */ function (str) { return str; }; /** * @private * @param {?} contentArray * @param {?} searchTerm * @return {?} */ ComboboxComponent.prototype.defaultFilter = /** * @private * @param {?} contentArray * @param {?} searchTerm * @return {?} */ function (contentArray, searchTerm) { var _this = this; /** @type {?} */ var searchLower = searchTerm.toLocaleLowerCase(); return contentArray.filter((/** * @param {?} item * @return {?} */ function (item) { if (item) { return _this.displayFn(item).toLocaleLowerCase().includes(searchLower); } })); }; /** * @private * @param {?} term * @return {?} */ ComboboxComponent.prototype.handleClickActions = /** * @private * @param {?} term * @return {?} */ function (term) { if (this.closeOnSelect) { this.isOpen = false; } if (this.fillOnSelect) { this.inputText = this.displayFn(term); this.handleSearchTermChange(); } }; ComboboxComponent.decorators = [ { type: Component, args: [{ selector: 'fd-combobox', template: "<fd-popover [(isOpen)]=\"isOpen\"\n [fillControlMode]=\"'at-least'\"\n [disabled]=\"disabled\"\n class=\"fd-combobox-popover-custom\"\n [ngClass]=\"{'fd-popover-body--display-none': displayedValues && !displayedValues.length}\">\n <fd-popover-control>\n <div class=\"fd-combobox-control\">\n <div class=\"fd-input-group fd-input-group--after\" [ngClass]=\"{'fd-input-group--compact': compact}\">\n <input #searchInputElement type=\"text\" class=\"fd-input\" [ngClass]=\"{'fd-input--compact': compact}\"\n (keydown)=\"onInputKeydownHandler($event)\"\n (keyup)=\"onInputKeyupHandler()\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"inputText\"\n (ngModelChange)=\"handleSearchTermChange()\"\n placeholder=\"{{placeholder}}\">\n <span class=\"fd-input-group__addon fd-input-group__addon--after fd-input-group__addon--button\">\n <button fd-button\n tabindex=\"-1\"\n type=\"button\"\n [fdType]=\"'light'\"\n [glyph]=\"glyph\"\n [disabled]=\"disabled\"\n (click)=\"onPrimaryButtonClick()\">\n </button>\n </span>\n </div>\n </div>\n </fd-popover-control>\n <fd-popover-body *ngIf=\"displayedValues && displayedValues.length\">\n <fd-menu class=\"fd-combobox-input-menu-overflow\"\n [style.maxHeight]=\"maxHeight\">\n <ng-content></ng-content>\n <ul fd-menu-list>\n <li *ngFor=\"let term of displayedValues; let index = index;\"\n (click)=\"onMenuClickHandler(index)\"\n (keydown)=\"onMenuKeydownHandler($event, index)\"\n fd-menu-item\n tabindex=\"0\">\n <span *ngIf=\"!itemTemplate\"\n [innerHTML]=\"term | displayFnPipe:displayFn | highlight:inputText:highlighting\"\n ></span>\n <ng-container *ngIf=\"itemTemplate\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: term}\"></ng-container>\n </ng-container>\n </li>\n </ul>\n </fd-menu>\n </fd-popover-body>\n</fd-popover>\n\n", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ function () { return ComboboxComponent; })), multi: true }, MenuKeyboardService ], host: { '[class.fd-combobox-custom-class]': 'true', '[class.fd-combobox-input]': 'true' }, encapsulation: ViewEncapsulation.None, styles: [".fd-combobox-custom-class,.fd-combobox-custom-class .fd-combobox-popover-custom{display:block}.fd-combobox-custom-class .fd-combobox-input-menu-overflow{overflow:auto}"] }] } ]; /** @nocollapse */ ComboboxComponent.ctorParameters = function () { return [ { type: MenuKeyboardService } ]; }; ComboboxComponent.propDecorators = { dropdownValues: [{ type: Input }], filterFn: [{ type: Input }], disabled: [{ type: Input }], placeholder: [{ type: Input }], glyph: [{ type: Input }], itemTemplate: [{ type: Input }], maxHeight: [{ type: Input }], searchFunction: [{ type: Input }], compact: [{ type: Input }], highlighting: [{ type: Input }], closeOnSelect: [{ type: Input }], fillOnSelect: [{ type: Input }], displayFn: [{ type: Input }], itemClicked: [{ type: Output }], menuItems: [{ type: ViewChildren, args: [MenuItemDirective,] }], searchInputElement: [{ type: ViewChild, args: ['searchInputElement',] }] }; return ComboboxComponent; }()); export { ComboboxComponent }; if (false) { /** * Values to be filtered in the search input. * @type {?} */ ComboboxComponent.prototype.dropdownValues; /** * Filter function. Accepts an array of objects and a search term as arguments * and returns a string. See search input examples for details. * @type {?} */ ComboboxComponent.prototype.filterFn; /** * Whether the search input is disabled. * * @type {?} */ ComboboxComponent.prototype.disabled; /** * Placeholder of the search input. * * @type {?} */ ComboboxComponent.prototype.placeholder; /** * Icon to display in the right-side button. * @type {?} */ ComboboxComponent.prototype.glyph; /** * The template with which to display the individual listed items. * Use it by passing an ng-template with implicit content. See examples for more info. * @type {?} */ ComboboxComponent.prototype.itemTemplate; /** * Max height of the popover. Any overflowing elements will be accessible through scrolling. * @type {?} */ ComboboxComponent.prototype.maxHeight; /** * Search function to execute when the Enter key is pressed on the main input. * @type {?} */ ComboboxComponent.prototype.searchFunction; /** * Whether the search input should be displayed in compact mode. * @type {?} */ ComboboxComponent.prototype.compact; /** * Whether the matching string should be highlighted during filtration. * @type {?} */ ComboboxComponent.prototype.highlighting; /** * Whether the popover should close when a user selects a result. * @type {?} */ ComboboxComponent.prototype.closeOnSelect; /** * Whether the input field should be populated with the result picked by the user. * @type {?} */ ComboboxComponent.prototype.fillOnSelect; /** * Display function. Accepts an object of the same type as the * items passed to dropdownValues as argument, and outputs a string. * An arrow function can be used to access the *this* keyword in the calling component. * See search input examples for details. * @type {?} */ ComboboxComponent.prototype.displayFn; /** * Event emitted when an item is clicked. Use *$event* to retrieve it. * @type {?} */ ComboboxComponent.prototype.itemClicked; /** * @hidden * @type {?} */ ComboboxComponent.prototype.menuItems; /** * @hidden * @type {?} */ ComboboxComponent.prototype.searchInputElement; /** * @hidden * @type {?} */ ComboboxComponent.prototype.displayedValues; /** * @hidden * @type {?} */ ComboboxComponent.prototype.isOpen; /** * @hidden * @type {?} */ ComboboxComponent.prototype.inputTextValue; /** * @hidden * @type {?} * @private */ ComboboxComponent.prototype.onDestroy$; /** * @hidden * @type {?} */ ComboboxComponent.prototype.onChange; /** * @hidden * @type {?} */ ComboboxComponent.prototype.onTouched; /** * @type {?} * @private */ ComboboxComponent.prototype.menuKeyboardService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm9ib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2NvbWJvYm94L2NvbWJvYm94LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUVILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDTSxXQUFXLEVBQzFCLFNBQVMsRUFDVCxZQUFZLEVBQ1osaUJBQWlCLEVBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBTzNDO0lBNkdJLDJCQUFvQixtQkFBd0M7UUFBeEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjs7OztRQXZGNUQsbUJBQWMsR0FBVSxFQUFFLENBQUM7Ozs7O1FBSzNCLGFBQVEsR0FBYSxJQUFJLENBQUMsYUFBYSxDQUFDOzs7O1FBWXhDLFVBQUssR0FBVyx1QkFBdUIsQ0FBQzs7OztRQVd4QyxjQUFTLEdBQVcsT0FBTyxDQUFDOzs7O1FBUTVCLFlBQU8sR0FBWSxLQUFLLENBQUM7Ozs7UUFJekIsaUJBQVksR0FBWSxJQUFJLENBQUM7Ozs7UUFJN0Isa0JBQWEsR0FBWSxJQUFJLENBQUM7Ozs7UUFJOUIsaUJBQVksR0FBWSxJQUFJLENBQUM7Ozs7Ozs7UUFPN0IsY0FBUyxHQUFhLElBQUksQ0FBQyxjQUFjLENBQUM7Ozs7UUFJMUMsZ0JBQVcsR0FBK0IsSUFB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Ozs7O0lBR3ZCLHVDQUFpRTs7Ozs7SUFHakUscUNBQTBCOzs7OztJQUcxQixzQ0FBMkI7Ozs7O0lBRWYsZ0RBQWdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcywgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3Q2hpbGRyZW4sXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNZW51SXRlbURpcmVjdGl2ZSB9IGZyb20gJy4uL21lbnUvbWVudS1pdGVtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBDb21ib2JveEl0ZW0gfSBmcm9tICcuL2NvbWJvYm94LWl0ZW0nO1xuaW1wb3J0IHsgTWVudUtleWJvYXJkU2VydmljZSB9IGZyb20gJy4uL21lbnUvbWVudS1rZXlib2FyZC5zZXJ2aWNlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuLyoqXG4gKiBBbGxvd3MgdXNlcnMgdG8gZmlsdGVyIHRocm91Z2ggcmVzdWx0cyBhbmQgc2VsZWN0IGEgdmFsdWUuXG4gKlxuICogU3VwcG9ydHMgQW5ndWxhciBGb3Jtcy5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdmZC1jb21ib2JveCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NvbWJvYm94LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jb21ib2JveC5jb21wb25lbnQuc2NzcyddLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IENvbWJvYm94Q29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIE1lbnVLZXlib2FyZFNlcnZpY2VcbiAgICBdLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJ1tjbGFzcy5mZC1jb21ib2JveC1jdXN0b20tY2xhc3NdJzogJ3RydWUnLFxuICAgICAgICAnW2NsYXNzLmZkLWNvbWJvYm94LWlucHV0XSc6ICd0cnVlJ1xuICAgIH0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBDb21ib2JveENvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIC8qKiBWYWx1ZXMgdG8gYmUgZmlsdGVyZWQgaW4gdGhlIHNlYXJjaCBpbnB1dC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRyb3Bkb3duVmFsdWVzOiBhbnlbXSA9IFtdO1xuXG4gICAgLyoqIEZpbHRlciBmdW5jdGlvbi4gQWNjZXB0cyBhbiBhcnJheSBvZiBvYmplY3RzIGFuZCBhIHNlYXJjaCB0ZXJtIGFzIGFyZ3VtZW50c1xuICAgICAqIGFuZCByZXR1cm5zIGEgc3RyaW5nLiBTZWUgc2VhcmNoIGlucHV0IGV4YW1wbGVzIGZvciBkZXRhaWxzLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZmlsdGVyRm46IEZ1bmN0aW9uID0gdGhpcy5kZWZhdWx0RmlsdGVyO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHNlYXJjaCBpbnB1dCBpcyBkaXNhYmxlZC4gKiovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlZDogYm9vbGVhbjtcblxuICAgIC8qKiBQbGFjZWhvbGRlciBvZiB0aGUgc2VhcmNoIGlucHV0LiAqKi9cbiAgICBASW5wdXQoKVxuICAgIHBsYWNlaG9sZGVyOiBzdHJpbmc7XG5cbiAgICAvKiogSWNvbiB0byBkaXNwbGF5IGluIHRoZSByaWdodC1zaWRlIGJ1dHRvbi4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdseXBoOiBzdHJpbmcgPSAnbmF2aWdhdGlvbi1kb3duLWFycm93JztcblxuICAgIC8qKlxuICAgICAqIFRoZSB0ZW1wbGF0ZSB3aXRoIHdoaWNoIHRvIGRpc3BsYXkgdGhlIGluZGl2aWR1YWwgbGlzdGVkIGl0ZW1zLlxuICAgICAqIFVzZSBpdCBieSBwYXNzaW5nIGFuIG5nLXRlbXBsYXRlIHdpdGggaW1wbGljaXQgY29udGVudC4gU2VlIGV4YW1wbGVzIGZvciBtb3JlIGluZm8uXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBpdGVtVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKiogTWF4IGhlaWdodCBvZiB0aGUgcG9wb3Zlci4gQW55IG92ZXJmbG93aW5nIGVsZW1lbnRzIHdpbGwgYmUgYWNjZXNzaWJsZSB0aHJvdWdoIHNjcm9sbGluZy4gKi9cbiAgICBASW5wdXQoKVxuICAgIG1heEhlaWdodDogc3RyaW5nID0gJzIwMHB4JztcblxuICAgIC8qKiBTZWFyY2ggZnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBFbnRlciBrZXkgaXMgcHJlc3NlZCBvbiB0aGUgbWFpbiBpbnB1dC4gKi9cbiAgICBASW5wdXQoKVxuICAgIHNlYXJjaEZ1bmN0aW9uOiBGdW5jdGlvbjtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBzZWFyY2ggaW5wdXQgc2hvdWxkIGJlIGRpc3BsYXllZCBpbiBjb21wYWN0IG1vZGUuICovXG4gICAgQElucHV0KClcbiAgICBjb21wYWN0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKiogV2hldGhlciB0aGUgbWF0Y2hpbmcgc3RyaW5nIHNob3VsZCBiZSBoaWdobGlnaHRlZCBkdXJpbmcgZmlsdHJhdGlvbi4gKi9cbiAgICBASW5wdXQoKVxuICAgIGhpZ2hsaWdodGluZzogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogV2hldGhlciB0aGUgcG9wb3ZlciBzaG91bGQgY2xvc2Ugd2hlbiBhIHVzZXIgc2VsZWN0cyBhIHJlc3VsdC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGNsb3NlT25TZWxlY3Q6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGlucHV0IGZpZWxkIHNob3VsZCBiZSBwb3B1bGF0ZWQgd2l0aCB0aGUgcmVzdWx0IHBpY2tlZCBieSB0aGUgdXNlci4gKi9cbiAgICBASW5wdXQoKVxuICAgIGZpbGxPblNlbGVjdDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogRGlzcGxheSBmdW5jdGlvbi4gQWNjZXB0cyBhbiBvYmplY3Qgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGVcbiAgICAgKiBpdGVtcyBwYXNzZWQgdG8gZHJvcGRvd25WYWx1ZXMgYXMgYXJndW1lbnQsIGFuZCBvdXRwdXRzIGEgc3RyaW5nLlxuICAgICAqIEFuIGFycm93IGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGFjY2VzcyB0aGUgKnRoaXMqIGtleXdvcmQgaW4gdGhlIGNhbGxpbmcgY29tcG9uZW50LlxuICAgICAqIFNlZSBzZWFyY2ggaW5wdXQgZXhhbXBsZXMgZm9yIGRldGFpbHMuICovXG4gICAgQElucHV0KClcbiAgICBkaXNwbGF5Rm46IEZ1bmN0aW9uID0gdGhpcy5kZWZhdWx0RGlzcGxheTtcblxuICAgIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gYW4gaXRlbSBpcyBjbGlja2VkLiBVc2UgKiRldmVudCogdG8gcmV0cmlldmUgaXQuICovXG4gICAgQE91dHB1dCgpXG4gICAgaXRlbUNsaWNrZWQ6IEV2ZW50RW1pdHRlcjxDb21ib2JveEl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxDb21ib2JveEl0ZW0+KCk7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBWaWV3Q2hpbGRyZW4oTWVudUl0ZW1EaXJlY3RpdmUpXG4gICAgbWVudUl0ZW1zOiBRdWVyeUxpc3Q8TWVudUl0ZW1EaXJlY3RpdmU+O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBAVmlld0NoaWxkKCdzZWFyY2hJbnB1dEVsZW1lbnQnKVxuICAgIHNlYXJjaElucHV0RWxlbWVudDogRWxlbWVudFJlZjtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgZGlzcGxheWVkVmFsdWVzOiBhbnlbXSA9IFtdO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgaW5wdXRUZXh0VmFsdWU6IHN0cmluZztcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBvbkRlc3Ryb3kkOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25DaGFuZ2U6IGFueSA9ICgpID0+IHsgfTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25Ub3VjaGVkOiBhbnkgPSAoKSA9PiB7IH07XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lbnVLZXlib2FyZFNlcnZpY2U6IE1lbnVLZXlib2FyZFNlcnZpY2UpIHsgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJvcGRvd25WYWx1ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gdGhpcy5kcm9wZG93blZhbHVlcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBpZiAodGhpcy5kcm9wZG93blZhbHVlcyAmJiAoY2hhbmdlcy5kcm9wZG93blZhbHVlcyB8fCBjaGFuZ2VzLnNlYXJjaFRlcm0pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dFRleHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXllZFZhbHVlcyA9IHRoaXMuZmlsdGVyRm4odGhpcy5kcm9wZG93blZhbHVlcywgdGhpcy5pbnB1dFRleHQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXllZFZhbHVlcyA9IHRoaXMuZHJvcGRvd25WYWx1ZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vbkRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5vbkRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVudUtleWJvYXJkU2VydmljZS5pdGVtQ2xpY2tlZFxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKGluZGV4ID0+IHRoaXMub25NZW51Q2xpY2tIYW5kbGVyKGluZGV4KSk7XG4gICAgICAgIHRoaXMubWVudUtleWJvYXJkU2VydmljZS5mb2N1c0VzY2FwZUJlZm9yZUxpc3QgPSAoKSA9PiB0aGlzLnNlYXJjaElucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgIHRoaXMubWVudUtleWJvYXJkU2VydmljZS5mb2N1c0VzY2FwZUFmdGVyTGlzdCA9ICgpID0+IHsgfTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uSW5wdXRLZXlkb3duSGFuZGxlcihldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0VudGVyJyAmJiB0aGlzLnNlYXJjaEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZ1bmN0aW9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93RG93bicpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5tZW51SXRlbXMgJiYgdGhpcy5tZW51SXRlbXMuZmlyc3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lbnVJdGVtcy5maXJzdC5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbklucHV0S2V5dXBIYW5kbGVyKCkge1xuICAgICAgICBpZiAodGhpcy5pbnB1dFRleHQgJiYgdGhpcy5pbnB1dFRleHQubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uTWVudUtleWRvd25IYW5kbGVyKGV2ZW50OiBLZXlib2FyZEV2ZW50LCBpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMubWVudUtleWJvYXJkU2VydmljZS5rZXlEb3duSGFuZGxlcihldmVudCwgaW5kZXgsIHRoaXMubWVudUl0ZW1zLnRvQXJyYXkoKSk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbk1lbnVDbGlja0hhbmRsZXIoaW5kZXg6IG51bWJlcikge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSB0aGlzLmRpc3BsYXllZFZhbHVlc1tpbmRleF07XG4gICAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xpY2tBY3Rpb25zKHNlbGVjdGVkSXRlbSk7XG4gICAgICAgICAgICB0aGlzLml0ZW1DbGlja2VkLmVtaXQoeyBpdGVtOiBzZWxlY3RlZEl0ZW0sIGluZGV4OiBpbmRleCB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBHZXQgdGhlIGlucHV0IHRleHQgb2YgdGhlIGlucHV0LiAqL1xuICAgIGdldCBpbnB1dFRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0VGV4dFZhbHVlO1xuICAgIH1cblxuICAgIC8qKiBTZXQgdGhlIGlucHV0IHRleHQgb2YgdGhlIGlucHV0LiAqL1xuICAgIHNldCBpbnB1dFRleHQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5pbnB1dFRleHRWYWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xuICAgICAgICB0aGlzLmlucHV0VGV4dFZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICByZWdpc3Rlck9uQ2hhbmdlKGZuKSB7XG4gICAgICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuKSB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBoYW5kbGVTZWFyY2hUZXJtQ2hhbmdlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc3BsYXllZFZhbHVlcyA9IHRoaXMuZmlsdGVyRm4odGhpcy5kcm9wZG93blZhbHVlcywgdGhpcy5pbnB1dFRleHQpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25QcmltYXJ5QnV0dG9uQ2xpY2soKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNlYXJjaEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZ1bmN0aW9uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRlZmF1bHREaXNwbGF5KHN0cjogYW55KTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRlZmF1bHRGaWx0ZXIoY29udGVudEFycmF5OiBhbnlbXSwgc2VhcmNoVGVybTogc3RyaW5nKTogYW55W10ge1xuICAgICAgICBjb25zdCBzZWFyY2hMb3dlciA9IHNlYXJjaFRlcm0udG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGNvbnRlbnRBcnJheS5maWx0ZXIoaXRlbSA9PiB7XG4gICAgICAgICAgICBpZiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRpc3BsYXlGbihpdGVtKS50b0xvY2FsZUxvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaExvd2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVDbGlja0FjdGlvbnModGVybSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jbG9zZU9uU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmZpbGxPblNlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5pbnB1dFRleHQgPSB0aGlzLmRpc3BsYXlGbih0ZXJtKTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlU2VhcmNoVGVybUNoYW5nZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG59XG4iXX0=