less 3.10.0-beta.2 → 3.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.DS_Store +0 -0
  2. package/bin/lessc +6652 -5505
  3. package/dist/less.cjs.js +6593 -5448
  4. package/dist/less.js +10 -6
  5. package/dist/less.min.js +2 -2
  6. package/dist/less.min.js.map +1 -1
  7. package/lib/less/constants.js +13 -0
  8. package/lib/less/contexts.js +164 -0
  9. package/lib/less/data/colors.js +150 -0
  10. package/lib/less/data/index.js +4 -0
  11. package/lib/less/data/unit-conversions.js +21 -0
  12. package/lib/less/default-options.js +68 -0
  13. package/lib/less/environment/abstract-file-manager.js +127 -0
  14. package/lib/less/environment/abstract-plugin-loader.js +187 -0
  15. package/lib/less/environment/environment-api.js +25 -0
  16. package/lib/less/environment/environment.js +59 -0
  17. package/lib/less/environment/file-manager-api.js +103 -0
  18. package/lib/less/functions/boolean.js +13 -0
  19. package/lib/less/functions/color-blending.js +84 -0
  20. package/lib/less/functions/color.js +417 -0
  21. package/lib/less/functions/data-uri.js +74 -0
  22. package/lib/less/functions/default.js +25 -0
  23. package/lib/less/functions/function-caller.js +49 -0
  24. package/lib/less/functions/function-registry.js +35 -0
  25. package/lib/less/functions/index.js +33 -0
  26. package/lib/less/functions/list.js +143 -0
  27. package/lib/less/functions/math-helper.js +15 -0
  28. package/lib/less/functions/math.js +28 -0
  29. package/lib/less/functions/number.js +89 -0
  30. package/lib/less/functions/string.js +36 -0
  31. package/lib/less/functions/svg.js +87 -0
  32. package/lib/less/functions/types.js +70 -0
  33. package/lib/less/import-manager.js +169 -0
  34. package/lib/less/index.js +92 -0
  35. package/lib/less/less-error.js +140 -0
  36. package/lib/less/logger.js +34 -0
  37. package/lib/less/parse-tree.js +66 -0
  38. package/lib/less/parse.js +89 -0
  39. package/lib/less/parser/chunker.js +122 -0
  40. package/lib/less/parser/parser-input.js +390 -0
  41. package/lib/less/parser/parser.js +2418 -0
  42. package/lib/less/plugin-manager.js +168 -0
  43. package/lib/less/render.js +42 -0
  44. package/lib/less/source-map-builder.js +77 -0
  45. package/lib/less/source-map-output.js +149 -0
  46. package/lib/less/transform-tree.js +96 -0
  47. package/lib/less/tree/anonymous.js +37 -0
  48. package/lib/less/tree/assignment.js +33 -0
  49. package/lib/less/tree/atrule.js +165 -0
  50. package/lib/less/tree/attribute.js +34 -0
  51. package/lib/less/tree/call.js +105 -0
  52. package/lib/less/tree/color.js +246 -0
  53. package/lib/less/tree/combinator.js +29 -0
  54. package/lib/less/tree/comment.js +29 -0
  55. package/lib/less/tree/condition.js +43 -0
  56. package/lib/less/tree/debug-info.js +34 -0
  57. package/lib/less/tree/declaration.js +115 -0
  58. package/lib/less/tree/detached-ruleset.js +30 -0
  59. package/lib/less/tree/dimension.js +179 -0
  60. package/lib/less/tree/element.js +73 -0
  61. package/lib/less/tree/expression.js +74 -0
  62. package/lib/less/tree/extend.js +66 -0
  63. package/lib/less/tree/import.js +184 -0
  64. package/lib/less/tree/index.js +54 -0
  65. package/lib/less/tree/javascript.js +33 -0
  66. package/lib/less/tree/js-eval-node.js +58 -0
  67. package/lib/less/tree/keyword.js +21 -0
  68. package/lib/less/tree/media.js +154 -0
  69. package/lib/less/tree/mixin-call.js +215 -0
  70. package/lib/less/tree/mixin-definition.js +229 -0
  71. package/lib/less/tree/namespace-value.js +87 -0
  72. package/lib/less/tree/negative.js +26 -0
  73. package/lib/less/tree/node.js +178 -0
  74. package/lib/less/tree/operation.js +62 -0
  75. package/lib/less/tree/paren.js +22 -0
  76. package/lib/less/tree/property.js +77 -0
  77. package/lib/less/tree/quoted.js +70 -0
  78. package/lib/less/tree/ruleset.js +867 -0
  79. package/lib/less/tree/selector.js +146 -0
  80. package/lib/less/tree/unicode-descriptor.js +13 -0
  81. package/lib/less/tree/unit.js +141 -0
  82. package/lib/less/tree/url.js +65 -0
  83. package/lib/less/tree/value.js +44 -0
  84. package/lib/less/tree/variable-call.js +46 -0
  85. package/lib/less/tree/variable.js +67 -0
  86. package/lib/less/utils.js +122 -0
  87. package/lib/less/visitors/extend-visitor.js +505 -0
  88. package/lib/less/visitors/import-sequencer.js +58 -0
  89. package/lib/less/visitors/import-visitor.js +189 -0
  90. package/lib/less/visitors/index.js +15 -0
  91. package/lib/less/visitors/join-selector-visitor.js +57 -0
  92. package/lib/less/visitors/set-tree-visibility-visitor.js +45 -0
  93. package/lib/less/visitors/to-css-visitor.js +363 -0
  94. package/lib/less/visitors/visitor.js +163 -0
  95. package/lib/less-browser/add-default-options.js +49 -0
  96. package/lib/less-browser/bootstrap.js +69 -0
  97. package/lib/less-browser/browser.js +65 -0
  98. package/lib/less-browser/cache.js +43 -0
  99. package/lib/less-browser/error-reporting.js +170 -0
  100. package/lib/less-browser/file-manager.js +113 -0
  101. package/lib/less-browser/image-size.js +28 -0
  102. package/lib/less-browser/index.js +285 -0
  103. package/lib/less-browser/log-listener.js +42 -0
  104. package/lib/less-browser/plugin-loader.js +26 -0
  105. package/lib/less-browser/utils.js +24 -0
  106. package/lib/less-node/environment.js +16 -0
  107. package/lib/less-node/file-manager.js +177 -0
  108. package/lib/less-node/fs.js +10 -0
  109. package/lib/less-node/image-size.js +58 -0
  110. package/lib/less-node/index.js +27 -0
  111. package/lib/less-node/lessc-helper.js +89 -0
  112. package/lib/less-node/plugin-loader.js +53 -0
  113. package/lib/less-node/url-file-manager.js +49 -0
  114. package/lib/lessc.js +557 -0
  115. package/lib/source-map/source-map-0.1.31.js +1933 -0
  116. package/lib/source-map/source-map-footer.js +4 -0
  117. package/lib/source-map/source-map-header.js +3 -0
  118. package/package.json +1 -1
  119. package/test/.DS_Store +0 -0
  120. package/test/browser/less.min.js +11 -0
  121. package/test/browser/less.min.js.map +1 -0
  122. package/test/css/css-escapes.css +1 -0
  123. package/test/less/css-escapes.less +3 -1
  124. package/.git/index +0 -0
@@ -0,0 +1,92 @@
1
+ import data from './data';
2
+ import tree from './tree';
3
+ import Environment from './environment/environment';
4
+ import AbstractFileManager from './environment/abstract-file-manager';
5
+ import AbstractPluginLoader from './environment/abstract-plugin-loader';
6
+ import visitors from './visitors';
7
+ import Parser from './parser/parser';
8
+ import Functions from './functions';
9
+ import contexts from './contexts';
10
+ import sourceMapOutput from './source-map-output';
11
+ import sourceMapBuilder from './source-map-builder';
12
+ import parseTree from './parse-tree';
13
+ import importManager from './import-manager';
14
+ import Render from './render';
15
+ import Parse from './parse';
16
+ import LessError from './less-error';
17
+ import transformTree from './transform-tree';
18
+ import * as utils from './utils';
19
+ import PluginManager from './plugin-manager';
20
+ import logger from './logger';
21
+
22
+ export default (environment, fileManagers) => {
23
+ /**
24
+ * @todo
25
+ * This original code could be improved quite a bit.
26
+ * Many classes / modules currently add side-effects / mutations to passed in objects,
27
+ * which makes it hard to refactor and reason about.
28
+ */
29
+ environment = new Environment(environment, fileManagers);
30
+
31
+ const SourceMapOutput = sourceMapOutput(environment);
32
+ const SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment);
33
+ const ParseTree = parseTree(SourceMapBuilder);
34
+ const ImportManager = importManager(environment);
35
+ const render = Render(environment, ParseTree, ImportManager);
36
+ const parse = Parse(environment, ParseTree, ImportManager);
37
+ const functions = Functions(environment);
38
+
39
+ /**
40
+ * @todo
41
+ * This root properties / methods need to be organized.
42
+ * It's not clear what should / must be public and why.
43
+ */
44
+ const initial = {
45
+ version: [3, 10, 3],
46
+ data,
47
+ tree,
48
+ Environment,
49
+ AbstractFileManager,
50
+ AbstractPluginLoader,
51
+ environment,
52
+ visitors,
53
+ Parser,
54
+ functions,
55
+ contexts,
56
+ SourceMapOutput,
57
+ SourceMapBuilder,
58
+ ParseTree,
59
+ ImportManager,
60
+ render,
61
+ parse,
62
+ LessError,
63
+ transformTree,
64
+ utils,
65
+ PluginManager,
66
+ logger
67
+ };
68
+
69
+ // Create a public API
70
+ const ctor = t => function (...args) {
71
+ return new t(...args);
72
+ };
73
+
74
+ let t;
75
+ const api = Object.create(initial);
76
+ for (const n in initial.tree) {
77
+ /* eslint guard-for-in: 0 */
78
+ t = initial.tree[n];
79
+ if (typeof t === 'function') {
80
+ api[n.toLowerCase()] = ctor(t);
81
+ }
82
+ else {
83
+ api[n] = Object.create(null);
84
+ for (const o in t) {
85
+ /* eslint guard-for-in: 0 */
86
+ api[n][o.toLowerCase()] = ctor(t[o]);
87
+ }
88
+ }
89
+ }
90
+
91
+ return api;
92
+ };
@@ -0,0 +1,140 @@
1
+ import * as utils from './utils';
2
+ /**
3
+ * This is a centralized class of any error that could be thrown internally (mostly by the parser).
4
+ * Besides standard .message it keeps some additional data like a path to the file where the error
5
+ * occurred along with line and column numbers.
6
+ *
7
+ * @class
8
+ * @extends Error
9
+ * @type {module.LessError}
10
+ *
11
+ * @prop {string} type
12
+ * @prop {string} filename
13
+ * @prop {number} index
14
+ * @prop {number} line
15
+ * @prop {number} column
16
+ * @prop {number} callLine
17
+ * @prop {number} callExtract
18
+ * @prop {string[]} extract
19
+ *
20
+ * @param {Object} e - An error object to wrap around or just a descriptive object
21
+ * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?
22
+ * @param {string} [currentFilename]
23
+ */
24
+ const LessError = function LessError(e, fileContentMap, currentFilename) {
25
+ Error.call(this);
26
+
27
+ const filename = e.filename || currentFilename;
28
+
29
+ this.message = e.message;
30
+ this.stack = e.stack;
31
+
32
+ if (fileContentMap && filename) {
33
+ const input = fileContentMap.contents[filename];
34
+ const loc = utils.getLocation(e.index, input);
35
+ const line = loc.line;
36
+ const col = loc.column;
37
+ const callLine = e.call && utils.getLocation(e.call, input).line;
38
+ const lines = input ? input.split('\n') : '';
39
+
40
+ this.type = e.type || 'Syntax';
41
+ this.filename = filename;
42
+ this.index = e.index;
43
+ this.line = typeof line === 'number' ? line + 1 : null;
44
+ this.column = col;
45
+
46
+ if (!this.line && this.stack) {
47
+ const found = this.stack.match(/(<anonymous>|Function):(\d+):(\d+)/);
48
+
49
+ if (found) {
50
+ if (found[2]) {
51
+ this.line = parseInt(found[2]) - 2;
52
+ }
53
+ if (found[3]) {
54
+ this.column = parseInt(found[3]);
55
+ }
56
+ }
57
+ }
58
+
59
+ this.callLine = callLine + 1;
60
+ this.callExtract = lines[callLine];
61
+
62
+ this.extract = [
63
+ lines[this.line - 2],
64
+ lines[this.line - 1],
65
+ lines[this.line]
66
+ ];
67
+ }
68
+
69
+ };
70
+
71
+ if (typeof Object.create === 'undefined') {
72
+ const F = () => {};
73
+ F.prototype = Error.prototype;
74
+ LessError.prototype = new F();
75
+ } else {
76
+ LessError.prototype = Object.create(Error.prototype);
77
+ }
78
+
79
+ LessError.prototype.constructor = LessError;
80
+
81
+ /**
82
+ * An overridden version of the default Object.prototype.toString
83
+ * which uses additional information to create a helpful message.
84
+ *
85
+ * @param {Object} options
86
+ * @returns {string}
87
+ */
88
+ LessError.prototype.toString = function(options = {}) {
89
+ let message = '';
90
+ const extract = this.extract || [];
91
+ let error = [];
92
+ let stylize = str => str;
93
+ if (options.stylize) {
94
+ const type = typeof options.stylize;
95
+ if (type !== 'function') {
96
+ throw Error(`options.stylize should be a function, got a ${type}!`);
97
+ }
98
+ stylize = options.stylize;
99
+ }
100
+
101
+ if (this.line !== null) {
102
+ if (typeof extract[0] === 'string') {
103
+ error.push(stylize(`${this.line - 1} ${extract[0]}`, 'grey'));
104
+ }
105
+
106
+ if (typeof extract[1] === 'string') {
107
+ let errorTxt = `${this.line} `;
108
+ if (extract[1]) {
109
+ errorTxt += extract[1].slice(0, this.column) +
110
+ stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +
111
+ extract[1].slice(this.column + 1), 'red'), 'inverse');
112
+ }
113
+ error.push(errorTxt);
114
+ }
115
+
116
+ if (typeof extract[2] === 'string') {
117
+ error.push(stylize(`${this.line + 1} ${extract[2]}`, 'grey'));
118
+ }
119
+ error = `${error.join('\n') + stylize('', 'reset')}\n`;
120
+ }
121
+
122
+ message += stylize(`${this.type}Error: ${this.message}`, 'red');
123
+ if (this.filename) {
124
+ message += stylize(' in ', 'red') + this.filename;
125
+ }
126
+ if (this.line) {
127
+ message += stylize(` on line ${this.line}, column ${this.column + 1}:`, 'grey');
128
+ }
129
+
130
+ message += `\n${error}`;
131
+
132
+ if (this.callLine) {
133
+ message += `${stylize('from ', 'red') + (this.filename || '')}/n`;
134
+ message += `${stylize(this.callLine, 'grey')} ${this.callExtract}/n`;
135
+ }
136
+
137
+ return message;
138
+ };
139
+
140
+ export default LessError;
@@ -0,0 +1,34 @@
1
+ export default {
2
+ error: function(msg) {
3
+ this._fireEvent('error', msg);
4
+ },
5
+ warn: function(msg) {
6
+ this._fireEvent('warn', msg);
7
+ },
8
+ info: function(msg) {
9
+ this._fireEvent('info', msg);
10
+ },
11
+ debug: function(msg) {
12
+ this._fireEvent('debug', msg);
13
+ },
14
+ addListener: function(listener) {
15
+ this._listeners.push(listener);
16
+ },
17
+ removeListener: function(listener) {
18
+ for (let i = 0; i < this._listeners.length; i++) {
19
+ if (this._listeners[i] === listener) {
20
+ this._listeners.splice(i, 1);
21
+ return;
22
+ }
23
+ }
24
+ },
25
+ _fireEvent: function(type, msg) {
26
+ for (let i = 0; i < this._listeners.length; i++) {
27
+ const logFunction = this._listeners[i][type];
28
+ if (logFunction) {
29
+ logFunction(msg);
30
+ }
31
+ }
32
+ },
33
+ _listeners: []
34
+ };
@@ -0,0 +1,66 @@
1
+ import LessError from './less-error';
2
+ import transformTree from './transform-tree';
3
+ import logger from './logger';
4
+
5
+ export default SourceMapBuilder => {
6
+ class ParseTree {
7
+ constructor(root, imports) {
8
+ this.root = root;
9
+ this.imports = imports;
10
+ }
11
+
12
+ toCSS(options) {
13
+ let evaldRoot;
14
+ const result = {};
15
+ let sourceMapBuilder;
16
+ try {
17
+ evaldRoot = transformTree(this.root, options);
18
+ } catch (e) {
19
+ throw new LessError(e, this.imports);
20
+ }
21
+
22
+ try {
23
+ const compress = Boolean(options.compress);
24
+ if (compress) {
25
+ logger.warn('The compress option has been deprecated. ' +
26
+ 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');
27
+ }
28
+
29
+ const toCSSOptions = {
30
+ compress,
31
+ dumpLineNumbers: options.dumpLineNumbers,
32
+ strictUnits: Boolean(options.strictUnits),
33
+ numPrecision: 8};
34
+
35
+ if (options.sourceMap) {
36
+ sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
37
+ result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
38
+ } else {
39
+ result.css = evaldRoot.toCSS(toCSSOptions);
40
+ }
41
+ } catch (e) {
42
+ throw new LessError(e, this.imports);
43
+ }
44
+
45
+ if (options.pluginManager) {
46
+ const postProcessors = options.pluginManager.getPostProcessors();
47
+ for (let i = 0; i < postProcessors.length; i++) {
48
+ result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options, imports: this.imports });
49
+ }
50
+ }
51
+ if (options.sourceMap) {
52
+ result.map = sourceMapBuilder.getExternalSourceMap();
53
+ }
54
+
55
+ result.imports = [];
56
+ for (const file in this.imports.files) {
57
+ if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) {
58
+ result.imports.push(file);
59
+ }
60
+ }
61
+ return result;
62
+ }
63
+ }
64
+
65
+ return ParseTree;
66
+ };
@@ -0,0 +1,89 @@
1
+ let PromiseConstructor;
2
+ import contexts from './contexts';
3
+ import Parser from './parser/parser';
4
+ import PluginManager from './plugin-manager';
5
+ import LessError from './less-error';
6
+ import * as utils from './utils';
7
+
8
+ export default (environment, ParseTree, ImportManager) => {
9
+ const parse = function (input, options, callback) {
10
+
11
+ if (typeof options === 'function') {
12
+ callback = options;
13
+ options = utils.copyOptions(this.options, {});
14
+ }
15
+ else {
16
+ options = utils.copyOptions(this.options, options || {});
17
+ }
18
+
19
+ if (!callback) {
20
+ const self = this;
21
+ return new Promise((resolve, reject) => {
22
+ parse.call(self, input, options, (err, output) => {
23
+ if (err) {
24
+ reject(err);
25
+ } else {
26
+ resolve(output);
27
+ }
28
+ });
29
+ });
30
+ } else {
31
+ let context;
32
+ let rootFileInfo;
33
+ const pluginManager = new PluginManager(this, !options.reUsePluginManager);
34
+
35
+ options.pluginManager = pluginManager;
36
+
37
+ context = new contexts.Parse(options);
38
+
39
+ if (options.rootFileInfo) {
40
+ rootFileInfo = options.rootFileInfo;
41
+ } else {
42
+ const filename = options.filename || 'input';
43
+ const entryPath = filename.replace(/[^\/\\]*$/, '');
44
+ rootFileInfo = {
45
+ filename,
46
+ rewriteUrls: context.rewriteUrls,
47
+ rootpath: context.rootpath || '',
48
+ currentDirectory: entryPath,
49
+ entryPath,
50
+ rootFilename: filename
51
+ };
52
+ // add in a missing trailing slash
53
+ if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {
54
+ rootFileInfo.rootpath += '/';
55
+ }
56
+ }
57
+
58
+ const imports = new ImportManager(this, context, rootFileInfo);
59
+ this.importManager = imports;
60
+
61
+ // TODO: allow the plugins to be just a list of paths or names
62
+ // Do an async plugin queue like lessc
63
+
64
+ if (options.plugins) {
65
+ options.plugins.forEach(plugin => {
66
+ let evalResult;
67
+ let contents;
68
+ if (plugin.fileContent) {
69
+ contents = plugin.fileContent.replace(/^\uFEFF/, '');
70
+ evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename);
71
+ if (evalResult instanceof LessError) {
72
+ return callback(evalResult);
73
+ }
74
+ }
75
+ else {
76
+ pluginManager.addPlugin(plugin);
77
+ }
78
+ });
79
+ }
80
+
81
+ new Parser(context, imports, rootFileInfo)
82
+ .parse(input, (e, root) => {
83
+ if (e) { return callback(e); }
84
+ callback(null, root, imports, options);
85
+ }, options);
86
+ }
87
+ };
88
+ return parse;
89
+ };
@@ -0,0 +1,122 @@
1
+ // Split the input into chunks.
2
+ export default (input, fail) => {
3
+ const len = input.length;
4
+ let level = 0;
5
+ let parenLevel = 0;
6
+ let lastOpening;
7
+ let lastOpeningParen;
8
+ let lastMultiComment;
9
+ let lastMultiCommentEndBrace;
10
+ const chunks = [];
11
+ let emitFrom = 0;
12
+ let chunkerCurrentIndex;
13
+ let currentChunkStartIndex;
14
+ let cc;
15
+ let cc2;
16
+ let matched;
17
+
18
+ function emitChunk(force) {
19
+ const len = chunkerCurrentIndex - emitFrom;
20
+ if (((len < 512) && !force) || !len) {
21
+ return;
22
+ }
23
+ chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
24
+ emitFrom = chunkerCurrentIndex + 1;
25
+ }
26
+
27
+ for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
28
+ cc = input.charCodeAt(chunkerCurrentIndex);
29
+ if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
30
+ // a-z or whitespace
31
+ continue;
32
+ }
33
+
34
+ switch (cc) {
35
+ case 40: // (
36
+ parenLevel++;
37
+ lastOpeningParen = chunkerCurrentIndex;
38
+ continue;
39
+ case 41: // )
40
+ if (--parenLevel < 0) {
41
+ return fail('missing opening `(`', chunkerCurrentIndex);
42
+ }
43
+ continue;
44
+ case 59: // ;
45
+ if (!parenLevel) { emitChunk(); }
46
+ continue;
47
+ case 123: // {
48
+ level++;
49
+ lastOpening = chunkerCurrentIndex;
50
+ continue;
51
+ case 125: // }
52
+ if (--level < 0) {
53
+ return fail('missing opening `{`', chunkerCurrentIndex);
54
+ }
55
+ if (!level && !parenLevel) { emitChunk(); }
56
+ continue;
57
+ case 92: // \
58
+ if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
59
+ return fail('unescaped `\\`', chunkerCurrentIndex);
60
+ case 34:
61
+ case 39:
62
+ case 96: // ", ' and `
63
+ matched = 0;
64
+ currentChunkStartIndex = chunkerCurrentIndex;
65
+ for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
66
+ cc2 = input.charCodeAt(chunkerCurrentIndex);
67
+ if (cc2 > 96) { continue; }
68
+ if (cc2 == cc) { matched = 1; break; }
69
+ if (cc2 == 92) { // \
70
+ if (chunkerCurrentIndex == len - 1) {
71
+ return fail('unescaped `\\`', chunkerCurrentIndex);
72
+ }
73
+ chunkerCurrentIndex++;
74
+ }
75
+ }
76
+ if (matched) { continue; }
77
+ return fail(`unmatched \`${String.fromCharCode(cc)}\``, currentChunkStartIndex);
78
+ case 47: // /, check for comment
79
+ if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
80
+ cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
81
+ if (cc2 == 47) {
82
+ // //, find lnfeed
83
+ for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
84
+ cc2 = input.charCodeAt(chunkerCurrentIndex);
85
+ if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }
86
+ }
87
+ } else if (cc2 == 42) {
88
+ // /*, find */
89
+ lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
90
+ for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
91
+ cc2 = input.charCodeAt(chunkerCurrentIndex);
92
+ if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }
93
+ if (cc2 != 42) { continue; }
94
+ if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
95
+ }
96
+ if (chunkerCurrentIndex == len - 1) {
97
+ return fail('missing closing `*/`', currentChunkStartIndex);
98
+ }
99
+ chunkerCurrentIndex++;
100
+ }
101
+ continue;
102
+ case 42: // *, check for unmatched */
103
+ if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
104
+ return fail('unmatched `/*`', chunkerCurrentIndex);
105
+ }
106
+ continue;
107
+ }
108
+ }
109
+
110
+ if (level !== 0) {
111
+ if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
112
+ return fail('missing closing `}` or `*/`', lastOpening);
113
+ } else {
114
+ return fail('missing closing `}`', lastOpening);
115
+ }
116
+ } else if (parenLevel !== 0) {
117
+ return fail('missing closing `)`', lastOpeningParen);
118
+ }
119
+
120
+ emitChunk(true);
121
+ return chunks;
122
+ };