react-scripts
Version:
Configuration and scripts for Create React App.
218 lines (186 loc) • 22.8 kB
JavaScript
var _lodash = require('lodash.find');
var _lodash2 = _interopRequireDefault(_lodash);
var _importType = require('../core/importType');
var _importType2 = _interopRequireDefault(_importType);
var _staticRequire = require('../core/staticRequire');
var _staticRequire2 = _interopRequireDefault(_staticRequire);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var defaultGroups = ['builtin', 'external', 'parent', 'sibling', 'index'];
// REPORTING
function reverse(array) {
return array.map(function (v) {
return {
name: v.name,
rank: -v.rank,
node: v.node
};
}).reverse();
}
function findOutOfOrder(imported) {
if (imported.length === 0) {
return [];
}
var maxSeenRankNode = imported[0];
return imported.filter(function (importedModule) {
var res = importedModule.rank < maxSeenRankNode.rank;
if (maxSeenRankNode.rank < importedModule.rank) {
maxSeenRankNode = importedModule;
}
return res;
});
}
function reportOutOfOrder(context, imported, outOfOrder, order) {
outOfOrder.forEach(function (imp) {
var found = (0, _lodash2.default)(imported, function hasHigherRank(importedItem) {
return importedItem.rank > imp.rank;
});
context.report(imp.node, '`' + imp.name + '` import should occur ' + order + ' import of `' + found.name + '`');
});
}
function makeOutOfOrderReport(context, imported) {
var outOfOrder = findOutOfOrder(imported);
if (!outOfOrder.length) {
return;
}
// There are things to report. Try to minimize the number of reported errors.
var reversedImported = reverse(imported);
var reversedOrder = findOutOfOrder(reversedImported);
if (reversedOrder.length < outOfOrder.length) {
reportOutOfOrder(context, reversedImported, reversedOrder, 'after');
return;
}
reportOutOfOrder(context, imported, outOfOrder, 'before');
}
// DETECTING
function computeRank(context, ranks, name, type) {
return ranks[(0, _importType2.default)(name, context)] + (type === 'import' ? 0 : 100);
}
function registerNode(context, node, name, type, ranks, imported) {
var rank = computeRank(context, ranks, name, type);
if (rank !== -1) {
imported.push({ name: name, rank: rank, node: node });
}
}
function isInVariableDeclarator(node) {
return node && (node.type === 'VariableDeclarator' || isInVariableDeclarator(node.parent));
}
var types = ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'];
// Creates an object with type-rank pairs.
// Example: { index: 0, sibling: 1, parent: 1, external: 1, builtin: 2, internal: 2 }
// Will throw an error if it contains a type that does not exist, or has a duplicate
function convertGroupsToRanks(groups) {
var rankObject = groups.reduce(function (res, group, index) {
if (typeof group === 'string') {
group = [group];
}
group.forEach(function (groupItem) {
if (types.indexOf(groupItem) === -1) {
throw new Error('Incorrect configuration of the rule: Unknown type `' + JSON.stringify(groupItem) + '`');
}
if (res[groupItem] !== undefined) {
throw new Error('Incorrect configuration of the rule: `' + groupItem + '` is duplicated');
}
res[groupItem] = index;
});
return res;
}, {});
var omittedTypes = types.filter(function (type) {
return rankObject[type] === undefined;
});
return omittedTypes.reduce(function (res, type) {
res[type] = groups.length;
return res;
}, rankObject);
}
function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports) {
var getNumberOfEmptyLinesBetween = function getNumberOfEmptyLinesBetween(currentImport, previousImport) {
var linesBetweenImports = context.getSourceCode().lines.slice(previousImport.node.loc.end.line, currentImport.node.loc.start.line - 1);
return linesBetweenImports.filter(function (line) {
return !line.trim().length;
}).length;
};
var previousImport = imported[0];
imported.slice(1).forEach(function (currentImport) {
if (newlinesBetweenImports === 'always') {
if (currentImport.rank !== previousImport.rank && getNumberOfEmptyLinesBetween(currentImport, previousImport) === 0) {
context.report(previousImport.node, 'There should be at least one empty line between import groups');
} else if (currentImport.rank === previousImport.rank && getNumberOfEmptyLinesBetween(currentImport, previousImport) > 0) {
context.report(previousImport.node, 'There should be no empty line within import group');
}
} else {
if (getNumberOfEmptyLinesBetween(currentImport, previousImport) > 0) {
context.report(previousImport.node, 'There should be no empty line between import groups');
}
}
previousImport = currentImport;
});
}
module.exports = function importOrderRule(context) {
var options = context.options[0] || {};
var ranks = void 0;
try {
ranks = convertGroupsToRanks(options.groups || defaultGroups);
} catch (error) {
// Malformed configuration
return {
Program: function Program(node) {
context.report(node, error.message);
}
};
}
var imported = [];
var level = 0;
function incrementLevel() {
level++;
}
function decrementLevel() {
level--;
}
return {
ImportDeclaration: function handleImports(node) {
if (node.specifiers.length) {
// Ignoring unassigned imports
var name = node.source.value;
registerNode(context, node, name, 'import', ranks, imported);
}
},
CallExpression: function handleRequires(node) {
if (level !== 0 || !(0, _staticRequire2.default)(node) || !isInVariableDeclarator(node.parent)) {
return;
}
var name = node.arguments[0].value;
registerNode(context, node, name, 'require', ranks, imported);
},
'Program:exit': function reportAndReset() {
makeOutOfOrderReport(context, imported);
if ('newlines-between' in options) {
makeNewlinesBetweenReport(context, imported, options['newlines-between']);
}
imported = [];
},
FunctionDeclaration: incrementLevel,
FunctionExpression: incrementLevel,
ArrowFunctionExpression: incrementLevel,
BlockStatement: incrementLevel,
ObjectExpression: incrementLevel,
'FunctionDeclaration:exit': decrementLevel,
'FunctionExpression:exit': decrementLevel,
'ArrowFunctionExpression:exit': decrementLevel,
'BlockStatement:exit': decrementLevel,
'ObjectExpression:exit': decrementLevel
};
};
module.exports.schema = [{
type: 'object',
properties: {
groups: {
type: 'array'
},
'newlines-between': {
enum: ['always', 'never']
}
},
additionalProperties: false
}];
//# sourceMappingURL=data:application/json;base64,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LENBQTlDLEVBQW1GO0FBQ2pGO0FBQ0Q7QUFDRCxVQUFNLE9BQU8sS0FBSyxTQUFMLENBQWUsQ0FBZixFQUFrQixLQUEvQjtBQUNBLG1CQUFhLE9BQWIsRUFBc0IsSUFBdEIsRUFBNEIsSUFBNUIsRUFBa0MsU0FBbEMsRUFBNkMsS0FBN0MsRUFBb0QsUUFBcEQ7QUFDRCxLQWJJO0FBY0wsb0JBQWdCLFNBQVMsY0FBVCxHQUEwQjtBQUN4QywyQkFBcUIsT0FBckIsRUFBOEIsUUFBOUI7O0FBRUEsVUFBSSxzQkFBc0IsT0FBMUIsRUFBbUM7QUFDakMsa0NBQTBCLE9BQTFCLEVBQW1DLFFBQW5DLEVBQTZDLFFBQVEsa0JBQVIsQ0FBN0M7QUFDRDs7QUFFRCxpQkFBVyxFQUFYO0FBQ0QsS0F0Qkk7QUF1QkwseUJBQXFCLGNBdkJoQjtBQXdCTCx3QkFBb0IsY0F4QmY7QUF5QkwsNkJBQXlCLGNBekJwQjtBQTBCTCxvQkFBZ0IsY0ExQlg7QUEyQkwsc0JBQWtCLGNBM0JiO0FBNEJMLGdDQUE0QixjQTVCdkI7QUE2QkwsK0JBQTJCLGNBN0J0QjtBQThCTCxvQ0FBZ0MsY0E5QjNCO0FBK0JMLDJCQUF1QixjQS9CbEI7QUFnQ0wsNkJBQXlCO0FBaENwQixHQUFQO0FBa0NELENBMUREOztBQTREQSxPQUFPLE9BQVAsQ0FBZSxNQUFmLEdBQXdCLENBQ3RCO0FBQ0UsUUFBTSxRQURSO0FBRUUsY0FBWTtBQUNWLFlBQVE7QUFDTixZQUFNO0FBREEsS0FERTtBQUlWLHdCQUFvQjtBQUNsQixZQUFNLENBQUUsUUFBRixFQUFZLE9BQVo7QUFEWTtBQUpWLEdBRmQ7QUFVRSx3QkFBc0I7QUFWeEIsQ0FEc0IsQ0FBeEIiLCJmaWxlIjoicnVsZXMvb3JkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuaW1wb3J0IGZpbmQgZnJvbSAnbG9kYXNoLmZpbmQnXG5pbXBvcnQgaW1wb3J0VHlwZSBmcm9tICcuLi9jb3JlL2ltcG9ydFR5cGUnXG5pbXBvcnQgaXNTdGF0aWNSZXF1aXJlIGZyb20gJy4uL2NvcmUvc3RhdGljUmVxdWlyZSdcblxuY29uc3QgZGVmYXVsdEdyb3VwcyA9IFsnYnVpbHRpbicsICdleHRlcm5hbCcsICdwYXJlbnQnLCAnc2libGluZycsICdpbmRleCddXG5cbi8vIFJFUE9SVElOR1xuXG5mdW5jdGlvbiByZXZlcnNlKGFycmF5KSB7XG4gIHJldHVybiBhcnJheS5tYXAoZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogdi5uYW1lLFxuICAgICAgcmFuazogLXYucmFuayxcbiAgICAgIG5vZGU6IHYubm9kZSxcbiAgICB9XG4gIH0pLnJldmVyc2UoKVxufVxuXG5mdW5jdGlvbiBmaW5kT3V0T2ZPcmRlcihpbXBvcnRlZCkge1xuICBpZiAoaW1wb3J0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFtdXG4gIH1cbiAgbGV0IG1heFNlZW5SYW5rTm9kZSA9IGltcG9ydGVkWzBdXG4gIHJldHVybiBpbXBvcnRlZC5maWx0ZXIoZnVuY3Rpb24gKGltcG9ydGVkTW9kdWxlKSB7XG4gICAgY29uc3QgcmVzID0gaW1wb3J0ZWRNb2R1bGUucmFuayA8IG1heFNlZW5SYW5rTm9kZS5yYW5rXG4gICAgaWYgKG1heFNlZW5SYW5rTm9kZS5yYW5rIDwgaW1wb3J0ZWRNb2R1bGUucmFuaykge1xuICAgICAgbWF4U2VlblJhbmtOb2RlID0gaW1wb3J0ZWRNb2R1bGVcbiAgICB9XG4gICAgcmV0dXJuIHJlc1xuICB9KVxufVxuXG5mdW5jdGlvbiByZXBvcnRPdXRPZk9yZGVyKGNvbnRleHQsIGltcG9ydGVkLCBvdXRPZk9yZGVyLCBvcmRlcikge1xuICBvdXRPZk9yZGVyLmZvckVhY2goZnVuY3Rpb24gKGltcCkge1xuICAgIGNvbnN0IGZvdW5kID0gZmluZChpbXBvcnRlZCwgZnVuY3Rpb24gaGFzSGlnaGVyUmFuayhpbXBvcnRlZEl0ZW0pIHtcbiAgICAgIHJldHVybiBpbXBvcnRlZEl0ZW0ucmFuayA+IGltcC5yYW5rXG4gICAgfSlcbiAgICBjb250ZXh0LnJlcG9ydChpbXAubm9kZSwgJ2AnICsgaW1wLm5hbWUgKyAnYCBpbXBvcnQgc2hvdWxkIG9jY3VyICcgKyBvcmRlciArXG4gICAgICAnIGltcG9ydCBvZiBgJyArIGZvdW5kLm5hbWUgKyAnYCcpXG4gIH0pXG59XG5cbmZ1bmN0aW9uIG1ha2VPdXRPZk9yZGVyUmVwb3J0KGNvbnRleHQsIGltcG9ydGVkKSB7XG4gIGNvbnN0IG91dE9mT3JkZXIgPSBmaW5kT3V0T2ZPcmRlcihpbXBvcnRlZClcbiAgaWYgKCFvdXRPZk9yZGVyLmxlbmd0aCkge1xuICAgIHJldHVyblxuICB9XG4gIC8vIFRoZXJlIGFyZSB0aGluZ3MgdG8gcmVwb3J0LiBUcnkgdG8gbWluaW1pemUgdGhlIG51bWJlciBvZiByZXBvcnRlZCBlcnJvcnMuXG4gIGNvbnN0IHJldmVyc2VkSW1wb3J0ZWQgPSByZXZlcnNlKGltcG9ydGVkKVxuICBjb25zdCByZXZlcnNlZE9yZGVyID0gZmluZE91dE9mT3JkZXIocmV2ZXJzZWRJbXBvcnRlZClcbiAgaWYgKHJldmVyc2VkT3JkZXIubGVuZ3RoIDwgb3V0T2ZPcmRlci5sZW5ndGgpIHtcbiAgICByZXBvcnRPdXRPZk9yZGVyKGNvbnRleHQsIHJldmVyc2VkSW1wb3J0ZWQsIHJldmVyc2VkT3JkZXIsICdhZnRlcicpXG4gICAgcmV0dXJuXG4gIH1cbiAgcmVwb3J0T3V0T2ZPcmRlcihjb250ZXh0LCBpbXBvcnRlZCwgb3V0T2ZPcmRlciwgJ2JlZm9yZScpXG59XG5cbi8vIERFVEVDVElOR1xuXG5mdW5jdGlvbiBjb21wdXRlUmFuayhjb250ZXh0LCByYW5rcywgbmFtZSwgdHlwZSkge1xuICByZXR1cm4gcmFua3NbaW1wb3J0VHlwZShuYW1lLCBjb250ZXh0KV0gK1xuICAgICh0eXBlID09PSAnaW1wb3J0JyA/IDAgOiAxMDApXG59XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyTm9kZShjb250ZXh0LCBub2RlLCBuYW1lLCB0eXBlLCByYW5rcywgaW1wb3J0ZWQpIHtcbiAgY29uc3QgcmFuayA9IGNvbXB1dGVSYW5rKGNvbnRleHQsIHJhbmtzLCBuYW1lLCB0eXBlKVxuICBpZiAocmFuayAhPT0gLTEpIHtcbiAgICBpbXBvcnRlZC5wdXNoKHtuYW1lLCByYW5rLCBub2RlfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0luVmFyaWFibGVEZWNsYXJhdG9yKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUgJiZcbiAgICAobm9kZS50eXBlID09PSAnVmFyaWFibGVEZWNsYXJhdG9yJyB8fCBpc0luVmFyaWFibGVEZWNsYXJhdG9yKG5vZGUucGFyZW50KSlcbn1cblxuY29uc3QgdHlwZXMgPSBbJ2J1aWx0aW4nLCAnZXh0ZXJuYWwnLCAnaW50ZXJuYWwnLCAncGFyZW50JywgJ3NpYmxpbmcnLCAnaW5kZXgnXVxuXG4vLyBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHR5cGUtcmFuayBwYWlycy5cbi8vIEV4YW1wbGU6IHsgaW5kZXg6IDAsIHNpYmxpbmc6IDEsIHBhcmVudDogMSwgZXh0ZXJuYWw6IDEsIGJ1aWx0aW46IDIsIGludGVybmFsOiAyIH1cbi8vIFdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgaXQgY29udGFpbnMgYSB0eXBlIHRoYXQgZG9lcyBub3QgZXhpc3QsIG9yIGhhcyBhIGR1cGxpY2F0ZVxuZnVuY3Rpb24gY29udmVydEdyb3Vwc1RvUmFua3MoZ3JvdXBzKSB7XG4gIGNvbnN0IHJhbmtPYmplY3QgPSBncm91cHMucmVkdWNlKGZ1bmN0aW9uKHJlcywgZ3JvdXAsIGluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBncm91cCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGdyb3VwID0gW2dyb3VwXVxuICAgIH1cbiAgICBncm91cC5mb3JFYWNoKGZ1bmN0aW9uKGdyb3VwSXRlbSkge1xuICAgICAgaWYgKHR5cGVzLmluZGV4T2YoZ3JvdXBJdGVtKSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvcnJlY3QgY29uZmlndXJhdGlvbiBvZiB0aGUgcnVsZTogVW5rbm93biB0eXBlIGAnICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShncm91cEl0ZW0pICsgJ2AnKVxuICAgICAgfVxuICAgICAgaWYgKHJlc1tncm91cEl0ZW1dICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvcnJlY3QgY29uZmlndXJhdGlvbiBvZiB0aGUgcnVsZTogYCcgKyBncm91cEl0ZW0gKyAnYCBpcyBkdXBsaWNhdGVkJylcbiAgICAgIH1cbiAgICAgIHJlc1tncm91cEl0ZW1dID0gaW5kZXhcbiAgICB9KVxuICAgIHJldHVybiByZXNcbiAgfSwge30pXG5cbiAgY29uc3Qgb21pdHRlZFR5cGVzID0gdHlwZXMuZmlsdGVyKGZ1bmN0aW9uKHR5cGUpIHtcbiAgICByZXR1cm4gcmFua09iamVjdFt0eXBlXSA9PT0gdW5kZWZpbmVkXG4gIH0pXG5cbiAgcmV0dXJuIG9taXR0ZWRUeXBlcy5yZWR1Y2UoZnVuY3Rpb24ocmVzLCB0eXBlKSB7XG4gICAgcmVzW3R5cGVdID0gZ3JvdXBzLmxlbmd0aFxuICAgIHJldHVybiByZXNcbiAgfSwgcmFua09iamVjdClcbn1cblxuZnVuY3Rpb24gbWFrZU5ld2xpbmVzQmV0d2VlblJlcG9ydCAoY29udGV4dCwgaW1wb3J0ZWQsIG5ld2xpbmVzQmV0d2VlbkltcG9ydHMpIHtcbiAgY29uc3QgZ2V0TnVtYmVyT2ZFbXB0eUxpbmVzQmV0d2VlbiA9IChjdXJyZW50SW1wb3J0LCBwcmV2aW91c0ltcG9ydCkgPT4ge1xuICAgIGNvbnN0IGxpbmVzQmV0d2VlbkltcG9ydHMgPSBjb250ZXh0LmdldFNvdXJjZUNvZGUoKS5saW5lcy5zbGljZShcbiAgICAgIHByZXZpb3VzSW1wb3J0Lm5vZGUubG9jLmVuZC5saW5lLFxuICAgICAgY3VycmVudEltcG9ydC5ub2RlLmxvYy5zdGFydC5saW5lIC0gMVxuICAgIClcblxuICAgIHJldHVybiBsaW5lc0JldHdlZW5JbXBvcnRzLmZpbHRlcigobGluZSkgPT4gIWxpbmUudHJpbSgpLmxlbmd0aCkubGVuZ3RoXG4gIH1cbiAgbGV0IHByZXZpb3VzSW1wb3J0ID0gaW1wb3J0ZWRbMF1cblxuICBpbXBvcnRlZC5zbGljZSgxKS5mb3JFYWNoKGZ1bmN0aW9uKGN1cnJlbnRJbXBvcnQpIHtcbiAgICBpZiAobmV3bGluZXNCZXR3ZWVuSW1wb3J0cyA9PT0gJ2Fsd2F5cycpIHtcbiAgICAgIGlmIChjdXJyZW50SW1wb3J0LnJhbmsgIT09IHByZXZpb3VzSW1wb3J0LnJhbmtcbiAgICAgICAgJiYgZ2V0TnVtYmVyT2ZFbXB0eUxpbmVzQmV0d2VlbihjdXJyZW50SW1wb3J0LCBwcmV2aW91c0ltcG9ydCkgPT09IDApXG4gICAgICB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KFxuICAgICAgICAgIHByZXZpb3VzSW1wb3J0Lm5vZGUsICdUaGVyZSBzaG91bGQgYmUgYXQgbGVhc3Qgb25lIGVtcHR5IGxpbmUgYmV0d2VlbiBpbXBvcnQgZ3JvdXBzJ1xuICAgICAgICApXG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRJbXBvcnQucmFuayA9PT0gcHJldmlvdXNJbXBvcnQucmFua1xuICAgICAgICAmJiBnZXROdW1iZXJPZkVtcHR5TGluZXNCZXR3ZWVuKGN1cnJlbnRJbXBvcnQsIHByZXZpb3VzSW1wb3J0KSA+IDApXG4gICAgICB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KFxuICAgICAgICAgIHByZXZpb3VzSW1wb3J0Lm5vZGUsICdUaGVyZSBzaG91bGQgYmUgbm8gZW1wdHkgbGluZSB3aXRoaW4gaW1wb3J0IGdyb3VwJ1xuICAgICAgICApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChnZXROdW1iZXJPZkVtcHR5TGluZXNCZXR3ZWVuKGN1cnJlbnRJbXBvcnQsIHByZXZpb3VzSW1wb3J0KSA+IDApIHtcbiAgICAgICAgY29udGV4dC5yZXBvcnQocHJldmlvdXNJbXBvcnQubm9kZSwgJ1RoZXJlIHNob3VsZCBiZSBubyBlbXB0eSBsaW5lIGJldHdlZW4gaW1wb3J0IGdyb3VwcycpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJldmlvdXNJbXBvcnQgPSBjdXJyZW50SW1wb3J0XG4gIH0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW1wb3J0T3JkZXJSdWxlIChjb250ZXh0KSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBjb250ZXh0Lm9wdGlvbnNbMF0gfHwge31cbiAgbGV0IHJhbmtzXG5cbiAgdHJ5IHtcbiAgICByYW5rcyA9IGNvbnZlcnRHcm91cHNUb1JhbmtzKG9wdGlvbnMuZ3JvdXBzIHx8IGRlZmF1bHRHcm91cHMpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgLy8gTWFsZm9ybWVkIGNvbmZpZ3VyYXRpb25cbiAgICByZXR1cm4ge1xuICAgICAgUHJvZ3JhbTogZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBjb250ZXh0LnJlcG9ydChub2RlLCBlcnJvci5tZXNzYWdlKVxuICAgICAgfSxcbiAgICB9XG4gIH1cbiAgbGV0IGltcG9ydGVkID0gW11cbiAgbGV0IGxldmVsID0gMFxuXG4gIGZ1bmN0aW9uIGluY3JlbWVudExldmVsKCkge1xuICAgIGxldmVsKytcbiAgfVxuICBmdW5jdGlvbiBkZWNyZW1lbnRMZXZlbCgpIHtcbiAgICBsZXZlbC0tXG4gIH1cblxuICByZXR1cm4ge1xuICAgIEltcG9ydERlY2xhcmF0aW9uOiBmdW5jdGlvbiBoYW5kbGVJbXBvcnRzKG5vZGUpIHtcbiAgICAgIGlmIChub2RlLnNwZWNpZmllcnMubGVuZ3RoKSB7IC8vIElnbm9yaW5nIHVuYXNzaWduZWQgaW1wb3J0c1xuICAgICAgICBjb25zdCBuYW1lID0gbm9kZS5zb3VyY2UudmFsdWVcbiAgICAgICAgcmVnaXN0ZXJOb2RlKGNvbnRleHQsIG5vZGUsIG5hbWUsICdpbXBvcnQnLCByYW5rcywgaW1wb3J0ZWQpXG4gICAgICB9XG4gICAgfSxcbiAgICBDYWxsRXhwcmVzc2lvbjogZnVuY3Rpb24gaGFuZGxlUmVxdWlyZXMobm9kZSkge1xuICAgICAgaWYgKGxldmVsICE9PSAwIHx8ICFpc1N0YXRpY1JlcXVpcmUobm9kZSkgfHwgIWlzSW5WYXJpYWJsZURlY2xhcmF0b3Iobm9kZS5wYXJlbnQpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgY29uc3QgbmFtZSA9IG5vZGUuYXJndW1lbnRzWzBdLnZhbHVlXG4gICAgICByZWdpc3Rlck5vZGUoY29udGV4dCwgbm9kZSwgbmFtZSwgJ3JlcXVpcmUnLCByYW5rcywgaW1wb3J0ZWQpXG4gICAgfSxcbiAgICAnUHJvZ3JhbTpleGl0JzogZnVuY3Rpb24gcmVwb3J0QW5kUmVzZXQoKSB7XG4gICAgICBtYWtlT3V0T2ZPcmRlclJlcG9ydChjb250ZXh0LCBpbXBvcnRlZClcblxuICAgICAgaWYgKCduZXdsaW5lcy1iZXR3ZWVuJyBpbiBvcHRpb25zKSB7XG4gICAgICAgIG1ha2VOZXdsaW5lc0JldHdlZW5SZXBvcnQoY29udGV4dCwgaW1wb3J0ZWQsIG9wdGlvbnNbJ25ld2xpbmVzLWJldHdlZW4nXSlcbiAgICAgIH1cblxuICAgICAgaW1wb3J0ZWQgPSBbXVxuICAgIH0sXG4gICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgRnVuY3Rpb25FeHByZXNzaW9uOiBpbmNyZW1lbnRMZXZlbCxcbiAgICBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgQmxvY2tTdGF0ZW1lbnQ6IGluY3JlbWVudExldmVsLFxuICAgIE9iamVjdEV4cHJlc3Npb246IGluY3JlbWVudExldmVsLFxuICAgICdGdW5jdGlvbkRlY2xhcmF0aW9uOmV4aXQnOiBkZWNyZW1lbnRMZXZlbCxcbiAgICAnRnVuY3Rpb25FeHByZXNzaW9uOmV4aXQnOiBkZWNyZW1lbnRMZXZlbCxcbiAgICAnQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgICdCbG9ja1N0YXRlbWVudDpleGl0JzogZGVjcmVtZW50TGV2ZWwsXG4gICAgJ09iamVjdEV4cHJlc3Npb246ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnNjaGVtYSA9IFtcbiAge1xuICAgIHR5cGU6ICdvYmplY3QnLFxuICAgIHByb3BlcnRpZXM6IHtcbiAgICAgIGdyb3Vwczoge1xuICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgfSxcbiAgICAgICduZXdsaW5lcy1iZXR3ZWVuJzoge1xuICAgICAgICBlbnVtOiBbICdhbHdheXMnLCAnbmV2ZXInIF0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICB9LFxuXVxuIl19
;