firebase-bolt
Version:
Firebase Bolt Security and Modeling Language Compiler
626 lines (625 loc) • 70.5 kB
JavaScript
"use strict";
exports.__esModule = true;
/*
* AST builders for Firebase Rules Language.
*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var util = require("./util");
var logger = require("./logger");
var errors = {
typeMismatch: "Unexpected type: ",
duplicatePathPart: "A path component name is duplicated: "
};
;
;
var PathPart = /** @class */ (function () {
// "label", undefined - static path part
// "$label", X - variable path part
// X, !undefined - variable path part
function PathPart(label, variable) {
if (label[0] === '$' && variable === undefined) {
variable = label;
}
if (variable && label[0] !== '$') {
label = '$' + label;
}
this.label = label;
this.variable = variable;
}
return PathPart;
}());
exports.PathPart = PathPart;
var PathTemplate = /** @class */ (function () {
function PathTemplate(parts) {
if (parts === void 0) { parts = []; }
this.parts = parts.map(function (part) {
if (util.isType(part, 'string')) {
return new PathPart(part);
}
else {
return part;
}
});
}
PathTemplate.prototype.copy = function () {
var result = new PathTemplate();
result.push(this);
return result;
};
PathTemplate.prototype.getLabels = function () {
return this.parts.map(function (part) { return part.label; });
};
// Mapping from variables to JSON labels
PathTemplate.prototype.getScope = function () {
var result = {};
this.parts.forEach(function (part) {
if (part.variable) {
if (result[part.variable]) {
throw new Error(errors.duplicatePathPart + part.variable);
}
result[part.variable] = literal(part.label);
}
});
return result;
};
PathTemplate.prototype.push = function (temp) {
util.extendArray(this.parts, temp.parts);
};
PathTemplate.prototype.pop = function (temp) {
var _this = this;
temp.parts.forEach(function (part) {
_this.parts.pop();
});
};
PathTemplate.prototype.length = function () {
return this.parts.length;
};
PathTemplate.prototype.getPart = function (i) {
if (i > this.parts.length || i < -this.parts.length) {
var l = this.parts.length;
throw new Error("Path reference out of bounds: " + i +
" [" + -l + " .. " + l + "]");
}
if (i < 0) {
return this.parts[this.parts.length + i];
}
return this.parts[i];
};
return PathTemplate;
}());
exports.PathTemplate = PathTemplate;
;
var Schema = /** @class */ (function () {
function Schema() {
}
Schema.isGeneric = function (schema) {
return schema.params !== undefined && schema.params.length > 0;
};
return Schema;
}());
exports.Schema = Schema;
;
exports.string = valueGen('String');
exports.boolean = valueGen('Boolean');
exports.number = valueGen('Number');
exports.array = valueGen('Array');
exports.neg = opGen('neg', 1);
exports.not = opGen('!', 1);
exports.mult = opGen('*');
exports.div = opGen('/');
exports.mod = opGen('%');
exports.add = opGen('+');
exports.sub = opGen('-');
exports.eq = opGen('==');
exports.lt = opGen('<');
exports.lte = opGen('<=');
exports.gt = opGen('>');
exports.gte = opGen('>=');
exports.ne = opGen('!=');
exports.and = opGen('&&');
exports.or = opGen('||');
exports.ternary = opGen('?:', 3);
exports.value = opGen('value', 1);
function variable(name) {
return { type: 'var', valueType: 'Any', name: name };
}
exports.variable = variable;
function literal(name) {
return { type: 'literal', valueType: 'Any', name: name };
}
exports.literal = literal;
function nullType() {
return { type: 'Null', valueType: 'Null' };
}
exports.nullType = nullType;
function reference(base, prop) {
return {
type: 'ref',
valueType: 'Any',
base: base,
accessor: prop
};
}
exports.reference = reference;
var reIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_]*$/;
function isIdentifierStringExp(exp) {
return exp.type === 'String' && reIdentifier.test(exp.value);
}
exports.isIdentifierStringExp = isIdentifierStringExp;
// Shallow copy of an expression (so it can be modified and preserve
// immutability of the original expression).
function copyExp(exp) {
exp = util.extend({}, exp);
switch (exp.type) {
case 'op':
case 'call':
var opExp = exp;
opExp.args = util.copyArray(opExp.args);
return opExp;
case 'union':
var unionExp = exp;
unionExp.types = util.copyArray(unionExp.types);
return unionExp;
case 'generic':
var genericExp = exp;
genericExp.params = util.copyArray(genericExp.params);
return genericExp;
default:
return exp;
}
}
exports.copyExp = copyExp;
// Make a (shallow) copy of the base expression, setting (or removing) it's
// valueType.
//
// valueType is a string indicating the type of evaluating an expression (e.g.
// 'Snapshot') - used to know when type coercion is needed in the context
// of parent expressions.
function cast(base, valueType) {
var result = copyExp(base);
result.valueType = valueType;
return result;
}
exports.cast = cast;
function call(ref, args) {
if (args === void 0) { args = []; }
return { type: 'call', valueType: 'Any', ref: ref, args: args };
}
exports.call = call;
// Return empty string if not a function.
function getFunctionName(exp) {
if (exp.ref.type === 'ref') {
return '';
}
return exp.ref.name;
}
exports.getFunctionName = getFunctionName;
// Return empty string if not a (simple) method call -- ref.fn()
function getMethodName(exp) {
if (exp.ref.type === 'var') {
return exp.ref.name;
}
if (exp.ref.type !== 'ref') {
return '';
}
return getPropName(exp.ref);
}
exports.getMethodName = getMethodName;
function getPropName(ref) {
if (ref.accessor.type !== 'String') {
return '';
}
return ref.accessor.value;
}
exports.getPropName = getPropName;
// TODO: Type of function signature does not fail this declaration?
function builtin(fn) {
return { type: 'builtin', valueType: 'Any', fn: fn };
}
exports.builtin = builtin;
function snapshotVariable(name) {
return cast(variable(name), 'Snapshot');
}
exports.snapshotVariable = snapshotVariable;
function snapshotParent(base) {
if (base.valueType !== 'Snapshot') {
throw new Error(errors.typeMismatch + "expected Snapshot");
}
return cast(call(reference(cast(base, 'Any'), exports.string('parent'))), 'Snapshot');
}
exports.snapshotParent = snapshotParent;
function ensureValue(exp) {
if (exp.valueType === 'Snapshot') {
return snapshotValue(exp);
}
return exp;
}
exports.ensureValue = ensureValue;
// ref.val()
function snapshotValue(exp) {
return call(reference(cast(exp, 'Any'), exports.string('val')));
}
exports.snapshotValue = snapshotValue;
// Ensure expression is a boolean (when used in a boolean context).
function ensureBoolean(exp) {
exp = ensureValue(exp);
if (isCall(exp, 'val')) {
exp = exports.eq(exp, exports.boolean(true));
}
return exp;
}
exports.ensureBoolean = ensureBoolean;
function isCall(exp, methodName) {
return exp.type === 'call' && exp.ref.type === 'ref' &&
exp.ref.accessor.type === 'String' &&
exp.ref.accessor.value === methodName;
}
exports.isCall = isCall;
// Return value generating function for a given Type.
function valueGen(typeName) {
return function (val) {
return {
type: typeName,
valueType: typeName,
value: val // The (constant) value itself.
};
};
}
function regexp(pattern, modifiers) {
if (modifiers === void 0) { modifiers = ""; }
switch (modifiers) {
case "":
case "i":
break;
default:
throw new Error("Unsupported RegExp modifier: " + modifiers);
}
return {
type: 'RegExp',
valueType: 'RegExp',
value: pattern,
modifiers: modifiers
};
}
exports.regexp = regexp;
function cmpValues(v1, v2) {
if (v1.type !== v2.type) {
return false;
}
return v1.value === v2.value;
}
function isOp(opType, exp) {
return exp.type === 'op' && exp.op === opType;
}
// Return a generating function to make an operator exp node.
function opGen(opType, arity) {
if (arity === void 0) { arity = 2; }
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (args.length !== arity) {
throw new Error("Operator has " + args.length +
" arguments (expecting " + arity + ").");
}
return op(opType, args);
};
}
exports.andArray = leftAssociateGen('&&', exports.boolean(true), exports.boolean(false));
exports.orArray = leftAssociateGen('||', exports.boolean(false), exports.boolean(true));
// Create an expression builder function which operates on arrays of values.
// Returns new expression like v1 op v2 op v3 ...
//
// - Any identityValue's in array input are ignored.
// - If zeroValue is found - just return zeroValue.
//
// Our function re-orders top-level op in array elements to the resulting
// expression is left-associating. E.g.:
//
// [a && b, c && d] => (((a && b) && c) && d)
// (NOT (a && b) && (c && d))
function leftAssociateGen(opType, identityValue, zeroValue) {
return function (a) {
var i;
function reducer(result, current) {
if (result === undefined) {
return current;
}
return op(opType, [result, current]);
}
// First flatten all top-level op values to one flat array.
var flat = [];
for (i = 0; i < a.length; i++) {
flatten(opType, a[i], flat);
}
var result = [];
for (i = 0; i < flat.length; i++) {
// Remove identifyValues from array.
if (cmpValues(flat[i], identityValue)) {
continue;
}
// Just return zeroValue if found
if (cmpValues(flat[i], zeroValue)) {
return zeroValue;
}
result.push(flat[i]);
}
if (result.length === 0) {
return identityValue;
}
// Return left-associative expression of opType.
return result.reduce(reducer);
};
}
// Flatten the top level tree of op into a single flat array of expressions.
function flatten(opType, exp, flat) {
var i;
if (flat === undefined) {
flat = [];
}
if (!isOp(opType, exp)) {
flat.push(exp);
return flat;
}
for (i = 0; i < exp.args.length; i++) {
flatten(opType, exp.args[i], flat);
}
return flat;
}
exports.flatten = flatten;
function op(opType, args) {
return {
type: 'op',
valueType: 'Any',
op: opType,
args: args // Arguments to the operator Array<exp>
};
}
exports.op = op;
// Warning: NOT an expression type!
function method(params, body) {
return {
params: params,
body: body
};
}
exports.method = method;
function typeType(typeName) {
return { type: "type", valueType: "type", name: typeName };
}
exports.typeType = typeType;
function unionType(types) {
return { type: "union", valueType: "type", types: types };
}
exports.unionType = unionType;
function genericType(typeName, params) {
return { type: "generic", valueType: "type", name: typeName, params: params };
}
exports.genericType = genericType;
var Symbols = /** @class */ (function () {
function Symbols() {
this.functions = {};
this.paths = [];
this.schema = {};
}
Symbols.prototype.register = function (map, typeName, name, object) {
if (map[name]) {
logger.error("Duplicated " + typeName + " definition: " + name + ".");
}
else {
map[name] = object;
}
return map[name];
};
Symbols.prototype.registerFunction = function (name, params, body) {
return this.register(this.functions, 'functions', name, method(params, body));
};
Symbols.prototype.registerPath = function (template, isType, methods) {
if (methods === void 0) { methods = {}; }
isType = isType || typeType('Any');
var p = {
template: template.copy(),
isType: isType,
methods: methods
};
this.paths.push(p);
return p;
};
Symbols.prototype.registerSchema = function (name, derivedFrom, properties, methods, params) {
if (properties === void 0) { properties = {}; }
if (methods === void 0) { methods = {}; }
if (params === void 0) { params = []; }
derivedFrom = derivedFrom || typeType(Object.keys(properties).length > 0 ? 'Object' : 'Any');
var s = {
derivedFrom: derivedFrom,
properties: properties,
methods: methods,
params: params
};
return this.register(this.schema, 'schema', name, s);
};
Symbols.prototype.isDerivedFrom = function (type, ancestor) {
var _this = this;
if (ancestor === 'Any') {
return true;
}
switch (type.type) {
case 'type':
case 'generic':
var simpleType = type;
if (simpleType.name === ancestor) {
return true;
}
if (simpleType.name === 'Any') {
return false;
}
var schema = this.schema[simpleType.name];
if (!schema) {
return false;
}
return this.isDerivedFrom(schema.derivedFrom, ancestor);
case 'union':
return type.types
.map(function (subType) { return _this.isDerivedFrom(subType, ancestor); })
.reduce(util.or);
default:
throw new Error("Unknown type: " + type.type);
}
};
return Symbols;
}());
exports.Symbols = Symbols;
var JS_OPS = {
'value': { rep: "", p: 18 },
'neg': { rep: "-", p: 15 },
'!': { p: 15 },
'*': { p: 14 },
'/': { p: 14 },
'%': { p: 14 },
'+': { p: 13 },
'-': { p: 13 },
'<': { p: 11 },
'<=': { p: 11 },
'>': { p: 11 },
'>=': { p: 11 },
'in': { p: 11 },
'==': { p: 10 },
"!=": { p: 10 },
'&&': { p: 6 },
'||': { p: 5 },
'?:': { p: 4 },
',': { p: 0 }
};
// From an AST, decode as an expression (string).
function decodeExpression(exp, outerPrecedence) {
if (outerPrecedence === undefined) {
outerPrecedence = 0;
}
var innerPrecedence = precedenceOf(exp);
var result = '';
switch (exp.type) {
case 'Boolean':
case 'Number':
result = JSON.stringify(exp.value);
break;
case 'String':
result = util.quoteString(exp.value);
break;
// RegExp assumed to be in pre-quoted format.
case 'RegExp':
var regexp_1 = exp;
result = '/' + regexp_1.value + '/';
if (regexp_1.modifiers !== '') {
result += regexp_1.modifiers;
}
break;
case 'Array':
result = '[' + decodeArray(exp.value) + ']';
break;
case 'Null':
result = 'null';
break;
case 'var':
case 'literal':
result = exp.name;
break;
case 'ref':
var expRef = exp;
if (isIdentifierStringExp(expRef.accessor)) {
result = decodeExpression(expRef.base, innerPrecedence) + '.' + expRef.accessor.value;
}
else {
result = decodeExpression(expRef.base, innerPrecedence) +
'[' + decodeExpression(expRef.accessor) + ']';
}
break;
case 'call':
var expCall = exp;
result = decodeExpression(expCall.ref) + '(' + decodeArray(expCall.args) + ')';
break;
case 'builtin':
result = decodeExpression(exp);
break;
case 'op':
var expOp = exp;
var rep = JS_OPS[expOp.op].rep === undefined ? expOp.op : JS_OPS[expOp.op].rep;
if (expOp.args.length === 1) {
result = rep + decodeExpression(expOp.args[0], innerPrecedence);
}
else if (expOp.args.length === 2) {
result =
decodeExpression(expOp.args[0], innerPrecedence) +
' ' + rep + ' ' +
// All ops are left associative - so nudge the innerPrecendence
// down on the right hand side to force () for right-associating
// operations.
decodeExpression(expOp.args[1], innerPrecedence + 1);
if ((innerPrecedence >= outerPrecedence) && ((expOp.op === '&&') || (expOp.op === '||'))) {
result = '(' + result + ')';
}
}
else if (expOp.args.length === 3) {
result =
decodeExpression(expOp.args[0], innerPrecedence) + ' ? ' +
decodeExpression(expOp.args[1], innerPrecedence) + ' : ' +
decodeExpression(expOp.args[2], innerPrecedence);
}
break;
case 'type':
result = exp.name;
break;
case 'union':
result = exp.types.map(decodeExpression).join(' | ');
break;
case 'generic':
var genericType_1 = exp;
return genericType_1.name + '<' + decodeArray(genericType_1.params) + '>';
default:
result = "***UNKNOWN TYPE*** (" + exp.type + ")";
break;
}
if (innerPrecedence < outerPrecedence) {
result = '(' + result + ')';
}
return result;
}
exports.decodeExpression = decodeExpression;
function decodeArray(args) {
return args.map(decodeExpression).join(', ');
}
function precedenceOf(exp) {
var result;
switch (exp.type) {
case 'op':
result = JS_OPS[exp.op].p;
break;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
// lists call as 17 and ref as 18 - but how could they be anything other than left to right?
// http://www.scriptingmaster.com/javascript/operator-precedence.asp - agrees.
case 'call':
result = 18;
break;
case 'ref':
result = 18;
break;
default:
result = 19;
break;
}
return result;
}
//# sourceMappingURL=data:application/json;charset=utf8;base64,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QU07UUFDUjtZQUNFLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDWixNQUFNO0tBQ1A7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwiZmlsZSI6ImFzdC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBBU1QgYnVpbGRlcnMgZm9yIEZpcmViYXNlIFJ1bGVzIExhbmd1YWdlLlxuICpcbiAqIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgKiBhcyBsb2dnZXIgZnJvbSAnLi9sb2dnZXInO1xuXG52YXIgZXJyb3JzID0ge1xuICB0eXBlTWlzbWF0Y2g6IFwiVW5leHBlY3RlZCB0eXBlOiBcIixcbiAgZHVwbGljYXRlUGF0aFBhcnQ6IFwiQSBwYXRoIGNvbXBvbmVudCBuYW1lIGlzIGR1cGxpY2F0ZWQ6IFwiLFxufTtcblxuZXhwb3J0IHR5cGUgT2JqZWN0ID0geyBbcHJvcDogc3RyaW5nXTogYW55IH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwIHtcbiAgdHlwZTogc3RyaW5nO1xuICB2YWx1ZVR5cGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHBWYWx1ZSBleHRlbmRzIEV4cCB7XG4gIHZhbHVlOiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVnRXhwVmFsdWUgZXh0ZW5kcyBFeHBWYWx1ZSB7XG4gIG1vZGlmaWVyczogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cE51bGwgZXh0ZW5kcyBFeHAge1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cE9wIGV4dGVuZHMgRXhwIHtcbiAgb3A6IHN0cmluZztcbiAgYXJnczogRXhwW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwVmFyaWFibGUgZXh0ZW5kcyBFeHAge1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwTGl0ZXJhbCBleHRlbmRzIEV4cCB7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuLy8gYmFzZVthY2Nlc3Nvcl1cbmV4cG9ydCBpbnRlcmZhY2UgRXhwUmVmZXJlbmNlIGV4dGVuZHMgRXhwIHtcbiAgYmFzZTogRXhwO1xuICBhY2Nlc3NvcjogRXhwO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cENhbGwgZXh0ZW5kcyBFeHAge1xuICByZWY6IEV4cFJlZmVyZW5jZSB8IEV4cFZhcmlhYmxlO1xuICBhcmdzOiBFeHBbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXJhbXMgeyBbbmFtZTogc3RyaW5nXTogRXhwOyB9O1xuXG5leHBvcnQgdHlwZSBCdWlsdGluRnVuY3Rpb24gPSAoYXJnczogRXhwW10sIHBhcmFtczogUGFyYW1zKSA9PiBFeHA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwQnVpbHRpbiBleHRlbmRzIEV4cCB7XG4gIGZuOiBCdWlsdGluRnVuY3Rpb247XG59XG5cbmV4cG9ydCB0eXBlIEV4cFR5cGUgPSBFeHBTaW1wbGVUeXBlIHwgRXhwVW5pb25UeXBlIHwgRXhwR2VuZXJpY1R5cGU7XG5leHBvcnQgaW50ZXJmYWNlIFR5cGVQYXJhbXMgeyBbbmFtZTogc3RyaW5nXTogRXhwVHlwZTsgfTtcblxuLy8gU2ltcGxlIFR5cGUgKHJlZmVyZW5jZSlcbmV4cG9ydCBpbnRlcmZhY2UgRXhwU2ltcGxlVHlwZSBleHRlbmRzIEV4cCB7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuLy8gVW5pb24gVHlwZTogVHlwZTEgfCBUeXBlMiB8IC4uLlxuZXhwb3J0IGludGVyZmFjZSBFeHBVbmlvblR5cGUgZXh0ZW5kcyBFeHAge1xuICB0eXBlczogRXhwVHlwZVtdO1xufVxuXG4vLyBHZW5lcmljIFR5cGUgKHJlZmVyZW5jZSk6IFR5cGU8VHlwZTEsIFR5cGUyLCAuLi4+XG5leHBvcnQgaW50ZXJmYWNlIEV4cEdlbmVyaWNUeXBlIGV4dGVuZHMgRXhwIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwYXJhbXM6IEV4cFR5cGVbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZXRob2Qge1xuICBwYXJhbXM6IHN0cmluZ1tdO1xuICBib2R5OiBFeHA7XG59XG5cbmV4cG9ydCBjbGFzcyBQYXRoUGFydCB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZhcmlhYmxlOiBzdHJpbmc7XG5cbiAgLy8gXCJsYWJlbFwiLCB1bmRlZmluZWQgLSBzdGF0aWMgcGF0aCBwYXJ0XG4gIC8vIFwiJGxhYmVsXCIsIFggLSB2YXJpYWJsZSBwYXRoIHBhcnRcbiAgLy8gWCwgIXVuZGVmaW5lZCAtIHZhcmlhYmxlIHBhdGggcGFydFxuICBjb25zdHJ1Y3RvcihsYWJlbDogc3RyaW5nLCB2YXJpYWJsZT86IHN0cmluZykge1xuICAgIGlmIChsYWJlbFswXSA9PT0gJyQnICYmIHZhcmlhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhcmlhYmxlID0gbGFiZWw7XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZSAmJiBsYWJlbFswXSAhPT0gJyQnKSB7XG4gICAgICBsYWJlbCA9ICckJyArIGxhYmVsO1xuICAgIH1cbiAgICB0aGlzLmxhYmVsID0gbGFiZWw7XG4gICAgdGhpcy52YXJpYWJsZSA9IDxzdHJpbmc+IHZhcmlhYmxlO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQYXRoVGVtcGxhdGUge1xuICBwYXJ0czogUGF0aFBhcnRbXTtcblxuICBjb25zdHJ1Y3RvcihwYXJ0cyA9IDwoc3RyaW5nIHwgUGF0aFBhcnQpW10+IFtdKSB7XG4gICAgdGhpcy5wYXJ0cyA9IDxQYXRoUGFydFtdPiBwYXJ0cy5tYXAoKHBhcnQpID0+IHtcbiAgICAgIGlmICh1dGlsLmlzVHlwZShwYXJ0LCAnc3RyaW5nJykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQYXRoUGFydCg8c3RyaW5nPiBwYXJ0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiA8UGF0aFBhcnQ+IHBhcnQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjb3B5KCkge1xuICAgIGxldCByZXN1bHQgPSBuZXcgUGF0aFRlbXBsYXRlKCk7XG4gICAgcmVzdWx0LnB1c2godGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGdldExhYmVscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMucGFydHMubWFwKChwYXJ0KSA9PiBwYXJ0LmxhYmVsKTtcbiAgfVxuXG4gIC8vIE1hcHBpbmcgZnJvbSB2YXJpYWJsZXMgdG8gSlNPTiBsYWJlbHNcbiAgZ2V0U2NvcGUoKTogUGFyYW1zIHtcbiAgICBsZXQgcmVzdWx0ID0gPFBhcmFtcz4ge307XG4gICAgdGhpcy5wYXJ0cy5mb3JFYWNoKChwYXJ0KSA9PiB7XG4gICAgICBpZiAocGFydC52YXJpYWJsZSkge1xuICAgICAgICBpZiAocmVzdWx0W3BhcnQudmFyaWFibGVdKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9ycy5kdXBsaWNhdGVQYXRoUGFydCArIHBhcnQudmFyaWFibGUpO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFtwYXJ0LnZhcmlhYmxlXSA9IGxpdGVyYWwocGFydC5sYWJlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1c2godGVtcDogUGF0aFRlbXBsYXRlKSB7XG4gICAgdXRpbC5leHRlbmRBcnJheSh0aGlzLnBhcnRzLCB0ZW1wLnBhcnRzKTtcbiAgfVxuXG4gIHBvcCh0ZW1wOiBQYXRoVGVtcGxhdGUpIHtcbiAgICB0ZW1wLnBhcnRzLmZvckVhY2goKHBhcnQpID0+IHtcbiAgICAgIHRoaXMucGFydHMucG9wKCk7XG4gICAgfSk7XG4gIH1cblxuICBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJ0cy5sZW5ndGg7XG4gIH1cblxuICBnZXRQYXJ0KGk6IG51bWJlcik6IFBhdGhQYXJ0IHtcbiAgICBpZiAoaSA+IHRoaXMucGFydHMubGVuZ3RoIHx8IGkgPCAtdGhpcy5wYXJ0cy5sZW5ndGgpIHtcbiAgICAgIGxldCBsID0gdGhpcy5wYXJ0cy5sZW5ndGg7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXRoIHJlZmVyZW5jZSBvdXQgb2YgYm91bmRzOiBcIiArIGkgK1xuICAgICAgICAgICAgICAgICAgICAgIFwiIFtcIiArIC1sICsgXCIgLi4gXCIgKyBsICsgXCJdXCIpO1xuICAgIH1cbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnRzW3RoaXMucGFydHMubGVuZ3RoICsgaV07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBhcnRzW2ldO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGF0aCB7XG4gIHRlbXBsYXRlOiBQYXRoVGVtcGxhdGU7XG4gIGlzVHlwZTogRXhwVHlwZTtcbiAgbWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogTWV0aG9kIH07XG59O1xuXG5leHBvcnQgY2xhc3MgU2NoZW1hIHtcbiAgZGVyaXZlZEZyb206IEV4cFR5cGU7XG4gIHByb3BlcnRpZXM6IFR5cGVQYXJhbXM7XG4gIG1ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106IE1ldGhvZCB9O1xuXG4gIC8vIEdlbmVyaWMgcGFyYW1ldGVycyAtIGlmIGEgR2VuZXJpYyBzY2hlbWFcbiAgcGFyYW1zPzogc3RyaW5nW107XG4gIGdldFZhbGlkYXRvcj86IChwYXJhbXM6IEV4cFtdKSA9PiBPYmplY3Q7XG5cbiAgc3RhdGljIGlzR2VuZXJpYyhzY2hlbWE6IFNjaGVtYSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzY2hlbWEucGFyYW1zICE9PSB1bmRlZmluZWQgJiYgc2NoZW1hLnBhcmFtcy5sZW5ndGggPiAwO1xuICB9XG59O1xuXG5leHBvcnQgdmFyIHN0cmluZzogKHY6IHN0cmluZykgPT4gRXhwVmFsdWUgPSB2YWx1ZUdlbignU3RyaW5nJyk7XG5leHBvcnQgdmFyIGJvb2xlYW46ICh2OiBib29sZWFuKSA9PiBFeHBWYWx1ZSA9IHZhbHVlR2VuKCdCb29sZWFuJyk7XG5leHBvcnQgdmFyIG51bWJlcjogKHY6IG51bWJlcikgPT4gRXhwVmFsdWUgPSB2YWx1ZUdlbignTnVtYmVyJyk7XG5leHBvcnQgdmFyIGFycmF5OiAodjogQXJyYXk8YW55PikgPT4gRXhwVmFsdWUgPSB2YWx1ZUdlbignQXJyYXknKTtcblxuZXhwb3J0IHZhciBuZWcgPSBvcEdlbignbmVnJywgMSk7XG5leHBvcnQgdmFyIG5vdCA9IG9wR2VuKCchJywgMSk7XG5leHBvcnQgdmFyIG11bHQgPSBvcEdlbignKicpO1xuZXhwb3J0IHZhciBkaXYgPSBvcEdlbignLycpO1xuZXhwb3J0IHZhciBtb2QgPSBvcEdlbignJScpO1xuZXhwb3J0IHZhciBhZGQgPSBvcEdlbignKycpO1xuZXhwb3J0IHZhciBzdWIgPSBvcEdlbignLScpO1xuZXhwb3J0IHZhciBlcSA9IG9wR2VuKCc9PScpO1xuZXhwb3J0IHZhciBsdCA9IG9wR2VuKCc8Jyk7XG5leHBvcnQgdmFyIGx0ZSA9IG9wR2VuKCc8PScpO1xuZXhwb3J0IHZhciBn