fundamental-ngx
Version:
SAP Fundamentals, implemented in Angular
407 lines • 29.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { PopoverComponent } from '../popover/popover.component';
/**
* Input field with multiple selection enabled. Should be used when a user can select between a
* limited number of pre-defined options with a filter-enabled context.
*
* Supports Angular Forms.
*/
export class MultiInputComponent {
/**
* @hidden
* @param {?} elRef
*/
constructor(elRef) {
this.elRef = elRef;
/**
* @hidden
*/
this.multiInputClass = true;
/**
* Placeholder for the input field.
*/
this.placeholder = '';
/**
* Whether the input is disabled.
*/
this.disabled = false;
/**
* Whether the input is in compact mode.
*/
this.compact = false;
/**
* Max height of the popover. Any overflowing elements will be accessible through scrolling.
*/
this.maxHeight = '300px';
/**
* Icon of the button on the right of the input field.
*/
this.glyph = 'navigation-down-arrow';
/**
* Values to be displayed in the unfiltered dropdown.
*/
this.dropdownValues = [];
/**
* Whether the search term should be highlighted in results.
*/
this.highlight = true;
/**
* Selected dropdown items.
*/
this.selected = [];
/**
* Filter function. Accepts an array and a string as arguments, and outputs an array.
* An arrow function can be used to access the *this* keyword in the calling component.
* See multi input examples for details.
*/
this.filterFn = this.defaultFilter;
/**
* 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 multi input examples for details.
*/
this.displayFn = this.defaultDisplay;
/**
* Aria label for the multi input body.
*/
this.multiInputBodyLabel = 'Multi input body';
/**
* Preset options for the popover body width.
* * `at-least` will apply a minimum width to the body equivalent to the width of the control.
* * `equal` will apply a width to the body equivalent to the width of the control.
* * Leave blank for no effect.
*/
this.fillControlMode = 'at-least';
/**
* Event emitted when the search term changes. Use *$event* to access the new term.
*/
this.searchTermChange = new EventEmitter();
/**
* Event emitted when the selected items change. Use *$event* to access the new selected array.
*/
this.selectedChange = new EventEmitter();
/**
* @hidden
*/
this.displayedValues = [];
/**
* @hidden
*/
this.isOpen = false;
/**
* @hidden
*/
this.onChange = (/**
* @return {?}
*/
() => { });
/**
* @hidden
*/
this.onTouched = (/**
* @return {?}
*/
() => { });
}
/**
* @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.searchTerm) {
this.displayedValues = this.filterFn(this.dropdownValues, this.searchTerm);
}
else {
this.displayedValues = this.dropdownValues;
}
}
}
/**
* @hidden
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @hidden
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @hidden
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* @hidden
* @param {?} selected
* @return {?}
*/
writeValue(selected) {
if (selected) {
this.selected = selected;
}
}
/**
* @hidden
* @param {?} checked
* @param {?} value
* @return {?}
*/
handleSelect(checked, value) {
/** @type {?} */
const previousLength = this.selected.length;
if (checked) {
this.selected.push(value);
}
else {
this.selected.splice(this.selected.indexOf(value), 1);
}
// Handle popover placement update
if ((previousLength === 0 && this.selected.length === 1) ||
(previousLength === 1 && this.selected.length === 0)) {
this.popoverRef.updatePopover();
}
this.onChange(this.selected);
this.selectedChange.emit(this.selected);
}
/**
* @hidden
* @return {?}
*/
handleSearchTermChange() {
this.searchTermChange.emit(this.searchTerm);
this.displayedValues = this.filterFn(this.dropdownValues, this.searchTerm);
this.popoverRef.updatePopover();
}
/**
* @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);
}
}));
}
/**
* @private
* @param {?} str
* @return {?}
*/
defaultDisplay(str) {
return str;
}
/**
* @hidden
* @param {?} event
* @return {?}
*/
clickHandler(event) {
event.stopPropagation();
if (!this.elRef.nativeElement.contains(event.target)) {
this.isOpen = false;
}
}
}
MultiInputComponent.decorators = [
{ type: Component, args: [{
selector: 'fd-multi-input',
template: "<div class=\"fd-multi-input-field\">\n <fd-popover [(isOpen)]=\"isOpen\"\n [triggers]=\"[]\"\n [disabled]=\"disabled\"\n [fillControlMode]=\"fillControlMode\"\n class=\"fd-multi-input-popover-custom\">\n <fd-popover-control>\n <div class=\"fd-combobox-control\"\n [attr.aria-label]=\"multiInputBodyLabel\"\n [attr.aria-expanded]=\"isOpen\">\n <div class=\"fd-input-group fd-input-group--after\" [ngClass]=\"{'fd-input-group--compact': compact}\">\n <input type=\"text\" class=\"fd-input\"\n [ngClass]=\"{'fd-input--compact': compact}\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"handleSearchTermChange()\"\n (keypress)=\"isOpen = true\"\n (click)=\"isOpen = !isOpen\">\n <span class=\"fd-input-group__addon fd-input-group__addon--after\n fd-input-group__addon--button\">\n <button class=\"fd-button--light\" type=\"button\"\n [ngClass]=\"('sap-icon--' + glyph)\"\n [disabled]=\"disabled\"\n (click)=\"isOpen = !isOpen\"></button>\n </span>\n </div>\n </div>\n </fd-popover-control>\n <fd-popover-body [attr.aria-hidden]=\"!isOpen\">\n <fd-menu class=\"fd-multi-input-menu-overflow\"\n *ngIf=\"displayedValues && displayedValues.length\"\n [style.maxHeight]=\"maxHeight\">\n <ul fd-menu-list>\n <li *ngFor=\"let value of displayedValues\">\n <label fd-menu-item>\n <input type=\"checkbox\" class=\"fd-checkbox\"\n [ngModel]=\"selected ? selected.indexOf(value) !== -1 : false\"\n (ngModelChange)=\"handleSelect($event, value)\">\n <span [innerHtml]=\"value | displayFnPipe:displayFn | highlight:searchTerm:highlight\"></span>\n </label>\n </li>\n </ul>\n </fd-menu>\n <ng-content></ng-content>\n </fd-popover-body>\n </fd-popover>\n</div>\n<div class=\"fd-multi-input-tags\">\n <fd-token *ngFor=\"let token of selected\"\n (onCloseClick)=\"handleSelect(false, token)\"\n class=\"fd-multi-input-token-spacing\">\n {{token | displayFnPipe:displayFn}}\n </fd-token>\n</div>\n\n",
host: {
'(blur)': 'onTouched()',
'[class.fd-multi-input-custom]': 'true'
},
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => MultiInputComponent)),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
styles: [".fd-multi-input-custom{display:block}.fd-multi-input-custom .fd-multi-input-popover-size{overflow:auto;display:block}.fd-multi-input-custom .fd-multi-input-popover-custom{display:block}.fd-multi-input-custom .fd-multi-input-menu-overflow{overflow:auto}.fd-multi-input-custom .fd-multi-input-token-spacing{margin:0 4px 4px 0}.fd-multi-input-custom .fd-multi-input-token-spacing:last-child{margin-right:0}"]
}] }
];
/** @nocollapse */
MultiInputComponent.ctorParameters = () => [
{ type: ElementRef }
];
MultiInputComponent.propDecorators = {
popoverRef: [{ type: ViewChild, args: [PopoverComponent,] }],
multiInputClass: [{ type: HostBinding, args: ['class.fd-multi-input',] }],
placeholder: [{ type: Input }],
disabled: [{ type: Input }],
compact: [{ type: Input }],
maxHeight: [{ type: Input }],
glyph: [{ type: Input }],
dropdownValues: [{ type: Input }],
searchTerm: [{ type: Input }],
highlight: [{ type: Input }],
selected: [{ type: Input }],
filterFn: [{ type: Input }],
displayFn: [{ type: Input }],
multiInputBodyLabel: [{ type: Input }],
fillControlMode: [{ type: Input }],
searchTermChange: [{ type: Output }],
selectedChange: [{ type: Output }],
clickHandler: [{ type: HostListener, args: ['document:click', ['$event'],] }]
};
if (false) {
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.popoverRef;
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.multiInputClass;
/**
* Placeholder for the input field.
* @type {?}
*/
MultiInputComponent.prototype.placeholder;
/**
* Whether the input is disabled.
* @type {?}
*/
MultiInputComponent.prototype.disabled;
/**
* Whether the input is in compact mode.
* @type {?}
*/
MultiInputComponent.prototype.compact;
/**
* Max height of the popover. Any overflowing elements will be accessible through scrolling.
* @type {?}
*/
MultiInputComponent.prototype.maxHeight;
/**
* Icon of the button on the right of the input field.
* @type {?}
*/
MultiInputComponent.prototype.glyph;
/**
* Values to be displayed in the unfiltered dropdown.
* @type {?}
*/
MultiInputComponent.prototype.dropdownValues;
/**
* Search term, or more specifically the value of the inner input field.
* @type {?}
*/
MultiInputComponent.prototype.searchTerm;
/**
* Whether the search term should be highlighted in results.
* @type {?}
*/
MultiInputComponent.prototype.highlight;
/**
* Selected dropdown items.
* @type {?}
*/
MultiInputComponent.prototype.selected;
/**
* Filter function. Accepts an array and a string as arguments, and outputs an array.
* An arrow function can be used to access the *this* keyword in the calling component.
* See multi input examples for details.
* @type {?}
*/
MultiInputComponent.prototype.filterFn;
/**
* 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 multi input examples for details.
* @type {?}
*/
MultiInputComponent.prototype.displayFn;
/**
* Aria label for the multi input body.
* @type {?}
*/
MultiInputComponent.prototype.multiInputBodyLabel;
/**
* Preset options for the popover body width.
* * `at-least` will apply a minimum width to the body equivalent to the width of the control.
* * `equal` will apply a width to the body equivalent to the width of the control.
* * Leave blank for no effect.
* @type {?}
*/
MultiInputComponent.prototype.fillControlMode;
/**
* Event emitted when the search term changes. Use *$event* to access the new term.
* @type {?}
*/
MultiInputComponent.prototype.searchTermChange;
/**
* Event emitted when the selected items change. Use *$event* to access the new selected array.
* @type {?}
*/
MultiInputComponent.prototype.selectedChange;
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.displayedValues;
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.isOpen;
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.onChange;
/**
* @hidden
* @type {?}
*/
MultiInputComponent.prototype.onTouched;
/**
* @type {?}
* @private
*/
MultiInputComponent.prototype.elRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL211bHRpLWlucHV0L211bHRpLWlucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixFQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7Ozs7QUEwQmhFLE1BQU0sT0FBTyxtQkFBbUI7Ozs7O0lBNkY1QixZQUFvQixLQUFpQjtRQUFqQixVQUFLLEdBQUwsS0FBSyxDQUFZOzs7O1FBckZyQyxvQkFBZSxHQUFHLElBQUksQ0FBQzs7OztRQUl2QixnQkFBVyxHQUFXLEVBQUUsQ0FBQzs7OztRQUl6QixhQUFRLEdBQVksS0FBSyxDQUFDOzs7O1FBSTFCLFlBQU8sR0FBWSxLQUFLLENBQUM7Ozs7UUFJekIsY0FBUyxHQUFXLE9BQU8sQ0FBQzs7OztRQUk1QixVQUFLLEdBQVcsdUJBQXVCLENBQUM7Ozs7UUFJeEMsbUJBQWMsR0FBVSxFQUFFLENBQUM7Ozs7UUFRM0IsY0FBUyxHQUFZLElBQUksQ0FBQzs7OztRQUkxQixhQUFRLEdBQVUsRUFBRSxDQUFDOzs7Ozs7UUFNckIsYUFBUSxHQUFhLElBQUksQ0FBQyxhQUFhLENBQUM7Ozs7Ozs7UUFPeEMsY0FBUyxHQUFhLElBQUksQ0FBQyxjQUFjLENBQUM7Ozs7UUFJMUMsd0JBQW1CLEdBQVcsa0JBQWtCLENBQUM7Ozs7Ozs7UUFTakQsb0JBQWUsR0FBb0IsVUFBVSxDQUFDOzs7O1FBSXJDLHFCQUFn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LEtBQUs7b0JBSUwsS0FBSzs2QkFJTCxLQUFLO3lCQUlMLEtBQUs7d0JBSUwsS0FBSzt1QkFJTCxLQUFLO3VCQU1MLEtBQUs7d0JBT0wsS0FBSztrQ0FJTCxLQUFLOzhCQVNMLEtBQUs7K0JBSUwsTUFBTTs2QkFJTixNQUFNOzJCQWtHTixZQUFZLFNBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Ozs7Ozs7SUE1SzFDLHlDQUM2Qjs7Ozs7SUFHN0IsOENBQ3VCOzs7OztJQUd2QiwwQ0FDeUI7Ozs7O0lBR3pCLHVDQUMwQjs7Ozs7SUFHMUIsc0NBQ3lCOzs7OztJQUd6Qix3Q0FDNEI7Ozs7O0lBRzVCLG9DQUN3Qzs7Ozs7SUFHeEMsNkNBQzJCOzs7OztJQUczQix5Q0FDbUI7Ozs7O0lBR25CLHdDQUMwQjs7Ozs7SUFHMUIsdUNBQ3FCOzs7Ozs7O0lBS3JCLHVDQUN3Qzs7Ozs7Ozs7SUFNeEMsd0NBQzBDOzs7OztJQUcxQyxrREFDaUQ7Ozs7Ozs7O0lBUWpELDhDQUM4Qzs7Ozs7SUFHOUMsK0NBQzZFOzs7OztJQUc3RSw2Q0FDeUU7Ozs7O0lBR3pFLDhDQUE0Qjs7Ozs7SUFHNUIscUNBQWU7Ozs7O0lBR2YsdUNBQStCOzs7OztJQUcvQix3Q0FBZ0M7Ozs7O0lBR3BCLG9DQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkluaXQsXG4gICAgT3V0cHV0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUG9wb3ZlckNvbXBvbmVudCB9IGZyb20gJy4uL3BvcG92ZXIvcG9wb3Zlci5jb21wb25lbnQnO1xuaW1wb3J0IHsgUG9wb3ZlckZpbGxNb2RlIH0gZnJvbSAnLi4vcG9wb3Zlci9wb3BvdmVyLWRpcmVjdGl2ZS9wb3BvdmVyLmRpcmVjdGl2ZSc7XG5cbi8qKlxuICogSW5wdXQgZmllbGQgd2l0aCBtdWx0aXBsZSBzZWxlY3Rpb24gZW5hYmxlZC4gU2hvdWxkIGJlIHVzZWQgd2hlbiBhIHVzZXIgY2FuIHNlbGVjdCBiZXR3ZWVuIGFcbiAqIGxpbWl0ZWQgbnVtYmVyIG9mIHByZS1kZWZpbmVkIG9wdGlvbnMgd2l0aCBhIGZpbHRlci1lbmFibGVkIGNvbnRleHQuXG4gKlxuICogU3VwcG9ydHMgQW5ndWxhciBGb3Jtcy5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdmZC1tdWx0aS1pbnB1dCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL211bHRpLWlucHV0LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9tdWx0aS1pbnB1dC5jb21wb25lbnQuc2NzcyddLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyhibHVyKSc6ICdvblRvdWNoZWQoKScsXG4gICAgICAgICdbY2xhc3MuZmQtbXVsdGktaW5wdXQtY3VzdG9tXSc6ICd0cnVlJ1xuICAgIH0sXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTXVsdGlJbnB1dENvbXBvbmVudCksXG4gICAgICAgICAgICBtdWx0aTogdHJ1ZVxuICAgICAgICB9XG4gICAgXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIE11bHRpSW5wdXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBAVmlld0NoaWxkKFBvcG92ZXJDb21wb25lbnQpXG4gICAgcG9wb3ZlclJlZjogUG9wb3ZlckNvbXBvbmVudDtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mZC1tdWx0aS1pbnB1dCcpXG4gICAgbXVsdGlJbnB1dENsYXNzID0gdHJ1ZTtcblxuICAgIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIGlucHV0IGZpZWxkLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICcnO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGlucHV0IGlzIGRpc2FibGVkLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBpbnB1dCBpcyBpbiBjb21wYWN0IG1vZGUuICovXG4gICAgQElucHV0KClcbiAgICBjb21wYWN0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKiogTWF4IGhlaWdodCBvZiB0aGUgcG9wb3Zlci4gQW55IG92ZXJmbG93aW5nIGVsZW1lbnRzIHdpbGwgYmUgYWNjZXNzaWJsZSB0aHJvdWdoIHNjcm9sbGluZy4gKi9cbiAgICBASW5wdXQoKVxuICAgIG1heEhlaWdodDogc3RyaW5nID0gJzMwMHB4JztcblxuICAgIC8qKiBJY29uIG9mIHRoZSBidXR0b24gb24gdGhlIHJpZ2h0IG9mIHRoZSBpbnB1dCBmaWVsZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdseXBoOiBzdHJpbmcgPSAnbmF2aWdhdGlvbi1kb3duLWFycm93JztcblxuICAgIC8qKiBWYWx1ZXMgdG8gYmUgZGlzcGxheWVkIGluIHRoZSB1bmZpbHRlcmVkIGRyb3Bkb3duLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZHJvcGRvd25WYWx1ZXM6IGFueVtdID0gW107XG5cbiAgICAvKiogU2VhcmNoIHRlcm0sIG9yIG1vcmUgc3BlY2lmaWNhbGx5IHRoZSB2YWx1ZSBvZiB0aGUgaW5uZXIgaW5wdXQgZmllbGQuICovXG4gICAgQElucHV0KClcbiAgICBzZWFyY2hUZXJtOiBzdHJpbmc7XG5cbiAgICAvKiogV2hldGhlciB0aGUgc2VhcmNoIHRlcm0gc2hvdWxkIGJlIGhpZ2hsaWdodGVkIGluIHJlc3VsdHMuICovXG4gICAgQElucHV0KClcbiAgICBoaWdobGlnaHQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIFNlbGVjdGVkIGRyb3Bkb3duIGl0ZW1zLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgc2VsZWN0ZWQ6IGFueVtdID0gW107XG5cbiAgICAvKiogRmlsdGVyIGZ1bmN0aW9uLiBBY2NlcHRzIGFuIGFycmF5IGFuZCBhIHN0cmluZyBhcyBhcmd1bWVudHMsIGFuZCBvdXRwdXRzIGFuIGFycmF5LlxuICAgICAqIEFuIGFycm93IGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGFjY2VzcyB0aGUgKnRoaXMqIGtleXdvcmQgaW4gdGhlIGNhbGxpbmcgY29tcG9uZW50LlxuICAgICAqIFNlZSBtdWx0aSBpbnB1dCBleGFtcGxlcyBmb3IgZGV0YWlscy4gKi9cbiAgICBASW5wdXQoKVxuICAgIGZpbHRlckZuOiBGdW5jdGlvbiA9IHRoaXMuZGVmYXVsdEZpbHRlcjtcblxuICAgIC8qKiBEaXNwbGF5IGZ1bmN0aW9uLiBBY2NlcHRzIGFuIG9iamVjdCBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoZVxuICAgICAqIGl0ZW1zIHBhc3NlZCB0byBkcm9wZG93blZhbHVlcyBhcyBhcmd1bWVudCwgYW5kIG91dHB1dHMgYSBzdHJpbmcuXG4gICAgICogQW4gYXJyb3cgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gYWNjZXNzIHRoZSAqdGhpcyoga2V5d29yZCBpbiB0aGUgY2FsbGluZyBjb21wb25lbnQuXG4gICAgICogU2VlIG11bHRpIGlucHV0IGV4YW1wbGVzIGZvciBkZXRhaWxzLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzcGxheUZuOiBGdW5jdGlvbiA9IHRoaXMuZGVmYXVsdERpc3BsYXk7XG5cbiAgICAvKiogQXJpYSBsYWJlbCBmb3IgdGhlIG11bHRpIGlucHV0IGJvZHkuICovXG4gICAgQElucHV0KClcbiAgICBtdWx0aUlucHV0Qm9keUxhYmVsOiBzdHJpbmcgPSAnTXVsdGkgaW5wdXQgYm9keSc7XG5cbiAgICAvKipcbiAgICAgKiBQcmVzZXQgb3B0aW9ucyBmb3IgdGhlIHBvcG92ZXIgYm9keSB3aWR0aC5cbiAgICAgKiAqIGBhdC1sZWFzdGAgd2lsbCBhcHBseSBhIG1pbmltdW0gd2lkdGggdG8gdGhlIGJvZHkgZXF1aXZhbGVudCB0byB0aGUgd2lkdGggb2YgdGhlIGNvbnRyb2wuXG4gICAgICogKiBgZXF1YWxgIHdpbGwgYXBwbHkgYSB3aWR0aCB0byB0aGUgYm9keSBlcXVpdmFsZW50IHRvIHRoZSB3aWR0aCBvZiB0aGUgY29udHJvbC5cbiAgICAgKiAqIExlYXZlIGJsYW5rIGZvciBubyBlZmZlY3QuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBmaWxsQ29udHJvbE1vZGU6IFBvcG92ZXJGaWxsTW9kZSA9ICdhdC1sZWFzdCc7XG5cbiAgICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBzZWFyY2ggdGVybSBjaGFuZ2VzLiBVc2UgKiRldmVudCogdG8gYWNjZXNzIHRoZSBuZXcgdGVybS4gKi9cbiAgICBAT3V0cHV0KClcbiAgICByZWFkb25seSBzZWFyY2hUZXJtQ2hhbmdlOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgc2VsZWN0ZWQgaXRlbXMgY2hhbmdlLiBVc2UgKiRldmVudCogdG8gYWNjZXNzIHRoZSBuZXcgc2VsZWN0ZWQgYXJyYXkuICovXG4gICAgQE91dHB1dCgpXG4gICAgcmVhZG9ubHkgc2VsZWN0ZWRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnlbXT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueVtdPigpO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBkaXNwbGF5ZWRWYWx1ZXM6IGFueVtdID0gW107XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGlzT3BlbiA9IGZhbHNlO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbkNoYW5nZTogRnVuY3Rpb24gPSAoKSA9PiB7IH07XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7IH07XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxSZWY6IEVsZW1lbnRSZWYpIHsgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJvcGRvd25WYWx1ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gdGhpcy5kcm9wZG93blZhbHVlcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBpZiAodGhpcy5kcm9wZG93blZhbHVlcyAmJiAoY2hhbmdlcy5kcm9wZG93blZhbHVlcyB8fCBjaGFuZ2VzLnNlYXJjaFRlcm0pKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zZWFyY2hUZXJtKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRWYWx1ZXMgPSB0aGlzLmZpbHRlckZuKHRoaXMuZHJvcGRvd25WYWx1ZXMsIHRoaXMuc2VhcmNoVGVybSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkVmFsdWVzID0gdGhpcy5kcm9wZG93blZhbHVlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHdyaXRlVmFsdWUoc2VsZWN0ZWQ6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZCA9IHNlbGVjdGVkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBoYW5kbGVTZWxlY3QoY2hlY2tlZDogYW55LCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzTGVuZ3RoID0gdGhpcy5zZWxlY3RlZC5sZW5ndGg7XG4gICAgICAgIGlmIChjaGVja2VkKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkLnB1c2godmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZC5zcGxpY2UodGhpcy5zZWxlY3RlZC5pbmRleE9mKHZhbHVlKSwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgcG9wb3ZlciBwbGFjZW1lbnQgdXBkYXRlXG4gICAgICAgIGlmICgocHJldmlvdXNMZW5ndGggPT09IDAgJiYgdGhpcy5zZWxlY3RlZC5sZW5ndGggPT09IDEpIHx8XG4gICAgICAgICAgICAocHJldmlvdXNMZW5ndGggPT09IDEgJiYgdGhpcy5zZWxlY3RlZC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICB0aGlzLnBvcG92ZXJSZWYudXBkYXRlUG9wb3ZlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLnNlbGVjdGVkKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZENoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWQpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgaGFuZGxlU2VhcmNoVGVybUNoYW5nZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZWFyY2hUZXJtQ2hhbmdlLmVtaXQodGhpcy5zZWFyY2hUZXJtKTtcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRWYWx1ZXMgPSB0aGlzLmZpbHRlckZuKHRoaXMuZHJvcGRvd25WYWx1ZXMsIHRoaXMuc2VhcmNoVGVybSk7XG4gICAgICAgIHRoaXMucG9wb3ZlclJlZi51cGRhdGVQb3BvdmVyKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZWZhdWx0RmlsdGVyKGNvbnRlbnRBcnJheTogYW55W10sIHNlYXJjaFRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICAgICAgY29uc3Qgc2VhcmNoTG93ZXIgPSBzZWFyY2hUZXJtLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBjb250ZW50QXJyYXkuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kaXNwbGF5Rm4oaXRlbSkudG9Mb2NhbGVMb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2hMb3dlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGVmYXVsdERpc3BsYXkoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICAgIGNsaWNrSGFuZGxlcihldmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgaWYgKCF0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxufVxuIl19