@glimmer/syntax
Version:
572 lines (481 loc) • 58.9 kB
JavaScript
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
import { Parser } from '../parser';
import { NON_EXISTENT_LOCATION } from '../source/location';
import { generateSyntaxError } from '../syntax-error';
import { appendChild, isHBSLiteral, printLiteral } from '../utils';
import { PathExpressionImplV1 } from '../v1/legacy-interop';
import b from '../v1/parser-builders';
export var HandlebarsNodeVisitors = /*#__PURE__*/function (_Parser) {
_inheritsLoose(HandlebarsNodeVisitors, _Parser);
function HandlebarsNodeVisitors() {
return _Parser.apply(this, arguments) || this;
}
var _proto = HandlebarsNodeVisitors.prototype;
_proto.Program = function Program(program) {
var body = [];
var node;
if (this.isTopLevel) {
node = b.template({
body: body,
blockParams: program.blockParams,
loc: this.source.spanFor(program.loc)
});
} else {
node = b.blockItself({
body: body,
blockParams: program.blockParams,
chained: program.chained,
loc: this.source.spanFor(program.loc)
});
}
var i,
l = program.body.length;
this.elementStack.push(node);
if (l === 0) {
return this.elementStack.pop();
}
for (i = 0; i < l; i++) {
this.acceptNode(program.body[i]);
} // Ensure that that the element stack is balanced properly.
var poppedNode = this.elementStack.pop();
if (poppedNode !== node) {
var elementNode = poppedNode;
throw generateSyntaxError("Unclosed element `" + elementNode.tag + "`", elementNode.loc);
}
return node;
};
_proto.BlockStatement = function BlockStatement(block) {
if (this.tokenizer.state === "comment"
/* comment */
) {
this.appendToCommentData(this.sourceForNode(block));
return;
}
if (this.tokenizer.state !== "data"
/* data */
&& this.tokenizer.state !== "beforeData"
/* beforeData */
) {
throw generateSyntaxError('A block may only be used inside an HTML element or another block.', this.source.spanFor(block.loc));
}
var _acceptCallNodes = acceptCallNodes(this, block),
path = _acceptCallNodes.path,
params = _acceptCallNodes.params,
hash = _acceptCallNodes.hash; // These are bugs in Handlebars upstream
if (!block.program.loc) {
block.program.loc = NON_EXISTENT_LOCATION;
}
if (block.inverse && !block.inverse.loc) {
block.inverse.loc = NON_EXISTENT_LOCATION;
}
var program = this.Program(block.program);
var inverse = block.inverse ? this.Program(block.inverse) : null;
var node = b.block({
path: path,
params: params,
hash: hash,
defaultBlock: program,
elseBlock: inverse,
loc: this.source.spanFor(block.loc),
openStrip: block.openStrip,
inverseStrip: block.inverseStrip,
closeStrip: block.closeStrip
});
var parentProgram = this.currentElement();
appendChild(parentProgram, node);
};
_proto.MustacheStatement = function MustacheStatement(rawMustache) {
var tokenizer = this.tokenizer;
if (tokenizer.state === 'comment') {
this.appendToCommentData(this.sourceForNode(rawMustache));
return;
}
var mustache;
var escaped = rawMustache.escaped,
loc = rawMustache.loc,
strip = rawMustache.strip;
if (isHBSLiteral(rawMustache.path)) {
mustache = b.mustache({
path: this.acceptNode(rawMustache.path),
params: [],
hash: b.hash([], this.source.spanFor(rawMustache.path.loc).collapse('end')),
trusting: !escaped,
loc: this.source.spanFor(loc),
strip: strip
});
} else {
var _acceptCallNodes2 = acceptCallNodes(this, rawMustache),
path = _acceptCallNodes2.path,
params = _acceptCallNodes2.params,
hash = _acceptCallNodes2.hash;
mustache = b.mustache({
path: path,
params: params,
hash: hash,
trusting: !escaped,
loc: this.source.spanFor(loc),
strip: strip
});
}
switch (tokenizer.state) {
// Tag helpers
case "tagOpen"
/* tagOpen */
:
case "tagName"
/* tagName */
:
throw generateSyntaxError("Cannot use mustaches in an elements tagname", mustache.loc);
case "beforeAttributeName"
/* beforeAttributeName */
:
addElementModifier(this.currentStartTag, mustache);
break;
case "attributeName"
/* attributeName */
:
case "afterAttributeName"
/* afterAttributeName */
:
this.beginAttributeValue(false);
this.finishAttributeValue();
addElementModifier(this.currentStartTag, mustache);
tokenizer.transitionTo("beforeAttributeName"
/* beforeAttributeName */
);
break;
case "afterAttributeValueQuoted"
/* afterAttributeValueQuoted */
:
addElementModifier(this.currentStartTag, mustache);
tokenizer.transitionTo("beforeAttributeName"
/* beforeAttributeName */
);
break;
// Attribute values
case "beforeAttributeValue"
/* beforeAttributeValue */
:
this.beginAttributeValue(false);
this.appendDynamicAttributeValuePart(mustache);
tokenizer.transitionTo("attributeValueUnquoted"
/* attributeValueUnquoted */
);
break;
case "attributeValueDoubleQuoted"
/* attributeValueDoubleQuoted */
:
case "attributeValueSingleQuoted"
/* attributeValueSingleQuoted */
:
case "attributeValueUnquoted"
/* attributeValueUnquoted */
:
this.appendDynamicAttributeValuePart(mustache);
break;
// TODO: Only append child when the tokenizer state makes
// sense to do so, otherwise throw an error.
default:
appendChild(this.currentElement(), mustache);
}
return mustache;
};
_proto.appendDynamicAttributeValuePart = function appendDynamicAttributeValuePart(part) {
this.finalizeTextPart();
var attr = this.currentAttr;
attr.isDynamic = true;
attr.parts.push(part);
};
_proto.finalizeTextPart = function finalizeTextPart() {
var attr = this.currentAttr;
var text = attr.currentPart;
if (text !== null) {
this.currentAttr.parts.push(text);
this.startTextPart();
}
};
_proto.startTextPart = function startTextPart() {
this.currentAttr.currentPart = null;
};
_proto.ContentStatement = function ContentStatement(content) {
updateTokenizerLocation(this.tokenizer, content);
this.tokenizer.tokenizePart(content.value);
this.tokenizer.flushData();
};
_proto.CommentStatement = function CommentStatement(rawComment) {
var tokenizer = this.tokenizer;
if (tokenizer.state === "comment"
/* comment */
) {
this.appendToCommentData(this.sourceForNode(rawComment));
return null;
}
var value = rawComment.value,
loc = rawComment.loc;
var comment = b.mustacheComment(value, this.source.spanFor(loc));
switch (tokenizer.state) {
case "beforeAttributeName"
/* beforeAttributeName */
:
case "afterAttributeName"
/* afterAttributeName */
:
this.currentStartTag.comments.push(comment);
break;
case "beforeData"
/* beforeData */
:
case "data"
/* data */
:
appendChild(this.currentElement(), comment);
break;
default:
throw generateSyntaxError("Using a Handlebars comment when in the `" + tokenizer['state'] + "` state is not supported", this.source.spanFor(rawComment.loc));
}
return comment;
};
_proto.PartialStatement = function PartialStatement(partial) {
throw generateSyntaxError("Handlebars partials are not supported", this.source.spanFor(partial.loc));
};
_proto.PartialBlockStatement = function PartialBlockStatement(partialBlock) {
throw generateSyntaxError("Handlebars partial blocks are not supported", this.source.spanFor(partialBlock.loc));
};
_proto.Decorator = function Decorator(decorator) {
throw generateSyntaxError("Handlebars decorators are not supported", this.source.spanFor(decorator.loc));
};
_proto.DecoratorBlock = function DecoratorBlock(decoratorBlock) {
throw generateSyntaxError("Handlebars decorator blocks are not supported", this.source.spanFor(decoratorBlock.loc));
};
_proto.SubExpression = function SubExpression(sexpr) {
var _acceptCallNodes3 = acceptCallNodes(this, sexpr),
path = _acceptCallNodes3.path,
params = _acceptCallNodes3.params,
hash = _acceptCallNodes3.hash;
return b.sexpr({
path: path,
params: params,
hash: hash,
loc: this.source.spanFor(sexpr.loc)
});
};
_proto.PathExpression = function PathExpression(path) {
var original = path.original;
var parts;
if (original.indexOf('/') !== -1) {
if (original.slice(0, 2) === './') {
throw generateSyntaxError("Using \"./\" is not supported in Glimmer and unnecessary", this.source.spanFor(path.loc));
}
if (original.slice(0, 3) === '../') {
throw generateSyntaxError("Changing context using \"../\" is not supported in Glimmer", this.source.spanFor(path.loc));
}
if (original.indexOf('.') !== -1) {
throw generateSyntaxError("Mixing '.' and '/' in paths is not supported in Glimmer; use only '.' to separate property paths", this.source.spanFor(path.loc));
}
parts = [path.parts.join('/')];
} else if (original === '.') {
throw generateSyntaxError("'.' is not a supported path in Glimmer; check for a path with a trailing '.'", this.source.spanFor(path.loc));
} else {
parts = path.parts;
}
var thisHead = false; // This is to fix a bug in the Handlebars AST where the path expressions in
// `{{this.foo}}` (and similarly `{{foo-bar this.foo named=this.foo}}` etc)
// are simply turned into `{{foo}}`. The fix is to push it back onto the
// parts array and let the runtime see the difference. However, we cannot
// simply use the string `this` as it means literally the property called
// "this" in the current context (it can be expressed in the syntax as
// `{{[this]}}`, where the square bracket are generally for this kind of
// escaping – such as `{{foo.["bar.baz"]}}` would mean lookup a property
// named literally "bar.baz" on `this.foo`). By convention, we use `null`
// for this purpose.
if (original.match(/^this(\..+)?$/)) {
thisHead = true;
}
var pathHead;
if (thisHead) {
pathHead = {
type: 'ThisHead',
loc: {
start: path.loc.start,
end: {
line: path.loc.start.line,
column: path.loc.start.column + 4
}
}
};
} else if (path.data) {
var head = parts.shift();
if (head === undefined) {
throw generateSyntaxError("Attempted to parse a path expression, but it was not valid. Paths beginning with @ must start with a-z.", this.source.spanFor(path.loc));
}
pathHead = {
type: 'AtHead',
name: "@" + head,
loc: {
start: path.loc.start,
end: {
line: path.loc.start.line,
column: path.loc.start.column + head.length + 1
}
}
};
} else {
var _head = parts.shift();
if (_head === undefined) {
throw generateSyntaxError("Attempted to parse a path expression, but it was not valid. Paths must start with a-z or A-Z.", this.source.spanFor(path.loc));
}
pathHead = {
type: 'VarHead',
name: _head,
loc: {
start: path.loc.start,
end: {
line: path.loc.start.line,
column: path.loc.start.column + _head.length
}
}
};
}
return new PathExpressionImplV1(path.original, pathHead, parts, this.source.spanFor(path.loc));
};
_proto.Hash = function Hash(hash) {
var pairs = [];
for (var i = 0; i < hash.pairs.length; i++) {
var pair = hash.pairs[i];
pairs.push(b.pair({
key: pair.key,
value: this.acceptNode(pair.value),
loc: this.source.spanFor(pair.loc)
}));
}
return b.hash(pairs, this.source.spanFor(hash.loc));
};
_proto.StringLiteral = function StringLiteral(string) {
return b.literal({
type: 'StringLiteral',
value: string.value,
loc: string.loc
});
};
_proto.BooleanLiteral = function BooleanLiteral(_boolean) {
return b.literal({
type: 'BooleanLiteral',
value: _boolean.value,
loc: _boolean.loc
});
};
_proto.NumberLiteral = function NumberLiteral(number) {
return b.literal({
type: 'NumberLiteral',
value: number.value,
loc: number.loc
});
};
_proto.UndefinedLiteral = function UndefinedLiteral(undef) {
return b.literal({
type: 'UndefinedLiteral',
value: undefined,
loc: undef.loc
});
};
_proto.NullLiteral = function NullLiteral(nul) {
return b.literal({
type: 'NullLiteral',
value: null,
loc: nul.loc
});
};
_createClass(HandlebarsNodeVisitors, [{
key: "isTopLevel",
get: function get() {
return this.elementStack.length === 0;
}
}]);
return HandlebarsNodeVisitors;
}(Parser);
function calculateRightStrippedOffsets(original, value) {
if (value === '') {
// if it is empty, just return the count of newlines
// in original
return {
lines: original.split('\n').length - 1,
columns: 0
};
} // otherwise, return the number of newlines prior to
// `value`
var difference = original.split(value)[0];
var lines = difference.split(/\n/);
var lineCount = lines.length - 1;
return {
lines: lineCount,
columns: lines[lineCount].length
};
}
function updateTokenizerLocation(tokenizer, content) {
var line = content.loc.start.line;
var column = content.loc.start.column;
var offsets = calculateRightStrippedOffsets(content.original, content.value);
line = line + offsets.lines;
if (offsets.lines) {
column = offsets.columns;
} else {
column = column + offsets.columns;
}
tokenizer.line = line;
tokenizer.column = column;
}
function acceptCallNodes(compiler, node) {
if (node.path.type.endsWith('Literal')) {
var _path = node.path;
var value = '';
if (_path.type === 'BooleanLiteral') {
value = _path.original.toString();
} else if (_path.type === 'StringLiteral') {
value = "\"" + _path.original + "\"";
} else if (_path.type === 'NullLiteral') {
value = 'null';
} else if (_path.type === 'NumberLiteral') {
value = _path.value.toString();
} else {
value = 'undefined';
}
throw generateSyntaxError(_path.type + " \"" + (_path.type === 'StringLiteral' ? _path.original : value) + "\" cannot be called as a sub-expression, replace (" + value + ") with " + value, compiler.source.spanFor(_path.loc));
}
var path = node.path.type === 'PathExpression' ? compiler.PathExpression(node.path) : compiler.SubExpression(node.path);
var params = node.params ? node.params.map(function (e) {
return compiler.acceptNode(e);
}) : []; // if there is no hash, position it as a collapsed node immediately after the last param (or the
// path, if there are also no params)
var end = params.length > 0 ? params[params.length - 1].loc : path.loc;
var hash = node.hash ? compiler.Hash(node.hash) : {
type: 'Hash',
pairs: [],
loc: compiler.source.spanFor(end).collapse('end')
};
return {
path: path,
params: params,
hash: hash
};
}
function addElementModifier(element, mustache) {
var path = mustache.path,
params = mustache.params,
hash = mustache.hash,
loc = mustache.loc;
if (isHBSLiteral(path)) {
var _modifier = "{{" + printLiteral(path) + "}}";
var tag = "<" + element.name + " ... " + _modifier + " ...";
throw generateSyntaxError("In " + tag + ", " + _modifier + " is not a valid modifier", mustache.loc);
}
var modifier = b.elementModifier({
path: path,
params: params,
hash: hash,
loc: loc
});
element.modifiers.push(modifier);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvcGFyc2VyL2hhbmRsZWJhcnMtbm9kZS12aXNpdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQSxTQUFBLE1BQUEsUUFBQSxXQUFBO0FBQ0EsU0FBQSxxQkFBQSxRQUFBLG9CQUFBO0FBQ0EsU0FBQSxtQkFBQSxRQUFBLGlCQUFBO0FBQ0EsU0FBQSxXQUFBLEVBQUEsWUFBQSxFQUFBLFlBQUEsUUFBQSxVQUFBO0FBR0EsU0FBQSxvQkFBQSxRQUFBLHNCQUFBO0FBQ0EsT0FBQSxDQUFBLE1BQUEsdUJBQUE7QUFFQSxXQUFNLHNCQUFOO0FBQUE7O0FBQUE7QUFBQTtBQUFBOztBQUFBOztBQUFBLFNBWUUsT0FaRixHQVlFLGlCQUFPLE9BQVAsRUFBNEI7QUFDMUIsUUFBSSxJQUFJLEdBQVIsRUFBQTtBQUNBLFFBQUEsSUFBQTs7QUFFQSxRQUFJLEtBQUosVUFBQSxFQUFxQjtBQUNuQixNQUFBLElBQUksR0FBRyxDQUFDLENBQUQsUUFBQSxDQUFXO0FBQ2hCLFFBQUEsSUFEZ0IsRUFDaEIsSUFEZ0I7QUFFaEIsUUFBQSxXQUFXLEVBQUUsT0FBTyxDQUZKLFdBQUE7QUFHaEIsUUFBQSxHQUFHLEVBQUUsS0FBQSxNQUFBLENBQUEsT0FBQSxDQUFvQixPQUFPLENBQTNCLEdBQUE7QUFIVyxPQUFYLENBQVA7QUFERixLQUFBLE1BTU87QUFDTCxNQUFBLElBQUksR0FBRyxDQUFDLENBQUQsV0FBQSxDQUFjO0FBQ25CLFFBQUEsSUFEbUIsRUFDbkIsSUFEbUI7QUFFbkIsUUFBQSxXQUFXLEVBQUUsT0FBTyxDQUZELFdBQUE7QUFHbkIsUUFBQSxPQUFPLEVBQUUsT0FBTyxDQUhHLE9BQUE7QUFJbkIsUUFBQSxHQUFHLEVBQUUsS0FBQSxNQUFBLENBQUEsT0FBQSxDQUFvQixPQUFPLENBQTNCLEdBQUE7QUFKYyxPQUFkLENBQVA7QUFNRDs7QUFFRCxRQUFBLENBQUE7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QUNEOztBQUVELFNBQUEsa0JBQUEsQ0FBQSxPQUFBLEVBQUEsUUFBQSxFQUVtQztBQUFBLE1BRTdCLElBRjZCLEdBRWpDLFFBRmlDLENBRTdCLElBRjZCO0FBQUEsTUFFN0IsTUFGNkIsR0FFakMsUUFGaUMsQ0FFN0IsTUFGNkI7QUFBQSxNQUU3QixJQUY2QixHQUVqQyxRQUZpQyxDQUU3QixJQUY2QjtBQUFBLE1BRVAsR0FGTyxHQUVqQyxRQUZpQyxDQUVQLEdBRk87O0FBSWpDLE1BQUksWUFBWSxDQUFoQixJQUFnQixDQUFoQixFQUF3QjtBQUN0QixRQUFJLFNBQVEsVUFBUSxZQUFZLENBQWhDLElBQWdDLENBQXBCLE9BQVo7O0FBQ0EsUUFBSSxHQUFHLFNBQU8sT0FBTyxDQUFDLElBQWYsYUFBUCxTQUFPLFNBQVA7QUFFQSxVQUFNLG1CQUFtQixTQUFPLEdBQVAsVUFBQSxTQUFBLCtCQUFtRCxRQUFRLENBQXBGLEdBQXlCLENBQXpCO0FBQ0Q7O0FBRUQsTUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFELGVBQUEsQ0FBa0I7QUFBRSxJQUFBLElBQUYsRUFBRSxJQUFGO0FBQVEsSUFBQSxNQUFSLEVBQVEsTUFBUjtBQUFnQixJQUFBLElBQWhCLEVBQWdCLElBQWhCO0FBQXNCLElBQUEsR0FBQSxFQUFBO0FBQXRCLEdBQWxCLENBQWY7QUFDQSxFQUFBLE9BQU8sQ0FBUCxTQUFBLENBQUEsSUFBQSxDQUFBLFFBQUE7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wdGlvbiwgUmVjYXN0IH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBUb2tlbml6ZXJTdGF0ZSB9IGZyb20gJ3NpbXBsZS1odG1sLXRva2VuaXplcic7XG5cbmltcG9ydCB7IFBhcnNlciwgUGFyc2VyTm9kZUJ1aWxkZXIsIFRhZyB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBOT05fRVhJU1RFTlRfTE9DQVRJT04gfSBmcm9tICcuLi9zb3VyY2UvbG9jYXRpb24nO1xuaW1wb3J0IHsgZ2VuZXJhdGVTeW50YXhFcnJvciB9IGZyb20gJy4uL3N5bnRheC1lcnJvcic7XG5pbXBvcnQgeyBhcHBlbmRDaGlsZCwgaXNIQlNMaXRlcmFsLCBwcmludExpdGVyYWwgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgKiBhcyBBU1R2MSBmcm9tICcuLi92MS9hcGknO1xuaW1wb3J0ICogYXMgSEJTIGZyb20gJy4uL3YxL2hhbmRsZWJhcnMtYXN0JztcbmltcG9ydCB7IFBhdGhFeHByZXNzaW9uSW1wbFYxIH0gZnJvbSAnLi4vdjEvbGVnYWN5LWludGVyb3AnO1xuaW1wb3J0IGIgZnJvbSAnLi4vdjEvcGFyc2VyLWJ1aWxkZXJzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEhhbmRsZWJhcnNOb2RlVmlzaXRvcnMgZXh0ZW5kcyBQYXJzZXIge1xuICBhYnN0cmFjdCBhcHBlbmRUb0NvbW1lbnREYXRhKHM6IHN0cmluZyk6IHZvaWQ7XG4gIGFic3RyYWN0IGJlZ2luQXR0cmlidXRlVmFsdWUocXVvdGVkOiBib29sZWFuKTogdm9pZDtcbiAgYWJzdHJhY3QgZmluaXNoQXR0cmlidXRlVmFsdWUoKTogdm9pZDtcblxuICBwcml2YXRlIGdldCBpc1RvcExldmVsKCkge1xuICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjay5sZW5ndGggPT09IDA7XG4gIH1cblxuICBQcm9ncmFtKHByb2dyYW06IEhCUy5Qcm9ncmFtKTogQVNUdjEuQmxvY2s7XG4gIFByb2dyYW0ocHJvZ3JhbTogSEJTLlByb2dyYW0pOiBBU1R2MS5UZW1wbGF0ZTtcbiAgUHJvZ3JhbShwcm9ncmFtOiBIQlMuUHJvZ3JhbSk6IEFTVHYxLlRlbXBsYXRlIHwgQVNUdjEuQmxvY2s7XG4gIFByb2dyYW0ocHJvZ3JhbTogSEJTLlByb2dyYW0pOiBBU1R2MS5CbG9jayB8IEFTVHYxLlRlbXBsYXRlIHtcbiAgICBsZXQgYm9keTogQVNUdjEuU3RhdGVtZW50W10gPSBbXTtcbiAgICBsZXQgbm9kZTtcblxuICAgIGlmICh0aGlzLmlzVG9wTGV2ZWwpIHtcbiAgICAgIG5vZGUgPSBiLnRlbXBsYXRlKHtcbiAgICAgICAgYm9keSxcbiAgICAgICAgYmxvY2tQYXJhbXM6IHByb2dyYW0uYmxvY2tQYXJhbXMsXG4gICAgICAgIGxvYzogdGhpcy5zb3VyY2Uuc3BhbkZvcihwcm9ncmFtLmxvYyksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZSA9IGIuYmxvY2tJdHNlbGYoe1xuICAgICAgICBib2R5LFxuICAgICAgICBibG9ja1BhcmFtczogcHJvZ3JhbS5ibG9ja1BhcmFtcyxcbiAgICAgICAgY2hhaW5lZDogcHJvZ3JhbS5jaGFpbmVkLFxuICAgICAgICBsb2M6IHRoaXMuc291cmNlLnNwYW5Gb3IocHJvZ3JhbS5sb2MpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IGksXG4gICAgICBsID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aDtcblxuICAgIHRoaXMuZWxlbWVudFN0YWNrLnB1c2gobm9kZSk7XG5cbiAgICBpZiAobCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpIGFzIEFTVHYxLkJsb2NrIHwgQVNUdjEuVGVtcGxhdGU7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5hY2NlcHROb2RlKHByb2dyYW0uYm9keVtpXSk7XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhhdCB0aGUgZWxlbWVudCBzdGFjayBpcyBiYWxhbmNlZCBwcm9wZXJseS5cbiAgICBsZXQgcG9wcGVkTm9kZSA9IHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpO1xuICAgIGlmIChwb3BwZWROb2RlICE9PSBub2RlKSB7XG4gICAgICBsZXQgZWxlbWVudE5vZGUgPSBwb3BwZWROb2RlIGFzIEFTVHYxLkVsZW1lbnROb2RlO1xuXG4gICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKGBVbmNsb3NlZCBlbGVtZW50IFxcYCR7ZWxlbWVudE5vZGUudGFnfVxcYGAsIGVsZW1lbnROb2RlLmxvYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBCbG9ja1N0YXRlbWVudChibG9jazogSEJTLkJsb2NrU3RhdGVtZW50KTogQVNUdjEuQmxvY2tTdGF0ZW1lbnQgfCB2b2lkIHtcbiAgICBpZiAodGhpcy50b2tlbml6ZXIuc3RhdGUgPT09IFRva2VuaXplclN0YXRlLmNvbW1lbnQpIHtcbiAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUoYmxvY2spKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnRva2VuaXplci5zdGF0ZSAhPT0gVG9rZW5pemVyU3RhdGUuZGF0YSAmJlxuICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgIT09IFRva2VuaXplclN0YXRlLmJlZm9yZURhdGFcbiAgICApIHtcbiAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICdBIGJsb2NrIG1heSBvbmx5IGJlIHVzZWQgaW5zaWRlIGFuIEhUTUwgZWxlbWVudCBvciBhbm90aGVyIGJsb2NrLicsXG4gICAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IoYmxvY2subG9jKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCBibG9jayk7XG5cbiAgICAvLyBUaGVzZSBhcmUgYnVncyBpbiBIYW5kbGViYXJzIHVwc3RyZWFtXG4gICAgaWYgKCFibG9jay5wcm9ncmFtLmxvYykge1xuICAgICAgYmxvY2sucHJvZ3JhbS5sb2MgPSBOT05fRVhJU1RFTlRfTE9DQVRJT047XG4gICAgfVxuXG4gICAgaWYgKGJsb2NrLmludmVyc2UgJiYgIWJsb2NrLmludmVyc2UubG9jKSB7XG4gICAgICBibG9jay5pbnZlcnNlLmxvYyA9IE5PTl9FWElTVEVOVF9MT0NBVElPTjtcbiAgICB9XG5cbiAgICBsZXQgcHJvZ3JhbSA9IHRoaXMuUHJvZ3JhbShibG9jay5wcm9ncmFtKTtcbiAgICBsZXQgaW52ZXJzZSA9IGJsb2NrLmludmVyc2UgPyB0aGlzLlByb2dyYW0oYmxvY2suaW52ZXJzZSkgOiBudWxsO1xuXG4gICAgbGV0IG5vZGUgPSBiLmJsb2NrKHtcbiAgICAgIHBhdGgsXG4gICAgICBwYXJhbXMsXG4gICAgICBoYXNoLFxuICAgICAgZGVmYXVsdEJsb2NrOiBwcm9ncmFtLFxuICAgICAgZWxzZUJsb2NrOiBpbnZlcnNlLFxuICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGJsb2NrLmxvYyksXG4gICAgICBvcGVuU3RyaXA6IGJsb2NrLm9wZW5TdHJpcCxcbiAgICAgIGludmVyc2VTdHJpcDogYmxvY2suaW52ZXJzZVN0cmlwLFxuICAgICAgY2xvc2VTdHJpcDogYmxvY2suY2xvc2VTdHJpcCxcbiAgICB9KTtcblxuICAgIGxldCBwYXJlbnRQcm9ncmFtID0gdGhpcy5jdXJyZW50RWxlbWVudCgpO1xuXG4gICAgYXBwZW5kQ2hpbGQocGFyZW50UHJvZ3JhbSwgbm9kZSk7XG4gIH1cblxuICBNdXN0YWNoZVN0YXRlbWVudChyYXdNdXN0YWNoZTogSEJTLk11c3RhY2hlU3RhdGVtZW50KTogQVNUdjEuTXVzdGFjaGVTdGF0ZW1lbnQgfCB2b2lkIHtcbiAgICBsZXQgeyB0b2tlbml6ZXIgfSA9IHRoaXM7XG5cbiAgICBpZiAodG9rZW5pemVyLnN0YXRlID09PSAnY29tbWVudCcpIHtcbiAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUocmF3TXVzdGFjaGUpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgbXVzdGFjaGU6IEFTVHYxLk11c3RhY2hlU3RhdGVtZW50O1xuICAgIGxldCB7IGVzY2FwZWQsIGxvYywgc3RyaXAgfSA9IHJhd011c3RhY2hlO1xuXG4gICAgaWYgKGlzSEJTTGl0ZXJhbChyYXdNdXN0YWNoZS5wYXRoKSkge1xuICAgICAgbXVzdGFjaGUgPSBiLm11c3RhY2hlKHtcbiAgICAgICAgcGF0aDogdGhpcy5hY2NlcHROb2RlPEFTVHYxLkxpdGVyYWw+KHJhd011c3RhY2hlLnBhdGgpLFxuICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICBoYXNoOiBiLmhhc2goW10sIHRoaXMuc291cmNlLnNwYW5Gb3IocmF3TXVzdGFjaGUucGF0aC5sb2MpLmNvbGxhcHNlKCdlbmQnKSksXG4gICAgICAgIHRydXN0aW5nOiAhZXNjYXBlZCxcbiAgICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGxvYyksXG4gICAgICAgIHN0cmlwLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCB9ID0gYWNjZXB0Q2FsbE5vZGVzKFxuICAgICAgICB0aGlzLFxuICAgICAgICByYXdNdXN0YWNoZSBhcyBIQlMuTXVzdGFjaGVTdGF0ZW1lbnQgJiB7XG4gICAgICAgICAgcGF0aDogSEJTLlBhdGhFeHByZXNzaW9uIHwgSEJTLlN1YkV4cHJlc3Npb247XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBtdXN0YWNoZSA9IGIubXVzdGFjaGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBwYXJhbXMsXG4gICAgICAgIGhhc2gsXG4gICAgICAgIHRydXN0aW5nOiAhZXNjYXBlZCxcbiAgICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGxvYyksXG4gICAgICAgIHN0cmlwLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0b2tlbml6ZXIuc3RhdGUpIHtcbiAgICAgIC8vIFRhZyBoZWxwZXJzXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLnRhZ09wZW46XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLnRhZ05hbWU6XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoYENhbm5vdCB1c2UgbXVzdGFjaGVzIGluIGFuIGVsZW1lbnRzIHRhZ25hbWVgLCBtdXN0YWNoZS5sb2MpO1xuXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZU5hbWU6XG4gICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYXR0cmlidXRlTmFtZTpcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYWZ0ZXJBdHRyaWJ1dGVOYW1lOlxuICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICB0aGlzLmZpbmlzaEF0dHJpYnV0ZVZhbHVlKCk7XG4gICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICB0b2tlbml6ZXIudHJhbnNpdGlvblRvKFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYWZ0ZXJBdHRyaWJ1dGVWYWx1ZVF1b3RlZDpcbiAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgIHRva2VuaXplci50cmFuc2l0aW9uVG8oVG9rZW5pemVyU3RhdGUuYmVmb3JlQXR0cmlidXRlTmFtZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICAvLyBBdHRyaWJ1dGUgdmFsdWVzXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZVZhbHVlOlxuICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICB0aGlzLmFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQobXVzdGFjaGUpO1xuICAgICAgICB0b2tlbml6ZXIudHJhbnNpdGlvblRvKFRva2VuaXplclN0YXRlLmF0dHJpYnV0ZVZhbHVlVW5xdW90ZWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYXR0cmlidXRlVmFsdWVEb3VibGVRdW90ZWQ6XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVkOlxuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5hdHRyaWJ1dGVWYWx1ZVVucXVvdGVkOlxuICAgICAgICB0aGlzLmFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQobXVzdGFjaGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gVE9ETzogT25seSBhcHBlbmQgY2hpbGQgd2hlbiB0aGUgdG9rZW5pemVyIHN0YXRlIG1ha2VzXG4gICAgICAvLyBzZW5zZSB0byBkbyBzbywgb3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXBwZW5kQ2hpbGQodGhpcy5jdXJyZW50RWxlbWVudCgpLCBtdXN0YWNoZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG11c3RhY2hlO1xuICB9XG5cbiAgYXBwZW5kRHluYW1pY0F0dHJpYnV0ZVZhbHVlUGFydChwYXJ0OiBBU1R2MS5NdXN0YWNoZVN0YXRlbWVudCk6IHZvaWQge1xuICAgIHRoaXMuZmluYWxpemVUZXh0UGFydCgpO1xuICAgIGxldCBhdHRyID0gdGhpcy5jdXJyZW50QXR0cjtcbiAgICBhdHRyLmlzRHluYW1pYyA9IHRydWU7XG4gICAgYXR0ci5wYXJ0cy5wdXNoKHBhcnQpO1xuICB9XG5cbiAgZmluYWxpemVUZXh0UGFydCgpOiB2b2lkIHtcbiAgICBsZXQgYXR0ciA9IHRoaXMuY3VycmVudEF0dHI7XG4gICAgbGV0IHRleHQgPSBhdHRyLmN1cnJlbnRQYXJ0O1xuICAgIGlmICh0ZXh0ICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmN1cnJlbnRBdHRyLnBhcnRzLnB1c2godGV4dCk7XG4gICAgICB0aGlzLnN0YXJ0VGV4dFBhcnQoKTtcbiAgICB9XG4gIH1cblxuICBzdGFydFRleHRQYXJ0KCk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudEF0dHIuY3VycmVudFBhcnQgPSBudWxsO1xuICB9XG5cbiAgQ29udGVudFN0YXRlbWVudChjb250ZW50OiBIQlMuQ29udGVudFN0YXRlbWVudCk6IHZvaWQge1xuICAgIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRoaXMudG9rZW5pemVyLCBjb250ZW50KTtcblxuICAgIHRoaXMudG9rZW5pemVyLnRva2VuaXplUGFydChjb250ZW50LnZhbHVlKTtcbiAgICB0aGlzLnRva2VuaXplci5mbHVzaERhdGEoKTtcbiAgfVxuXG4gIENvbW1lbnRTdGF0ZW1lbnQocmF3Q29tbWVudDogSEJTLkNvbW1lbnRTdGF0ZW1lbnQpOiBPcHRpb248QVNUdjEuTXVzdGFjaGVDb21tZW50U3RhdGVtZW50PiB7XG4gICAgbGV0IHsgdG9rZW5pemVyIH0gPSB0aGlzO1xuXG4gICAgaWYgKHRva2VuaXplci5zdGF0ZSA9PT0gVG9rZW5pemVyU3RhdGUuY29tbWVudCkge1xuICAgICAgdGhpcy5hcHBlbmRUb0NvbW1lbnREYXRhKHRoaXMuc291cmNlRm9yTm9kZShyYXdDb21tZW50KSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgeyB2YWx1ZSwgbG9jIH0gPSByYXdDb21tZW50O1xuICAgIGxldCBjb21tZW50ID0gYi5tdXN0YWNoZUNvbW1lbnQodmFsdWUsIHRoaXMuc291cmNlLnNwYW5Gb3IobG9jKSk7XG5cbiAgICBzd2l0Y2ggKHRva2VuaXplci5zdGF0ZSkge1xuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5iZWZvcmVBdHRyaWJ1dGVOYW1lOlxuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5hZnRlckF0dHJpYnV0ZU5hbWU6XG4gICAgICAgIHRoaXMuY3VycmVudFN0YXJ0VGFnLmNvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZURhdGE6XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmRhdGE6XG4gICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgY29tbWVudCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgICAgIGBVc2luZyBhIEhhbmRsZWJhcnMgY29tbWVudCB3aGVuIGluIHRoZSBcXGAke3Rva2VuaXplclsnc3RhdGUnXX1cXGAgc3RhdGUgaXMgbm90IHN1cHBvcnRlZGAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihyYXdDb21tZW50LmxvYylcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tbWVudDtcbiAgfVxuXG4gIFBhcnRpYWxTdGF0ZW1lbnQocGFydGlhbDogSEJTLlBhcnRpYWxTdGF0ZW1lbnQpOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIHBhcnRpYWxzIGFyZSBub3Qgc3VwcG9ydGVkYCxcbiAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IocGFydGlhbC5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIFBhcnRpYWxCbG9ja1N0YXRlbWVudChwYXJ0aWFsQmxvY2s6IEhCUy5QYXJ0aWFsQmxvY2tTdGF0ZW1lbnQpOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIHBhcnRpYWwgYmxvY2tzIGFyZSBub3Qgc3VwcG9ydGVkYCxcbiAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IocGFydGlhbEJsb2NrLmxvYylcbiAgICApO1xuICB9XG5cbiAgRGVjb3JhdG9yKGRlY29yYXRvcjogSEJTLkRlY29yYXRvcik6IG5ldmVyIHtcbiAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgYEhhbmRsZWJhcnMgZGVjb3JhdG9ycyBhcmUgbm90IHN1cHBvcnRlZGAsXG4gICAgICB0aGlzLnNvdXJjZS5zcGFuRm9yKGRlY29yYXRvci5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIERlY29yYXRvckJsb2NrKGRlY29yYXRvckJsb2NrOiBIQlMuRGVjb3JhdG9yQmxvY2spOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIGRlY29yYXRvciBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWRgLFxuICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihkZWNvcmF0b3JCbG9jay5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIFN1YkV4cHJlc3Npb24oc2V4cHI6IEhCUy5TdWJFeHByZXNzaW9uKTogQVNUdjEuU3ViRXhwcmVzc2lvbiB7XG4gICAgbGV0IHsgcGF0aCwgcGFyYW1zLCBoYXNoIH0gPSBhY2NlcHRDYWxsTm9kZXModGhpcywgc2V4cHIpO1xuICAgIHJldHVybiBiLnNleHByKHsgcGF0aCwgcGFyYW1zLCBoYXNoLCBsb2M6IHRoaXMuc291cmNlLnNwYW5Gb3Ioc2V4cHIubG9jKSB9KTtcbiAgfVxuXG4gIFBhdGhFeHByZXNzaW9uKHBhdGg6IEhCUy5QYXRoRXhwcmVzc2lvbik6IEFTVHYxLlBhdGhFeHByZXNzaW9uIHtcbiAgICBsZXQgeyBvcmlnaW5hbCB9ID0gcGF0aDtcbiAgICBsZXQgcGFydHM6IHN0cmluZ1tdO1xuXG4gICAgaWYgKG9yaWdpbmFsLmluZGV4T2YoJy8nKSAhPT0gLTEpIHtcbiAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAyKSA9PT0gJy4vJykge1xuICAgICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgICAgIGBVc2luZyBcIi4vXCIgaXMgbm90IHN1cHBvcnRlZCBpbiBHbGltbWVyIGFuZCB1bm5lY2Vzc2FyeWAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAzKSA9PT0gJy4uLycpIHtcbiAgICAgICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgICAgICBgQ2hhbmdpbmcgY29udGV4dCB1c2luZyBcIi4uL1wiIGlzIG5vdCBzdXBwb3J0ZWQgaW4gR2xpbW1lcmAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKCcuJykgIT09IC0xKSB7XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICAgYE1peGluZyAnLicgYW5kICcvJyBpbiBwYXRocyBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI7IHVzZSBvbmx5ICcuJyB0byBzZXBhcmF0ZSBwcm9wZXJ0eSBwYXRoc2AsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHBhcnRzID0gW3BhdGgucGFydHMuam9pbignLycpXTtcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsID09PSAnLicpIHtcbiAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgIGAnLicgaXMgbm90IGEgc3VwcG9ydGVkIHBhdGggaW4gR2xpbW1lcjsgY2hlY2sgZm9yIGEgcGF0aCB3aXRoIGEgdHJhaWxpbmcgJy4nYCxcbiAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcnRzID0gcGF0aC5wYXJ0cztcbiAgICB9XG5cbiAgICBsZXQgdGhpc0hlYWQgPSBmYWxzZTtcblxuICAgIC8vIFRoaXMgaXMgdG8gZml4IGEgYnVnIGluIHRoZSBIYW5kbGViYXJzIEFTVCB3aGVyZSB0aGUgcGF0aCBleHByZXNzaW9ucyBpblxuICAgIC8vIGB7e3RoaXMuZm9vfX1gIChhbmQgc2ltaWxhcmx5IGB7e2Zvby1iYXIgdGhpcy5mb28gbmFtZWQ9dGhpcy5mb299fWAgZXRjKVxuICAgIC8vIGFyZSBzaW1wbHkgdHVybmVkIGludG8gYHt7Zm9vfX1gLiBUaGUgZml4IGlzIHRvIHB1c2ggaXQgYmFjayBvbnRvIHRoZVxuICAgIC8vIHBhcnRzIGFycmF5IGFuZCBsZXQgdGhlIHJ1bnRpbWUgc2VlIHRoZSBkaWZmZXJlbmNlLiBIb3dldmVyLCB3ZSBjYW5ub3RcbiAgICAvLyBzaW1wbHkgdXNlIHRoZSBzdHJpbmcgYHRoaXNgIGFzIGl0IG1lYW5zIGxpdGVyYWxseSB0aGUgcHJvcGVydHkgY2FsbGVkXG4gICAgLy8gXCJ0aGlzXCIgaW4gdGhlIGN1cnJlbnQgY29udGV4dCAoaXQgY2FuIGJlIGV4cHJlc3NlZCBpbiB0aGUgc3ludGF4IGFzXG4gI