UNPKG

@knora/core

Version:
176 lines 33.3 kB
import * as tslib_1 from "tslib"; import { Injectable } from '@angular/core'; import { Constants } from '@knora/api'; import { KnoraConstants, KnoraSchema } from '../../declarations/api/knora-constants'; import { ExtendedSearchParams, SearchParamsService } from './search-params.service'; import * as i0 from "@angular/core"; import * as i1 from "./search-params.service"; /** * @deprecated Use new service from `@knora/api` (github:dasch-swiss/knora-api-js-lib) instead * * Create GravSearch queries from provided parameters. */ var GravsearchGenerationService = /** @class */ (function () { function GravsearchGenerationService(_searchParamsService) { this._searchParamsService = _searchParamsService; } GravsearchGenerationService_1 = GravsearchGenerationService; /** * @deprecated since v10.0.0 * * Will be replaced by `@knora/api` (github:knora-api-js-lib) * * Generates a Gravsearch query from the provided arguments. * * @param {PropertyWithValue[]} properties the properties specified by the user. * @param {string} [mainResourceClassOption] the class of the main resource, if specified. * @param {number} offset the offset to be used (nth page of results). * @returns string - a KnarQL query string. */ GravsearchGenerationService.prototype.createGravsearchQuery = function (properties, mainResourceClassOption, offset) { if (offset === void 0) { offset = 0; } // class restriction for the resource searched for var mainResourceClass = ''; // if given, create the class restriction for the main resource if (mainResourceClassOption !== undefined) { mainResourceClass = "?mainRes a <" + mainResourceClassOption + "> ."; } // criteria for the order by statement var orderByCriteria = []; // statements to be returned in query results var returnStatements = []; // loop over given properties and create statements and filters from them var props = properties.map(function (propWithVal, index) { // represents the object of a statement var propValue; if (!propWithVal.property.isLinkProperty || propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Exists') { // it is not a linking property, create a variable for the value (to be used by a subsequent FILTER) // OR the comparison operator Exists is used in which case we do not need to specify the object any further propValue = "?propVal" + index; } else { // it is a linking property and the comparison operator is not Exists, use its IRI propValue = propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex); } // generate statement var statement = "?mainRes <" + propWithVal.property.id + "> " + propValue + " ."; // check if it is a linking property that has to be wrapped in a FILTER NOT EXISTS (comparison operator NOT_EQUALS) to negate it if (propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') { // do not include statement in results, because the query checks for the absence of this statement statement = "FILTER NOT EXISTS {\n" + statement + "\n\n\n}"; } else { // TODO: check if statement should be returned returned in results (Boolean flag from checkbox) returnStatements.push(statement); statement = "\n" + statement + "\n\n\n"; } // generate restricting expression (e.g., a FILTER) if comparison operator is not Exists var restriction = ''; // only create a FILTER if the comparison operator is not EXISTS and it is not a linking property if (!propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() !== 'Exists') { // generate variable for value literal var propValueLiteral = propValue + "Literal"; if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Like') { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // use regex function for LIKE restriction += "FILTER regex(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ", \"i\")"; } else if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Match') { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // use contains function for MATCH restriction += "FILTER <" + KnoraConstants.MatchFunction + ">(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")"; } else if (propWithVal.property.objectType === Constants.DateValue) { // handle date property restriction = "FILTER(knora-api:toSimpleDate(" + propValue + ") " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")"; } else if (propWithVal.property.objectType === Constants.ListValue) { // handle list node restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + '\n'; // check for comparison operator "not equals" if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') { restriction = "FILTER NOT EXISTS {\n " + restriction + "\n }"; } } else { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // generate filter expression restriction += "FILTER(" + propValueLiteral + " " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")"; } } // check if current value is a sort criterion if (propWithVal.isSortCriterion) orderByCriteria.push(propValue); return statement + "\n" + restriction + "\n"; }); var orderByStatement = ''; if (orderByCriteria.length > 0) { orderByStatement = "\nORDER BY " + orderByCriteria.join(' ') + "\n"; } // template of the Gravsearch query with dynamic components var gravsearchTemplate = "\nPREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>\nCONSTRUCT {\n\n?mainRes knora-api:isMainResource true .\n\n" + returnStatements.join('\n') + "\n\n} WHERE {\n\n?mainRes a knora-api:Resource .\n\n" + mainResourceClass + "\n\n" + props.join('') + "\n\n}\n" + orderByStatement; // offset component of the Gravsearch query var offsetTemplate = "\nOFFSET " + offset + "\n"; // function that generates the same KnarQL query with the given offset var generateGravsearchQueryWithCustomOffset = function (localOffset) { var offsetCustomTemplate = "\nOFFSET " + localOffset + "\n"; return gravsearchTemplate + offsetCustomTemplate; }; if (offset === 0) { // store the function so another KnarQL query can be created with an increased offset this._searchParamsService.changeSearchParamsMsg(new ExtendedSearchParams(generateGravsearchQueryWithCustomOffset)); } return gravsearchTemplate + offsetTemplate; }; var GravsearchGenerationService_1; /** * @ignore * * Map of complex knora-api value types to simple ones. * Use computed property name: http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer. */ GravsearchGenerationService.typeConversionComplexToSimple = { 'http://api.knora.org/ontology/knora-api/v2#IntValue': Constants.XsdInteger, 'http://api.knora.org/ontology/knora-api/v2#DecimalValue': Constants.XsdDecimal, 'http://api.knora.org/ontology/knora-api/v2#BooleanValue': Constants.XsdBoolean, 'http://api.knora.org/ontology/knora-api/v2#TextValue': Constants.XsdString, 'http://api.knora.org/ontology/knora-api/v2#UriValue': Constants.XsdAnyUri, 'http://api.knora.org/ontology/knora-api/v2#DateValue': KnoraConstants.dateSimple, 'http://api.knora.org/ontology/knora-api/v2#IntervalValue': KnoraConstants.intervalSimple, 'http://api.knora.org/ontology/knora-api/v2#GeomValue': KnoraConstants.geomSimple, 'http://api.knora.org/ontology/knora-api/v2#ColorValue': KnoraConstants.colorSimple, 'http://api.knora.org/ontology/knora-api/v2#GeonameValue': KnoraConstants.geonameSimple, 'http://api.knora.org/ontology/knora-api/v2#StillImageFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#FileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#MovingImageFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#DDDFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#AudioFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#DocumentFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#TextFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#ListValue': KnoraConstants.listNodeSimple }; GravsearchGenerationService.complexTypeToProp = { 'http://api.knora.org/ontology/knora-api/v2#IntValue': Constants.IntValueAsInt, 'http://api.knora.org/ontology/knora-api/v2#DecimalValue': Constants.DecimalValueAsDecimal, 'http://api.knora.org/ontology/knora-api/v2#BooleanValue': Constants.BooleanValueAsBoolean, 'http://api.knora.org/ontology/knora-api/v2#TextValue': Constants.ValueAsString, 'http://api.knora.org/ontology/knora-api/v2#UriValue': Constants.UriValueAsUri, 'http://api.knora.org/ontology/knora-api/v2#ListValue': Constants.ListValueAsListNode }; GravsearchGenerationService.ctorParameters = function () { return [ { type: SearchParamsService } ]; }; GravsearchGenerationService.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function GravsearchGenerationService_Factory() { return new GravsearchGenerationService(i0.ɵɵinject(i1.SearchParamsService)); }, token: GravsearchGenerationService, providedIn: "root" }); GravsearchGenerationService = GravsearchGenerationService_1 = tslib_1.__decorate([ Injectable({ providedIn: 'root' }), tslib_1.__metadata("design:paramtypes", [SearchParamsService]) ], GravsearchGenerationService); return GravsearchGenerationService; }()); export { GravsearchGenerationService }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jhdi1zZWFyY2guc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Brbm9yYS9jb3JlLyIsInNvdXJjZXMiOlsibGliL3NlcnZpY2VzL3YyL2dyYXYtc2VhcmNoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBR3JGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7QUFFcEY7Ozs7R0FJRztBQUlIO0lBc0NJLHFDQUFvQixvQkFBeUM7UUFBekMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFxQjtJQUFJLENBQUM7b0NBdEN6RCwyQkFBMkI7SUF3Q3BDOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsMkRBQXFCLEdBQXJCLFVBQXNCLFVBQStCLEVBQUUsdUJBQWdDLEVBQUUsTUFBa0I7UUFBbEIsdUJBQUEsRUFBQSxVQUFrQjtRQUV2RyxrREFBa0Q7UUFDbEQsSUFBSSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFFM0IsK0RBQStEO1FBQy9ELElBQUksdUJBQXVCLEtBQUssU0FBUyxFQUFFO1lBQ3ZDLGlCQUFpQixHQUFHLGlCQUFlLHVCQUF1QixRQUFLLENBQUM7U0FDbkU7UUFFRCxzQ0FBc0M7UUFDdEMsSUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBRTNCLDZDQUE2QztRQUM3QyxJQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUU1Qix5RUFBeUU7UUFDekUsSUFBTSxLQUFLLEdBQWEsVUFBVSxDQUFDLEdBQUcsQ0FDbEMsVUFBQyxXQUE4QixFQUFFLEtBQWE7WUFFMUMsdUNBQXVDO1lBQ3ZDLElBQUksU0FBUyxDQUFDO1lBQ2QsSUFBSSxDQUFDLFdBQVcs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aUUsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUM1Rix5REFBeUQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUNwRiwyREFBMkQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUN0Riw4REFBOEQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUN6RiwwREFBMEQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUNyRixzREFBc0QsRUFBRSxjQUFjLENBQUMsY0FBYztLQUN4RixDQUFDO0lBRVksNkNBQWlCLEdBQUc7UUFDOUIscURBQXFELEVBQUUsU0FBUyxDQUFDLGFBQWE7UUFDOUUseURBQXlELEVBQUUsU0FBUyxDQUFDLHFCQUFxQjtRQUMxRix5REFBeUQsRUFBRSxTQUFTLENBQUMscUJBQXFCO1FBQzFGLHNEQUFzRCxFQUFFLFNBQVMsQ0FBQyxhQUFhO1FBQy9FLHFEQUFxRCxFQUFFLFNBQVMsQ0FBQyxhQUFhO1FBQzlFLHNEQUFzRCxFQUFFLFNBQVMsQ0FBQyxtQkFBbUI7S0FDeEYsQ0FBQzs7Z0JBRXdDLG1CQUFtQjs7O0lBdENwRCwyQkFBMkI7UUFIdkMsVUFBVSxDQUFDO1lBQ1IsVUFBVSxFQUFFLE1BQU07U0FDckIsQ0FBQztpREF1QzRDLG1CQUFtQjtPQXRDcEQsMkJBQTJCLENBME12QztzQ0ExTkQ7Q0EwTkMsQUExTUQsSUEwTUM7U0ExTVksMkJBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSAnQGtub3JhL2FwaSc7XG5cbmltcG9ydCB7IEtub3JhQ29uc3RhbnRzLCBLbm9yYVNjaGVtYSB9IGZyb20gJy4uLy4uL2RlY2xhcmF0aW9ucy9hcGkva25vcmEtY29uc3RhbnRzJztcbmltcG9ydCB7IFByb3BlcnR5V2l0aFZhbHVlIH0gZnJvbSAnLi4vLi4vZGVjbGFyYXRpb25zL2FwaS9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBFeHRlbmRlZFNlYXJjaFBhcmFtcywgU2VhcmNoUGFyYW1zU2VydmljZSB9IGZyb20gJy4vc2VhcmNoLXBhcmFtcy5zZXJ2aWNlJztcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgbmV3IHNlcnZpY2UgZnJvbSBgQGtub3JhL2FwaWAgKGdpdGh1YjpkYXNjaC1zd2lzcy9rbm9yYS1hcGktanMtbGliKSBpbnN0ZWFkXG4gKlxuICogQ3JlYXRlIEdyYXZTZWFyY2ggcXVlcmllcyBmcm9tIHByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgR3JhdnNlYXJjaEdlbmVyYXRpb25TZXJ2aWNlIHtcblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKlxuICAgICAqIE1hcCBvZiBjb21wbGV4IGtub3JhLWFwaSB2YWx1ZSB0eXBlcyB0byBzaW1wbGUgb25lcy5cbiAgICAgKiBVc2UgY29tcHV0ZWQgcHJvcGVydHkgbmFtZTogaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC1pbml0aWFsaXplci5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHR5cGVDb252ZXJzaW9uQ29tcGxleFRvU2ltcGxlID0ge1xuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0ludFZhbHVlJzogQ29uc3RhbnRzLlhzZEludGVnZXIsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjRGVjaW1hbFZhbHVlJzogQ29uc3RhbnRzLlhzZERlY2ltYWwsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjQm9vbGVhblZhbHVlJzogQ29uc3RhbnRzLlhzZEJvb2xlYW4sXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjVGV4dFZhbHVlJzogQ29uc3RhbnRzLlhzZFN0cmluZyxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNVcmlWYWx1ZSc6IENvbnN0YW50cy5Yc2RBbnlVcmksXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjRGF0ZVZhbHVlJzogS25vcmFDb25zdGFudHMuZGF0ZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNJbnRlcnZhbFZhbHVlJzogS25vcmFDb25zdGFudHMuaW50ZXJ2YWxTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjR2VvbVZhbHVlJzogS25vcmFDb25zdGFudHMuZ2VvbVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNDb2xvclZhbHVlJzogS25vcmFDb25zdGFudHMuY29sb3JTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjR2VvbmFtZVZhbHVlJzogS25vcmFDb25zdGFudHMuZ2VvbmFtZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNTdGlsbEltYWdlRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNGaWxlVmFsdWUnOiBLbm9yYUNvbnN0YW50cy5maWxlU2ltcGxlLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI01vdmluZ0ltYWdlRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNERERGaWxlVmFsdWUnOiBLbm9yYUNvbnN0YW50cy5maWxlU2ltcGxlLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0F1ZGlvRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNEb2N1bWVudEZpbGVWYWx1ZSc6IEtub3JhQ29uc3RhbnRzLmZpbGVTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjVGV4dEZpbGVWYWx1ZSc6IEtub3JhQ29uc3RhbnRzLmZpbGVTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjTGlzdFZhbHVlJzogS25vcmFDb25zdGFudHMubGlzdE5vZGVTaW1wbGVcbiAgICB9O1xuXG4gICAgcHVibGljIHN0YXRpYyBjb21wbGV4VHlwZVRvUHJvcCA9IHtcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNJbnRWYWx1ZSc6IENvbnN0YW50cy5JbnRWYWx1ZUFzSW50LFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0RlY2ltYWxWYWx1ZSc6IENvbnN0YW50cy5EZWNpbWFsVmFsdWVBc0RlY2ltYWwsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjQm9vbGVhblZhbHVlJzogQ29uc3RhbnRzLkJvb2xlYW5WYWx1ZUFzQm9vbGVhbixcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNUZXh0VmFsdWUnOiBDb25zdGFudHMuVmFsdWVBc1N0cmluZyxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNVcmlWYWx1ZSc6IENvbnN0YW50cy5VcmlWYWx1ZUFzVXJpLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0xpc3RWYWx1ZSc6IENvbnN0YW50cy5MaXN0VmFsdWVBc0xpc3ROb2RlXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3NlYXJjaFBhcmFtc1NlcnZpY2U6IFNlYXJjaFBhcmFtc1NlcnZpY2UpIHsgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdjEwLjAuMFxuICAgICAqXG4gICAgICogV2lsbCBiZSByZXBsYWNlZCBieSBgQGtub3JhL2FwaWAgKGdpdGh1Yjprbm9yYS1hcGktanMtbGliKVxuICAgICAqXG4gICAgICogR2VuZXJhdGVzIGEgR3JhdnNlYXJjaCBxdWVyeSBmcm9tIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1Byb3BlcnR5V2l0aFZhbHVlW119IHByb3BlcnRpZXMgdGhlIHByb3BlcnRpZXMgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbWFpblJlc291cmNlQ2xhc3NPcHRpb25dIHRoZSBjbGFzcyBvZiB0aGUgbWFpbiByZXNvdXJjZSwgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgdGhlIG9mZnNldCB0byBiZSB1c2VkIChudGggcGFnZSBvZiByZXN1bHRzKS5cbiAgICAgKiBAcmV0dXJucyBzdHJpbmcgLSBhIEtuYXJRTCBxdWVyeSBzdHJpbmcuXG4gICAgICovXG4gICAgY3JlYXRlR3JhdnNlYXJjaFF1ZXJ5KHByb3BlcnRpZXM6IFByb3BlcnR5V2l0aFZhbHVlW10sIG1haW5SZXNvdXJjZUNsYXNzT3B0aW9uPzogc3RyaW5nLCBvZmZzZXQ6IG51bWJlciA9IDApOiBzdHJpbmcge1xuXG4gICAgICAgIC8vIGNsYXNzIHJlc3RyaWN0aW9uIGZvciB0aGUgcmVzb3VyY2Ugc2VhcmNoZWQgZm9yXG4gICAgICAgIGxldCBtYWluUmVzb3VyY2VDbGFzcyA9ICcnO1xuXG4gICAgICAgIC8vIGlmIGdpdmVuLCBjcmVhdGUgdGhlIGNsYXNzIHJlc3RyaWN0aW9uIGZvciB0aGUgbWFpbiByZXNvdXJjZVxuICAgICAgICBpZiAobWFpblJlc291cmNlQ2xhc3NPcHRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFpblJlc291cmNlQ2xhc3MgPSBgP21haW5SZXMgYSA8JHttYWluUmVzb3VyY2VDbGFzc09wdGlvbn0+IC5gO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY3JpdGVyaWEgZm9yIHRoZSBvcmRlciBieSBzdGF0ZW1lbnRcbiAgICAgICAgY29uc3Qgb3JkZXJCeUNyaXRlcmlhID0gW107XG5cbiAgICAgICAgLy8gc3RhdGVtZW50cyB0byBiZSByZXR1cm5lZCBpbiBxdWVyeSByZXN1bHRzXG4gICAgICAgIGNvbnN0IHJldHVyblN0YXRlbWVudHMgPSBbXTtcblxuICAgICAgICAvLyBsb29wIG92ZXIgZ2l2ZW4gcHJvcGVydGllcyBhbmQgY3JlYXRlIHN0YXRlbWVudHMgYW5kIGZpbHRlcnMgZnJvbSB0aGVtXG4gICAgICAgIGNvbnN0IHByb3BzOiBzdHJpbmdbXSA9IHByb3BlcnRpZXMubWFwKFxuICAgICAgICAgICAgKHByb3BXaXRoVmFsOiBQcm9wZXJ0eVdpdGhWYWx1ZSwgaW5kZXg6IG51bWJlcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgLy8gcmVwcmVzZW50cyB0aGUgb2JqZWN0IG9mIGEgc3RhdGVtZW50XG4gICAgICAgICAgICAgICAgbGV0IHByb3BWYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoIXByb3BXaXRoVmFsLnByb3BlcnR5LmlzTGlua1Byb3BlcnR5IHx8IHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdFeGlzdHMnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IGlzIG5vdCBhIGxpbmtpbmcgcHJvcGVydHksIGNyZWF0ZSBhIHZhcmlhYmxlIGZvciB0aGUgdmFsdWUgKHRvIGJlIHVzZWQgYnkgYSBzdWJzZXF1ZW50IEZJTFRFUilcbiAgICAgICAgICAgICAgICAgICAgLy8gT1IgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgRXhpc3RzIGlzIHVzZWQgaW4gd2hpY2ggY2FzZSB3ZSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IHRoZSBvYmplY3QgYW55IGZ1cnRoZXJcbiAgICAgICAgICAgICAgICAgICAgcHJvcFZhbHVlID0gYD9wcm9wVmFsJHtpbmRleH1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IGlzIGEgbGlua2luZyBwcm9wZXJ0eSBhbmQgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgaXMgbm90IEV4aXN0cywgdXNlIGl0cyBJUklcbiAgICAgICAgICAgICAgICAgICAgcHJvcFZhbHVlID0gcHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLnZhbHVlLnRvU3BhcnFsKEtub3JhU2NoZW1hLmNvbXBsZXgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHN0YXRlbWVudFxuICAgICAgICAgICAgICAgIGxldCBzdGF0ZW1lbnQ6IHN0cmluZyA9IGA/bWFpblJlcyA8JHtwcm9wV2l0aFZhbC5wcm9wZXJ0eS5pZH0+ICR7cHJvcFZhbHVlfSAuYDtcblxuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIGEgbGlua2luZyBwcm9wZXJ0eSB0aGF0IGhhcyB0byBiZSB3cmFwcGVkIGluIGEgRklMVEVSIE5PVCBFWElTVFMgKGNvbXBhcmlzb24gb3BlcmF0b3IgTk9UX0VRVUFMUykgdG8gbmVnYXRlIGl0XG4gICAgICAgICAgICAgICAgaWYgKHByb3BXaXRoVmFsLnByb3BlcnR5LmlzTGlua1Byb3BlcnR5ICYmIHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdOb3RFcXVhbHMnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBpbmNsdWRlIHN0YXRlbWVudCBpbiByZXN1bHRzLCBiZWNhdXNlIHRoZSBxdWVyeSBjaGVja3MgZm9yIHRoZSBhYnNlbmNlIG9mIHRoaXMgc3RhdGVtZW50XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudCA9IGBGSUxURVIgTk9UIEVYSVNUUyB7XG4ke3N0YXRlbWVudH1cblxuXG59YDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBjaGVjayBpZiBzdGF0ZW1lbnQgc2hvdWxkIGJlIHJldHVybmVkIHJldHVybmVkIGluIHJlc3VsdHMgKEJvb2xlYW4gZmxhZyBmcm9tIGNoZWNrYm94KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50ID0gYFxuJHtzdGF0ZW1lbnR9XG5cblxuYDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSByZXN0cmljdGluZyBleHByZXNzaW9uIChlLmcuLCBhIEZJTFRFUikgaWYgY29tcGFyaXNvbiBvcGVyYXRvciBpcyBub3QgRXhpc3RzXG4gICAgICAgICAgICAgICAgbGV0IHJlc3RyaWN0aW9uOiBzdHJpbmcgPSAnJztcbiAgICAgICAgICAgICAgICAvLyBvbmx5IGNyZWF0ZSBhIEZJTFRFUiBpZiB0aGUgY29tcGFyaXNvbiBvcGVyYXRvciBpcyBub3QgRVhJU1RTIGFuZCBpdCBpcyBub3QgYSBsaW5raW5nIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgaWYgKCFwcm9wV2l0aFZhbC5wcm9wZXJ0eS5pc0xpbmtQcm9wZXJ0eSAmJiBwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLmdldENsYXNzTmFtZSgpICE9PSAnRXhpc3RzJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSB2YXJpYWJsZSBmb3IgdmFsdWUgbGl0ZXJhbFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9wVmFsdWVMaXRlcmFsID0gYCR7cHJvcFZhbHVlfUxpdGVyYWxgO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLmdldENsYXNzTmFtZSgpID09PSAnTGlrZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHN0YXRlbWVudCB0byB2YWx1ZSBsaXRlcmFsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGlvbiA9IGAke3Byb3BWYWx1ZX0gPCR7R3JhdnNlYXJjaEdlbmVyYXRpb25TZXJ2aWNlLmNvbXBsZXhUeXBlVG9Qcm9wW3Byb3BXaXRoVmFsLnByb3BlcnR5Lm9iamVjdFR5cGVdfT4gJHtwcm9wVmFsdWVMaXRlcmFsfWAgKyAnXFxuJztcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSByZWdleCBmdW5jdGlvbiBmb3IgTElLRVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gKz0gYEZJTFRFUiByZWdleCgke3Byb3BWYWx1ZUxpdGVyYWx9LCAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC52YWx1ZS50b1NwYXJxbChLbm9yYVNjaGVtYS5jb21wbGV4KX0sIFwiaVwiKWA7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLmNvbXBhcmlzb25PcGVyYXRvci5nZXRDbGFzc05hbWUoKSA9PT0gJ01hdGNoJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgc3RhdGVtZW50IHRvIHZhbHVlIGxpdGVyYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BWYWx1ZUxpdGVyYWx9YCArICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIGNvbnRhaW5zIGZ1bmN0aW9uIGZvciBNQVRDSFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gKz0gYEZJTFRFUiA8JHtLbm9yYUNvbnN0YW50cy5NYXRjaEZ1bmN0aW9ufT4oJHtwcm9wVmFsdWVMaXRlcmFsfSwgJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwudmFsdWUudG9TcGFycWwoS25vcmFTY2hlbWEuY29tcGxleCl9KWA7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZSA9PT0gQ29uc3RhbnRzLkRhdGVWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGRhdGUgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYEZJTFRFUihrbm9yYS1hcGk6dG9TaW1wbGVEYXRlKCR7cHJvcFZhbHVlfSkgJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLnR5cGV9ICR7cHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLnZhbHVlLnRvU3BhcnFsKEtub3JhU2NoZW1hLmNvbXBsZXgpfSlgO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3BXaXRoVmFsLnByb3BlcnR5Lm9iamVjdFR5cGUgPT09IENvbnN0YW50cy5MaXN0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBsaXN0IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC52YWx1ZS50b1NwYXJxbChLbm9yYVNjaGVtYS5jb21wbGV4KX1gICsgJ1xcbic7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgY29tcGFyaXNvbiBvcGVyYXRvciBcIm5vdCBlcXVhbHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdOb3RFcXVhbHMnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gPSBgRklMVEVSIE5PVCBFWElTVFMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3Jlc3RyaWN0aW9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1gO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgc3RhdGVtZW50IHRvIHZhbHVlIGxpdGVyYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BWYWx1ZUxpdGVyYWx9YCArICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgZmlsdGVyIGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uICs9IGBGSUxURVIoJHtwcm9wVmFsdWVMaXRlcmFsfSAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IudHlwZX0gJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwudmFsdWUudG9TcGFycWwoS25vcmFTY2hlbWEuY29tcGxleCl9KWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBjdXJyZW50IHZhbHVlIGlzIGEgc29ydCBjcml0ZXJpb25cbiAgICAgICAgICAgICAgICBpZiAocHJvcFdpdGhWYWwuaXNTb3J0Q3JpdGVyaW9uKSBvcmRlckJ5Q3JpdGVyaWEucHVzaChwcm9wVmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3N0YXRlbWVudH1cbiR7cmVzdHJpY3Rpb259XG5gO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBsZXQgb3JkZXJCeVN0YXRlbWVudCA9ICcnO1xuXG4gICAgICAgIGlmIChvcmRlckJ5Q3JpdGVyaWEubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgb3JkZXJCeVN0YXRlbWVudCA9IGBcbk9SREVSIEJZICR7b3JkZXJCeUNyaXRlcmlhLmpvaW4oJyAnKX1cbmA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0ZW1wbGF0ZSBvZiB0aGUgR3JhdnNlYXJjaCBxdWVyeSB3aXRoIGR5bmFtaWMgY29tcG9uZW50c1xuICAgICAgICBjb25zdCBncmF2c2VhcmNoVGVtcGxhdGUgPSBgXG5QUkVGSVgga25vcmEtYXBpOiA8aHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyIz5cbkNPTlNUUlVDVCB7XG5cbj9tYWluUmVzIGtub3JhLWFwaTppc01haW5SZXNvdXJjZSB0cnVlIC5cblxuJHtyZXR1cm5TdGF0ZW1lbnRzLmpvaW4oJ1xcbicpfVxuXG59IFdIRVJFIHtcblxuP21haW5SZXMgYSBrbm9yYS1hcGk6UmVzb3VyY2UgLlxuXG4ke21haW5SZXNvdXJjZUNsYXNzfVxuXG4ke3Byb3BzLmpvaW4oJycpfVxuXG59XG4ke29yZGVyQnlTdGF0ZW1lbnR9YDtcblxuICAgICAgICAvLyBvZmZzZXQgY29tcG9uZW50IG9mIHRoZSBHcmF2c2VhcmNoIHF1ZXJ5XG4gICAgICAgIGNvbnN0IG9mZnNldFRlbXBsYXRlID0gYFxuT0ZGU0VUICR7b2Zmc2V0fVxuYDtcblxuICAgICAgICAvLyBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyB0aGUgc2FtZSBLbmFyUUwgcXVlcnkgd2l0aCB0aGUgZ2l2ZW4gb2Zmc2V0XG4gICAgICAgIGNvbnN0IGdlbmVyYXRlR3JhdnNlYXJjaFF1ZXJ5V2l0aEN1c3RvbU9mZnNldCA9IChsb2NhbE9mZnNldDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEN1c3RvbVRlbXBsYXRlID0gYFxuT0ZGU0VUICR7bG9jYWxPZmZzZXR9XG5gO1xuXG4gICAgICAgICAgICByZXR1cm4gZ3JhdnNlYXJjaFRlbXBsYXRlICsgb2Zmc2V0Q3VzdG9tVGVtcGxhdGU7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG9mZnNldCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGZ1bmN0aW9uIHNvIGFub3RoZXIgS25hclFMIHF1ZXJ5IGNhbiBiZSBjcmVhdGVkIHdpdGggYW4gaW5jcmVhc2VkIG9mZnNldFxuICAgICAgICAgICAgdGhpcy5fc2VhcmNoUGFyYW1zU2VydmljZS5jaGFuZ2VTZWFyY2hQYXJhbXNNc2cobmV3IEV4dGVuZGVkU2VhcmNoUGFyYW1zKGdlbmVyYXRlR3JhdnNlYXJjaFF1ZXJ5V2l0aEN1c3RvbU9mZnNldCkpO1xuICAgICAgICB9XG5cblxuICAgICAgICByZXR1cm4gZ3JhdnNlYXJjaFRlbXBsYXRlICsgb2Zmc2V0VGVtcGxhdGU7XG5cbiAgICB9XG5cbn1cbiJdfQ==