ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
409 lines (400 loc) • 55.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _templateVisitor = require("./template-visitor");
var _templateVisitor2 = _interopRequireDefault(_templateVisitor);
var _javascriptCompiler = require("./javascript-compiler");
var _javascriptCompiler2 = _interopRequireDefault(_javascriptCompiler);
var _util = require("@glimmer/util");
var _syntax = require("@glimmer/syntax");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isTrustedValue(value) {
return value.escaped !== undefined && !value.escaped;
}
class TemplateCompiler {
constructor(options) {
this.templateId = 0;
this.templateIds = [];
this.symbolStack = new _util.Stack();
this.opcodes = [];
this.includeMeta = false;
this.options = options || {};
}
static compile(options, ast) {
let templateVisitor = new _templateVisitor2.default();
templateVisitor.visit(ast);
let compiler = new TemplateCompiler(options);
let opcodes = compiler.process(templateVisitor.actions);
return _javascriptCompiler2.default.process(opcodes, ast['symbols'], options.meta);
}
get symbols() {
return (0, _util.expect)(this.symbolStack.current, 'Expected a symbol table on the stack');
}
process(actions) {
actions.forEach(([name, ...args]) => {
if (!this[name]) {
throw new Error(`Unimplemented ${name} on TemplateCompiler`);
}
this[name](...args);
});
return this.opcodes;
}
startProgram(program) {
this.symbolStack.push(program[0]['symbols']);
this.opcode('startProgram', program, program);
}
endProgram() {
this.symbolStack.pop();
this.opcode('endProgram', null);
}
startBlock(program) {
this.symbolStack.push(program[0]['symbols']);
this.templateId++;
this.opcode('startBlock', program, program);
}
endBlock() {
this.symbolStack.pop();
this.templateIds.push(this.templateId - 1);
this.opcode('endBlock', null);
}
text([action]) {
this.opcode('text', action, action.chars);
}
comment([action]) {
this.opcode('comment', action, action.value);
}
openElement([action]) {
this.opcode('openElement', action, action);
for (let i = 0; i < action.attributes.length; i++) {
this.attribute([action.attributes[i]]);
}
for (let i = 0; i < action.modifiers.length; i++) {
this.modifier([action.modifiers[i]]);
}
this.opcode('flushElement', null);
this.symbolStack.push(action['symbols']);
}
closeElement([action]) {
this.symbolStack.pop();
this.opcode('closeElement', null, action);
}
attribute([action]) {
let { name, value } = action;
let namespace = (0, _util.getAttrNamespace)(name);
let isStatic = this.prepareAttributeValue(value);
if (name.charAt(0) === '@') {
// Arguments
if (isStatic) {
this.opcode('staticArg', action, name);
} else if (action.value.type === 'MustacheStatement') {
this.opcode('dynamicArg', action, name);
} else {
this.opcode('dynamicArg', action, name);
}
} else {
let isTrusting = isTrustedValue(value);
if (isStatic) {
this.opcode('staticAttr', action, name, namespace);
} else if (isTrusting) {
this.opcode('trustingAttr', action, name, namespace);
} else if (action.value.type === 'MustacheStatement') {
this.opcode('dynamicAttr', action, name);
} else {
this.opcode('dynamicAttr', action, name, namespace);
}
}
}
modifier([action]) {
assertIsSimplePath(action.path, action.loc, 'modifier');
let { path: { parts } } = action;
this.prepareHelper(action);
this.opcode('modifier', action, parts[0]);
}
mustache([action]) {
let { path } = action;
if ((0, _syntax.isLiteral)(path)) {
this.mustacheExpression(action);
this.opcode('append', action, !action.escaped);
} else if (isYield(path)) {
let to = assertValidYield(action);
this.yield(to, action);
} else if (isPartial(path)) {
let params = assertValidPartial(action);
this.partial(params, action);
} else if (isDebugger(path)) {
assertValidDebuggerUsage(action);
this.debugger('debugger', action);
} else {
this.mustacheExpression(action);
this.opcode('append', action, !action.escaped);
}
}
block([action /*, index, count*/]) {
this.prepareHelper(action);
let templateId = this.templateIds.pop();
let inverseId = action.inverse === null ? null : this.templateIds.pop();
this.opcode('block', action, action.path.parts[0], templateId, inverseId);
}
/// Internal actions, not found in the original processed actions
arg([path]) {
let { parts: [head, ...rest] } = path;
let symbol = this.symbols.allocateNamed(head);
this.opcode('get', path, symbol, rest);
}
mustacheExpression(expr) {
let { path } = expr;
if ((0, _syntax.isLiteral)(path)) {
this.opcode('literal', expr, path.value);
} else if (isBuiltInHelper(path)) {
this.builtInHelper(expr);
} else if (isArg(path)) {
this.arg([path]);
} else if (isHelperInvocation(expr)) {
this.prepareHelper(expr);
this.opcode('helper', expr, path.parts[0]);
} else if (path.this) {
this.opcode('get', expr, 0, path.parts);
} else if (isLocal(path, this.symbols)) {
let [head, ...parts] = path.parts;
this.opcode('get', expr, this.symbols.get(head), parts);
} else if (isSimplePath(path)) {
this.opcode('unknown', expr, path.parts[0]);
} else {
this.opcode('maybeLocal', expr, path.parts);
}
}
/// Internal Syntax
yield(to, action) {
this.prepareParams(action.params);
this.opcode('yield', action, this.symbols.allocateBlock(to));
}
debugger(_name, action) {
this.opcode('debugger', action, this.symbols.getEvalInfo());
}
hasBlock(name, action) {
this.opcode('hasBlock', action, this.symbols.allocateBlock(name));
}
hasBlockParams(name, action) {
this.opcode('hasBlockParams', action, this.symbols.allocateBlock(name));
}
partial(_params, action) {
this.prepareParams(action.params);
this.opcode('partial', action, this.symbols.getEvalInfo());
}
builtInHelper(expr) {
let { path } = expr;
if (isHasBlock(path)) {
let name = assertValidHasBlockUsage(expr.path.original, expr);
this.hasBlock(name, expr);
} else if (isHasBlockParams(path)) {
let name = assertValidHasBlockUsage(expr.path.original, expr);
this.hasBlockParams(name, expr);
}
}
/// Expressions, invoked recursively from prepareParams and prepareHash
SubExpression(expr) {
if (isBuiltInHelper(expr.path)) {
this.builtInHelper(expr);
} else {
this.prepareHelper(expr);
this.opcode('helper', expr, expr.path.parts[0]);
}
}
PathExpression(expr) {
if (expr.data) {
this.arg([expr]);
} else {
let { symbols } = this;
let [head] = expr.parts;
if (expr.this) {
this.opcode('get', expr, 0, expr.parts);
} else if (symbols.has(head)) {
this.opcode('get', expr, symbols.get(head), expr.parts.slice(1));
} else {
this.opcode('get', expr, 0, expr.parts);
}
}
}
StringLiteral(action) {
this.opcode('literal', null, action.value);
}
BooleanLiteral(action) {
this.opcode('literal', null, action.value);
}
NumberLiteral(action) {
this.opcode('literal', null, action.value);
}
NullLiteral(action) {
this.opcode('literal', null, action.value);
}
UndefinedLiteral(action) {
this.opcode('literal', null, action.value);
}
/// Utilities
opcode(name, action, ...args) {
let opcode = [name, ...args];
if (this.includeMeta && action) {
opcode.push(this.meta(action));
}
this.opcodes.push(opcode);
}
prepareHelper(expr) {
assertIsSimplePath(expr.path, expr.loc, 'helper');
let { params, hash } = expr;
this.prepareHash(hash);
this.prepareParams(params);
}
prepareParams(params) {
if (!params.length) {
this.opcode('literal', null, null);
return;
}
for (let i = params.length - 1; i >= 0; i--) {
let param = params[i];
(0, _util.assert)(this[param.type], `Unimplemented ${param.type} on TemplateCompiler`);
this[param.type](param);
}
this.opcode('prepareArray', null, params.length);
}
prepareHash(hash) {
let pairs = hash.pairs;
if (!pairs.length) {
this.opcode('literal', null, null);
return;
}
for (let i = pairs.length - 1; i >= 0; i--) {
let { key, value } = pairs[i];
(0, _util.assert)(this[value.type], `Unimplemented ${value.type} on TemplateCompiler`);
this[value.type](value);
this.opcode('literal', null, key);
}
this.opcode('prepareObject', null, pairs.length);
}
prepareAttributeValue(value) {
// returns the static value if the value is static
switch (value.type) {
case 'TextNode':
this.opcode('literal', value, value.chars);
return true;
case 'MustacheStatement':
this.attributeMustache([value]);
return false;
case 'ConcatStatement':
this.prepareConcatParts(value.parts);
this.opcode('concat', value);
return false;
}
}
prepareConcatParts(parts) {
for (let i = parts.length - 1; i >= 0; i--) {
let part = parts[i];
if (part.type === 'MustacheStatement') {
this.attributeMustache([part]);
} else if (part.type === 'TextNode') {
this.opcode('literal', null, part.chars);
}
}
this.opcode('prepareArray', null, parts.length);
}
attributeMustache([action]) {
this.mustacheExpression(action);
}
meta(node) {
let loc = node.loc;
if (!loc) {
return [];
}
let { source, start, end } = loc;
return ['loc', [source || null, [start.line, start.column], [end.line, end.column]]];
}
}
exports.default = TemplateCompiler;
function isHelperInvocation(mustache) {
return mustache.params && mustache.params.length > 0 || mustache.hash && mustache.hash.pairs.length > 0;
}
function isSimplePath({ parts }) {
return parts.length === 1;
}
function isLocal({ parts }, symbols) {
return symbols && symbols.has(parts[0]);
}
function isYield(path) {
return path.original === 'yield';
}
function isPartial(path) {
return path.original === 'partial';
}
function isDebugger(path) {
return path.original === 'debugger';
}
function isHasBlock(path) {
return path.original === 'has-block';
}
function isHasBlockParams(path) {
return path.original === 'has-block-params';
}
function isBuiltInHelper(path) {
return isHasBlock(path) || isHasBlockParams(path);
}
function isArg(path) {
return !!path['data'];
}
function assertIsSimplePath(path, loc, context) {
if (!isSimplePath(path)) {
throw new _syntax.SyntaxError(`\`${path.original}\` is not a valid name for a ${context} on line ${loc.start.line}.`, path.loc);
}
}
function assertValidYield(statement) {
let { pairs } = statement.hash;
if (pairs.length === 1 && pairs[0].key !== 'to' || pairs.length > 1) {
throw new _syntax.SyntaxError(`yield only takes a single named argument: 'to'`, statement.loc);
} else if (pairs.length === 1 && pairs[0].value.type !== 'StringLiteral') {
throw new _syntax.SyntaxError(`you can only yield to a literal value`, statement.loc);
} else if (pairs.length === 0) {
return 'default';
} else {
return pairs[0].value.value;
}
}
function assertValidPartial(statement) {
let { params, hash, escaped, loc } = statement;
if (params && params.length !== 1) {
throw new _syntax.SyntaxError(`Partial found with no arguments. You must specify a template name. (on line ${loc.start.line})`, statement.loc);
} else if (hash && hash.pairs.length > 0) {
throw new _syntax.SyntaxError(`partial does not take any named arguments (on line ${loc.start.line})`, statement.loc);
} else if (!escaped) {
throw new _syntax.SyntaxError(`{{{partial ...}}} is not supported, please use {{partial ...}} instead (on line ${loc.start.line})`, statement.loc);
}
return params;
}
function assertValidHasBlockUsage(type, call) {
let { params, hash, loc } = call;
if (hash && hash.pairs.length > 0) {
throw new _syntax.SyntaxError(`${type} does not take any named arguments`, call.loc);
}
if (params.length === 0) {
return 'default';
} else if (params.length === 1) {
let param = params[0];
if (param.type === 'StringLiteral') {
return param.value;
} else {
throw new _syntax.SyntaxError(`you can only yield to a literal value (on line ${loc.start.line})`, call.loc);
}
} else {
throw new _syntax.SyntaxError(`${type} only takes a single positional argument (on line ${loc.start.line})`, call.loc);
}
}
function assertValidDebuggerUsage(statement) {
let { params, hash } = statement;
if (hash && hash.pairs.length > 0) {
throw new _syntax.SyntaxError(`debugger does not take any named arguments`, statement.loc);
}
if (params.length === 0) {
return 'default';
} else {
throw new _syntax.SyntaxError(`debugger does not take any positional arguments`, statement.loc);
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90ZW1wbGF0ZS1jb21waWxlci5qcyJdLCJuYW1lcyI6WyJpc1RydXN0ZWRWYWx1ZSIsInZhbHVlIiwiZXNjYXBlZCIsInVuZGVmaW5lZCIsIlRlbXBsYXRlQ29tcGlsZXIiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJ0ZW1wbGF0ZUlkIiwidGVtcGxhdGVJZHMiLCJzeW1ib2xTdGFjayIsIm9wY29kZXMiLCJpbmNsdWRlTWV0YSIsImNvbXBpbGUiLCJhc3QiLCJ0ZW1wbGF0ZVZpc2l0b3IiLCJ2aXNpdCIsImNvbXBpbGVyIiwicHJvY2VzcyIsImFjdGlvbnMiLCJtZXRhIiwic3ltYm9scyIsImN1cnJlbnQiLCJmb3JFYWNoIiwibmFtZSIsImFyZ3MiLCJFcnJvciIsInN0YXJ0UHJvZ3JhbSIsInByb2dyYW0iLCJwdXNoIiwib3Bjb2RlIiwiZW5kUHJvZ3JhbSIsInBvcCIsInN0YXJ0QmxvY2siLCJlbmRCbG9jayIsInRleHQiLCJhY3Rpb24iLCJjaGFycyIsImNvbW1lbnQiLCJvcGVuRWxlbWVudCIsImkiLCJhdHRyaWJ1dGVzIiwibGVuZ3RoIiwiYXR0cmlidXRlIiwibW9kaWZpZXJzIiwibW9kaWZpZXIiLCJjbG9zZUVsZW1lbnQiLCJuYW1lc3BhY2UiLCJpc1N0YXRpYyIsInByZXBhcmVBdHRyaWJ1dGVWYWx1ZSIsImNoYXJBdCIsInR5cGUiLCJpc1RydXN0aW5nIiwiYXNzZXJ0SXNTaW1wbGVQYXRoIiwicGF0aCIsImxvYyIsInBhcnRzIiwicHJlcGFyZUhlbHBlciIsIm11c3RhY2hlIiwibXVzdGFjaGVFeHByZXNzaW9uIiwiaXNZaWVsZCIsInRvIiwiYXNzZXJ0VmFsaWRZaWVsZCIsInlpZWxkIiwiaXNQYXJ0aWFsIiwicGFyYW1zIiwiYXNzZXJ0VmFsaWRQYXJ0aWFsIiwicGFydGlhbCIsImlzRGVidWdnZXIiLCJhc3NlcnRWYWxpZERlYnVnZ2VyVXNhZ2UiLCJkZWJ1Z2dlciIsImJsb2NrIiwiaW52ZXJzZUlkIiwiaW52ZXJzZSIsImFyZyIsImhlYWQiLCJyZXN0Iiwic3ltYm9sIiwiYWxsb2NhdGVOYW1lZCIsImV4cHIiLCJpc0J1aWx0SW5IZWxwZXIiLCJidWlsdEluSGVscGVyIiwiaXNBcmciLCJpc0hlbHBlckludm9jYXRpb24iLCJ0aGlzIiwiaXNMb2NhbCIsImdldCIsImlzU2ltcGxlUGF0aCIsInByZXBhcmVQYXJhbXMiLCJhbGxvY2F0ZUJsb2NrIiwiX25hbWUiLCJnZXRFdmFsSW5mbyIsImhhc0Jsb2NrIiwiaGFzQmxvY2tQYXJhbXMiLCJfcGFyYW1zIiwiaXNIYXNCbG9jayIsImFzc2VydFZhbGlkSGFzQmxvY2tVc2FnZSIsIm9yaWdpbmFsIiwiaXNIYXNCbG9ja1BhcmFtcyIsIlN1YkV4cHJlc3Npb24iLCJQYXRoRXhwcmVzc2lvbiIsImRhdGEiLCJoYXMiLCJzbGljZSIsIlN0cmluZ0xpdGVyYWwiLCJCb29sZWFuTGl0ZXJhbCIsIk51bWJlckxpdGVyYWwiLCJOdWxsTGl0ZXJhbCIsIlVuZGVmaW5lZExpdGVyYWwiLCJoYXNoIiwicHJlcGFyZUhhc2giLCJwYXJhbSIsInBhaXJzIiwia2V5IiwiYXR0cmlidXRlTXVzdGFjaGUiLCJwcmVwYXJlQ29uY2F0UGFydHMiLCJwYXJ0Iiwibm9kZSIsInNvdXJjZSIsInN0YXJ0IiwiZW5kIiwibGluZSIsImNvbHVtbiIsImNvbnRleHQiLCJzdGF0ZW1lbnQiLCJjYWxsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7OztBQUNBOzs7O0FBQ0E7O0FBRUE7Ozs7QUFDQSxTQUFTQSxjQUFULENBQXdCQyxLQUF4QixFQUErQjtBQUMzQixXQUFPQSxNQUFNQyxPQUFOLEtBQWtCQyxTQUFsQixJQUErQixDQUFDRixNQUFNQyxPQUE3QztBQUNIO0FBQ2MsTUFBTUUsZ0JBQU4sQ0FBdUI7QUFDbENDLGdCQUFZQyxPQUFaLEVBQXFCO0FBQ2pCLGFBQUtDLFVBQUwsR0FBa0IsQ0FBbEI7QUFDQSxhQUFLQyxXQUFMLEdBQW1CLEVBQW5CO0FBQ0EsYUFBS0MsV0FBTCxHQUFtQixpQkFBbkI7QUFD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QUYsRUFBVTRDLElBQVYsS0FBbUJlLFNBQXZCO0FBQ0EsUUFBSWYsUUFBUUEsS0FBS0csS0FBTCxDQUFXdEUsTUFBWCxHQUFvQixDQUFoQyxFQUFtQztBQUMvQixjQUFNLHdCQUFpQiw0Q0FBakIsRUFBOERrRixVQUFVckUsR0FBeEUsQ0FBTjtBQUNIO0FBQ0QsUUFBSVUsT0FBT3ZCLE1BQVAsS0FBa0IsQ0FBdEIsRUFBeUI7QUFDckIsZUFBTyxTQUFQO0FBQ0gsS0FGRCxNQUVPO0FBQ0gsY0FBTSx3QkFBaUIsaURBQWpCLEVBQW1Fa0YsVUFBVXJFLEdBQTdFLENBQU47QUFDSDtBQUNKIiwiZmlsZSI6ImxpYi90ZW1wbGF0ZS1jb21waWxlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBUZW1wbGF0ZVZpc2l0b3IgZnJvbSBcIi4vdGVtcGxhdGUtdmlzaXRvclwiO1xuaW1wb3J0IEphdmFTY3JpcHRDb21waWxlciBmcm9tIFwiLi9qYXZhc2NyaXB0LWNvbXBpbGVyXCI7XG5pbXBvcnQgeyBTdGFjaywgZ2V0QXR0ck5hbWVzcGFjZSB9IGZyb20gXCJAZ2xpbW1lci91dGlsXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGV4cGVjdCB9IGZyb20gXCJAZ2xpbW1lci91dGlsXCI7XG5pbXBvcnQgeyBpc0xpdGVyYWwsIFN5bnRheEVycm9yIH0gZnJvbSAnQGdsaW1tZXIvc3ludGF4JztcbmZ1bmN0aW9uIGlzVHJ1c3RlZFZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLmVzY2FwZWQgIT09IHVuZGVmaW5lZCAmJiAhdmFsdWUuZXNjYXBlZDtcbn1cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlbXBsYXRlQ29tcGlsZXIge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUlkID0gMDtcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUlkcyA9IFtdO1xuICAgICAgICB0aGlzLnN5bWJvbFN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgICAgIHRoaXMub3Bjb2RlcyA9IFtdO1xuICAgICAgICB0aGlzLmluY2x1ZGVNZXRhID0gZmFsc2U7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgfVxuICAgIHN0YXRpYyBjb21waWxlKG9wdGlvbnMsIGFzdCkge1xuICAgICAgICBsZXQgdGVtcGxhdGVWaXNpdG9yID0gbmV3IFRlbXBsYXRlVmlzaXRvcigpO1xuICAgICAgICB0ZW1wbGF0ZVZpc2l0b3IudmlzaXQoYXN0KTtcbiAgICAgICAgbGV0IGNvbXBpbGVyID0gbmV3IFRlbXBsYXRlQ29tcGlsZXIob3B0aW9ucyk7XG4gICAgICAgIGxldCBvcGNvZGVzID0gY29tcGlsZXIucHJvY2Vzcyh0ZW1wbGF0ZVZpc2l0b3IuYWN0aW9ucyk7XG4gICAgICAgIHJldHVybiBKYXZhU2NyaXB0Q29tcGlsZXIucHJvY2VzcyhvcGNvZGVzLCBhc3RbJ3N5bWJvbHMnXSwgb3B0aW9ucy5tZXRhKTtcbiAgICB9XG4gICAgZ2V0IHN5bWJvbHMoKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5zeW1ib2xTdGFjay5jdXJyZW50LCAnRXhwZWN0ZWQgYSBzeW1ib2wgdGFibGUgb24gdGhlIHN0YWNrJyk7XG4gICAgfVxuICAgIHByb2Nlc3MoYWN0aW9ucykge1xuICAgICAgICBhY3Rpb25zLmZvckVhY2goKFtuYW1lLCAuLi5hcmdzXSkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmltcGxlbWVudGVkICR7bmFtZX0gb24gVGVtcGxhdGVDb21waWxlcmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpc1tuYW1lXSguLi5hcmdzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLm9wY29kZXM7XG4gICAgfVxuICAgIHN0YXJ0UHJvZ3JhbShwcm9ncmFtKSB7XG4gICAgICAgIHRoaXMuc3ltYm9sU3RhY2sucHVzaChwcm9ncmFtWzBdWydzeW1ib2xzJ10pO1xuICAgICAgICB0aGlzLm9wY29kZSgnc3RhcnRQcm9ncmFtJywgcHJvZ3JhbSwgcHJvZ3JhbSk7XG4gICAgfVxuICAgIGVuZFByb2dyYW0oKSB7XG4gICAgICAgIHRoaXMuc3ltYm9sU3RhY2sucG9wKCk7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdlbmRQcm9ncmFtJywgbnVsbCk7XG4gICAgfVxuICAgIHN0YXJ0QmxvY2socHJvZ3JhbSkge1xuICAgICAgICB0aGlzLnN5bWJvbFN0YWNrLnB1c2gocHJvZ3JhbVswXVsnc3ltYm9scyddKTtcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUlkKys7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdzdGFydEJsb2NrJywgcHJvZ3JhbSwgcHJvZ3JhbSk7XG4gICAgfVxuICAgIGVuZEJsb2NrKCkge1xuICAgICAgICB0aGlzLnN5bWJvbFN0YWNrLnBvcCgpO1xuICAgICAgICB0aGlzLnRlbXBsYXRlSWRzLnB1c2godGhpcy50ZW1wbGF0ZUlkIC0gMSk7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdlbmRCbG9jaycsIG51bGwpO1xuICAgIH1cbiAgICB0ZXh0KFthY3Rpb25dKSB7XG4gICAgICAgIHRoaXMub3Bjb2RlKCd0ZXh0JywgYWN0aW9uLCBhY3Rpb24uY2hhcnMpO1xuICAgIH1cbiAgICBjb21tZW50KFthY3Rpb25dKSB7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdjb21tZW50JywgYWN0aW9uLCBhY3Rpb24udmFsdWUpO1xuICAgIH1cbiAgICBvcGVuRWxlbWVudChbYWN0aW9uXSkge1xuICAgICAgICB0aGlzLm9wY29kZSgnb3BlbkVsZW1lbnQnLCBhY3Rpb24sIGFjdGlvbik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0aW9uLmF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlKFthY3Rpb24uYXR0cmlidXRlc1tpXV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0aW9uLm1vZGlmaWVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5tb2RpZmllcihbYWN0aW9uLm1vZGlmaWVyc1tpXV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3Bjb2RlKCdmbHVzaEVsZW1lbnQnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zeW1ib2xTdGFjay5wdXNoKGFjdGlvblsnc3ltYm9scyddKTtcbiAgICB9XG4gICAgY2xvc2VFbGVtZW50KFthY3Rpb25dKSB7XG4gICAgICAgIHRoaXMuc3ltYm9sU3RhY2sucG9wKCk7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdjbG9zZUVsZW1lbnQnLCBudWxsLCBhY3Rpb24pO1xuICAgIH1cbiAgICBhdHRyaWJ1dGUoW2FjdGlvbl0pIHtcbiAgICAgICAgbGV0IHsgbmFtZSwgdmFsdWUgfSA9IGFjdGlvbjtcbiAgICAgICAgbGV0IG5hbWVzcGFjZSA9IGdldEF0dHJOYW1lc3BhY2UobmFtZSk7XG4gICAgICAgIGxldCBpc1N0YXRpYyA9IHRoaXMucHJlcGFyZUF0dHJpYnV0ZVZhbHVlKHZhbHVlKTtcbiAgICAgICAgaWYgKG5hbWUuY2hhckF0KDApID09PSAnQCcpIHtcbiAgICAgICAgICAgIC8vIEFyZ3VtZW50c1xuICAgICAgICAgICAgaWYgKGlzU3RhdGljKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ3N0YXRpY0FyZycsIGFjdGlvbiwgbmFtZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi52YWx1ZS50eXBlID09PSAnTXVzdGFjaGVTdGF0ZW1lbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2R5bmFtaWNBcmcnLCBhY3Rpb24sIG5hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wY29kZSgnZHluYW1pY0FyZycsIGFjdGlvbiwgbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgaXNUcnVzdGluZyA9IGlzVHJ1c3RlZFZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgIGlmIChpc1N0YXRpYykge1xuICAgICAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdzdGF0aWNBdHRyJywgYWN0aW9uLCBuYW1lLCBuYW1lc3BhY2UpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RydXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ3RydXN0aW5nQXR0cicsIGFjdGlvbiwgbmFtZSwgbmFtZXNwYWNlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uLnZhbHVlLnR5cGUgPT09ICdNdXN0YWNoZVN0YXRlbWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wY29kZSgnZHluYW1pY0F0dHInLCBhY3Rpb24sIG5hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wY29kZSgnZHluYW1pY0F0dHInLCBhY3Rpb24sIG5hbWUsIG5hbWVzcGFjZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgbW9kaWZpZXIoW2FjdGlvbl0pIHtcbiAgICAgICAgYXNzZXJ0SXNTaW1wbGVQYXRoKGFjdGlvbi5wYXRoLCBhY3Rpb24ubG9jLCAnbW9kaWZpZXInKTtcbiAgICAgICAgbGV0IHsgcGF0aDogeyBwYXJ0cyB9IH0gPSBhY3Rpb247XG4gICAgICAgIHRoaXMucHJlcGFyZUhlbHBlcihhY3Rpb24pO1xuICAgICAgICB0aGlzLm9wY29kZSgnbW9kaWZpZXInLCBhY3Rpb24sIHBhcnRzWzBdKTtcbiAgICB9XG4gICAgbXVzdGFjaGUoW2FjdGlvbl0pIHtcbiAgICAgICAgbGV0IHsgcGF0aCB9ID0gYWN0aW9uO1xuICAgICAgICBpZiAoaXNMaXRlcmFsKHBhdGgpKSB7XG4gICAgICAgICAgICB0aGlzLm11c3RhY2hlRXhwcmVzc2lvbihhY3Rpb24pO1xuICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2FwcGVuZCcsIGFjdGlvbiwgIWFjdGlvbi5lc2NhcGVkKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1lpZWxkKHBhdGgpKSB7XG4gICAgICAgICAgICBsZXQgdG8gPSBhc3NlcnRWYWxpZFlpZWxkKGFjdGlvbik7XG4gICAgICAgICAgICB0aGlzLnlpZWxkKHRvLCBhY3Rpb24pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzUGFydGlhbChwYXRoKSkge1xuICAgICAgICAgICAgbGV0IHBhcmFtcyA9IGFzc2VydFZhbGlkUGFydGlhbChhY3Rpb24pO1xuICAgICAgICAgICAgdGhpcy5wYXJ0aWFsKHBhcmFtcywgYWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0RlYnVnZ2VyKHBhdGgpKSB7XG4gICAgICAgICAgICBhc3NlcnRWYWxpZERlYnVnZ2VyVXNhZ2UoYWN0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuZGVidWdnZXIoJ2RlYnVnZ2VyJywgYWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubXVzdGFjaGVFeHByZXNzaW9uKGFjdGlvbik7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnYXBwZW5kJywgYWN0aW9uLCAhYWN0aW9uLmVzY2FwZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGJsb2NrKFthY3Rpb24gLyosIGluZGV4LCBjb3VudCovXSkge1xuICAgICAgICB0aGlzLnByZXBhcmVIZWxwZXIoYWN0aW9uKTtcbiAgICAgICAgbGV0IHRlbXBsYXRlSWQgPSB0aGlzLnRlbXBsYXRlSWRzLnBvcCgpO1xuICAgICAgICBsZXQgaW52ZXJzZUlkID0gYWN0aW9uLmludmVyc2UgPT09IG51bGwgPyBudWxsIDogdGhpcy50ZW1wbGF0ZUlkcy5wb3AoKTtcbiAgICAgICAgdGhpcy5vcGNvZGUoJ2Jsb2NrJywgYWN0aW9uLCBhY3Rpb24ucGF0aC5wYXJ0c1swXSwgdGVtcGxhdGVJZCwgaW52ZXJzZUlkKTtcbiAgICB9XG4gICAgLy8vIEludGVybmFsIGFjdGlvbnMsIG5vdCBmb3VuZCBpbiB0aGUgb3JpZ2luYWwgcHJvY2Vzc2VkIGFjdGlvbnNcbiAgICBhcmcoW3BhdGhdKSB7XG4gICAgICAgIGxldCB7IHBhcnRzOiBbaGVhZCwgLi4ucmVzdF0gfSA9IHBhdGg7XG4gICAgICAgIGxldCBzeW1ib2wgPSB0aGlzLnN5bWJvbHMuYWxsb2NhdGVOYW1lZChoZWFkKTtcbiAgICAgICAgdGhpcy5vcGNvZGUoJ2dldCcsIHBhdGgsIHN5bWJvbCwgcmVzdCk7XG4gICAgfVxuICAgIG11c3RhY2hlRXhwcmVzc2lvbihleHByKSB7XG4gICAgICAgIGxldCB7IHBhdGggfSA9IGV4cHI7XG4gICAgICAgIGlmIChpc0xpdGVyYWwocGF0aCkpIHtcbiAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdsaXRlcmFsJywgZXhwciwgcGF0aC52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNCdWlsdEluSGVscGVyKHBhdGgpKSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWx0SW5IZWxwZXIoZXhwcik7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcmcocGF0aCkpIHtcbiAgICAgICAgICAgIHRoaXMuYXJnKFtwYXRoXSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNIZWxwZXJJbnZvY2F0aW9uKGV4cHIpKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVIZWxwZXIoZXhwcik7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnaGVscGVyJywgZXhwciwgcGF0aC5wYXJ0c1swXSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGF0aC50aGlzKSB7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnZ2V0JywgZXhwciwgMCwgcGF0aC5wYXJ0cyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNMb2NhbChwYXRoLCB0aGlzLnN5bWJvbHMpKSB7XG4gICAgICAgICAgICBsZXQgW2hlYWQsIC4uLnBhcnRzXSA9IHBhdGgucGFydHM7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnZ2V0JywgZXhwciwgdGhpcy5zeW1ib2xzLmdldChoZWFkKSwgcGFydHMpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzU2ltcGxlUGF0aChwYXRoKSkge1xuICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ3Vua25vd24nLCBleHByLCBwYXRoLnBhcnRzWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdtYXliZUxvY2FsJywgZXhwciwgcGF0aC5wYXJ0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8vIEludGVybmFsIFN5bnRheFxuICAgIHlpZWxkKHRvLCBhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5wcmVwYXJlUGFyYW1zKGFjdGlvbi5wYXJhbXMpO1xuICAgICAgICB0aGlzLm9wY29kZSgneWllbGQnLCBhY3Rpb24sIHRoaXMuc3ltYm9scy5hbGxvY2F0ZUJsb2NrKHRvKSk7XG4gICAgfVxuICAgIGRlYnVnZ2VyKF9uYW1lLCBhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5vcGNvZGUoJ2RlYnVnZ2VyJywgYWN0aW9uLCB0aGlzLnN5bWJvbHMuZ2V0RXZhbEluZm8oKSk7XG4gICAgfVxuICAgIGhhc0Jsb2NrKG5hbWUsIGFjdGlvbikge1xuICAgICAgICB0aGlzLm9wY29kZSgnaGFzQmxvY2snLCBhY3Rpb24sIHRoaXMuc3ltYm9scy5hbGxvY2F0ZUJsb2NrKG5hbWUpKTtcbiAgICB9XG4gICAgaGFzQmxvY2tQYXJhbXMobmFtZSwgYWN0aW9uKSB7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdoYXNCbG9ja1BhcmFtcycsIGFjdGlvbiwgdGhpcy5zeW1ib2xzLmFsbG9jYXRlQmxvY2sobmFtZSkpO1xuICAgIH1cbiAgICBwYXJ0aWFsKF9wYXJhbXMsIGFjdGlvbikge1xuICAgICAgICB0aGlzLnByZXBhcmVQYXJhbXMoYWN0aW9uLnBhcmFtcyk7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdwYXJ0aWFsJywgYWN0aW9uLCB0aGlzLnN5bWJvbHMuZ2V0RXZhbEluZm8oKSk7XG4gICAgfVxuICAgIGJ1aWx0SW5IZWxwZXIoZXhwcikge1xuICAgICAgICBsZXQgeyBwYXRoIH0gPSBleHByO1xuICAgICAgICBpZiAoaXNIYXNCbG9jayhwYXRoKSkge1xuICAgICAgICAgICAgbGV0IG5hbWUgPSBhc3NlcnRWYWxpZEhhc0Jsb2NrVXNhZ2UoZXhwci5wYXRoLm9yaWdpbmFsLCBleHByKTtcbiAgICAgICAgICAgIHRoaXMuaGFzQmxvY2sobmFtZSwgZXhwcik7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNIYXNCbG9ja1BhcmFtcyhwYXRoKSkge1xuICAgICAgICAgICAgbGV0IG5hbWUgPSBhc3NlcnRWYWxpZEhhc0Jsb2NrVXNhZ2UoZXhwci5wYXRoLm9yaWdpbmFsLCBleHByKTtcbiAgICAgICAgICAgIHRoaXMuaGFzQmxvY2tQYXJhbXMobmFtZSwgZXhwcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8vIEV4cHJlc3Npb25zLCBpbnZva2VkIHJlY3Vyc2l2ZWx5IGZyb20gcHJlcGFyZVBhcmFtcyBhbmQgcHJlcGFyZUhhc2hcbiAgICBTdWJFeHByZXNzaW9uKGV4cHIpIHtcbiAgICAgICAgaWYgKGlzQnVpbHRJbkhlbHBlcihleHByLnBhdGgpKSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWx0SW5IZWxwZXIoZXhwcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVIZWxwZXIoZXhwcik7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnaGVscGVyJywgZXhwciwgZXhwci5wYXRoLnBhcnRzWzBdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBQYXRoRXhwcmVzc2lvbihleHByKSB7XG4gICAgICAgIGlmIChleHByLmRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuYXJnKFtleHByXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgeyBzeW1ib2xzIH0gPSB0aGlzO1xuICAgICAgICAgICAgbGV0IFtoZWFkXSA9IGV4cHIucGFydHM7XG4gICAgICAgICAgICBpZiAoZXhwci50aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2dldCcsIGV4cHIsIDAsIGV4cHIucGFydHMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzeW1ib2xzLmhhcyhoZWFkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdnZXQnLCBleHByLCBzeW1ib2xzLmdldChoZWFkKSwgZXhwci5wYXJ0cy5zbGljZSgxKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdnZXQnLCBleHByLCAwLCBleHByLnBhcnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBTdHJpbmdMaXRlcmFsKGFjdGlvbikge1xuICAgICAgICB0aGlzLm9wY29kZSgnbGl0ZXJhbCcsIG51bGwsIGFjdGlvbi52YWx1ZSk7XG4gICAgfVxuICAgIEJvb2xlYW5MaXRlcmFsKGFjdGlvbikge1xuICAgICAgICB0aGlzLm9wY29kZSgnbGl0ZXJhbCcsIG51bGwsIGFjdGlvbi52YWx1ZSk7XG4gICAgfVxuICAgIE51bWJlckxpdGVyYWwoYWN0aW9uKSB7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdsaXRlcmFsJywgbnVsbCwgYWN0aW9uLnZhbHVlKTtcbiAgICB9XG4gICAgTnVsbExpdGVyYWwoYWN0aW9uKSB7XG4gICAgICAgIHRoaXMub3Bjb2RlKCdsaXRlcmFsJywgbnVsbCwgYWN0aW9uLnZhbHVlKTtcbiAgICB9XG4gICAgVW5kZWZpbmVkTGl0ZXJhbChhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5vcGNvZGUoJ2xpdGVyYWwnLCBudWxsLCBhY3Rpb24udmFsdWUpO1xuICAgIH1cbiAgICAvLy8gVXRpbGl0aWVzXG4gICAgb3Bjb2RlKG5hbWUsIGFjdGlvbiwgLi4uYXJncykge1xuICAgICAgICBsZXQgb3Bjb2RlID0gW25hbWUsIC4uLmFyZ3NdO1xuICAgICAgICBpZiAodGhpcy5pbmNsdWRlTWV0YSAmJiBhY3Rpb24pIHtcbiAgICAgICAgICAgIG9wY29kZS5wdXNoKHRoaXMubWV0YShhY3Rpb24pKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wY29kZXMucHVzaChvcGNvZGUpO1xuICAgIH1cbiAgICBwcmVwYXJlSGVscGVyKGV4cHIpIHtcbiAgICAgICAgYXNzZXJ0SXNTaW1wbGVQYXRoKGV4cHIucGF0aCwgZXhwci5sb2MsICdoZWxwZXInKTtcbiAgICAgICAgbGV0IHsgcGFyYW1zLCBoYXNoIH0gPSBleHByO1xuICAgICAgICB0aGlzLnByZXBhcmVIYXNoKGhhc2gpO1xuICAgICAgICB0aGlzLnByZXBhcmVQYXJhbXMocGFyYW1zKTtcbiAgICB9XG4gICAgcHJlcGFyZVBhcmFtcyhwYXJhbXMpIHtcbiAgICAgICAgaWYgKCFwYXJhbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnbGl0ZXJhbCcsIG51bGwsIG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSBwYXJhbXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCBwYXJhbSA9IHBhcmFtc1tpXTtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzW3BhcmFtLnR5cGVdLCBgVW5pbXBsZW1lbnRlZCAke3BhcmFtLnR5cGV9IG9uIFRlbXBsYXRlQ29tcGlsZXJgKTtcbiAgICAgICAgICAgIHRoaXNbcGFyYW0udHlwZV0ocGFyYW0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3Bjb2RlKCdwcmVwYXJlQXJyYXknLCBudWxsLCBwYXJhbXMubGVuZ3RoKTtcbiAgICB9XG4gICAgcHJlcGFyZUhhc2goaGFzaCkge1xuICAgICAgICBsZXQgcGFpcnMgPSBoYXNoLnBhaXJzO1xuICAgICAgICBpZiAoIXBhaXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2xpdGVyYWwnLCBudWxsLCBudWxsKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gcGFpcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCB7IGtleSwgdmFsdWUgfSA9IHBhaXJzW2ldO1xuICAgICAgICAgICAgYXNzZXJ0KHRoaXNbdmFsdWUudHlwZV0sIGBVbmltcGxlbWVudGVkICR7dmFsdWUudHlwZX0gb24gVGVtcGxhdGVDb21waWxlcmApO1xuICAgICAgICAgICAgdGhpc1t2YWx1ZS50eXBlXSh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLm9wY29kZSgnbGl0ZXJhbCcsIG51bGwsIGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcGNvZGUoJ3ByZXBhcmVPYmplY3QnLCBudWxsLCBwYWlycy5sZW5ndGgpO1xuICAgIH1cbiAgICBwcmVwYXJlQXR0cmlidXRlVmFsdWUodmFsdWUpIHtcbiAgICAgICAgLy8gcmV0dXJucyB0aGUgc3RhdGljIHZhbHVlIGlmIHRoZSB2YWx1ZSBpcyBzdGF0aWNcbiAgICAgICAgc3dpdGNoICh2YWx1ZS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdUZXh0Tm9kZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2xpdGVyYWwnLCB2YWx1ZSwgdmFsdWUuY2hhcnMpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgY2FzZSAnTXVzdGFjaGVTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlTXVzdGFjaGUoW3ZhbHVlXSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgY2FzZSAnQ29uY2F0U3RhdGVtZW50JzpcbiAgICAgICAgICAgICAgICB0aGlzLnByZXBhcmVDb25jYXRQYXJ0cyh2YWx1ZS5wYXJ0cyk7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGNvZGUoJ2NvbmNhdCcsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJlcGFyZUNvbmNhdFBhcnRzKHBhcnRzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdNdXN0YWNoZVN0YXRlbWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZU11c3RhY2hlKFtwYXJ0XSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gJ1RleHROb2RlJykge1xuICAgICAgICAgICAgICAgIHRoaXMub3Bjb2RlKCdsaXRlcmFsJywgbnVsbCwgcGFydC5jaGFycyk7XG4gIC