UNPKG

@knora/search

Version:
210 lines 30.1 kB
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=