@muzykantov/ngx-dadata
Version:
Angular 6+ [DaData][dadata] suggestion (подсказки) implementation
468 lines (458 loc) • 34.5 kB
JavaScript
import { Injectable, Component, EventEmitter, forwardRef, HostListener, Input, Output, Renderer2, ViewChild, NgModule, defineInjectable, inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Subject, timer } from 'rxjs';
import { debounce } from 'rxjs/operators';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
var DaDataType = {
fio: "fio",
address: "address",
party: "party",
bank: "bank",
email: "email",
};
var NgxDaDataService = /** @class */ (function () {
function NgxDaDataService(http) {
this.http = http;
this.apiKey = '';
}
/**
* @param {?} key
* @return {?}
*/
NgxDaDataService.prototype.setApiKey = /**
* @param {?} key
* @return {?}
*/
function (key) {
this.apiKey = key;
};
/**
* @param {?} value
* @param {?=} type
* @param {?=} count
* @param {?=} options
* @return {?}
*/
NgxDaDataService.prototype.getData = /**
* @param {?} value
* @param {?=} type
* @param {?=} count
* @param {?=} options
* @return {?}
*/
function (value, type, count, options) {
if (type === void 0) { type = DaDataType.address; }
if (count === void 0) { count = 10; }
if (options === void 0) { options = null; }
/** @type {?} */
var httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token ' + this.apiKey,
})
};
/** @type {?} */
var body = Object.assign({ query: value, count: count }, options);
return this.http.post("https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/" + type, body, httpOptions);
};
NgxDaDataService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
NgxDaDataService.ctorParameters = function () { return [
{ type: HttpClient }
]; };
/** @nocollapse */ NgxDaDataService.ngInjectableDef = defineInjectable({ factory: function NgxDaDataService_Factory() { return new NgxDaDataService(inject(HttpClient)); }, token: NgxDaDataService, providedIn: "root" });
return NgxDaDataService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
var DaDataConfigDefault = {
apiKey: '',
type: DaDataType.address,
delay: 500,
limit: 10,
width: 'auto',
minWidth: '0',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
var NGX_DADATA_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return NgxDaDataComponent; }),
multi: true
};
/*const NGX_DADATA_VALIDATOR = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NgxDaDataComponent),
multi: true,
};*/
/**
* @param {?} value
* @return {?}
*/
function createDaDataValidator(value) {
return function (c) {
/** @type {?} */
var err = {
rangeError: {
given: c.value,
expected: value,
}
};
return (c.value !== value) ? err : null;
};
}
var NgxDaDataComponent = /** @class */ (function () {
function NgxDaDataComponent(dataService, _r) {
this.dataService = dataService;
this._r = _r;
this._value = '';
this.currentFocus = -1;
this.data = [];
this.config = DaDataConfigDefault;
this.disabled = null;
this.type = DaDataType.address;
this.options = null;
this.limit = DaDataConfigDefault.limit;
this.placeholder = '';
this.selected = new EventEmitter();
this.input = new EventEmitter();
this.inputString$ = new Subject();
// onSuggestionSelected = (value: string) => {};
this.onTouched = function () { };
this.propagateChange = function () { };
this.validateFn = function () { };
}
Object.defineProperty(NgxDaDataComponent.prototype, "value", {
get: /**
* @return {?}
*/
function () {
return this._value;
},
set: /**
* @param {?} v
* @return {?}
*/
function (v) {
if (v !== this._value) {
this._value = v;
this.propagateChange(v);
this.input.emit(v);
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
NgxDaDataComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
/*this.validateFn = createDaDataValidator(this._value);
this.propagateChange(this._value);*/
this.type = this.config.type;
this.dataService.setApiKey(this.apiKey ? this.apiKey : this.config.apiKey);
this.inputString$.pipe(debounce(function () { return timer(_this.config.delay ? _this.config.delay : 500); })).subscribe(function (x) {
_this.dataService.getData(x, _this.type, _this.limit, _this.options).subscribe(function (y) {
_this.data = y.suggestions;
});
});
};
/**
* @param {?} changes
* @return {?}
*/
NgxDaDataComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes.value) ;
};
/**
* @param {?} value
* @return {?}
*/
NgxDaDataComponent.prototype.getData = /**
* @param {?} value
* @return {?}
*/
function (value) {
this.inputString$.next(value);
this.currentFocus = -1;
};
/**
* @param {?} e
* @param {?} item
* @return {?}
*/
NgxDaDataComponent.prototype.onClick = /**
* @param {?} e
* @param {?} item
* @return {?}
*/
function (e, item) {
//e.preventDefault();
this.inputValue.nativeElement.value = item.value;
this.propagateChange(item.value);
this.inputValue.nativeElement.focus();
this.selectedSuggestion = item;
this.data = [];
this.currentFocus = -1;
//this.writeValue(item.value);
this.selected.emit(item);
// this.selectedData.emit(item.data);
// this.selectedString.emit(item.value);
};
/**
* @return {?}
*/
NgxDaDataComponent.prototype.onOutsideClick = /**
* @return {?}
*/
function () {
this.data = [];
};
/**
* @return {?}
*/
NgxDaDataComponent.prototype.onArrowDown = /**
* @return {?}
*/
function () {
this.removeFocus(this.currentFocus);
if (this.currentFocus >= this.data.length - 1) {
this.currentFocus = 0;
}
else {
this.currentFocus++;
}
this.setFocus(this.currentFocus);
};
/**
* @return {?}
*/
NgxDaDataComponent.prototype.onArrowUp = /**
* @return {?}
*/
function () {
this.removeFocus(this.currentFocus);
if (this.currentFocus === 0) {
this.currentFocus = this.data.length - 1;
}
else {
this.currentFocus--;
}
this.setFocus(this.currentFocus);
};
/**
* @return {?}
*/
NgxDaDataComponent.prototype.onEnter = /**
* @return {?}
*/
function () {
this.selectedSuggestion = this.data[this.currentFocus];
this.inputValue.nativeElement.value = this.selectedSuggestion.value;
this.data = [];
this.currentFocus = -1;
this.propagateChange(this.selectedSuggestion.value);
// this.writeValue(this.selectedSuggestion.value);
this.selected.emit(this.selectedSuggestion);
// this.selectedData.emit(this.selectedSuggestion.data);
// this.selectedString.emit(this.selectedSuggestion.value);
};
/**
* @param {?} id
* @return {?}
*/
NgxDaDataComponent.prototype.setFocus = /**
* @param {?} id
* @return {?}
*/
function (id) {
/** @type {?} */
var activeEl = document.getElementById(id + "item");
this._r.addClass(activeEl, "active");
};
/**
* @param {?} id
* @return {?}
*/
NgxDaDataComponent.prototype.removeFocus = /**
* @param {?} id
* @return {?}
*/
function (id) {
if (id !== -1) {
/** @type {?} */
var activeEl = document.getElementById(id + "item");
this._r.removeClass(activeEl, "active");
}
};
/**
* @param {?} value
* @return {?}
*/
NgxDaDataComponent.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (value !== undefined) {
this._value = value;
}
// this.onSuggestionSelected(value);
};
/**
* Set the function to be called
* when the control receives a change event.
*
* @param fn a function
*/
/**
* Set the function to be called
* when the control receives a change event.
*
* @param {?} fn a function
* @return {?}
*/
NgxDaDataComponent.prototype.registerOnChange = /**
* Set the function to be called
* when the control receives a change event.
*
* @param {?} fn a function
* @return {?}
*/
function (fn) {
// this.onSuggestionSelected = fn;
this.propagateChange = fn;
};
/**
* Set the function to be called
* when the control receives a touch event.
*
* @param fn a function
*/
/**
* Set the function to be called
* when the control receives a touch event.
*
* @param {?} fn a function
* @return {?}
*/
NgxDaDataComponent.prototype.registerOnTouched = /**
* Set the function to be called
* when the control receives a touch event.
*
* @param {?} fn a function
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* Implements disabled state for this element
*
* @param isDisabled
*/
/**
* Implements disabled state for this element
*
* @param {?} isDisabled
* @return {?}
*/
NgxDaDataComponent.prototype.setDisabledState = /**
* Implements disabled state for this element
*
* @param {?} isDisabled
* @return {?}
*/
function (isDisabled) {
alert("disabled!");
this.disabled = isDisabled;
};
NgxDaDataComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-da-data',
template: "<div class=\"autocomplete\">\r\n <label for=\"address_input\"></label>\r\n <input [disabled]=\"disabled ? true : null\" type=\"text\" id=\"address_input\" name=\"address\" class=\"search\" #inputValue (input)=\"getData(inputValue.value)\"\r\n [placeholder]=\"placeholder\" (keyup.ArrowDown)=\"onArrowDown()\" (keyup.ArrowUp)=\"onArrowUp()\"\r\n (keyup.Enter)=\"onEnter()\" spellcheck=\"false\" [(ngModel)]=\"value\" autocomplete=\"new-password\" />\r\n <div *ngIf=\"data.length\">\r\n <div class=\"autocomplete-items\">\r\n <div class=\"autocomplele-item\" *ngFor=\"let item of data;let i = index\" (click)=\"onClick($event, item)\" [id]=\"i+'item'\">\r\n {{item.value}}\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n",
providers: [NGX_DADATA_VALUE_ACCESSOR,],
styles: [".autocomplete{position:relative}input{border:0 solid transparent;background-color:#f1f1f1;padding:5px}input[type=text]{background-color:#f1f1f1;width:100%}input[type=submit]{background-color:#1e90ff;color:#fff}.autocomplete-items{position:absolute;border:1px solid #d4d4d4;border-bottom:none;border-top:none;z-index:99;top:100%;left:0;right:0}.autocomplete-items .autocomplele-item{padding:5px 10px;cursor:pointer;background-color:#fff;border-bottom:1px solid #d4d4d4}.autocomplete-items .autocomplele-item:hover{background-color:#e9e9e9}.autocomplete-items .autocomplele-item.active{background-color:#1e90ff!important;color:#fff}"]
}] }
];
NgxDaDataComponent.ctorParameters = function () { return [
{ type: NgxDaDataService },
{ type: Renderer2 }
]; };
NgxDaDataComponent.propDecorators = {
config: [{ type: Input }],
apiKey: [{ type: Input }],
disabled: [{ type: Input }],
type: [{ type: Input }],
options: [{ type: Input }],
limit: [{ type: Input }],
placeholder: [{ type: Input }],
selectedSuggestion: [{ type: Output }],
selected: [{ type: Output }],
input: [{ type: Output }],
inputValue: [{ type: ViewChild, args: ['inputValue',] }],
onOutsideClick: [{ type: HostListener, args: ['document:click',] }]
};
return NgxDaDataComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var NgxDaDataModule = /** @class */ (function () {
function NgxDaDataModule() {
}
NgxDaDataModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FormsModule
],
declarations: [NgxDaDataComponent],
exports: [NgxDaDataComponent]
},] }
];
return NgxDaDataModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { DaDataType, NgxDaDataService, createDaDataValidator, NgxDaDataComponent, NgxDaDataModule, DaDataConfigDefault };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV6eWthbnRvdi1uZ3gtZGFkYXRhLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AbXV6eWthbnRvdi9uZ3gtZGFkYXRhL2xpYi9uZ3gtZGEtZGF0YS5zZXJ2aWNlLnRzIiwibmc6Ly9AbXV6eWthbnRvdi9uZ3gtZGFkYXRhL2xpYi9kYS1kYXRhLWNvbmZpZy50cyIsIm5nOi8vQG11enlrYW50b3Yvbmd4LWRhZGF0YS9saWIvbmd4LWRhLWRhdGEuY29tcG9uZW50LnRzIiwibmc6Ly9AbXV6eWthbnRvdi9uZ3gtZGFkYXRhL2xpYi9uZ3gtZGEtZGF0YS5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0h0dHBDbGllbnQsIEh0dHBIZWFkZXJzfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcclxuaW1wb3J0IHtPYnNlcnZhYmxlfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge0RhRGF0YVJlc3BvbnNlfSBmcm9tIFwiLi9tb2RlbHMvZGEtZGF0YS1yZXNwb25zZVwiO1xyXG5cclxuZXhwb3J0IGVudW0gRGFEYXRhVHlwZSB7XHJcbiAgZmlvID0gXCJmaW9cIixcclxuICBhZGRyZXNzID0gXCJhZGRyZXNzXCIsXHJcbiAgcGFydHkgPSBcInBhcnR5XCIsXHJcbiAgYmFuayA9IFwiYmFua1wiLFxyXG4gIGVtYWlsID0gXCJlbWFpbFwiXHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIE5neERhRGF0YVNlcnZpY2Uge1xyXG4gIGFwaUtleSA9ICcnO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQpIHsgfVxyXG5cclxuICBzZXRBcGlLZXkoa2V5OiBzdHJpbmcpIHtcclxuICAgIHRoaXMuYXBpS2V5ID0ga2V5O1xyXG4gIH1cclxuXHJcbiAgZ2V0RGF0YSh2YWx1ZTogc3RyaW5nLCB0eXBlOiBEYURhdGFUeXBlID0gRGFEYXRhVHlwZS5hZGRyZXNzLCBjb3VudDogbnVtYmVyID0gMTAsIG9wdGlvbnM6IGFueSA9IG51bGwpOiBPYnNlcnZhYmxlPERhRGF0YVJlc3BvbnNlPntcclxuICAgIGNvbnN0IGh0dHBPcHRpb25zID0ge1xyXG4gICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMoe1xyXG4gICAgICAgICdBY2NlcHQnOiAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiAnVG9rZW4gJyArIHRoaXMuYXBpS2V5LFxyXG4gICAgICB9KVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbih7IHF1ZXJ5OiB2YWx1ZSwgY291bnQ6IGNvdW50IH0sIG9wdGlvbnMpO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PERhRGF0YVJlc3BvbnNlPihcImh0dHBzOi8vc3VnZ2VzdGlvbnMuZGFkYXRhLnJ1L3N1Z2dlc3Rpb25zL2FwaS80XzEvcnMvc3VnZ2VzdC9cIiArIHR5cGUsIGJvZHksIGh0dHBPcHRpb25zKVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQge0RhRGF0YVR5cGV9IGZyb20gXCIuL25neC1kYS1kYXRhLnNlcnZpY2VcIjtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRGFEYXRhQ29uZmlnIHtcclxuICBhcGlLZXk6IHN0cmluZztcclxuICB0eXBlPzogRGFEYXRhVHlwZSxcclxuICBkZWxheT86IG51bWJlcjtcclxuICBsaW1pdD86IG51bWJlcjtcclxuICB3aWR0aD86ICdhdXRvJyB8IHN0cmluZyxcclxuICBtaW5XaWR0aD86ICcwJyB8IHN0cmluZyxcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IERhRGF0YUNvbmZpZ0RlZmF1bHQ6IERhRGF0YUNvbmZpZyA9IHtcclxuICBhcGlLZXk6ICcnLFxyXG4gIHR5cGU6IERhRGF0YVR5cGUuYWRkcmVzcyxcclxuICBkZWxheTogNTAwLFxyXG4gIGxpbWl0OiAxMCxcclxuICB3aWR0aDogJ2F1dG8nLFxyXG4gIG1pbldpZHRoOiAnMCcsXHJcbn07XHJcbiIsImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIGZvcndhcmRSZWYsXHJcbiAgSG9zdExpc3RlbmVyLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFJlbmRlcmVyMixcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0RhRGF0YVR5cGUsIE5neERhRGF0YVNlcnZpY2V9IGZyb20gXCIuL25neC1kYS1kYXRhLnNlcnZpY2VcIjtcclxuaW1wb3J0IHtTdWJqZWN0LCB0aW1lcn0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHtkZWJvdW5jZX0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XHJcbmltcG9ydCB7RGFEYXRhUmVzcG9uc2V9IGZyb20gXCIuL21vZGVscy9kYS1kYXRhLXJlc3BvbnNlXCI7XHJcbmltcG9ydCB7RGFEYXRhU3VnZ2VzdGlvbn0gZnJvbSBcIi4vbW9kZWxzL3N1Z2dlc3Rpb25cIjtcclxuaW1wb3J0IHtEYURhdGFDb25maWcsIERhRGF0YUNvbmZpZ0RlZmF1bHR9IGZyb20gXCIuL2RhLWRhdGEtY29uZmlnXCI7XHJcbmltcG9ydCB7Q29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBOR19WQUxJREFUT1JTLCBOR19WQUxVRV9BQ0NFU1NPUn0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcbmltcG9ydCB7RGFEYXRhQWRkcmVzcywgRGFEYXRhQmFuaywgRGFEYXRhRW1haWwsIERhRGF0YUZJTywgRGFEYXRhUGFydHl9IGZyb20gXCIuL21vZGVscy9kYXRhXCI7XHJcblxyXG5jb25zdCBOR1hfREFEQVRBX1ZBTFVFX0FDQ0VTU09SID0ge1xyXG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neERhRGF0YUNvbXBvbmVudCksXHJcbiAgbXVsdGk6IHRydWVcclxufTtcclxuXHJcbi8qY29uc3QgTkdYX0RBREFUQV9WQUxJREFUT1IgPSB7XHJcbiAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcclxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOZ3hEYURhdGFDb21wb25lbnQpLFxyXG4gIG11bHRpOiB0cnVlLFxyXG59OyovXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGFEYXRhVmFsaWRhdG9yKHZhbHVlKSB7XHJcbiAgcmV0dXJuIChjOiBGb3JtQ29udHJvbCkgPT4ge1xyXG4gICAgY29uc3QgZXJyID0ge1xyXG4gICAgICByYW5nZUVycm9yOiB7XHJcbiAgICAgICAgZ2l2ZW46IGMudmFsdWUsXHJcbiAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiAoYy52YWx1ZSAhPT0gdmFsdWUpID8gZXJyIDogbnVsbDtcclxuICB9O1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25neC1kYS1kYXRhJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vbmd4LWRhLWRhdGEuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL25neC1kYS1kYXRhLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgcHJvdmlkZXJzOiBbTkdYX0RBREFUQV9WQUxVRV9BQ0NFU1NPUiwgLypOR1hfREFEQVRBX1ZBTElEQVRPUiovXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd4RGFEYXRhQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzIHtcclxuICBwcml2YXRlIF92YWx1ZTogYW55ID0gJyc7XHJcbiAgY3VycmVudEZvY3VzID0gLTE7XHJcblxyXG4gIGRhdGE6IERhRGF0YVN1Z2dlc3Rpb25bXSA9IFtdO1xyXG5cclxuICBASW5wdXQoKSBjb25maWc6IERhRGF0YUNvbmZpZyA9IERhRGF0YUNvbmZpZ0RlZmF1bHQ7XHJcbiAgQElucHV0KCkgYXBpS2V5OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBudWxsO1xyXG4gIEBJbnB1dCgpIHR5cGUgPSBEYURhdGFUeXBlLmFkZHJlc3M7XHJcbiAgQElucHV0KCkgb3B0aW9ucyA9IG51bGw7XHJcbiAgQElucHV0KCkgbGltaXQgPSBEYURhdGFDb25maWdEZWZhdWx0LmxpbWl0O1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gJyc7XHJcblxyXG4gIEBPdXRwdXQoKSBzZWxlY3RlZFN1Z2dlc3Rpb246IERhRGF0YVN1Z2dlc3Rpb247XHJcbiAgQE91dHB1dCgpIHNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxEYURhdGFTdWdnZXN0aW9uPigpO1xyXG4gIEBPdXRwdXQoKSBpbnB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIC8vIEBPdXRwdXQoKSBzZWxlY3RlZERhdGEgPSBuZXcgRXZlbnRFbWl0dGVyPERhRGF0YUFkZHJlc3MgfCBEYURhdGFGSU8gfCBEYURhdGFCYW5rIHwgRGFEYXRhUGFydHkgfCBEYURhdGFFbWFpbD4oKTtcclxuICAvLyBAT3V0cHV0KCkgc2VsZWN0ZWRTdHJpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnaW5wdXRWYWx1ZScpIGlucHV0VmFsdWU6IEVsZW1lbnRSZWY7XHJcblxyXG4gIHByaXZhdGUgaW5wdXRTdHJpbmckID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xyXG5cclxuICAvLyBvblN1Z2dlc3Rpb25TZWxlY3RlZCA9ICh2YWx1ZTogc3RyaW5nKSA9PiB7fTtcclxuICBvblRvdWNoZWQgPSAoKSA9PiB7fTtcclxuICBwcm9wYWdhdGVDaGFuZ2U6IGFueSA9ICgpID0+IHt9O1xyXG4gIHZhbGlkYXRlRm46IGFueSA9ICgpID0+IHt9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGFTZXJ2aWNlOiBOZ3hEYURhdGFTZXJ2aWNlLCBwcml2YXRlIF9yOiBSZW5kZXJlcjIpIHtcclxuICB9XHJcblxyXG4gIGdldCB2YWx1ZSgpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gIH1cclxuXHJcbiAgc2V0IHZhbHVlKHY6IGFueSkge1xyXG4gICAgaWYgKHYgIT09IHRoaXMuX3ZhbHVlKSB7XHJcbiAgICAgIHRoaXMuX3ZhbHVlID0gdjtcclxuICAgICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2Uodik7XHJcblxyXG4gICAgICB0aGlzLmlucHV0LmVtaXQodik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIC8qdGhpcy52YWxpZGF0ZUZuID0gY3JlYXRlRGFEYXRhVmFsaWRhdG9yKHRoaXMuX3ZhbHVlKTtcclxuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlKHRoaXMuX3ZhbHVlKTsqL1xyXG4gICAgdGhpcy50eXBlID0gdGhpcy5jb25maWcudHlwZTsgICAgXHJcbiAgICB0aGlzLmRhdGFTZXJ2aWNlLnNldEFwaUtleSh0aGlzLmFwaUtleSA/IHRoaXMuYXBpS2V5IDogdGhpcy5jb25maWcuYXBpS2V5KTtcclxuICAgIHRoaXMuaW5wdXRTdHJpbmckLnBpcGUoXHJcbiAgICAgIGRlYm91bmNlKCgpID0+IHRpbWVyKHRoaXMuY29uZmlnLmRlbGF5ID8gdGhpcy5jb25maWcuZGVsYXkgOiA1MDApKSxcclxuICAgICkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICB0aGlzLmRhdGFTZXJ2aWNlLmdldERhdGEoeCwgdGhpcy50eXBlLCB0aGlzLmxpbWl0LCB0aGlzLm9wdGlvbnMpLnN1YnNjcmliZSgoeTogRGFEYXRhUmVzcG9uc2UpID0+IHtcclxuICAgICAgICB0aGlzLmRhdGEgPSB5LnN1Z2dlc3Rpb25zO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgaWYgKGNoYW5nZXMudmFsdWUpIHtcclxuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXREYXRhKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuaW5wdXRTdHJpbmckLm5leHQodmFsdWUpO1xyXG4gICAgdGhpcy5jdXJyZW50Rm9jdXMgPSAtMTtcclxuICB9XHJcblxyXG4gIG9uQ2xpY2soZTogTW91c2VFdmVudCwgaXRlbTogRGFEYXRhU3VnZ2VzdGlvbikge1xyXG4gICAgLy9lLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLmlucHV0VmFsdWUubmF0aXZlRWxlbWVudC52YWx1ZSA9IGl0ZW0udmFsdWU7XHJcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZShpdGVtLnZhbHVlKTtcclxuICAgIHRoaXMuaW5wdXRWYWx1ZS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XHJcbiAgICB0aGlzLnNlbGVjdGVkU3VnZ2VzdGlvbiA9IGl0ZW07XHJcbiAgICB0aGlzLmRhdGEgPSBbXTtcclxuICAgIHRoaXMuY3VycmVudEZvY3VzID0gLTE7XHJcblxyXG4gICAgLy90aGlzLndyaXRlVmFsdWUoaXRlbS52YWx1ZSk7XHJcbiAgICB0aGlzLnNlbGVjdGVkLmVtaXQoaXRlbSk7XHJcbiAgICAvLyB0aGlzLnNlbGVjdGVkRGF0YS5lbWl0KGl0ZW0uZGF0YSk7XHJcbiAgICAvLyB0aGlzLnNlbGVjdGVkU3RyaW5nLmVtaXQoaXRlbS52YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycpXHJcbiAgb25PdXRzaWRlQ2xpY2soKSB7XHJcbiAgICB0aGlzLmRhdGEgPSBbXTtcclxuICB9XHJcblxyXG4gIG9uQXJyb3dEb3duKCkge1xyXG4gICAgdGhpcy5yZW1vdmVGb2N1cyh0aGlzLmN1cnJlbnRGb2N1cyk7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50Rm9jdXMgPj0gdGhpcy5kYXRhLmxlbmd0aCAtIDEpIHtcclxuICAgICAgdGhpcy5jdXJyZW50Rm9jdXMgPSAwO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdXJyZW50Rm9jdXMrKztcclxuICAgIH1cclxuICAgIHRoaXMuc2V0Rm9jdXModGhpcy5jdXJyZW50Rm9jdXMpO1xyXG4gIH1cclxuXHJcbiAgb25BcnJvd1VwKCkge1xyXG4gICAgdGhpcy5yZW1vdmVGb2N1cyh0aGlzLmN1cnJlbnRGb2N1cyk7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50Rm9jdXMgPT09IDApIHtcclxuICAgICAgdGhpcy5jdXJyZW50Rm9jdXMgPSB0aGlzLmRhdGEubGVuZ3RoIC0gMTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY3VycmVudEZvY3VzLS07XHJcbiAgICB9XHJcbiAgICB0aGlzLnNldEZvY3VzKHRoaXMuY3VycmVudEZvY3VzKTtcclxuICB9XHJcblxyXG4gIG9uRW50ZXIoKSB7XHJcbiAgICB0aGlzLnNlbGVjdGVkU3VnZ2VzdGlvbiA9IHRoaXMuZGF0YVt0aGlzLmN1cnJlbnRGb2N1c107XHJcbiAgICB0aGlzLmlucHV0VmFsdWUubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uLnZhbHVlO1xyXG4gICAgdGhpcy5kYXRhID0gW107XHJcbiAgICB0aGlzLmN1cnJlbnRGb2N1cyA9IC0xO1xyXG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy5zZWxlY3RlZFN1Z2dlc3Rpb24udmFsdWUpO1xyXG4gICAgLy8gdGhpcy53cml0ZVZhbHVlKHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uLnZhbHVlKTtcclxuICAgIHRoaXMuc2VsZWN0ZWQuZW1pdCh0aGlzLnNlbGVjdGVkU3VnZ2VzdGlvbik7XHJcbiAgICAvLyB0aGlzLnNlbGVjdGVkRGF0YS5lbWl0KHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uLmRhdGEpO1xyXG4gICAgLy8gdGhpcy5zZWxlY3RlZFN0cmluZy5lbWl0KHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uLnZhbHVlKTtcclxuICB9XHJcblxyXG4gIHNldEZvY3VzKGlkOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IGFjdGl2ZUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQgKyBcIml0ZW1cIik7XHJcbiAgICB0aGlzLl9yLmFkZENsYXNzKGFjdGl2ZUVsLCBcImFjdGl2ZVwiKTtcclxuICB9XHJcblxyXG4gIHJlbW92ZUZvY3VzKGlkOiBudW1iZXIpIHtcclxuICAgIGlmIChpZCAhPT0gLTEpIHtcclxuICAgICAgY29uc3QgYWN0aXZlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCArIFwiaXRlbVwiKTtcclxuICAgICAgdGhpcy5fci5yZW1vdmVDbGFzcyhhY3RpdmVFbCwgXCJhY3RpdmVcIik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgICAvLyB0aGlzLm9uU3VnZ2VzdGlvblNlbGVjdGVkKHZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldCB0aGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXHJcbiAgICogd2hlbiB0aGUgY29udHJvbCByZWNlaXZlcyBhIGNoYW5nZSBldmVudC5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBmbiBhIGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XHJcbiAgICAvLyB0aGlzLm9uU3VnZ2VzdGlvblNlbGVjdGVkID0gZm47XHJcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IHRoZSBmdW5jdGlvbiB0byBiZSBjYWxsZWRcclxuICAgKiB3aGVuIHRoZSBjb250cm9sIHJlY2VpdmVzIGEgdG91Y2ggZXZlbnQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZm4gYSBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbXBsZW1lbnRzIGRpc2FibGVkIHN0YXRlIGZvciB0aGlzIGVsZW1lbnRcclxuICAgKlxyXG4gICAqIEBwYXJhbSBpc0Rpc2FibGVkXHJcbiAgICovXHJcbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBhbGVydChcImRpc2FibGVkIVwiKTtcclxuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOZ3hEYURhdGFDb21wb25lbnQgfSBmcm9tICcuL25neC1kYS1kYXRhLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XHJcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBGb3Jtc01vZHVsZVxyXG4gIF0sXHJcbiAgZGVjbGFyYXRpb25zOiBbTmd4RGFEYXRhQ29tcG9uZW50XSxcclxuICBleHBvcnRzOiBbTmd4RGFEYXRhQ29tcG9uZW50XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd4RGFEYXRhTW9kdWxlIHsgfVxyXG4iXSwibmFtZXMiOltdLCJt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