UNPKG

angular-text-input-autocomplete

Version:

A angular 6+ directive for adding autocomplete functionality to text input elements, built around composability

460 lines (449 loc) 48 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('textarea-caret'), require('rxjs/operators'), require('to-px'), require('@angular/common')) : typeof define === 'function' && define.amd ? define('angular-text-input-autocomplete', ['exports', '@angular/core', 'rxjs', 'textarea-caret', 'rxjs/operators', 'to-px', '@angular/common'], factory) : (factory((global['angular-text-input-autocomplete'] = {}),global.ng.core,global.rxjs,global.getCaretCoordinates,global.rxjs.operators,null,global.ng.common)); }(this, (function (exports,core,rxjs,getCaretCoordinates,operators,toPX,common) { 'use strict'; getCaretCoordinates = getCaretCoordinates && getCaretCoordinates.hasOwnProperty('default') ? getCaretCoordinates['default'] : getCaretCoordinates; toPX = toPX && toPX.hasOwnProperty('default') ? toPX['default'] : toPX; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var TextInputAutocompleteMenuComponent = (function () { function TextInputAutocompleteMenuComponent() { this.selectChoice = new rxjs.Subject(); this.choiceLoading = false; this.trackById = function (index, choice) { return typeof choice.id !== 'undefined' ? choice.id : choice; }; } Object.defineProperty(TextInputAutocompleteMenuComponent.prototype, "choices", { get: /** * @return {?} */ function () { return this._choices; }, set: /** * @param {?} choices * @return {?} */ function (choices) { this._choices = choices; if (choices.indexOf(this.activeChoice) === -1 && choices.length > 0) { this.activeChoice = choices[0]; } }, enumerable: true, configurable: true }); /** * @param {?} event * @return {?} */ TextInputAutocompleteMenuComponent.prototype.onArrowDown = /** * @param {?} event * @return {?} */ function (event) { event.preventDefault(); var /** @type {?} */ index = this.choices.indexOf(this.activeChoice); if (this.choices[index + 1]) { this.scrollToChoice(index + 1); } }; /** * @param {?} event * @return {?} */ TextInputAutocompleteMenuComponent.prototype.onArrowUp = /** * @param {?} event * @return {?} */ function (event) { event.preventDefault(); var /** @type {?} */ index = this.choices.indexOf(this.activeChoice); if (this.choices[index - 1]) { this.scrollToChoice(index - 1); } }; /** * @param {?} event * @return {?} */ TextInputAutocompleteMenuComponent.prototype.onEnter = /** * @param {?} event * @return {?} */ function (event) { if (this.choices.indexOf(this.activeChoice) > -1) { event.preventDefault(); this.selectChoice.next(this.activeChoice); } }; /** * @param {?} index * @return {?} */ TextInputAutocompleteMenuComponent.prototype.scrollToChoice = /** * @param {?} index * @return {?} */ function (index) { this.activeChoice = this._choices[index]; if (this.dropdownMenuElement) { var /** @type {?} */ ulPosition = this.dropdownMenuElement.nativeElement.getBoundingClientRect(); var /** @type {?} */ li = this.dropdownMenuElement.nativeElement.children[index]; var /** @type {?} */ liPosition = li.getBoundingClientRect(); if (liPosition.top < ulPosition.top || liPosition.bottom > ulPosition.bottom) { li.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } } }; TextInputAutocompleteMenuComponent.decorators = [ { type: core.Component, args: [{ selector: 'mwl-text-input-autocomplete-menu', template: "\n <ul \n *ngIf=\"choices?.length > 0\"\n #dropdownMenu\n class=\"dropdown-menu\"\n [style.top.px]=\"position?.top\"\n [style.left.px]=\"position?.left\">\n <li\n *ngFor=\"let choice of choices; trackBy:trackById\"\n [class.active]=\"activeChoice === choice\">\n <a\n href=\"javascript:;\"\n (click)=\"selectChoice.next(choice)\">\n {{ choice }}\n </a>\n </li>\n </ul>\n ", styles: [ "\n .dropdown-menu {\n display: block;\n max-height: 200px;\n overflow-y: auto;\n }\n " ] },] }, ]; TextInputAutocompleteMenuComponent.propDecorators = { dropdownMenuElement: [{ type: core.ViewChild, args: ['dropdownMenu',] }], onArrowDown: [{ type: core.HostListener, args: ['document:keydown.ArrowDown', ['$event'],] }], onArrowUp: [{ type: core.HostListener, args: ['document:keydown.ArrowUp', ['$event'],] }], onEnter: [{ type: core.HostListener, args: ['document:keydown.Enter', ['$event'],] }] }; return TextInputAutocompleteMenuComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var TextInputAutocompleteDirective = (function () { function TextInputAutocompleteDirective(componentFactoryResolver, viewContainerRef, injector, elm) { this.componentFactoryResolver = componentFactoryResolver; this.viewContainerRef = viewContainerRef; this.injector = injector; this.elm = elm; /** * The character that will trigger the menu to appear */ this.triggerCharacter = '@'; /** * The regular expression that will match the search text after the trigger character */ this.searchRegexp = /^\w*$/; /** * Whether to close the menu when the host textarea loses focus */ this.closeMenuOnBlur = false; /** * The menu component to show with available options. * You can extend the built in `TextInputAutocompleteMenuComponent` component to use a custom template */ this.menuComponent = TextInputAutocompleteMenuComponent; /** * Called when the options menu is shown */ this.menuShown = new core.EventEmitter(); /** * Called when the options menu is hidden */ this.menuHidden = new core.EventEmitter(); /** * Called when a choice is selected */ this.choiceSelected = new core.EventEmitter(); /** * A function that formats the selected choice once selected. */ this.getChoiceLabel = function (choice) { return choice; }; this.menuHidden$ = new rxjs.Subject(); this.usingShortcut = false; } /** * @param {?} key * @return {?} */ TextInputAutocompleteDirective.prototype.onKeypress = /** * @param {?} key * @return {?} */ function (key) { if (key === this.triggerCharacter) { this.usingShortcut = false; this.showMenu(); } }; /** * @param {?} event * @return {?} */ TextInputAutocompleteDirective.prototype.onKeyDown = /** * @param {?} event * @return {?} */ function (event) { if (this.keyboardShortcut && this.keyboardShortcut(event)) { this.usingShortcut = true; this.showMenu(); this.onChange(''); } }; /** * @param {?} value * @return {?} */ TextInputAutocompleteDirective.prototype.onChange = /** * @param {?} value * @return {?} */ function (value) { var _this = this; if (this.menu) { if (value[this.menu.triggerCharacterPosition] !== this.triggerCharacter && !this.usingShortcut) { this.hideMenu(); } else { var /** @type {?} */ cursor = this.elm.nativeElement.selectionStart; if (cursor < this.menu.triggerCharacterPosition) { this.hideMenu(); } else { if (this.usingShortcut && !this.menu) { value = this.triggerCharacter; } var /** @type {?} */ offset = this.usingShortcut ? 0 : 1; var /** @type {?} */ searchText = value.slice(this.menu.triggerCharacterPosition + offset, cursor); if (!searchText.match(this.searchRegexp)) { this.hideMenu(); } else { this.menu.component.instance.searchText = searchText; this.menu.component.instance.choices = []; this.menu.component.instance.choiceLoadError = undefined; this.menu.component.instance.choiceLoading = true; this.menu.component.changeDetectorRef.detectChanges(); Promise.resolve(this.findChoices(searchText)) .then(function (choices) { if (_this.menu) { _this.menu.component.instance.choices = choices; _this.menu.component.instance.choiceLoading = false; _this.menu.component.changeDetectorRef.detectChanges(); } }) .catch(function (err) { if (_this.menu) { _this.menu.component.instance.choiceLoading = false; _this.menu.component.instance.choiceLoadError = err; _this.menu.component.changeDetectorRef.detectChanges(); } }); } } } } }; /** * @return {?} */ TextInputAutocompleteDirective.prototype.onBlur = /** * @return {?} */ function () { if (this.menu) { this.menu.lastCaretPosition = this.elm.nativeElement.selectionStart; if (this.closeMenuOnBlur === true) { this.hideMenu(); } } }; /** * @return {?} */ TextInputAutocompleteDirective.prototype.showMenu = /** * @return {?} */ function () { var _this = this; if (!this.menu) { var /** @type {?} */ menuFactory = this.componentFactoryResolver.resolveComponentFactory(this.menuComponent); this.menu = { component: this.viewContainerRef.createComponent(menuFactory, 0, this.injector), triggerCharacterPosition: this.elm.nativeElement.selectionStart }; var /** @type {?} */ lineHeight = this.getLineHeight(this.elm.nativeElement); var _a = getCaretCoordinates(this.elm.nativeElement, this.elm.nativeElement.selectionStart), top_1 = _a.top, left = _a.left; this.menu.component.instance.position = { top: top_1 + lineHeight, left: left }; this.menu.component.changeDetectorRef.detectChanges(); this.menu.component.instance.selectChoice .pipe(operators.takeUntil(this.menuHidden$)) .subscribe(function (choice) { var /** @type {?} */ label = _this.getChoiceLabel(choice); var /** @type {?} */ textarea = _this.elm.nativeElement; var /** @type {?} */ value = textarea.value; var /** @type {?} */ startIndex = ((_this.menu)).triggerCharacterPosition; var /** @type {?} */ start = value.slice(0, startIndex); var /** @type {?} */ caretPosition = ((_this.menu)).lastCaretPosition || textarea.selectionStart; var /** @type {?} */ end = value.slice(caretPosition); textarea.value = start + label + end; // force ng model / form control to update textarea.dispatchEvent(new Event('input')); _this.hideMenu(); var /** @type {?} */ setCursorAt = (start + label).length; textarea.setSelectionRange(setCursorAt, setCursorAt); textarea.focus(); _this.choiceSelected.emit({ choice: choice, insertedAt: { start: startIndex, end: startIndex + label.length } }); }); this.menuShown.emit(); } }; /** * @param {?} elm * @return {?} */ TextInputAutocompleteDirective.prototype.getLineHeight = /** * @param {?} elm * @return {?} */ function (elm) { var /** @type {?} */ lineHeightStr = getComputedStyle(elm).lineHeight || ''; var /** @type {?} */ fontSizeStr = getComputedStyle(elm).fontSize || ''; var /** @type {?} */ fontSize = +toPX(fontSizeStr); var /** @type {?} */ normal = 1.2; var /** @type {?} */ lineHeightNum = parseFloat(lineHeightStr); if (lineHeightStr === lineHeightNum + '') { return fontSize * lineHeightNum; } if (lineHeightStr.toLowerCase() === 'normal') { return fontSize * normal; } return toPX(lineHeightStr); }; /** * @return {?} */ TextInputAutocompleteDirective.prototype.hideMenu = /** * @return {?} */ function () { if (this.menu) { this.menu.component.destroy(); this.menuHidden$.next(); this.menuHidden.emit(); this.menu = undefined; } }; /** * @return {?} */ TextInputAutocompleteDirective.prototype.ngOnDestroy = /** * @return {?} */ function () { this.hideMenu(); }; TextInputAutocompleteDirective.decorators = [ { type: core.Directive, args: [{ selector: 'textarea[mwlTextInputAutocomplete],input[type="text"][mwlTextInputAutocomplete]' },] }, ]; /** @nocollapse */ TextInputAutocompleteDirective.ctorParameters = function () { return [ { type: core.ComponentFactoryResolver }, { type: core.ViewContainerRef }, { type: core.Injector }, { type: core.ElementRef } ]; }; TextInputAutocompleteDirective.propDecorators = { triggerCharacter: [{ type: core.Input }], keyboardShortcut: [{ type: core.Input }], searchRegexp: [{ type: core.Input }], closeMenuOnBlur: [{ type: core.Input }], menuComponent: [{ type: core.Input }], menuShown: [{ type: core.Output }], menuHidden: [{ type: core.Output }], choiceSelected: [{ type: core.Output }], findChoices: [{ type: core.Input }], getChoiceLabel: [{ type: core.Input }], onKeypress: [{ type: core.HostListener, args: ['keypress', ['$event.key'],] }], onKeyDown: [{ type: core.HostListener, args: ['keydown', ['$event'],] }], onChange: [{ type: core.HostListener, args: ['input', ['$event.target.value'],] }], onBlur: [{ type: core.HostListener, args: ['blur',] }] }; return TextInputAutocompleteDirective; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var TextInputAutocompleteContainerComponent = (function () { function TextInputAutocompleteContainerComponent() { } TextInputAutocompleteContainerComponent.decorators = [ { type: core.Component, args: [{ selector: 'mwl-text-input-autocomplete-container', styles: [ "\n :host {\n position: relative;\n display: block;\n }\n " ], template: '<ng-content></ng-content>' },] }, ]; return TextInputAutocompleteContainerComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var TextInputAutocompleteModule = (function () { function TextInputAutocompleteModule() { } TextInputAutocompleteModule.decorators = [ { type: core.NgModule, args: [{ declarations: [ TextInputAutocompleteDirective, TextInputAutocompleteContainerComponent, TextInputAutocompleteMenuComponent ], imports: [common.CommonModule], exports: [ TextInputAutocompleteDirective, TextInputAutocompleteContainerComponent, TextInputAutocompleteMenuComponent ], entryComponents: [TextInputAutocompleteMenuComponent] },] }, ]; return TextInputAutocompleteModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ exports.TextInputAutocompleteMenuComponent = TextInputAutocompleteMenuComponent; exports.TextInputAutocompleteModule = TextInputAutocompleteModule; exports.ɵb = TextInputAutocompleteContainerComponent; exports.ɵa = TextInputAutocompleteDirective; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci10ZXh0LWlucHV0LWF1dG9jb21wbGV0ZS51bWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL2FuZ3VsYXItdGV4dC1pbnB1dC1hdXRvY29tcGxldGUvdGV4dC1pbnB1dC1hdXRvY29tcGxldGUtbWVudS5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXItdGV4dC1pbnB1dC1hdXRvY29tcGxldGUvdGV4dC1pbnB1dC1hdXRvY29tcGxldGUuZGlyZWN0aXZlLnRzIiwibmc6Ly9hbmd1bGFyLXRleHQtaW5wdXQtYXV0b2NvbXBsZXRlL3RleHQtaW5wdXQtYXV0b2NvbXBsZXRlLWNvbnRhaW5lci5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXItdGV4dC1pbnB1dC1hdXRvY29tcGxldGUvdGV4dC1pbnB1dC1hdXRvY29tcGxldGUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbXdsLXRleHQtaW5wdXQtYXV0b2NvbXBsZXRlLW1lbnUnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDx1bCBcbiAgICAgICpuZ0lmPVwiY2hvaWNlcz8ubGVuZ3RoID4gMFwiXG4gICAgICAjZHJvcGRvd25NZW51XG4gICAgICBjbGFzcz1cImRyb3Bkb3duLW1lbnVcIlxuICAgICAgW3N0eWxlLnRvcC5weF09XCJwb3NpdGlvbj8udG9wXCJcbiAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cInBvc2l0aW9uPy5sZWZ0XCI+XG4gICAgICA8bGlcbiAgICAgICAgKm5nRm9yPVwibGV0IGNob2ljZSBvZiBjaG9pY2VzOyB0cmFja0J5OnRyYWNrQnlJZFwiXG4gICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlQ2hvaWNlID09PSBjaG9pY2VcIj5cbiAgICAgICAgPGFcbiAgICAgICAgICBocmVmPVwiamF2YXNjcmlwdDo7XCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0Q2hvaWNlLm5leHQoY2hvaWNlKVwiPlxuICAgICAgICAgIHt7IGNob2ljZSB9fVxuICAgICAgICA8L2E+XG4gICAgICA8L2xpPlxuICAgIDwvdWw+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIC5kcm9wZG93bi1tZW51IHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIG1heC1oZWlnaHQ6IDIwMHB4O1xuICAgICAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgICAgfVxuICAgIGBcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBUZXh0SW5wdXRBdXRvY29tcGxldGVNZW51Q29tcG9uZW50IHtcbiAgQFZpZXdDaGlsZCgnZHJvcGRvd25NZW51JykgZHJvcGRvd25NZW51RWxlbWVudDogRWxlbWVudFJlZjxIVE1MVUxpc3RFbGVtZW50PjtcbiAgcG9zaXRpb246IHsgdG9wOiBudW1iZXI7IGxlZnQ6IG51bWJlciB9O1xuICBzZWxlY3RDaG9pY2UgPSBuZXcgU3ViamVjdCgpO1xuICBhY3RpdmVDaG9pY2U6IGFueTtcbiAgc2VhcmNoVGV4dDogc3RyaW5nO1xuICBjaG9pY2VMb2FkRXJyb3I6IGFueTtcbiAgY2hvaWNlTG9hZGluZyA9IGZhbHNlO1xuICBwcml2YXRlIF9jaG9pY2VzOiBhbnlbXTtcbiAgdHJhY2tCeUlkID0gKGluZGV4OiBudW1iZXIsIGNob2ljZTogYW55KSA9PlxuICAgIHR5cGVvZiBjaG9pY2UuaWQgIT09ICd1bmRlZmluZWQnID8gY2hvaWNlLmlkIDogY2hvaWNlO1xuXG4gIHNldCBjaG9pY2VzKGNob2ljZXM6IGFueVtdKSB7XG4gICAgdGhpcy5fY2hvaWNlcyA9IGNob2ljZXM7XG4gICAgaWYgKGNob2ljZXMuaW5kZXhPZih0aGlzLmFjdGl2ZUNob2ljZSkgPT09IC0xICYmIGNob2ljZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5hY3RpdmVDaG9pY2UgPSBjaG9pY2VzWzBdO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjaG9pY2VzKCkge1xuICAgIHJldHVybiB0aGlzLl9jaG9pY2VzO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5BcnJvd0Rvd24nLCBbJyRldmVudCddKVxuICBvbkFycm93RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmNob2ljZXMuaW5kZXhPZih0aGlzLmFjdGl2ZUNob2ljZSk7XG4gICAgaWYgKHRoaXMuY2hvaWNlc1tpbmRleCArIDFdKSB7XG4gICAgICB0aGlzLnNjcm9sbFRvQ2hvaWNlKGluZGV4ICsgMSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5BcnJvd1VwJywgWyckZXZlbnQnXSlcbiAgb25BcnJvd1VwKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuY2hvaWNlcy5pbmRleE9mKHRoaXMuYWN0aXZlQ2hvaWNlKTtcbiAgICBpZiAodGhpcy5jaG9pY2VzW2luZGV4IC0gMV0pIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9DaG9pY2UoaW5kZXggLSAxKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLkVudGVyJywgWyckZXZlbnQnXSlcbiAgb25FbnRlcihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmICh0aGlzLmNob2ljZXMuaW5kZXhPZih0aGlzLmFjdGl2ZUNob2ljZSkgPiAtMSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMuc2VsZWN0Q2hvaWNlLm5leHQodGhpcy5hY3RpdmVDaG9pY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9DaG9pY2UoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuYWN0aXZlQ2hvaWNlID0gdGhpcy5fY2hvaWNlc1tpbmRleF07XG5cbiAgICBpZiAodGhpcy5kcm9wZG93bk1lbnVFbGVtZW50KSB7XG4gICAgICBjb25zdCB1bFBvc2l0aW9uID0gdGhpcy5kcm9wZG93bk1lbnVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBsaSA9IHRoaXMuZHJvcGRvd25NZW51RWxlbWVudC5uYXRpdmVFbGVtZW50LmNoaWxkcmVuW2luZGV4XTtcbiAgICAgIGNvbnN0IGxpUG9zaXRpb24gPSBsaS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgaWYgKFxuICAgICAgICBsaVBvc2l0aW9uLnRvcCA8IHVsUG9zaXRpb24udG9wIHx8XG4gICAgICAgIGxpUG9zaXRpb24uYm90dG9tID4gdWxQb3NpdGlvbi5ib3R0b21cbiAgICAgICkge1xuICAgICAgICBsaS5zY3JvbGxJbnRvVmlldyh7XG4gICAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxuICAgICAgICAgIGJsb2NrOiAnbmVhcmVzdCdcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQge1xuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gIENvbXBvbmVudFJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCBnZXRDYXJldENvb3JkaW5hdGVzIGZyb20gJ3RleHRhcmVhLWNhcmV0JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFRleHRJbnB1dEF1dG9jb21wbGV0ZU1lbnVDb21wb25lbnQgfSBmcm9tICcuL3RleHQtaW5wdXQtYXV0b2NvbXBsZXRlLW1lbnUuY29tcG9uZW50JztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB0b1BYIGZyb20gJ3RvLXB4JztcblxuZXhwb3J0IGludGVyZmFjZSBDaG9pY2VTZWxlY3RlZEV2ZW50IHtcbiAgY2hvaWNlOiBhbnk7XG4gIGluc2VydGVkQXQ6IHtcbiAgICBzdGFydDogbnVtYmVyO1xuICAgIGVuZDogbnVtYmVyO1xuICB9O1xufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6XG4gICAgJ3RleHRhcmVhW213bFRleHRJbnB1dEF1dG9jb21wbGV0ZV0saW5wdXRbdHlwZT1cInRleHRcIl1bbXdsVGV4dElucHV0QXV0b2NvbXBsZXRlXSdcbn0pXG5leHBvcnQgY2xhc3MgVGV4dElucHV0QXV0b2NvbXBsZXRlRGlyZWN0aXZlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgLyoqXG4gICAqIFRoZSBjaGFyYWN0ZXIgdGhhdCB3aWxsIHRyaWdnZXIgdGhlIG1lbnUgdG8gYXBwZWFyXG4gICAqL1xuICBASW5wdXQoKSB0cmlnZ2VyQ2hhcmFjdGVyID0gJ0AnO1xuXG4gIC8qKlxuICAgKiBBbiBvcHRpb25hbCBrZXlib2FyZCBzaG9ydGN1dCB0aGF0IHdpbGwgdHJpZ2dlciB0aGUgbWVudSB0byBhcHBlYXJcbiAgICovXG4gIEBJbnB1dCgpIGtleWJvYXJkU2hvcnRjdXQ6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IHdpbGwgbWF0Y2ggdGhlIHNlYXJjaCB0ZXh0IGFmdGVyIHRoZSB0cmlnZ2VyIGNoYXJhY3RlclxuICAgKi9cbiAgQElucHV0KCkgc2VhcmNoUmVnZXhwID0gL15cXHcqJC87XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY2xvc2UgdGhlIG1lbnUgd2hlbiB0aGUgaG9zdCB0ZXh0YXJlYSBsb3NlcyBmb2N1c1xuICAgKi9cbiAgQElucHV0KCkgY2xvc2VNZW51T25CbHVyID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFRoZSBtZW51IGNvbXBvbmVudCB0byBzaG93IHdpdGggYXZhaWxhYmxlIG9wdGlvbnMuXG4gICAqIFlvdSBjYW4gZXh0ZW5kIHRoZSBidWlsdCBpbiBgVGV4dElucHV0QXV0b2NvbXBsZXRlTWVudUNvbXBvbmVudGAgY29tcG9uZW50IHRvIHVzZSBhIGN1c3RvbSB0ZW1wbGF0ZVxuICAgKi9cbiAgQElucHV0KCkgbWVudUNvbXBvbmVudCA9IFRleHRJbnB1dEF1dG9jb21wbGV0ZU1lbnVDb21wb25lbnQ7XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBvcHRpb25zIG1lbnUgaXMgc2hvd25cbiAgICovXG4gIEBPdXRwdXQoKSBtZW51U2hvd24gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBvcHRpb25zIG1lbnUgaXMgaGlkZGVuXG4gICAqL1xuICBAT3V0cHV0KCkgbWVudUhpZGRlbiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gYSBjaG9pY2UgaXMgc2VsZWN0ZWRcbiAgICovXG4gIEBPdXRwdXQoKSBjaG9pY2VTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hvaWNlU2VsZWN0ZWRFdmVudD4oKTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYSBzZWFyY2ggc3RyaW5nIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGNob2ljZXMuIENhbiBhbHNvIHJldHVybiBhIHByb21pc2UuXG4gICAqL1xuICBASW5wdXQoKSBmaW5kQ2hvaWNlczogKHNlYXJjaFRleHQ6IHN0cmluZykgPT4gYW55W10gfCBQcm9taXNlPGFueVtdPjtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGZvcm1hdHMgdGhlIHNlbGVjdGVkIGNob2ljZSBvbmNlIHNlbGVjdGVkLlxuICAgKi9cbiAgQElucHV0KCkgZ2V0Q2hvaWNlTGFiZWw6IChjaG9pY2U6IGFueSkgPT4gc3RyaW5nID0gY2hvaWNlID0+IGNob2ljZTtcblxuICAvKiB0c2xpbnQ6ZGlzYWJsZSBtZW1iZXItb3JkZXJpbmcgKi9cbiAgcHJpdmF0ZSBtZW51OlxuICAgIHwge1xuICAgICAgICBjb21wb25lbnQ6IENvbXBvbmVudFJlZjxUZXh0SW5wdXRBdXRvY29tcGxldGVNZW51Q29tcG9uZW50PjtcbiAgICAgICAgdHJpZ2dlckNoYXJhY3RlclBvc2l0aW9uOiBudW1iZXI7XG4gICAgICAgIGxhc3RDYXJldFBvc2l0aW9uPzogbnVtYmVyO1xuICAgICAgfVxuICAgIHwgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgbWVudUhpZGRlbiQgPSBuZXcgU3ViamVjdCgpO1xuXG4gIHByaXZhdGUgdXNpbmdTaG9ydGN1dCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY29tcG9uZW50RmFjdG9yeVJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgcHJpdmF0ZSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByaXZhdGUgZWxtOiBFbGVtZW50UmVmXG4gICkge31cblxuICBASG9zdExpc3RlbmVyKCdrZXlwcmVzcycsIFsnJGV2ZW50LmtleSddKVxuICBvbktleXByZXNzKGtleTogc3RyaW5nKSB7XG4gICAgaWYgKGtleSA9PT0gdGhpcy50cmlnZ2VyQ2hhcmFjdGVyKSB7XG4gICAgICB0aGlzLnVzaW5nU2hvcnRjdXQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2hvd01lbnUoKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcbiAgb25LZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgaWYgKHRoaXMua2V5Ym9hcmRTaG9ydGN1dCAmJiB0aGlzLmtleWJvYXJkU2hvcnRjdXQoZXZlbnQpKSB7XG4gICAgICB0aGlzLnVzaW5nU2hvcnRjdXQgPSB0cnVlO1xuICAgICAgdGhpcy5zaG93TWVudSgpO1xuICAgICAgdGhpcy5vbkNoYW5nZSgnJyk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignaW5wdXQnLCBbJyRldmVudC50YXJnZXQudmFsdWUnXSlcbiAgb25DaGFuZ2UodmFsdWU6IHN0cmluZykge1xuICAgIGlmICh0aGlzLm1lbnUpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdmFsdWVbdGhpcy5tZW51LnRyaWdnZXJDaGFyYWN0ZXJQb3NpdGlvbl0gIT09IHRoaXMudHJpZ2dlckNoYXJhY3RlciAmJlxuICAgICAgICAhdGhpcy51c2luZ1Nob3J0Y3V0XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaWRlTWVudSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY3Vyc29yID0gdGhpcy5lbG0ubmF0aXZlRWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgaWYgKGN1cnNvciA8IHRoaXMubWVudS50cmlnZ2VyQ2hhcmFjdGVyUG9zaXRpb24pIHtcbiAgICAgICAgICB0aGlzLmhpZGVNZW51KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMudXNpbmdTaG9ydGN1dCAmJiAhdGhpcy5tZW51KSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMudHJpZ2dlckNoYXJhY3RlcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy51c2luZ1Nob3J0Y3V0ID8gMCA6IDE7XG4gICAgICAgICAgY29uc3Qgc2VhcmNoVGV4dCA9IHZhbHVlLnNsaWNlKFxuICAgICAgICAgICAgdGhpcy5tZW51LnRyaWdnZXJDaGFyYWN0ZXJQb3NpdGlvbiArIG9mZnNldCxcbiAgICAgICAgICAgIGN1cnNvclxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoIXNlYXJjaFRleHQubWF0Y2godGhpcy5zZWFyY2hSZWdleHApKSB7XG4gICAgICAgICAgICB0aGlzLmhpZGVNZW51KCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuaW5zdGFuY2Uuc2VhcmNoVGV4dCA9IHNlYXJjaFRleHQ7XG4gICAgICAgICAgICB0aGlzLm1lbnUuY29tcG9uZW50Lmluc3RhbmNlLmNob2ljZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuaW5zdGFuY2UuY2hvaWNlTG9hZEVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5tZW51LmNvbXBvbmVudC5pbnN0YW5jZS5jaG9pY2VMb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHRoaXMuZmluZENob2ljZXMoc2VhcmNoVGV4dCkpXG4gICAgICAgICAgICAgIC50aGVuKGNob2ljZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1lbnUpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuaW5zdGFuY2UuY2hvaWNlcyA9IGNob2ljZXM7XG4gICAgICAgICAgICAgICAgICB0aGlzLm1lbnUuY29tcG9uZW50Lmluc3RhbmNlLmNob2ljZUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWVudSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5tZW51LmNvbXBvbmVudC5pbnN0YW5jZS5jaG9pY2VMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB0aGlzLm1lbnUuY29tcG9uZW50Lmluc3RhbmNlLmNob2ljZUxvYWRFcnJvciA9IGVycjtcbiAgICAgICAgICAgICAgICAgIHRoaXMubWVudS5jb21wb25lbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpXG4gIG9uQmx1cigpIHtcbiAgICBpZiAodGhpcy5tZW51KSB7XG4gICAgICB0aGlzLm1lbnUubGFzdENhcmV0UG9zaXRpb24gPSB0aGlzLmVsbS5uYXRpdmVFbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuXG4gICAgICBpZiAodGhpcy5jbG9zZU1lbnVPbkJsdXIgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5oaWRlTWVudSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2hvd01lbnUoKSB7XG4gICAgaWYgKCF0aGlzLm1lbnUpIHtcbiAgICAgIGNvbnN0IG1lbnVGYWN0b3J5ID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3Rvcnk8XG4gICAgICAgIFRleHRJbnB1dEF1dG9jb21wbGV0ZU1lbnVDb21wb25lbnRcbiAgICAgID4odGhpcy5tZW51Q29tcG9uZW50KTtcbiAgICAgIHRoaXMubWVudSA9IHtcbiAgICAgICAgY29tcG9uZW50OiB0aGlzLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KFxuICAgICAgICAgIG1lbnVGYWN0b3J5LFxuICAgICAgICAgIDAsXG4gICAgICAgICAgdGhpcy5pbmplY3RvclxuICAgICAgICApLFxuICAgICAgICB0cmlnZ2VyQ2hhcmFjdGVyUG9zaXRpb246IHRoaXMuZWxtLm5hdGl2ZUVsZW1lbnQuc2VsZWN0aW9uU3RhcnRcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSB0aGlzLmdldExpbmVIZWlnaHQodGhpcy5lbG0ubmF0aXZlRWxlbWVudCk7XG4gICAgICBjb25zdCB7IHRvcCwgbGVmdCB9ID0gZ2V0Q2FyZXRDb29yZGluYXRlcyhcbiAgICAgICAgdGhpcy5lbG0ubmF0aXZlRWxlbWVudCxcbiAgICAgICAgdGhpcy5lbG0ubmF0aXZlRWxlbWVudC5zZWxlY3Rpb25TdGFydFxuICAgICAgKTtcbiAgICAgIHRoaXMubWVudS5jb21wb25lbnQuaW5zdGFuY2UucG9zaXRpb24gPSB7XG4gICAgICAgIHRvcDogdG9wICsgbGluZUhlaWdodCxcbiAgICAgICAgbGVmdFxuICAgICAgfTtcbiAgICAgIHRoaXMubWVudS5jb21wb25lbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdGhpcy5tZW51LmNvbXBvbmVudC5pbnN0YW5jZS5zZWxlY3RDaG9pY2VcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubWVudUhpZGRlbiQpKVxuICAgICAgICAuc3Vic2NyaWJlKGNob2ljZSA9PiB7XG4gICAgICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmdldENob2ljZUxhYmVsKGNob2ljZSk7XG4gICAgICAgICAgY29uc3QgdGV4dGFyZWE6IEhUTUxUZXh0QXJlYUVsZW1lbnQgPSB0aGlzLmVsbS5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSB0ZXh0YXJlYS52YWx1ZTtcbiAgICAgICAgICBjb25zdCBzdGFydEluZGV4ID0gdGhpcy5tZW51IS50cmlnZ2VyQ2hhcmFjdGVyUG9zaXRpb247XG4gICAgICAgICAgY29uc3Qgc3RhcnQgPSB2YWx1ZS5zbGljZSgwLCBzdGFydEluZGV4KTtcbiAgICAgICAgICBjb25zdCBjYXJldFBvc2l0aW9uID1cbiAgICAgICAgICAgIHRoaXMubWVudSEubGFzdENhcmV0UG9zaXRpb24gfHwgdGV4dGFyZWEuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgY29uc3QgZW5kID0gdmFsdWUuc2xpY2UoY2FyZXRQb3NpdGlvbik7XG4gICAgICAgICAgdGV4dGFyZWEudmFsdWUgPSBzdGFydCArIGxhYmVsICsgZW5kO1xuICAgICAgICAgIC8vIGZvcmNlIG5nIG1vZGVsIC8gZm9ybSBjb250cm9sIHRvIHVwZGF0ZVxuICAgICAgICAgIHRleHRhcmVhLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdpbnB1dCcpKTtcbiAgICAgICAgICB0aGlzLmhpZGVNZW51KCk7XG4gICAgICAgICAgY29uc3Qgc2V0Q3Vyc29yQXQgPSAoc3RhcnQgKyBsYWJlbCkubGVuZ3RoO1xuICAgICAgICAgIHRleHRhcmVhLnNldFNlbGVjdGlvblJhbmdlKHNldEN1cnNvckF0LCBzZXRDdXJzb3JBdCk7XG4gICAgICAgICAgdGV4dGFyZWEuZm9jdXMoKTtcbiAgICAgICAgICB0aGlzLmNob2ljZVNlbGVjdGVkLmVtaXQoe1xuICAgICAgICAgICAgY2hvaWNlLFxuICAgICAgICAgICAgaW5zZXJ0ZWRBdDoge1xuICAgICAgICAgICAgICBzdGFydDogc3RhcnRJbmRleCxcbiAgICAgICAgICAgICAgZW5kOiBzdGFydEluZGV4ICsgbGFiZWwubGVuZ3RoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgdGhpcy5tZW51U2hvd24uZW1pdCgpO1xuICAgIH1cbiAgfVxuXG4gIGdldExpbmVIZWlnaHQoZWxtOiBIVE1MRWxlbWVudCk6IG51bWJlciB7XG4gICAgY29uc3QgbGluZUhlaWdodFN0ciA9IGdldENvbXB1dGVkU3R5bGUoZWxtKS5saW5lSGVpZ2h0IHx8ICcnO1xuICAgIGNvbnN0IGZvbnRTaXplU3RyID0gZ2V0Q29tcHV0ZWRTdHlsZShlbG0pLmZvbnRTaXplIHx8ICcnO1xuICAgIGNvbnN0IGZvbnRTaXplID0gK3RvUFgoZm9udFNpemVTdHIpO1xuICAgIGNvbnN0IG5vcm1hbCA9IDEuMjtcbiAgICBjb25zdCBsaW5lSGVpZ2h0TnVtID0gcGFyc2VGbG9hdChsaW5lSGVpZ2h0U3RyKTtcblxuICAgIGlmIChsaW5lSGVpZ2h0U3RyID09PSBsaW5lSGVpZ2h0TnVtICsgJycpIHtcbiAgICAgIHJldHVybiBmb250U2l6ZSAqIGxpbmVIZWlnaHROdW07XG4gICAgfVxuXG4gICAgaWYgKGxpbmVIZWlnaHRTdHIudG9Mb3dlckNhc2UoKSA9PT0gJ25vcm1hbCcpIHtcbiAgICAgIHJldHVybiBmb250U2l6ZSAqIG5vcm1hbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdG9QWChsaW5lSGVpZ2h0U3RyKTtcbiAgfVxuXG4gIHByaXZhdGUgaGlkZU1lbnUoKSB7XG4gICAgaWYgKHRoaXMubWVudSkge1xuICAgICAgdGhpcy5tZW51LmNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICB0aGlzLm1lbnVIaWRkZW4kLm5leHQoKTtcbiAgICAgIHRoaXMubWVudUhpZGRlbi5lbWl0KCk7XG4gICAgICB0aGlzLm1lbnUgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5oaWRlTWVudSgpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbXdsLXRleHQtaW5wdXQtYXV0b2NvbXBsZXRlLWNvbnRhaW5lcicsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIDpob3N0IHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIH1cbiAgICBgXG4gIF0sXG4gIHRlbXBsYXRlOiAnPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50Pidcbn0pXG5leHBvcnQgY2xhc3MgVGV4dElucHV0QXV0b2NvbXBsZXRlQ29udGFpbmVyQ29tcG9uZW50IHt9XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFRleHRJbnB1dEF1dG9jb21wbGV0ZURpcmVjdGl2ZSB9IGZyb20gJy4vdGV4dC1pbnB1dC1hdXRvY29tcGxldGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IFRleHRJbnB1dEF1dG9jb21wbGV0ZUNvbnRhaW5lckNvbXBvbmVudCB9IGZyb20gJy4vdGV4dC1pbnB1dC1hdXRvY29tcGxldGUtY29udGFpbmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUZXh0SW5wdXRBdXRvY29tcGxldGVNZW51Q29tcG9uZW50IH0gZnJvbSAnLi90ZXh0LWlucHV0LWF1dG9jb21wbGV0ZS1tZW51LmNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFRleHRJbnB1dEF1dG9jb21wbGV0ZURpcmVjdGl2ZSxcbiAgICBUZXh0SW5wdXRBdXRvY29tcGxldGVDb250YWluZXJDb21wb25lbnQsXG4gICAgVGV4dElucHV0QXV0b2NvbXBsZXRlTWVudUNvbXBvbmVudFxuICBdLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgZXhwb3J0czogW1xuICAgIFRleHRJbnB1dEF1dG9jb21wbGV0ZURpcmVjdGl2ZSxcbiAgICBUZXh0SW5wdXRBdXRvY29tcGxldGVDb250YWluZXJDb21wb25lbnQsXG4gICAgVGV4dElucHV0QXV0b2NvbXBsZXRlTWVudUNvbXBvbmVudFxuICBdLFxuICBlbnRyeUNvbXBvbmVudHM6IFtUZXh0SW5wdXRBdXRvY29tcGxldGVNZW51Q29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBUZXh0SW5wdXRBdXRvY29tcGxldGVNb2R1bGUge31cbiJdLCJuYW1lcyI6WyJTdWJqZWN0IiwiQ29tcG9uZW50IiwiVmlld0NoaWxkIiwiSG9zdExpc3RlbmVyIiwiRXZlbnRFbWl0dGVyIiwidGFrZVVudGlsIiwiRGlyZWN0aXZlIiwiQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyIiwiVmlld0NvbnRhaW5lclJlZiIsIkluamVjdG9yIiwiRWxlbWVudFJlZiIsIklucHV0IiwiT3V0cHV0IiwiTmdNb2R1bGUiLCJDb21tb25Nb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7Z0NBb0NpQixJQUFJQSxZQUFPLEVBQUU7aUNBSVosS0FBSzs2QkFFVCxVQUFDLEtBQWEsRUFBRSxNQUFXO2dCQUNyQyxPQUFBLE9BQU8sTUFBTSxDQUFDLEVBQUUsS0FBSyxXQUFXLEdBQUcsTUFBTSxDQUFDLEVBQUUsR0FBRyxNQUFNO2FBQUE7O1FBRXZELHNCQUFJLHVEQUFPOzs7Z0JBT1g7Z0JBQ0UsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO2FBQ3RCOzs7O2dCQVRELFVBQVksT0FBYztnQkFDeEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7Z0JBQ3hCLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ25FLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNoQzthQUNGOzs7V0FBQTs7Ozs7UUFPRCx3REFBVzs7OztZQURYLFVBQ1ksS0FBb0I7Z0JBQzlCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIscUJBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDdEQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRTtvQkFDM0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7aUJBQ2hDO2FBQ0Y7Ozs7O1FBR0Qs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