UNPKG

@glimmer/compiler

Version:
312 lines (261 loc) 28.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.keyword = keyword; exports.keywords = keywords; exports.Keywords = exports.KEYWORD_NODES = void 0; var _syntax = require("@glimmer/syntax"); var _util = require("@glimmer/util"); var _result = require("../../../shared/result"); function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var KeywordImpl = /*#__PURE__*/function () { function KeywordImpl(keyword, type, delegate) { this.keyword = keyword; this.delegate = delegate; var nodes = new Set(); for (var _iterator = _createForOfIteratorHelperLoose(KEYWORD_NODES[type]), _step; !(_step = _iterator()).done;) { var nodeType = _step.value; nodes.add(nodeType); } this.types = nodes; } var _proto = KeywordImpl.prototype; _proto.match = function match(node) { if (!this.types.has(node.type)) { return false; } var path = getCalleeExpression(node); if (path !== null && path.type === 'Path' && path.ref.type === 'Free') { if (path.tail.length > 0) { if (path.ref.resolution.serialize() === 'Loose') { // cannot be a keyword reference, keywords do not allow paths (must be // relying on implicit this fallback) return false; } } return path.ref.name === this.keyword; } else { return false; } }; _proto.translate = function translate(node, state) { var _this = this; if (this.match(node)) { var path = getCalleeExpression(node); if (path !== null && path.type === 'Path' && path.tail.length > 0) { return (0, _result.Err)((0, _syntax.generateSyntaxError)("The `" + this.keyword + "` keyword was used incorrectly. It was used as `" + path.loc.asString() + "`, but it cannot be used with additional path segments. \n\nError caused by", node.loc)); } var param = this.delegate.assert(node, state); return param.andThen(function (param) { return _this.delegate.translate({ node: node, state: state }, param); }); } else { return null; } }; return KeywordImpl; }(); var KEYWORD_NODES = { Call: ['Call'], Block: ['InvokeBlock'], Append: ['AppendContent'], Modifier: ['ElementModifier'] }; exports.KEYWORD_NODES = KEYWORD_NODES; function keyword(keyword, type, delegate) { return new KeywordImpl(keyword, type, delegate); } function getCalleeExpression(node) { switch (node.type) { // This covers the inside of attributes and expressions, as well as the callee // of call nodes case 'Path': return node; case 'AppendContent': return getCalleeExpression(node.value); case 'Call': case 'InvokeBlock': case 'ElementModifier': return node.callee; default: return null; } } var Keywords = /*#__PURE__*/function () { function Keywords(type) { this._keywords = []; this._type = type; } var _proto2 = Keywords.prototype; _proto2.kw = function kw(name, delegate) { this._keywords.push(keyword(name, this._type, delegate)); return this; }; _proto2.translate = function translate(node, state) { for (var _iterator2 = _createForOfIteratorHelperLoose(this._keywords), _step2; !(_step2 = _iterator2()).done;) { var _keyword = _step2.value; var result = _keyword.translate(node, state); if (result !== null) { return result; } } var path = getCalleeExpression(node); if (path && path.type === 'Path' && path.ref.type === 'Free' && (0, _syntax.isKeyword)(path.ref.name)) { var name = path.ref.name; var usedType = this._type; var validTypes = _syntax.KEYWORDS_TYPES[name]; if (validTypes.indexOf(usedType) === -1) { return (0, _result.Err)((0, _syntax.generateSyntaxError)("The `" + name + "` keyword was used incorrectly. It was used as " + typesToReadableName[usedType] + ", but its valid usages are:\n\n" + generateTypesMessage(name, validTypes) + "\n\nError caused by", node.loc)); } } return null; }; return Keywords; }(); exports.Keywords = Keywords; var typesToReadableName = { Append: 'an append statement', Block: 'a block statement', Call: 'a call expression', Modifier: 'a modifier' }; function generateTypesMessage(name, types) { return types.map(function (type) { switch (type) { case 'Append': return "- As an append statement, as in: {{" + name + "}}"; case 'Block': return "- As a block statement, as in: {{#" + name + "}}{{/" + name + "}}"; case 'Call': return "- As an expression, as in: (" + name + ")"; case 'Modifier': return "- As a modifier, as in: <div {{" + name + "}}></div>"; default: return (0, _util.exhausted)(type); } }).join('\n\n'); } /** * This function builds keyword definitions for a particular type of AST node (`KeywordType`). * * You can build keyword definitions for: * * - `Expr`: A `SubExpression` or `PathExpression` * - `Block`: A `BlockStatement` * - A `BlockStatement` is a keyword candidate if its head is a * `PathExpression` * - `Append`: An `AppendStatement` * * A node is a keyword candidate if: * * - A `PathExpression` is a keyword candidate if it has no tail, and its * head expression is a `LocalVarHead` or `FreeVarHead` whose name is * the keyword's name. * - A `SubExpression`, `AppendStatement`, or `BlockStatement` is a keyword * candidate if its head is a keyword candidate. * * The keyword infrastructure guarantees that: * * - If a node is not a keyword candidate, it is never passed to any keyword's * `assert` method. * - If a node is not the `KeywordType` for a particular keyword, it will not * be passed to the keyword's `assert` method. * * `Expr` keywords are used in expression positions and should return HIR * expressions. `Block` and `Append` keywords are used in statement * positions and should return HIR statements. * * A keyword definition has two parts: * * - `match`, which determines whether an AST node matches the keyword, and can * optionally return some information extracted from the AST node. * - `translate`, which takes a matching AST node as well as the extracted * information and returns an appropriate HIR instruction. * * # Example * * This keyword: * * - turns `(hello)` into `"hello"` * - as long as `hello` is not in scope * - makes it an error to pass any arguments (such as `(hello world)`) * * ```ts * keywords('SubExpr').kw('hello', { * assert(node: ExprKeywordNode): Result<void> | false { * // we don't want to transform `hello` as a `PathExpression` * if (node.type !== 'SubExpression') { * return false; * } * * // node.head would be `LocalVarHead` if `hello` was in scope * if (node.head.type !== 'FreeVarHead') { * return false; * } * * if (node.params.length || node.hash) { * return Err(generateSyntaxError(`(hello) does not take any arguments`), node.loc); * } else { * return Ok(); * } * }, * * translate(node: ASTv2.SubExpression): hir.Expression { * return ASTv2.builders.literal("hello", node.loc) * } * }) * ``` * * The keyword infrastructure checks to make sure that the node is the right * type before calling `assert`, so you only need to consider `SubExpression` * and `PathExpression` here. It also checks to make sure that the node passed * to `assert` has the keyword name in the right place. * * Note the important difference between returning `false` from `assert`, * which just means that the node didn't match, and returning `Err`, which * means that the node matched, but there was a keyword-specific syntax * error. */ function keywords(type) { return new Keywords(type); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2NvbXBpbGVyL2xpYi9wYXNzZXMvMS1ub3JtYWxpemF0aW9uL2tleXdvcmRzL2ltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7O0FBT0E7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFnQkEsVztBQVFFLFdBQUEsV0FBQSxDQUFBLE9BQUEsRUFBQSxJQUFBLEVBQUEsUUFBQSxFQUdrRTtBQUZ0RCxTQUFBLE9BQUEsR0FBQSxPQUFBO0FBRUYsU0FBQSxRQUFBLEdBQUEsUUFBQTtBQUVSLFFBQUksS0FBSyxHQUFHLElBQVosR0FBWSxFQUFaOztBQUNBLFNBQUEsSUFBQSxTQUFBLEdBQUEsK0JBQUEsQ0FBcUIsYUFBYSxDQUFsQyxJQUFrQyxDQUFsQyxDQUFBLEVBQUEsS0FBQSxFQUFBLENBQUEsQ0FBQSxLQUFBLEdBQUEsU0FBQSxFQUFBLEVBQUEsSUFBQSxHQUEwQztBQUFBLFVBQTFDLFFBQTBDLEdBQUEsS0FBQSxDQUFBLEtBQUE7QUFDeEMsTUFBQSxLQUFLLENBQUwsR0FBQSxDQUFBLFFBQUE7QUFDRDs7QUFFRCxTQUFBLEtBQUEsR0FBQSxLQUFBO0FBQ0Q7Ozs7U0FFUyxLLEdBQUEsU0FBQSxLQUFBLENBQUEsSUFBQSxFQUFnQztBQUN4QyxRQUFJLENBQUMsS0FBQSxLQUFBLENBQUEsR0FBQSxDQUFlLElBQUksQ0FBeEIsSUFBSyxDQUFMLEVBQWdDO0FBQzlCLGFBQUEsS0FBQTtBQUNEOztBQUVELFFBQUksSUFBSSxHQUFHLG1CQUFtQixDQUE5QixJQUE4QixDQUE5Qjs7QUFFQSxRQUFJLElBQUksS0FBSixJQUFBLElBQWlCLElBQUksQ0FBSixJQUFBLEtBQWpCLE1BQUEsSUFBeUMsSUFBSSxDQUFKLEdBQUEsQ0FBQSxJQUFBLEtBQTdDLE1BQUEsRUFBdUU7QUFDckUsVUFBSSxJQUFJLENBQUosSUFB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QUEsU0FBQSxRQUFBO0FBQUEsQ0FBQSxFQUFBOzs7QUF3REEsSUFBTSxtQkFBbUIsR0FBRztBQUMxQixFQUFBLE1BQU0sRUFEb0IscUJBQUE7QUFFMUIsRUFBQSxLQUFLLEVBRnFCLG1CQUFBO0FBRzFCLEVBQUEsSUFBSSxFQUhzQixtQkFBQTtBQUkxQixFQUFBLFFBQVEsRUFBRTtBQUpnQixDQUE1Qjs7QUFPQSxTQUFBLG9CQUFBLENBQUEsSUFBQSxFQUFBLEtBQUEsRUFBZ0U7QUFDOUQsU0FBTyxLQUFLLENBQUwsR0FBQSxDQUNDLFVBQUQsSUFBQyxFQUFRO0FBQ1osWUFBQSxJQUFBO0FBQ0UsV0FBQSxRQUFBO0FBQ0UsZUFBQSx3Q0FBQSxJQUFBLEdBQUEsSUFBQTs7QUFDRixXQUFBLE9BQUE7QUFDRSxlQUFBLHVDQUFBLElBQUEsR0FBQSxPQUFBLEdBQUEsSUFBQSxHQUFBLElBQUE7O0FBQ0YsV0FBQSxNQUFBO0FBQ0UsZUFBQSxpQ0FBQSxJQUFBLEdBQUEsR0FBQTs7QUFDRixXQUFBLFVBQUE7QUFDRSxlQUFBLG9DQUFBLElBQUEsR0FBQSxXQUFBOztBQUNGO0FBQ0UsZUFBTyxxQkFBUCxJQUFPLENBQVA7QUFWSjtBQUZHLEdBQUEsRUFBQSxJQUFBLENBQVAsTUFBTyxDQUFQO0FBZ0JEO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaUZNLFNBQUEsUUFBQSxDQUFBLElBQUEsRUFBaUQ7QUFDckQsU0FBTyxJQUFBLFFBQUEsQ0FBUCxJQUFPLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFTVHYyLFxuICBnZW5lcmF0ZVN5bnRheEVycm9yLFxuICBpc0tleXdvcmQsXG4gIEtFWVdPUkRTX1RZUEVTLFxuICBLZXl3b3JkVHlwZSxcbn0gZnJvbSAnQGdsaW1tZXIvc3ludGF4JztcbmltcG9ydCB7IGV4aGF1c3RlZCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG5pbXBvcnQgeyBFcnIsIFJlc3VsdCB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9yZXN1bHQnO1xuaW1wb3J0IHsgTm9ybWFsaXphdGlvblN0YXRlIH0gZnJvbSAnLi4vY29udGV4dCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2V5d29yZERlbGVnYXRlPE1hdGNoIGV4dGVuZHMgS2V5d29yZE1hdGNoLCBWLCBPdXQ+IHtcbiAgYXNzZXJ0KG9wdGlvbnM6IE1hdGNoLCBzdGF0ZTogTm9ybWFsaXphdGlvblN0YXRlKTogUmVzdWx0PFY+O1xuICB0cmFuc2xhdGUob3B0aW9uczogeyBub2RlOiBNYXRjaDsgc3RhdGU6IE5vcm1hbGl6YXRpb25TdGF0ZSB9LCBwYXJhbTogVik6IFJlc3VsdDxPdXQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEtleXdvcmQ8SyBleHRlbmRzIEtleXdvcmRUeXBlID0gS2V5d29yZFR5cGUsIE91dCA9IHVua25vd24+IHtcbiAgdHJhbnNsYXRlKG5vZGU6IEtleXdvcmRDYW5kaWRhdGVzW0tdLCBzdGF0ZTogTm9ybWFsaXphdGlvblN0YXRlKTogUmVzdWx0PE91dD4gfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJsb2NrS2V5d29yZDxPdXQgPSB1bmtub3duPiB7XG4gIHRyYW5zbGF0ZShub2RlOiBBU1R2Mi5JbnZva2VCbG9jaywgc3RhdGU6IE5vcm1hbGl6YXRpb25TdGF0ZSk6IFJlc3VsdDxPdXQ+IHwgbnVsbDtcbn1cblxuY2xhc3MgS2V5d29yZEltcGw8XG4gIEsgZXh0ZW5kcyBLZXl3b3JkVHlwZSxcbiAgUyBleHRlbmRzIHN0cmluZyA9IHN0cmluZyxcbiAgUGFyYW0gPSB1bmtub3duLFxuICBPdXQgPSB1bmtub3duXG4+IHtcbiAgcHJvdGVjdGVkIHR5cGVzOiBTZXQ8S2V5d29yZENhbmRpZGF0ZXNbS11bJ3R5cGUnXT47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGtleXdvcmQ6IFMsXG4gICAgdHlwZTogS2V5d29yZFR5cGUsXG4gICAgcHJpdmF0ZSBkZWxlZ2F0ZTogS2V5d29yZERlbGVnYXRlPEtleXdvcmRNYXRjaGVzW0tdLCBQYXJhbSwgT3V0PlxuICApIHtcbiAgICBsZXQgbm9kZXMgPSBuZXcgU2V0PEtleXdvcmROb2RlWyd0eXBlJ10+KCk7XG4gICAgZm9yIChsZXQgbm9kZVR5cGUgb2YgS0VZV09SRF9OT0RFU1t0eXBlXSkge1xuICAgICAgbm9kZXMuYWRkKG5vZGVUeXBlKTtcbiAgICB9XG5cbiAgICB0aGlzLnR5cGVzID0gbm9kZXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWF0Y2gobm9kZTogS2V5d29yZENhbmRpZGF0ZXNbS10pOiBub2RlIGlzIEtleXdvcmRNYXRjaGVzW0tdIHtcbiAgICBpZiAoIXRoaXMudHlwZXMuaGFzKG5vZGUudHlwZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgcGF0aCA9IGdldENhbGxlZUV4cHJlc3Npb24obm9kZSk7XG5cbiAgICBpZiAocGF0aCAhPT0gbnVsbCAmJiBwYXRoLnR5cGUgPT09ICdQYXRoJyAmJiBwYXRoLnJlZi50eXBlID09PSAnRnJlZScpIHtcbiAgICAgIGlmIChwYXRoLnRhaWwubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAocGF0aC5yZWYucmVzb2x1dGlvbi5zZXJpYWxpemUoKSA9PT0gJ0xvb3NlJykge1xuICAgICAgICAgIC8vIGNhbm5vdCBiZSBhIGtleXdvcmQgcmVmZXJlbmNlLCBrZXl3b3JkcyBkbyBub3QgYWxsb3cgcGF0aHMgKG11c3QgYmVcbiAgICAgICAgICAvLyByZWx5aW5nIG9uIGltcGxpY2l0IHRoaXMgZmFsbGJhY2spXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXRoLnJlZi5uYW1lID09PSB0aGlzLmtleXdvcmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0cmFuc2xhdGUobm9kZTogS2V5d29yZE1hdGNoZXNbS10sIHN0YXRlOiBOb3JtYWxpemF0aW9uU3RhdGUpOiBSZXN1bHQ8T3V0PiB8IG51bGwge1xuICAgIGlmICh0aGlzLm1hdGNoKG5vZGUpKSB7XG4gICAgICBsZXQgcGF0aCA9IGdldENhbGxlZUV4cHJlc3Npb24obm9kZSk7XG5cbiAgICAgIGlmIChwYXRoICE9PSBudWxsICYmIHBhdGgudHlwZSA9PT0gJ1BhdGgnICYmIHBhdGgudGFpbC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBFcnIoXG4gICAgICAgICAgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgICAgICAgIGBUaGUgXFxgJHtcbiAgICAgICAgICAgICAgdGhpcy5rZXl3b3JkXG4gICAgICAgICAgICB9XFxgIGtleXdvcmQgd2FzIHVzZWQgaW5jb3JyZWN0bHkuIEl0IHdhcyB1c2VkIGFzIFxcYCR7cGF0aC5sb2MuYXNTdHJpbmcoKX1cXGAsIGJ1dCBpdCBjYW5ub3QgYmUgdXNlZCB3aXRoIGFkZGl0aW9uYWwgcGF0aCBzZWdtZW50cy4gXFxuXFxuRXJyb3IgY2F1c2VkIGJ5YCxcbiAgICAgICAgICAgIG5vZGUubG9jXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBsZXQgcGFyYW0gPSB0aGlzLmRlbGVnYXRlLmFzc2VydChub2RlLCBzdGF0ZSk7XG4gICAgICByZXR1cm4gcGFyYW0uYW5kVGhlbigocGFyYW0pID0+IHRoaXMuZGVsZWdhdGUudHJhbnNsYXRlKHsgbm9kZSwgc3RhdGUgfSwgcGFyYW0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB0eXBlIFBvc3NpYmxlTm9kZSA9XG4gIHwgQVNUdjIuUGF0aEV4cHJlc3Npb25cbiAgfCBBU1R2Mi5BcHBlbmRDb250ZW50XG4gIHwgQVNUdjIuQ2FsbEV4cHJlc3Npb25cbiAgfCBBU1R2Mi5JbnZva2VCbG9jaztcblxuZXhwb3J0IGNvbnN0IEtFWVdPUkRfTk9ERVMgPSB7XG4gIENhbGw6IFsnQ2FsbCddLFxuICBCbG9jazogWydJbnZva2VCbG9jayddLFxuICBBcHBlbmQ6IFsnQXBwZW5kQ29udGVudCddLFxuICBNb2RpZmllcjogWydFbGVtZW50TW9kaWZpZXInXSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2V5d29yZENhbmRpZGF0ZXMge1xuICBDYWxsOiBBU1R2Mi5FeHByZXNzaW9uTm9kZTtcbiAgQmxvY2s6IEFTVHYyLkludm9rZUJsb2NrO1xuICBBcHBlbmQ6IEFTVHYyLkFwcGVuZENvbnRlbnQ7XG4gIE1vZGlmaWVyOiBBU1R2Mi5FbGVtZW50TW9kaWZpZXI7XG59XG5cbmV4cG9ydCB0eXBlIEtleXdvcmRDYW5kaWRhdGUgPSBLZXl3b3JkQ2FuZGlkYXRlc1trZXlvZiBLZXl3b3JkQ2FuZGlkYXRlc107XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2V5d29yZE1hdGNoZXMge1xuICBDYWxsOiBBU1R2Mi5DYWxsRXhwcmVzc2lvbjtcbiAgQmxvY2s6IEFTVHYyLkludm9rZUJsb2NrO1xuICBBcHBlbmQ6IEFTVHYyLkFwcGVuZENvbnRlbnQ7XG4gIE1vZGlmaWVyOiBBU1R2Mi5FbGVtZW50TW9kaWZpZXI7XG59XG5cbmV4cG9ydCB0eXBlIEtleXdvcmRNYXRjaCA9IEtleXdvcmRNYXRjaGVzW2tleW9mIEtleXdvcmRNYXRjaGVzXTtcblxuLyoqXG4gKiBBIFwiZ2VuZXJpY1wiIGtleXdvcmQgaXMgc29tZXRoaW5nIGxpa2UgYGhhcy1ibG9ja2AsIHdoaWNoIG1ha2VzIHNlbnNlIGluIHRoZSBjb250ZXh0XG4gKiBvZiBzdWItZXhwcmVzc2lvbiBvciBhcHBlbmRcbiAqL1xuZXhwb3J0IHR5cGUgR2VuZXJpY0tleXdvcmROb2RlID0gQVNUdjIuQXBwZW5kQ29udGVudCB8IEFTVHYyLkNhbGxFeHByZXNzaW9uO1xuXG5leHBvcnQgdHlwZSBLZXl3b3JkTm9kZSA9XG4gIHwgR2VuZXJpY0tleXdvcmROb2RlXG4gIHwgQVNUdjIuQ2FsbEV4cHJlc3Npb25cbiAgfCBBU1R2Mi5JbnZva2VCbG9ja1xuICB8IEFTVHYyLkVsZW1lbnRNb2RpZmllcjtcblxuZXhwb3J0IGZ1bmN0aW9uIGtleXdvcmQ8XG4gIEsgZXh0ZW5kcyBLZXl3b3JkVHlwZSxcbiAgRCBleHRlbmRzIEtleXdvcmREZWxlZ2F0ZTxLZXl3b3JkTWF0Y2hlc1tLXSwgdW5rbm93biwgT3V0PixcbiAgT3V0ID0gdW5rbm93blxuPihrZXl3b3JkOiBzdHJpbmcsIHR5cGU6IEssIGRlbGVnYXRlOiBEKTogS2V5d29yZDxLLCBPdXQ+IHtcbiAgcmV0dXJuIG5ldyBLZXl3b3JkSW1wbChrZXl3b3JkLCB0eXBlLCBkZWxlZ2F0ZSBhcyBLZXl3b3JkRGVsZWdhdGU8S2V5d29yZE1hdGNoLCB1bmtub3duLCBPdXQ+KTtcbn1cblxuZXhwb3J0IHR5cGUgUG9zc2libGVLZXl3b3JkID0gS2V5d29yZE5vZGU7XG50eXBlIE91dEZvcjxLIGV4dGVuZHMgS2V5d29yZCB8IEJsb2NrS2V5d29yZD4gPSBLIGV4dGVuZHMgQmxvY2tLZXl3b3JkPGluZmVyIE91dD5cbiAgPyBPdXRcbiAgOiBLIGV4dGVuZHMgS2V5d29yZDxLZXl3b3JkVHlwZSwgaW5mZXIgT3V0PlxuICA/IE91dFxuICA6IG5ldmVyO1xuXG5mdW5jdGlvbiBnZXRDYWxsZWVFeHByZXNzaW9uKFxuICBub2RlOiBLZXl3b3JkTm9kZSB8IEFTVHYyLkV4cHJlc3Npb25Ob2RlXG4pOiBBU1R2Mi5FeHByZXNzaW9uTm9kZSB8IG51bGwge1xuICBzd2l0Y2ggKG5vZGUudHlwZSkge1xuICAgIC8vIFRoaXMgY292ZXJzIHRoZSBpbnNpZGUgb2YgYXR0cmlidXRlcyBhbmQgZXhwcmVzc2lvbnMsIGFzIHdlbGwgYXMgdGhlIGNhbGxlZVxuICAgIC8vIG9mIGNhbGwgbm9kZXNcbiAgICBjYXNlICdQYXRoJzpcbiAgICAgIHJldHVybiBub2RlO1xuICAgIGNhc2UgJ0FwcGVuZENvbnRlbnQnOlxuICAgICAgcmV0dXJuIGdldENhbGxlZUV4cHJlc3Npb24obm9kZS52YWx1ZSk7XG4gICAgY2FzZSAnQ2FsbCc6XG4gICAgY2FzZSAnSW52b2tlQmxvY2snOlxuICAgIGNhc2UgJ0VsZW1lbnRNb2RpZmllcic6XG4gICAgICByZXR1cm4gbm9kZS5jYWxsZWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBLZXl3b3JkczxLIGV4dGVuZHMgS2V5d29yZFR5cGUsIEtleXdvcmRMaXN0IGV4dGVuZHMgS2V5d29yZDxLPiA9IG5ldmVyPlxuICBpbXBsZW1lbnRzIEtleXdvcmQ8SywgT3V0Rm9yPEtleXdvcmRMaXN0Pj4ge1xuICBfa2V5d29yZHM6IEtleXdvcmRbXSA9IFtdO1xuICBfdHlwZTogSztcblxuICBjb25zdHJ1Y3Rvcih0eXBlOiBLKSB7XG4gICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gIH1cblxuICBrdzxTIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLCBPdXQgPSB1bmtub3duPihcbiAgICBuYW1lOiBTLFxuICAgIGRlbGVnYXRlOiBLZXl3b3JkRGVsZWdhdGU8S2V5d29yZE1hdGNoZXNbS10sIHVua25vd24sIE91dD5cbiAgKTogS2V5d29yZHM8SywgS2V5d29yZExpc3QgfCBLZXl3b3JkPEssIE91dD4+IHtcbiAgICB0aGlzLl9rZXl3b3Jkcy5wdXNoKGtleXdvcmQobmFtZSwgdGhpcy5fdHlwZSwgZGVsZWdhdGUpKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdHJhbnNsYXRlKFxuICAgIG5vZGU6IEtleXdvcmRDYW5kaWRhdGVzW0tdLFxuICAgIHN0YXRlOiBOb3JtYWxpemF0aW9uU3RhdGVcbiAgKTogUmVzdWx0PE91dEZvcjxLZXl3b3JkTGlzdD4+IHwgbnVsbCB7XG4gICAgZm9yIChsZXQga2V5d29yZCBvZiB0aGlzLl9rZXl3b3Jkcykge1xuICAgICAgbGV0IHJlc3VsdCA9IGtleXdvcmQudHJhbnNsYXRlKG5vZGUsIHN0YXRlKSBhcyBSZXN1bHQ8T3V0Rm9yPEtleXdvcmRMaXN0Pj47XG4gICAgICBpZiAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHBhdGggPSBnZXRDYWxsZWVFeHByZXNzaW9uKG5vZGUpO1xuXG4gICAgaWYgKHBhdGggJiYgcGF0aC50eXBlID09PSAnUGF0aCcgJiYgcGF0aC5yZWYudHlwZSA9PT0gJ0ZyZWUnICYmIGlzS2V5d29yZChwYXRoLnJlZi5uYW1lKSkge1xuICAgICAgbGV0IHsgbmFtZSB9ID0gcGF0aC5yZWY7XG5cbiAgICAgIGxldCB1c2VkVHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICBsZXQgdmFsaWRUeXBlcyA9IEtFWVdPUkRTX1RZUEVTW25hbWVdO1xuXG4gICAgICBpZiAodmFsaWRUeXBlcy5pbmRleE9mKHVzZWRUeXBlKSA9PT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIEVycihcbiAgICAgICAgICBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgICAgICAgYFRoZSBcXGAke25hbWV9XFxgIGtleXdvcmQgd2FzIHVzZWQgaW5jb3JyZWN0bHkuIEl0IHdhcyB1c2VkIGFzICR7XG4gICAgICAgICAgICAgIHR5cGVzVG9SZWFkYWJsZU5hbWVbdXNlZFR5cGVdXG4gICAgICAgICAgICB9LCBidXQgaXRzIHZhbGlkIHVzYWdlcyBhcmU6XFxuXFxuJHtnZW5lcmF0ZVR5cGVzTWVzc2FnZShcbiAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgdmFsaWRUeXBlc1xuICAgICAgICAgICAgKX1cXG5cXG5FcnJvciBjYXVzZWQgYnlgLFxuICAgICAgICAgICAgbm9kZS5sb2NcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuY29uc3QgdHlwZXNUb1JlYWRhYmxlTmFtZSA9IHtcbiAgQXBwZW5kOiAnYW4gYXBwZW5kIHN0YXRlbWVudCcsXG4gIEJsb2NrOiAnYSBibG9jayBzdGF0ZW1lbnQnLFxuICBDYWxsOiAnYSBjYWxsIGV4cHJlc3Npb24nLFxuICBNb2RpZmllcjogJ2EgbW9kaWZpZXInLFxufTtcblxuZnVuY3Rpb24gZ2VuZXJhdGVUeXBlc01lc3NhZ2UobmFtZTogc3RyaW5nLCB0eXBlczogS2V5d29yZFR5cGVbXSk6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlc1xuICAgIC5tYXAoKHR5cGUpID0+IHtcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdBcHBlbmQnOlxuICAgICAgICAgIHJldHVybiBgLSBBcyBhbiBhcHBlbmQgc3RhdGVtZW50LCBhcyBpbjoge3ske25hbWV9fX1gO1xuICAgICAgICBjYXNlICdCbG9jayc6XG4gICAgICAgICAgcmV0dXJuIGAtIEFzIGEgYmxvY2sgc3RhdGVtZW50LCBhcyBpbjoge3sjJHtuYW1lfX19e3svJHtuYW1lfX19YDtcbiAgICAgICAgY2FzZSAnQ2FsbCc6XG4gICAgICAgICAgcmV0dXJuIGAtIEFzIGFuIGV4cHJlc3Npb24sIGFzIGluOiAoJHtuYW1lfSlgO1xuICAgICAgICBjYXNlICdNb2RpZmllcic6XG4gICAgICAgICAgcmV0dXJuIGAtIEFzIGEgbW9kaWZpZXIsIGFzIGluOiA8ZGl2IHt7JHtuYW1lfX19PjwvZGl2PmA7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIGV4aGF1c3RlZCh0eXBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5qb2luKCdcXG5cXG4nKTtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGJ1aWxkcyBrZXl3b3JkIGRlZmluaXRpb25zIGZvciBhIHBhcnRpY3VsYXIgdHlwZSBvZiBBU1Qgbm9kZSAoYEtleXdvcmRUeXBlYCkuXG4gKlxuICogWW91IGNhbiBidWlsZCBrZXl3b3JkIGRlZmluaXRpb25zIGZvcjpcbiAqXG4gKiAtIGBFeHByYDogQSBgU3ViRXhwcmVzc2lvbmAgb3IgYFBhdGhFeHByZXNzaW9uYFxuICogLSBgQmxvY2tgOiBBIGBCbG9ja1N0YXRlbWVudGBcbiAqICAgLSBBIGBCbG9ja1N0YXRlbWVudGAgaXMgYSBrZXl3b3JkIGNhbmRpZGF0ZSBpZiBpdHMgaGVhZCBpcyBhXG4gKiAgICAgYFBhdGhFeHByZXNzaW9uYFxuICogLSBgQXBwZW5kYDogQW4gYEFwcGVuZFN0YXRlbWVudGBcbiAqXG4gKiBBIG5vZGUgaXMgYSBrZXl3b3JkIGNhbmRpZGF0ZSBpZjpcbiAqXG4gKiAtIEEgYFBhdGhFeHByZXNzaW9uYCBpcyBhIGtleXdvcmQgY2FuZGlkYXRlIGlmIGl0IGhhcyBubyB0YWlsLCBhbmQgaXRzXG4gKiAgIGhlYWQgZXhwcmVzc2lvbiBpcyBhIGBMb2NhbFZhckhlYWRgIG9yIGBGcmVlVmFySGVhZGAgd2hvc2UgbmFtZSBpc1xuICogICB0aGUga2V5d29yZCdzIG5hbWUuXG4gKiAtIEEgYFN1YkV4cHJlc3Npb25gLCBgQXBwZW5kU3RhdGVtZW50YCwgb3IgYEJsb2NrU3RhdGVtZW50YCBpcyBhIGtleXdvcmRcbiAqICAgY2FuZGlkYXRlIGlmIGl0cyBoZWFkIGlzIGEga2V5d29yZCBjYW5kaWRhdGUuXG4gKlxuICogVGhlIGtleXdvcmQgaW5mcmFzdHJ1Y3R1cmUgZ3VhcmFudGVlcyB0aGF0OlxuICpcbiAqIC0gSWYgYSBub2RlIGlzIG5vdCBhIGtleXdvcmQgY2FuZGlkYXRlLCBpdCBpcyBuZXZlciBwYXNzZWQgdG8gYW55IGtleXdvcmQnc1xuICogICBgYXNzZXJ0YCBtZXRob2QuXG4gKiAtIElmIGEgbm9kZSBpcyBub3QgdGhlIGBLZXl3b3JkVHlwZWAgZm9yIGEgcGFydGljdWxhciBrZXl3b3JkLCBpdCB3aWxsIG5vdFxuICogICBiZSBwYXNzZWQgdG8gdGhlIGtleXdvcmQncyBgYXNzZXJ0YCBtZXRob2QuXG4gKlxuICogYEV4cHJgIGtleXdvcmRzIGFyZSB1c2VkIGluIGV4cHJlc3Npb24gcG9zaXRpb25zIGFuZCBzaG91bGQgcmV0dXJuIEhJUlxuICogZXhwcmVzc2lvbnMuIGBCbG9ja2AgYW5kIGBBcHBlbmRgIGtleXdvcmRzIGFyZSB1c2VkIGluIHN0YXRlbWVudFxuICogcG9zaXRpb25zIGFuZCBzaG91bGQgcmV0dXJuIEhJUiBzdGF0ZW1lbnRzLlxuICpcbiAqIEEga2V5d29yZCBkZWZpbml0aW9uIGhhcyB0d28gcGFydHM6XG4gKlxuICogLSBgbWF0Y2hgLCB3aGljaCBkZXRlcm1pbmVzIHdoZXRoZXIgYW4gQVNUIG5vZGUgbWF0Y2hlcyB0aGUga2V5d29yZCwgYW5kIGNhblxuICogICBvcHRpb25hbGx5IHJldHVybiBzb21lIGluZm9ybWF0aW9uIGV4dHJhY3RlZCBmcm9tIHRoZSBBU1Qgbm9kZS5cbiAqIC0gYHRyYW5zbGF0ZWAsIHdoaWNoIHRha2VzIGEgbWF0Y2hpbmcgQVNUIG5vZGUgYXMgd2VsbCBhcyB0aGUgZXh0cmFjdGVkXG4gKiAgIGluZm9ybWF0aW9uIGFuZCByZXR1cm5zIGFuIGFwcHJvcHJpYXRlIEhJUiBpbnN0cnVjdGlvbi5cbiAqXG4gKiAjIEV4YW1wbGVcbiAqXG4gKiBUaGlzIGtleXdvcmQ6XG4gKlxuICogLSB0dXJucyBgKGhlbGxvKWAgaW50byBgXCJoZWxsb1wiYFxuICogICAtIGFzIGxvbmcgYXMgYGhlbGxvYCBpcyBub3QgaW4gc2NvcGVcbiAqIC0gbWFrZXMgaXQgYW4gZXJyb3IgdG8gcGFzcyBhbnkgYXJndW1lbnRzIChzdWNoIGFzIGAoaGVsbG8gd29ybGQpYClcbiAqXG4gKiBgYGB0c1xuICoga2V5d29yZHMoJ1N1YkV4cHInKS5rdygnaGVsbG8nLCB7XG4gKiAgIGFzc2VydChub2RlOiBFeHByS2V5d29yZE5vZGUpOiBSZXN1bHQ8dm9pZD4gfCBmYWxzZSB7XG4gKiAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byB0cmFuc2Zvcm0gYGhlbGxvYCBhcyBhIGBQYXRoRXhwcmVzc2lvbmBcbiAqICAgICBpZiAobm9kZS50eXBlICE9PSAnU3ViRXhwcmVzc2lvbicpIHtcbiAqICAgICAgIHJldHVybiBmYWxzZTtcbiAqICAgICB9XG4gKlxuICogICAgIC8vIG5vZGUuaGVhZCB3b3VsZCBiZSBgTG9jYWxWYXJIZWFkYCBpZiBgaGVsbG9gIHdhcyBpbiBzY29wZVxuICogICAgIGlmIChub2RlLmhlYWQudHlwZSAhPT0gJ0ZyZWVWYXJIZWFkJykge1xuICogICAgICAgcmV0dXJuIGZhbHNlO1xuICogICAgIH1cbiAqXG4gKiAgICAgaWYgKG5vZGUucGFyYW1zLmxlbmd0aCB8fCBub2RlLmhhc2gpIHtcbiAqICAgICAgIHJldHVybiBFcnIoZ2VuZXJhdGVTeW50YXhFcnJvcihgKGhlbGxvKSBkb2VzIG5vdCB0YWtlIGFueSBhcmd1bWVudHNgKSwgbm9kZS5sb2MpO1xuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICByZXR1cm4gT2soKTtcbiAqICAgICB9XG4gKiAgIH0sXG4gKlxuICogICB0cmFuc2xhdGUobm9kZTogQVNUdjIuU3ViRXhwcmVzc2lvbik6IGhpci5FeHByZXNzaW9uIHtcbiAqICAgICByZXR1cm4gQVNUdjIuYnVpbGRlcnMubGl0ZXJhbChcImhlbGxvXCIsIG5vZGUubG9jKVxuICogICB9XG4gKiB9KVxuICogYGBgXG4gKlxuICogVGhlIGtleXdvcmQgaW5mcmFzdHJ1Y3R1cmUgY2hlY2tzIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBub2RlIGlzIHRoZSByaWdodFxuICogdHlwZSBiZWZvcmUgY2FsbGluZyBgYXNzZXJ0YCwgc28geW91IG9ubHkgbmVlZCB0byBjb25zaWRlciBgU3ViRXhwcmVzc2lvbmBcbiAqIGFuZCBgUGF0aEV4cHJlc3Npb25gIGhlcmUuIEl0IGFsc28gY2hlY2tzIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBub2RlIHBhc3NlZFxuICogdG8gYGFzc2VydGAgaGFzIHRoZSBrZXl3b3JkIG5hbWUgaW4gdGhlIHJpZ2h0IHBsYWNlLlxuICpcbiAqIE5vdGUgdGhlIGltcG9ydGFudCBkaWZmZXJlbmNlIGJldHdlZW4gcmV0dXJuaW5nIGBmYWxzZWAgZnJvbSBgYXNzZXJ0YCxcbiAqIHdoaWNoIGp1c3QgbWVhbnMgdGhhdCB0aGUgbm9kZSBkaWRuJ3QgbWF0Y2gsIGFuZCByZXR1cm5pbmcgYEVycmAsIHdoaWNoXG4gKiBtZWFucyB0aGF0IHRoZSBub2RlIG1hdGNoZWQsIGJ1dCB0aGVyZSB3YXMgYSBrZXl3b3JkLXNwZWNpZmljIHN5bnRheFxuICogZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBrZXl3b3JkczxLIGV4dGVuZHMgS2V5d29yZFR5cGU+KHR5cGU6IEspOiBLZXl3b3JkczxLPiB7XG4gIHJldHVybiBuZXcgS2V5d29yZHModHlwZSk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9