@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
245 lines (244 loc) • 52.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const client_common_1 = require("@neo-one/client-common");
const utils_1 = require("@neo-one/utils");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const constants_1 = require("../../../constants");
const Helper_1 = require("../Helper");
const utils_2 = require("./utils");
class InvokeSmartContractHelper extends Helper_1.Helper {
constructor({ contractInfo }) {
super();
this.contractInfo = contractInfo;
}
emit(sb, node, optionsIn) {
const options = sb.pushValueOptions(optionsIn);
const getCaseBase = (decl, name, whenTrue) => ({
condition: () => {
sb.emitOp(decl, 'DUP');
sb.emitPushString(decl, name);
sb.emitOp(decl, 'EQUAL');
},
whenTrue: () => {
sb.emitOp(decl, 'DROP');
whenTrue();
},
});
const getFunctionCase = (propInfo) => getCaseBase(propInfo.decl, propInfo.name, () => {
const decl = propInfo.decl;
if (typescript_1.default.isPropertyDeclaration(decl)) {
sb.context.reportUnsupported(decl);
return;
}
if (propInfo.send) {
sb.emitHelper(decl, options, sb.helpers.handleSend({ method: decl, returnType: propInfo.returnType }));
}
else if (propInfo.receive) {
sb.emitHelper(decl, options, sb.helpers.handleReceive({ opposite: propInfo.sendUnsafe, method: decl, returnType: propInfo.returnType }));
}
else if (propInfo.sendUnsafe) {
sb.emitHelper(decl, options, sb.helpers.handleSendUnsafe({ opposite: propInfo.receive, method: decl, returnType: propInfo.returnType }));
}
else {
sb.emitHelper(decl, options, sb.helpers.handleNormal({ propInfo }));
}
});
const getDeployCase = (contractInfo, propInfo) => {
const decl = propInfo.decl === undefined ? propInfo.classDecl : propInfo.decl;
return getCaseBase(decl, propInfo.name, () => {
sb.emitHelper(decl, options, sb.helpers.deploy({ contractInfo, propInfo }));
});
};
const getPropertyCase = (propInfo) => {
const decl = propInfo.decl;
return getCaseBase(decl, propInfo.name, () => {
sb.emitHelper(decl, options, sb.helpers.handleNormal({ propInfo }));
});
};
const getAccessorCase = (propInfo) => {
const mutableCases = [];
const getter = propInfo.getter;
if (getter !== undefined) {
mutableCases.push(getCaseBase(getter.decl, getter.name, () => {
sb.emitHelper(getter.decl, options, sb.helpers.handleNormal({ propInfo, getter: true }));
}));
}
const setter = propInfo.setter;
if (setter !== undefined) {
mutableCases.push(getCaseBase(setter.decl, setter.name, () => {
sb.emitHelper(setter.decl, options, sb.helpers.handleNormal({ propInfo, getter: false }));
}));
}
return mutableCases;
};
const getRefundAssetsCase = (propInfo) => getCaseBase(node, constants_1.ContractPropertyName.refundAssets, () => {
sb.emitHelper(node, options, sb.helpers.handleNormal({ propInfo }));
});
const getCompleteSendCase = (propInfo) => getCaseBase(node, constants_1.ContractPropertyName.completeSend, () => {
sb.emitHelper(node, options, sb.helpers.handleNormal({ propInfo }));
});
const getUpgradeCase = (propInfo) => getCaseBase(node, constants_1.ContractPropertyName.upgrade, () => {
sb.emitHelper(node, options, sb.helpers.handleNormal({ propInfo }));
});
const allCases = lodash_1.default.flatten(this.contractInfo.propInfos
.filter((propInfo) => propInfo.isPublic && propInfo.type !== 'deploy')
.map((propInfo) => {
if (propInfo.type === 'function') {
return [
{
propCase: getFunctionCase(propInfo),
claimVerify: propInfo.claim,
invokeVerify: propInfo.send || propInfo.sendUnsafe || propInfo.receive,
},
];
}
if (propInfo.type === 'refundAssets') {
return [{ propCase: getRefundAssetsCase(propInfo), claimVerify: false, invokeVerify: true }];
}
if (propInfo.type === 'completeSend') {
return [{ propCase: getCompleteSendCase(propInfo), claimVerify: false, invokeVerify: true }];
}
if (propInfo.type === 'property') {
return [{ propCase: getPropertyCase(propInfo), claimVerify: false, invokeVerify: false }];
}
if (propInfo.type === 'accessor') {
return getAccessorCase(propInfo).map((propCase) => ({
propCase,
claimVerify: false,
invokeVerify: false,
}));
}
if (propInfo.type === 'upgrade') {
return [{ propCase: getUpgradeCase(propInfo), claimVerify: false, invokeVerify: false }];
}
if (propInfo.type === 'deploy') {
throw new Error('For TS');
}
utils_1.utils.assertNever(propInfo);
throw new Error('For TS');
}));
let applicationCases = allCases.filter((propCase) => !propCase.claimVerify).map(({ propCase }) => propCase);
const deploy = utils_2.findDeployInfo(this.contractInfo);
if (deploy !== undefined) {
applicationCases = applicationCases.concat(getDeployCase(deploy[0], deploy[1]));
}
const invocationVerifyCases = allCases.filter((propCase) => propCase.invokeVerify).map(({ propCase }) => propCase);
const nonVerifyCases = allCases.filter((propCase) => !propCase.invokeVerify).map(({ propCase }) => propCase);
const claimCases = allCases.filter((propCase) => propCase.claimVerify).map(({ propCase }) => propCase);
const throwDefault = () => {
sb.emitOp(node, 'DROP');
sb.emitOp(node, 'THROW');
};
const handleInvokeVerify = (func) => {
sb.emitHelper(node, options, sb.helpers.if({
condition: () => {
sb.emitHelper(node, options, sb.helpers.applicationMatchesVerification);
sb.emitOp(node, 'DUP');
},
whenTrue: () => {
func();
sb.emitOp(node, 'DROP');
},
}));
};
const handleClaimVerify = (func) => {
func();
sb.emitOp(node, 'DROP');
sb.emitPushBoolean(node, true);
};
const handleDefaultInvokeVerify = () => {
sb.emitOp(node, 'DROP');
sb.emitHelper(node, options, sb.helpers.didReceiveAssets);
sb.emitHelper(node, options, sb.helpers.didSendAssets);
sb.emitHelper(node, options, sb.helpers.if({
condition: () => {
sb.emitOp(node, 'BOOLOR');
},
whenTrue: () => {
sb.emitOp(node, 'THROW');
},
whenFalse: () => {
sb.emitPushInt(node, 0);
sb.emitHelper(node, options, sb.helpers.getArgument);
sb.emitHelper(node, options, sb.helpers.case(nonVerifyCases, throwDefault));
},
}));
};
sb.emitSysCall(node, 'Neo.Runtime.GetTrigger');
sb.emitHelper(node, options, sb.helpers.case([
{
condition: () => {
sb.emitOp(node, 'DUP');
sb.emitPushInt(node, 0x10);
sb.emitOp(node, 'NUMEQUAL');
},
whenTrue: () => {
sb.emitOp(node, 'DROP');
sb.emitPushInt(node, 0);
sb.emitHelper(node, options, sb.helpers.getArgument);
sb.emitHelper(node, options, sb.helpers.case(applicationCases, throwDefault));
},
},
{
condition: () => {
sb.emitOp(node, 'DUP');
sb.emitPushInt(node, 0x00);
sb.emitOp(node, 'NUMEQUAL');
},
whenTrue: () => {
sb.emitOp(node, 'DROP');
sb.emitSysCall(node, 'System.ExecutionEngine.GetScriptContainer');
sb.emitSysCall(node, 'Neo.Transaction.GetType');
sb.emitHelper(node, options, sb.helpers.case([
{
condition: () => {
sb.emitOp(node, 'DUP');
sb.emitPushInt(node, client_common_1.TransactionTypeModel.Invocation);
sb.emitOp(node, 'NUMEQUAL');
},
whenTrue: () => {
sb.emitOp(node, 'DROP');
sb.emitPushInt(node, 0);
sb.emitHelper(node, options, sb.helpers.getArgument);
sb.emitHelper(node, options, sb.helpers.case(invocationVerifyCases.map((propCase) => (Object.assign({}, propCase, { whenTrue: () => {
handleInvokeVerify(propCase.whenTrue);
} }))), handleDefaultInvokeVerify));
},
},
{
condition: () => {
sb.emitOp(node, 'DUP');
sb.emitPushInt(node, client_common_1.TransactionTypeModel.Claim);
sb.emitOp(node, 'NUMEQUAL');
},
whenTrue: () => {
sb.emitOp(node, 'DROP');
sb.emitHelper(node, options, sb.helpers.didReceiveNonClaimAssets);
sb.emitHelper(node, options, sb.helpers.didSendAssets);
sb.emitHelper(node, options, sb.helpers.if({
condition: () => {
sb.emitOp(node, 'BOOLOR');
},
whenTrue: () => {
sb.emitPushBoolean(node, false);
},
whenFalse: () => {
sb.emitPushInt(node, 0);
sb.emitHelper(node, options, sb.helpers.getArgument);
sb.emitHelper(node, options, sb.helpers.case(claimCases.map((propCase) => (Object.assign({}, propCase, { whenTrue: () => {
handleClaimVerify(propCase.whenTrue);
} }))), throwDefault));
},
}));
},
},
], throwDefault));
},
},
], throwDefault));
}
}
exports.InvokeSmartContractHelper = InvokeSmartContractHelper;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkludm9rZVNtYXJ0Q29udHJhY3RIZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsMERBQWlGO0FBQ2pGLDBDQUF1QztBQUN2Qyw0REFBdUI7QUFDdkIsb0VBQTRCO0FBQzVCLGtEQUEwRDtBQWExRCxzQ0FBbUM7QUFFbkMsbUNBQXlDO0FBc056QyxNQUFhLHlCQUEwQixTQUFRLGVBQU07SUFHbkQsWUFBbUIsRUFBRSxZQUFZLEVBQW9DO1FBQ25FLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDbkMsQ0FBQztJQUVNLElBQUksQ0FBQyxFQUFpQixFQUFFLElBQWEsRUFBRSxTQUF1QjtRQUNuRSxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFL0MsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFhLEVBQUUsSUFBWSxFQUFFLFFBQW9CLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDMUUsU0FBUyxFQUFFLEdBQUcsRUFBRTtnQkFFZCxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFFdkIsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRTlCLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzNCLENBQUM7WUFDRCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUViLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN4QixRQUFRLEVBQUUsQ0FBQztZQUNiLENBQUM7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQTBCLEVBQUUsRUFBRSxDQUNyRCxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtZQUM3QyxNQUFN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QUFDO0NBQ0Y7QUFwWEQsOERBb1hDIiwiZmlsZSI6Im5lby1vbmUtc21hcnQtY29udHJhY3QtY29tcGlsZXIvc3JjL2NvbXBpbGUvaGVscGVyL2NvbnRyYWN0L0ludm9rZVNtYXJ0Q29udHJhY3RIZWxwZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0c2xpbnQ6ZGlzYWJsZSBwcmVmZXItc3dpdGNoXG5pbXBvcnQgeyBUcmFuc2FjdGlvblR5cGVNb2RlbCBhcyBUcmFuc2FjdGlvblR5cGUgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7IHV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IENvbnRyYWN0UHJvcGVydHlOYW1lIH0gZnJvbSAnLi4vLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIEFjY2Vzc29yUHJvcEluZm8sXG4gIENvbXBsZXRlU2VuZFByb3BJbmZvLFxuICBDb250cmFjdEluZm8sXG4gIERlcGxveVByb3BJbmZvLFxuICBGdW5jdGlvblByb3BJbmZvLFxuICBQcm9wZXJ0eVByb3BJbmZvLFxuICBSZWZ1bmRBc3NldHNQcm9wSW5mbyxcbiAgVXBncmFkZVByb3BJbmZvLFxufSBmcm9tICcuLi8uLi8uLi9jb250cmFjdCc7XG5pbXBvcnQgeyBTY3JpcHRCdWlsZGVyIH0gZnJvbSAnLi4vLi4vc2InO1xuaW1wb3J0IHsgVmlzaXRPcHRpb25zIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgSGVscGVyIH0gZnJvbSAnLi4vSGVscGVyJztcbmltcG9ydCB7IENhc2UgfSBmcm9tICcuLi9zdGF0ZW1lbnQnO1xuaW1wb3J0IHsgZmluZERlcGxveUluZm8gfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnZva2VTbWFydENvbnRyYWN0SGVscGVyT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNvbnRyYWN0SW5mbzogQ29udHJhY3RJbmZvO1xufVxuXG4vKipcbiAqIFBzZXVkb2NvZGUgb2Ygd2hhdCdzIGhhcHBlbmluZyBoZXJlOlxuICogY29uc3QgY29udHJhY3QgPSBuZXcgQ29udHJhY3QoKTtcbiAqXG4gKiBjb25zdCBoYW5kbGVTZW5kID0gKCkgPT4ge1xuICogIGlmIChpc1Byb2Nlc3NlZChCbG9ja2NoYWluLmN1cnJlbnRUcmFuc2FjdGlvbi5oYXNoKSkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgaWYgKCFmaXJzdE91dHB1dFRvU2VsZigpKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBpZiAoIWFsbElucHV0c0FyZVByb2Nlc3NlZEFuZFVuY2xhaW1lZCgpKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBpZiAoIW5ldFplcm8oKSkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgY29uc3QgYXJncyA9IGdldEFyZ3VtZW50KDEpO1xuICogIGNvbnN0IHsgYXNzZXQsIGFtb3VudCB9ID0gZ2V0U2VuZEFyZ3MoKTtcbiAqICBjb25zdCByZXN1bHQgPSBjb250cmFjdC5zZW5kTWV0aG9kKC4uLmFyZ3MsIGFzc2V0LCBhbW91bnQpO1xuICogIGlmIChyZXN1bHQpIHtcbiAqICAgIG1hcmtQcm9jZXNzZWQoQmxvY2tjaGFpbi5jdXJyZW50VHJhbnNhY3Rpb24uaGFzaCk7XG4gKiAgICBtYXJrQ2xhaW1lZChCbG9ja2NoYWluLmN1cnJlbnRUcmFuc2FjdGlvbi5oYXNoLCByZWNlaXZlcik7XG4gKiAgfVxuICogIHJldHVybiByZXN1bHQ7XG4gKiB9XG4gKlxuICogLy8gQ29tcGxldGluZyBhIHBlbmRpbmcgc2VuZCBmdWxseSBjb25zdW1lcyB0aGUgZmlyc3Qgb3V0cHV0IG9mIGNsYWltZWQgdHJhbnNhY3Rpb24ocykuXG4gKiAvLyBObyBhZGRpdGlvbmFsIHRyYWNraW5nIHJlcXVpcmVkIHNpbmNlIG91dHB1dHMgY2FuIG9ubHkgYmUgdXNlZCBvbmNlLlxuICogY29uc3QgY29tcGxldGVTZW5kID0gKCkgPT4ge1xuICogIGNvbnN0IGhhc2ggPSBnZXRTZW50QXNzZXRzVHJhbnNhY3Rpb25IYXNoKCk7XG4gKiAgaWYgKGhhc2ggPT09IHVuZGVmaW5lZCkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgY29uc3QgcmVjZWl2ZXIgPSBnZXRDbGFpbWVkKGhhc2gpO1xuICogIGlmIChyZWNlaXZlciA9PT0gdW5kZWZpbmVkKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBpZiAoIUFkZHJlc3MuaXNDYWxsZXIocmVjZWl2ZXIpKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBpZiAoYW55T3RoZXJSZWZlcmVuY2VGcm9tQ29udHJhY3QoKSkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgcmV0dXJuIHRydWU7XG4gKiB9XG4gKlxuICogY29uc3QgaGFuZGxlU2VuZFVuc2FmZSA9ICgpID0+IHtcbiAqICBpZiAoaXNQcm9jZXNzZWQoQmxvY2tjaGFpbi5jdXJyZW50VHJhbnNhY3Rpb24uaGFzaCkpIHtcbiAqICAgIHJldHVybiBmYWxzZTtcbiAqICB9XG4gKlxuICogIGlmICghaXNSZWNlaXZlTWV0aG9kKCkgJiYgIW9ubHlTZW50QXNzZXRzKCkpIHtcbiAqICAgIHJldHVybiBmYWxzZTtcbiAqICB9XG4gKlxuICogIGNvbnN0IGFyZ3MgPSBnZXRBcmd1bWVudCgxKTtcbiAqICBjb25zdCByZXN1bHQgPSBjb250cmFjdC5zZW5kVW5zYWZlTWV0aG9kKC4uLmFyZ3MpO1xuICogIGlmIChyZXN1bHQpIHtcbiAqICAgIG1hcmtQcm9jZXNzZWQoQmxvY2tjaGFpbi5jdXJyZW50VHJhbnNhY3Rpb24uaGFzaCk7XG4gKiAgfVxuICogIHJldHVybiByZXN1bHQ7XG4gKiB9XG4gKlxuICogY29uc3QgaGFuZGxlUmVjZWl2ZSA9ICgpID0+IHtcbiAqICBpZiAoaXNQcm9jZXNzZWQoQmxvY2tjaGFpbi5jdXJyZW50VHJhbnNhY3Rpb24uaGFzaCkpIHtcbiAqICAgIHJldHVybiBmYWxzZTtcbiAqICB9XG4gKlxuICogIGlmICghaXNTZW5kVW5zYWZlTWV0aG9kKCkgJiYgIW9ubHlSZWNlaXZlZEFzc2V0cygpKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBjb25zdCBhcmdzID0gZ2V0QXJndW1lbnQoMSk7XG4gKiAgY29uc3QgcmVzdWx0ID0gY29udHJhY3QucmVjZWl2ZU1ldGhvZCguLi5hcmdzKTtcbiAqICBpZiAocmVzdWx0KSB7XG4gKiAgICBtYXJrUHJvY2Vzc2VkKEJsb2NrY2hhaW4uY3VycmVudFRyYW5zYWN0aW9uLmhhc2gpO1xuICogIH1cbiAqICByZXR1cm4gcmVzdWx0O1xuICogfVxuICpcbiAqIC8vIFJlZnVuZHMgZnVsbHkgY29uc3VtZSB0aGUgb3V0cHV0cyBvZiBhbiB1bnByb2Nlc3NlZCB0cmFuc2FjdGlvbiwgd2hpY2ggbWVhbnNcbiAqIC8vIHdlIGRvbid0IGhhdmUgdG8gZG8gYW55IGFkZGl0aW9uYWwgdHJhY2tpbmcgc2luY2Ugb3V0cHV0cyBjYW4gb25seSBiZSB1c2VkIG9uY2UuXG4gKiBjb25zdCBoYW5kbGVSZWZ1bmQgPSAoKSA9PiB7XG4gKiAgY29uc3QgaGFzaCA9IGdldFNlbnRBc3NldHNUcmFuc2FjdGlvbkhhc2goKTtcbiAqICBpZiAoaGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gKiAgICByZXR1cm4gZmFsc2U7XG4gKiAgfVxuICpcbiAqICBpZiAoaXNQcm9jZXNzZWQoaGFzaCkpIHtcbiAqICAgIHJldHVybiBmYWxzZTtcbiAqICB9XG4gKlxuICogIGlmICghZ2V0VHJhbnNhY3Rpb25SZWZlcmVuY2VzKGhhc2gpLmV2ZXJ5KChvdXRwdXQpID0+IEFkZHJlc3MuaXNDYWxsZXIob3V0cHV0LnNjcmlwdEhhc2gpKSkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgcmV0dXJuIHRydWU7XG4gKiB9XG4gKlxuICogY29uc3QgaGFuZGxlTm9ybWFsID0gKCkgPT4ge1xuICogIGNvbnN0IGFyZ3MgPSBnZXRBcmd1bWVudCgxKTtcbiAqICByZXR1cm4gY29udHJhY3Qubm9ybWFsTWV0aG9kKC4uLmFyZ3MpO1xuICogfVxuICpcbiAqIGNvbnN0IGhhbmRsZVVwZ3JhZGUgPSAoKSA9PiB7XG4gKiAgaWYgKGNvbnRyYWN0LmFwcHJvdmVVcGdyYWRlKCkpIHtcbiAqICAgIGNvbnN0IGFyZ3MgPSBnZXRBcmd1bWVudCgxKTtcbiAqICAgIE5lby5Db250cmFjdC5NaWdyYXRlKC4uLmFyZ3MpO1xuICogICAgcmV0dXJuIHRydWU7XG4gKiAgfVxuICogIHJldHVybiBmYWxzZTtcbiAqIH1cbiAqXG4gKiBjb25zdCBoYW5kbGVEZXBsb3kgPSAoKSA9PiB7XG4gKiAgaWYgKGlzRGVwbG95ZWQoKSkge1xuICogICAgcmV0dXJuIGZhbHNlO1xuICogIH1cbiAqXG4gKiAgY29udHJhY3QuZGVwbG95KC4uLmdldEFyZ3VtZW50KDEpKTtcbiAqICBzZXREZXBsb3llZCh0cnVlKTtcbiAqICByZXR1cm4gdHJ1ZTtcbiAqIH1cbiAqXG4gKiBjb25zdCBoYW5kbGVDbGFpbSA9ICgpID0+IHtcbiAqICByZXR1cm4gY29udHJhY3QuY2xhaW1NZXRob2QoLi4uZ2V0QXJndW1lbnQoMSksIFN5c3RlbS5FeGVjdXRpb25FbmdpbmVyLkdldFNjcmlwdENvbnRhaW5lcigpKTtcbiAqIH1cbiAqXG4gKiBjb25zdCB0cmlnZ2VyID0gTmVvLlJ1bnRpbWUuR2V0VHJpZ2dlcigpXG4gKiBpZiAodHJpZ2dlciA9PT0gVHJpZ2dlclR5cGUuQXBwbGljYXRpb24pIHtcbiAqICBjb25zdCBtZXRob2QgPSBnZXRBcmd1bWVudCgwKTtcbiAqICBzd2l0Y2ggKG1ldGhvZCkge1xuICogICAgY2FzZSAnbm9ybWFsTWV0aG9kJzpcbiAqICAgICAgcmV0dXJuIGhhbmRsZU5vcm1hbE1ldGhvZCgpO1xuICogICAgY2FzZSAnc2VuZE1ldGhvZCc6XG4gKiAgICAgIHJldHVybiBoYW5kbGVTZW5kKCk7XG4gKiAgICBjYXNlICdzZW5kVW5zYWZlTWV0aG9kJzpcbiAqICAgICAgcmV0dXJuIGhhbmRsZVNlbmRVbnNhZmUoKTtcbiAqICAgIGNhc2UgJ3JlY2VpdmVNZXRob2QnOlxuICogICAgICByZXR1cm4gaGFuZGxlUmVjZWl2ZSgpO1xuICogICAgY2FzZSAndXBncmFkZSc6XG4gKiAgICAgIHJldHVybiBoYW5kbGVVcGdyYWRlKCk7XG4gKiAgICBjYXNlICdyZWZ1bmRBc3NldHMnOlxuICogICAgICByZXR1cm4gaGFuZGxlUmVmdW5kKCk7XG4gKiAgICBjYXNlICdjb21wbGV0ZVNlbmQnOlxuICogICAgICByZXR1cm4gaGFuZGxlQ29tcGxldGVTZW5kKCk7XG4gKiAgICBjYXNlICdkZXBsb3knOlxuICogICAgICByZXR1cm4gaGFuZGxlRGVwbG95KCk7XG4gKiAgICBkZWZhdWx0OlxuICogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbWV0aG9kJyk7XG4gKiB9IGVsc2UgaWYgKHRyaWdnZXIgPT09IFRyaWdnZXJUeXBlLlZlcmlmaWNhdGlvbikge1xuICogIGNvbnN0IHRyYW5zYWN0aW9uID0gU3lzdGVtLkV4ZWN1dGlvbkVuZ2luZXIuR2V0U2NyaXB0Q29udGFpbmVyKCk7XG4gKiAgaWYgKHRyYW5zYWN0aW9uLnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5JbnZvY2F0aW9uKSB7XG4gKiAgICBjb25zdCBtZXRob2QgPSBnZXRBcmd1bWVudCgwKTtcbiAqICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gKiAgICAgIGNhc2UgJ3NlbmRNZXRob2QnOlxuICogICAgICAgIGlmICghYXBwbGljYXRpb25TY3JpcHRNYXRjaGVzVmVyaWZpY2F0aW9uKCkpIHtcbiAqICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAqICAgICAgICB9XG4gKiAgICAgICAgcmV0dXJuIGhhbmRsZVNlbmQoKTtcbiAqICAgICAgY2FzZSAnc2VuZFVuc2FmZU1ldGhvZCc6XG4gKiAgICAgICAgaWYgKCFhcHBsaWNhdGlvblNjcmlwdE1hdGNoZXNWZXJpZmljYXRpb24oKSkge1xuICogICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICogICAgICAgIH1cbiAqICAgICAgICByZXR1cm4gaGFuZGxlU2VuZFVuc2FmZSgpO1xuICogICAgICBjYXNlICdyZWNlaXZlTWV0aG9kJzpcbiAqICAgICAgICBpZiAoIWFwcGxpY2F0aW9uU2NyaXB0TWF0Y2hlc1ZlcmlmaWNhdGlvbigpKSB7XG4gKiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gKiAgICAgICAgfVxuICogICAgICAgIHJldHVybiBoYW5kbGVSZWNlaXZlKCk7XG4gKiAgICAgIGNhc2UgJ2NvbXBsZXRlU2VuZCc6XG4gKiAgICAgICAgcmV0dXJuIGhhbmRsZUNvbXBsZXRlU2VuZCgpO1xuICogICAgICBkZWZhdWx0OlxuICogICAgICAgIGlmIChkaWRTZW5kQXNzZXRzKCkgfHwgZGlkUmVjZWl2ZUFzc2V0cygpKSB7XG4gKiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAqICAgICAgICB9XG4gKiAgICAgICAgcmV0dXJuIGhhbmRsZU90aGVyKCk7XG4gKiAgICB9XG4gKiAgfSBlbHNlIGlmICh0cmFuc2FjdGlvbi50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuQ2xhaW0pIHtcbiAqICAgIGlmIChkaWRTZW5kQXNzZXRzKCkgfHwgZGlkUmVjZWl2ZU5vbkNsYWltQXNzZXRzKCkpIHtcbiAqICAgICAgcmV0dXJuIGZhbHNlO1xuICogICAgfVxuICogICAgY29uc3QgbWV0aG9kID0gZ2V0QXJndW1lbnQoMCk7XG4gKiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICogICAgICBjYXNlICdjbGFpbU1ldGhvZCc6XG4gKiAgICAgICAgcmV0dXJuIGhhbmRsZUNsYWltKCk7XG4gKiAgICAgIGRlZmF1bHQ6XG4gKiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gKiAgICB9IGVsc2Uge1xuICogICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAqICAgIH1cbiAqICB9IGVsc2Uge1xuICogICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gKiAgfVxuICogfVxuICpcbiAqL1xuXG4vLyBJbnB1dDogW11cbi8vIE91dHB1dDogW11cbmV4cG9ydCBjbGFzcyBJbnZva2VTbWFydENvbnRyYWN0SGVscGVyIGV4dGVuZHMgSGVscGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBjb250cmFjdEluZm86IENvbnRyYWN0SW5mbztcblxuICBwdWJsaWMgY29uc3RydWN0b3IoeyBjb250cmFjdEluZm8gfTogSW52b2tlU21hcnRDb250cmFjdEhlbHBlck9wdGlvbnMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuY29udHJhY3RJbmZvID0gY29udHJhY3RJbmZvO1xuICB9XG5cbiAgcHVibGljIGVtaXQoc2I6IFNjcmlwdEJ1aWxkZXIsIG5vZGU6IHRzLk5vZGUsIG9wdGlvbnNJbjogVmlzaXRPcHRpb25zKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHNiLnB1c2hWYWx1ZU9wdGlvbnMob3B0aW9uc0luKTtcblxuICAgIGNvbnN0IGdldENhc2VCYXNlID0gKGRlY2w6IHRzLk5vZGUsIG5hbWU6IHN0cmluZywgd2hlblRydWU6ICgpID0+IHZvaWQpID0+ICh7XG4gICAgICBjb25kaXRpb246ICgpID0+IHtcbiAgICAgICAgLy8gW2FyZywgYXJnXVxuICAgICAgICBzYi5lbWl0T3AoZGVjbCwgJ0RVUCcpO1xuICAgICAgICAvLyBbc3RyaW5nLCBhcmcsIGFyZ11cbiAgICAgICAgc2IuZW1pdFB1c2hTdHJpbmcoZGVjbCwgbmFtZSk7XG4gICAgICAgIC8vIFtib29sZWFuLCBhcmddXG4gICAgICAgIHNiLmVtaXRPcChkZWNsLCAnRVFVQUwnKTtcbiAgICAgIH0sXG4gICAgICB3aGVuVHJ1ZTogKCkgPT4ge1xuICAgICAgICAvLyBbXVxuICAgICAgICBzYi5lbWl0T3AoZGVjbCwgJ0RST1AnKTtcbiAgICAgICAgd2hlblRydWUoKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBnZXRGdW5jdGlvbkNhc2UgPSAocHJvcEluZm86IEZ1bmN0aW9uUHJvcEluZm8pID0+XG4gICAgICBnZXRDYXNlQmFzZShwcm9wSW5mby5kZWNsLCBwcm9wSW5mby5uYW1lLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlY2wgPSBwcm9wSW5mby5kZWNsO1xuICAgICAgICBpZiAodHMuaXNQcm9wZXJ0eURlY2xhcmF0aW9uKGRlY2wpKSB7XG4gICAgICAgICAgc2IuY29udGV4dC5yZXBvcnRVbnN1cHBvcnRlZChkZWNsKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wSW5mby5zZW5kKSB7XG4gICAgICAgICAgc2IuZW1pdEhlbHBlcihkZWNsLCBvcHRpb25zLCBzYi5oZWxwZXJzLmhhbmRsZVNlbmQoeyBtZXRob2Q6IGRlY2wsIHJldHVyblR5cGU6IHByb3BJbmZvLnJldHVyblR5cGUgfSkpO1xuICAgICAgICB9IGVsc2UgaWYgKHByb3BJbmZvLnJlY2VpdmUpIHtcbiAgICAgICAgICBzYi5lbWl0SGVscGVyKFxuICAgICAgICAgICAgZGVjbCxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICBzYi5oZWxwZXJzLmhhbmRsZVJlY2VpdmUoeyBvcHBvc2l0ZTogcHJvcEluZm8uc2VuZFVuc2FmZSwgbWV0aG9kOiBkZWNsLCByZXR1cm5UeXBlOiBwcm9wSW5mby5yZXR1cm5UeXBlIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvcEluZm8uc2VuZFVuc2FmZSkge1xuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoXG4gICAgICAgICAgICBkZWNsLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHNiLmhlbHBlcnMuaGFuZGxlU2VuZFVuc2FmZSh7IG9wcG9zaXRlOiBwcm9wSW5mby5yZWNlaXZlLCBtZXRob2Q6IGRlY2wsIHJldHVyblR5cGU6IHByb3BJbmZvLnJldHVyblR5cGUgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzYi5lbWl0SGVscGVyKGRlY2wsIG9wdGlvbnMsIHNiLmhlbHBlcnMuaGFuZGxlTm9ybWFsKHsgcHJvcEluZm8gfSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGdldERlcGxveUNhc2UgPSAoY29udHJhY3RJbmZvOiBDb250cmFjdEluZm8sIHByb3BJbmZvOiBEZXBsb3lQcm9wSW5mbykgPT4ge1xuICAgICAgY29uc3QgZGVjbCA9IHByb3BJbmZvLmRlY2wgPT09IHVuZGVmaW5lZCA/IHByb3BJbmZvLmNsYXNzRGVjbCA6IHByb3BJbmZvLmRlY2w7XG5cbiAgICAgIHJldHVybiBnZXRDYXNlQmFzZShkZWNsLCBwcm9wSW5mby5uYW1lLCAoKSA9PiB7XG4gICAgICAgIHNiLmVtaXRIZWxwZXIoZGVjbCwgb3B0aW9ucywgc2IuaGVscGVycy5kZXBsb3koeyBjb250cmFjdEluZm8sIHByb3BJbmZvIH0pKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBjb25zdCBnZXRQcm9wZXJ0eUNhc2UgPSAocHJvcEluZm86IFByb3BlcnR5UHJvcEluZm8pID0+IHtcbiAgICAgIGNvbnN0IGRlY2wgPSBwcm9wSW5mby5kZWNsO1xuXG4gICAgICByZXR1cm4gZ2V0Q2FzZUJhc2UoZGVjbCwgcHJvcEluZm8ubmFtZSwgKCkgPT4ge1xuICAgICAgICBzYi5lbWl0SGVscGVyKGRlY2wsIG9wdGlvbnMsIHNiLmhlbHBlcnMuaGFuZGxlTm9ybWFsKHsgcHJvcEluZm8gfSkpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGdldEFjY2Vzc29yQ2FzZSA9IChwcm9wSW5mbzogQWNjZXNzb3JQcm9wSW5mbykgPT4ge1xuICAgICAgY29uc3QgbXV0YWJsZUNhc2VzOiBDYXNlW10gPSBbXTtcbiAgICAgIGNvbnN0IGdldHRlciA9IHByb3BJbmZvLmdldHRlcjtcblxuICAgICAgaWYgKGdldHRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG11dGFibGVDYXNlcy5wdXNoKFxuICAgICAgICAgIGdldENhc2VCYXNlKGdldHRlci5kZWNsLCBnZXR0ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihnZXR0ZXIuZGVjbCwgb3B0aW9ucywgc2IuaGVscGVycy5oYW5kbGVOb3JtYWwoeyBwcm9wSW5mbywgZ2V0dGVyOiB0cnVlIH0pKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2V0dGVyID0gcHJvcEluZm8uc2V0dGVyO1xuICAgICAgaWYgKHNldHRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG11dGFibGVDYXNlcy5wdXNoKFxuICAgICAgICAgIGdldENhc2VCYXNlKHNldHRlci5kZWNsLCBzZXR0ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihzZXR0ZXIuZGVjbCwgb3B0aW9ucywgc2IuaGVscGVycy5oYW5kbGVOb3JtYWwoeyBwcm9wSW5mbywgZ2V0dGVyOiBmYWxzZSB9KSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtdXRhYmxlQ2FzZXM7XG4gICAgfTtcblxuICAgIGNvbnN0IGdldFJlZnVuZEFzc2V0c0Nhc2UgPSAocHJvcEluZm86IFJlZnVuZEFzc2V0c1Byb3BJbmZvKSA9PlxuICAgICAgZ2V0Q2FzZUJhc2Uobm9kZSwgQ29udHJhY3RQcm9wZXJ0eU5hbWUucmVmdW5kQXNzZXRzLCAoKSA9PiB7XG4gICAgICAgIHNiLmVtaXRIZWxwZXIobm9kZSwgb3B0aW9ucywgc2IuaGVscGVycy5oYW5kbGVOb3JtYWwoeyBwcm9wSW5mbyB9KSk7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGdldENvbXBsZXRlU2VuZENhc2UgPSAocHJvcEluZm86IENvbXBsZXRlU2VuZFByb3BJbmZvKSA9PlxuICAgICAgZ2V0Q2FzZUJhc2Uobm9kZSwgQ29udHJhY3RQcm9wZXJ0eU5hbWUuY29tcGxldGVTZW5kLCAoKSA9PiB7XG4gICAgICAgIHNiLmVtaXRIZWxwZXIobm9kZSwgb3B0aW9ucywgc2IuaGVscGVycy5oYW5kbGVOb3JtYWwoeyBwcm9wSW5mbyB9KSk7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGdldFVwZ3JhZGVDYXNlID0gKHByb3BJbmZvOiBVcGdyYWRlUHJvcEluZm8pID0+XG4gICAgICBnZXRDYXNlQmFzZShub2RlLCBDb250cmFjdFByb3BlcnR5TmFtZS51cGdyYWRlLCAoKSA9PiB7XG4gICAgICAgIHNiLmVtaXRIZWxwZXIobm9kZSwgb3B0aW9ucywgc2IuaGVscGVycy5oYW5kbGVOb3JtYWwoeyBwcm9wSW5mbyB9KSk7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGFsbENhc2VzID0gXy5mbGF0dGVuKFxuICAgICAgdGhpcy5jb250cmFjdEluZm8ucHJvcEluZm9zXG4gICAgICAgIC5maWx0ZXIoKHByb3BJbmZvKSA9PiBwcm9wSW5mby5pc1B1YmxpYyAmJiBwcm9wSW5mby50eXBlICE9PSAnZGVwbG95JylcbiAgICAgICAgLm1hcCgocHJvcEluZm8pID0+IHtcbiAgICAgICAgICBpZiAocHJvcEluZm8udHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb3BDYXNlOiBnZXRGdW5jdGlvbkNhc2UocHJvcEluZm8pLFxuICAgICAgICAgICAgICAgIGNsYWltVmVyaWZ5OiBwcm9wSW5mby5jbGFpbSxcbiAgICAgICAgICAgICAgICBpbnZva2VWZXJpZnk6IHByb3BJbmZvLnNlbmQgfHwgcHJvcEluZm8uc2VuZFVuc2FmZSB8fCBwcm9wSW5mby5yZWNlaXZlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocHJvcEluZm8udHlwZSA9PT0gJ3JlZnVuZEFzc2V0cycpIHtcbiAgICAgICAgICAgIHJldHVybiBbeyBwcm9wQ2FzZTogZ2V0UmVmdW5kQXNzZXRzQ2FzZShwcm9wSW5mbyksIGNsYWltVmVyaWZ5OiBmYWxzZSwgaW52b2tlVmVyaWZ5OiB0cnVlIH1dO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwcm9wSW5mby50eXBlID09PSAnY29tcGxldGVTZW5kJykge1xuICAgICAgICAgICAgcmV0dXJuIFt7IHByb3BDYXNlOiBnZXRDb21wbGV0ZVNlbmRDYXNlKHByb3BJbmZvKSwgY2xhaW1WZXJpZnk6IGZhbHNlLCBpbnZva2VWZXJpZnk6IHRydWUgfV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHByb3BJbmZvLnR5cGUgPT09ICdwcm9wZXJ0eScpIHtcbiAgICAgICAgICAgIHJldHVybiBbeyBwcm9wQ2FzZTogZ2V0UHJvcGVydHlDYXNlKHByb3BJbmZvKSwgY2xhaW1WZXJpZnk6IGZhbHNlLCBpbnZva2VWZXJpZnk6IGZhbHNlIH1dO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwcm9wSW5mby50eXBlID09PSAnYWNjZXNzb3InKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0QWNjZXNzb3JDYXNlKHByb3BJbmZvKS5tYXAoKHByb3BDYXNlKSA9PiAoe1xuICAgICAgICAgICAgICBwcm9wQ2FzZSxcbiAgICAgICAgICAgICAgY2xhaW1WZXJpZnk6IGZhbHNlLFxuICAgICAgICAgICAgICBpbnZva2VWZXJpZnk6IGZhbHNlLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwcm9wSW5mby50eXBlID09PSAndXBncmFkZScpIHtcbiAgICAgICAgICAgIHJldHVybiBbeyBwcm9wQ2FzZTogZ2V0VXBncmFkZUNhc2UocHJvcEluZm8pLCBjbGFpbVZlcmlmeTogZmFsc2UsIGludm9rZVZlcmlmeTogZmFsc2UgfV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHByb3BJbmZvLnR5cGUgPT09ICdkZXBsb3knKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvciBUUycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgdXRpbHMuYXNzZXJ0TmV2ZXIocHJvcEluZm8pO1xuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3IgVFMnKTtcbiAgICAgICAgfSksXG4gICAgKTtcbiAgICBsZXQgYXBwbGljYXRpb25DYXNlcyA9IGFsbENhc2VzLmZpbHRlcigocHJvcENhc2UpID0+ICFwcm9wQ2FzZS5jbGFpbVZlcmlmeSkubWFwKCh7IHByb3BDYXNlIH0pID0+IHByb3BDYXNlKTtcbiAgICBjb25zdCBkZXBsb3kgPSBmaW5kRGVwbG95SW5mbyh0aGlzLmNvbnRyYWN0SW5mbyk7XG4gICAgaWYgKGRlcGxveSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhcHBsaWNhdGlvbkNhc2VzID0gYXBwbGljYXRpb25DYXNlcy5jb25jYXQoZ2V0RGVwbG95Q2FzZShkZXBsb3lbMF0sIGRlcGxveVsxXSkpO1xuICAgIH1cbiAgICBjb25zdCBpbnZvY2F0aW9uVmVyaWZ5Q2FzZXMgPSBhbGxDYXNlcy5maWx0ZXIoKHByb3BDYXNlKSA9PiBwcm9wQ2FzZS5pbnZva2VWZXJpZnkpLm1hcCgoeyBwcm9wQ2FzZSB9KSA9PiBwcm9wQ2FzZSk7XG4gICAgY29uc3Qgbm9uVmVyaWZ5Q2FzZXMgPSBhbGxDYXNlcy5maWx0ZXIoKHByb3BDYXNlKSA9PiAhcHJvcENhc2UuaW52b2tlVmVyaWZ5KS5tYXAoKHsgcHJvcENhc2UgfSkgPT4gcHJvcENhc2UpO1xuICAgIGNvbnN0IGNsYWltQ2FzZXMgPSBhbGxDYXNlcy5maWx0ZXIoKHByb3BDYXNlKSA9PiBwcm9wQ2FzZS5jbGFpbVZlcmlmeSkubWFwKCh7IHByb3BDYXNlIH0pID0+IHByb3BDYXNlKTtcblxuICAgIGNvbnN0IHRocm93RGVmYXVsdCA9ICgpID0+IHtcbiAgICAgIHNiLmVtaXRPcChub2RlLCAnRFJPUCcpO1xuICAgICAgc2IuZW1pdE9wKG5vZGUsICdUSFJPVycpO1xuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVJbnZva2VWZXJpZnkgPSAoZnVuYzogKCkgPT4gdm9pZCkgPT4ge1xuICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgbm9kZSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgc2IuaGVscGVycy5pZih7XG4gICAgICAgICAgY29uZGl0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgICAvLyBbYm9vbGVhbl1cbiAgICAgICAgICAgIHNiLmVtaXRIZWxwZXIobm9kZSwgb3B0aW9ucywgc2IuaGVscGVycy5hcHBsaWNhdGlvbk1hdGNoZXNWZXJpZmljYXRpb24pO1xuICAgICAgICAgICAgLy8gW2Jvb2xlYW4sIGJvb2xlYW5dXG4gICAgICAgICAgICBzYi5lbWl0T3Aobm9kZSwgJ0RVUCcpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgd2hlblRydWU6ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFt2YWx1ZSwgYm9vbGVhbl1cbiAgICAgICAgICAgIGZ1bmMoKTtcbiAgICAgICAgICAgIC8vIFtib29sZWFuXVxuICAgICAgICAgICAgc2IuZW1pdE9wKG5vZGUsICdEUk9QJyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVDbGFpbVZlcmlmeSA9IChmdW5jOiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgICAvLyBbdmFsdWVdXG4gICAgICBmdW5jKCk7XG4gICAgICAvLyBbXVxuICAgICAgc2IuZW1pdE9wKG5vZGUsICdEUk9QJyk7XG4gICAgICAvLyBbYm9vbGVhbl1cbiAgICAgIHNiLmVtaXRQdXNoQm9vbGVhbihub2RlLCB0cnVlKTtcbiAgICB9O1xuXG4gICAgY29uc3QgaGFuZGxlRGVmYXVsdEludm9rZVZlcmlmeSA9ICgpID0+IHtcbiAgICAgIC8vIFtdXG4gICAgICBzYi5lbWl0T3Aobm9kZSwgJ0RST1AnKTtcbiAgICAgIC8vIFtib29sZWFuXVxuICAgICAgc2IuZW1pdEhlbHBlcihub2RlLCBvcHRpb25zLCBzYi5oZWxwZXJzLmRpZFJlY2VpdmVBc3NldHMpO1xuICAgICAgLy8gW2Jvb2xlYW4sIGJvb2xlYW5dXG4gICAgICBzYi5lbWl0SGVscGVyKG5vZGUsIG9wdGlvbnMsIHNiLmhlbHBlcnMuZGlkU2VuZEFzc2V0cyk7XG4gICAgICBzYi5lbWl0SGVscGVyKFxuICAgICAgICBub2RlLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICBzYi5oZWxwZXJzLmlmKHtcbiAgICAgICAgICBjb25kaXRpb246ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFtib29sZWFuXVxuICAgICAgICAgICAgc2IuZW1pdE9wKG5vZGUsICdCT09MT1InKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdoZW5UcnVlOiAoKSA9PiB7XG4gICAgICAgICAgICBzYi5lbWl0T3Aobm9kZSwgJ1RIUk9XJyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB3aGVuRmFsc2U6ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFtudW1iZXJdXG4gICAgICAgICAgICBzYi5lbWl0UHVzaEludChub2RlLCAwKTtcbiAgICAgICAgICAgIC8vIFthcmddXG4gICAgICAgICAgICBzYi5lbWl0SGVscGVyKG5vZGUsIG9wdGlvbnMsIHNiLmhlbHBlcnMuZ2V0QXJndW1lbnQpO1xuICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihub2RlLCBvcHRpb25zLCBzYi5oZWxwZXJzLmNhc2Uobm9uVmVyaWZ5Q2FzZXMsIHRocm93RGVmYXVsdCkpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLy8gW251bWJlcl1cbiAgICBzYi5lbWl0U3lzQ2FsbChub2RlLCAnTmVvLlJ1bnRpbWUuR2V0VHJpZ2dlcicpO1xuICAgIHNiLmVtaXRIZWxwZXIoXG4gICAgICBub2RlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHNiLmhlbHBlcnMuY2FzZShcbiAgICAgICAgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBbbnVtYmVyLCBudW1iZXJdXG4gICAgICAgICAgICAgIHNiLmVtaXRPcChub2RlLCAnRFVQJyk7XG4gICAgICAgICAgICAgIC8vIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXVxuICAgICAgICAgICAgICBzYi5lbWl0UHVzaEludChub2RlLCAweDEwKTtcbiAgICAgICAgICAgICAgLy8gW2Jvb2xlYW4sIG51bWJlcl1cbiAgICAgICAgICAgICAgc2IuZW1pdE9wKG5vZGUsICdOVU1FUVVBTCcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdoZW5UcnVlOiAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIFtdXG4gICAgICAgICAgICAgIHNiLmVtaXRPcChub2RlLCAnRFJPUCcpO1xuICAgICAgICAgICAgICAvLyBbbnVtYmVyXVxuICAgICAgICAgICAgICBzYi5lbWl0UHVzaEludChub2RlLCAwKTtcbiAgICAgICAgICAgICAgLy8gW2FyZ11cbiAgICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihub2RlLCBvcHRpb25zLCBzYi5oZWxwZXJzLmdldEFyZ3VtZW50KTtcbiAgICAgICAgICAgICAgLy8gW11cbiAgICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihub2RlLCBvcHRpb25zLCBzYi5oZWxwZXJzLmNhc2UoYXBwbGljYXRpb25DYXNlcywgdGhyb3dEZWZhdWx0KSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgY29uZGl0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIFtudW1iZXIsIG51bWJlcl1cbiAgICAgICAgICAgICAgc2IuZW1pdE9wKG5vZGUsICdEVVAnKTtcbiAgICAgICAgICAgICAgLy8gW251bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICAgICAgICAgICAgIHNiLmVtaXRQdXNoSW50KG5vZGUsIDB4MDApO1xuICAgICAgICAgICAgICAvLyBbYm9vbGVhbiwgbnVtYmVyXVxuICAgICAgICAgICAgICBzYi5lbWl0T3Aobm9kZSwgJ05VTUVRVUFMJyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd2hlblRydWU6ICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gW11cbiAgICAgICAgICAgICAgc2IuZW1pdE9wKG5vZGUsICdEUk9QJyk7XG4gICAgICAgICAgICAgIC8vIFt0cmFuc2FjdGlvbl1cbiAgICAgICAgICAgICAgc2IuZW1pdFN5c0NhbGwobm9kZSwgJ1N5c3RlbS5FeGVjdXRpb25FbmdpbmUuR2V0U2NyaXB0Q29udGFpbmVyJyk7XG4gICAgICAgICAgICAgIC8vIFt0eXBlXVxuICAgICAgICAgICAgICBzYi5lbWl0U3lzQ2FsbChub2RlLCAnTmVvLlRyYW5zYWN0aW9uLkdldFR5cGUnKTtcbiAgICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICAgICAgc2IuaGVscGVycy5jYXNlKFxuICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBbdHlwZSwgdHlwZV1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRPcChub2RlLCAnRFVQJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBbbnVtYmVyLCB0eXBlLCB0eXBlXVxuICAgICAgICAgICAgICAgICAgICAgICAgc2IuZW1pdFB1c2hJbnQobm9kZSwgVHJhbnNhY3Rpb25UeXBlLkludm9jYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW2Jvb2xlYW4sIHR5cGVdXG4gICAgICAgICAgICAgICAgICAgICAgICBzYi5lbWl0T3Aobm9kZSwgJ05VTUVRVUFMJyk7XG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICB3aGVuVHJ1ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW11cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRPcChub2RlLCAnRFJPUCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW251bWJlcl1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRQdXNoSW50KG5vZGUsIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW2FyZ11cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRIZWxwZXIobm9kZSwgb3B0aW9ucywgc2IuaGVscGVycy5nZXRBcmd1bWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuaGVscGVycy5jYXNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludm9jYXRpb25WZXJpZnlDYXNlcy5tYXAoKHByb3BDYXNlKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucHJvcENhc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVuVHJ1ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVJbnZva2VWZXJpZnkocHJvcENhc2Uud2hlblRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlRGVmYXVsdEludm9rZVZlcmlmeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbjogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW3R5cGUsIHR5cGVdXG4gICAgICAgICAgICAgICAgICAgICAgICBzYi5lbWl0T3Aobm9kZSwgJ0RVUCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gW251bWJlciwgdHlwZSwgdHlwZV1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRQdXNoSW50KG5vZGUsIFRyYW5zYWN0aW9uVHlwZS5DbGFpbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBbYm9vbGVhbiwgdHlwZV1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmVtaXRPcChub2RlLCAnTlVNRVFVQUwnKTtcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIC