UNPKG

20.5 kBJavaScriptView Raw
1'use strict';
2
3
4
5
6var _staticRequire = require('../core/staticRequire');var _staticRequire2 = _interopRequireDefault(_staticRequire);
7var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_docsUrl);
8
9var _debug = require('debug');var _debug2 = _interopRequireDefault(_debug);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
10const log = (0, _debug2.default)('eslint-plugin-import:rules:newline-after-import');
11
12//------------------------------------------------------------------------------
13// Rule Definition
14//------------------------------------------------------------------------------
15/**
16 * @fileoverview Rule to enforce new line after import not followed by another import.
17 * @author Radek Benkel
18 */function containsNodeOrEqual(outerNode, innerNode) {return outerNode.range[0] <= innerNode.range[0] && outerNode.range[1] >= innerNode.range[1];}
19
20function getScopeBody(scope) {
21 if (scope.block.type === 'SwitchStatement') {
22 log('SwitchStatement scopes not supported');
23 return null;
24 }const
25
26 body = scope.block.body;
27 if (body && body.type === 'BlockStatement') {
28 return body.body;
29 }
30
31 return body;
32}
33
34function findNodeIndexInScopeBody(body, nodeToFind) {
35 return body.findIndex(node => containsNodeOrEqual(node, nodeToFind));
36}
37
38function getLineDifference(node, nextNode) {
39 return nextNode.loc.start.line - node.loc.end.line;
40}
41
42function isClassWithDecorator(node) {
43 return node.type === 'ClassDeclaration' && node.decorators && node.decorators.length;
44}
45
46function isExportDefaultClass(node) {
47 return node.type === 'ExportDefaultDeclaration' && node.declaration.type === 'ClassDeclaration';
48}
49
50function isExportNameClass(node) {
51 return node.type === 'ExportNamedDeclaration' && node.declaration.type === 'ClassDeclaration';
52}
53
54module.exports = {
55 meta: {
56 type: 'layout',
57 docs: {
58 url: (0, _docsUrl2.default)('newline-after-import') },
59
60 fixable: 'whitespace',
61 schema: [
62 {
63 'type': 'object',
64 'properties': {
65 'count': {
66 'type': 'integer',
67 'minimum': 1 } },
68
69
70 'additionalProperties': false }] },
71
72
73
74 create: function (context) {
75 let level = 0;
76 const requireCalls = [];
77
78 function checkForNewLine(node, nextNode, type) {
79 if (isExportDefaultClass(nextNode) || isExportNameClass(nextNode)) {
80 const classNode = nextNode.declaration;
81
82 if (isClassWithDecorator(classNode)) {
83 nextNode = classNode.decorators[0];
84 }
85 } else if (isClassWithDecorator(nextNode)) {
86 nextNode = nextNode.decorators[0];
87 }
88
89 const options = context.options[0] || { count: 1 };
90 const lineDifference = getLineDifference(node, nextNode);
91 const EXPECTED_LINE_DIFFERENCE = options.count + 1;
92
93 if (lineDifference < EXPECTED_LINE_DIFFERENCE) {
94 let column = node.loc.start.column;
95
96 if (node.loc.start.line !== node.loc.end.line) {
97 column = 0;
98 }
99
100 context.report({
101 loc: {
102 line: node.loc.end.line,
103 column },
104
105 message: `Expected ${options.count} empty line${options.count > 1 ? 's' : ''} \
106after ${type} statement not followed by another ${type}.`,
107 fix: fixer => fixer.insertTextAfter(
108 node,
109 '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference)) });
110
111
112 }
113 }
114
115 function incrementLevel() {
116 level++;
117 }
118 function decrementLevel() {
119 level--;
120 }
121
122 function checkImport(node) {const
123 parent = node.parent;
124 const nodePosition = parent.body.indexOf(node);
125 const nextNode = parent.body[nodePosition + 1];
126
127 // skip "export import"s
128 if (node.type === 'TSImportEqualsDeclaration' && node.isExport) {
129 return;
130 }
131
132 if (nextNode && nextNode.type !== 'ImportDeclaration' && (nextNode.type !== 'TSImportEqualsDeclaration' || nextNode.isExport)) {
133 checkForNewLine(node, nextNode, 'import');
134 }
135 }
136
137 return {
138 ImportDeclaration: checkImport,
139 TSImportEqualsDeclaration: checkImport,
140 CallExpression: function (node) {
141 if ((0, _staticRequire2.default)(node) && level === 0) {
142 requireCalls.push(node);
143 }
144 },
145 'Program:exit': function () {
146 log('exit processing for', context.getFilename());
147 const scopeBody = getScopeBody(context.getScope());
148 log('got scope:', scopeBody);
149
150 requireCalls.forEach(function (node, index) {
151 const nodePosition = findNodeIndexInScopeBody(scopeBody, node);
152 log('node position in scope:', nodePosition);
153
154 const statementWithRequireCall = scopeBody[nodePosition];
155 const nextStatement = scopeBody[nodePosition + 1];
156 const nextRequireCall = requireCalls[index + 1];
157
158 if (nextRequireCall && containsNodeOrEqual(statementWithRequireCall, nextRequireCall)) {
159 return;
160 }
161
162 if (nextStatement && (
163 !nextRequireCall || !containsNodeOrEqual(nextStatement, nextRequireCall))) {
164
165 checkForNewLine(statementWithRequireCall, nextStatement, 'require');
166 }
167 });
168 },
169 FunctionDeclaration: incrementLevel,
170 FunctionExpression: incrementLevel,
171 ArrowFunctionExpression: incrementLevel,
172 BlockStatement: incrementLevel,
173 ObjectExpression: incrementLevel,
174 Decorator: incrementLevel,
175 'FunctionDeclaration:exit': decrementLevel,
176 'FunctionExpression:exit': decrementLevel,
177 'ArrowFunctionExpression:exit': decrementLevel,
178 'BlockStatement:exit': decrementLevel,
179 'ObjectExpression:exit': decrementLevel,
180 'Decorator:exit': decrementLevel };
181
182 } };
183//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uZXdsaW5lLWFmdGVyLWltcG9ydC5qcyJdLCJuYW1lcyI6WyJsb2ciLCJjb250YWluc05vZGVPckVxdWFsIiwib3V0ZXJOb2RlIiwiaW5uZXJOb2RlIiwicmFuZ2UiLCJnZXRTY29wZUJvZHkiLCJzY29wZSIsImJsb2NrIiwidHlwZSIsImJvZHkiLCJmaW5kTm9kZUluZGV4SW5TY29wZUJvZHkiLCJub2RlVG9GaW5kIiwiZmluZEluZGV4Iiwibm9kZSIsImdldExpbmVEaWZmZXJlbmNlIiwibmV4dE5vZGUiLCJsb2MiLCJzdGFydCIsImxpbmUiLCJlbmQiLCJpc0NsYXNzV2l0aERlY29yYXRvciIsImRlY29yYXRvcnMiLCJsZW5ndGgiLCJpc0V4cG9ydERlZmF1bHRDbGFzcyIsImRlY2xhcmF0aW9uIiwiaXNFeHBvcnROYW1lQ2xhc3MiLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJ1cmwiLCJmaXhhYmxlIiwic2NoZW1hIiwiY3JlYXRlIiwiY29udGV4dCIsImxldmVsIiwicmVxdWlyZUNhbGxzIiwiY2hlY2tGb3JOZXdMaW5lIiwiY2xhc3NOb2RlIiwib3B0aW9ucyIsImNvdW50IiwibGluZURpZmZlcmVuY2UiLCJFWFBFQ1RFRF9MSU5FX0RJRkZFUkVOQ0UiLCJjb2x1bW4iLCJyZXBvcnQiLCJtZXNzYWdlIiwiZml4IiwiZml4ZXIiLCJpbnNlcnRUZXh0QWZ0ZXIiLCJyZXBlYXQiLCJpbmNyZW1lbnRMZXZlbCIsImRlY3JlbWVudExldmVsIiwiY2hlY2tJbXBvcnQiLCJwYXJlbnQiLCJub2RlUG9zaXRpb24iLCJpbmRleE9mIiwiaXNFeHBvcnQiLCJJbXBvcnREZWNsYXJhdGlvbiIsIlRTSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24iLCJDYWxsRXhwcmVzc2lvbiIsInB1c2giLCJnZXRGaWxlbmFtZSIsInNjb3BlQm9keSIsImdldFNjb3BlIiwiZm9yRWFjaCIsImluZGV4Iiwic3RhdGVtZW50V2l0aFJlcXVpcmVDYWxsIiwibmV4dFN0YXRlbWVudCIsIm5leHRSZXF1aXJlQ2FsbCIsIkZ1bmN0aW9uRGVjbGFyYXRpb24iLCJGdW5jdGlvbkV4cHJlc3Npb24iLCJBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbiIsIkJsb2NrU3RhdGVtZW50IiwiT2JqZWN0RXhwcmVzc2lvbiIsIkRlY29yYXRvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSxzRDtBQUNBLHFDOztBQUVBLDhCO0FBQ0EsTUFBTUEsTUFBTSxxQkFBTSxpREFBTixDQUFaOztBQUVBO0FBQ0E7QUFDQTtBQWJBOzs7R0FlQSxTQUFTQyxtQkFBVCxDQUE2QkMsU0FBN0IsRUFBd0NDLFNBQXhDLEVBQW1ELENBQ2pELE9BQU9ELFVBQVVFLEtBQVYsQ0FBZ0IsQ0FBaEIsS0FBc0JELFVBQVVDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBdEIsSUFBNENGLFVBQVVFLEtBQVYsQ0FBZ0IsQ0FBaEIsS0FBc0JELFVBQVVDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBekUsQ0FDRDs7QUFFRCxTQUFTQyxZQUFULENBQXNCQyxLQUF0QixFQUE2QjtBQUMzQixNQUFJQSxNQUFNQyxLQUFOLENBQVlDLElBQVosS0FBcUIsaUJBQXpCLEVBQTRDO0FBQzFDUixRQUFJLHNDQUFKO0FBQ0EsV0FBTyxJQUFQO0FBQ0QsR0FKMEI7O0FBTW5CUyxNQU5tQixHQU1WSCxNQUFNQyxLQU5JLENBTW5CRSxJQU5tQjtBQU8zQixNQUFJQSxRQUFRQSxLQUFLRCxJQUFMLEtBQWMsZ0JBQTFCLEVBQTRDO0FBQzFDLFdBQU9DLEtBQUtBLElBQVo7QUFDRDs7QUFFRCxTQUFPQSxJQUFQO0FBQ0Q7O0FBRUQsU0FBU0Msd0JBQVQsQ0FBa0NELElBQWxDLEVBQXdDRSxVQUF4QyxFQUFvRDtBQUNsRCxTQUFPRixLQUFLRyxTQUFMLENBQWdCQyxJQUFELElBQVVaLG9CQUFvQlksSUFBcEIsRUFBMEJGLFVBQTFCLENBQXpCLENBQVA7QUFDRDs7QUFFRCxTQUFTRyxpQkFBVCxDQUEyQkQsSUFBM0IsRUFBaUNFLFFBQWpD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O0FBQzFDLGdCQUFNWCxlQUFlNUMseUJBQXlCb0QsU0FBekIsRUFBb0NqRCxJQUFwQyxDQUFyQjtBQUNBYixjQUFJLHlCQUFKLEVBQStCc0QsWUFBL0I7O0FBRUEsZ0JBQU1ZLDJCQUEyQkosVUFBVVIsWUFBVixDQUFqQztBQUNBLGdCQUFNYSxnQkFBZ0JMLFVBQVVSLGVBQWUsQ0FBekIsQ0FBdEI7QUFDQSxnQkFBTWMsa0JBQWtCaEMsYUFBYTZCLFFBQVEsQ0FBckIsQ0FBeEI7O0FBRUEsY0FBSUcsbUJBQW1CbkUsb0JBQW9CaUUsd0JBQXBCLEVBQThDRSxlQUE5QyxDQUF2QixFQUF1RjtBQUNyRjtBQUNEOztBQUVELGNBQUlEO0FBQ0EsV0FBQ0MsZUFBRCxJQUFvQixDQUFDbkUsb0JBQW9Ca0UsYUFBcEIsRUFBbUNDLGVBQW5DLENBRHJCLENBQUosRUFDK0U7O0FBRTdFL0IsNEJBQWdCNkIsd0JBQWhCLEVBQTBDQyxhQUExQyxFQUF5RCxTQUF6RDtBQUNEO0FBQ0YsU0FqQkQ7QUFrQkQsT0EvQkk7QUFnQ0xFLDJCQUFxQm5CLGNBaENoQjtBQWlDTG9CLDBCQUFvQnBCLGNBakNmO0FBa0NMcUIsK0JBQXlCckIsY0FsQ3BCO0FBbUNMc0Isc0JBQWdCdEIsY0FuQ1g7QUFvQ0x1Qix3QkFBa0J2QixjQXBDYjtBQXFDTHdCLGlCQUFXeEIsY0FyQ047QUFzQ0wsa0NBQTRCQyxjQXRDdkI7QUF1Q0wsaUNBQTJCQSxjQXZDdEI7QUF3Q0wsc0NBQWdDQSxjQXhDM0I7QUF5Q0wsNkJBQXVCQSxjQXpDbEI7QUEwQ0wsK0JBQXlCQSxjQTFDcEI7QUEyQ0wsd0JBQWtCQSxjQTNDYixFQUFQOztBQTZDRCxHQWhJYyxFQUFqQiIsImZpbGUiOiJuZXdsaW5lLWFmdGVyLWltcG9ydC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVvdmVydmlldyBSdWxlIHRvIGVuZm9yY2UgbmV3IGxpbmUgYWZ0ZXIgaW1wb3J0IG5vdCBmb2xsb3dlZCBieSBhbm90aGVyIGltcG9ydC5cbiAqIEBhdXRob3IgUmFkZWsgQmVua2VsXG4gKi9cblxuaW1wb3J0IGlzU3RhdGljUmVxdWlyZSBmcm9tICcuLi9jb3JlL3N0YXRpY1JlcXVpcmUnO1xuaW1wb3J0IGRvY3NVcmwgZnJvbSAnLi4vZG9jc1VybCc7XG5cbmltcG9ydCBkZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5jb25zdCBsb2cgPSBkZWJ1ZygnZXNsaW50LXBsdWdpbi1pbXBvcnQ6cnVsZXM6bmV3bGluZS1hZnRlci1pbXBvcnQnKTtcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGUgRGVmaW5pdGlvblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZnVuY3Rpb24gY29udGFpbnNOb2RlT3JFcXVhbChvdXRlck5vZGUsIGlubmVyTm9kZSkge1xuICByZXR1cm4gb3V0ZXJOb2RlLnJhbmdlWzBdIDw9IGlubmVyTm9kZS5yYW5nZVswXSAmJiBvdXRlck5vZGUucmFuZ2VbMV0gPj0gaW5uZXJOb2RlLnJhbmdlWzFdO1xufVxuXG5mdW5jdGlvbiBnZXRTY29wZUJvZHkoc2NvcGUpIHtcbiAgaWYgKHNjb3BlLmJsb2NrLnR5cGUgPT09ICdTd2l0Y2hTdGF0ZW1lbnQnKSB7XG4gICAgbG9nKCdTd2l0Y2hTdGF0ZW1lbnQgc2NvcGVzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHsgYm9keSB9ID0gc2NvcGUuYmxvY2s7XG4gIGlmIChib2R5ICYmIGJvZHkudHlwZSA9PT0gJ0Jsb2NrU3RhdGVtZW50Jykge1xuICAgIHJldHVybiBib2R5LmJvZHk7XG4gIH1cblxuICByZXR1cm4gYm9keTtcbn1cblxuZnVuY3Rpb24gZmluZE5vZGVJbmRleEluU2NvcGVCb2R5KGJvZHksIG5vZGVUb0ZpbmQpIHtcbiAgcmV0dXJuIGJvZHkuZmluZEluZGV4KChub2RlKSA9PiBjb250YWluc05vZGVPckVxdWFsKG5vZGUsIG5vZGVUb0ZpbmQpKTtcbn1cblxuZnVuY3Rpb24gZ2V0TGluZURpZmZlcmVuY2Uobm9kZSwgbmV4dE5vZGUpIHtcbiAgcmV0dXJuIG5leHROb2RlLmxvYy5zdGFydC5saW5lIC0gbm9kZS5sb2MuZW5kLmxpbmU7XG59XG5cbmZ1bmN0aW9uIGlzQ2xhc3NXaXRoRGVjb3JhdG9yKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ0NsYXNzRGVjbGFyYXRpb24nICYmIG5vZGUuZGVjb3JhdG9ycyAmJiBub2RlLmRlY29yYXRvcnMubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBpc0V4cG9ydERlZmF1bHRDbGFzcyhub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24nICYmIG5vZGUuZGVjbGFyYXRpb24udHlwZSA9PT0gJ0NsYXNzRGVjbGFyYXRpb24nO1xufVxuXG5mdW5jdGlvbiBpc0V4cG9ydE5hbWVDbGFzcyhub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdFeHBvcnROYW1lZERlY2xhcmF0aW9uJyAmJiBub2RlLmRlY2xhcmF0aW9uLnR5cGUgPT09ICdDbGFzc0RlY2xhcmF0aW9uJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG1ldGE6IHtcbiAgICB0eXBlOiAnbGF5b3V0JyxcbiAgICBkb2NzOiB7XG4gICAgICB1cmw6IGRvY3NVcmwoJ25ld2xpbmUtYWZ0ZXItaW1wb3J0JyksXG4gICAgfSxcbiAgICBmaXhhYmxlOiAnd2hpdGVzcGFjZScsXG4gICAgc2NoZW1hOiBbXG4gICAgICB7XG4gICAgICAgICd0eXBlJzogJ29iamVjdCcsXG4gICAgICAgICdwcm9wZXJ0aWVzJzoge1xuICAgICAgICAgICdjb3VudCc6IHtcbiAgICAgICAgICAgICd0eXBlJzogJ2ludGVnZXInLFxuICAgICAgICAgICAgJ21pbmltdW0nOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgICdhZGRpdGlvbmFsUHJvcGVydGllcyc6IGZhbHNlLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuICBjcmVhdGU6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgbGV0IGxldmVsID0gMDtcbiAgICBjb25zdCByZXF1aXJlQ2FsbHMgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGNoZWNrRm9yTmV3TGluZShub2RlLCBuZXh0Tm9kZSwgdHlwZSkge1xuICAgICAgaWYgKGlzRXhwb3J0RGVmYXVsdENsYXNzKG5leHROb2RlKSB8fCBpc0V4cG9ydE5hbWVDbGFzcyhuZXh0Tm9kZSkpIHtcbiAgICAgICAgY29uc3QgY2xhc3NOb2RlID0gbmV4dE5vZGUuZGVjbGFyYXRpb247XG5cbiAgICAgICAgaWYgKGlzQ2xhc3NXaXRoRGVjb3JhdG9yKGNsYXNzTm9kZSkpIHtcbiAgICAgICAgICBuZXh0Tm9kZSA9IGNsYXNzTm9kZS5kZWNvcmF0b3JzWzBdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzQ2xhc3NXaXRoRGVjb3JhdG9yKG5leHROb2RlKSkge1xuICAgICAgICBuZXh0Tm9kZSA9IG5leHROb2RlLmRlY29yYXRvcnNbMF07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb250ZXh0Lm9wdGlvbnNbMF0gfHwgeyBjb3VudDogMSB9O1xuICAgICAgY29uc3QgbGluZURpZmZlcmVuY2UgPSBnZXRMaW5lRGlmZmVyZW5jZShub2RlLCBuZXh0Tm9kZSk7XG4gICAgICBjb25zdCBFWFBFQ1RFRF9MSU5FX0RJRkZFUkVOQ0UgPSBvcHRpb25zLmNvdW50ICsgMTtcblxuICAgICAgaWYgKGxpbmVEaWZmZXJlbmNlIDwgRVhQRUNURURfTElORV9ESUZGRVJFTkNFKSB7XG4gICAgICAgIGxldCBjb2x1bW4gPSBub2RlLmxvYy5zdGFydC5jb2x1bW47XG5cbiAgICAgICAgaWYgKG5vZGUubG9jLnN0YXJ0LmxpbmUgIT09IG5vZGUubG9jLmVuZC5saW5lKSB7XG4gICAgICAgICAgY29sdW1uID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICBsb2M6IHtcbiAgICAgICAgICAgIGxpbmU6IG5vZGUubG9jLmVuZC5saW5lLFxuICAgICAgICAgICAgY29sdW1uLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbWVzc2FnZTogYEV4cGVjdGVkICR7b3B0aW9ucy5jb3VudH0gZW1wdHkgbGluZSR7b3B0aW9ucy5jb3VudCA+IDEgPyAncycgOiAnJ30gXFxcbmFmdGVyICR7dHlwZX0gc3RhdGVtZW50IG5vdCBmb2xsb3dlZCBieSBhbm90aGVyICR7dHlwZX0uYCxcbiAgICAgICAgICBmaXg6IGZpeGVyID0+IGZpeGVyLmluc2VydFRleHRBZnRlcihcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAnXFxuJy5yZXBlYXQoRVhQRUNURURfTElORV9ESUZGRVJFTkNFIC0gbGluZURpZmZlcmVuY2UpXG4gICAgICAgICAgKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5jcmVtZW50TGV2ZWwoKSB7XG4gICAgICBsZXZlbCsrO1xuICAgIH1cbiAgICBmdW5jdGlvbiBkZWNyZW1lbnRMZXZlbCgpIHtcbiAgICAgIGxldmVsLS07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tJbXBvcnQobm9kZSkge1xuICAgICAgY29uc3QgeyBwYXJlbnQgfSA9IG5vZGU7XG4gICAgICBjb25zdCBub2RlUG9zaXRpb24gPSBwYXJlbnQuYm9keS5pbmRleE9mKG5vZGUpO1xuICAgICAgY29uc3QgbmV4dE5vZGUgPSBwYXJlbnQuYm9keVtub2RlUG9zaXRpb24gKyAxXTtcbiAgICAgICAgXG4gICAgICAvLyBza2lwIFwiZXhwb3J0IGltcG9ydFwic1xuICAgICAgaWYgKG5vZGUudHlwZSA9PT0gJ1RTSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24nICYmIG5vZGUuaXNFeHBvcnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV4dE5vZGUgJiYgbmV4dE5vZGUudHlwZSAhPT0gJ0ltcG9ydERlY2xhcmF0aW9uJyAmJiAobmV4dE5vZGUudHlwZSAhPT0gJ1RTSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24nIHx8IG5leHROb2RlLmlzRXhwb3J0KSkge1xuICAgICAgICBjaGVja0Zvck5ld0xpbmUobm9kZSwgbmV4dE5vZGUsICdpbXBvcnQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgSW1wb3J0RGVjbGFyYXRpb246IGNoZWNrSW1wb3J0LFxuICAgICAgVFNJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbjogY2hlY2tJbXBvcnQsXG4gICAgICBDYWxsRXhwcmVzc2lvbjogZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBpZiAoaXNTdGF0aWNSZXF1aXJlKG5vZGUpICYmIGxldmVsID09PSAwKSB7XG4gICAgICAgICAgcmVxdWlyZUNhbGxzLnB1c2gobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAnUHJvZ3JhbTpleGl0JzogZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2coJ2V4aXQgcHJvY2Vzc2luZyBmb3InLCBjb250ZXh0LmdldEZpbGVuYW1lKCkpO1xuICAgICAgICBjb25zdCBzY29wZUJvZHkgPSBnZXRTY29wZUJvZHkoY29udGV4dC5nZXRTY29wZSgpKTtcbiAgICAgICAgbG9nKCdnb3Qgc2NvcGU6Jywgc2NvcGVCb2R5KTtcblxuICAgICAgICByZXF1aXJlQ2FsbHMuZm9yRWFjaChmdW5jdGlvbiAobm9kZSwgaW5kZXgpIHtcbiAgICAgICAgICBjb25zdCBub2RlUG9zaXRpb24gPSBmaW5kTm9kZUluZGV4SW5TY29wZUJvZHkoc2NvcGVCb2R5LCBub2RlKTtcbiAgICAgICAgICBsb2coJ25vZGUgcG9zaXRpb24gaW4gc2NvcGU6Jywgbm9kZVBvc2l0aW9uKTtcblxuICAgICAgICAgIGNvbnN0IHN0YXRlbWVudFdpdGhSZXF1aXJlQ2FsbCA9IHNjb3BlQm9keVtub2RlUG9zaXRpb25dO1xuICAgICAgICAgIGNvbnN0IG5leHRTdGF0ZW1lbnQgPSBzY29wZUJvZHlbbm9kZVBvc2l0aW9uICsgMV07XG4gICAgICAgICAgY29uc3QgbmV4dFJlcXVpcmVDYWxsID0gcmVxdWlyZUNhbGxzW2luZGV4ICsgMV07XG5cbiAgICAgICAgICBpZiAobmV4dFJlcXVpcmVDYWxsICYmIGNvbnRhaW5zTm9kZU9yRXF1YWwoc3RhdGVtZW50V2l0aFJlcXVpcmVDYWxsLCBuZXh0UmVxdWlyZUNhbGwpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5leHRTdGF0ZW1lbnQgJiZcbiAgICAgICAgICAgICAoIW5leHRSZXF1aXJlQ2FsbCB8fCAhY29udGFpbnNOb2RlT3JFcXVhbChuZXh0U3RhdGVtZW50LCBuZXh0UmVxdWlyZUNhbGwpKSkge1xuXG4gICAgICAgICAgICBjaGVja0Zvck5ld0xpbmUoc3RhdGVtZW50V2l0aFJlcXVpcmVDYWxsLCBuZXh0U3RhdGVtZW50LCAncmVxdWlyZScpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgICBGdW5jdGlvbkV4cHJlc3Npb246IGluY3JlbWVudExldmVsLFxuICAgICAgQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246IGluY3JlbWVudExldmVsLFxuICAgICAgQmxvY2tTdGF0ZW1lbnQ6IGluY3JlbWVudExldmVsLFxuICAgICAgT2JqZWN0RXhwcmVzc2lvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgICBEZWNvcmF0b3I6IGluY3JlbWVudExldmVsLFxuICAgICAgJ0Z1bmN0aW9uRGVjbGFyYXRpb246ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgICAgJ0Z1bmN0aW9uRXhwcmVzc2lvbjpleGl0JzogZGVjcmVtZW50TGV2ZWwsXG4gICAgICAnQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgICAgJ0Jsb2NrU3RhdGVtZW50OmV4aXQnOiBkZWNyZW1lbnRMZXZlbCxcbiAgICAgICdPYmplY3RFeHByZXNzaW9uOmV4aXQnOiBkZWNyZW1lbnRMZXZlbCxcbiAgICAgICdEZWNvcmF0b3I6ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgIH07XG4gIH0sXG59O1xuIl19
\No newline at end of file