UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

394 lines (393 loc) 66.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const client_common_1 = require("@neo-one/client-common"); const ts_utils_1 = require("@neo-one/ts-utils"); const utils_1 = require("@neo-one/utils"); const typescript_1 = tslib_1.__importDefault(require("typescript")); const types_1 = require("../compile/helper/types"); const DiagnosticCode_1 = require("../DiagnosticCode"); const DiagnosticMessage_1 = require("../DiagnosticMessage"); const utils_2 = require("../utils"); exports.DEFAULT_DIAGNOSTIC_OPTIONS = { error: true, warning: false, }; class AnalysisService { constructor(context) { this.context = context; this.memoized = utils_2.createMemoized(); } getFunctionReturnType(node, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { if (typescript_1.default.isAccessor(node)) { return this.getType(node); } const typeNode = ts_utils_1.tsUtils.type_.getTypeNode(node); if (typeNode !== undefined) { return this.getNotAnyType(typeNode, ts_utils_1.tsUtils.type_.getTypeFromTypeNode(this.context.typeChecker, typeNode)); } const signatureTypes = this.extractSignature(node, options); return signatureTypes === undefined ? undefined : signatureTypes.returnType; } extractAllSignatures(node, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { return this.extractAllSignaturesForType(node, this.getType(node), options); } extractSignature(node, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { return this.extractSignatureForType(node, this.getType(node), options); } getSignatures(node) { const signature = this.context.typeChecker.getResolvedSignature(node); if (signature !== undefined && !ts_utils_1.tsUtils.signature.isFailure(signature)) { return [signature]; } const expr = ts_utils_1.tsUtils.expression.getExpressionForCall(node); const type = this.getType(expr); if (type === undefined) { return undefined; } return ts_utils_1.tsUtils.type_.getCallSignatures(type); } extractAllSignaturesForType(node, type, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { const signatures = type === undefined ? undefined : ts_utils_1.tsUtils.type_.getCallSignatures(type); if (signatures === undefined) { return []; } return signatures.map((signature) => this.extractSignatureTypes(node, signature, options)).filter(utils_1.utils.notNull); } extractSignatureForType(node, type, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { const signatureTypes = this.extractAllSignaturesForType(node, type, options); if (signatureTypes.length === 0) { return undefined; } if (signatureTypes.length !== 1) { this.report(options, node, DiagnosticCode_1.DiagnosticCode.MultipleSignatures, DiagnosticMessage_1.DiagnosticMessage.MultipleSignatures); return undefined; } return signatureTypes[0]; } extractSignaturesForCall(node, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { const signatures = this.getSignatures(node); if (signatures === undefined) { return undefined; } return signatures.map((signature) => this.extractSignatureTypes(node, signature, options)).filter(utils_1.utils.notNull); } extractSignatureTypes(node, signature, options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) { const params = ts_utils_1.tsUtils.signature.getParameters(signature); const paramTypes = params.map((param) => this.getTypeOfSymbol(param, node)); const paramDeclsNullable = params.map((param) => ts_utils_1.tsUtils.symbol.getValueDeclaration(param)); const nullParamIndex = paramDeclsNullable.indexOf(undefined); if (nullParamIndex !== -1) { const nullParam = params[nullParamIndex]; this.report(options, node, DiagnosticCode_1.DiagnosticCode.Invariant, DiagnosticMessage_1.DiagnosticMessage.MissingParameterDeclaration, ts_utils_1.tsUtils.symbol.getName(nullParam)); return undefined; } const paramDecls = paramDeclsNullable.filter(utils_1.utils.notNull).filter(typescript_1.default.isParameter); const declToType = new Map(); for (const [paramDecl, paramType] of utils_1.utils.zip(paramDecls, paramTypes)) { declToType.set(paramDecl, paramType); } return { paramDecls, paramTypes: declToType, returnType: this.getNotAnyType(node, ts_utils_1.tsUtils.signature.getReturnType(signature)), }; } extractLiteralAddress(original) { return this.memoized('extract-literal-address', utils_2.nodeKey(original), () => this.extractLiteral(original, 'AddressConstructor', (value) => { try { return client_common_1.common.stringToUInt160(client_common_1.addressToScriptHash(value)); } catch (_a) { return client_common_1.common.stringToUInt160(value); } }, client_common_1.common.bufferToUInt160)); } extractLiteralHash256(original) { return this.extractLiteral(original, 'Hash256Constructor', client_common_1.common.stringToUInt256, client_common_1.common.bufferToUInt256); } extractLiteralPublicKey(original) { return this.extractLiteral(original, 'PublicKeyConstructor', client_common_1.common.stringToECPoint, client_common_1.common.bufferToECPoint); } getType(node, options = {}) { return this.memoized('get-type', utils_2.nodeKey(node), () => this.getNotAnyType(node, ts_utils_1.tsUtils.type_.getType(this.context.typeChecker, node), options)); } getTypeOfSymbol(symbol, node) { if (symbol === undefined) { return undefined; } return this.memoized('get-type-of-symbol', `${ts_utils_1.symbolKey(symbol)}:${utils_2.nodeKey(node)}`, () => this.getNotAnyType(node, ts_utils_1.tsUtils.type_.getTypeAtLocation(this.context.typeChecker, symbol, node))); } getSymbol(node) { return this.memoized('symbol', utils_2.nodeKey(node), () => { const symbol = ts_utils_1.tsUtils.node.getSymbol(this.context.typeChecker, node); if (symbol === undefined) { return undefined; } const aliased = ts_utils_1.tsUtils.symbol.getAliasedSymbol(this.context.typeChecker, symbol); if (aliased !== undefined) { return aliased; } return symbol; }); } getTypeSymbol(node) { return this.memoized('get-type-symbol', utils_2.nodeKey(node), () => { const type = this.getType(node); return this.getSymbolForType(node, type); }); } getSymbolForType(_node, type) { if (type === undefined) { return undefined; } return this.memoized('get-symbol-for-type', utils_2.typeKey(type), () => { let symbol = ts_utils_1.tsUtils.type_.getAliasSymbol(type); if (symbol === undefined) { symbol = ts_utils_1.tsUtils.type_.getSymbol(type); } if (symbol === undefined) { return undefined; } const aliased = ts_utils_1.tsUtils.symbol.getAliasedSymbol(this.context.typeChecker, symbol); if (aliased !== undefined) { return aliased; } return symbol; }); } getNotAnyType(node, type, { error = true } = {}) { if (type !== undefined && ts_utils_1.tsUtils.type_.isAny(type)) { if (error && !ts_utils_1.tsUtils.type_.isErrorType(type)) { this.context.reportTypeError(node); } return undefined; } if (type !== undefined) { const constraintType = ts_utils_1.tsUtils.type_.getConstraint(type); if (constraintType !== undefined) { return constraintType; } } return type; } extractStorageKey(node) { return this.memoized('extract-storage-key', utils_2.nodeKey(node), () => { const smartContract = ts_utils_1.tsUtils.node.getFirstAncestorByTest(node, typescript_1.default.isClassDeclaration); if (smartContract === undefined || !this.isSmartContract(smartContract)) { return undefined; } const decl = ts_utils_1.tsUtils.node.getFirstAncestorByTest(node, typescript_1.default.isPropertyDeclaration); if (decl === undefined) { return undefined; } return ts_utils_1.tsUtils.node.getName(decl); }); } isSmartContract(node) { return this.memoized('is-smart-contract', utils_2.nodeKey(node), () => { const extendsExpr = ts_utils_1.tsUtils.class_.getExtends(node); const isSmartContract = extendsExpr !== undefined && this.context.builtins.isValue(ts_utils_1.tsUtils.expression.getExpression(extendsExpr), 'SmartContract'); if (isSmartContract) { return true; } const baseClasses = ts_utils_1.tsUtils.class_.getBaseClasses(this.context.typeChecker, node); if (baseClasses.some((value) => this.context.builtins.isValue(value, 'SmartContract'))) { return true; } const baseClass = ts_utils_1.tsUtils.class_.getBaseClass(this.context.typeChecker, node); return baseClass !== undefined && this.isSmartContract(baseClass); }); } isSmartContractNode(node) { return this.memoized('is-smart-contract-node', utils_2.nodeKey(node), () => { const symbol = this.getSymbol(node); if (symbol === undefined) { return false; } const decls = ts_utils_1.tsUtils.symbol.getDeclarations(symbol); if (decls.length === 0) { return false; } const decl = decls[0]; return typescript_1.default.isClassDeclaration(decl) && this.isSmartContract(decl); }); } getSymbolAndAllInheritedSymbols(node) { return this.memoized('get-symbol-and-all-inherited-symbols', utils_2.nodeKey(node), () => { const symbol = this.getSymbol(node); const symbols = [symbol].filter(utils_1.utils.notNull); if (typescript_1.default.isClassDeclaration(node) || typescript_1.default.isClassExpression(node) || typescript_1.default.isInterfaceDeclaration(node)) { const baseTypes = ts_utils_1.tsUtils.class_.getBaseTypesFlattened(this.context.typeChecker, node); return symbols.concat(baseTypes.map((baseType) => this.getSymbolForType(node, baseType)).filter(utils_1.utils.notNull)); } return symbols; }); } isValidStorageType(node, type) { return !ts_utils_1.tsUtils.type_.hasType(type, (tpe) => !ts_utils_1.tsUtils.type_.isOnlyType(tpe, (tp) => types_1.isOnlyUndefined(this.context, node, tp) || types_1.isOnlyNull(this.context, node, tp) || types_1.isOnlyBoolean(this.context, node, tp) || types_1.isOnlyNumber(this.context, node, tp) || types_1.isOnlyString(this.context, node, tp) || types_1.isOnlySymbol(this.context, node, tp) || types_1.isOnlyBuffer(this.context, node, tp) || this.isValidStorageArray(node, tp) || this.isValidStorageMap(node, tp) || this.isValidStorageSet(node, tp))); } findReferencesAsNodes(node) { return this.memoized('find-references-as-nodes', utils_2.nodeKey(node), () => ts_utils_1.tsUtils.reference .findReferencesAsNodes(this.context.program, this.context.languageService, node) .filter((found) => this.context.sourceFiles.has(ts_utils_1.tsUtils.node.getSourceFile(found)))); } isSmartContractMixinFunction(node) { const parameters = ts_utils_1.tsUtils.parametered.getParameters(node); if (parameters.length !== 1) { return false; } const signatureTypess = this.extractAllSignatures(node); if (signatureTypess.length !== 1) { return false; } const signatureTypes = signatureTypess[0]; const firstParam = signatureTypes.paramDecls[0]; const firstParamType = signatureTypes.paramTypes.get(firstParam); if (firstParamType === undefined || ts_utils_1.tsUtils.type_.getConstructSignatures(firstParamType).length !== 1) { return false; } const constructSignatureTypes = this.extractSignatureTypes(firstParam, ts_utils_1.tsUtils.type_.getConstructSignatures(firstParamType)[0]); if (constructSignatureTypes === undefined) { return false; } const returnTypeSymbol = this.getSymbolForType(firstParam, constructSignatureTypes.returnType); return returnTypeSymbol !== undefined && returnTypeSymbol === this.context.builtins.getValueSymbol('SmartContract'); } isValidStorageArray(node, type) { if (!types_1.isOnlyArray(this.context, node, type)) { return false; } const typeArguments = ts_utils_1.tsUtils.type_.getTypeArgumentsArray(type); if (typeArguments.length !== 1) { return true; } return this.isValidStorageType(node, typeArguments[0]); } isValidStorageMap(node, type) { if (!types_1.isOnlyMap(this.context, node, type)) { return false; } const typeArguments = ts_utils_1.tsUtils.type_.getTypeArgumentsArray(type); if (typeArguments.length !== 2) { return true; } return this.isValidStorageType(node, typeArguments[0]) && this.isValidStorageType(node, typeArguments[1]); } isValidStorageSet(node, type) { if (!types_1.isOnlySet(this.context, node, type)) { return false; } const typeArguments = ts_utils_1.tsUtils.type_.getTypeArgumentsArray(type); if (typeArguments.length !== 1) { return true; } return this.isValidStorageType(node, typeArguments[0]); } extractLiteral(original, name, processText, processBuffer) { return this.traceIdentifier(original, (node) => { if (!typescript_1.default.isCallExpression(node) && !typescript_1.default.isTaggedTemplateExpression(node)) { return undefined; } const expr = typescript_1.default.isCallExpression(node) ? ts_utils_1.tsUtils.expression.getExpression(node) : ts_utils_1.tsUtils.template.getTag(node); const symbol = this.getSymbol(expr); const hash256From = this.context.builtins.getOnlyMemberSymbol(name, 'from'); const bufferFrom = this.context.builtins.getOnlyMemberSymbol('BufferConstructor', 'from'); if (symbol === hash256From) { const arg = typescript_1.default.isCallExpression(node) ? ts_utils_1.tsUtils.argumented.getArguments(node)[0] : ts_utils_1.tsUtils.template.getTemplate(node); if (typescript_1.default.isTaggedTemplateExpression(node) && !typescript_1.default.isNoSubstitutionTemplateLiteral(ts_utils_1.tsUtils.template.getTemplate(node))) { return undefined; } if (arg === undefined) { return undefined; } return this.traceIdentifier(arg, (value) => { if (typescript_1.default.isStringLiteral(value) || typescript_1.default.isNoSubstitutionTemplateLiteral(value)) { try { return processText(ts_utils_1.tsUtils.literal.getLiteralValue(value)); } catch (_a) { } } return undefined; }); } if (symbol === bufferFrom && typescript_1.default.isCallExpression(node)) { const arg = ts_utils_1.tsUtils.argumented.getArguments(node)[0]; if (arg === undefined) { return undefined; } return this.traceIdentifier(arg, (value) => { if (!typescript_1.default.isStringLiteral(value)) { return undefined; } try { return processBuffer(Buffer.from(ts_utils_1.tsUtils.literal.getLiteralValue(value), 'hex')); } catch (_a) { return undefined; } }); } return undefined; }); } traceIdentifier(nodeIn, extractValue) { const node = this.unwrapExpression(nodeIn); if (typescript_1.default.isIdentifier(node)) { const symbol = this.getSymbol(node); if (symbol === undefined) { return undefined; } const decl = ts_utils_1.tsUtils.symbol.getValueDeclaration(symbol); if (decl === undefined) { return undefined; } if (!typescript_1.default.isVariableDeclaration(decl)) { return undefined; } const parent = ts_utils_1.tsUtils.node.getParent(decl); if (!typescript_1.default.isVariableDeclarationList(parent) || !ts_utils_1.tsUtils.modifier.isConst(parent)) { return undefined; } const initializer = ts_utils_1.tsUtils.initializer.getInitializer(parent); if (initializer === undefined) { return undefined; } return this.traceIdentifier(initializer, extractValue); } return extractValue(node); } unwrapExpression(node) { if (typescript_1.default.isParenthesizedExpression(node)) { return ts_utils_1.tsUtils.expression.getExpression(node); } if (typescript_1.default.isAsExpression(node)) { return ts_utils_1.tsUtils.expression.getExpression(node); } return node; } report(options, node, code, message, ...args) { if (options.error) { this.context.reportError(node, code, message, ...args); } else if (options.warning) { this.context.reportWarning(node, code, message, ...args); } } } exports.AnalysisService = AnalysisService; //# sourceMappingURL=data:application/json;charset=utf8;base64,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LENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0QsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFO2dCQUM3QixPQUFPLFNBQVMsQ0FBQzthQUNsQjtZQUVELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDeEQ7UUFFRCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsSUFBbUI7UUFDMUMsSUFBSSxvQkFBRSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3RDLE9BQU8sa0JBQU8sQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQy9DO1FBRUQsSUFBSSxvQkFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUMzQixPQUFPLGtCQUFPLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUMvQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLE1BQU0sQ0FDWixPQUEwQixFQUMxQixJQUFhLEVBQ2IsSUFBb0IsRUFDcEIsT0FBMEIsRUFFMUIsR0FBRyxJQUFXO1FBRWQsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7U0FDeEQ7YUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUU7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztTQUMxRDtJQUNILENBQUM7Q0FDRjtBQWppQkQsMENBaWlCQyIsImZpbGUiOiJuZW8tb25lLXNtYXJ0LWNvbnRyYWN0LWNvbXBpbGVyL3NyYy9hbmFseXNpcy9BbmFseXNpc1NlcnZpY2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhZGRyZXNzVG9TY3JpcHRIYXNoLCBjb21tb24sIEVDUG9pbnQsIFVJbnQxNjAsIFVJbnQyNTYgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7IEFueU5hbWVhYmxlTm9kZSwgc3ltYm9sS2V5LCB0c1V0aWxzIH0gZnJvbSAnQG5lby1vbmUvdHMtdXRpbHMnO1xuaW1wb3J0IHsgdXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscyc7XG5pbXBvcnQgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5pbXBvcnQge1xuICBpc09ubHlBcnJheSxcbiAgaXNPbmx5Qm9vbGVhbixcbiAgaXNPbmx5QnVmZmVyLFxuICBpc09ubHlNYXAsXG4gIGlzT25seU51bGwsXG4gIGlzT25seU51bWJlcixcbiAgaXNPbmx5U2V0LFxuICBpc09ubHlTdHJpbmcsXG4gIGlzT25seVN5bWJvbCxcbiAgaXNPbmx5VW5kZWZpbmVkLFxufSBmcm9tICcuLi9jb21waWxlL2hlbHBlci90eXBlcyc7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSAnLi4vQ29udGV4dCc7XG5pbXBvcnQgeyBEaWFnbm9zdGljQ29kZSB9IGZyb20gJy4uL0RpYWdub3N0aWNDb2RlJztcbmltcG9ydCB7IERpYWdub3N0aWNNZXNzYWdlIH0gZnJvbSAnLi4vRGlhZ25vc3RpY01lc3NhZ2UnO1xuaW1wb3J0IHsgY3JlYXRlTWVtb2l6ZWQsIG5vZGVLZXksIHR5cGVLZXkgfSBmcm9tICcuLi91dGlscyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXJyb3JEaWFnbm9zdGljT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGVycm9yPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaWFnbm9zdGljT3B0aW9ucyBleHRlbmRzIEVycm9yRGlhZ25vc3RpY09wdGlvbnMge1xuICByZWFkb25seSB3YXJuaW5nPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TID0ge1xuICBlcnJvcjogdHJ1ZSxcbiAgd2FybmluZzogZmFsc2UsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25hdHVyZVR5cGVzIHtcbiAgcmVhZG9ubHkgcGFyYW1EZWNsczogUmVhZG9ubHlBcnJheTx0cy5QYXJhbWV0ZXJEZWNsYXJhdGlvbj47XG4gIHJlYWRvbmx5IHBhcmFtVHlwZXM6IE1hcDx0cy5QYXJhbWV0ZXJEZWNsYXJhdGlvbiwgdHMuVHlwZSB8IHVuZGVmaW5lZD47XG4gIHJlYWRvbmx5IHJldHVyblR5cGU6IHRzLlR5cGUgfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBBbmFseXNpc1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IG1lbW9pemVkID0gY3JlYXRlTWVtb2l6ZWQoKTtcbiAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY29udGV4dDogQ29udGV4dCkge31cblxuICBwdWJsaWMgZ2V0RnVuY3Rpb25SZXR1cm5UeXBlKFxuICAgIG5vZGU6IHRzLlNpZ25hdHVyZURlY2xhcmF0aW9uLFxuICAgIG9wdGlvbnM6IERpYWdub3N0aWNPcHRpb25zID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMsXG4gICk6IHRzLlR5cGUgfCB1bmRlZmluZWQge1xuICAgIGlmICh0cy5pc0FjY2Vzc29yKG5vZGUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUeXBlKG5vZGUpO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGVOb2RlID0gdHNVdGlscy50eXBlXy5nZXRUeXBlTm9kZShub2RlKSBhcyB0cy5UeXBlTm9kZSB8IHVuZGVmaW5lZDtcbiAgICBpZiAodHlwZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0Tm90QW55VHlwZSh0eXBlTm9kZSwgdHNVdGlscy50eXBlXy5nZXRUeXBlRnJvbVR5cGVOb2RlKHRoaXMuY29udGV4dC50eXBlQ2hlY2tlciwgdHlwZU5vZGUpKTtcbiAgICB9XG5cbiAgICBjb25zdCBzaWduYXR1cmVUeXBlcyA9IHRoaXMuZXh0cmFjdFNpZ25hdHVyZShub2RlLCBvcHRpb25zKTtcblxuICAgIHJldHVybiBzaWduYXR1cmVUeXBlcyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogc2lnbmF0dXJlVHlwZXMucmV0dXJuVHlwZTtcbiAgfVxuXG4gIHB1YmxpYyBleHRyYWN0QWxsU2lnbmF0dXJlcyhcbiAgICBub2RlOiB0cy5Ob2RlLFxuICAgIG9wdGlvbnM6IERpYWdub3N0aWNPcHRpb25zID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMsXG4gICk6IFJlYWRvbmx5QXJyYXk8U2lnbmF0dXJlVHlwZXM+IHtcbiAgICByZXR1cm4gdGhpcy5leHRyYWN0QWxsU2lnbmF0dXJlc0ZvclR5cGUobm9kZSwgdGhpcy5nZXRUeXBlKG5vZGUpLCBvcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBleHRyYWN0U2lnbmF0dXJlKFxuICAgIG5vZGU6IHRzLk5vZGUsXG4gICAgb3B0aW9uczogRGlhZ25vc3RpY09wdGlvbnMgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUyxcbiAgKTogU2lnbmF0dXJlVHlwZXMgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmV4dHJhY3RTaWduYXR1cmVGb3JUeXBlKG5vZGUsIHRoaXMuZ2V0VHlwZShub2RlKSwgb3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0U2lnbmF0dXJlcyhub2RlOiB0cy5DYWxsTGlrZUV4cHJlc3Npb24pOiBSZWFkb25seUFycmF5PHRzLlNpZ25hdHVyZT4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHNpZ25hdHVyZSA9IHRoaXMuY29udGV4dC50eXBlQ2hlY2tlci5nZXRSZXNvbHZlZFNpZ25hdHVyZShub2RlKTtcbiAgICBpZiAoc2lnbmF0dXJlICE9PSB1bmRlZmluZWQgJiYgIXRzVXRpbHMuc2lnbmF0dXJlLmlzRmFpbHVyZShzaWduYXR1cmUpKSB7XG4gICAgICByZXR1cm4gW3NpZ25hdHVyZV07XG4gICAgfVxuICAgIGNvbnN0IGV4cHIgPSB0c1V0aWxzLmV4cHJlc3Npb24uZ2V0RXhwcmVzc2lvbkZvckNhbGwobm9kZSk7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0VHlwZShleHByKTtcbiAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB0c1V0aWxzLnR5cGVfLmdldENhbGxTaWduYXR1cmVzKHR5cGUpO1xuICB9XG5cbiAgcHVibGljIGV4dHJhY3RBbGxTaWduYXR1cmVzRm9yVHlwZShcbiAgICBub2RlOiB0cy5Ob2RlLFxuICAgIHR5cGU6IHRzLlR5cGUgfCB1bmRlZmluZWQsXG4gICAgb3B0aW9uczogRGlhZ25vc3RpY09wdGlvbnMgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUyxcbiAgKTogUmVhZG9ubHlBcnJheTxTaWduYXR1cmVUeXBlcz4ge1xuICAgIGNvbnN0IHNpZ25hdHVyZXMgPSB0eXBlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB0c1V0aWxzLnR5cGVfLmdldENhbGxTaWduYXR1cmVzKHR5cGUpO1xuICAgIGlmIChzaWduYXR1cmVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lnbmF0dXJlcy5tYXAoKHNpZ25hdHVyZSkgPT4gdGhpcy5leHRyYWN0U2lnbmF0dXJlVHlwZXMobm9kZSwgc2lnbmF0dXJlLCBvcHRpb25zKSkuZmlsdGVyKHV0aWxzLm5vdE51bGwpO1xuICB9XG5cbiAgcHVibGljIGV4dHJhY3RTaWduYXR1cmVGb3JUeXBlKFxuICAgIG5vZGU6IHRzLk5vZGUsXG4gICAgdHlwZTogdHMuVHlwZSB8IHVuZGVmaW5lZCxcbiAgICBvcHRpb25zOiBEaWFnbm9zdGljT3B0aW9ucyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLFxuICApOiBTaWduYXR1cmVUeXBlcyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc2lnbmF0dXJlVHlwZXMgPSB0aGlzLmV4dHJhY3RBbGxTaWduYXR1cmVzRm9yVHlwZShub2RlLCB0eXBlLCBvcHRpb25zKTtcbiAgICBpZiAoc2lnbmF0dXJlVHlwZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChzaWduYXR1cmVUeXBlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRoaXMucmVwb3J0KG9wdGlvbnMsIG5vZGUsIERpYWdub3N0aWNDb2RlLk11bHRpcGxlU2lnbmF0dXJlcywgRGlhZ25vc3RpY01lc3NhZ2UuTXVsdGlwbGVTaWduYXR1cmVzKTtcblxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lnbmF0dXJlVHlwZXNbMF07XG4gIH1cblxuICBwdWJsaWMgZXh0cmFjdFNpZ25hdHVyZXNGb3JDYWxsKFxuICAgIG5vZGU6IHRzLkNhbGxMaWtlRXhwcmVzc2lvbixcbiAgICBvcHRpb25zOiBEaWFnbm9zdGljT3B0aW9ucyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLFxuICApOiBSZWFkb25seUFycmF5PFNpZ25hdHVyZVR5cGVzPiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc2lnbmF0dXJlcyA9IHRoaXMuZ2V0U2lnbmF0dXJlcyhub2RlKTtcbiAgICBpZiAoc2lnbmF0dXJlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBzaWduYXR1cmVzLm1hcCgoc2lnbmF0dXJlKSA9PiB0aGlzLmV4dHJhY3RTaWduYXR1cmVUeXBlcyhub2RlLCBzaWduYXR1cmUsIG9wdGlvbnMpKS5maWx0ZXIodXRpbHMubm90TnVsbCk7XG4gIH1cblxuICBwdWJsaWMgZXh0cmFjdFNpZ25hdHVyZVR5cGVzKFxuICAgIG5vZGU6IHRzLk5vZGUsXG4gICAgc2lnbmF0dXJlOiB0cy5TaWduYXR1cmUsXG4gICAgb3B0aW9uczogRGlhZ25vc3RpY09wdGlvbnMgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUyxcbiAgKTogU2lnbmF0dXJlVHlwZXMgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHBhcmFtcyA9IHRzVXRpbHMuc2lnbmF0dXJlLmdldFBhcmFtZXRlcnMoc2lnbmF0dXJlKTtcbiAgICBjb25zdCBwYXJhbVR5cGVzID0gcGFyYW1zLm1hcCgocGFyYW0pID0+IHRoaXMuZ2V0VHlwZU9mU3ltYm9sKHBhcmFtLCBub2RlKSk7XG4gICAgY29uc3QgcGFyYW1EZWNsc051bGxhYmxlID0gcGFyYW1zLm1hcCgocGFyYW0pID0+IHRzVXRpbHMuc3ltYm9sLmdldFZhbHVlRGVjbGFyYXRpb24ocGFyYW0pKTtcbiAgICBjb25zdCBudWxsUGFyYW1JbmRleCA9IHBhcmFtRGVjbHNOdWxsYWJsZS5pbmRleE9mKHVuZGVmaW5lZCk7XG4gICAgaWYgKG51bGxQYXJhbUluZGV4ICE9PSAtMSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGNvbnN0IG51bGxQYXJhbSA9IHBhcmFtc1tudWxsUGFyYW1JbmRleF07XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhpcy5yZXBvcnQoXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIERpYWdub3N0aWNDb2RlLkludmFyaWFudCxcbiAgICAgICAgRGlhZ25vc3RpY01lc3NhZ2UuTWlzc2luZ1BhcmFtZXRlckRlY2xhcmF0aW9uLFxuICAgICAgICB0c1V0aWxzLnN5bWJvbC5nZXROYW1lKG51bGxQYXJhbSksXG4gICAgICApO1xuXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbURlY2xzID0gcGFyYW1EZWNsc051bGxhYmxlLmZpbHRlcih1dGlscy5ub3ROdWxsKS5maWx0ZXIodHMuaXNQYXJhbWV0ZXIpO1xuXG4gICAgY29uc3QgZGVjbFRvVHlwZSA9IG5ldyBNYXA8dHMuUGFyYW1ldGVyRGVjbGFyYXRpb24sIHRzLlR5cGUgfCB1bmRlZmluZWQ+KCk7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gICAgZm9yIChjb25zdCBbcGFyYW1EZWNsLCBwYXJhbVR5cGVdIG9mIHV0aWxzLnppcChwYXJhbURlY2xzLCBwYXJhbVR5cGVzKSkge1xuICAgICAgZGVjbFRvVHlwZS5zZXQocGFyYW1EZWNsLCBwYXJhbVR5cGUpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwYXJhbURlY2xzLFxuICAgICAgcGFyYW1UeXBlczogZGVjbFRvVHlwZSxcbiAgICAgIHJldHVyblR5cGU6IHRoaXMuZ2V0Tm90QW55VHlwZShub2RlLCB0c1V0aWxzLnNpZ25hdHVyZS5nZXRSZXR1cm5UeXBlKHNpZ25hdHVyZSkpLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgZXh0cmFjdExpdGVyYWxBZGRyZXNzKG9yaWdpbmFsOiB0cy5FeHByZXNzaW9uKTogVUludDE2MCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubWVtb2l6ZWQoJ2V4dHJhY3QtbGl0ZXJhbC1hZGRyZXNzJywgbm9kZUtleShvcmlnaW5hbCksICgpID0+XG4gICAgICB0aGlzLmV4dHJhY3RMaXRlcmFsKFxuICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgJ0FkZHJlc3NDb25zdHJ1Y3RvcicsXG4gICAgICAgICh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gY29tbW9uLnN0cmluZ1RvVUludDE2MChhZGRyZXNzVG9TY3JpcHRIYXNoKHZhbHVlKSk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICByZXR1cm4gY29tbW9uLnN0cmluZ1RvVUludDE2MCh2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21tb24uYnVmZmVyVG9VSW50MTYwLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGV4dHJhY3RMaXRlcmFsSGFzaDI1NihvcmlnaW5hbDogdHMuRXhwcmVzc2lvbik6IFVJbnQyNTYgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmV4dHJhY3RMaXRlcmFsKG9yaWdpbmFsLCAnSGFzaDI1NkNvbnN0cnVjdG9yJywgY29tbW9uLnN0cmluZ1RvVUludDI1NiwgY29tbW9uLmJ1ZmZlclRvVUludDI1Nik7XG4gIH1cblxuICBwdWJsaWMgZXh0cmFjdExpdGVyYWxQdWJsaWNLZXkob3JpZ2luYWw6IHRzLkV4cHJlc3Npb24pOiBFQ1BvaW50IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5leHRyYWN0TGl0ZXJhbChvcmlnaW5hbCwgJ1B1YmxpY0tleUNvbnN0cnVjdG9yJywgY29tbW9uLnN0cmluZ1RvRUNQb2ludCwgY29tbW9uLmJ1ZmZlclRvRUNQb2ludCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0VHlwZShub2RlOiB0cy5Ob2RlLCBvcHRpb25zOiBFcnJvckRpYWdub3N0aWNPcHRpb25zID0ge30pOiB0cy5UeXBlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5tZW1vaXplZCgnZ2V0LXR5cGUnLCBub2RlS2V5KG5vZGUpLCAoKSA9PlxuICAgICAgdGhpcy5nZXROb3RBbnlUeXBlKG5vZGUsIHRzVXRpbHMudHlwZV8uZ2V0VHlwZSh0aGlzLmNvbnRleHQudHlwZUNoZWNrZXIsIG5vZGUpLCBvcHRpb25zKSxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGdldFR5cGVPZlN5bWJvbChzeW1ib2w6IHRzLlN5bWJvbCB8IHVuZGVmaW5lZCwgbm9kZTogdHMuTm9kZSk6IHRzLlR5cGUgfCB1bmRlZmluZWQge1xuICAgIGlmIChzeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5