UNPKG

firebase-bolt

Version:

Firebase Bolt Security and Modeling Language Compiler

626 lines (625 loc) 70.5 kB
"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