@knora/search
Version:
Knora ui module: search
210 lines • 30.1 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, EventEmitter, Inject, Input, Output, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiResponseError, KnoraApiConnection, OntologiesMetadata, OntologyMetadata, ReadResource } from '@knora/api';
import { GravsearchGenerationService, KnoraApiConnectionToken, OntologyCacheService, OntologyInformation, Properties, PropertyWithValue, ResourceClass } from '@knora/core';
import { SelectResourceClassComponent } from './select-resource-class/select-resource-class.component';
/**
* The extended search allows you to filter by project, by source type (resource class), or by the metadata (properties) of source types. Each filter can be standalone or combined. The metadata field can be precisely filtered with criteria such as "contains", "like", "equals to", "exists" or in case of a date value with "before" or "after". In addition, for a metadata field that is connected to another source type, it's possible to filter by this second source type. If you are looking for the source type "Photograph" with the metadata field "Photographer", which is connected to source type "Person", you can search for photograph(s) taken by person(s) who is born before February 1970. The result of this request will be an intersection of the two source types.
*/
var ExtendedSearchComponent = /** @class */ (function () {
function ExtendedSearchComponent(fb, knoraApiConnection, _route, _router, _cacheService, _gravSearchService) {
this.fb = fb;
this.knoraApiConnection = knoraApiConnection;
this._route = _route;
this._router = _router;
this._cacheService = _cacheService;
this._gravSearchService = _gravSearchService;
/**
* @param {boolean} toggleExtendedSearchForm Trigger toggle for extended search form.
*/
this.toggleExtendedSearchForm = new EventEmitter();
/**
* @param {string} gravsearch Send the gravsearch query back.
*/
this.gravsearch = new EventEmitter();
// all available ontologies
this.ontologies = [];
// properties specified by the user
this.activeProperties = [];
// resource classes for the selected ontology
this.resourceClasses = [];
this.result = [new ReadResource()];
// form validation status
this.formValid = false;
}
ExtendedSearchComponent.prototype.ngOnInit = function () {
var _this = this;
// parent form is empty, it gets passed to the child components
this.form = this.fb.group({});
// if form status changes, re-run validation
this.form.statusChanges.subscribe(function (data) {
_this.formValid = _this.validateForm();
// console.log(this.form);
});
// initialize ontologies to be used for the ontologies selection in the search form
this.initializeOntologies();
};
/**
* @ignore
* Add a property to the search form.
* @returns void
*/
ExtendedSearchComponent.prototype.addProperty = function () {
this.activeProperties.push(true);
};
/**
* @ignore
* Remove the last property from the search form.
* @returns void
*/
ExtendedSearchComponent.prototype.removeProperty = function () {
this.activeProperties.splice(-1, 1);
};
/**
* @ignore
* Gets all available ontologies for the search form.
* @returns void
*/
ExtendedSearchComponent.prototype.initializeOntologies = function () {
var _this = this;
this.knoraApiConnection.v2.onto.getOntologiesMetadata().subscribe(function (response) {
_this.ontologies = response.ontologies;
}, function (error) {
console.error(error);
});
};
/**
* @ignore
* Once an ontology has been selected, gets its classes and properties.
* The classes and properties will be made available to the user for selection.
*
* @param ontologyIri Iri of the ontology chosen by the user.
* @returns void
*/
ExtendedSearchComponent.prototype.getResourceClassesAndPropertiesForOntology = function (ontologyIri) {
var _this = this;
// reset active resource class definition
this.activeResourceClass = undefined;
// reset specified properties
this.activeProperties = [];
this.activeOntology = ontologyIri;
this._cacheService.getEntityDefinitionsForOntologies([ontologyIri]).subscribe(function (ontoInfo) {
_this.resourceClasses = ontoInfo.getResourceClassesAsArray(true);
_this.properties = ontoInfo.getProperties();
});
};
/**
* @ignore
* Once a resource class has been selected, gets its properties.
* The properties will be made available to the user for selection.
*
* @param resourceClassIri
* @returns void
*/
ExtendedSearchComponent.prototype.getPropertiesForResourceClass = function (resourceClassIri) {
var _this = this;
// reset specified properties
this.activeProperties = [];
// if the client undoes the selection of a resource class, use the active ontology as a fallback
if (resourceClassIri === null) {
this.getResourceClassesAndPropertiesForOntology(this.activeOntology);
}
else {
this._cacheService.getResourceClassDefinitions([resourceClassIri]).subscribe(function (ontoInfo) {
_this.properties = ontoInfo.getProperties();
_this.activeResourceClass = ontoInfo.getResourceClasses()[resourceClassIri];
});
}
};
/**
* @ignore
* Validates form and returns its status (boolean).
*/
ExtendedSearchComponent.prototype.validateForm = function () {
// check that either a resource class is selected or at least one property is specified
return this.form.valid &&
(this.propertyComponents.length > 0 || (this.resourceClassComponent !== undefined && this.resourceClassComponent.getResourceClassSelected() !== false));
};
/**
* @ignore
* Resets the form (selected resource class and specified properties) preserving the active ontology.
*/
ExtendedSearchComponent.prototype.resetForm = function () {
if (this.activeOntology !== undefined) {
this.getResourceClassesAndPropertiesForOntology(this.activeOntology);
}
};
/**
* @ignore
* Creates a GravSearch query with the given form values and calls the extended search route.
*/
ExtendedSearchComponent.prototype.submit = function () {
if (!this.formValid)
return; // check that from is valid
var resClassOption = this.resourceClassComponent.getResourceClassSelected();
var resClass;
if (resClassOption !== false) {
resClass = resClassOption;
}
var properties = this.propertyComponents.map(function (propComp) {
return propComp.getPropertySelectedWithValue();
});
var gravsearch = this._gravSearchService.createGravsearchQuery(properties, resClass, 0);
if (this.route) {
this._router.navigate([this.route + '/extended/', gravsearch], { relativeTo: this._route });
}
else {
this.gravsearch.emit(gravsearch);
}
// toggle extended search form
this.toggleExtendedSearchForm.emit(true);
};
ExtendedSearchComponent.ctorParameters = function () { return [
{ type: FormBuilder, decorators: [{ type: Inject, args: [FormBuilder,] }] },
{ type: KnoraApiConnection, decorators: [{ type: Inject, args: [KnoraApiConnectionToken,] }] },
{ type: ActivatedRoute },
{ type: Router },
{ type: OntologyCacheService },
{ type: GravsearchGenerationService }
]; };
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "route", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "toggleExtendedSearchForm", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "gravsearch", void 0);
tslib_1.__decorate([
ViewChild('resourceClass', { static: false }),
tslib_1.__metadata("design:type", SelectResourceClassComponent)
], ExtendedSearchComponent.prototype, "resourceClassComponent", void 0);
tslib_1.__decorate([
ViewChildren('property'),
tslib_1.__metadata("design:type", QueryList)
], ExtendedSearchComponent.prototype, "propertyComponents", void 0);
ExtendedSearchComponent = tslib_1.__decorate([
Component({
selector: 'kui-extended-search',
template: "<form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"kui-form-content\">\n\n <div>\n <kui-select-ontology *ngIf=\"ontologies.length > 0\" [formGroup]=\"form\" [ontologies]=\"ontologies\"\n (ontologySelected)=\"getResourceClassesAndPropertiesForOntology($event)\"></kui-select-ontology>\n </div>\n\n <div class=\"select-resource-class\" *ngIf=\"resourceClasses?.length > 0\">\n <kui-select-resource-class #resourceClass [formGroup]=\"form\" [resourceClasses]=\"resourceClasses\"\n (resourceClassSelectedEvent)=\"getPropertiesForResourceClass($event)\">\n </kui-select-resource-class>\n </div>\n\n <div class=\"select-property\" *ngIf=\"properties !== undefined\">\n <div *ngFor=\"let prop of activeProperties; let i = index\">\n\n <kui-select-property #property [activeResourceClass]=\"activeResourceClass\" [formGroup]=\"form\" [index]=\"i\"\n [properties]=\"properties\"></kui-select-property>\n\n </div>\n </div>\n\n\n <div class=\"select-property buttons\">\n <button mat-mini-fab class=\"property-button add-property-button\" color=\"primary\" type=\"button\"\n (click)=\"addProperty()\" [disabled]=\"activeOntology === undefined || activeProperties.length >= 4\">\n <mat-icon aria-label=\"add a property\">add</mat-icon>\n </button>\n\n <button mat-mini-fab class=\"property-button remove-property-button\" color=\"primary\" type=\"button\"\n (click)=\"removeProperty()\" [disabled]=\"activeProperties.length == 0\">\n <mat-icon aria-label=\"remove property\">remove</mat-icon>\n </button>\n </div>\n\n <!-- <div>\n <button mat-icon-button type=\"button\" (click)=\"resetForm()\" [disabled]=\"this.activeOntology === undefined\">\n <mat-icon aria-label=\"reset query form\">clear</mat-icon>\n </button>\n\n <button mat-icon-button type=\"submit\" [disabled]=\"!formValid\">\n <mat-icon aria-label=\"submit query\">send</mat-icon>\n </button>\n </div> -->\n\n <div class=\"kui-form-action\">\n <button class=\"reset\" mat-button type=\"button\" (click)=\"resetForm()\" [disabled]=\"this.activeOntology === undefined\">\n Reset\n </button>\n <span class=\"fill-remaining-space\"></span>\n <button class=\"extended-search-button\" mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"!formValid\">\n Search\n </button>\n </div>\n\n</form>\n",
styles: [".select-resource-class{margin-left:8px}.select-property{margin-left:16px}.select-property .property-button{margin:0 12px 64px 0}"]
}),
tslib_1.__param(0, Inject(FormBuilder)),
tslib_1.__param(1, Inject(KnoraApiConnectionToken)),
tslib_1.__metadata("design:paramtypes", [FormBuilder,
KnoraApiConnection,
ActivatedRoute,
Router,
OntologyCacheService,
GravsearchGenerationService])
], ExtendedSearchComponent);
return ExtendedSearchComponent;
}());
export { ExtendedSearchComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5kZWQtc2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Brbm9yYS9zZWFyY2gvIiwic291cmNlcyI6WyJsaWIvZXh0ZW5kZWQtc2VhcmNoL2V4dGVuZGVkLXNlYXJjaC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNILE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RILE9BQU8sRUFBRSwyQkFBMkIsRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRzVLLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBRXZHOztHQUVHO0FBTUg7SUFpREksaUNBQ2lDLEVBQWUsRUFDSCxrQkFBc0MsRUFDdkUsTUFBc0IsRUFDdEIsT0FBZSxFQUNmLGFBQW1DLEVBQ25DLGtCQUErQztRQUwxQixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ0gsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN2RSxXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUN0QixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQ2Ysa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ25DLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBNkI7UUFo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QUMsQ0FBQTtpREFEQyxXQUFXO1lBQ2lCLGtCQUFrQjtZQUMvRCxjQUFjO1lBQ2IsTUFBTTtZQUNBLG9CQUFvQjtZQUNmLDJCQUEyQjtPQXZEbEQsdUJBQXVCLENBaU9uQztJQUFELDhCQUFDO0NBQUEsQUFqT0QsSUFpT0M7U0FqT1ksdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBRdWVyeUxpc3QsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBBcGlSZXNwb25zZUVycm9yLCBLbm9yYUFwaUNvbm5lY3Rpb24sIE9udG9sb2dpZXNNZXRhZGF0YSwgT250b2xvZ3lNZXRhZGF0YSwgUmVhZFJlc291cmNlIH0gZnJvbSAnQGtub3JhL2FwaSc7XG5pbXBvcnQgeyBHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UsIEtub3JhQXBpQ29ubmVjdGlvblRva2VuLCBPbnRvbG9neUNhY2hlU2VydmljZSwgT250b2xvZ3lJbmZvcm1hdGlvbiwgUHJvcGVydGllcywgUHJvcGVydHlXaXRoVmFsdWUsIFJlc291cmNlQ2xhc3MgfSBmcm9tICdAa25vcmEvY29yZSc7XG5cbmltcG9ydCB7IFNlbGVjdFByb3BlcnR5Q29tcG9uZW50IH0gZnJvbSAnLi9zZWxlY3QtcHJvcGVydHkvc2VsZWN0LXByb3BlcnR5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWxlY3RSZXNvdXJjZUNsYXNzQ29tcG9uZW50IH0gZnJvbSAnLi9zZWxlY3QtcmVzb3VyY2UtY2xhc3Mvc2VsZWN0LXJlc291cmNlLWNsYXNzLmNvbXBvbmVudCc7XG5cbi8qKlxuICogVGhlIGV4dGVuZGVkIHNlYXJjaCBhbGxvd3MgeW91IHRvIGZpbHRlciBieSBwcm9qZWN0LCBieSBzb3VyY2UgdHlwZSAocmVzb3VyY2UgY2xhc3MpLCBvciBieSB0aGUgbWV0YWRhdGEgKHByb3BlcnRpZXMpIG9mIHNvdXJjZSB0eXBlcy4gRWFjaCBmaWx0ZXIgY2FuIGJlIHN0YW5kYWxvbmUgb3IgY29tYmluZWQuIFRoZSBtZXRhZGF0YSBmaWVsZCBjYW4gYmUgcHJlY2lzZWx5IGZpbHRlcmVkIHdpdGggY3JpdGVyaWEgc3VjaCBhcyBcImNvbnRhaW5zXCIsIFwibGlrZVwiLCBcImVxdWFscyB0b1wiLCBcImV4aXN0c1wiIG9yIGluIGNhc2Ugb2YgYSBkYXRlIHZhbHVlIHdpdGggXCJiZWZvcmVcIiBvciBcImFmdGVyXCIuIEluIGFkZGl0aW9uLCBmb3IgYSBtZXRhZGF0YSBmaWVsZCB0aGF0IGlzIGNvbm5lY3RlZCB0byBhbm90aGVyIHNvdXJjZSB0eXBlLCBpdCdzIHBvc3NpYmxlIHRvIGZpbHRlciBieSB0aGlzIHNlY29uZCBzb3VyY2UgdHlwZS4gSWYgeW91IGFyZSBsb29raW5nIGZvciB0aGUgc291cmNlIHR5cGUgXCJQaG90b2dyYXBoXCIgd2l0aCB0aGUgbWV0YWRhdGEgZmllbGQgXCJQaG90b2dyYXBoZXJcIiwgd2hpY2ggaXMgY29ubmVjdGVkIHRvIHNvdXJjZSB0eXBlIFwiUGVyc29uXCIsIHlvdSBjYW4gc2VhcmNoIGZvciBwaG90b2dyYXBoKHMpIHRha2VuIGJ5IHBlcnNvbihzKSB3aG8gaXMgYm9ybiBiZWZvcmUgRmVicnVhcnkgMTk3MC4gVGhlIHJlc3VsdCBvZiB0aGlzIHJlcXVlc3Qgd2lsbCBiZSBhbiBpbnRlcnNlY3Rpb24gb2YgdGhlIHR3byBzb3VyY2UgdHlwZXMuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAna3VpLWV4dGVuZGVkLXNlYXJjaCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2V4dGVuZGVkLXNlYXJjaC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZXh0ZW5kZWQtc2VhcmNoLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRXh0ZW5kZWRTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtICB7c3RyaW5nfSByb3V0ZSBSb3V0ZSB0byBuYXZpZ2F0ZSBhZnRlciBzZWFyY2guIFRoaXMgcm91dGUgcGF0aCBzaG91bGQgY29udGFpbiBhIGNvbXBvbmVudCBmb3Igc2VhcmNoIHJlc3VsdHMuXG4gICAgICovXG4gICAgQElucHV0KCkgcm91dGU/O1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtICB7Ym9vbGVhbn0gdG9nZ2xlRXh0ZW5kZWRTZWFyY2hGb3JtIFRyaWdnZXIgdG9nZ2xlIGZvciBleHRlbmRlZCBzZWFyY2ggZm9ybS5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgdG9nZ2xlRXh0ZW5kZWRTZWFyY2hGb3JtID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtICB7c3RyaW5nfSBncmF2c2VhcmNoIFNlbmQgdGhlIGdyYXZzZWFyY2ggcXVlcnkgYmFjay5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgZ3JhdnNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgLy8gYWxsIGF2YWlsYWJsZSBvbnRvbG9naWVzXG4gICAgb250b2xvZ2llczogT250b2xvZ3lNZXRhZGF0YVtdID0gW107XG5cbiAgICAvLyBvbnRvbG9neSBjaG9zZW4gYnkgdGhlIHVzZXJcbiAgICBhY3RpdmVPbnRvbG9neTogc3RyaW5nO1xuXG4gICAgLy8gcHJvcGVydGllcyBzcGVjaWZpZWQgYnkgdGhlIHVzZXJcbiAgICBhY3RpdmVQcm9wZXJ0aWVzOiBib29sZWFuW10gPSBbXTtcblxuICAgIC8vIHJlc291cmNlIGNsYXNzZXMgZm9yIHRoZSBzZWxlY3RlZCBvbnRvbG9neVxuICAgIHJlc291cmNlQ2xhc3NlczogQXJyYXk8UmVzb3VyY2VDbGFzcz4gPSBbXTtcblxuICAgIC8vIGRlZmluaXRpb24gb2YgdGhlIHNlbGVjdGVkIHJlc291cmNlIGNsYXNzLCBpZiBzZXQuXG4gICAgYWN0aXZlUmVzb3VyY2VDbGFzczogUmVzb3VyY2VDbGFzcztcblxuICAgIC8vIHByb3BlcnRpZXMgZm9yIHRoZSBzZWxlY3RlZCBvbnRvbG9neSBvciBzZWxlY3RlZCByZXNvdXJjZSBjbGFzc1xuICAgIHByb3BlcnRpZXM6IFByb3BlcnRpZXM7XG5cbiAgICByZXN1bHQ6IFJlYWRSZXNvdXJjZVtdID0gW25ldyBSZWFkUmVzb3VyY2UoKV07XG5cbiAgICAvLyByZWZlcmVuY2UgdG8gdGhlIGNvbXBvbmVudCB0aGF0IGNvbnRyb2xzIHRoZSByZXNvdXJjZSBjbGFzcyBzZWxlY3Rpb25cbiAgICBAVmlld0NoaWxkKCdyZXNvdXJjZUNsYXNzJywgeyBzdGF0aWM6IGZhbHNlIH0pIHJlc291cmNlQ2xhc3NDb21wb25lbnQ6IFNlbGVjdFJlc291cmNlQ2xhc3NDb21wb25lbnQ7XG5cbiAgICAvLyByZWZlcmVuY2UgdG8gdGhlIGNvbXBvbmVudCBjb250cm9sbGluZyB0aGUgcHJvcGVydHkgc2VsZWN0aW9uXG4gICAgQFZpZXdDaGlsZHJlbigncHJvcGVydHknKSBwcm9wZXJ0eUNvbXBvbmVudHM6IFF1ZXJ5TGlzdDxTZWxlY3RQcm9wZXJ0eUNvbXBvbmVudD47XG5cbiAgICAvLyBGb3JtR3JvdXAgKHVzZWQgYXMgcGFyZW50IGZvciBjaGlsZCBjb21wb25lbnRzKVxuICAgIGZvcm06IEZvcm1Hcm91cDtcblxuICAgIC8vIGZvcm0gdmFsaWRhdGlvbiBzdGF0dXNcbiAgICBmb3JtVmFsaWQgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBASW5qZWN0KEZvcm1CdWlsZGVyKSBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICAgICAgQEluamVjdChLbm9yYUFwaUNvbm5lY3Rpb25Ub2tlbikgcHJpdmF0ZSBrbm9yYUFwaUNvbm5lY3Rpb246IEtub3JhQXBpQ29ubmVjdGlvbixcbiAgICAgICAgcHJpdmF0ZSBfcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgICAgICBwcml2YXRlIF9yb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgcHJpdmF0ZSBfY2FjaGVTZXJ2aWNlOiBPbnRvbG9neUNhY2hlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBfZ3JhdlNlYXJjaFNlcnZpY2U6IEdyYXZzZWFyY2hHZW5lcmF0aW9uU2VydmljZSkge1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuXG4gICAgICAgIC8vIHBhcmVudCBmb3JtIGlzIGVtcHR5LCBpdCBnZXRzIHBhc3NlZCB0byB0aGUgY2hpbGQgY29tcG9uZW50c1xuICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKHt9KTtcblxuICAgICAgICAvLyBpZiBmb3JtIHN0YXR1cyBjaGFuZ2VzLCByZS1ydW4gdmFsaWRhdGlvblxuICAgICAgICB0aGlzLmZvcm0uc3RhdHVzQ2hhbmdlcy5zdWJzY3JpYmUoKGRhdGEpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkID0gdGhpcy52YWxpZGF0ZUZvcm0oKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZm9ybSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGluaXRpYWxpemUgb250b2xvZ2llcyB0byBiZSB1c2VkIGZvciB0aGUgb250b2xvZ2llcyBzZWxlY3Rpb24gaW4gdGhlIHNlYXJjaCBmb3JtXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZU9udG9sb2dpZXMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogQWRkIGEgcHJvcGVydHkgdG8gdGhlIHNlYXJjaCBmb3JtLlxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBhZGRQcm9wZXJ0eSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hY3RpdmVQcm9wZXJ0aWVzLnB1c2godHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIFJlbW92ZSB0aGUgbGFzdCBwcm9wZXJ0eSBmcm9tIHRoZSBzZWFyY2ggZm9ybS5cbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgcmVtb3ZlUHJvcGVydHkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYWN0aXZlUHJvcGVydGllcy5zcGxpY2UoLTEsIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBHZXRzIGFsbCBhdmFpbGFibGUgb250b2xvZ2llcyBmb3IgdGhlIHNlYXJjaCBmb3JtLlxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBpbml0aWFsaXplT250b2xvZ2llcygpOiB2b2lkIHtcblxuICAgICAgICB0aGlzLmtub3JhQXBpQ29ubmVjdGlvbi52Mi5vbnRvLmdldE9udG9sb2dpZXNNZXRhZGF0YSgpLnN1YnNjcmliZShcbiAgICAgICAgICAgIChyZXNwb25zZTogT250b2xvZ2llc01ldGFkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbnRvbG9naWVzID0gcmVzcG9uc2Uub250b2xvZ2llcztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoZXJyb3I6IEFwaVJlc3BvbnNlRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBPbmNlIGFuIG9udG9sb2d5IGhhcyBiZWVuIHNlbGVjdGVkLCBnZXRzIGl0cyBjbGFzc2VzIGFuZCBwcm9wZXJ0aWVzLlxuICAgICAqIFRoZSBjbGFzc2VzIGFuZCBwcm9wZXJ0aWVzIHdpbGwgYmUgbWFkZSBhdmFpbGFibGUgdG8gdGhlIHVzZXIgZm9yIHNlbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvbnRvbG9neUlyaSBJcmkgb2YgdGhlIG9udG9sb2d5IGNob3NlbiBieSB0aGUgdXNlci5cbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgZ2V0UmVzb3VyY2VDbGFzc2VzQW5kUHJvcGVydGllc0Zvck9udG9sb2d5KG9udG9sb2d5SXJpOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICAvLyByZXNldCBhY3RpdmUgcmVzb3VyY2UgY2xhc3MgZGVmaW5pdGlvblxuICAgICAgICB0aGlzLmFjdGl2ZVJlc291cmNlQ2xhc3MgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gcmVzZXQgc3BlY2lmaWVkIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5hY3RpdmVQcm9wZXJ0aWVzID0gW107XG5cbiAgICAgICAgdGhpcy5hY3RpdmVPbnRvbG9neSA9IG9udG9sb2d5SXJpO1xuXG4gICAgICAgIHRoaXMuX2NhY2hlU2VydmljZS5nZXRFbnRpdHlEZWZpbml0aW9uc0Zvck9udG9sb2dpZXMoW29udG9sb2d5SXJpXSkuc3Vic2NyaWJlKFxuICAgICAgICAgICAgKG9udG9JbmZvOiBPbnRvbG9neUluZm9ybWF0aW9uKSA9PiB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlc291cmNlQ2xhc3NlcyA9IG9udG9JbmZvLmdldFJlc291cmNlQ2xhc3Nlc0FzQXJyYXkodHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gb250b0luZm8uZ2V0UHJvcGVydGllcygpO1xuXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogT25jZSBhIHJlc291cmNlIGNsYXNzIGhhcyBiZWVuIHNlbGVjdGVkLCBnZXRzIGl0cyBwcm9wZXJ0aWVzLlxuICAgICAqIFRoZSBwcm9wZXJ0aWVzIHdpbGwgYmUgbWFkZSBhdmFpbGFibGUgdG8gdGhlIHVzZXIgZm9yIHNlbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXNvdXJjZUNsYXNzSXJpXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGdldFByb3BlcnRpZXNGb3JSZXNvdXJjZUNsYXNzKHJlc291cmNlQ2xhc3NJcmk6IHN0cmluZyk6IHZvaWQge1xuXG4gICAgICAgIC8vIHJlc2V0IHNwZWNpZmllZCBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuYWN0aXZlUHJvcGVydGllcyA9IFtdO1xuXG4gICAgICAgIC8vIGlmIHRoZSBjbGllbnQgdW5kb2VzIHRoZSBzZWxlY3Rpb24gb2YgYSByZXNvdXJjZSBjbGFzcywgdXNlIHRoZSBhY3RpdmUgb250b2xvZ3kgYXMgYSBmYWxsYmFja1xuICAgICAgICBpZiAocmVzb3VyY2VDbGFzc0lyaSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5nZXRSZXNvdXJjZUNsYXNzZXNBbmRQcm9wZXJ0aWVzRm9yT250b2xvZ3kodGhpcy5hY3RpdmVPbnRvbG9neSk7XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIHRoaXMuX2NhY2hlU2VydmljZS5nZXRSZXNvdXJjZUNsYXNzRGVmaW5pdGlvbnMoW3Jlc291cmNlQ2xhc3NJcmldKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgKG9udG9JbmZvOiBPbnRvbG9neUluZm9ybWF0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcGVydGllcyA9IG9udG9JbmZvLmdldFByb3BlcnRpZXMoKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlc291cmNlQ2xhc3MgPSBvbnRvSW5mby5nZXRSZXNvdXJjZUNsYXNzZXMoKVtyZXNvdXJjZUNsYXNzSXJpXTtcblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIFZhbGlkYXRlcyBmb3JtIGFuZCByZXR1cm5zIGl0cyBzdGF0dXMgKGJvb2xlYW4pLlxuICAgICAqL1xuICAgIHByaXZhdGUgdmFsaWRhdGVGb3JtKCkge1xuXG4gICAgICAgIC8vIGNoZWNrIHRoYXQgZWl0aGVyIGEgcmVzb3VyY2UgY2xhc3MgaXMgc2VsZWN0ZWQgb3IgYXQgbGVhc3Qgb25lIHByb3BlcnR5IGlzIHNwZWNpZmllZFxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtLnZhbGlkICYmXG4gICAgICAgICAgICAodGhpcy5wcm9wZXJ0eUNvbXBvbmVudHMubGVuZ3RoID4gMCB8fCAodGhpcy5yZXNvdXJjZUNsYXNzQ29tcG9uZW50ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5yZXNvdXJjZUNsYXNzQ29tcG9uZW50LmdldFJlc291cmNlQ2xhc3NTZWxlY3RlZCgpICE9PSBmYWxzZSkpO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIFJlc2V0cyB0aGUgZm9ybSAoc2VsZWN0ZWQgcmVzb3VyY2UgY2xhc3MgYW5kIHNwZWNpZmllZCBwcm9wZXJ0aWVzKSBwcmVzZXJ2aW5nIHRoZSBhY3RpdmUgb250b2xvZ3kuXG4gICAgICovXG4gICAgcmVzZXRGb3JtKCkge1xuICAgICAgICBpZiAodGhpcy5hY3RpdmVPbnRvbG9neSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlc291cmNlQ2xhc3Nlc0FuZFByb3BlcnRpZXNGb3JPbnRvbG9neSh0aGlzLmFjdGl2ZU9udG9sb2d5KTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIENyZWF0ZXMgYSBHcmF2U2VhcmNoIHF1ZXJ5IHdpdGggdGhlIGdpdmVuIGZvcm0gdmFsdWVzIGFuZCBjYWxscyB0aGUgZXh0ZW5kZWQgc2VhcmNoIHJvdXRlLlxuICAgICAqL1xuICAgIHN1Ym1pdCgpIHtcblxuICAgICAgICBpZiAoIXRoaXMuZm9ybVZhbGlkKSByZXR1cm47IC8vIGNoZWNrIHRoYXQgZnJvbSBpcyB2YWxpZFxuXG4gICAgICAgIGNvbnN0IHJlc0NsYXNzT3B0aW9uID0gdGhpcy5yZXNvdXJjZUNsYXNzQ29tcG9uZW50LmdldFJlc291cmNlQ2xhc3NTZWxlY3RlZCgpO1xuXG4gICAgICAgIGxldCByZXNDbGFzcztcblxuICAgICAgICBpZiAocmVzQ2xhc3NPcHRpb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXNDbGFzcyA9IHJlc0NsYXNzT3B0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvcGVydGllczogUHJvcGVydHlXaXRoVmFsdWVbXSA9IHRoaXMucHJvcGVydHlDb21wb25lbnRzLm1hcChcbiAgICAgICAgICAgIChwcm9wQ29tcCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9wQ29tcC5nZXRQcm9wZXJ0eVNlbGVjdGVkV2l0aFZhbHVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgZ3JhdnNlYXJjaCA9IHRoaXMuX2dyYXZTZWFyY2hTZXJ2aWNlLmNyZWF0ZUdyYXZzZWFyY2hRdWVyeShwcm9wZXJ0aWVzLCByZXNDbGFzcywgMCk7XG5cbiAgICAgICAgaWYgKHRoaXMucm91dGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShbdGhpcy5yb3V0ZSArICcvZXh0ZW5kZWQvJywgZ3JhdnNlYXJjaF0sIHsgcmVsYXRpdmVUbzogdGhpcy5fcm91dGUgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdyYXZzZWFyY2guZW1pdChncmF2c2VhcmNoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRvZ2dsZSBleHRlbmRlZCBzZWFyY2ggZm9ybVxuICAgICAgICB0aGlzLnRvZ2dsZUV4dGVuZGVkU2VhcmNoRm9ybS5lbWl0KHRydWUpO1xuXG4gICAgfVxuXG59XG4iXX0=