@fdot/angular-staff
Version:
The angular-staff package wraps service calls to FDOT Staff API and also includes pipes and components based on bootstrap 4. ## Installation The angular staff package use a peer dependency of ng-bootstrap so you will need to also perform an NPM install
527 lines (515 loc) • 56.7 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('@angular/common/http'), require('rxjs/operators'), require('@angular/common'), require('@ng-bootstrap/ng-bootstrap'), require('@angular/forms')) :
typeof define === 'function' && define.amd ? define('@fdot/angular-staff', ['exports', '@angular/core', 'rxjs', '@angular/common/http', 'rxjs/operators', '@angular/common', '@ng-bootstrap/ng-bootstrap', '@angular/forms'], factory) :
(factory((global.fdot = global.fdot || {}, global.fdot['angular-staff'] = {}),global.ng.core,null,global.ng.common.http,global.Rx.Observable.prototype,global.ng.common,null,global.ng.forms));
}(this, (function (exports,i0,rxjs,i1,operators,common,ngBootstrap,forms) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var Config = (function () {
function Config(host, apiKey) {
this.host = host;
this.apiKey = apiKey;
}
return Config;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var AngularStaffService = (function () {
function AngularStaffService(http, config) {
this.http = http;
this.config = config;
this.staffByIdCache = new Map();
this.staffByRacfIdCache = new Map();
this.staffSearchCache = new Map();
if (!config) {
throw Error('Call AngularStaffmodule with for root passing in the config object');
}
}
/**
* @param {?} staff
* @param {?} format
* @return {?}
*/
AngularStaffService.prototype.Format = /**
* @param {?} staff
* @param {?} format
* @return {?}
*/
function (staff, format) {
if (format) {
var /** @type {?} */ formattedStr = format.replace('{firstName}', staff.firstName);
formattedStr = formattedStr.replace('{lastName}', staff.lastName);
formattedStr = formattedStr.replace('{racfId}', staff.racfId);
formattedStr = formattedStr.replace('{emailAddress}', staff.emailAddress);
formattedStr = formattedStr.replace('{phone}', staff.phone);
return formattedStr;
}
return staff.firstName + " " + staff.lastName;
};
/**
* Method GetStaffById
* @param {?} id Id for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.GetStaffById = /**
* Method GetStaffById
* @param {?} id Id for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
function (id) {
var _this = this;
if (!this.staffByIdCache.get(id)) {
this.staffByIdCache.set(id, new rxjs.BehaviorSubject(null));
var /** @type {?} */ uri = "/GetStaffById";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
if (id !== undefined && id !== null) {
params = params.set('id', id + '');
}
this.sendRequest('get', uri, headers, params, null).toPromise().then(function (r) {
if (r && r.body) {
_this.staffByIdCache.get(id).next(r.body);
}
});
}
return this.staffByIdCache.get(id);
};
/**
* Method GetStaffByIds
* @param {?} id Id for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.GetStaffByIds = /**
* Method GetStaffByIds
* @param {?} id Id for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
function (id) {
var /** @type {?} */ uri = "/GetStaffByIds";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
if (id !== undefined && id !== null) {
params = params.set('id', id + '');
}
return this.sendRequest('get', uri, headers, params, null).pipe(operators.map(function (r) {
if (r && r.body) {
return r.body;
}
}));
};
/**
* Method GetStaffByRacfId
* @param {?} racfId RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.GetStaffByRacfId = /**
* Method GetStaffByRacfId
* @param {?} racfId RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
function (racfId) {
var _this = this;
if (!this.staffByRacfIdCache.get(racfId)) {
this.staffByRacfIdCache.set(racfId, new rxjs.BehaviorSubject(null));
var /** @type {?} */ uri = "/GetStaffByRacfId";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
if (racfId !== undefined && racfId !== null) {
params = params.set('racfId', racfId + '');
}
this.sendRequest('get', uri, headers, params, null).pipe(operators.map(function (r) {
if (r && r.body) {
_this.staffByRacfIdCache.get(racfId).next(r.body);
}
}));
}
return this.staffByRacfIdCache.get(racfId);
};
/**
* Method GetStaffByRacfIds
* @param {?} racfId RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.GetStaffByRacfIds = /**
* Method GetStaffByRacfIds
* @param {?} racfId RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
function (racfId) {
var /** @type {?} */ uri = "/GetStaffByRacfIds";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
if (racfId !== undefined && racfId !== null) {
params = params.set('racfId', racfId + '');
}
return this.sendRequest('get', uri, headers, params, null).pipe(operators.map(function (r) {
if (r && r.body) {
return r.body;
}
}));
};
/**
* Method SearchStaffBySearchCriteriaGet
* @param {?} racfId RacfId for Staff to retrieve
* @param {?} peopleFirstId The people first id to Search for
* @param {?} status The status code to search for
* @param {?} partialName The partial name to search for
* @param {?} firstName The first name to search for
* @param {?} lastName The last name to search for
* @param {?} districtCode The district to search for
* @param {?} positionNumber The position number to search for
* @param {?} organizationalCode The organization code to search for
* @param {?} emailAddress The email address to search for
* @param {?} staffTypeCode The staff type code to search for
* @param {?} staffId The staff id to search for
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.SearchStaffBySearchCriteriaGet = /**
* Method SearchStaffBySearchCriteriaGet
* @param {?} racfId RacfId for Staff to retrieve
* @param {?} peopleFirstId The people first id to Search for
* @param {?} status The status code to search for
* @param {?} partialName The partial name to search for
* @param {?} firstName The first name to search for
* @param {?} lastName The last name to search for
* @param {?} districtCode The district to search for
* @param {?} positionNumber The position number to search for
* @param {?} organizationalCode The organization code to search for
* @param {?} emailAddress The email address to search for
* @param {?} staffTypeCode The staff type code to search for
* @param {?} staffId The staff id to search for
* @return {?} Full HTTP response as Observable
*/
function (racfId, peopleFirstId, status, partialName, firstName, lastName, districtCode, positionNumber, organizationalCode, emailAddress, staffTypeCode, staffId) {
var /** @type {?} */ uri = "/SearchStaffBySearchCriteria";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
if (racfId !== undefined && racfId !== null) {
params = params.set('racfId', racfId + '');
}
if (peopleFirstId !== undefined && peopleFirstId !== null) {
params = params.set('peopleFirstId', peopleFirstId + '');
}
if (status !== undefined && status !== null) {
params = params.set('status', status + '');
}
if (partialName !== undefined && partialName !== null) {
params = params.set('partialName', partialName + '');
}
if (firstName !== undefined && firstName !== null) {
params = params.set('firstName', firstName + '');
}
if (lastName !== undefined && lastName !== null) {
params = params.set('lastName', lastName + '');
}
if (districtCode !== undefined && districtCode !== null) {
params = params.set('districtCode', districtCode + '');
}
if (positionNumber !== undefined && positionNumber !== null) {
params = params.set('positionNumber', positionNumber + '');
}
if (organizationalCode !== undefined && organizationalCode !== null) {
params = params.set('organizationalCode', organizationalCode + '');
}
if (emailAddress !== undefined && emailAddress !== null) {
params = params.set('emailAddress', emailAddress + '');
}
if (staffTypeCode !== undefined && staffTypeCode !== null) {
params = params.set('staffTypeCode', staffTypeCode + '');
}
if (staffId !== undefined && staffId !== null) {
params = params.set('staffId', staffId + '');
}
return this.sendRequest('get', uri, headers, params, null).pipe(operators.map(function (r) {
if (r && r.body) {
return r.body;
}
}));
};
/**
* @param {?} name
* @return {?}
*/
AngularStaffService.prototype.SearchActiveStaffByName = /**
* @param {?} name
* @return {?}
*/
function (name) {
var _this = this;
if (!this.staffSearchCache.get(name)) {
this.staffSearchCache.set(name, new rxjs.BehaviorSubject([]));
this.SearchStaffBySearchCriteriaGet(null, null, 'active', name, null, null, null, null, null, null, null, null).toPromise().then(function (results) {
_this.staffSearchCache.get(name).next(results);
});
}
return this.staffSearchCache.get(name);
};
/**
* Method SearchStaffBySearchCriteriaPost
* @param {?} searchCriteria RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
AngularStaffService.prototype.SearchStaffBySearchCriteriaPost = /**
* Method SearchStaffBySearchCriteriaPost
* @param {?} searchCriteria RacfId for Staff to retrieve
* @return {?} Full HTTP response as Observable
*/
function (searchCriteria) {
var /** @type {?} */ uri = "/SearchStaffBySearchCriteria";
var /** @type {?} */ headers = new i1.HttpHeaders();
var /** @type {?} */ params = new i1.HttpParams();
return this.sendRequest('post', uri, headers, params, JSON.stringify(searchCriteria));
};
/**
* @template T
* @param {?} method
* @param {?} uri
* @param {?} headers
* @param {?} params
* @param {?} body
* @return {?}
*/
AngularStaffService.prototype.sendRequest = /**
* @template T
* @param {?} method
* @param {?} uri
* @param {?} headers
* @param {?} params
* @param {?} body
* @return {?}
*/
function (method, uri, headers, params, body) {
headers = headers.set('Ocp-Apim-Subscription-Key', this.config.apiKey);
if (method === 'get') {
return this.http.get(this.config.host + uri, { headers: headers.set('Accept', 'application/json'), params: params, observe: 'response' });
}
else if (method === 'put') {
return this.http.put(this.config.host + uri, body, { headers: headers.set('Content-Type', 'application/json'), params: params, observe: 'response' });
}
else if (method === 'post') {
return this.http.post(this.config.host + uri, body, { headers: headers.set('Content-Type', 'application/json'), params: params, observe: 'response' });
}
else if (method === 'delete') {
return this.http.delete(this.config.host + uri, { headers: headers, params: params, observe: 'response' });
}
else {
console.error('Unsupported request: ' + method);
return rxjs.Observable.throw('Unsupported request: ' + method);
}
};
AngularStaffService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
AngularStaffService.ctorParameters = function () {
return [
{ type: i1.HttpClient, },
{ type: Config, decorators: [{ type: i0.Inject, args: ['config',] },] },
];
};
/** @nocollapse */ AngularStaffService.ngInjectableDef = i0.defineInjectable({ factory: function AngularStaffService_Factory() { return new AngularStaffService(i0.inject(i1.HttpClient), i0.inject("config")); }, token: AngularStaffService, providedIn: "root" });
return AngularStaffService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var StaffSelectorComponent = (function () {
function StaffSelectorComponent(staffService) {
var _this = this;
this.staffService = staffService;
this.selected = new i0.EventEmitter();
this.searching = false;
this.searchFailed = false;
this.search = function (text$) {
return text$.pipe(operators.debounceTime(300), operators.distinctUntilChanged(), operators.tap(function () { return _this.searching = true; }), operators.switchMap(function (term) {
return term && term.length > 2 ?
_this.staffService.SearchActiveStaffByName(term).pipe(operators.tap(function () { return _this.searchFailed = false; }), operators.catchError(function () {
_this.searchFailed = true;
return rxjs.of([]);
}))
: rxjs.of([]);
}), operators.tap(function () { return _this.searching = false; }));
};
this.formatter = function (result) {
if (result != null) {
return _this.staffService.Format(result, _this.format);
}
return '';
};
}
Object.defineProperty(StaffSelectorComponent.prototype, "value", {
get: /**
* @return {?}
*/ function () {
return this._value;
},
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
var _this = this;
this._value = value;
this.staffService.GetStaffById(value).subscribe(function (s) {
if (s) {
_this.model = s;
_this.selected.emit(s);
}
});
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
StaffSelectorComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
};
/**
* @return {?}
*/
StaffSelectorComponent.prototype.onBlur = /**
* @return {?}
*/
function () {
if (typeof this.model !== 'object') {
this.model = null;
this.selected.emit(null);
}
};
/**
* @param {?} event
* @return {?}
*/
StaffSelectorComponent.prototype.itemSelected = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event) {
this.selected.emit(event.item);
}
};
StaffSelectorComponent.decorators = [
{ type: i0.Component, args: [{
// tslint:disable-next-line:component-selector
selector: 'fdot-staff-selector',
template: "<div class=\"form-group\">\n <input type=\"text\" class=\"form-control\" [class.is-invalid]=\"searchFailed\" [(ngModel)]=\"model\" [ngbTypeahead]=\"search\" placeholder=\"{{placeholder}}\"\n [editable]=\"false\" (blur)=\"onBlur()\" [resultFormatter]=\"formatter\" (selectItem)=\"itemSelected($event)\" [inputFormatter]=\"formatter\"\n />\n <span *ngIf=\"searching\">searching...</span>\n <div class=\"invalid-feedback\" *ngIf=\"searchFailed\">No results found</div>\n</div>",
styles: [""]
},] },
];
/** @nocollapse */
StaffSelectorComponent.ctorParameters = function () {
return [
{ type: AngularStaffService, },
];
};
StaffSelectorComponent.propDecorators = {
"selected": [{ type: i0.Output },],
"format": [{ type: i0.Input },],
"placeholder": [{ type: i0.Input },],
"value": [{ type: i0.Input },],
};
return StaffSelectorComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var StaffPipe = (function () {
function StaffPipe(staffService) {
this.staffService = staffService;
}
/**
* @param {?} value
* @param {?=} format
* @return {?}
*/
StaffPipe.prototype.transform = /**
* @param {?} value
* @param {?=} format
* @return {?}
*/
function (value, format) {
var _this = this;
return this.staffService.GetStaffById(value).pipe(operators.map(function (c) {
if (!c) {
return;
}
return _this.staffService.Format(c, format);
}));
};
StaffPipe.decorators = [
{ type: i0.Pipe, args: [{
name: 'staff'
},] },
];
/** @nocollapse */
StaffPipe.ctorParameters = function () {
return [
{ type: AngularStaffService, },
];
};
return StaffPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var AngularStaffModule = (function () {
function AngularStaffModule() {
}
/**
* @param {?} config
* @return {?}
*/
AngularStaffModule.forRoot = /**
* @param {?} config
* @return {?}
*/
function (config) {
return {
ngModule: AngularStaffModule,
providers: [
{ provide: 'config', useValue: config }
]
};
};
AngularStaffModule.decorators = [
{ type: i0.NgModule, args: [{
imports: [i1.HttpClientModule, ngBootstrap.NgbModule, forms.FormsModule, common.CommonModule],
declarations: [StaffPipe, StaffSelectorComponent],
exports: [StaffPipe, StaffSelectorComponent]
},] },
];
return AngularStaffModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
exports.AngularStaffService = AngularStaffService;
exports.StaffSelectorComponent = StaffSelectorComponent;
exports.Config = Config;
exports.AngularStaffModule = AngularStaffModule;
exports.ɵa = StaffPipe;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmRvdC1hbmd1bGFyLXN0YWZmLnVtZC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGZkb3QvYW5ndWxhci1zdGFmZi9saWIvbW9kZWxzL2NvbmZpZy50cyIsIm5nOi8vQGZkb3QvYW5ndWxhci1zdGFmZi9saWIvYW5ndWxhci1zdGFmZi5zZXJ2aWNlLnRzIiwibmc6Ly9AZmRvdC9hbmd1bGFyLXN0YWZmL2xpYi9zdGFmZi1zZWxlY3Rvci9zdGFmZi1zZWxlY3Rvci5jb21wb25lbnQudHMiLCJuZzovL0BmZG90L2FuZ3VsYXItc3RhZmYvbGliL3N0YWZmLnBpcGUudHMiLCJuZzovL0BmZG90L2FuZ3VsYXItc3RhZmYvbGliL2FuZ3VsYXItc3RhZmYubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb25maWcge1xyXG4gICAgY29uc3RydWN0b3IocHVibGljIGhvc3Q6IHN0cmluZywgcHVibGljIGFwaUtleTogc3RyaW5nKSB7XHJcblxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IEluamVjdGFibGUsIE9wdGlvbmFsLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFN0YWZmTWVtYmVyLCBTZWFyY2hDcml0ZXJpYSB9IGZyb20gJy4vbW9kZWxzJztcclxuaW1wb3J0IHsgSHR0cFJlc3BvbnNlLCBIdHRwSGVhZGVycywgSHR0cFBhcmFtcywgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL21vZGVscy9jb25maWcnO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQW5ndWxhclN0YWZmU2VydmljZSB7XHJcbiAgcHJpdmF0ZSBzdGFmZkJ5SWRDYWNoZSA9IG5ldyBNYXA8bnVtYmVyLCBCZWhhdmlvclN1YmplY3Q8U3RhZmZNZW1iZXI+PigpO1xyXG4gIHByaXZhdGUgc3RhZmZCeVJhY2ZJZENhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEJlaGF2aW9yU3ViamVjdDxTdGFmZk1lbWJlcj4+KCk7XHJcbiAgcHJpdmF0ZSBzdGFmZlNlYXJjaENhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEJlaGF2aW9yU3ViamVjdDxTdGFmZk1lbWJlcltdPj4oKTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LCBASW5qZWN0KCdjb25maWcnKSBwcml2YXRlIGNvbmZpZzogQ29uZmlnKSB7XHJcbiAgICBpZiAoIWNvbmZpZykge1xyXG4gICAgICB0aHJvdyBFcnJvcignQ2FsbCBBbmd1bGFyU3RhZmZtb2R1bGUgd2l0aCBmb3Igcm9vdCBwYXNzaW5nIGluIHRoZSBjb25maWcgb2JqZWN0Jyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgRm9ybWF0KHN0YWZmOiBTdGFmZk1lbWJlciwgZm9ybWF0OiBzdHJpbmcpIHtcclxuICAgIGlmIChmb3JtYXQpIHtcclxuICAgICAgbGV0IGZvcm1hdHRlZFN0ciA9IGZvcm1hdC5yZXBsYWNlKCd7Zmlyc3ROYW1lfScsIHN0YWZmLmZpcnN0TmFtZSk7XHJcblxyXG4gICAgICBmb3JtYXR0ZWRTdHIgPSBmb3JtYXR0ZWRTdHIucmVwbGFjZSgne2xhc3ROYW1lfScsIHN0YWZmLmxhc3ROYW1lKTtcclxuICAgICAgZm9ybWF0dGVkU3RyID0gZm9ybWF0dGVkU3RyLnJlcGxhY2UoJ3tyYWNmSWR9Jywgc3RhZmYucmFjZklkKTtcclxuICAgICAgZm9ybWF0dGVkU3RyID0gZm9ybWF0dGVkU3RyLnJlcGxhY2UoJ3tlbWFpbEFkZHJlc3N9Jywgc3RhZmYuZW1haWxBZGRyZXNzKTtcclxuICAgICAgZm9ybWF0dGVkU3RyID0gZm9ybWF0dGVkU3RyLnJlcGxhY2UoJ3twaG9uZX0nLCBzdGFmZi5waG9uZSk7XHJcblxyXG4gICAgICByZXR1cm4gZm9ybWF0dGVkU3RyO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBgJHtzdGFmZi5maXJzdE5hbWV9ICR7c3RhZmYubGFzdE5hbWV9YDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogTWV0aG9kIEdldFN0YWZmQnlJZFxyXG4gICogQHBhcmFtIGlkIElkIGZvciBTdGFmZiB0byByZXRyaWV2ZVxyXG4gICogQHJldHVybiBGdWxsIEhUVFAgcmVzcG9uc2UgYXMgT2JzZXJ2YWJsZVxyXG4gICovXHJcbiAgcHVibGljIEdldFN0YWZmQnlJZChpZDogbnVtYmVyKTogT2JzZXJ2YWJsZTxTdGFmZk1lbWJlcj4ge1xyXG4gICAgaWYgKCF0aGlzLnN0YWZmQnlJZENhY2hlLmdldChpZCkpIHtcclxuICAgICAgdGhpcy5zdGFmZkJ5SWRDYWNoZS5zZXQoaWQsIG5ldyBCZWhhdmlvclN1YmplY3Q8U3RhZmZNZW1iZXI+KG51bGwpKTtcclxuXHJcbiAgICAgIGNvbnN0IHVyaSA9IGAvR2V0U3RhZmZCeUlkYDtcclxuICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xyXG4gICAgICBsZXQgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKTtcclxuICAgICAgaWYgKGlkICE9PSB1bmRlZmluZWQgJiYgaWQgIT09IG51bGwpIHtcclxuICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdpZCcsIGlkICsgJycpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3Q8U3RhZmZNZW1iZXI+KCdnZXQnLCB1cmksIGhlYWRlcnMsIHBhcmFtcywgbnVsbCkudG9Qcm9taXNlKCkudGhlbihyID0+IHtcclxuICAgICAgICBpZiAociAmJiByLmJvZHkpIHtcclxuICAgICAgICAgIHRoaXMuc3RhZmZCeUlkQ2FjaGUuZ2V0KGlkKS5uZXh0KHIuYm9keSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5zdGFmZkJ5SWRDYWNoZS5nZXQoaWQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBNZXRob2QgR2V0U3RhZmZCeUlkc1xyXG4gICogQHBhcmFtIGlkIElkIGZvciBTdGFmZiB0byByZXRyaWV2ZVxyXG4gICogQHJldHVybiBGdWxsIEhUVFAgcmVzcG9uc2UgYXMgT2JzZXJ2YWJsZVxyXG4gICovXHJcbiAgcHVibGljIEdldFN0YWZmQnlJZHMoaWQ6IG51bWJlcltdKTogT2JzZXJ2YWJsZTxTdGFmZk1lbWJlcltdPiB7XHJcbiAgICBjb25zdCB1cmkgPSBgL0dldFN0YWZmQnlJZHNgO1xyXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xyXG4gICAgbGV0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XHJcbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCAmJiBpZCAhPT0gbnVsbCkge1xyXG4gICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdpZCcsIGlkICsgJycpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuc2VuZFJlcXVlc3Q8YW55PignZ2V0JywgdXJpLCBoZWFkZXJzLCBwYXJhbXMsIG51bGwpLnBpcGUobWFwKHIgPT4ge1xyXG4gICAgICBpZiAociAmJiByLmJvZHkpIHtcclxuICAgICAgICByZXR1cm4gci5ib2R5O1xyXG4gICAgICB9XHJcbiAgICB9KSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIE1ldGhvZCBHZXRTdGFmZkJ5UmFjZklkXHJcbiAgKiBAcGFyYW0gcmFjZklkIFJhY2ZJZCBmb3IgU3RhZmYgdG8gcmV0cmlldmVcclxuICAqIEByZXR1cm4gRnVsbCBIVFRQIHJlc3BvbnNlIGFzIE9ic2VydmFibGVcclxuICAqL1xyXG4gIHB1YmxpYyBHZXRTdGFmZkJ5UmFjZklkKHJhY2ZJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxTdGFmZk1lbWJlcj4ge1xyXG4gICAgaWYgKCF0aGlzLnN0YWZmQnlSYWNmSWRDYWNoZS5nZXQocmFjZklkKSkge1xyXG4gICAgICB0aGlzLnN0YWZmQnlSYWNmSWRDYWNoZS5zZXQocmFjZklkLCBuZXcgQmVoYXZpb3JTdWJqZWN0PFN0YWZmTWVtYmVyPihudWxsKSk7XHJcbiAgICAgIGNvbnN0IHVyaSA9IGAvR2V0U3RhZmZCeVJhY2ZJZGA7XHJcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoKTtcclxuICAgICAgbGV0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XHJcbiAgICAgIGlmIChyYWNmSWQgIT09IHVuZGVmaW5lZCAmJiByYWNmSWQgIT09IG51bGwpIHtcclxuICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdyYWNmSWQnLCByYWNmSWQgKyAnJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuc2VuZFJlcXVlc3Q8U3RhZmZNZW1iZXI+KCdnZXQnLCB1cmksIGhlYWRlcnMsIHBhcmFtcywgbnVsbCkucGlwZShtYXAociA9PiB7XHJcbiAgICAgICAgaWYgKHIgJiYgci5ib2R5KSB7XHJcbiAgICAgICAgICB0aGlzLnN0YWZmQnlSYWNmSWRDYWNoZS5nZXQocmFjZklkKS5uZXh0KHIuYm9keSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc3RhZmZCeVJhY2ZJZENhY2hlLmdldChyYWNmSWQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBNZXRob2QgR2V0U3RhZmZCeVJhY2ZJZHNcclxuICAqIEBwYXJhbSByYWNmSWQgUmFjZklkIGZvciBTdGFmZiB0byByZXRyaWV2ZVxyXG4gICogQHJldHVybiBGdWxsIEhUVFAgcmVzcG9uc2UgYXMgT2JzZXJ2YWJsZVxyXG4gICovXHJcbiAgcHVibGljIEdldFN0YWZmQnlSYWNmSWRzKHJhY2ZJZDogbnVtYmVyW10pOiBPYnNlcnZhYmxlPFN0YWZmTWVtYmVyW10+IHtcclxuICAgIGNvbnN0IHVyaSA9IGAvR2V0U3RhZmZCeVJhY2ZJZHNgO1xyXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xyXG4gICAgbGV0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XHJcbiAgICBpZiAocmFjZklkICE9PSB1bmRlZmluZWQgJiYgcmFjZklkICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3JhY2ZJZCcsIHJhY2ZJZCArICcnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLnNlbmRSZXF1ZXN0PGFueT4oJ2dldCcsIHVyaSwgaGVhZGVycywgcGFyYW1zLCBudWxsKS5waXBlKG1hcChyID0+IHtcclxuICAgICAgaWYgKHIgJiYgci5ib2R5KSB7XHJcbiAgICAgICAgcmV0dXJuIHIuYm9keTtcclxuICAgICAgfVxyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBNZXRob2QgU2VhcmNoU3RhZmZCeVNlYXJjaENyaXRlcmlhR2V0XHJcbiAgKiBAcGFyYW0gcmFjZklkIFJhY2ZJZCBmb3IgU3RhZmYgdG8gcmV0cmlldmVcclxuICAqIEBwYXJhbSBwZW9wbGVGaXJzdElkIFRoZSBwZW9wbGUgZmlyc3QgaWQgdG8gU2VhcmNoIGZvclxyXG4gICogQHBhcmFtIHN0YXR1cyBUaGUgc3RhdHVzIGNvZGUgdG8gc2VhcmNoIGZvclxyXG4gICogQHBhcmFtIHBhcnRpYWxOYW1lIFRoZSBwYXJ0aWFsIG5hbWUgdG8gc2VhcmNoIGZvclxyXG4gICogQHBhcmFtIGZpcnN0TmFtZSBUaGUgZmlyc3QgbmFtZSB0byBzZWFyY2ggZm9yXHJcbiAgKiBAcGFyYW0gbGFzdE5hbWUgVGhlIGxhc3QgbmFtZSB0byBzZWFyY2ggZm9yXHJcbiAgKiBAcGFyYW0gZGlzdHJpY3RDb2RlIFRoZSBkaXN0cmljdCB0byBzZWFyY2ggZm9yXHJcbiAgKiBAcGFyYW0gcG9zaXRpb25OdW1iZXIgVGhlIHBvc2l0aW9uIG51bWJlciB0byBzZWFyY2ggZm9yXHJcbiAgKiBAcGFyYW0gb3JnYW5pemF0aW9uYWxDb2RlIFRoZSBvcmdhbml6YXRpb24gY29kZSB0byBzZWFyY2ggZm9yXHJcbiAgKiBAcGFyYW0gZW1haWxBZGRyZXNzIFRoZSBlbWFpbCBhZGRyZXNzIHRvIHNlYXJjaCBmb3JcclxuICAqIEBwYXJhbSBzdGFmZlR5cGVDb2RlIFRoZSBzdGFmZiB0eXBlIGNvZGUgdG8gc2VhcmNoIGZvclxyXG4gICogQHBhcmFtIHN0YWZmSWQgVGhlIHN0YWZmIGlkIHRvIHNlYXJjaCBmb3JcclxuICAqIEByZXR1cm4gRnVsbCBIVFRQIHJlc3BvbnNlIGFzIE9ic2VydmFibGVcclxuICAqL1xyXG4gIHB1YmxpYyBTZWFyY2hTdGFmZkJ5U2VhcmNoQ3JpdGVyaWFHZXQocmFjZklkOiBudW1iZXJbXSwgcGVvcGxlRmlyc3RJZDogc3RyaW5nLCBzdGF0dXM6IHN0cmluZywgcGFydGlhbE5hbWU6IHN0cmluZyxcclxuICAgIGZpcnN0TmFtZTogc3RyaW5nLCBsYXN0TmFtZTogc3RyaW5nLCBkaXN0cmljdENvZGU6IHN0cmluZywgcG9zaXRpb25OdW1iZXI6IHN0cmluZywgb3JnYW5pemF0aW9uYWxDb2RlOiBzdHJpbmcsXHJcbiAgICBlbWFpbEFkZHJlc3M6IHN0cmluZywgc3RhZmZUeXBlQ29kZTogc3RyaW5nLCBzdGFmZklkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFN0YWZmTWVtYmVyW10+IHtcclxuICAgIGNvbnN0IHVyaSA9IGAvU2VhcmNoU3RhZmZCeVNlYXJjaENyaXRlcmlhYDtcclxuICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoKTtcclxuICAgIGxldCBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpO1xyXG4gICAgaWYgKHJhY2ZJZCAhPT0gdW5kZWZpbmVkICYmIHJhY2ZJZCAhPT0gbnVsbCkge1xyXG4gICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdyYWNmSWQnLCByYWNmSWQgKyAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAocGVvcGxlRmlyc3RJZCAhPT0gdW5kZWZpbmVkICYmIHBlb3BsZUZpcnN0SWQgIT09IG51bGwpIHtcclxuICAgICAgcGFyYW1zID0gcGFyYW1zLnNldCgncGVvcGxlRmlyc3RJZCcsIHBlb3BsZUZpcnN0SWQgKyAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoc3RhdHVzICE9PSB1bmRlZmluZWQgJiYgc3RhdHVzICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3N0YXR1cycsIHN0YXR1cyArICcnKTtcclxuICAgIH1cclxuICAgIGlmIChwYXJ0aWFsTmFtZSAhPT0gdW5kZWZpbmVkICYmIHBhcnRpYWxOYW1lICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3BhcnRpYWxOYW1lJywgcGFydGlhbE5hbWUgKyAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoZmlyc3ROYW1lICE9PSB1bmRlZmluZWQgJiYgZmlyc3ROYW1lICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ2ZpcnN0TmFtZScsIGZpcnN0TmFtZSArICcnKTtcclxuICAgIH1cclxuICAgIGlmIChsYXN0TmFtZSAhPT0gdW5kZWZpbmVkICYmIGxhc3ROYW1lICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ2xhc3ROYW1lJywgbGFzdE5hbWUgKyAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoZGlzdHJpY3RDb2RlICE9PSB1bmRlZmluZWQgJiYgZGlzdHJpY3RDb2RlICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ2Rpc3RyaWN0Q29kZScsIGRpc3RyaWN0Q29kZSArICcnKTtcclxuICAgIH1cclxuICAgIGlmIChwb3NpdGlvbk51bWJlciAhPT0gdW5kZWZpbmVkICYmIHBvc2l0aW9uTnVtYmVyICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3Bvc2l0aW9uTnVtYmVyJywgcG9zaXRpb25OdW1iZXIgKyAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAob3JnYW5pemF0aW9uYWxDb2RlICE9PSB1bmRlZmluZWQgJiYgb3JnYW5pemF0aW9uYWxDb2RlICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ29yZ2FuaXphdGlvbmFsQ29kZScsIG9yZ2FuaXphdGlvbmFsQ29kZSArICcnKTtcclxuICAgIH1cclxuICAgIGlmIChlbWFpbEFkZHJlc3MgIT09IHVuZGVmaW5lZCAmJiBlbWFpbEFkZHJlc3MgIT09IG51bGwpIHtcclxuICAgICAgcGFyYW1zID0gcGFyYW1zLnNldCgnZW1haWxBZGRyZXNzJywgZW1haWxBZGRyZXNzICsgJycpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN0YWZmVHlwZUNvZGUgIT09IHVuZGVmaW5lZCAmJiBzdGFmZlR5cGVDb2RlICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3N0YWZmVHlwZUNvZGUnLCBzdGFmZlR5cGVDb2RlICsgJycpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN0YWZmSWQgIT09IHVuZGVmaW5lZCAmJiBzdGFmZklkICE9PSBudWxsKSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ3N0YWZmSWQnLCBzdGFmZklkICsgJycpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLnNlbmRSZXF1ZXN0PGFueT4oJ2dldCcsIHVyaSwgaGVhZGVycywgcGFyYW1zLCBudWxsKS5waXBlKG1hcChyID0+IHtcclxuICAgICAgaWYgKHIgJiYgci5ib2R5KSB7XHJcbiAgICAgICAgcmV0dXJuIHIuYm9keTtcclxuICAgICAgfVxyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIFNlYXJjaEFjdGl2ZVN0YWZmQnlOYW1lKG5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8U3RhZmZNZW1iZXJbXT4ge1xyXG4gICAgaWYgKCF0aGlzLnN0YWZmU2VhcmNoQ2FjaGUuZ2V0KG5hbWUpKSB7XHJcbiAgICAgIHRoaXMuc3RhZmZTZWFyY2hDYWNoZS5zZXQobmFtZSwgbmV3IEJlaGF2aW9yU3ViamVjdDxTdGFmZk1lbWJlcltdPihbXSkpO1xyXG5cclxuICAgICAgdGhpcy5TZWFyY2hTdGFmZkJ5U2VhcmNoQ3JpdGVyaWFHZXQobnVsbCwgbnVsbCwgJ2FjdGl2ZScsIG5hbWUsXHJcbiAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCkudG9Qcm9taXNlKCkudGhlbigocmVzdWx0cykgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zdGFmZlNlYXJjaENhY2hlLmdldChuYW1lKS5uZXh0KHJlc3VsdHMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuc3RhZmZTZWFyY2hDYWNoZS5nZXQobmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIE1ldGhvZCBTZWFyY2hTdGFmZkJ5U2VhcmNoQ3JpdGVyaWFQb3N0XHJcbiAgKiBAcGFyYW0gc2VhcmNoQ3JpdGVyaWEgUmFjZklkIGZvciBTdGFmZiB0byByZXRyaWV2ZVxyXG4gICogQHJldHVybiBGdWxsIEhUVFAgcmVzcG9uc2UgYXMgT2JzZXJ2YWJsZVxyXG4gICovXHJcbiAgcHVibGljIFNlYXJjaFN0YWZmQnlTZWFyY2hDcml0ZXJpYVBvc3Qoc2VhcmNoQ3JpdGVyaWE6IFNlYXJjaENyaXRlcmlhKTogT2JzZXJ2YWJsZTxIdHRwUmVzcG9uc2U8YW55Pj4ge1xyXG4gICAgY29uc3QgdXJpID0gYC9TZWFyY2hTdGFmZkJ5U2VhcmNoQ3JpdGVyaWFgO1xyXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xyXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKTtcclxuICAgIHJldHVybiB0aGlzLnNlbmRSZXF1ZXN0PGFueT4oJ3Bvc3QnLCB1cmksIGhlYWRlcnMsIHBhcmFtcywgSlNPTi5zdHJpbmdpZnkoc2VhcmNoQ3JpdGVyaWEpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2VuZFJlcXVlc3Q8VD4obWV0aG9kOiBzdHJpbmcsIHVyaTogc3RyaW5nLCBoZWFkZXJzOiBIdHRwSGVhZGVycywgcGFyYW1zOiBIdHRwUGFyYW1zLCBib2R5OiBhbnkpOiBPYnNlcnZhYmxlPEh0dHBSZXNwb25zZTxUPj4ge1xyXG4gICAgaGVhZGVycyA9IGhlYWRlcnMuc2V0KCdPY3AtQXBpbS1TdWJzY3JpcHRpb24tS2V5JywgdGhpcy5jb25maWcuYXBpS2V5KTtcclxuICAgIGlmIChtZXRob2QgPT09ICdnZXQnKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFQ+KHRoaXMuY29uZmlnLmhvc3QgKyB1cmksXHJcbiAgICAgICAgeyBoZWFkZXJzOiBoZWFkZXJzLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKSwgcGFyYW1zOiBwYXJhbXMsIG9ic2VydmU6ICdyZXNwb25zZScgfSk7XHJcbiAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gJ3B1dCcpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wdXQ8VD4odGhpcy5jb25maWcuaG9zdCArIHVyaSwgYm9keSxcclxuICAgICAgICB7IGhlYWRlcnM6IGhlYWRlcnMuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpLCBwYXJhbXM6IHBhcmFtcywgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyB9KTtcclxuICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSAncG9zdCcpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PFQ+KHRoaXMuY29uZmlnLmhvc3QgKyB1cmksIGJvZHksXHJcbiAgICAgICAgeyBoZWFkZXJzOiBoZWFkZXJzLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKSwgcGFyYW1zOiBwYXJhbXMsIG9ic2VydmU6ICdyZXNwb25zZScgfSk7XHJcbiAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5kZWxldGU8VD4odGhpcy5jb25maWcuaG9zdCArIHVyaSwgeyBoZWFkZXJzOiBoZWFkZXJzLCBwYXJhbXM6IHBhcmFtcywgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vuc3VwcG9ydGVkIHJlcXVlc3Q6ICcgKyBtZXRob2QpO1xyXG4gICAgICByZXR1cm4gT2JzZXJ2YWJsZS50aHJvdygnVW5zdXBwb3J0ZWQgcmVxdWVzdDogJyArIG1ldGhvZCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IFN0YWZmTWVtYmVyIH0gZnJvbSAnLi4vbW9kZWxzL3N0YWZmbWVtYmVyLm1vZGVsJztcclxuaW1wb3J0IHsgQW5ndWxhclN0YWZmU2VydmljZSB9IGZyb20gJy4vLi4vYW5ndWxhci1zdGFmZi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YXAsIHN3aXRjaE1hcCwgY2F0Y2hFcnJvciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgTmdiVHlwZWFoZWFkU2VsZWN0SXRlbUV2ZW50IH0gZnJvbSBcIkBuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwL3R5cGVhaGVhZC90eXBlYWhlYWRcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcclxuICBzZWxlY3RvcjogJ2Zkb3Qtc3RhZmYtc2VsZWN0b3InLFxyXG4gIHRlbXBsYXRlOiBgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cclxuICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtjbGFzcy5pcy1pbnZhbGlkXT1cInNlYXJjaEZhaWxlZFwiIFsobmdNb2RlbCldPVwibW9kZWxcIiBbbmdiVHlwZWFoZWFkXT1cInNlYXJjaFwiIHBsYWNlaG9sZGVyPVwie3twbGFjZWhvbGRlcn19XCJcclxuICAgIFtlZGl0YWJsZV09XCJmYWxzZVwiIChibHVyKT1cIm9uQmx1cigpXCIgW3Jlc3VsdEZvcm1hdHRlcl09XCJmb3JtYXR0ZXJcIiAoc2VsZWN0SXRlbSk9XCJpdGVtU2VsZWN0ZWQoJGV2ZW50KVwiIFtpbnB1dEZvcm1hdHRlcl09XCJmb3JtYXR0ZXJcIlxyXG4gIC8+XHJcbiAgPHNwYW4gKm5nSWY9XCJzZWFyY2hpbmdcIj5zZWFyY2hpbmcuLi48L3NwYW4+XHJcbiAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiAqbmdJZj1cInNlYXJjaEZhaWxlZFwiPk5vIHJlc3VsdHMgZm91bmQ8L2Rpdj5cclxuPC9kaXY+YCxcclxuICBzdHlsZXM6IFtgYF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFN0YWZmU2VsZWN0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0YWZmU2VydmljZTogQW5ndWxhclN0YWZmU2VydmljZSkgeyB9XHJcblxyXG4gIEBPdXRwdXQoKVxyXG4gIHNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8U3RhZmZNZW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxTdGFmZk1lbWJlcj4oKTtcclxuXHJcbiAgbW9kZWw6IFN0YWZmTWVtYmVyO1xyXG4gIEBJbnB1dCgpXHJcbiAgZm9ybWF0OiBzdHJpbmc7XHJcbiAgQElucHV0KClcclxuICBwbGFjZWhvbGRlcjogc3RyaW5nO1xyXG5cclxuICBwcml2YXRlIF92YWx1ZTogbnVtYmVyO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNldCB2YWx1ZSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xyXG4gICAgdGhpcy5zdGFmZlNlcnZpY2UuR2V0U3RhZmZCeUlkKHZhbHVlKS5zdWJzY3JpYmUoKHM6IFN0YWZmTWVtYmVyKSA9PiB7XHJcbiAgICAgIGlmIChzKSB7XHJcbiAgICAgICAgdGhpcy5tb2RlbCA9IHM7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZC5lbWl0KHMpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGdldCB2YWx1ZSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gIH1cclxuXHJcbiAgc2VhcmNoaW5nID0gZmFsc2U7XHJcbiAgc2VhcmNoRmFpbGVkID0gZmFsc2U7XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gIH1cclxuXHJcbiAgb25CbHVyKCkge1xyXG4gICAgaWYgKHR5cGVvZiB0aGlzLm1vZGVsICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICB0aGlzLm1vZGVsID0gbnVsbDtcclxuICAgICAgdGhpcy5zZWxlY3RlZC5lbWl0KG51bGwpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2VhcmNoID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pOiBPYnNlcnZhYmxlPFN0YWZmTWVtYmVyW10+ID0+XHJcbiAgICB0ZXh0JC5waXBlKFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFwKCgpID0+IHRoaXMuc2VhcmNoaW5nID0gdHJ1ZSksXHJcbiAgICAgIHN3aXRjaE1hcCgodGVybTogc3RyaW5nKSA9PiB0ZXJtICYmIHRlcm0ubGVuZ3RoID4gMiA/XHJcbiAgICAgICAgdGhpcy5zdGFmZlNlcnZpY2UuU2VhcmNoQWN0aXZlU3RhZmZCeU5hbWUodGVybSkucGlwZShcclxuICAgICAgICAgIHRhcCgoKSA9PiB0aGlzLnNlYXJjaEZhaWxlZCA9IGZhbHNlKSxcclxuICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZhaWxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHJldHVybiBvZihbXSk7XHJcbiAgICAgICAgICB9KSlcclxuICAgICAgICA6IG9mKFtdKVxyXG4gICAgICApLFxyXG4gICAgICB0YXAoKCkgPT4gdGhpcy5zZWFyY2hpbmcgPSBmYWxzZSlcclxuICAgICk7XHJcblxyXG4gIGl0ZW1TZWxlY3RlZChldmVudDogTmdiVHlwZWFoZWFkU2VsZWN0SXRlbUV2ZW50KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZC5lbWl0KGV2ZW50Lml0ZW0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZm9ybWF0dGVyID0gKHJlc3VsdDogU3RhZmZNZW1iZXIpOiBzdHJpbmcgPT4ge1xyXG4gICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnN0YWZmU2VydmljZS5Gb3JtYXQocmVzdWx0LCB0aGlzLmZvcm1hdCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG59IiwiaW1wb3J0IHsgQW5ndWxhclN0YWZmU2VydmljZSB9IGZyb20gJy4vYW5ndWxhci1zdGFmZi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5AUGlwZSh7XHJcbiAgbmFtZTogJ3N0YWZmJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgU3RhZmZQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RhZmZTZXJ2aWNlOiBBbmd1bGFyU3RhZmZTZXJ2aWNlKSB7XHJcblxyXG4gIH1cclxuXHJcbiAgdHJhbnNmb3JtKHZhbHVlOiBudW1iZXIsIGZvcm1hdD86IHN0cmluZyk6IGFueSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGFmZlNlcnZpY2UuR2V0U3RhZmZCeUlkKHZhbHVlKS5waXBlKG1hcChjID0+IHtcclxuICAgICAgaWYgKCFjKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5zdGFmZlNlcnZpY2UuRm9ybWF0KGMsIGZvcm1hdCk7XHJcbiAgICB9KSk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL21vZGVscy9jb25maWcnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBOZ01vZHVsZSwgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdGFmZlBpcGUgfSBmcm9tICcuL3N0YWZmLnBpcGUnO1xyXG5pbXBvcnQgeyBTdGFmZlNlbGVjdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9zdGFmZi1zZWxlY3Rvci9zdGFmZi1zZWxlY3Rvci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOZ2JNb2R1bGUgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XHJcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5ATmdNb2R1bGUoe1xyXG4gIGltcG9ydHM6IFtIdHRwQ2xpZW50TW9kdWxlLCBOZ2JNb2R1bGUsIEZvcm1zTW9kdWxlLCBDb21tb25Nb2R1bGVdLFxyXG4gIGRlY2xhcmF0aW9uczogW1N0YWZmUGlwZSwgU3RhZmZTZWxlY3RvckNvbXBvbmVudF0sXHJcbiAgZXhwb3J0czogW1N0YWZmUGlwZSwgU3RhZmZTZWxlY3RvckNvbXBvbmVudF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJTdGFmZk1vZHVsZSB7XHJcbiAgc3RhdGljIGZvclJvb3QoY29uZmlnOiBDb25maWcpOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIG5nTW9kdWxlOiBBbmd1bGFyU3RhZmZNb2R1bGUsXHJcbiAgICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHsgcHJvdmlkZTogJ2NvbmZpZycsIHVzZVZhbHVlOiBjb25maWcgfVxyXG4gICAgICBdXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iXSwibmFtZXMiOlsiQmVoYXZpb3JTdWJqZWN0IiwiSHR0cEhlYWRlcnMiLCJIdHRwUGFyYW1zIiwibWFwIiwiT2JzZXJ2YWJsZSIsIkluamVjdGFibGUiLCJIdHRwQ2xpZW50IiwiSW5qZWN0IiwiRXZlbnRFbWl0dGVyIiwiZGVib3VuY2VUaW1lIiwiZGlzdGluY3RVbnRpbENoYW5nZWQiLCJ0YXAiLCJzd2l0Y2hNYXAiLCJjYXRjaEVycm9yIiwib2YiLCJDb21wb25lbnQiLCJPdXRwdXQiLCJJbnB1dCIsIlBpcGUiLCJOZ01vZHVsZSIsIkh0dHBDbGllbnRNb2R1bGUiLCJOZ2JNb2R1bGUiLCJGb3Jtc01vZHVsZSIsIkNvbW1vbk1vZHVsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLFFBQUE7UUFDSSxnQkFBbUIsSUFBWSxFQUFTLE1BQWM7WUFBbkMsU0FBSSxHQUFKLElBQUksQ0FBUTtZQUFTLFdBQU0sR0FBTixNQUFNLENBQVE7U0FFckQ7cUJBSEw7UUFJQzs7Ozs7O0FDSkQ7UUFlRSw2QkFBb0IsSUFBZ0IsRUFBNEI7WUFBNUMsU0FBSSxHQUFKLElBQUksQ0FBWTtZQUE0QixXQUFNLEdBQU4sTUFBTTtrQ0FKN0MsSUFBSSxHQUFHLEVBQXdDO3NDQUMzQyxJQUFJLEdBQUcsRUFBd0M7b0NBQ2pELElBQUksR0FBRyxFQUEwQztZQUcxRSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNYLE1BQU0sS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7YUFDbkY7U0FDRjs7Ozs7O1FBRU0sb0NBQU07Ozs7O3NCQUFDLEtBQWtCLEVBQUUsTUFBYztnQkFDOUMsSUFBSSxNQUFNLEVBQUU7b0JBQ1YscUJBQUksWUFBWSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFFbEUsWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDbEUsWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDOUQsWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUMxRSxZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUU1RCxPQUFPLFlBQVksQ0FBQztpQkFDckI7Z0JBRUQsT0FBVSxLQUFLLENBQUMsU0FBUyxTQUFJLEtBQUssQ0FBQyxRQUFVLENBQUM7Ozs7Ozs7UUFRekMsMENBQVk7Ozs7O3NCQUFDLEVBQVU7O2dCQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7b0JBQ2hDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJQSxvQkFBZSxDQUFjLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBRXBFLHFCQUFNLEdBQUcsR0FBRyxlQUFlLENBQUM7b0JBQzVCLHFCQUFNLE9BQU8sR0FBRyxJQUFJQyxjQUFXLEVBQUUsQ0FBQztvQkFDbEMscUJBQUksTUFBTSxHQUFHLElBQUlDLGFBQVUsRUFBRSxDQUFDO29CQUM5QixJQUFJLEVBQUUsS0FBSyxTQUFTLElBQUksRUFBRSxLQUFLLElBQUksRUFBRTt3QkFDbkMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztxQkFDcEM7b0JBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBYyxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUEsQ0FBQzt3QkFDakYsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRTs0QkFDZixLQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO3lCQUMxQztxQkFDRixDQUFDLENBQUM7aUJBQ0o7Z0JBRUQsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQzs7Ozs7OztRQVE5QiwyQ0FBYTs7Ozs7c0JBQUMsRUFBWTtnQkFDL0IscUJBQU0sR0FBRyxHQUFHLGdCQUFnQixDQUFDO2dCQUM3QixxQkFBTSxPQUFPLEdBQUcsSUFBSUQsY0FBVyxFQUFFLENBQUM7Z0JBQ2xDLHFCQUFJLE1BQU0sR0FBRyxJQUFJQyxhQUFVLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxFQUFFLEtBQUssU0FBUyxJQUFJLEVBQUUsS0FBSyxJQUFJLEVBQUU7b0JBQ25DLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQ3BDO2dCQUNELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBTSxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDQyxhQUFHLENBQUMsVUFBQSxDQUFDO29CQUN4RSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO3dCQUNmLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQztxQkFDZjtpQkFDRixDQUFDLENBQUMsQ0FBQzs7Ozs7OztRQVFDLDhDQUFnQjs7Ozs7c0JBQUMsTUFBYzs7Z0JBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO29CQUN4QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJSCxvQkFBZSxDQUFjLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQzVFLHFCQUFNLEdBQUcsR0FBRyxtQkFBbUIsQ0FBQztvQkFDaEMscUJBQU0sT0FBTyxHQUFHLElBQUlDLGNBQVcsRUFBRSxDQUFDO29CQUNsQyxxQkFBSSxNQUFNLEdBQUcsSUFBSUMsYUFBVSxFQUFFLENBQUM7b0JBQzlCLElBQUksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO3dCQUMzQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO3FCQUM1QztvQkFFRCxJQUFJLENBQUMsV0FBVyxDQUFjLEtBQUssRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUNDLGFBQUcsQ0FBQyxVQUFBLENBQUM7d0JBQ3pFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUU7NEJBQ2YsS0FBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO3lCQUNsRDtxQkFDRixDQUFDLENBQUMsQ0FBQztpQkFDTDtnQkFFRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7Ozs7Ozs7UUFRdEMsK0NBQWlCOzs7OztzQkFBQyxNQUFnQjtnQkFDdkMscUJBQU0sR0FBRyxHQUFHLG9CQUFvQixDQUFDO2dCQUNqQyxxQkFBTSxPQUFPLEdBQUcsSUFBSUYsY0FBVyxFQUFFLENBQUM7Z0JBQ2xDLHFCQUFJLE1BQU0sR0FBRyxJQUFJQyxhQUFVLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUU7b0JBQzNDLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQzVDO2dCQUNELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBTSxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDQyxhQUFHLENBQUMsVUFBQSxDQUFDO29CQUN4RSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO3dCQUNmLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQztxQkFDZjtpQkFDRixDQUFDLENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBbUJDLDREQUE4Qjs7Ozs7Ozs7Ozs7Ozs7OztzQkFBQyxNQUFnQixFQUFFLGFBQXFCLEVBQUUsTUFBYyxFQUFFLFdBQW1CLEVBQ2hILFNBQWlCLEVBQUUsUUFBZ0IsRUFBRSxZQUFvQixFQUFFLGNBQXNCLEVBQUUsa0JBQTBCLEVBQzdHLFlBQW9CLEVBQUUsYUFBcUIsRUFBRSxPQUFlO2dCQUM1RCxxQkFBTSxHQUFHLEdBQUcsOEJBQThCLENBQUM7Z0JBQzNDLHFCQUFNLE9BQU8sR0FBRyxJQUFJRixjQUFXLEVBQUUsQ0FBQztnQkFDbEMscUJBQUksTUFBTSxHQUFHLElBQUlDLGFBQVUsRUFBRSxDQUFDO2dCQUM5QixJQUFJLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtvQkFDM0MsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQztpQkFDNUM7Z0JBQ0QsSUFBSSxhQUFhLEtBQUssU0FBUyxJQUFJLGFBQWEsS0FBSyxJQUFJLEVBQUU7b0JBQ3pELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxhQUFhLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQzFEO2dCQUNELElBQUksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO29CQUMzQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO2lCQUM1QztnQkFDRCxJQUFJLFdBQVcsS0FBSyxTQUFTLElBQUksV0FBVyxLQUFLLElBQUksRUFBRTtvQkFDckQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFdBQVcsR0FBRyxFQUFFLENBQUMsQ0FBQztpQkFDdEQ7Z0JBQ0QsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUU7b0JBQ2pELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQ2xEO2dCQUNELElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFO29CQUMvQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsUUFBUSxHQUFHLEVBQUUsQ0FBQyxDQUFDO2lCQUNoRDtnQkFDRCxJQUFJLFlBQVksS0FBSyxTQUFTLElBQUksWUFBWSxLQUFLLElBQUksRUFBRTtvQkFDdkQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLFlBQVksR0FBRyxFQUFFLENBQUMsQ0FBQztpQkFDeEQ7Z0JBQ0QsSUFBSSxjQUFjLEtBQUssU0FBUyxJQUFJLGNBQWMsS0FBSyxJQUFJLEVBQUU7b0JBQzNELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGNBQWMsR0FBRyxFQUFFLENBQUMsQ0FBQztpQkFDNUQ7Z0JBQ0QsSUFBSSxrQkFBa0IsS0FBSyxTQUFTLElBQUksa0JBQWtCLEtBQUssSUFBSSxFQUFFO29CQUNuRSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxrQkFBa0IsR0FBRyxFQUFFLENBQUMsQ0FBQztpQkFDcEU7Z0JBQ0QsSUFBSSxZQUFZLEtBQUssU0FBUyxJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7b0JBQ3ZELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxZQUFZLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQ3hEO2dCQUNELElBQUksYUFBYSxLQUFLLFNBQVMsSUFBSSxhQUFhLEtBQUssSUFBSSxFQUFFO29CQ