UNPKG

ngx-bootstrap

Version:
898 lines 70.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; /* tslint:disable:max-file-line-count */ import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2, TemplateRef, ViewContainerRef } from '@angular/core'; import { NgControl } from '@angular/forms'; import { from, isObservable } from 'rxjs'; import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader'; import { TypeaheadContainerComponent } from './typeahead-container.component'; import { TypeaheadMatch } from './typeahead-match.class'; import { TypeaheadConfig } from './typeahead.config'; import { getValueFromObject, latinize, tokenize } from './typeahead-utils'; import { debounceTime, filter, mergeMap, switchMap, toArray } from 'rxjs/operators'; var TypeaheadDirective = /** @class */ (function () { function TypeaheadDirective(cis, config, changeDetection, element, ngControl, renderer, viewContainerRef) { this.changeDetection = changeDetection; this.element = element; this.ngControl = ngControl; this.renderer = renderer; /** * minimal no of characters that needs to be entered before * typeahead kicks-in. When set to 0, typeahead shows on focus with full * list of options (limited as normal by typeaheadOptionsLimit) */ this.typeaheadMinLength = void 0; /** * turn on/off animation */ this.isAnimated = false; /** * should be used only in case of typeahead attribute is array. * If true - loading of options will be async, otherwise - sync. * true make sense if options array is large. */ this.typeaheadAsync = void 0; /** * match latin symbols. * If true the word súper would match super and vice versa. */ this.typeaheadLatinize = true; /** * Can be use to search words by inserting a single white space between each characters * for example 'C a l i f o r n i a' will match 'California'. */ this.typeaheadSingleWords = true; /** * should be used only in case typeaheadSingleWords attribute is true. * Sets the word delimiter to break words. Defaults to space. */ this.typeaheadWordDelimiters = ' '; /** * should be used only in case typeaheadSingleWords attribute is true. * Sets the word delimiter to match exact phrase. * Defaults to simple and double quotes. */ this.typeaheadPhraseDelimiters = '\'"'; /** * specifies if typeahead is scrollable */ this.typeaheadScrollable = false; /** * specifies number of options to show in scroll view */ this.typeaheadOptionsInScrollableView = 5; /** * fired when an options list was opened and the user clicked Tab * If a value equal true, it will be chosen first or active item in the list * If value equal false, it will be chosen an active item in the list or nothing */ this.typeaheadSelectFirstItem = true; /** * makes active first item in a list */ this.typeaheadIsFirstItemActive = true; /** * fired when 'busy' state of this component was changed, * fired on async mode only, returns boolean */ this.typeaheadLoading = new EventEmitter(); /** * fired on every key event and returns true * in case of matches are not detected */ this.typeaheadNoResults = new EventEmitter(); /** * fired when option was selected, return object with data of this option */ this.typeaheadOnSelect = new EventEmitter(); /** * fired when blur event occurs. returns the active item */ // tslint:disable-next-line:no-any this.typeaheadOnBlur = new EventEmitter(); /** * This attribute indicates that the dropdown should be opened upwards */ this.dropup = false; this.isActiveItemChanged = false; this.isTypeaheadOptionsListActive = false; // tslint:disable-next-line:no-any this.keyUpEventEmitter = new EventEmitter(); this.placement = 'bottom-left'; this._subscriptions = []; this._typeahead = cis.createLoader(element, viewContainerRef, renderer) .provide({ provide: TypeaheadConfig, useValue: config }); Object.assign(this, { typeaheadHideResultsOnBlur: config.hideResultsOnBlur, typeaheadSelectFirstItem: config.selectFirstItem, typeaheadIsFirstItemActive: config.isFirstItemActive, typeaheadMinLength: config.minLength, adaptivePosition: config.adaptivePosition, isAnimated: config.isAnimated }); } /** * @return {?} */ TypeaheadDirective.prototype.ngOnInit = /** * @return {?} */ function () { this.typeaheadOptionsLimit = this.typeaheadOptionsLimit || 20; this.typeaheadMinLength = this.typeaheadMinLength === void 0 ? 1 : this.typeaheadMinLength; this.typeaheadWaitMs = this.typeaheadWaitMs || 0; // async should be false in case of array if (this.typeaheadAsync === undefined && !(isObservable(this.typeahead))) { this.typeaheadAsync = false; } if (isObservable(this.typeahead)) { this.typeaheadAsync = true; } if (this.typeaheadAsync) { this.asyncActions(); } else { this.syncActions(); } }; /** * @param {?} e * @return {?} */ // tslint:disable-next-line:no-any TypeaheadDirective.prototype.onInput = /** * @param {?} e * @return {?} */ function (e) { // For `<input>`s, use the `value` property. For others that don't have a // `value` (such as `<span contenteditable="true">`), use either // `textContent` or `innerText` (depending on which one is supported, i.e. // Firefox or IE). /** @type {?} */ var value = e.target.value !== undefined ? e.target.value : e.target.textContent !== undefined ? e.target.textContent : e.target.innerText; if (value != null && value.trim().length >= this.typeaheadMinLength) { this.typeaheadLoading.emit(true); this.keyUpEventEmitter.emit(e.target.value); } else { this.typeaheadLoading.emit(false); this.typeaheadNoResults.emit(false); this.hide(); } }; /** * @param {?} event * @return {?} */ TypeaheadDirective.prototype.onChange = /** * @param {?} event * @return {?} */ function (event) { if (this._container) { // esc /* tslint:disable-next-line: deprecation */ if (event.keyCode === 27 || event.key === 'Escape') { this.hide(); return; } // up /* tslint:disable-next-line: deprecation */ if (event.keyCode === 38 || event.key === 'ArrowUp') { this.isActiveItemChanged = true; this._container.prevActiveMatch(); return; } // down /* tslint:disable-next-line: deprecation */ if (event.keyCode === 40 || event.key === 'ArrowDown') { this.isActiveItemChanged = true; this._container.nextActiveMatch(); return; } // enter /* tslint:disable-next-line: deprecation */ if (event.keyCode === 13 || event.key === 'Enter') { this._container.selectActiveMatch(); return; } } }; /** * @return {?} */ TypeaheadDirective.prototype.onFocus = /** * @return {?} */ function () { if (this.typeaheadMinLength === 0) { this.typeaheadLoading.emit(true); this.keyUpEventEmitter.emit(this.element.nativeElement.value || ''); } }; /** * @return {?} */ TypeaheadDirective.prototype.onBlur = /** * @return {?} */ function () { if (this._container && !this._container.isFocused) { this.typeaheadOnBlur.emit(this._container.active); } }; /** * @param {?} event * @return {?} */ TypeaheadDirective.prototype.onKeydown = /** * @param {?} event * @return {?} */ function (event) { // no container - no problems if (!this._container) { return; } /* tslint:disable-next-line: deprecation */ if (event.keyCode === 9 || event.key === 'Tab' || event.keyCode === 13 || event.key === 'Enter') { event.preventDefault(); if (this.typeaheadSelectFirstItem) { this._container.selectActiveMatch(); return; } if (!this.typeaheadSelectFirstItem) { this._container.selectActiveMatch(this.isActiveItemChanged); this.isActiveItemChanged = false; this.hide(); } } }; /** * @param {?} match * @return {?} */ TypeaheadDirective.prototype.changeModel = /** * @param {?} match * @return {?} */ function (match) { /** @type {?} */ var valueStr = match.value; this.ngControl.viewToModelUpdate(valueStr); (this.ngControl.control).setValue(valueStr); this.changeDetection.markForCheck(); this.hide(); }; Object.defineProperty(TypeaheadDirective.prototype, "matches", { get: /** * @return {?} */ function () { return this._matches; }, enumerable: true, configurable: true }); /** * @return {?} */ TypeaheadDirective.prototype.show = /** * @return {?} */ function () { var _this = this; this._typeahead .attach(TypeaheadContainerComponent) .to(this.container) .position({ attachment: (this.dropup ? 'top' : 'bottom') + " start" }) .show({ typeaheadRef: this, placement: this.placement, animation: false, dropup: this.dropup }); this._outsideClickListener = this.renderer.listen('document', 'click', (/** * @param {?} e * @return {?} */ function (e) { if (_this.typeaheadMinLength === 0 && _this.element.nativeElement.contains(e.target)) { return undefined; } if (!_this.typeaheadHideResultsOnBlur || _this.element.nativeElement.contains(e.target)) { return undefined; } _this.onOutsideClick(); })); this._container = this._typeahead.instance; this._container.parent = this; // This improves the speed as it won't have to be done for each list item /** @type {?} */ var normalizedQuery = (this.typeaheadLatinize ? latinize(this.ngControl.control.value) : this.ngControl.control.value) .toString() .toLowerCase(); this._container.query = this.typeaheadSingleWords ? tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters) : normalizedQuery; this._container.matches = this._matches; this.element.nativeElement.focus(); }; /** * @return {?} */ TypeaheadDirective.prototype.hide = /** * @return {?} */ function () { if (this._typeahead.isShown) { this._typeahead.hide(); this._outsideClickListener(); this._container = null; } }; /** * @return {?} */ TypeaheadDirective.prototype.onOutsideClick = /** * @return {?} */ function () { if (this._container && !this._container.isFocused) { this.hide(); } }; /** * @return {?} */ TypeaheadDirective.prototype.ngOnDestroy = /** * @return {?} */ function () { var e_1, _a; try { // clean up subscriptions for (var _b = tslib_1.__values(this._subscriptions), _c = _b.next(); !_c.done; _c = _b.next()) { var sub = _c.value; sub.unsubscribe(); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } this._typeahead.dispose(); }; /** * @protected * @return {?} */ TypeaheadDirective.prototype.asyncActions = /** * @protected * @return {?} */ function () { var _this = this; this._subscriptions.push(this.keyUpEventEmitter .pipe(debounceTime(this.typeaheadWaitMs), switchMap((/** * @return {?} */ function () { return _this.typeahead; }))) .subscribe((/** * @param {?} matches * @return {?} */ function (matches) { _this.finalizeAsyncCall(matches); }))); }; /** * @protected * @return {?} */ TypeaheadDirective.prototype.syncActions = /** * @protected * @return {?} */ function () { var _this = this; this._subscriptions.push(this.keyUpEventEmitter .pipe(debounceTime(this.typeaheadWaitMs), mergeMap((/** * @param {?} value * @return {?} */ function (value) { /** @type {?} */ var normalizedQuery = _this.normalizeQuery(value); return from(_this.typeahead) .pipe(filter((/** * @param {?} option * @return {?} */ function (option) { return (option && _this.testMatch(_this.normalizeOption(option), normalizedQuery)); })), toArray()); }))) .subscribe((/** * @param {?} matches * @return {?} */ function (matches) { _this.finalizeAsyncCall(matches); }))); }; // tslint:disable-next-line:no-any // tslint:disable-next-line:no-any /** * @protected * @param {?} option * @return {?} */ TypeaheadDirective.prototype.normalizeOption = // tslint:disable-next-line:no-any /** * @protected * @param {?} option * @return {?} */ function (option) { /** @type {?} */ var optionValue = getValueFromObject(option, this.typeaheadOptionField); /** @type {?} */ var normalizedOption = this.typeaheadLatinize ? latinize(optionValue) : optionValue; return normalizedOption.toLowerCase(); }; /** * @protected * @param {?} value * @return {?} */ TypeaheadDirective.prototype.normalizeQuery = /** * @protected * @param {?} value * @return {?} */ function (value) { // If singleWords, break model here to not be doing extra work on each // iteration /** @type {?} */ var normalizedQuery = (this.typeaheadLatinize ? latinize(value) : value) .toString() .toLowerCase(); normalizedQuery = this.typeaheadSingleWords ? tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters) : normalizedQuery; return normalizedQuery; }; /** * @protected * @param {?} match * @param {?} test * @return {?} */ TypeaheadDirective.prototype.testMatch = /** * @protected * @param {?} match * @param {?} test * @return {?} */ function (match, test) { /** @type {?} */ var spaceLength; if (typeof test === 'object') { spaceLength = test.length; for (var i = 0; i < spaceLength; i += 1) { if (test[i].length > 0 && match.indexOf(test[i]) < 0) { return false; } } return true; } return match.indexOf(test) >= 0; }; /** * @protected * @param {?} matches * @return {?} */ TypeaheadDirective.prototype.finalizeAsyncCall = /** * @protected * @param {?} matches * @return {?} */ function (matches) { this.prepareMatches(matches || []); this.typeaheadLoading.emit(false); this.typeaheadNoResults.emit(!this.hasMatches()); if (!this.hasMatches()) { this.hide(); return; } if (this._container) { // fix: remove usage of ngControl internals /** @type {?} */ var _controlValue = (this.typeaheadLatinize ? latinize(this.ngControl.control.value) : this.ngControl.control.value) || ''; // This improves the speed as it won't have to be done for each list item /** @type {?} */ var normalizedQuery = _controlValue.toString().toLowerCase(); this._container.query = this.typeaheadSingleWords ? tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters) : normalizedQuery; this._container.matches = this._matches; } else { this.show(); } }; /** * @protected * @param {?} options * @return {?} */ TypeaheadDirective.prototype.prepareMatches = /** * @protected * @param {?} options * @return {?} */ function (options) { var _this = this; /** @type {?} */ var limited = options.slice(0, this.typeaheadOptionsLimit); if (this.typeaheadGroupField) { /** @type {?} */ var matches_1 = []; // extract all group names /** @type {?} */ var groups = limited .map((/** * @param {?} option * @return {?} */ function (option) { return getValueFromObject(option, _this.typeaheadGroupField); })) .filter((/** * @param {?} v * @param {?} i * @param {?} a * @return {?} */ function (v, i, a) { return a.indexOf(v) === i; })); groups.forEach((/** * @param {?} group * @return {?} */ function (group) { // add group header to array of matches matches_1.push(new TypeaheadMatch(group, group, true)); // add each item of group to array of matches matches_1 = matches_1.concat(limited .filter(( // tslint:disable-next-line:no-any // tslint:disable-next-line:no-any /** * @param {?} option * @return {?} */ function (option) { return getValueFromObject(option, _this.typeaheadGroupField) === group; })) .map(( // tslint:disable-next-line:no-any // tslint:disable-next-line:no-any /** * @param {?} option * @return {?} */ function (option) { return new TypeaheadMatch(option, getValueFromObject(option, _this.typeaheadOptionField)); }))); })); this._matches = matches_1; } else { this._matches = limited.map(( // tslint:disable-next-line:no-any // tslint:disable-next-line:no-any /** * @param {?} option * @return {?} */ function (option) { return new TypeaheadMatch(option, getValueFromObject(option, _this.typeaheadOptionField)); })); } }; /** * @protected * @return {?} */ TypeaheadDirective.prototype.hasMatches = /** * @protected * @return {?} */ function () { return this._matches.length > 0; }; TypeaheadDirective.decorators = [ { type: Directive, args: [{ selector: '[typeahead]', exportAs: 'bs-typeahead' },] } ]; /** @nocollapse */ TypeaheadDirective.ctorParameters = function () { return [ { type: ComponentLoaderFactory }, { type: TypeaheadConfig }, { type: ChangeDetectorRef }, { type: ElementRef }, { type: NgControl }, { type: Renderer2 }, { type: ViewContainerRef } ]; }; TypeaheadDirective.propDecorators = { typeahead: [{ type: Input }], typeaheadMinLength: [{ type: Input }], adaptivePosition: [{ type: Input }], isAnimated: [{ type: Input }], typeaheadWaitMs: [{ type: Input }], typeaheadOptionsLimit: [{ type: Input }], typeaheadOptionField: [{ type: Input }], typeaheadGroupField: [{ type: Input }], typeaheadAsync: [{ type: Input }], typeaheadLatinize: [{ type: Input }], typeaheadSingleWords: [{ type: Input }], typeaheadWordDelimiters: [{ type: Input }], typeaheadPhraseDelimiters: [{ type: Input }], typeaheadItemTemplate: [{ type: Input }], optionsListTemplate: [{ type: Input }], typeaheadScrollable: [{ type: Input }], typeaheadOptionsInScrollableView: [{ type: Input }], typeaheadHideResultsOnBlur: [{ type: Input }], typeaheadSelectFirstItem: [{ type: Input }], typeaheadIsFirstItemActive: [{ type: Input }], typeaheadLoading: [{ type: Output }], typeaheadNoResults: [{ type: Output }], typeaheadOnSelect: [{ type: Output }], typeaheadOnBlur: [{ type: Output }], container: [{ type: Input }], dropup: [{ type: Input }], onInput: [{ type: HostListener, args: ['input', ['$event'],] }], onChange: [{ type: HostListener, args: ['keyup', ['$event'],] }], onFocus: [{ type: HostListener, args: ['click',] }, { type: HostListener, args: ['focus',] }], onBlur: [{ type: HostListener, args: ['blur',] }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }] }; return TypeaheadDirective; }()); export { TypeaheadDirective }; if (false) { /** * options source, can be Array of strings, objects or * an Observable for external matching process * @type {?} */ TypeaheadDirective.prototype.typeahead; /** * minimal no of characters that needs to be entered before * typeahead kicks-in. When set to 0, typeahead shows on focus with full * list of options (limited as normal by typeaheadOptionsLimit) * @type {?} */ TypeaheadDirective.prototype.typeaheadMinLength; /** * sets use adaptive position * @type {?} */ TypeaheadDirective.prototype.adaptivePosition; /** * turn on/off animation * @type {?} */ TypeaheadDirective.prototype.isAnimated; /** * minimal wait time after last character typed before typeahead kicks-in * @type {?} */ TypeaheadDirective.prototype.typeaheadWaitMs; /** * maximum length of options items list. The default value is 20 * @type {?} */ TypeaheadDirective.prototype.typeaheadOptionsLimit; /** * when options source is an array of objects, the name of field * that contains the options value, we use array item as option in case * of this field is missing. Supports nested properties and methods. * @type {?} */ TypeaheadDirective.prototype.typeaheadOptionField; /** * when options source is an array of objects, the name of field that * contains the group value, matches are grouped by this field when set. * @type {?} */ TypeaheadDirective.prototype.typeaheadGroupField; /** * should be used only in case of typeahead attribute is array. * If true - loading of options will be async, otherwise - sync. * true make sense if options array is large. * @type {?} */ TypeaheadDirective.prototype.typeaheadAsync; /** * match latin symbols. * If true the word súper would match super and vice versa. * @type {?} */ TypeaheadDirective.prototype.typeaheadLatinize; /** * Can be use to search words by inserting a single white space between each characters * for example 'C a l i f o r n i a' will match 'California'. * @type {?} */ TypeaheadDirective.prototype.typeaheadSingleWords; /** * should be used only in case typeaheadSingleWords attribute is true. * Sets the word delimiter to break words. Defaults to space. * @type {?} */ TypeaheadDirective.prototype.typeaheadWordDelimiters; /** * should be used only in case typeaheadSingleWords attribute is true. * Sets the word delimiter to match exact phrase. * Defaults to simple and double quotes. * @type {?} */ TypeaheadDirective.prototype.typeaheadPhraseDelimiters; /** * used to specify a custom item template. * Template variables exposed are called item and index; * @type {?} */ TypeaheadDirective.prototype.typeaheadItemTemplate; /** * used to specify a custom options list template. * Template variables: matches, itemTemplate, query * @type {?} */ TypeaheadDirective.prototype.optionsListTemplate; /** * specifies if typeahead is scrollable * @type {?} */ TypeaheadDirective.prototype.typeaheadScrollable; /** * specifies number of options to show in scroll view * @type {?} */ TypeaheadDirective.prototype.typeaheadOptionsInScrollableView; /** * used to hide result on blur * @type {?} */ TypeaheadDirective.prototype.typeaheadHideResultsOnBlur; /** * fired when an options list was opened and the user clicked Tab * If a value equal true, it will be chosen first or active item in the list * If value equal false, it will be chosen an active item in the list or nothing * @type {?} */ TypeaheadDirective.prototype.typeaheadSelectFirstItem; /** * makes active first item in a list * @type {?} */ TypeaheadDirective.prototype.typeaheadIsFirstItemActive; /** * fired when 'busy' state of this component was changed, * fired on async mode only, returns boolean * @type {?} */ TypeaheadDirective.prototype.typeaheadLoading; /** * fired on every key event and returns true * in case of matches are not detected * @type {?} */ TypeaheadDirective.prototype.typeaheadNoResults; /** * fired when option was selected, return object with data of this option * @type {?} */ TypeaheadDirective.prototype.typeaheadOnSelect; /** * fired when blur event occurs. returns the active item * @type {?} */ TypeaheadDirective.prototype.typeaheadOnBlur; /** * A selector specifying the element the typeahead should be appended to. * @type {?} */ TypeaheadDirective.prototype.container; /** * This attribute indicates that the dropdown should be opened upwards * @type {?} */ TypeaheadDirective.prototype.dropup; /** * if false don't focus the input element the typeahead directive is associated with on selection * @type {?} */ TypeaheadDirective.prototype._container; /** @type {?} */ TypeaheadDirective.prototype.isActiveItemChanged; /** @type {?} */ TypeaheadDirective.prototype.isTypeaheadOptionsListActive; /** * @type {?} * @protected */ TypeaheadDirective.prototype.keyUpEventEmitter; /** * @type {?} * @protected */ TypeaheadDirective.prototype._matches; /** * @type {?} * @protected */ TypeaheadDirective.prototype.placement; /** * @type {?} * @private */ TypeaheadDirective.prototype._typeahead; /** * @type {?} * @private */ TypeaheadDirective.prototype._subscriptions; /** * @type {?} * @private */ TypeaheadDirective.prototype._outsideClickListener; /** * @type {?} * @private */ TypeaheadDirective.prototype.changeDetection; /** * @type {?} * @private */ TypeaheadDirective.prototype.element; /** * @type {?} * @private */ TypeaheadDirective.prototype.ngControl; /** * @type {?} * @private */ TypeaheadDirective.prototype.renderer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWFoZWFkLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1ib290c3RyYXAvdHlwZWFoZWFkLyIsInNvdXJjZXMiOlsidHlwZWFoZWFkLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1gsZ0JBQWdCLEVBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsSUFBSSxFQUFnQixZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEQsT0FBTyxFQUFtQixzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXBGO0lBNEhFLDRCQUNFLEdBQTJCLEVBQzNCLE1BQXVCLEVBQ2YsZUFBa0MsRUFDbEMsT0FBbUIsRUFDbkIsU0FBb0IsRUFDcEIsUUFBbUIsRUFDM0IsZ0JBQWtDO1FBSjFCLG9CQUFlLEdBQWYsZUFBZSxDQUFtQjtRQUNsQyxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFDcEIsYUFBUSxH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LCJzb3VyY2VzQ29udGVudCI6WyIvKiB0c2xpbnQ6ZGlzYWJsZTptYXgtZmlsZS1saW5lLWNvdW50ICovXG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDb250YWluZXJSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE5nQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgZnJvbSwgU3Vic2NyaXB0aW9uLCBpc09ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENvbXBvbmVudExvYWRlciwgQ29tcG9uZW50TG9hZGVyRmFjdG9yeSB9IGZyb20gJ25neC1ib290c3RyYXAvY29tcG9uZW50LWxvYWRlcic7XG5pbXBvcnQgeyBUeXBlYWhlYWRDb250YWluZXJDb21wb25lbnQgfSBmcm9tICcuL3R5cGVhaGVhZC1jb250YWluZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFR5cGVhaGVhZE1hdGNoIH0gZnJvbSAnLi90eXBlYWhlYWQtbWF0Y2guY2xhc3MnO1xuaW1wb3J0IHsgVHlwZWFoZWFkQ29uZmlnIH0gZnJvbSAnLi90eXBlYWhlYWQuY29uZmlnJztcbmltcG9ydCB7IGdldFZhbHVlRnJvbU9iamVjdCwgbGF0aW5pemUsIHRva2VuaXplIH0gZnJvbSAnLi90eXBlYWhlYWQtdXRpbHMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBmaWx0ZXIsIG1lcmdlTWFwLCBzd2l0Y2hNYXAsIHRvQXJyYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnW3R5cGVhaGVhZF0nLCBleHBvcnRBczogJ2JzLXR5cGVhaGVhZCd9KVxuZXhwb3J0IGNsYXNzIFR5cGVhaGVhZERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIG9wdGlvbnMgc291cmNlLCBjYW4gYmUgQXJyYXkgb2Ygc3RyaW5ncywgb2JqZWN0cyBvclxuICAgKiBhbiBPYnNlcnZhYmxlIGZvciBleHRlcm5hbCBtYXRjaGluZyBwcm9jZXNzXG4gICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgQElucHV0KCkgdHlwZWFoZWFkOiBhbnk7XG4gIC8qKiBtaW5pbWFsIG5vIG9mIGNoYXJhY3RlcnMgdGhhdCBuZWVkcyB0byBiZSBlbnRlcmVkIGJlZm9yZVxuICAgKiB0eXBlYWhlYWQga2lja3MtaW4uIFdoZW4gc2V0IHRvIDAsIHR5cGVhaGVhZCBzaG93cyBvbiBmb2N1cyB3aXRoIGZ1bGxcbiAgICogbGlzdCBvZiBvcHRpb25zIChsaW1pdGVkIGFzIG5vcm1hbCBieSB0eXBlYWhlYWRPcHRpb25zTGltaXQpXG4gICAqL1xuICBASW5wdXQoKSB0eXBlYWhlYWRNaW5MZW5ndGg6IG51bWJlciA9IHZvaWQgMDtcbiAgLyoqIHNldHMgdXNlIGFkYXB0aXZlIHBvc2l0aW9uICovXG4gIEBJbnB1dCgpIGFkYXB0aXZlUG9zaXRpb246IGJvb2xlYW47XG4gIC8qKiB0dXJuIG9uL29mZiBhbmltYXRpb24gKi9cbiAgQElucHV0KCkgaXNBbmltYXRlZCA9IGZhbHNlO1xuICAvKiogbWluaW1hbCB3YWl0IHRpbWUgYWZ0ZXIgbGFzdCBjaGFyYWN0ZXIgdHlwZWQgYmVmb3JlIHR5cGVhaGVhZCBraWNrcy1pbiAqL1xuICBASW5wdXQoKSB0eXBlYWhlYWRXYWl0TXM6IG51bWJlcjtcbiAgLyoqIG1heGltdW0gbGVuZ3RoIG9mIG9wdGlvbnMgaXRlbXMgbGlzdC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMjAgKi9cbiAgQElucHV0KCkgdHlwZWFoZWFkT3B0aW9uc0xpbWl0OiBudW1iZXI7XG4gIC8qKiB3aGVuIG9wdGlvbnMgc291cmNlIGlzIGFuIGFycmF5IG9mIG9iamVjdHMsIHRoZSBuYW1lIG9mIGZpZWxkXG4gICAqIHRoYXQgY29udGFpbnMgdGhlIG9wdGlvbnMgdmFsdWUsIHdlIHVzZSBhcnJheSBpdGVtIGFzIG9wdGlvbiBpbiBjYXNlXG4gICAqIG9mIHRoaXMgZmllbGQgaXMgbWlzc2luZy4gU3VwcG9ydHMgbmVzdGVkIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMuXG4gICAqL1xuICBASW5wdXQoKSB0eXBlYWhlYWRPcHRpb25GaWVsZDogc3RyaW5nO1xuICAvKiogd2hlbiBvcHRpb25zIHNvdXJjZSBpcyBhbiBhcnJheSBvZiBvYmplY3RzLCB0aGUgbmFtZSBvZiBmaWVsZCB0aGF0XG4gICAqIGNvbnRhaW5zIHRoZSBncm91cCB2YWx1ZSwgbWF0Y2hlcyBhcmUgZ3JvdXBlZCBieSB0aGlzIGZpZWxkIHdoZW4gc2V0LlxuICAgKi9cbiAgQElucHV0KCkgdHlwZWFoZWFkR3JvdXBGaWVsZDogc3RyaW5nO1xuICAvKiogc2hvdWxkIGJlIHVzZWQgb25seSBpbiBjYXNlIG9mIHR5cGVhaGVhZCBhdHRyaWJ1dGUgaXMgYXJyYXkuXG4gICAqIElmIHRydWUgLSBsb2FkaW5nIG9mIG9wdGlvbnMgd2lsbCBiZSBhc3luYywgb3RoZXJ3aXNlIC0gc3luYy5cbiAgICogdHJ1ZSBtYWtlIHNlbnNlIGlmIG9wdGlvbnMgYXJyYXkgaXMgbGFyZ2UuXG4gICAqL1xuICBASW5wdXQoKSB0eXBlYWhlYWRBc3luYzogYm9vbGVhbiA9IHZvaWQgMDtcbiAgLyoqIG1hdGNoIGxhdGluIHN5bWJvbHMuXG4gICAqIElmIHRydWUgdGhlIHdvcmQgc8O6cGVyIHdvdWxkIG1hdGNoIHN1cGVyIGFuZCB2aWNlIHZlcnNhLlxuICAgKi9cbiAgQElucHV0KCkgdHlwZWFoZWFkTGF0aW5pemUgPSB0cnVlO1xuICAvKiogQ2FuIGJlIHVzZSB0byBzZWFyY2ggd29yZHMgYnkgaW5zZXJ0aW5nIGEgc2luZ2xlIHdoaXRlIHNwYWNlIGJldHdlZW4gZWFjaCBjaGFyYWN0ZXJzXG