ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
214 lines • 34.1 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, EventEmitter, forwardRef, Inject, Injector } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { OFormComponent } from '../../components/form/o-form.component';
import { BooleanInputConverter, NumberInputConverter } from '../../decorators/input-converter';
import { LocalStorageService } from '../../services/local-storage.service';
import { OFilterBuilderComponentStateService } from '../../services/state/o-filter-builder-component-state.service';
import { Codes } from '../../util/codes';
import { FilterExpressionUtils } from '../../util/filter-expression.utils';
import { Util } from '../../util/util';
import { OFilterBuilderBase } from './o-filter-builder-base.class';
import * as i0 from "@angular/core";
import * as i1 from "../../components/form/o-form.component";
export const DEFAULT_INPUTS_O_FILTER_BUILDER = [
'filters',
'targetCmp: target',
'expressionBuilder: expression-builder',
'queryOnChange: query-on-change',
'queryOnChangeDelay: query-on-change-delay',
'queryOnChangeEventType: query-on-change-event-type',
'oattr: attr',
];
export const DEFAULT_OUTPUTS_O_FILTER_BUILDER = [
'onFilter',
'onClear'
];
export class OFilterBuilderComponent {
constructor(injector, form) {
this.injector = injector;
this.form = form;
this.onFilter = new EventEmitter();
this.onClear = new EventEmitter();
this.queryOnChange = false;
this.queryOnChangeDelay = 0;
this.queryOnChangeEventType = Codes.DEFAULT_CHANGE_EVENT;
this.filterComponents = [];
this.subscriptions = new Subscription();
this.localStorageService = this.injector.get(LocalStorageService);
this.componentStateService = this.injector.get(OFilterBuilderComponentStateService);
this.router = this.injector.get(Router);
this.actRoute = this.injector.get(ActivatedRoute);
}
ngOnInit() {
this.initialize();
}
ngAfterViewInit() {
this.initializeListeners();
}
ngOnDestroy() {
if (this.subscriptions) {
this.subscriptions.unsubscribe();
}
}
initialize() {
this.componentStateService.initialize(this);
if (this.filters) {
const filterArray = Util.parseArray(this.filters);
filterArray.forEach(filter => {
const filterElms = filter.split(Codes.COLUMNS_ALIAS_SEPARATOR);
this.filterComponents.push({
targetAttr: filterElms[0],
formComponentAttr: filterElms[1] ? filterElms[1] : filterElms[0]
});
});
}
if (Util.isDefined(this.targetCmp)) {
this.targetCmp.setFilterBuilder(this);
}
}
initializeListeners() {
if (this.queryOnChange) {
this.filterComponents.forEach((filterComponent) => {
const formComponent = this.form.getComponents()[filterComponent.formComponentAttr];
if (formComponent) {
this.subscriptions.add(this.getEventFromFormComponent(formComponent)
.pipe(debounceTime(this.queryOnChangeDelay))
.subscribe(() => this.triggerReload()));
}
});
}
}
getEventFromFormComponent(formComponent) {
return this.queryOnChangeEventType === Codes.DEFAULT_CHANGE_EVENT ?
formComponent.onValueChange :
formComponent.getFormControl().valueChanges;
}
getExpression() {
const formComponents = this.form.getComponents();
const params = [];
this.filterComponents.forEach((filterComponent) => {
const formComponent = formComponents[filterComponent.formComponentAttr];
if (formComponent) {
const value = formComponent.getValue();
params.push({
attr: filterComponent.targetAttr,
value: value
});
}
});
if (this.expressionBuilder) {
return this.expressionBuilder(params);
}
const expressions = [];
params.forEach(elem => {
if (Util.isDefined(elem.value)) {
expressions.push(FilterExpressionUtils.buildExpressionEquals(elem.attr, elem.value));
}
});
return expressions.length ? expressions.reduce((fe1, fe2) => FilterExpressionUtils.buildComplexExpression(fe1, fe2, FilterExpressionUtils.OP_OR)) : undefined;
}
getBasicExpression() {
return FilterExpressionUtils.buildBasicExpression(this.getExpression());
}
getTargetComponent() {
return this.targetCmp;
}
triggerReload() {
if (!this.targetCmp) {
return;
}
if (this.targetCmp.pageable) {
this.targetCmp.reloadPaginatedDataFromStart();
}
else {
this.targetCmp.reloadData();
}
this.onFilter.emit();
}
clearFilter() {
const formComponents = this.form.getComponents();
this.getFilterAttrs().forEach((attr) => {
formComponents[attr].clearValue();
});
this.onClear.emit();
}
getFilterValues() {
const result = [];
this.filterComponents.
forEach((filterComponent) => {
if (Util.isDefined(this.form.getComponents()[filterComponent.formComponentAttr])) {
result.push({ attr: filterComponent.formComponentAttr, value: this.form.getComponents()[filterComponent.formComponentAttr].getValue() });
}
});
return result;
}
setFilterValues(filterBuilderValues) {
filterBuilderValues.forEach((filterBuilderValue) => {
if (this.form.getComponents()[filterBuilderValue.attr]) {
this.form.getComponents()[filterBuilderValue.attr].setValue(filterBuilderValue.value);
}
else {
console.warn('The filter with attr ' + filterBuilderValue.attr + ' cannot be set ' + filterBuilderValue.value + ' because it does not exist .');
}
});
}
getFilterAttrs() {
return this.filterComponents.map((elem) => elem.formComponentAttr);
}
get state() {
return this.componentStateService.state;
}
getDataToStore() {
return this.componentStateService.state;
}
getComponentKey() {
if (!Util.isDefined(this.oattr)) {
console.error('Your o-filter-builder component must have an \'attr\'. Otherwise, your filter builder state will not set in localstorage.');
return 'OFilterBuilderComponent_';
}
return 'OFilterBuilderComponent_' + this.oattr;
}
storeFilterInState(arg) {
this.componentStateService.storeFilter(arg);
this.updateStateStorage();
}
updateStateStorage() {
if (this.localStorageService) {
this.localStorageService.updateComponentStorage(this, this.getRouteKey());
}
}
getRouteKey() {
let route = this.router.url;
this.actRoute.params.subscribe(params => {
Object.keys(params).forEach(key => {
route = route.replace(params[key], key);
});
});
return route;
}
}
OFilterBuilderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OFilterBuilderComponent, deps: [{ token: i0.Injector }, { token: forwardRef(() => OFormComponent) }], target: i0.ɵɵFactoryTarget.Component });
OFilterBuilderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OFilterBuilderComponent, selector: "o-filter-builder", inputs: { filters: "filters", targetCmp: ["target", "targetCmp"], expressionBuilder: ["expression-builder", "expressionBuilder"], queryOnChange: ["query-on-change", "queryOnChange"], queryOnChangeDelay: ["query-on-change-delay", "queryOnChangeDelay"], queryOnChangeEventType: ["query-on-change-event-type", "queryOnChangeEventType"], oattr: ["attr", "oattr"] }, outputs: { onFilter: "onFilter", onClear: "onClear" }, providers: [
{ provide: OFilterBuilderBase, useExisting: forwardRef(() => OFilterBuilderComponent) }
], ngImport: i0, template: "" });
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OFilterBuilderComponent.prototype, "queryOnChange", void 0);
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OFilterBuilderComponent.prototype, "queryOnChangeDelay", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OFilterBuilderComponent, decorators: [{
type: Component,
args: [{ selector: 'o-filter-builder', inputs: DEFAULT_INPUTS_O_FILTER_BUILDER, outputs: DEFAULT_OUTPUTS_O_FILTER_BUILDER, providers: [
{ provide: OFilterBuilderBase, useExisting: forwardRef(() => OFilterBuilderComponent) }
], template: "" }]
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.OFormComponent, decorators: [{
type: Inject,
args: [forwardRef(() => OFormComponent)]
}] }]; }, propDecorators: { queryOnChange: [], queryOnChangeDelay: [] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1maWx0ZXItYnVpbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbnRpbWl6ZS13ZWItbmd4L3NyYy9saWIvY29tcG9uZW50cy9maWx0ZXItYnVpbGRlci9vLWZpbHRlci1idWlsZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2ZpbHRlci1idWlsZGVyL28tZmlsdGVyLWJ1aWxkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDeEgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQWMsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDeEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFJL0YsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFM0UsT0FBTyxFQUFFLG1DQUFtQyxFQUFFLE1BQU0sK0RBQStELENBQUM7QUFLcEgsT0FBTyxFQUFpQixLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStC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V0FBVztRQUNoQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ2hDLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDOztxSEFyUFUsdUJBQXVCLDBDQXdCeEIsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQzt5R0F4Qi9CLHVCQUF1Qiw0Y0FUdkI7UUFDVCxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHVCQUF1QixDQUFDLEVBQUU7S0FDeEYsMEJDNURILEVBQUE7QUQyRUU7SUFBQyxxQkFBcUIsRUFBRTs7OERBQ2M7QUFDdEM7SUFBQyxvQkFBb0IsRUFBRTs7bUVBQ2U7NEZBWDNCLHVCQUF1QjtrQkFkbkMsU0FBUzsrQkFDRSxrQkFBa0IsVUFFcEIsK0JBQStCLFdBQzlCLGdDQUFnQyxhQUM5Qjt3QkFDVCxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSx3QkFBd0IsQ0FBQyxFQUFFO3FCQUN4Rjs7MEJBK0JFLE1BQU07MkJBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQzs0Q0FmbkMsYUFBYSxNQUViLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmLCBJbmplY3QsIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgT0Zvcm1Db21wb25lbnQgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2Zvcm0vby1mb3JtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCb29sZWFuSW5wdXRDb252ZXJ0ZXIsIE51bWJlcklucHV0Q29udmVydGVyIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9pbnB1dC1jb252ZXJ0ZXInO1xuaW1wb3J0IHsgSUZpbHRlckJ1aWxkZXJDbXBUYXJnZXQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci1idWlsZGVyLWNvbXBvbmVudC10YXJnZXQuaW50ZXJmYWNlJztcbmltcG9ydCB7IElGb3JtRGF0YUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZm9ybS1kYXRhLWNvbXBvbmVudC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSVNlcnZpY2VEYXRhQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9zZXJ2aWNlLWRhdGEtY29tcG9uZW50LmludGVyZmFjZSc7XG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbG9jYWwtc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IE9GaWx0ZXJCdWlsZGVyQ29tcG9uZW50U3RhdGVDbGFzcyB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3N0YXRlL28tZmlsdGVyLWJ1aWxkZXItY29tcG9uZW50LXN0YXRlLmNsYXNzJztcbmltcG9ydCB7IE9GaWx0ZXJCdWlsZGVyQ29tcG9uZW50U3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc3RhdGUvby1maWx0ZXItYnVpbGRlci1jb21wb25lbnQtc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBPRmlsdGVyRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IEJhc2ljRXhwcmVzc2lvbiB9IGZyb20gJy4uLy4uL3R5cGVzL2Jhc2ljLWV4cHJlc3Npb24udHlwZSc7XG5pbXBvcnQgeyBFeHByZXNzaW9uIH0gZnJvbSAnLi4vLi4vdHlwZXMvZXhwcmVzc2lvbi50eXBlJztcbmltcG9ydCB7IE9GaWx0ZXJCdWlsZGVyVmFsdWVzIH0gZnJvbSAnLi4vLi4vdHlwZXMvby1maWx0ZXItYnVpbGRlci12YWx1ZXMudHlwZSc7XG5pbXBvcnQgeyBDSEFOR0VfRVZFTlRTLCBDb2RlcyB9IGZyb20gJy4uLy4uL3V0aWwvY29kZXMnO1xuaW1wb3J0IHsgRmlsdGVyRXhwcmVzc2lvblV0aWxzIH0gZnJvbSAnLi4vLi4vdXRpbC9maWx0ZXItZXhwcmVzc2lvbi51dGlscyc7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsJztcbmltcG9ydCB7IE9GaWx0ZXJCdWlsZGVyQmFzZSB9IGZyb20gJy4vby1maWx0ZXItYnVpbGRlci1iYXNlLmNsYXNzJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfSU5QVVRTX09fRklMVEVSX0JVSUxERVIgPSBbXG4gIC8vIGZpbHRlcnM6IFtzdHJpbmddIExpc3Qgb2YgcGFpcnMgb2YgZm9ybSBjb21wb25lbnQgYXR0cmlidXRlcyBhbmQgdGFyZ2V0IGNvbXBvbmVudCBjb2x1bXMgKHRhcmdldENvbHVtbjE6Y29tcG9uZW50QXR0cjE7dGFyZ2V0Q29sdW1uMjpjb21wb25lbnRBdHRyMjsuLi4pLiBTZXBhcmF0ZWQgYnkgJzsnLlxuICAnZmlsdGVycycsXG5cbiAgLy8gdGFyZ2V0IFtgT1NlcnZpY2VDb21wb25lbnRgIGluc3RhbmNlXTogQ29tcG9uZW50IHdob3NlIGRhdGEgd2lsbCBiZSBmaWx0ZXJlZC5cbiAgJ3RhcmdldENtcDogdGFyZ2V0JyxcblxuICAvLyBleHByZXNzaW9uLWJ1aWxkZXIgW2Z1bnRpb25dOiBGdW50aW9uIGNhbGxlZCBmb3IgY3JlYXRpbmcgdGhlIGV4cHJlc3Npb24uXG4gICdleHByZXNzaW9uQnVpbGRlcjogZXhwcmVzc2lvbi1idWlsZGVyJyxcblxuICAvLyBxdWVyeS1vbi1jaGFuZ2UgW3llc3xub3x0cnVlfGZhbHNlXTogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRvIHRyaWdnZXIgdGhlIHRhcmdldCBjb21wb25lbnQgcmVmcmVzaCB3aGVuIGEgZmlsdGVyIGNvbXBvbmVudCBgb25DaGFuZ2VgIGV2ZW50IGlzIGZpcmVkLiBEZWZhdWx0OiBuby5cbiAgJ3F1ZXJ5T25DaGFuZ2U6IHF1ZXJ5LW9uLWNoYW5nZScsXG5cbiAgLy8gcXVlcnktb24tY2hhbmdlLWRlbGF5IFtudW1iZXJdOiBEZWxheSB0aW1lIGluIG1pbGxpc2Vjb25kcyBgcXVlcnktb24tY2hhbmdlYCBtZXRob2QgaXMgdHJpZ2dlcmVkLiBEZWZhdWx0OiAwLlxuICAncXVlcnlPbkNoYW5nZURlbGF5OiBxdWVyeS1vbi1jaGFuZ2UtZGVsYXknLFxuXG4gIC8vcXVlcnktb24tY2hhbmdlLWV2ZW50OiBbY2hhbmdlfCBvblZhbHVlQ2hhbmdlXSBUeXBlIG9mIGV2ZW50IHRoYXQgZW1pdCB3aGVuIHF1ZXJ5LW9uLWNoYW5nZT1geWVzYFxuICAncXVlcnlPbkNoYW5nZUV2ZW50VHlwZTogcXVlcnktb24tY2hhbmdlLWV2ZW50LXR5cGUnLFxuXG4gIC8vIGF0dHIgW3N0cmluZ106IGZpbHRlciBidWlsZGVyIGlkZW50aWZpZXIuIEl0IGlzIG1hbmRhdG9yeSBpZiBkYXRhIGFyZSBwcm92aWRlZCB0aHJvdWdoIHRoZSBkYXRhIGF0dHJpYnV0ZS4gRGVmYXVsdDogdGFyZ2V0IChpZiBzZXQpLlxuICAnb2F0dHI6IGF0dHInLFxuXVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9PVVRQVVRTX09fRklMVEVSX0JVSUxERVIgPSBbXG4gIC8vIEV2ZW50IHRyaWdnZXJlZCB3aGVuIHRoZSBmaWx0ZXIgYWN0aW9uIGlzIGV4ZWN1dGVkLlxuICAnb25GaWx0ZXInLFxuXG4gIC8vIEV2ZW50IHRyaWdnZXJlZCB3aGVuIHRoZSBjbGVhciBhY3Rpb24gaXMgZXhjdXRlZC5cbiAgJ29uQ2xlYXInXG5dO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvLWZpbHRlci1idWlsZGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL28tZmlsdGVyLWJ1aWxkZXIuY29tcG9uZW50Lmh0bWwnLFxuICBpbnB1dHM6IERFRkFVTFRfSU5QVVRTX09fRklMVEVSX0JVSUxERVIsXG4gIG91dHB1dHM6IERFRkFVTFRfT1VUUFVUU19PX0ZJTFRFUl9CVUlMREVSLFxuICBwcm92aWRlcnM6IFtcbiAgICB7IHByb3ZpZGU6IE9GaWx0ZXJCdWlsZGVyQmFzZSwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gT0ZpbHRlckJ1aWxkZXJDb21wb25lbnQpIH1cbiAgXVxufSlcblxuLyoqXG4gKiBUaGUgT0ZpbHRlckJ1aWxkZXJDb21wb25lbnQuXG4gKi9cblxuZXhwb3J0IGNsYXNzIE9GaWx0ZXJCdWlsZGVyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkluaXQge1xuXG4gIHB1YmxpYyBvbkZpbHRlcjogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHVibGljIG9uQ2xlYXI6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgcHVibGljIGZpbHRlcnM6IHN0cmluZztcbiAgcHVibGljIHRhcmdldENtcDogSVNlcnZpY2VEYXRhQ29tcG9uZW50O1xuICBwdWJsaWMgZXhwcmVzc2lvbkJ1aWxkZXI6ICh2YWx1ZXM6IEFycmF5PHsgYXR0ciwgdmFsdWUgfT4pID0+IEV4cHJlc3Npb247XG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBwdWJsaWMgcXVlcnlPbkNoYW5nZTogYm9vbGVhbiA9IGZhbHNlO1xuICBATnVtYmVySW5wdXRDb252ZXJ0ZXIoKVxuICBwdWJsaWMgcXVlcnlPbkNoYW5nZURlbGF5OiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcXVlcnlPbkNoYW5nZUV2ZW50VHlwZTogQ0hBTkdFX0VWRU5UUyA9IENvZGVzLkRFRkFVTFRfQ0hBTkdFX0VWRU5UO1xuXG4gIHByb3RlY3RlZCBmaWx0ZXJDb21wb25lbnRzOiBBcnJheTxJRmlsdGVyQnVpbGRlckNtcFRhcmdldD4gPSBbXTtcblxuICBwcm90ZWN0ZWQgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwdWJsaWMgb2F0dHI6IHN0cmluZztcbiAgcHJvdGVjdGVkIGNvbXBvbmVudFN0YXRlU2VydmljZTogT0ZpbHRlckJ1aWxkZXJDb21wb25lbnRTdGF0ZVNlcnZpY2U7XG4gIHByb3RlY3RlZCBsb2NhbFN0b3JhZ2VTZXJ2aWNlOiBMb2NhbFN0b3JhZ2VTZXJ2aWNlO1xuICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXI7XG4gIHByb3RlY3RlZCBhY3RSb3V0ZTogQWN0aXZhdGVkUm91dGU7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE9Gb3JtQ29tcG9uZW50KSkgcHVibGljIGZvcm06IE9Gb3JtQ29tcG9uZW50XG4gICkge1xuICAgIHRoaXMubG9jYWxTdG9yYWdlU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KExvY2FsU3RvcmFnZVNlcnZpY2UpO1xuICAgIHRoaXMuY29tcG9uZW50U3RhdGVTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQ8T0ZpbHRlckJ1aWxkZXJDb21wb25lbnRTdGF0ZVNlcnZpY2U+KE9GaWx0ZXJCdWlsZGVyQ29tcG9uZW50U3RhdGVTZXJ2aWNlKTtcbiAgICB0aGlzLnJvdXRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0PFJvdXRlcj4oUm91dGVyKTtcbiAgICB0aGlzLmFjdFJvdXRlID0gdGhpcy5pbmplY3Rvci5nZXQ8QWN0aXZhdGVkUm91dGU+KEFjdGl2YXRlZFJvdXRlKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdGlhbGl6ZUxpc3RlbmVycygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3Vic2NyaXB0aW9ucykge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgaW5pdGlhbGl6ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBvbmVudFN0YXRlU2VydmljZS5pbml0aWFsaXplKHRoaXMpO1xuICAgIC8vIFBhcnNlIGZpbHRlcnNcbiAgICBpZiAodGhpcy5maWx0ZXJzKSB7XG4gICAgICBjb25zdCBmaWx0ZXJBcnJheTogQXJyYXk8c3RyaW5nPiA9IFV0aWwucGFyc2VBcnJheSh0aGlzLmZpbHRlcnMpO1xuICAgICAgZmlsdGVyQXJyYXkuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgICAgICBjb25zdCBmaWx0ZXJFbG1zID0gZmlsdGVyLnNwbGl0KENvZGVzLkNPTFVNTlNfQUxJQVNfU0VQQVJBVE9SKTtcbiAgICAgICAgdGhpcy5maWx0ZXJDb21wb25lbnRzLnB1c2goe1xuICAgICAgICAgIHRhcmdldEF0dHI6IGZpbHRlckVsbXNbMF0sXG4gICAgICAgICAgZm9ybUNvbXBvbmVudEF0dHI6IGZpbHRlckVsbXNbMV0gPyBmaWx0ZXJFbG1zWzFdIDogZmlsdGVyRWxtc1swXVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChVdGlsLmlzRGVmaW5lZCh0aGlzLnRhcmdldENtcCkpIHtcbiAgICAgIHRoaXMudGFyZ2V0Q21wLnNldEZpbHRlckJ1aWxkZXIodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgaW5pdGlhbGl6ZUxpc3RlbmVycygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5xdWVyeU9uQ2hhbmdlKSB7XG4gICAgICB0aGlzLmZpbHRlckNvbXBvbmVudHMuZm9yRWFjaCgoZmlsdGVyQ29tcG9uZW50OiBJRmlsdGVyQnVpbGRlckNtcFRhcmdldCkgPT4ge1xuICAgICAgICBjb25zdCBmb3JtQ29tcG9uZW50OiBJRm9ybURhdGFDb21wb25lbnQgPSB0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpW2ZpbHRlckNvbXBvbmVudC5mb3JtQ29tcG9uZW50QXR0cl07XG4gICAgICAgIGlmIChmb3JtQ29tcG9uZW50KSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgICAgIHRoaXMuZ2V0RXZlbnRGcm9tRm9ybUNvbXBvbmVudChmb3JtQ29tcG9uZW50KVxuICAgICAgICAgICAgICAucGlwZShkZWJvdW5jZVRpbWUodGhpcy5xdWVyeU9uQ2hhbmdlRGVsYXkpKVxuICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMudHJpZ2dlclJlbG9hZCgpKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0RXZlbnRGcm9tRm9ybUNvbXBvbmVudChmb3JtQ29tcG9uZW50OiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5T25DaGFuZ2VFdmVudFR5cGUgPT09IENvZGVzLkRFRkFVTFRfQ0hBTkdFX0VWRU5UID9cbiAgICAgIGZvcm1Db21wb25lbnQub25WYWx1ZUNoYW5nZSA6XG4gICAgICBmb3JtQ29tcG9uZW50LmdldEZvcm1Db250cm9sKCkudmFsdWVDaGFuZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYEV4cHJlc3Npb25gIG9iamVjdCB3aXRoIHRoZSBmaWx0ZXIuXG4gICAqIEByZXR1cm5zIHRoZSBgRXhwcmVzc2lvbmAgb2JqZWN0IHdpdGggdGhlIGZpbHRlci5cbiAgICovXG4gIGdldEV4cHJlc3Npb24oKTogRXhwcmVzc2lvbiB7XG4gICAgLy8gUHJlcGFyZSBmb3JtIGZpbHRlciB2YWx1ZXMgWy4uLiB7IGF0dHIsIHZhbHVlIH1dXG4gICAgY29uc3QgZm9ybUNvbXBvbmVudHMgPSB0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpO1xuICAgIGNvbnN0IHBhcmFtczogQXJyYXk8eyBhdHRyLCB2YWx1ZSB9PiA9IFtdO1xuICAgIHRoaXMuZmlsdGVyQ29tcG9uZW50cy5mb3JFYWNoKChmaWx0ZXJDb21wb25lbnQ6IElGaWx0ZXJCdWlsZGVyQ21wVGFyZ2V0KSA9PiB7XG4gICAgICBjb25zdCBmb3JtQ29tcG9uZW50OiBJRm9ybURhdGFDb21wb25lbnQgPSBmb3JtQ29tcG9uZW50c1tmaWx0ZXJDb21wb25lbnQuZm9ybUNvbXBvbmVudEF0dHJdO1xuICAgICAgaWYgKGZvcm1Db21wb25lbnQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBmb3JtQ29tcG9uZW50LmdldFZhbHVlKCk7XG4gICAgICAgIHBhcmFtcy5wdXNoKHtcbiAgICAgICAgICBhdHRyOiBmaWx0ZXJDb21wb25lbnQudGFyZ2V0QXR0cixcbiAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBUcmlnZ2VyIHRoZSBmdW5jdGlvbiBwcm92aWRlZCBieSB0aGUgdXNlclxuICAgIGlmICh0aGlzLmV4cHJlc3Npb25CdWlsZGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uQnVpbGRlcihwYXJhbXMpO1xuICAgIH1cblxuICAgIC8vIEdlbmVyYXRlIGRlc2ZhdWx0IGV4cHJlc3Npb25cbiAgICBjb25zdCBleHByZXNzaW9uczogQXJyYXk8RXhwcmVzc2lvbj4gPSBbXTtcbiAgICBwYXJhbXMuZm9yRWFjaChlbGVtID0+IHtcbiAgICAgIGlmIChVdGlsLmlzRGVmaW5lZChlbGVtLnZhbHVlKSkge1xuICAgICAgICBleHByZXNzaW9ucy5wdXNoKEZpbHRlckV4cHJlc3Npb25VdGlscy5idWlsZEV4cHJlc3Npb25FcXVhbHMoZWxlbS5hdHRyLCBlbGVtLnZhbHVlKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZXhwcmVzc2lvbnMubGVuZ3RoID8gZXhwcmVzc2lvbnMucmVkdWNlKChmZTEsIGZlMikgPT4gRmlsdGVyRXhwcmVzc2lvblV0aWxzLmJ1aWxkQ29tcGxleEV4cHJlc3Npb24oZmUxLCBmZTIsIEZpbHRlckV4cHJlc3Npb25VdGlscy5PUF9PUikpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYEJhc2ljRXhwcmVzc2lvbmAgb2JqZWN0IHdpdGggdGhlIGZpbHRlci5cbiAgICogQHJldHVybnMgdGhlIGBCYXNpY0V4cHJlc3Npb25gIG9iamVjdCB3aXRoIHRoZSBmaWx0ZXIuXG4gICAqL1xuICBnZXRCYXNpY0V4cHJlc3Npb24oKTogQmFzaWNFeHByZXNzaW9uIHtcbiAgICByZXR1cm4gRmlsdGVyRXhwcmVzc2lvblV0aWxzLmJ1aWxkQmFzaWNFeHByZXNzaW9uKHRoaXMuZ2V0RXhwcmVzc2lvbigpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBmaWx0ZXIgYnVpbGRlciB0YXJnZXQgY29tcG9uZW50LlxuICAgKiBAcmV0dXJucyB0aGUgdGFyZ2V0IGNvbXBvbmVudC5cbiAgICovXG4gIGdldFRhcmdldENvbXBvbmVudCgpOiBJU2VydmljZURhdGFDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLnRhcmdldENtcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIHRoZSBgcmVsb2FkRGF0YWAgbWV0aG9kIGZyb20gdGhlIHRhcmdldCBjb21wb25lbnQuXG4gICAqL1xuICB0cmlnZ2VyUmVsb2FkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy50YXJnZXRDbXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMudGFyZ2V0Q21wLnBhZ2VhYmxlKSB7XG4gICAgICB0aGlzLnRhcmdldENtcC5yZWxvYWRQYWdpbmF0ZWREYXRhRnJvbVN0YXJ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGFyZ2V0Q21wLnJlbG9hZERhdGEoKTtcbiAgICB9XG4gICAgdGhpcy5vbkZpbHRlci5lbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgdGhlIGZvcm0gY29tcG9uZW50cyB1c2VkIGZvciB0aGUgZmlsdGVyLlxuICAgKi9cbiAgY2xlYXJGaWx0ZXIoKTogdm9pZCB7XG4gICAgY29uc3QgZm9ybUNvbXBvbmVudHMgPSB0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpO1xuICAgIHRoaXMuZ2V0RmlsdGVyQXR0cnMoKS5mb3JFYWNoKChhdHRyOiBzdHJpbmcpID0+IHtcbiAgICAgIGZvcm1Db21wb25lbnRzW2F0dHJdLmNsZWFyVmFsdWUoKTtcbiAgICB9KTtcbiAgICB0aGlzLm9uQ2xlYXIuZW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgZmlsdGVyIHZhbHVlc1xuICAgKiBAcmV0dXJucyBmaWx0ZXIgdmFsdWVzXG4gICAqL1xuICBnZXRGaWx0ZXJWYWx1ZXMoKTogT0ZpbHRlckJ1aWxkZXJWYWx1ZXNbXSB7XG4gICAgY29uc3QgcmVzdWx0OiBPRmlsdGVyQnVpbGRlclZhbHVlc1tdID0gW107XG5cbiAgICB0aGlzLmZpbHRlckNvbXBvbmVudHMuXG4gICAgICBmb3JFYWNoKChmaWx0ZXJDb21wb25lbnQ6IElGaWx0ZXJCdWlsZGVyQ21wVGFyZ2V0KSA9PiB7XG4gICAgICAgIGlmIChVdGlsLmlzRGVmaW5lZCh0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpW2ZpbHRlckNvbXBvbmVudC5mb3JtQ29tcG9uZW50QXR0cl0pKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goeyBhdHRyOiBmaWx0ZXJDb21wb25lbnQuZm9ybUNvbXBvbmVudEF0dHIsIHZhbHVlOiB0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpW2ZpbHRlckNvbXBvbmVudC5mb3JtQ29tcG9uZW50QXR0cl0uZ2V0VmFsdWUoKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgZmlsdGVyIHZhbHVlc1xuICAgKiBAcGFyYW0gZmlsdGVyQnVpbGRlclZhbHVlc1xuICAgKi9cbiAgc2V0RmlsdGVyVmFsdWVzKGZpbHRlckJ1aWxkZXJWYWx1ZXM6IE9GaWx0ZXJCdWlsZGVyVmFsdWVzW10pIHtcbiAgICBmaWx0ZXJCdWlsZGVyVmFsdWVzLmZvckVhY2goKGZpbHRlckJ1aWxkZXJWYWx1ZTogT0ZpbHRlckJ1aWxkZXJWYWx1ZXMpID0+IHtcbiAgICAgIGlmICh0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpW2ZpbHRlckJ1aWxkZXJWYWx1ZS5hdHRyXSkge1xuICAgICAgICB0aGlzLmZvcm0uZ2V0Q29tcG9uZW50cygpW2ZpbHRlckJ1aWxkZXJWYWx1ZS5hdHRyXS5zZXRWYWx1ZShmaWx0ZXJCdWlsZGVyVmFsdWUudmFsdWUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBmaWx0ZXIgd2l0aCBhdHRyICcgKyBmaWx0ZXJCdWlsZGVyVmFsdWUuYXR0ciArICcgY2Fubm90IGJlIHNldCAnICsgZmlsdGVyQnVpbGRlclZhbHVlLnZhbHVlICsgJyBiZWNhdXNlIGl0IGRvZXMgbm90IGV4aXN0IC4nKTtcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYXJyYXkgd2l0aCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgZmlsdGVyYWJsZSBjb21wb25lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0RmlsdGVyQXR0cnMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyQ29tcG9uZW50cy5tYXAoKGVsZW06IElGaWx0ZXJCdWlsZGVyQ21wVGFyZ2V0KSA9PiBlbGVtLmZvcm1Db21wb25lbnRBdHRyKTtcbiAgfVxuICAvKipcbiAgICogR2V0cyBzdGF0ZVxuICAgKi9cbiAgZ2V0IHN0YXRlKCk6IE9GaWx0ZXJCdWlsZGVyQ29tcG9uZW50U3RhdGVDbGFzcyB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50U3RhdGVTZXJ2aWNlLnN0YXRlO1xuICB9XG5cblxuICBnZXREYXRhVG9TdG9yZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb21wb25lbnRTdGF0ZVNlcnZpY2Uuc3RhdGU7XG4gIH1cblxuICBnZXRDb21wb25lbnRLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIVV0aWwuaXNEZWZpbmVkKHRoaXMub2F0dHIpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdZb3VyIG8tZmlsdGVyLWJ1aWxkZXIgY29tcG9uZW50IG11c3QgaGF2ZSBhbiBcXCdhdHRyXFwnLiBPdGhlcndpc2UsIHlvdXIgZmlsdGVyIGJ1aWxkZXIgc3RhdGUgd2lsbCBub3Qgc2V0IGluIGxvY2Fsc3RvcmFnZS4nKTtcbiAgICAgIHJldHVybiAnT0ZpbHRlckJ1aWxkZXJDb21wb25lbnRfJztcbiAgICB9XG5cbiAgICByZXR1cm4gJ09GaWx0ZXJCdWlsZGVyQ29tcG9uZW50XycgKyB0aGlzLm9hdHRyO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3JlcyBmaWx0ZXIgaW4gc3RhdGVcbiAgICogQHBhcmFtIGFyZ1xuICAgKi9cbiAgc3RvcmVGaWx0ZXJJblN0YXRlKGFyZzogT0ZpbHRlckRlZmluaXRpb24pIHtcbiAgICB0aGlzLmNvbXBvbmVudFN0YXRlU2VydmljZS5zdG9yZUZpbHRlcihhcmcpO1xuICAgIHRoaXMudXBkYXRlU3RhdGVTdG9yYWdlKCk7XG4gIH1cbiAgLyoqXG4gICAqIE1ldGhvZCB1cGRhdGUgc3RvcmUgbG9jYWxzdG9yYWdlLCBjYWxsIG9mIHRoZSBJTG9jYWxTdG9yYWdlXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlU3RhdGVTdG9yYWdlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2UpIHtcbiAgICAgIHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS51cGRhdGVDb21wb25lbnRTdG9yYWdlKHRoaXMsIHRoaXMuZ2V0Um91dGVLZXkoKSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldFJvdXRlS2V5KCk6IHN0cmluZyB7XG4gICAgbGV0IHJvdXRlID0gdGhpcy5yb3V0ZXIudXJsO1xuICAgIHRoaXMuYWN0Um91dGUucGFyYW1zLnN1YnNjcmliZShwYXJhbXMgPT4ge1xuICAgICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIHJvdXRlID0gcm91dGUucmVwbGFjZShwYXJhbXNba2V5XSwga2V5KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiByb3V0ZTtcbiAgfVxufVxuIiwiIl19