@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
132 lines • 20.8 kB
JavaScript
import { Query } from '../query/query';
import { BooleanOperator } from '../boolean-operator';
/**
* Represents the low level abstraction of query generation that is responsible for the creation of queries themselves.
*
* Operators are ment to be stateless and held as singleton instances, as they can be shared without any issues.
* This library uses the {@link OperatorService} to store the singleton instances, but you can use your own solution,
* or instantiate them multiple times if you prefer.
*
* @typeparam T type of arguments this Operator can generate queries from
*/
export class Operator {
/**
* Represents the placeholder "block" in operator display names.
*/
static INPUT_PLACEHOLDER = '';
/**
* Reserved characters for Elasticsearch queries. These characters can be escaped with a `\` character.
*/
static ESCAPABLE_CHARACTERS = new Set(['+', '-', '=', '&', '|', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~', '*', '?', ':', '\\', '/']);
/**
* Reserved characters for Elasticsearch queries. These characters cannot be escaped and must be removed from queries.
*/
static UNESCAPABLE_CHARACTERS = new Set(['<', '>']);
/**
* Determines the arity of the operator, that is the number of arguments/operands it takes.
*/
_numberOfOperands;
/**
* The operator symbol that is used to generate the query.
*/
_operatorSymbols;
constructor(numberOfOperands, operatorSymbols = '') {
this._numberOfOperands = numberOfOperands;
this._operatorSymbols = operatorSymbols;
}
/**
* Escapes all escapable Elasticsearch symbols. Removes all unescapable Elasticsearch symbols.
*
* For a list of symbols see Elasticsearch's Query string query
* [doc]{@link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#_reserved_characters}.
* @param input user input that should have special characters escaped
* @returns user input with the escapable characters escaped and the unescapable characters removed
*/
static escapeInput(input) {
if (typeof input === 'string') {
let escaped = false;
let output = '';
for (let i = 0; i < input.length; i++) {
if (Operator.UNESCAPABLE_CHARACTERS.has(input.charAt(i)))
continue;
if (Operator.ESCAPABLE_CHARACTERS.has(input.charAt(i))) {
output += '\\';
escaped = true;
}
output += input.charAt(i);
}
return { value: output, wasEscaped: escaped };
}
return { value: input, wasEscaped: false };
}
/**
* Creates a Query string query string literal with the provided arguments.
* @param elasticKeyword Elasticsearch index keyword for the field you want to query
* @param arg The value that you want to query the property for
* @param operator The operator you want to use to query the indexed field. Consult the Elasticsearch's
* [documentation]{@link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html}
* for more information.
* @returns combines the input strings by this pattern: `([elasticKeyword]:[operator][arg])`
*/
static query(elasticKeyword, arg, operator) {
return `(${elasticKeyword}:${operator}${arg})`;
}
/**
* Applies the provided function to all keywords and combines the resulting queries with an `OR` operator.
* @param elasticKeywords keywords that the function is call on
* @param queryConstructor function that generates a `Query` object for each keyword
*/
static forEachKeyword(elasticKeywords, queryConstructor) {
const simpleQueries = [];
elasticKeywords.forEach(keyword => {
simpleQueries.push(queryConstructor(keyword));
});
return Query.combineQueries(simpleQueries, BooleanOperator.OR);
}
/**
* If the value contains a space character, or if `force` is set to `true`.
* @param input user input that should be wrapped with double quotes
* @param forceWrap if set to `true` the value will be wrapped regardless of it's content
*/
static wrapInputWithQuotes(input, forceWrap = false) {
if (typeof input === 'string' && (input?.includes(' ') || forceWrap))
return { value: `"${input}"`, wasWrapped: true };
else
return { value: input, wasWrapped: false };
}
/**
* @returns the arity of the operator.
*/
get numberOfOperands() {
return this._numberOfOperands;
}
/**
* Simple implementation of query generation. Will not be suitable for all Operator derivatives.
*
* Escapes the first argument from the `args` array, calls the [query()]{@link Operator#query} function for each `keyword` and combines
* the results with an `OR` operator.
* @returns query that wos constructed with the given arguments and keywords. Returns an empty query if no arguments are provided.
*/
createQuery(elasticKeywords, args, escapeArgs = true) {
this.checkArgumentsCount(args);
return Operator.forEachKeyword(elasticKeywords, (keyword) => {
const escapedValue = escapeArgs ?
Operator.escapeInput(args[0]) : ({ value: args[0], wasEscaped: false });
const wrappedValue = Operator.wrapInputWithQuotes(escapedValue.value, escapedValue.wasEscaped);
const queryString = Operator.query(keyword, wrappedValue.value, this._operatorSymbols);
return new Query(queryString);
});
}
/**
* Checks whether the provided array contains at leas as many arguments, as is the operators number of operands.
* Throws an error if not enough arguments is provided.
* @param args an array of potential operands
*/
checkArgumentsCount(args) {
if (args.length < this.numberOfOperands) {
throw new Error(`At least ${this.numberOfOperands} arguments must be provided to `
+ `create a query with ${this.numberOfOperands} operands!`);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL3NlYXJjaC9tb2RlbHMvb3BlcmF0b3Ivb3BlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUlwRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBZ0IsUUFBUTtJQUUxQjs7T0FFRztJQUNJLE1BQU0sQ0FBVSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7SUFFOUM7O09BRUc7SUFDSyxNQUFNLENBQVUsb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQ2xELENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFM0c7O09BRUc7SUFDSyxNQUFNLENBQVUsc0JBQXNCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUVyRTs7T0FFRztJQUNjLGlCQUFpQixDQUFTO0lBRTNDOztPQUVHO0lBQ2MsZ0JBQWdCLENBQVM7SUFFMUMsWUFBc0IsZ0JBQXdCLEVBQUUsZUFBZSxHQUFHLEVBQUU7UUFDaEUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDO1FBQzFDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxlQUFlLENBQUM7SUFDNUMsQ0FB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WSxHQUFHLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMvRixNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3ZGLE9BQU8sSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBaUJEOzs7O09BSUc7SUFDTyxtQkFBbUIsQ0FBQyxJQUFnQjtRQUMxQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3JDLE1BQU0sSUFBSSxLQUFLLENBQUMsWUFBWSxJQUFJLENBQUMsZ0JBQWdCLGlDQUFpQztrQkFDNUUsdUJBQXVCLElBQUksQ0FBQyxnQkFBZ0IsWUFBWSxDQUFDLENBQUM7U0FDbkU7SUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtFc2NhcGVSZXN1bHR9IGZyb20gJy4uL2VzY2FwZS1yZXN1bHQnO1xuaW1wb3J0IHtRdWVyeX0gZnJvbSAnLi4vcXVlcnkvcXVlcnknO1xuaW1wb3J0IHtCb29sZWFuT3BlcmF0b3J9IGZyb20gJy4uL2Jvb2xlYW4tb3BlcmF0b3InO1xuaW1wb3J0IHtXcmFwUmVzdWx0fSBmcm9tICcuLi93cmFwLXJlc3VsdCc7XG5pbXBvcnQge09wZXJhdG9yc30gZnJvbSAnLi9vcGVyYXRvcnMnO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGxvdyBsZXZlbCBhYnN0cmFjdGlvbiBvZiBxdWVyeSBnZW5lcmF0aW9uIHRoYXQgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBjcmVhdGlvbiBvZiBxdWVyaWVzIHRoZW1zZWx2ZXMuXG4gKlxuICogT3BlcmF0b3JzIGFyZSBtZW50IHRvIGJlIHN0YXRlbGVzcyBhbmQgaGVsZCBhcyBzaW5nbGV0b24gaW5zdGFuY2VzLCBhcyB0aGV5IGNhbiBiZSBzaGFyZWQgd2l0aG91dCBhbnkgaXNzdWVzLlxuICogVGhpcyBsaWJyYXJ5IHVzZXMgdGhlIHtAbGluayBPcGVyYXRvclNlcnZpY2V9IHRvIHN0b3JlIHRoZSBzaW5nbGV0b24gaW5zdGFuY2VzLCBidXQgeW91IGNhbiB1c2UgeW91ciBvd24gc29sdXRpb24sXG4gKiBvciBpbnN0YW50aWF0ZSB0aGVtIG11bHRpcGxlIHRpbWVzIGlmIHlvdSBwcmVmZXIuXG4gKlxuICogQHR5cGVwYXJhbSBUIHR5cGUgb2YgYXJndW1lbnRzIHRoaXMgT3BlcmF0b3IgY2FuIGdlbmVyYXRlIHF1ZXJpZXMgZnJvbVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgT3BlcmF0b3I8VD4ge1xuXG4gICAgLyoqXG4gICAgICogUmVwcmVzZW50cyB0aGUgcGxhY2Vob2xkZXIgXCJibG9ja1wiIGluIG9wZXJhdG9yIGRpc3BsYXkgbmFtZXMuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTlBVVF9QTEFDRUhPTERFUiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogUmVzZXJ2ZWQgY2hhcmFjdGVycyBmb3IgRWxhc3RpY3NlYXJjaCBxdWVyaWVzLiBUaGVzZSBjaGFyYWN0ZXJzIGNhbiBiZSBlc2NhcGVkIHdpdGggYSBgXFxgIGNoYXJhY3Rlci5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBFU0NBUEFCTEVfQ0hBUkFDVEVSUyA9IG5ldyBTZXQoXG4gICAgICAgIFsnKycsICctJywgJz0nLCAnJicsICd8JywgJyEnLCAnKCcsICcpJywgJ3snLCAnfScsICdbJywgJ10nLCAnXicsICdcIicsICd+JywgJyonLCAnPycsICc6JywgJ1xcXFwnLCAnLyddKTtcblxuICAgIC8qKlxuICAgICAqIFJlc2VydmVkIGNoYXJhY3RlcnMgZm9yIEVsYXN0aWNzZWFyY2ggcXVlcmllcy4gVGhlc2UgY2hhcmFjdGVycyBjYW5ub3QgYmUgZXNjYXBlZCBhbmQgbXVzdCBiZSByZW1vdmVkIGZyb20gcXVlcmllcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBVTkVTQ0FQQUJMRV9DSEFSQUNURVJTID0gbmV3IFNldChbJzwnLCAnPiddKTtcblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgdGhlIGFyaXR5IG9mIHRoZSBvcGVyYXRvciwgdGhhdCBpcyB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cy9vcGVyYW5kcyBpdCB0YWtlcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9udW1iZXJPZk9wZXJhbmRzOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3BlcmF0b3Igc3ltYm9sIHRoYXQgaXMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgcXVlcnkuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfb3BlcmF0b3JTeW1ib2xzOiBzdHJpbmc7XG5cbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IobnVtYmVyT2ZPcGVyYW5kczogbnVtYmVyLCBvcGVyYXRvclN5bWJvbHMgPSAnJykge1xuICAgICAgICB0aGlzLl9udW1iZXJPZk9wZXJhbmRzID0gbnVtYmVyT2ZPcGVyYW5kcztcbiAgICAgICAgdGhpcy5fb3BlcmF0b3JTeW1ib2xzID0gb3BlcmF0b3JTeW1ib2xzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVzY2FwZXMgYWxsIGVzY2FwYWJsZSBFbGFzdGljc2VhcmNoIHN5bWJvbHMuIFJlbW92ZXMgYWxsIHVuZXNjYXBhYmxlIEVsYXN0aWNzZWFyY2ggc3ltYm9scy5cbiAgICAgKlxuICAgICAqIEZvciBhIGxpc3Qgb2Ygc3ltYm9scyBzZWUgRWxhc3RpY3NlYXJjaCdzIFF1ZXJ5IHN0cmluZyBxdWVyeVxuICAgICAqIFtkb2Nde0BsaW5rIGh0dHBzOi8vd3d3LmVsYXN0aWMuY28vZ3VpZGUvZW4vZWxhc3RpY3NlYXJjaC9yZWZlcmVuY2UvY3VycmVudC9xdWVyeS1kc2wtcXVlcnktc3RyaW5nLXF1ZXJ5Lmh0bWwjX3Jlc2VydmVkX2NoYXJhY3RlcnN9LlxuICAgICAqIEBwYXJhbSBpbnB1dCB1c2VyIGlucHV0IHRoYXQgc2hvdWxkIGhhdmUgc3BlY2lhbCBjaGFyYWN0ZXJzIGVzY2FwZWRcbiAgICAgKiBAcmV0dXJucyB1c2VyIGlucHV0IHdpdGggdGhlIGVzY2FwYWJsZSBjaGFyYWN0ZXJzIGVzY2FwZWQgYW5kIHRoZSB1bmVzY2FwYWJsZSBjaGFyYWN0ZXJzIHJlbW92ZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGVzY2FwZUlucHV0KGlucHV0OiBzdHJpbmcpOiBFc2NhcGVSZXN1bHQge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgbGV0IGVzY2FwZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBvdXRwdXQgPSAnJztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoT3BlcmF0b3IuVU5FU0NBUEFCTEVfQ0hBUkFDVEVSUy5oYXMoaW5wdXQuY2hhckF0KGkpKSlcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgaWYgKE9wZXJhdG9yLkVTQ0FQQUJMRV9DSEFSQUNURVJTLmhhcyhpbnB1dC5jaGFyQXQoaSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dCArPSAnXFxcXCc7XG4gICAgICAgICAgICAgICAgICAgIGVzY2FwZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaW5wdXQuY2hhckF0KGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHt2YWx1ZTogb3V0cHV0LCB3YXNFc2NhcGVkOiBlc2NhcGVkfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge3ZhbHVlOiBpbnB1dCwgd2FzRXNjYXBlZDogZmFsc2V9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBRdWVyeSBzdHJpbmcgcXVlcnkgc3RyaW5nIGxpdGVyYWwgd2l0aCB0aGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqIEBwYXJhbSBlbGFzdGljS2V5d29yZCBFbGFzdGljc2VhcmNoIGluZGV4IGtleXdvcmQgZm9yIHRoZSBmaWVsZCB5b3Ugd2FudCB0byBxdWVyeVxuICAgICAqIEBwYXJhbSBhcmcgVGhlIHZhbHVlIHRoYXQgeW91IHdhbnQgdG8gcXVlcnkgdGhlIHByb3BlcnR5IGZvclxuICAgICAqIEBwYXJhbSBvcGVyYXRvciBUaGUgb3BlcmF0b3IgeW91IHdhbnQgdG8gdXNlIHRvIHF1ZXJ5IHRoZSBpbmRleGVkIGZpZWxkLiBDb25zdWx0IHRoZSBFbGFzdGljc2VhcmNoJ3NcbiAgICAgKiBbZG9jdW1lbnRhdGlvbl17QGxpbmsgaHR0cHM6Ly93d3cuZWxhc3RpYy5jby9ndWlkZS9lbi9lbGFzdGljc2VhcmNoL3JlZmVyZW5jZS9jdXJyZW50L3F1ZXJ5LWRzbC1xdWVyeS1zdHJpbmctcXVlcnkuaHRtbH1cbiAgICAgKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgKiBAcmV0dXJucyBjb21iaW5lcyB0aGUgaW5wdXQgc3RyaW5ncyBieSB0aGlzIHBhdHRlcm46IGAoW2VsYXN0aWNLZXl3b3JkXTpbb3BlcmF0b3JdW2FyZ10pYFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcXVlcnkoZWxhc3RpY0tleXdvcmQ6IHN0cmluZywgYXJnOiBzdHJpbmcsIG9wZXJhdG9yOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYCgke2VsYXN0aWNLZXl3b3JkfToke29wZXJhdG9yfSR7YXJnfSlgO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uIHRvIGFsbCBrZXl3b3JkcyBhbmQgY29tYmluZXMgdGhlIHJlc3VsdGluZyBxdWVyaWVzIHdpdGggYW4gYE9SYCBvcGVyYXRvci5cbiAgICAgKiBAcGFyYW0gZWxhc3RpY0tleXdvcmRzIGtleXdvcmRzIHRoYXQgdGhlIGZ1bmN0aW9uIGlzIGNhbGwgb25cbiAgICAgKiBAcGFyYW0gcXVlcnlDb25zdHJ1Y3RvciBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBhIGBRdWVyeWAgb2JqZWN0IGZvciBlYWNoIGtleXdvcmRcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGZvckVhY2hLZXl3b3JkKGVsYXN0aWNLZXl3b3JkczogQXJyYXk8c3RyaW5nPiwgcXVlcnlDb25zdHJ1Y3RvcjogKGtleXdvcmQ6IHN0cmluZykgPT4gUXVlcnkpOiBRdWVyeSB7XG4gICAgICAgIGNvbnN0IHNpbXBsZVF1ZXJpZXMgPSBbXTtcbiAgICAgICAgZWxhc3RpY0tleXdvcmRzLmZvckVhY2goa2V5d29yZCA9PiB7XG4gICAgICAgICAgICBzaW1wbGVRdWVyaWVzLnB1c2gocXVlcnlDb25zdHJ1Y3RvcihrZXl3b3JkKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUXVlcnkuY29tYmluZVF1ZXJpZXMoc2ltcGxlUXVlcmllcywgQm9vbGVhbk9wZXJhdG9yLk9SKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgdmFsdWUgY29udGFpbnMgYSBzcGFjZSBjaGFyYWN0ZXIsIG9yIGlmIGBmb3JjZWAgaXMgc2V0IHRvIGB0cnVlYC5cbiAgICAgKiBAcGFyYW0gaW5wdXQgdXNlciBpbnB1dCB0aGF0IHNob3VsZCBiZSB3cmFwcGVkIHdpdGggZG91YmxlIHF1b3Rlc1xuICAgICAqIEBwYXJhbSBmb3JjZVdyYXAgaWYgc2V0IHRvIGB0cnVlYCB0aGUgdmFsdWUgd2lsbCBiZSB3cmFwcGVkIHJlZ2FyZGxlc3Mgb2YgaXQncyBjb250ZW50XG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyB3cmFwSW5wdXRXaXRoUXVvdGVzKGlucHV0OiBzdHJpbmcsIGZvcmNlV3JhcCA9IGZhbHNlKTogV3JhcFJlc3VsdCB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnICYmIChpbnB1dD8uaW5jbHVkZXMoJyAnKSB8fCBmb3JjZVdyYXApKVxuICAgICAgICAgICAgcmV0dXJuIHt2YWx1ZTogYFwiJHtpbnB1dH1cImAsIHdhc1dyYXBwZWQ6IHRydWV9O1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4ge3ZhbHVlOiBpbnB1dCwgd2FzV3JhcHBlZDogZmFsc2V9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRoZSBhcml0eSBvZiB0aGUgb3BlcmF0b3IuXG4gICAgICovXG4gICAgcHVibGljIGdldCBudW1iZXJPZk9wZXJhbmRzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9udW1iZXJPZk9wZXJhbmRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBxdWVyeSBnZW5lcmF0aW9uLiBXaWxsIG5vdCBiZSBzdWl0YWJsZSBmb3IgYWxsIE9wZXJhdG9yIGRlcml2YXRpdmVzLlxuICAgICAqXG4gICAgICogRXNjYXBlcyB0aGUgZmlyc3QgYXJndW1lbnQgZnJvbSB0aGUgYGFyZ3NgIGFycmF5LCBjYWxscyB0aGUgW3F1ZXJ5KClde0BsaW5rIE9wZXJhdG9yI3F1ZXJ5fSBmdW5jdGlvbiBmb3IgZWFjaCBga2V5d29yZGAgYW5kIGNvbWJpbmVzXG4gICAgICogdGhlIHJlc3VsdHMgd2l0aCBhbiBgT1JgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHF1ZXJ5IHRoYXQgd29zIGNvbnN0cnVjdGVkIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50cyBhbmQga2V5d29yZHMuIFJldHVybnMgYW4gZW1wdHkgcXVlcnkgaWYgbm8gYXJndW1lbnRzIGFyZSBwcm92aWRlZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlUXVlcnkoZWxhc3RpY0tleXdvcmRzOiBBcnJheTxzdHJpbmc+LCBhcmdzOiBBcnJheTxUPiwgZXNjYXBlQXJncyA9IHRydWUpOiBRdWVyeSB7XG4gICAgICAgIHRoaXMuY2hlY2tBcmd1bWVudHNDb3VudChhcmdzKTtcbiAgICAgICAgcmV0dXJuIE9wZXJhdG9yLmZvckVhY2hLZXl3b3JkKGVsYXN0aWNLZXl3b3JkcywgKGtleXdvcmQ6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXNjYXBlZFZhbHVlID0gZXNjYXBlQXJncyA/XG4gICAgICAgICAgICAgICAgT3BlcmF0b3IuZXNjYXBlSW5wdXQoYXJnc1swXSBhcyB1bmtub3duIGFzIHN0cmluZykgOiAoe3ZhbHVlOiBhcmdzWzBdIGFzIHVua25vd24gYXMgc3RyaW5nLCB3YXNFc2NhcGVkOiBmYWxzZX0pO1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFZhbHVlID0gT3BlcmF0b3Iud3JhcElucHV0V2l0aFF1b3Rlcyhlc2NhcGVkVmFsdWUudmFsdWUsIGVzY2FwZWRWYWx1ZS53YXNFc2NhcGVkKTtcbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5U3RyaW5nID0gT3BlcmF0b3IucXVlcnkoa2V5d29yZCwgd3JhcHBlZFZhbHVlLnZhbHVlLCB0aGlzLl9vcGVyYXRvclN5bWJvbHMpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBRdWVyeShxdWVyeVN0cmluZyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIHRlbXBsYXRlIGlzIHVzZWQgd2hlbiBnZW5lcmF0aW5nIHNlYXJjaCBHVUksIGFuZCBzbyB0aGUgYXJpdHkgb2YgdGhlIG9wZXJhdG9yIHNob3VsZCBtYXRjaCB0aGUgbnVtYmVyIG9mXG4gICAgICoge0BsaW5rIElOUFVUX1BMQUNFSE9MREVSfSBjb25zdGFudCBvY2N1cnJlbmNlcyBpbiB0aGUgcmV0dXJuZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBhbiBhcnJheSBvZiB0cmFuc2xhdGlvbiBwYXRocyB0aGF0IHJlcHJlc2VudCB0aGUgb3BlcmF0b3IgbmFtZSwgYXMgaXQgc2hvdWxkIGJlIGRpc3BsYXllZCB0byB0aGUgdXNlci5cbiAgICAgKiBUaGUge0BsaW5rIElOUFVUX1BMQUNFSE9MREVSfSBjb25zdGFudCAob3IgYW55IGZhbHN5IHZhbHVlKSBjYW4gYmUgdXNlZCB0byBwbGFjZSB2aXN1YWwgaW5wdXQgcGxhY2Vob2xkZXIgYmxvY2tzIGluIHRoZVxuICAgICAqIG9wZXJhdG9yIG5hbWUgd2hlcmUgdXNlciBpbnB1dCBpcyBleHBlY3RlZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWJzdHJhY3QgZ2V0T3BlcmF0b3JOYW1lVGVtcGxhdGUoKTogQXJyYXk8c3RyaW5nPjtcblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRoZSBvcGVyYXRvciBjbGFzcyBpbiBhIHNlcmlhbGl6YWJsZSBmb3JtXG4gICAgICovXG4gICAgcHVibGljIGFic3RyYWN0IHNlcmlhbGl6ZSgpOiBPcGVyYXRvcnMgfCBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcHJvdmlkZWQgYXJyYXkgY29udGFpbnMgYXQgbGVhcyBhcyBtYW55IGFyZ3VtZW50cywgYXMgaXMgdGhlIG9wZXJhdG9ycyBudW1iZXIgb2Ygb3BlcmFuZHMuXG4gICAgICogVGhyb3dzIGFuIGVycm9yIGlmIG5vdCBlbm91Z2ggYXJndW1lbnRzIGlzIHByb3ZpZGVkLlxuICAgICAqIEBwYXJhbSBhcmdzIGFuIGFycmF5IG9mIHBvdGVudGlhbCBvcGVyYW5kc1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBjaGVja0FyZ3VtZW50c0NvdW50KGFyZ3M6IEFycmF5PGFueT4pOiB2b2lkIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgdGhpcy5udW1iZXJPZk9wZXJhbmRzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEF0IGxlYXN0ICR7dGhpcy5udW1iZXJPZk9wZXJhbmRzfSBhcmd1bWVudHMgbXVzdCBiZSBwcm92aWRlZCB0byBgXG4gICAgICAgICAgICAgICAgKyBgY3JlYXRlIGEgcXVlcnkgd2l0aCAke3RoaXMubnVtYmVyT2ZPcGVyYW5kc30gb3BlcmFuZHMhYCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=