UNPKG

fundamental-ngx

Version:

SAP Fiori Fundamentals, implemented in Angular

474 lines 35.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, EventEmitter, forwardRef, HostBinding, Input, Output, QueryList, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { MenuItemDirective } from '../menu/menu-item.directive'; /** * Allows users to filter through results and select. * Can also be customized to execute a search function. * * Supports Angular Forms. */ export class SearchInputComponent { constructor() { /** * 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; /** * Whether the search input is in a shellbar * */ this.inShellbar = false; /** * Icon to display in the right-side button. */ this.glyph = 'search'; /** * 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.highlight = 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.searchInputClass = true; /** * @hidden */ this.shellBarClass = this.inShellbar; /** * @hidden */ this.onChange = (/** * @return {?} */ () => { }); /** * @hidden */ this.onTouched = (/** * @return {?} */ () => { }); } /** * @hidden * @param {?} event * @return {?} */ onInputKeydownHandler(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.itemEl.nativeElement.children[0].focus(); } } } /** * @hidden * @return {?} */ onInputKeyupHandler() { if (this.inputText && this.inputText.length) { this.isOpen = true; } } /** * @hidden * @param {?} event * @param {?=} term * @return {?} */ onMenuKeydownHandler(event, term) { if (event.code === 'Enter' && term) { this.handleClickActions(term); this.itemClicked.emit({ item: term, index: this.dropdownValues.indexOf(term) }); } else if (event.code === 'ArrowDown') { event.preventDefault(); /** @type {?} */ let foundItem = false; /** @type {?} */ const menuItemsArray = this.menuItems.toArray(); menuItemsArray.forEach((/** * @param {?} item * @param {?} index * @return {?} */ (item, index) => { if (document.activeElement === item.itemEl.nativeElement.children[0] && !foundItem) { if (menuItemsArray[index + 1]) { menuItemsArray[index + 1].itemEl.nativeElement.children[0].focus(); } foundItem = true; } })); } else if (event.code === 'ArrowUp') { event.preventDefault(); /** @type {?} */ let foundItem = false; /** @type {?} */ const menuItemsArray = this.menuItems.toArray(); menuItemsArray.forEach((/** * @param {?} item * @param {?} index * @return {?} */ (item, index) => { if (!foundItem) { if (document.activeElement === item.itemEl.nativeElement.children[0] && index === 0) { this.searchInputElement.nativeElement.focus(); foundItem = true; } else if (document.activeElement === item.itemEl.nativeElement.children[0]) { if (menuItemsArray[index - 1]) { menuItemsArray[index - 1].itemEl.nativeElement.children[0].focus(); } foundItem = true; } } })); } } /** * @hidden * @param {?} event * @param {?} term * @return {?} */ onMenuClickHandler(event, term) { if (term) { this.handleClickActions(term); this.itemClicked.emit({ item: term, index: this.dropdownValues.indexOf(term) }); } } /** * @hidden * @param {?} event * @return {?} */ shellbarSearchInputClicked(event) { event.stopPropagation(); } /** * Get the input text of the input. * @return {?} */ get inputText() { return this.inputTextValue; } /** * Set the input text of the input. * @param {?} value * @return {?} */ set inputText(value) { this.inputTextValue = value; this.onChange(value); this.onTouched(); } /** * @hidden * @param {?} value * @return {?} */ writeValue(value) { this.inputTextValue = value; } /** * @hidden * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @hidden * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @private * @param {?} term * @return {?} */ handleClickActions(term) { if (this.closeOnSelect) { this.isOpen = false; } if (this.fillOnSelect) { this.inputText = this.displayFn(term); this.handleSearchTermChange(); } } /** * @hidden * @return {?} */ ngOnInit() { if (this.dropdownValues) { this.displayedValues = this.dropdownValues; } } /** * @hidden * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (this.dropdownValues && (changes.dropdownValues || changes.searchTerm)) { if (this.inputText) { this.displayedValues = this.filterFn(this.dropdownValues, this.inputText); } else { this.displayedValues = this.dropdownValues; } } } /** * @hidden * @return {?} */ handleSearchTermChange() { this.displayedValues = this.filterFn(this.dropdownValues, this.inputText); } /** * @private * @param {?} str * @return {?} */ defaultDisplay(str) { return str; } /** * @private * @param {?} contentArray * @param {?} searchTerm * @return {?} */ defaultFilter(contentArray, searchTerm) { /** @type {?} */ const searchLower = searchTerm.toLocaleLowerCase(); return contentArray.filter((/** * @param {?} item * @return {?} */ item => { if (item) { return this.displayFn(item).toLocaleLowerCase().includes(searchLower); } })); } } SearchInputComponent.decorators = [ { type: Component, args: [{ selector: 'fd-search-input', template: "<fd-popover [(isOpen)]=\"isOpen\"\n [fillControl]=\"true\"\n [disabled]=\"disabled\"\n class=\"fd-search-input-popover-custom\"\n [ngClass]=\"{'fd-popover-body--display-none': displayedValues && !displayedValues.length}\">\n <fd-popover-control>\n <div *ngIf=\"!inShellbar\" 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 type=\"button\" class=\"fd-button--light\" [ngClass]=\"('sap-icon--' + this.glyph)\"></button>\n </span>\n </div>\n </div>\n <div *ngIf=\"inShellbar\" class=\"fd-search-input__control\">\n <button tabindex=\"0\" type=\"button\" class=\"fd-button--shell\" [attr.aria-expanded]=\"isOpen\"\n [ngClass]=\"('sap-icon--' + this.glyph)\"></button>\n <div class=\"fd-search-input__closedcontrol\" [attr.aria-hidden]=\"!isOpen\">\n <div class=\"fd-search-input__controlinput\" [attr.aria-expanded]=\"isOpen\" aria-haspopup=\"true\">\n <input type=\"text\" class=\"fd-input\"\n (keydown)=\"onInputKeydownHandler($event)\"\n (keyup)=\"onInputKeyupHandler()\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"inputText\"\n (ngModelChange)=\"handleSearchTermChange()\"\n placeholder=\"{{placeholder}}\"\n (click)=\"shellbarSearchInputClicked($event)\">\n </div>\n </div>\n </div>\n </fd-popover-control>\n <fd-popover-body *ngIf=\"displayedValues && displayedValues.length\">\n <fd-menu class=\"fd-search-input-menu-overflow\"\n [style.maxHeight]=\"maxHeight\">\n <ul fd-menu-list>\n <li fd-menu-item *ngFor=\"let term of displayedValues\"\n (click)=\"onMenuClickHandler($event, term)\"\n (keydown)=\"onMenuKeydownHandler($event, term)\">\n <a tabindex=\"0\" [innerHTML]=\"term | displayFnPipe:displayFn | highlight:inputText:highlight\"></a>\n </li>\n </ul>\n </fd-menu>\n </fd-popover-body>\n</fd-popover>\n", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => SearchInputComponent)), multi: true } ], host: { class: 'fd-search-input-custom' }, encapsulation: ViewEncapsulation.None, styles: [".fd-search-input-custom .fd-search-input-popover-custom{display:block}.fd-search-input-custom .fd-search-input-menu-overflow{overflow:auto}"] }] } ]; SearchInputComponent.propDecorators = { dropdownValues: [{ type: Input }], filterFn: [{ type: Input }], disabled: [{ type: Input }], placeholder: [{ type: Input }], inShellbar: [{ type: Input }], glyph: [{ type: Input }], maxHeight: [{ type: Input }], searchFunction: [{ type: Input }], compact: [{ type: Input }], highlight: [{ type: Input }], closeOnSelect: [{ type: Input }], fillOnSelect: [{ type: Input }], displayFn: [{ type: Input }], itemClicked: [{ type: Output }], menuItems: [{ type: ViewChildren, args: [MenuItemDirective,] }], searchInputElement: [{ type: ViewChild, args: ['searchInputElement',] }], searchInputClass: [{ type: HostBinding, args: ['class.fd-search-input',] }], shellBarClass: [{ type: HostBinding, args: ['class.fd-search-input--closed',] }] }; if (false) { /** * Values to be filtered in the search input. * @type {?} */ SearchInputComponent.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 {?} */ SearchInputComponent.prototype.filterFn; /** * Whether the search input is disabled. * * @type {?} */ SearchInputComponent.prototype.disabled; /** * Placeholder of the search input. * * @type {?} */ SearchInputComponent.prototype.placeholder; /** * Whether the search input is in a shellbar * * @type {?} */ SearchInputComponent.prototype.inShellbar; /** * Icon to display in the right-side button. * @type {?} */ SearchInputComponent.prototype.glyph; /** * Max height of the popover. Any overflowing elements will be accessible through scrolling. * @type {?} */ SearchInputComponent.prototype.maxHeight; /** * Search function to execute when the Enter key is pressed on the main input. * @type {?} */ SearchInputComponent.prototype.searchFunction; /** * Whether the search input should be displayed in compact mode. * @type {?} */ SearchInputComponent.prototype.compact; /** * Whether the matching string should be highlighted during filtration. * @type {?} */ SearchInputComponent.prototype.highlight; /** * Whether the popover should close when a user selects a result. * @type {?} */ SearchInputComponent.prototype.closeOnSelect; /** * Whether the input field should be populated with the result picked by the user. * @type {?} */ SearchInputComponent.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 {?} */ SearchInputComponent.prototype.displayFn; /** * Event emitted when an item is clicked. Use *$event* to retrieve it. * @type {?} */ SearchInputComponent.prototype.itemClicked; /** * @hidden * @type {?} */ SearchInputComponent.prototype.menuItems; /** * @hidden * @type {?} */ SearchInputComponent.prototype.searchInputElement; /** * @hidden * @type {?} */ SearchInputComponent.prototype.displayedValues; /** * @hidden * @type {?} */ SearchInputComponent.prototype.isOpen; /** * @hidden * @type {?} */ SearchInputComponent.prototype.inputTextValue; /** * @hidden * @type {?} */ SearchInputComponent.prototype.searchInputClass; /** * @hidden * @type {?} */ SearchInputComponent.prototype.shellBarClass; /** * @hidden * @type {?} */ SearchInputComponent.prototype.onChange; /** * @hidden * @type {?} */ SearchInputComponent.prototype.onTouched; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2Z1bmRhbWVudGFsLW5neC8iLCJzb3VyY2VzIjpbImxpYi9zZWFyY2gtaW5wdXQvc2VhcmNoLWlucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsS0FBSyxFQUdMLE1BQU0sRUFDTixTQUFTLEVBRVQsU0FBUyxFQUNULFlBQVksRUFDWixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7Ozs7O0FBd0JoRSxNQUFNLE9BQU8sb0JBQW9CO0lBaEJqQzs7OztRQW9CSSxtQkFBYyxHQUFVLEVBQUUsQ0FBQzs7Ozs7UUFLM0IsYUFBUSxHQUFhLElBQUksQ0FBQyxhQUFhLENBQUM7Ozs7UUFZeEMsZUFBVSxHQUFZLEtBQUssQ0FBQzs7OztRQUk1QixVQUFLLEdBQVcsUUFBUSxDQUFDOzs7O1FBSXpCLGNBQVMsR0FBVyxPQUFPLENBQUM7Ozs7UUFRNUIsWUFBTyxHQUFZLEtBQUssQ0FBQzs7OztRQUl6QixjQUFTLEdBQVksSUFBSSxDQUFDOzs7O1FBSTFCLGtCQUFhLEdBQVksSUFBSSxDQUFDOzs7O1FBSTlCLGlCQUFZLEdBQVksSUFBSSxDQUFDOzs7Ozs7O1FBTzdCLGNBQVMsR0FBYSxJQUFJLENBQUMsY0FBYyxDQUFDOzs7O1FBSTFDLGdCQUFXLEdBQTZDLElBQUksWUFBWSxFQUE4QixDQUFDOzs7O1FBV3ZHLG9CQUFlLEdBQVUsRUFBRSxDQUFDOzs7O1FBRzVCLFdBQU0sR0FBWSxLQUFLLENBQUM7Ozs7UUFPeEIscUJBQWdCLEdBQUcsSUFBSSxDQUFDOzs7O1FBSXhCLGtC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Qjs0QkFJbkMsV0FBVyxTQUFDLCtCQUErQjs7Ozs7OztJQWpGNUMsOENBQzJCOzs7Ozs7SUFJM0Isd0NBQ3dDOzs7OztJQUd4Qyx3Q0FDa0I7Ozs7O0lBR2xCLDJDQUNvQjs7Ozs7SUFHcEIsMENBQzRCOzs7OztJQUc1QixxQ0FDeUI7Ozs7O0lBR3pCLHlDQUM0Qjs7Ozs7SUFHNUIsOENBQ3lCOzs7OztJQUd6Qix1Q0FDeUI7Ozs7O0lBR3pCLHlDQUMwQjs7Ozs7SUFHMUIsNkNBQzhCOzs7OztJQUc5Qiw0Q0FDNkI7Ozs7Ozs7O0lBTTdCLHlDQUMwQzs7Ozs7SUFHMUMsMkNBQ3VHOzs7OztJQUd2Ryx5Q0FDd0M7Ozs7O0lBR3hDLGtEQUMrQjs7Ozs7SUFHL0IsK0NBQTRCOzs7OztJQUc1QixzQ0FBd0I7Ozs7O0lBR3hCLDhDQUF1Qjs7Ozs7SUFHdkIsZ0RBQ3dCOzs7OztJQUd4Qiw2Q0FDZ0M7Ozs7O0lBd0VoQyx3Q0FBeUI7Ozs7O0lBR3pCLHlDQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdDaGlsZHJlbixcbiAgICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1lbnVJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vbWVudS9tZW51LWl0ZW0uZGlyZWN0aXZlJztcblxuLyoqXG4gKiBBbGxvd3MgdXNlcnMgdG8gZmlsdGVyIHRocm91Z2ggcmVzdWx0cyBhbmQgc2VsZWN0LlxuICogQ2FuIGFsc28gYmUgY3VzdG9taXplZCB0byBleGVjdXRlIGEgc2VhcmNoIGZ1bmN0aW9uLlxuICpcbiAqIFN1cHBvcnRzIEFuZ3VsYXIgRm9ybXMuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZmQtc2VhcmNoLWlucHV0JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoLWlucHV0LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zZWFyY2gtaW5wdXQuY29tcG9uZW50LnNjc3MnXSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBTZWFyY2hJbnB1dENvbXBvbmVudCksXG4gICAgICAgICAgICBtdWx0aTogdHJ1ZVxuICAgICAgICB9XG4gICAgXSxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAnZmQtc2VhcmNoLWlucHV0LWN1c3RvbSdcbiAgICB9LFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgU2VhcmNoSW5wdXRDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBPbkNoYW5nZXMge1xuXG4gICAgLyoqIFZhbHVlcyB0byBiZSBmaWx0ZXJlZCBpbiB0aGUgc2VhcmNoIGlucHV0LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZHJvcGRvd25WYWx1ZXM6IGFueVtdID0gW107XG5cbiAgICAvKiogRmlsdGVyIGZ1bmN0aW9uLiBBY2NlcHRzIGFuIGFycmF5IG9mIG9iamVjdHMgYW5kIGEgc2VhcmNoIHRlcm0gYXMgYXJndW1lbnRzXG4gICAgICogYW5kIHJldHVybnMgYSBzdHJpbmcuIFNlZSBzZWFyY2ggaW5wdXQgZXhhbXBsZXMgZm9yIGRldGFpbHMuICovXG4gICAgQElucHV0KClcbiAgICBmaWx0ZXJGbjogRnVuY3Rpb24gPSB0aGlzLmRlZmF1bHRGaWx0ZXI7XG5cbiAgICAvKiogV2hldGhlciB0aGUgc2VhcmNoIGlucHV0IGlzIGRpc2FibGVkLiAqKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVkOiBib29sZWFuO1xuXG4gICAgLyoqIFBsYWNlaG9sZGVyIG9mIHRoZSBzZWFyY2ggaW5wdXQuICoqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2Vob2xkZXI6IHN0cmluZztcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBzZWFyY2ggaW5wdXQgaXMgaW4gYSBzaGVsbGJhciAqKi9cbiAgICBASW5wdXQoKVxuICAgIGluU2hlbGxiYXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBJY29uIHRvIGRpc3BsYXkgaW4gdGhlIHJpZ2h0LXNpZGUgYnV0dG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2x5cGg6IHN0cmluZyA9ICdzZWFyY2gnO1xuXG4gICAgLyoqIE1heCBoZWlnaHQgb2YgdGhlIHBvcG92ZXIuIEFueSBvdmVyZmxvd2luZyBlbGVtZW50cyB3aWxsIGJlIGFjY2Vzc2libGUgdGhyb3VnaCBzY3JvbGxpbmcuICovXG4gICAgQElucHV0KClcbiAgICBtYXhIZWlnaHQ6IHN0cmluZyA9ICcyMDBweCc7XG5cbiAgICAvKiogU2VhcmNoIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgd2hlbiB0aGUgRW50ZXIga2V5IGlzIHByZXNzZWQgb24gdGhlIG1haW4gaW5wdXQuICovXG4gICAgQElucHV0KClcbiAgICBzZWFyY2hGdW5jdGlvbjogRnVuY3Rpb247XG5cbiAgICAvKiogV2hldGhlciB0aGUgc2VhcmNoIGlucHV0IHNob3VsZCBiZSBkaXNwbGF5ZWQgaW4gY29tcGFjdCBtb2RlLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgY29tcGFjdDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIG1hdGNoaW5nIHN0cmluZyBzaG91bGQgYmUgaGlnaGxpZ2h0ZWQgZHVyaW5nIGZpbHRyYXRpb24uICovXG4gICAgQElucHV0KClcbiAgICBoaWdobGlnaHQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgc2hvdWxkIGNsb3NlIHdoZW4gYSB1c2VyIHNlbGVjdHMgYSByZXN1bHQuICovXG4gICAgQElucHV0KClcbiAgICBjbG9zZU9uU2VsZWN0OiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBpbnB1dCBmaWVsZCBzaG91bGQgYmUgcG9wdWxhdGVkIHdpdGggdGhlIHJlc3VsdCBwaWNrZWQgYnkgdGhlIHVzZXIuICovXG4gICAgQElucHV0KClcbiAgICBmaWxsT25TZWxlY3Q6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIERpc3BsYXkgZnVuY3Rpb24uIEFjY2VwdHMgYW4gb2JqZWN0IG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhlXG4gICAgICogaXRlbXMgcGFzc2VkIHRvIGRyb3Bkb3duVmFsdWVzIGFzIGFyZ3VtZW50LCBhbmQgb3V0cHV0cyBhIHN0cmluZy5cbiAgICAgKiBBbiBhcnJvdyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBhY2Nlc3MgdGhlICp0aGlzKiBrZXl3b3JkIGluIHRoZSBjYWxsaW5nIGNvbXBvbmVudC5cbiAgICAgKiBTZWUgc2VhcmNoIGlucHV0IGV4YW1wbGVzIGZvciBkZXRhaWxzLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzcGxheUZuOiBGdW5jdGlvbiA9IHRoaXMuZGVmYXVsdERpc3BsYXk7XG5cbiAgICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIGFuIGl0ZW0gaXMgY2xpY2tlZC4gVXNlICokZXZlbnQqIHRvIHJldHJpZXZlIGl0LiAqL1xuICAgIEBPdXRwdXQoKVxuICAgIGl0ZW1DbGlja2VkOiBFdmVudEVtaXR0ZXI8e2l0ZW06IGFueSwgaW5kZXg6IG51bWJlcn0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7aXRlbTogYW55LCBpbmRleDogbnVtYmVyfT4oKTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQFZpZXdDaGlsZHJlbihNZW51SXRlbURpcmVjdGl2ZSlcbiAgICBtZW51SXRlbXM6IFF1ZXJ5TGlzdDxNZW51SXRlbURpcmVjdGl2ZT47XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBWaWV3Q2hpbGQoJ3NlYXJjaElucHV0RWxlbWVudCcpXG4gICAgc2VhcmNoSW5wdXRFbGVtZW50OiBFbGVtZW50UmVmO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBkaXNwbGF5ZWRWYWx1ZXM6IGFueVtdID0gW107XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGlzT3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBpbnB1dFRleHRWYWx1ZTogc3RyaW5nO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmZkLXNlYXJjaC1pbnB1dCcpXG4gICAgc2VhcmNoSW5wdXRDbGFzcyA9IHRydWU7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZmQtc2VhcmNoLWlucHV0LS1jbG9zZWQnKVxuICAgIHNoZWxsQmFyQ2xhc3MgPSB0aGlzLmluU2hlbGxiYXI7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uSW5wdXRLZXlkb3duSGFuZGxlcihldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0VudGVyJyAmJiB0aGlzLnNlYXJjaEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZ1bmN0aW9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93RG93bicpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5tZW51SXRlbXMgJiYgdGhpcy5tZW51SXRlbXMuZmlyc3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lbnVJdGVtcy5maXJzdC5pdGVtRWwubmF0aXZlRWxlbWVudC5jaGlsZHJlblswXS5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbklucHV0S2V5dXBIYW5kbGVyKCkge1xuICAgICAgICBpZiAodGhpcy5pbnB1dFRleHQgJiYgdGhpcy5pbnB1dFRleHQubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uTWVudUtleWRvd25IYW5kbGVyKGV2ZW50LCB0ZXJtPykge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0VudGVyJyAmJiB0ZXJtKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNsaWNrQWN0aW9ucyh0ZXJtKTtcbiAgICAgICAgICAgIHRoaXMuaXRlbUNsaWNrZWQuZW1pdCh7aXRlbTogdGVybSwgaW5kZXg6IHRoaXMuZHJvcGRvd25WYWx1ZXMuaW5kZXhPZih0ZXJtKX0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmNvZGUgPT09ICdBcnJvd0Rvd24nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgbGV0IGZvdW5kSXRlbSA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgbWVudUl0ZW1zQXJyYXkgPSB0aGlzLm1lbnVJdGVtcy50b0FycmF5KCk7XG4gICAgICAgICAgICBtZW51SXRlbXNBcnJheS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBpdGVtLml0ZW1FbC5uYXRpdmVFbGVtZW50LmNoaWxkcmVuWzBdICYmICFmb3VuZEl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lbnVJdGVtc0FycmF5W2luZGV4ICsgMV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtc0FycmF5W2luZGV4ICsgMV0uaXRlbUVsLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW5bMF0uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3VuZEl0ZW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93VXAnKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgbGV0IGZvdW5kSXRlbSA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgbWVudUl0ZW1zQXJyYXkgPSB0aGlzLm1lbnVJdGVtcy50b0FycmF5KCk7XG4gICAgICAgICAgICBtZW51SXRlbXNBcnJheS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZm91bmRJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBpdGVtLml0ZW1FbC5uYXRpdmVFbGVtZW50LmNoaWxkcmVuWzBdICYmIGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaElucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEl0ZW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IGl0ZW0uaXRlbUVsLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW5bMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZW51SXRlbXNBcnJheVtpbmRleCAtIDFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVudUl0ZW1zQXJyYXlbaW5kZXggLSAxXS5pdGVtRWwubmF0aXZlRWxlbWVudC5jaGlsZHJlblswXS5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRJdGVtID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbk1lbnVDbGlja0hhbmRsZXIoZXZlbnQsIHRlcm0pIHtcbiAgICAgICAgaWYgKHRlcm0pIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xpY2tBY3Rpb25zKHRlcm0pO1xuICAgICAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5lbWl0KHtpdGVtOiB0ZXJtLCBpbmRleDogdGhpcy5kcm9wZG93blZhbHVlcy5pbmRleE9mKHRlcm0pfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHNoZWxsYmFyU2VhcmNoSW5wdXRDbGlja2VkKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25DaGFuZ2U6IGFueSA9ICgpID0+IHt9O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvblRvdWNoZWQ6IGFueSA9ICgpID0+IHt9O1xuXG4gICAgLyoqIEdldCB0aGUgaW5wdXQgdGV4dCBvZiB0aGUgaW5wdXQuICovXG4gICAgZ2V0IGlucHV0VGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXRUZXh0VmFsdWU7XG4gICAgfVxuXG4gICAgLyoqIFNldCB0aGUgaW5wdXQgdGV4dCBvZiB0aGUgaW5wdXQuICovXG4gICAgc2V0IGlucHV0VGV4dCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmlucHV0VGV4dFZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KSB7XG4gICAgICAgIHRoaXMuaW5wdXRUZXh0VmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm4pIHtcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcmVnaXN0ZXJPblRvdWNoZWQoZm4pIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGhhbmRsZUNsaWNrQWN0aW9ucyh0ZXJtKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNsb3NlT25TZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZmlsbE9uU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0VGV4dCA9IHRoaXMuZGlzcGxheUZuKHRlcm0pO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVTZWFyY2hUZXJtQ2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5kcm9wZG93blZhbHVlcykge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRWYWx1ZXMgPSB0aGlzLmRyb3Bkb3duVmFsdWVzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGlmICh0aGlzLmRyb3Bkb3duVmFsdWVzICYmIChjaGFuZ2VzLmRyb3Bkb3duVmFsdWVzIHx8IGNoYW5nZXMuc2VhcmNoVGVybSkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlucHV0VGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gdGhpcy5maWx0ZXJGbih0aGlzLmRyb3Bkb3duVmFsdWVzLCB0aGlzLmlucHV0VGV4dCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gIHRoaXMuZHJvcGRvd25WYWx1ZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGhhbmRsZVNlYXJjaFRlcm1DaGFuZ2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gdGhpcy5maWx0ZXJGbih0aGlzLmRyb3Bkb3duVmFsdWVzLCB0aGlzLmlucHV0VGV4dCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZWZhdWx0RGlzcGxheShzdHI6IGFueSk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZWZhdWx0RmlsdGVyKGNvbnRlbnRBcnJheTogYW55W10sIHNlYXJjaFRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICAgICAgY29uc3Qgc2VhcmNoTG93ZXIgPSBzZWFyY2hUZXJtLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBjb250ZW50QXJyYXkuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kaXNwbGF5Rm4oaXRlbSkudG9Mb2NhbGVMb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2hMb3dlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuIl19