solve-engine 1.0.1 → 1.1.0

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 (237) hide show
  1. package/dist/{BytecodeBuilder-B0xskcv5.d.cts → BytecodeBuilder-Bp9xeTmX.d.cts} +4 -0
  2. package/dist/{BytecodeBuilder-B0xskcv5.d.ts → BytecodeBuilder-Bp9xeTmX.d.ts} +4 -0
  3. package/dist/{Configuration-B-G5gTRn.d.cts → Configuration-C9W8tJv_.d.cts} +53 -1
  4. package/dist/{Configuration-B-G5gTRn.d.ts → Configuration-C9W8tJv_.d.ts} +53 -1
  5. package/dist/{EngineError-LU7W7AgI.d.cts → EngineError-B61GS1jp.d.cts} +14 -0
  6. package/dist/{EngineError-LU7W7AgI.d.ts → EngineError-B61GS1jp.d.ts} +14 -0
  7. package/dist/FormattingSettings-CJHyxcYu.d.cts +27 -0
  8. package/dist/FormattingSettings-CJHyxcYu.d.ts +27 -0
  9. package/dist/{Lexer-D78E2yDW.d.cts → Lexer-BOs7euZe.d.cts} +58 -1
  10. package/dist/{Lexer-BN5mt30n.d.ts → Lexer-CSI_lwbW.d.ts} +58 -1
  11. package/dist/PackageCompatibility-B-7rK1TD.d.cts +76 -0
  12. package/dist/PackageCompatibility-Dh59eF-X.d.ts +76 -0
  13. package/dist/{PackageRegistry-B37mRvvz.d.cts → PackageRegistry-BHWJP83F.d.cts} +449 -11
  14. package/dist/{PackageRegistry-DCUEzbQt.d.ts → PackageRegistry-_8rDlvxI.d.ts} +449 -11
  15. package/dist/{Parselet-BaySkMV3.d.ts → Parselet-BBT8riYh.d.ts} +12 -3
  16. package/dist/{Parselet-DuI1Pjiq.d.cts → Parselet-BHcgK9S7.d.cts} +12 -3
  17. package/dist/{ScopeManager-B6GzdhVG.d.cts → ScopeManager-8vf02dwj.d.cts} +56 -5
  18. package/dist/{ScopeManager-udv4Twwq.d.ts → ScopeManager-CxA24W5n.d.ts} +56 -5
  19. package/dist/{Token-BzG5G4ja.d.cts → Token-B1hdkedD.d.cts} +9 -0
  20. package/dist/{Token-BzG5G4ja.d.ts → Token-B1hdkedD.d.ts} +9 -0
  21. package/dist/{TokenNormalizer-t_GotBxr.d.ts → TokenNormalizer-C6VzZgHa.d.ts} +1 -1
  22. package/dist/{TokenNormalizer-DGVa24Q-.d.cts → TokenNormalizer-DRc1Js1V.d.cts} +1 -1
  23. package/dist/{VMCheckpoints-DwLjivM7.d.cts → VMCheckpoints-ELYqITdF.d.cts} +3 -3
  24. package/dist/{VMCheckpoints-BiaIlOOY.d.ts → VMCheckpoints-MK--EBH2.d.ts} +3 -3
  25. package/dist/{Value-CXJqDH9J.d.cts → Value-BUi1RA3S.d.cts} +124 -5
  26. package/dist/{Value-CXJqDH9J.d.ts → Value-BUi1RA3S.d.ts} +124 -5
  27. package/dist/WorkerError-_-RkoQ5P.d.ts +75 -0
  28. package/dist/WorkerError-gzmaopj2.d.cts +75 -0
  29. package/dist/{chunk-GQCOSXMG.js → chunk-267JPOTF.js} +43 -5
  30. package/dist/chunk-267JPOTF.js.map +1 -0
  31. package/dist/{chunk-JMXUNXQS.cjs → chunk-2TZKENDH.cjs} +51 -8
  32. package/dist/chunk-2TZKENDH.cjs.map +1 -0
  33. package/dist/chunk-3OWCDIPN.js +215 -0
  34. package/dist/chunk-3OWCDIPN.js.map +1 -0
  35. package/dist/{chunk-VB37OC6I.js → chunk-4D6NIHE2.js} +40 -3
  36. package/dist/chunk-4D6NIHE2.js.map +1 -0
  37. package/dist/{chunk-TY3TLZAW.cjs → chunk-536WPM2V.cjs} +18 -2
  38. package/dist/chunk-536WPM2V.cjs.map +1 -0
  39. package/dist/chunk-5HRB36DK.js +405 -0
  40. package/dist/chunk-5HRB36DK.js.map +1 -0
  41. package/dist/chunk-5ON7PUAZ.js +12 -0
  42. package/dist/chunk-5ON7PUAZ.js.map +1 -0
  43. package/dist/{chunk-KV7UW6T6.js → chunk-7KYSUDQO.js} +12 -5
  44. package/dist/chunk-7KYSUDQO.js.map +1 -0
  45. package/dist/{chunk-6WFMPTGB.cjs → chunk-7ZX6B7SY.cjs} +774 -528
  46. package/dist/chunk-7ZX6B7SY.cjs.map +1 -0
  47. package/dist/chunk-ALYRJ72W.cjs +434 -0
  48. package/dist/chunk-ALYRJ72W.cjs.map +1 -0
  49. package/dist/{chunk-5KMIY374.cjs → chunk-B4HBEFTB.cjs} +17 -2
  50. package/dist/chunk-B4HBEFTB.cjs.map +1 -0
  51. package/dist/chunk-B7NLZMQ3.cjs +74 -0
  52. package/dist/chunk-B7NLZMQ3.cjs.map +1 -0
  53. package/dist/{chunk-UQ3UIZJC.js → chunk-BLI4NIQY.js} +6 -2
  54. package/dist/chunk-BLI4NIQY.js.map +1 -0
  55. package/dist/{chunk-BHTNFEGZ.cjs → chunk-C75AFGVD.cjs} +11 -11
  56. package/dist/{chunk-BHTNFEGZ.cjs.map → chunk-C75AFGVD.cjs.map} +1 -1
  57. package/dist/{chunk-G535KJEG.js → chunk-CCBZZQAE.js} +2 -2
  58. package/dist/{chunk-G535KJEG.js.map → chunk-CCBZZQAE.js.map} +1 -1
  59. package/dist/chunk-CKQMXMHR.cjs +219 -0
  60. package/dist/chunk-CKQMXMHR.cjs.map +1 -0
  61. package/dist/{chunk-PFUESQTW.cjs → chunk-EJ3ILXX6.cjs} +48 -2
  62. package/dist/chunk-EJ3ILXX6.cjs.map +1 -0
  63. package/dist/{chunk-526PMQOA.js → chunk-ENKKJYD3.js} +10 -4
  64. package/dist/chunk-ENKKJYD3.js.map +1 -0
  65. package/dist/{chunk-5X2PTP6F.cjs → chunk-ENRIK36Q.cjs} +2 -12
  66. package/dist/chunk-ENRIK36Q.cjs.map +1 -0
  67. package/dist/{chunk-3D7V24DG.js → chunk-ERCOHGXD.js} +17 -2
  68. package/dist/chunk-ERCOHGXD.js.map +1 -0
  69. package/dist/{chunk-IF532O7C.js → chunk-FD5ZZHEU.js} +3 -12
  70. package/dist/chunk-FD5ZZHEU.js.map +1 -0
  71. package/dist/{chunk-TBN7DEHO.js → chunk-G7Z4HJQA.js} +11 -5
  72. package/dist/chunk-G7Z4HJQA.js.map +1 -0
  73. package/dist/{chunk-QY25VWBF.js → chunk-GQMUHVE3.js} +142 -6
  74. package/dist/chunk-GQMUHVE3.js.map +1 -0
  75. package/dist/chunk-GUG7SNSV.js +1764 -0
  76. package/dist/chunk-GUG7SNSV.js.map +1 -0
  77. package/dist/{chunk-UM6BVY2S.cjs → chunk-HIQ5HSZL.cjs} +175 -43
  78. package/dist/chunk-HIQ5HSZL.cjs.map +1 -0
  79. package/dist/{chunk-HVQFNJKE.cjs → chunk-HVRVSI2Z.cjs} +104 -86
  80. package/dist/chunk-HVRVSI2Z.cjs.map +1 -0
  81. package/dist/{chunk-3LAEG75D.js → chunk-I4GAWIPW.js} +24 -6
  82. package/dist/chunk-I4GAWIPW.js.map +1 -0
  83. package/dist/{chunk-PA4VC73I.cjs → chunk-J45BCEZ4.cjs} +33 -27
  84. package/dist/chunk-J45BCEZ4.cjs.map +1 -0
  85. package/dist/{chunk-V5PYO44Y.js → chunk-JIPATHVY.js} +1853 -2638
  86. package/dist/chunk-JIPATHVY.js.map +1 -0
  87. package/dist/{chunk-YPPPYLSR.js → chunk-JJIXHXFQ.js} +5 -5
  88. package/dist/{chunk-YPPPYLSR.js.map → chunk-JJIXHXFQ.js.map} +1 -1
  89. package/dist/chunk-L2TE7PMO.cjs +14 -0
  90. package/dist/chunk-L2TE7PMO.cjs.map +1 -0
  91. package/dist/{chunk-B7TLZABL.cjs → chunk-MG6Q3DUO.cjs} +1962 -2746
  92. package/dist/chunk-MG6Q3DUO.cjs.map +1 -0
  93. package/dist/{chunk-R3PY4G7J.js → chunk-MVTOCRV2.js} +48 -3
  94. package/dist/chunk-MVTOCRV2.js.map +1 -0
  95. package/dist/{chunk-Y7FT4IQT.js → chunk-NKW7LKYU.js} +266 -28
  96. package/dist/chunk-NKW7LKYU.js.map +1 -0
  97. package/dist/{chunk-O3ANBHSA.js → chunk-NNQ2TYDF.js} +123 -5
  98. package/dist/chunk-NNQ2TYDF.js.map +1 -0
  99. package/dist/{chunk-5F4C26RU.js → chunk-OADDUPT3.js} +4 -4
  100. package/dist/{chunk-5F4C26RU.js.map → chunk-OADDUPT3.js.map} +1 -1
  101. package/dist/{chunk-3AFRJYP4.cjs → chunk-OTN6SZOD.cjs} +1868 -393
  102. package/dist/chunk-OTN6SZOD.cjs.map +1 -0
  103. package/dist/{chunk-5LI5EPGJ.cjs → chunk-QFTDTX6K.cjs} +40 -3
  104. package/dist/chunk-QFTDTX6K.cjs.map +1 -0
  105. package/dist/{chunk-HMOISHXR.js → chunk-RRLHC37V.js} +1530 -57
  106. package/dist/chunk-RRLHC37V.js.map +1 -0
  107. package/dist/chunk-SNHVVOJK.cjs +1768 -0
  108. package/dist/chunk-SNHVVOJK.cjs.map +1 -0
  109. package/dist/{chunk-HDP7VK3C.cjs → chunk-SRGQ72IR.cjs} +649 -349
  110. package/dist/chunk-SRGQ72IR.cjs.map +1 -0
  111. package/dist/{chunk-4B2CNWQU.cjs → chunk-SSV46KFA.cjs} +14 -7
  112. package/dist/chunk-SSV46KFA.cjs.map +1 -0
  113. package/dist/{chunk-AJA6LUI7.js → chunk-UO6BUV6K.js} +18 -2
  114. package/dist/chunk-UO6BUV6K.js.map +1 -0
  115. package/dist/chunk-WWQEY7BV.js +67 -0
  116. package/dist/chunk-WWQEY7BV.js.map +1 -0
  117. package/dist/{chunk-5WVP4YHP.js → chunk-WXEHD6TT.js} +333 -33
  118. package/dist/chunk-WXEHD6TT.js.map +1 -0
  119. package/dist/{chunk-47LRVGOT.cjs → chunk-XA4CKRML.cjs} +2 -2
  120. package/dist/{chunk-47LRVGOT.cjs.map → chunk-XA4CKRML.cjs.map} +1 -1
  121. package/dist/{chunk-6KFYJ6TD.cjs → chunk-XIYYHA65.cjs} +6 -2
  122. package/dist/chunk-XIYYHA65.cjs.map +1 -0
  123. package/dist/{chunk-KBSXGXPM.cjs → chunk-XJGJCF2R.cjs} +6 -6
  124. package/dist/{chunk-KBSXGXPM.cjs.map → chunk-XJGJCF2R.cjs.map} +1 -1
  125. package/dist/{chunk-YWQ6V4ZN.cjs → chunk-YTIYVHL7.cjs} +211 -75
  126. package/dist/chunk-YTIYVHL7.cjs.map +1 -0
  127. package/dist/{chunk-TMA4RCEN.js → chunk-Z7XGGLI2.js} +3 -3
  128. package/dist/{chunk-TMA4RCEN.js.map → chunk-Z7XGGLI2.js.map} +1 -1
  129. package/dist/{chunk-A2N2GFCG.cjs → chunk-ZVTWQLK4.cjs} +10 -10
  130. package/dist/{chunk-A2N2GFCG.cjs.map → chunk-ZVTWQLK4.cjs.map} +1 -1
  131. package/dist/{chunk-2XLQPQKI.cjs → chunk-ZXCESUJS.cjs} +15 -9
  132. package/dist/chunk-ZXCESUJS.cjs.map +1 -0
  133. package/dist/constants.cjs +5 -5
  134. package/dist/constants.d.cts +1 -1
  135. package/dist/constants.d.ts +1 -1
  136. package/dist/constants.js +2 -2
  137. package/dist/engine.cjs +52 -35
  138. package/dist/engine.d.cts +13 -13
  139. package/dist/engine.d.ts +13 -13
  140. package/dist/engine.js +26 -21
  141. package/dist/errors.cjs +44 -19
  142. package/dist/errors.d.cts +3 -2
  143. package/dist/errors.d.ts +3 -2
  144. package/dist/errors.js +2 -1
  145. package/dist/format.cjs +19 -169
  146. package/dist/format.cjs.map +1 -1
  147. package/dist/format.d.cts +18 -26
  148. package/dist/format.d.ts +18 -26
  149. package/dist/format.js +7 -171
  150. package/dist/format.js.map +1 -1
  151. package/dist/index.cjs +250 -31
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.d.cts +110 -74
  154. package/dist/index.d.ts +110 -74
  155. package/dist/index.js +228 -23
  156. package/dist/index.js.map +1 -1
  157. package/dist/language.cjs +9 -9
  158. package/dist/language.d.cts +12 -12
  159. package/dist/language.d.ts +12 -12
  160. package/dist/language.js +3 -3
  161. package/dist/lexer.cjs +16 -16
  162. package/dist/lexer.d.cts +3 -3
  163. package/dist/lexer.d.ts +3 -3
  164. package/dist/lexer.js +5 -5
  165. package/dist/normalizer.cjs +10 -10
  166. package/dist/normalizer.d.cts +3 -3
  167. package/dist/normalizer.d.ts +3 -3
  168. package/dist/normalizer.js +4 -4
  169. package/dist/packages.cjs +45 -36
  170. package/dist/packages.d.cts +135 -31
  171. package/dist/packages.d.ts +135 -31
  172. package/dist/packages.js +14 -13
  173. package/dist/parser.cjs +16 -16
  174. package/dist/parser.d.cts +6 -5
  175. package/dist/parser.d.ts +6 -5
  176. package/dist/parser.js +6 -6
  177. package/dist/{pipeline-BEb3hujr.d.cts → pipeline-CtfJtPQc.d.cts} +3 -3
  178. package/dist/{pipeline-B6k5lCB7.d.ts → pipeline-DCd5M6Gk.d.ts} +3 -3
  179. package/dist/resolvers.d.cts +3 -3
  180. package/dist/resolvers.d.ts +3 -3
  181. package/dist/testing.cjs +478 -0
  182. package/dist/testing.cjs.map +1 -0
  183. package/dist/testing.d.cts +271 -0
  184. package/dist/testing.d.ts +271 -0
  185. package/dist/testing.js +470 -0
  186. package/dist/testing.js.map +1 -0
  187. package/dist/uom.cjs +16 -16
  188. package/dist/uom.d.cts +3 -3
  189. package/dist/uom.d.ts +3 -3
  190. package/dist/uom.js +6 -6
  191. package/dist/utilities.cjs +6 -5
  192. package/dist/utilities.js +2 -1
  193. package/dist/vm.cjs +34 -34
  194. package/dist/vm.d.cts +8 -8
  195. package/dist/vm.d.ts +8 -8
  196. package/dist/vm.js +9 -9
  197. package/dist/worker.cjs +493 -0
  198. package/dist/worker.cjs.map +1 -0
  199. package/dist/worker.d.cts +509 -0
  200. package/dist/worker.d.ts +509 -0
  201. package/dist/worker.js +484 -0
  202. package/dist/worker.js.map +1 -0
  203. package/package.json +21 -1
  204. package/dist/chunk-2XLQPQKI.cjs.map +0 -1
  205. package/dist/chunk-3AFRJYP4.cjs.map +0 -1
  206. package/dist/chunk-3D7V24DG.js.map +0 -1
  207. package/dist/chunk-3LAEG75D.js.map +0 -1
  208. package/dist/chunk-4B2CNWQU.cjs.map +0 -1
  209. package/dist/chunk-526PMQOA.js.map +0 -1
  210. package/dist/chunk-5KMIY374.cjs.map +0 -1
  211. package/dist/chunk-5LI5EPGJ.cjs.map +0 -1
  212. package/dist/chunk-5WVP4YHP.js.map +0 -1
  213. package/dist/chunk-5X2PTP6F.cjs.map +0 -1
  214. package/dist/chunk-6KFYJ6TD.cjs.map +0 -1
  215. package/dist/chunk-6WFMPTGB.cjs.map +0 -1
  216. package/dist/chunk-AJA6LUI7.js.map +0 -1
  217. package/dist/chunk-B7TLZABL.cjs.map +0 -1
  218. package/dist/chunk-GQCOSXMG.js.map +0 -1
  219. package/dist/chunk-HDP7VK3C.cjs.map +0 -1
  220. package/dist/chunk-HMOISHXR.js.map +0 -1
  221. package/dist/chunk-HVQFNJKE.cjs.map +0 -1
  222. package/dist/chunk-IF532O7C.js.map +0 -1
  223. package/dist/chunk-JMXUNXQS.cjs.map +0 -1
  224. package/dist/chunk-KV7UW6T6.js.map +0 -1
  225. package/dist/chunk-O3ANBHSA.js.map +0 -1
  226. package/dist/chunk-PA4VC73I.cjs.map +0 -1
  227. package/dist/chunk-PFUESQTW.cjs.map +0 -1
  228. package/dist/chunk-QY25VWBF.js.map +0 -1
  229. package/dist/chunk-R3PY4G7J.js.map +0 -1
  230. package/dist/chunk-TBN7DEHO.js.map +0 -1
  231. package/dist/chunk-TY3TLZAW.cjs.map +0 -1
  232. package/dist/chunk-UM6BVY2S.cjs.map +0 -1
  233. package/dist/chunk-UQ3UIZJC.js.map +0 -1
  234. package/dist/chunk-V5PYO44Y.js.map +0 -1
  235. package/dist/chunk-VB37OC6I.js.map +0 -1
  236. package/dist/chunk-Y7FT4IQT.js.map +0 -1
  237. package/dist/chunk-YWQ6V4ZN.cjs.map +0 -1
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunk5LI5EPGJ_cjs = require('./chunk-5LI5EPGJ.cjs');
3
+ var chunkQFTDTX6K_cjs = require('./chunk-QFTDTX6K.cjs');
4
4
  var chunkOUHT5Z36_cjs = require('./chunk-OUHT5Z36.cjs');
5
5
  var chunkAQNHHJMJ_cjs = require('./chunk-AQNHHJMJ.cjs');
6
- var chunk5KMIY374_cjs = require('./chunk-5KMIY374.cjs');
6
+ var chunkB4HBEFTB_cjs = require('./chunk-B4HBEFTB.cjs');
7
7
 
8
8
  // src/lexer/ExpressionLexer.ts
9
- chunk5LI5EPGJ_cjs.registerAllTokenTypes();
9
+ chunkQFTDTX6K_cjs.registerAllTokenTypes();
10
10
  function buildCharClassTable() {
11
11
  const table = new Uint8Array(128);
12
12
  for (let i = 48; i <= 57; i++) table[i] = 2 /* DIGIT */;
@@ -184,6 +184,16 @@ var _ExpressionLexer = class _ExpressionLexer {
184
184
  // Line / column tracking (1-indexed)
185
185
  this.line = 1;
186
186
  this.lineStartPos = 0;
187
+ // Open-bracket context stack for the current line, one entry per unclosed
188
+ // `(`/`[`, `true` when a comma inside it is a separator rather than a
189
+ // thousands group. A `[` (vector/matrix) and a CALL `(` (`rgb(255,255,255)`,
190
+ // preceded by an identifier) are separator contexts; a bare GROUPING `(`
191
+ // (`(1,000)`, preceded by an operator or the line start) is not, so a
192
+ // parenthesised thousands number still reads as one scalar. The number scanner
193
+ // consults the innermost entry. Tracked here because the flat token stream
194
+ // carries no nesting otherwise; reset per line, so an unbalanced bracket
195
+ // cannot bleed the decision into the next.
196
+ this.groupingStack = [];
187
197
  // Plugin-extensible keyword map (merged with locale keywordMap)
188
198
  this.pluginKeywordMap = /* @__PURE__ */ new Map();
189
199
  // Plugin-extensible two-char operators: firstChar → (secondChar → tokenType)
@@ -233,7 +243,7 @@ var _ExpressionLexer = class _ExpressionLexer {
233
243
  if (m && typeof m[1] === "string") {
234
244
  const value = m[1].trim();
235
245
  if (value.length > 0) {
236
- return new LexerToken(rule.tokenType, chunk5LI5EPGJ_cjs.tokenTypeId(rule.tokenType), value, value, 0, 0, this.line, 1);
246
+ return new LexerToken(rule.tokenType, chunkQFTDTX6K_cjs.tokenTypeId(rule.tokenType), value, value, 0, 0, this.line, 1);
237
247
  }
238
248
  }
239
249
  }
@@ -263,7 +273,7 @@ var _ExpressionLexer = class _ExpressionLexer {
263
273
  for (const [keyword, tokenType] of Object.entries(plugin.keywords)) {
264
274
  const lower = keyword.toLowerCase();
265
275
  if (this.keywordMap.has(lower)) {
266
- throw chunk5KMIY374_cjs.ErrorFactory.config(
276
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
267
277
  "PLUGIN_KEYWORD_COLLISION",
268
278
  `Plugin keyword "${keyword}" conflicts with built-in keyword (type: ${this.keywordMap.get(lower)}). Built-in keywords cannot be overridden.`,
269
279
  { keyword, builtinType: this.keywordMap.get(lower) }
@@ -281,28 +291,28 @@ var _ExpressionLexer = class _ExpressionLexer {
281
291
  const second = chars.charCodeAt(1);
282
292
  const builtInSecondMap = TWO_CHAR_OPS[first];
283
293
  if (builtInSecondMap && builtInSecondMap[second] !== void 0) {
284
- throw chunk5KMIY374_cjs.ErrorFactory.config(
294
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
285
295
  "PLUGIN_OPERATOR_COLLISION",
286
296
  `Plugin operator "${chars}" conflicts with built-in operator (type: ${builtInSecondMap[second]}). Built-in operators cannot be overridden.`,
287
297
  { operator: chars, builtinType: builtInSecondMap[second] }
288
298
  );
289
299
  }
290
300
  if (first === 60 && second === 60) {
291
- throw chunk5KMIY374_cjs.ErrorFactory.config(
301
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
292
302
  "PLUGIN_OPERATOR_COLLISION",
293
303
  `Plugin operator "${chars}" conflicts with built-in operator (type: LSHIFT). Built-in operators cannot be overridden.`,
294
304
  { operator: chars, builtinType: "LSHIFT" }
295
305
  );
296
306
  }
297
307
  if (first === 62 && second === 62) {
298
- throw chunk5KMIY374_cjs.ErrorFactory.config(
308
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
299
309
  "PLUGIN_OPERATOR_COLLISION",
300
310
  `Plugin operator "${chars}" conflicts with built-in operator (type: RSHIFT). Built-in operators cannot be overridden.`,
301
311
  { operator: chars, builtinType: "RSHIFT" }
302
312
  );
303
313
  }
304
314
  if (first === 47 && second === 47) {
305
- throw chunk5KMIY374_cjs.ErrorFactory.config(
315
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
306
316
  "PLUGIN_OPERATOR_COLLISION",
307
317
  `Plugin operator "${chars}" conflicts with built-in comment sequence. Comment sequences cannot be overridden.`,
308
318
  { operator: chars, builtinType: "COMMENT" }
@@ -320,7 +330,7 @@ var _ExpressionLexer = class _ExpressionLexer {
320
330
  if (plugin.units) {
321
331
  for (const unit of plugin.units) {
322
332
  if (chunkAQNHHJMJ_cjs.knownUnits.has(unit)) {
323
- throw chunk5KMIY374_cjs.ErrorFactory.config(
333
+ throw chunkB4HBEFTB_cjs.ErrorFactory.config(
324
334
  "PLUGIN_UNIT_COLLISION",
325
335
  `Plugin unit "${unit}" conflicts with a built-in unit. Built-in units cannot be overridden.`,
326
336
  { unit }
@@ -440,6 +450,7 @@ var _ExpressionLexer = class _ExpressionLexer {
440
450
  } else {
441
451
  const savedLen = this.len;
442
452
  this.len = lineEnd;
453
+ if (classification.contentOffset !== void 0) this.pos = classification.contentOffset;
443
454
  tokens = Array.from(this);
444
455
  this.len = savedLen;
445
456
  }
@@ -540,20 +551,20 @@ var _ExpressionLexer = class _ExpressionLexer {
540
551
  switch (cc) {
541
552
  case 2 /* DIGIT */:
542
553
  case 4 /* DOT */:
543
- yield new LexerToken("NUMBER", chunk5LI5EPGJ_cjs.tokenTypeId("NUMBER"), this.input, this.input, 0, 0, 1, 1);
554
+ yield new LexerToken("NUMBER", chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"), this.input, this.input, 0, 0, 1, 1);
544
555
  tokenIndex++;
545
556
  break;
546
557
  case 3 /* ALPHA */: {
547
558
  const input2 = this.input;
548
559
  const identLower = input2.toLowerCase();
549
560
  if (this.mergedUnits.has(input2)) {
550
- yield new LexerToken("UNIT", chunk5LI5EPGJ_cjs.tokenTypeId("UNIT"), input2, input2, 0, 0, 1, 1);
561
+ yield new LexerToken("UNIT", chunkQFTDTX6K_cjs.tokenTypeId("UNIT"), input2, input2, 0, 0, 1, 1);
551
562
  } else {
552
563
  const kwType = this.mergedKeywords.get(identLower);
553
564
  if (kwType) {
554
- yield new LexerToken(kwType, chunk5LI5EPGJ_cjs.tokenTypeId(kwType), input2, input2, 0, 0, 1, 1);
565
+ yield new LexerToken(kwType, chunkQFTDTX6K_cjs.tokenTypeId(kwType), input2, input2, 0, 0, 1, 1);
555
566
  } else {
556
- yield new LexerToken("IDENT", chunk5LI5EPGJ_cjs.tokenTypeId("IDENT"), input2, input2, 0, 0, 1, 1);
567
+ yield new LexerToken("IDENT", chunkQFTDTX6K_cjs.tokenTypeId("IDENT"), input2, input2, 0, 0, 1, 1);
557
568
  }
558
569
  }
559
570
  tokenIndex++;
@@ -562,7 +573,7 @@ var _ExpressionLexer = class _ExpressionLexer {
562
573
  case 5 /* OPERATOR */: {
563
574
  const opType = OP_MAP[c0];
564
575
  if (opType) {
565
- yield new LexerToken(opType, chunk5LI5EPGJ_cjs.tokenTypeId(opType), this.input, this.input, 0, 0, 1, 1);
576
+ yield new LexerToken(opType, chunkQFTDTX6K_cjs.tokenTypeId(opType), this.input, this.input, 0, 0, 1, 1);
566
577
  tokenIndex++;
567
578
  }
568
579
  break;
@@ -578,61 +589,64 @@ var _ExpressionLexer = class _ExpressionLexer {
578
589
  tokenIndex++;
579
590
  break;
580
591
  case 8 /* DOLLAR */:
581
- yield new LexerToken("DOLLAR", chunk5LI5EPGJ_cjs.tokenTypeId("DOLLAR"), "$", "$", 0, 0, 1, 1);
592
+ yield new LexerToken("DOLLAR", chunkQFTDTX6K_cjs.tokenTypeId("DOLLAR"), "$", "$", 0, 0, 1, 1);
582
593
  tokenIndex++;
583
594
  break;
584
595
  case 11 /* BACKTICK */:
585
- yield new LexerToken("BACKTICK_OPEN", chunk5LI5EPGJ_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", 0, 0, 1, 1);
596
+ yield new LexerToken("BACKTICK_OPEN", chunkQFTDTX6K_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", 0, 0, 1, 1);
586
597
  tokenIndex++;
587
598
  break;
588
599
  default: {
589
600
  if (isUnicodeSpace(c0)) ; else if (c0 === 215) {
590
- yield new LexerToken("STAR", chunk5LI5EPGJ_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", 0, 0, 1, 1);
601
+ yield new LexerToken("STAR", chunkQFTDTX6K_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", 0, 0, 1, 1);
591
602
  tokenIndex++;
592
603
  } else if (c0 === 247) {
593
- yield new LexerToken("SLASH", chunk5LI5EPGJ_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", 0, 0, 1, 1);
604
+ yield new LexerToken("SLASH", chunkQFTDTX6K_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", 0, 0, 1, 1);
605
+ tokenIndex++;
606
+ } else if (c0 === 177) {
607
+ yield new LexerToken("PLUS_MINUS", chunkQFTDTX6K_cjs.tokenTypeId("PLUS_MINUS"), "\xB1", "\xB1", 0, 0, 1, 1);
594
608
  tokenIndex++;
595
609
  } else if (c0 === 8800) {
596
- yield new LexerToken("NEQ", chunk5LI5EPGJ_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", 0, 0, 1, 1);
610
+ yield new LexerToken("NEQ", chunkQFTDTX6K_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", 0, 0, 1, 1);
597
611
  tokenIndex++;
598
612
  } else if (c0 === 163) {
599
- yield new LexerToken("POUND", chunk5LI5EPGJ_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", 0, 0, 1, 1);
613
+ yield new LexerToken("POUND", chunkQFTDTX6K_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", 0, 0, 1, 1);
600
614
  tokenIndex++;
601
615
  } else if (c0 === 8364) {
602
- yield new LexerToken("EURO", chunk5LI5EPGJ_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", 0, 0, 1, 1);
616
+ yield new LexerToken("EURO", chunkQFTDTX6K_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", 0, 0, 1, 1);
603
617
  tokenIndex++;
604
618
  } else if (c0 === 165) {
605
- yield new LexerToken("YEN", chunk5LI5EPGJ_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", 0, 0, 1, 1);
619
+ yield new LexerToken("YEN", chunkQFTDTX6K_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", 0, 0, 1, 1);
606
620
  tokenIndex++;
607
621
  } else if (c0 === 8381) {
608
- yield new LexerToken("RUBLE", chunk5LI5EPGJ_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", 0, 0, 1, 1);
622
+ yield new LexerToken("RUBLE", chunkQFTDTX6K_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", 0, 0, 1, 1);
609
623
  tokenIndex++;
610
624
  } else if (c0 === 8361) {
611
- yield new LexerToken("WON", chunk5LI5EPGJ_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", 0, 0, 1, 1);
625
+ yield new LexerToken("WON", chunkQFTDTX6K_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", 0, 0, 1, 1);
612
626
  tokenIndex++;
613
627
  } else if (c0 === 8377) {
614
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", 0, 0, 1, 1);
628
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", 0, 0, 1, 1);
615
629
  tokenIndex++;
616
630
  } else if (c0 === 8378) {
617
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", 0, 0, 1, 1);
631
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", 0, 0, 1, 1);
618
632
  tokenIndex++;
619
633
  } else if (c0 === 8372) {
620
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", 0, 0, 1, 1);
634
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", 0, 0, 1, 1);
621
635
  tokenIndex++;
622
636
  } else if (c0 === 8362) {
623
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", 0, 0, 1, 1);
637
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", 0, 0, 1, 1);
624
638
  tokenIndex++;
625
639
  } else if (c0 === 8363) {
626
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", 0, 0, 1, 1);
640
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", 0, 0, 1, 1);
627
641
  tokenIndex++;
628
642
  } else if (c0 === 8358) {
629
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", 0, 0, 1, 1);
643
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", 0, 0, 1, 1);
630
644
  tokenIndex++;
631
645
  } else if (c0 === 8369) {
632
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", 0, 0, 1, 1);
646
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", 0, 0, 1, 1);
633
647
  tokenIndex++;
634
648
  } else if (c0 >= 128) {
635
- yield new LexerToken("IDENT", chunk5LI5EPGJ_cjs.tokenTypeId("IDENT"), this.input, this.input, 0, 0, 1, 1);
649
+ yield new LexerToken("IDENT", chunkQFTDTX6K_cjs.tokenTypeId("IDENT"), this.input, this.input, 0, 0, 1, 1);
636
650
  tokenIndex++;
637
651
  }
638
652
  break;
@@ -642,6 +656,7 @@ var _ExpressionLexer = class _ExpressionLexer {
642
656
  return;
643
657
  }
644
658
  const input = this.input;
659
+ this.groupingStack.length = 0;
645
660
  while (this.pos < len) {
646
661
  const c0 = input.charCodeAt(this.pos);
647
662
  const cc = _ExpressionLexer.CHAR_CLASS[c0] ?? 0 /* SKIP */;
@@ -656,12 +671,14 @@ var _ExpressionLexer = class _ExpressionLexer {
656
671
  if (c0 === 10) {
657
672
  this.line++;
658
673
  this.lineStartPos = this.pos;
674
+ this.groupingStack.length = 0;
659
675
  } else if (c0 === 13) {
660
676
  this.line++;
661
677
  if (this.pos < len && input.charCodeAt(this.pos) === 10) {
662
678
  this.pos++;
663
679
  }
664
680
  this.lineStartPos = this.pos;
681
+ this.groupingStack.length = 0;
665
682
  }
666
683
  break;
667
684
  // ── Digit, inline number tokenizer ───────────────────────────
@@ -687,12 +704,12 @@ var _ExpressionLexer = class _ExpressionLexer {
687
704
  yield this.tokenizeNumber();
688
705
  } else {
689
706
  const col = this.pos - this.lineStartPos + 1;
690
- yield new LexerToken("DOT", chunk5LI5EPGJ_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
707
+ yield new LexerToken("DOT", chunkQFTDTX6K_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
691
708
  this.pos++;
692
709
  }
693
710
  } else {
694
711
  const col = this.pos - this.lineStartPos + 1;
695
- yield new LexerToken("DOT", chunk5LI5EPGJ_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
712
+ yield new LexerToken("DOT", chunkQFTDTX6K_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
696
713
  this.pos++;
697
714
  }
698
715
  tokenIndex++;
@@ -715,7 +732,7 @@ var _ExpressionLexer = class _ExpressionLexer {
715
732
  // ── Dollar sign $ ─────────────────────────────────────────────
716
733
  case 8 /* DOLLAR */: {
717
734
  const col = this.pos - this.lineStartPos + 1;
718
- yield new LexerToken("DOLLAR", chunk5LI5EPGJ_cjs.tokenTypeId("DOLLAR"), "$", "$", this.pos, 0, this.line, col);
735
+ yield new LexerToken("DOLLAR", chunkQFTDTX6K_cjs.tokenTypeId("DOLLAR"), "$", "$", this.pos, 0, this.line, col);
719
736
  this.pos++;
720
737
  tokenIndex++;
721
738
  break;
@@ -723,7 +740,7 @@ var _ExpressionLexer = class _ExpressionLexer {
723
740
  // ── Backtick ` ───────────────────────────────────────────────
724
741
  case 11 /* BACKTICK */: {
725
742
  const col = this.pos - this.lineStartPos + 1;
726
- yield new LexerToken("BACKTICK_OPEN", chunk5LI5EPGJ_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", this.pos, 0, this.line, col);
743
+ yield new LexerToken("BACKTICK_OPEN", chunkQFTDTX6K_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", this.pos, 0, this.line, col);
727
744
  this.pos++;
728
745
  if (openSpan) {
729
746
  const span = openSpan;
@@ -750,63 +767,67 @@ var _ExpressionLexer = class _ExpressionLexer {
750
767
  this.lineStartPos = this.pos;
751
768
  }
752
769
  } else if (c0 === 215) {
753
- yield new LexerToken("STAR", chunk5LI5EPGJ_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", this.pos, 0, this.line, col);
770
+ yield new LexerToken("STAR", chunkQFTDTX6K_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", this.pos, 0, this.line, col);
754
771
  this.pos++;
755
772
  tokenIndex++;
756
773
  } else if (c0 === 247) {
757
- yield new LexerToken("SLASH", chunk5LI5EPGJ_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", this.pos, 0, this.line, col);
774
+ yield new LexerToken("SLASH", chunkQFTDTX6K_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", this.pos, 0, this.line, col);
775
+ this.pos++;
776
+ tokenIndex++;
777
+ } else if (c0 === 177) {
778
+ yield new LexerToken("PLUS_MINUS", chunkQFTDTX6K_cjs.tokenTypeId("PLUS_MINUS"), "\xB1", "\xB1", this.pos, 0, this.line, col);
758
779
  this.pos++;
759
780
  tokenIndex++;
760
781
  } else if (c0 === 8800) {
761
- yield new LexerToken("NEQ", chunk5LI5EPGJ_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", this.pos, 0, this.line, col);
782
+ yield new LexerToken("NEQ", chunkQFTDTX6K_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", this.pos, 0, this.line, col);
762
783
  this.pos++;
763
784
  tokenIndex++;
764
785
  } else if (c0 === 163) {
765
- yield new LexerToken("POUND", chunk5LI5EPGJ_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", this.pos, 0, this.line, col);
786
+ yield new LexerToken("POUND", chunkQFTDTX6K_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", this.pos, 0, this.line, col);
766
787
  this.pos++;
767
788
  tokenIndex++;
768
789
  } else if (c0 === 8364) {
769
- yield new LexerToken("EURO", chunk5LI5EPGJ_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", this.pos, 0, this.line, col);
790
+ yield new LexerToken("EURO", chunkQFTDTX6K_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", this.pos, 0, this.line, col);
770
791
  this.pos++;
771
792
  tokenIndex++;
772
793
  } else if (c0 === 165) {
773
- yield new LexerToken("YEN", chunk5LI5EPGJ_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", this.pos, 0, this.line, col);
794
+ yield new LexerToken("YEN", chunkQFTDTX6K_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", this.pos, 0, this.line, col);
774
795
  this.pos++;
775
796
  tokenIndex++;
776
797
  } else if (c0 === 8381) {
777
- yield new LexerToken("RUBLE", chunk5LI5EPGJ_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", this.pos, 0, this.line, col);
798
+ yield new LexerToken("RUBLE", chunkQFTDTX6K_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", this.pos, 0, this.line, col);
778
799
  this.pos++;
779
800
  tokenIndex++;
780
801
  } else if (c0 === 8361) {
781
- yield new LexerToken("WON", chunk5LI5EPGJ_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", this.pos, 0, this.line, col);
802
+ yield new LexerToken("WON", chunkQFTDTX6K_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", this.pos, 0, this.line, col);
782
803
  this.pos++;
783
804
  tokenIndex++;
784
805
  } else if (c0 === 8377) {
785
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", this.pos, 0, this.line, col);
806
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", this.pos, 0, this.line, col);
786
807
  this.pos++;
787
808
  tokenIndex++;
788
809
  } else if (c0 === 8378) {
789
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", this.pos, 0, this.line, col);
810
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", this.pos, 0, this.line, col);
790
811
  this.pos++;
791
812
  tokenIndex++;
792
813
  } else if (c0 === 8372) {
793
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", this.pos, 0, this.line, col);
814
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", this.pos, 0, this.line, col);
794
815
  this.pos++;
795
816
  tokenIndex++;
796
817
  } else if (c0 === 8362) {
797
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", this.pos, 0, this.line, col);
818
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", this.pos, 0, this.line, col);
798
819
  this.pos++;
799
820
  tokenIndex++;
800
821
  } else if (c0 === 8363) {
801
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", this.pos, 0, this.line, col);
822
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", this.pos, 0, this.line, col);
802
823
  this.pos++;
803
824
  tokenIndex++;
804
825
  } else if (c0 === 8358) {
805
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", this.pos, 0, this.line, col);
826
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", this.pos, 0, this.line, col);
806
827
  this.pos++;
807
828
  tokenIndex++;
808
829
  } else if (c0 === 8369) {
809
- yield new LexerToken("CURRENCY_SYMBOL", chunk5LI5EPGJ_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", this.pos, 0, this.line, col);
830
+ yield new LexerToken("CURRENCY_SYMBOL", chunkQFTDTX6K_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", this.pos, 0, this.line, col);
810
831
  this.pos++;
811
832
  tokenIndex++;
812
833
  } else if (c0 >= 128) {
@@ -847,7 +868,7 @@ var _ExpressionLexer = class _ExpressionLexer {
847
868
  }
848
869
  const text2 = input.slice(start, pos);
849
870
  this.pos = pos;
850
- return new LexerToken("NUMBER", chunk5LI5EPGJ_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
871
+ return new LexerToken("NUMBER", chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
851
872
  }
852
873
  if (next === 98 || next === 66) {
853
874
  pos += 2;
@@ -856,7 +877,7 @@ var _ExpressionLexer = class _ExpressionLexer {
856
877
  }
857
878
  const text2 = input.slice(start, pos);
858
879
  this.pos = pos;
859
- return new LexerToken("NUMBER", chunk5LI5EPGJ_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
880
+ return new LexerToken("NUMBER", chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
860
881
  }
861
882
  if (next === 111 || next === 79) {
862
883
  pos += 2;
@@ -865,7 +886,7 @@ var _ExpressionLexer = class _ExpressionLexer {
865
886
  }
866
887
  const text2 = input.slice(start, pos);
867
888
  this.pos = pos;
868
- return new LexerToken("NUMBER", chunk5LI5EPGJ_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
889
+ return new LexerToken("NUMBER", chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
869
890
  }
870
891
  }
871
892
  let hasIntPart = false;
@@ -874,6 +895,9 @@ var _ExpressionLexer = class _ExpressionLexer {
874
895
  pos++;
875
896
  }
876
897
  while (hasIntPart && pos < len && (input.charCodeAt(pos) === 44 || input.charCodeAt(pos) === 46)) {
898
+ if (input.charCodeAt(pos) === 44 && this.groupingStack.length > 0 && this.groupingStack[this.groupingStack.length - 1]) {
899
+ break;
900
+ }
877
901
  if (pos + 4 <= len) {
878
902
  const d1 = input.charCodeAt(pos + 1);
879
903
  const d2 = input.charCodeAt(pos + 2);
@@ -923,12 +947,12 @@ var _ExpressionLexer = class _ExpressionLexer {
923
947
  pos++;
924
948
  const text2 = input.slice(start, pos);
925
949
  this.pos = pos;
926
- return new LexerToken("BIGINT", chunk5LI5EPGJ_cjs.tokenTypeId("BIGINT"), text2, text2, start, 0, this.line, startCol);
950
+ return new LexerToken("BIGINT", chunkQFTDTX6K_cjs.tokenTypeId("BIGINT"), text2, text2, start, 0, this.line, startCol);
927
951
  }
928
952
  }
929
953
  const text = input.slice(start, pos);
930
954
  this.pos = pos;
931
- return new LexerToken("NUMBER", chunk5LI5EPGJ_cjs.tokenTypeId("NUMBER"), text, text, start, 0, this.line, startCol);
955
+ return new LexerToken("NUMBER", chunkQFTDTX6K_cjs.tokenTypeId("NUMBER"), text, text, start, 0, this.line, startCol);
932
956
  }
933
957
  // ── Inline identifier / keyword tokenizer ──────────────────────────────
934
958
  /**
@@ -960,22 +984,22 @@ var _ExpressionLexer = class _ExpressionLexer {
960
984
  pos++;
961
985
  this.pos = pos;
962
986
  const fullText = input.slice(start, pos);
963
- return new LexerToken("INLINE_SOLVE_START", chunk5LI5EPGJ_cjs.tokenTypeId("INLINE_SOLVE_START"), fullText, fullText, start, 0, this.line, startCol);
987
+ return new LexerToken("INLINE_SOLVE_START", chunkQFTDTX6K_cjs.tokenTypeId("INLINE_SOLVE_START"), fullText, fullText, start, 0, this.line, startCol);
964
988
  }
965
989
  const isKnownUnit = this.mergedUnits.has(identText);
966
990
  if (isKnownUnit) {
967
991
  if (!this.isFollowedByLParen(pos)) {
968
992
  this.pos = pos;
969
- return new LexerToken("UNIT", chunk5LI5EPGJ_cjs.tokenTypeId("UNIT"), identText, identText, start, 0, this.line, startCol);
993
+ return new LexerToken("UNIT", chunkQFTDTX6K_cjs.tokenTypeId("UNIT"), identText, identText, start, 0, this.line, startCol);
970
994
  }
971
995
  }
972
996
  const localeKwType = this.mergedKeywords.get(identLower);
973
997
  if (localeKwType) {
974
998
  this.pos = pos;
975
- return new LexerToken(localeKwType, chunk5LI5EPGJ_cjs.tokenTypeId(localeKwType), identText, identText, start, 0, this.line, startCol);
999
+ return new LexerToken(localeKwType, chunkQFTDTX6K_cjs.tokenTypeId(localeKwType), identText, identText, start, 0, this.line, startCol);
976
1000
  }
977
1001
  this.pos = pos;
978
- return new LexerToken("IDENT", chunk5LI5EPGJ_cjs.tokenTypeId("IDENT"), identText, identText, start, 0, this.line, startCol);
1002
+ return new LexerToken("IDENT", chunkQFTDTX6K_cjs.tokenTypeId("IDENT"), identText, identText, start, 0, this.line, startCol);
979
1003
  }
980
1004
  /**
981
1005
  * Peek past in-expression whitespace (space, tab) from `pos` to check
@@ -993,6 +1017,42 @@ var _ExpressionLexer = class _ExpressionLexer {
993
1017
  return false;
994
1018
  }
995
1019
  // ── Inline operator tokenizer ─────────────────────────────────────────
1020
+ /**
1021
+ * Whether the `(` at `parenPos` opens a function call rather than a bare
1022
+ * grouping, deciding whether a comma inside it is a separator or a thousands
1023
+ * group (see {@link groupingStack}).
1024
+ *
1025
+ * It is a call when the nearest non-whitespace character before it belongs to
1026
+ * the value the call applies to: a closing `)`/`]` (a call on a result), or an
1027
+ * IDENTIFIER (`rgb(`, `vec2(`). A run of digits alone is a number, not an
1028
+ * identifier, so `2(1,000)` is implicit multiplication over the grouping
1029
+ * `(1,000)`, not a call, while `vec2(` and `atan2(` (identifiers that end in a
1030
+ * digit) are calls. A `(` after an operator, a comma, or the line start is a
1031
+ * grouping.
1032
+ */
1033
+ precededByCallTarget(parenPos) {
1034
+ const input = this.input;
1035
+ const start = this.lineStartPos;
1036
+ let i = parenPos - 1;
1037
+ while (i >= start && (input.charCodeAt(i) === 32 || input.charCodeAt(i) === 9)) i--;
1038
+ if (i < start) return false;
1039
+ const c = input.charCodeAt(i);
1040
+ const isWord = (ch) => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95;
1041
+ const isAlpha = (ch) => ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95;
1042
+ if (!isWord(c)) return false;
1043
+ const wordEnd = i + 1;
1044
+ let hasAlpha = false;
1045
+ while (i >= start) {
1046
+ const ch = input.charCodeAt(i);
1047
+ if (!isWord(ch)) break;
1048
+ if (isAlpha(ch)) hasAlpha = true;
1049
+ i--;
1050
+ }
1051
+ if (!hasAlpha) return false;
1052
+ const word = input.slice(i + 1, wordEnd).toLowerCase();
1053
+ const keywordType = this.mergedKeywords.get(word);
1054
+ return keywordType === void 0 || keywordType === "FUNC";
1055
+ }
996
1056
  /**
997
1057
  * Reads an operator/punctuation token.
998
1058
  * Handles two-char operators (==, !=, >=, <=, **) and the special
@@ -1012,7 +1072,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1012
1072
  if (twoCharType) {
1013
1073
  const text2 = input.slice(pos, pos + 2);
1014
1074
  this.pos = pos + 2;
1015
- return new LexerToken(twoCharType, chunk5LI5EPGJ_cjs.tokenTypeId(twoCharType), text2, text2, pos, 0, this.line, col);
1075
+ return new LexerToken(twoCharType, chunkQFTDTX6K_cjs.tokenTypeId(twoCharType), text2, text2, pos, 0, this.line, col);
1016
1076
  }
1017
1077
  }
1018
1078
  if (c0 === 47 && c1 === 47) {
@@ -1024,19 +1084,19 @@ var _ExpressionLexer = class _ExpressionLexer {
1024
1084
  }
1025
1085
  const text2 = input.slice(pos, commentPos);
1026
1086
  this.pos = commentPos;
1027
- return new LexerToken("COMMENT", chunk5LI5EPGJ_cjs.tokenTypeId("COMMENT"), text2, text2, pos, 0, this.line, col);
1087
+ return new LexerToken("COMMENT", chunkQFTDTX6K_cjs.tokenTypeId("COMMENT"), text2, text2, pos, 0, this.line, col);
1028
1088
  }
1029
1089
  if (c0 === 60 && c1 === 60) {
1030
1090
  this.pos = pos + 2;
1031
- return new LexerToken("LSHIFT", chunk5LI5EPGJ_cjs.tokenTypeId("LSHIFT"), "<<", "<<", pos, 0, this.line, col);
1091
+ return new LexerToken("LSHIFT", chunkQFTDTX6K_cjs.tokenTypeId("LSHIFT"), "<<", "<<", pos, 0, this.line, col);
1032
1092
  }
1033
1093
  if (c0 === 62 && c1 === 62) {
1034
1094
  if (input.charCodeAt(pos + 2) === 62) {
1035
1095
  this.pos = pos + 3;
1036
- return new LexerToken("URSHIFT", chunk5LI5EPGJ_cjs.tokenTypeId("URSHIFT"), ">>>", ">>>", pos, 0, this.line, col);
1096
+ return new LexerToken("URSHIFT", chunkQFTDTX6K_cjs.tokenTypeId("URSHIFT"), ">>>", ">>>", pos, 0, this.line, col);
1037
1097
  }
1038
1098
  this.pos = pos + 2;
1039
- return new LexerToken("RSHIFT", chunk5LI5EPGJ_cjs.tokenTypeId("RSHIFT"), ">>", ">>", pos, 0, this.line, col);
1099
+ return new LexerToken("RSHIFT", chunkQFTDTX6K_cjs.tokenTypeId("RSHIFT"), ">>", ">>", pos, 0, this.line, col);
1040
1100
  }
1041
1101
  if (this.hasPluginOps) {
1042
1102
  const pluginInner = this.pluginOperators.get(c0);
@@ -1045,15 +1105,22 @@ var _ExpressionLexer = class _ExpressionLexer {
1045
1105
  if (pluginType) {
1046
1106
  const text2 = input.slice(pos, pos + 2);
1047
1107
  this.pos = pos + 2;
1048
- return new LexerToken(pluginType, chunk5LI5EPGJ_cjs.tokenTypeId(pluginType), text2, text2, pos, 0, this.line, col);
1108
+ return new LexerToken(pluginType, chunkQFTDTX6K_cjs.tokenTypeId(pluginType), text2, text2, pos, 0, this.line, col);
1049
1109
  }
1050
1110
  }
1051
1111
  }
1052
1112
  }
1053
1113
  this.pos = pos + 1;
1114
+ if (c0 === 91) {
1115
+ this.groupingStack.push(true);
1116
+ } else if (c0 === 40) {
1117
+ this.groupingStack.push(this.precededByCallTarget(pos));
1118
+ } else if (c0 === 41 || c0 === 93) {
1119
+ if (this.groupingStack.length > 0) this.groupingStack.pop();
1120
+ }
1054
1121
  const opType = OP_MAP[c0];
1055
1122
  const text = input.charAt(pos);
1056
- return new LexerToken(opType || "ERROR", chunk5LI5EPGJ_cjs.tokenTypeId(opType || "ERROR"), text, text, pos, 0, this.line, col);
1123
+ return new LexerToken(opType || "ERROR", chunkQFTDTX6K_cjs.tokenTypeId(opType || "ERROR"), text, text, pos, 0, this.line, col);
1057
1124
  }
1058
1125
  // ── String literal tokenizer ──────────────────────────────────────────
1059
1126
  /**
@@ -1089,7 +1156,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1089
1156
  const text = input.slice(start, pos);
1090
1157
  const value = input.slice(start + 1, pos - 1);
1091
1158
  this.pos = pos;
1092
- return new LexerToken("STRING", chunk5LI5EPGJ_cjs.tokenTypeId("STRING"), value, text, start, lineBreaks, this.line, startCol);
1159
+ return new LexerToken("STRING", chunkQFTDTX6K_cjs.tokenTypeId("STRING"), value, text, start, lineBreaks, this.line, startCol);
1093
1160
  }
1094
1161
  if (c0 === 92 && pos + 1 < len) {
1095
1162
  pos += 2;
@@ -1103,7 +1170,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1103
1170
  pos++;
1104
1171
  }
1105
1172
  this.pos = pos;
1106
- throw chunk5KMIY374_cjs.ErrorFactory.parsing(
1173
+ throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
1107
1174
  "UNTERMINATED_STRING",
1108
1175
  `Unterminated string literal: ${input.slice(start, pos)}`,
1109
1176
  { literal: input.slice(start, pos), offset: start }
@@ -1139,6 +1206,60 @@ var _ExpressionLexer = class _ExpressionLexer {
1139
1206
  * Reads directly from this.input using start/end boundaries.
1140
1207
  * DOES NOT modify this.pos, purely a read-only classifier.
1141
1208
  */
1209
+ /**
1210
+ * Advance past the whitespace after a list marker, and past a task-item
1211
+ * checkbox if one follows.
1212
+ *
1213
+ * The checkbox is included because it is markup by the same argument the
1214
+ * marker is, and because leaving it stopped the line dead: `- [ ] 100 + 20`
1215
+ * lexed `[ ]` as a matrix literal and reported that a matrix cannot be
1216
+ * empty, which tells a user writing a to-do list nothing they can act on.
1217
+ *
1218
+ * @param from - Offset just past the marker character.
1219
+ * @param end - Line end, never read past.
1220
+ * @returns Offset of the first evaluable character.
1221
+ */
1222
+ skipMarkerGap(from, end) {
1223
+ const input = this.input;
1224
+ let pos = from;
1225
+ while (pos < end && (input.charCodeAt(pos) === 32 || input.charCodeAt(pos) === 9)) pos++;
1226
+ if (pos + 2 < end && input.charCodeAt(pos) === 91 && input.charCodeAt(pos + 2) === 93) {
1227
+ let after = pos + 3;
1228
+ while (after < end && (input.charCodeAt(after) === 32 || input.charCodeAt(after) === 9)) after++;
1229
+ if (after > pos + 3) return after;
1230
+ }
1231
+ return pos;
1232
+ }
1233
+ /**
1234
+ * The end offset (exclusive) of a `#hex` colour literal starting at `hashPos`,
1235
+ * or -1 if the run there is not one. A colour is `#` followed by EXACTLY 3, 4,
1236
+ * 6 or 8 hex digits (the CSS forms `#rgb`/`#rgba`/`#rrggbb`/`#rrggbbaa`) and
1237
+ * then a boundary, not a longer word or number. This is the one predicate that
1238
+ * carves colours out of the two things `#` otherwise means, a markdown heading
1239
+ * at line start and a comment mid-line, and it is pure character logic so line
1240
+ * classification stays vocabulary-independent. Examples: `#f00`, `#ff0000`,
1241
+ * `#deadbeef` match; `# Heading` (space), `#tag`/`#todo` (non-hex letter),
1242
+ * `#12345` (length 5), `#ff0000zz` (trailing word) do not.
1243
+ */
1244
+ matchHexColourEnd(hashPos, end) {
1245
+ const input = this.input;
1246
+ let p = hashPos + 1;
1247
+ let n = 0;
1248
+ while (p < end) {
1249
+ const c = input.charCodeAt(p);
1250
+ const isHex = c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
1251
+ if (!isHex) break;
1252
+ n++;
1253
+ p++;
1254
+ }
1255
+ if (n !== 3 && n !== 4 && n !== 6 && n !== 8) return -1;
1256
+ if (p < end) {
1257
+ const c = input.charCodeAt(p);
1258
+ const isWord = c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
1259
+ if (isWord) return -1;
1260
+ }
1261
+ return p;
1262
+ }
1142
1263
  classifyFromPositions(start, end) {
1143
1264
  const len = end;
1144
1265
  if (start >= len) {
@@ -1157,6 +1278,13 @@ var _ExpressionLexer = class _ExpressionLexer {
1157
1278
  const c0 = input.charCodeAt(pos);
1158
1279
  let hasInline;
1159
1280
  if (c0 === 35) {
1281
+ if (this.matchHexColourEnd(pos, len) !== -1) {
1282
+ if (hasInline === void 0) {
1283
+ const idx = input.indexOf("s`", pos);
1284
+ hasInline = idx !== -1 && idx < len;
1285
+ }
1286
+ return { type: "expression", skip: false, hasInlineSolve: hasInline };
1287
+ }
1160
1288
  let hashCount = 1;
1161
1289
  while (pos + hashCount < len && input.charCodeAt(pos + hashCount) === 35) {
1162
1290
  hashCount++;
@@ -1200,7 +1328,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1200
1328
  const idx = input.indexOf("s`", pos);
1201
1329
  hasInline = idx !== -1 && idx < len;
1202
1330
  }
1203
- return { type: "list", skip: false, hasInlineSolve: hasInline };
1331
+ return { type: "list", skip: false, hasInlineSolve: hasInline, contentOffset: this.skipMarkerGap(pos + 1, len) };
1204
1332
  }
1205
1333
  if (c0 >= 48 && c0 <= 57) {
1206
1334
  let digitPos = pos;
@@ -1213,7 +1341,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1213
1341
  const idx = input.indexOf("s`", pos);
1214
1342
  hasInline = idx !== -1 && idx < len;
1215
1343
  }
1216
- return { type: "list", skip: false, hasInlineSolve: hasInline };
1344
+ return { type: "list", skip: false, hasInlineSolve: hasInline, contentOffset: this.skipMarkerGap(digitPos + 1, len) };
1217
1345
  }
1218
1346
  }
1219
1347
  }
@@ -1342,6 +1470,14 @@ var _ExpressionLexer = class _ExpressionLexer {
1342
1470
  const len = this.len;
1343
1471
  const start = this.pos;
1344
1472
  const startCol = start - this.lineStartPos + 1;
1473
+ if (input.charCodeAt(start) === 35) {
1474
+ const hexEnd = this.matchHexColourEnd(start, len);
1475
+ if (hexEnd !== -1) {
1476
+ const text2 = input.slice(start, hexEnd);
1477
+ this.pos = hexEnd;
1478
+ return new LexerToken("HEX_COLOUR", chunkQFTDTX6K_cjs.tokenTypeId("HEX_COLOUR"), text2, text2, start, 0, this.line, startCol);
1479
+ }
1480
+ }
1345
1481
  let pos = this.pos;
1346
1482
  if (pos + 1 < len && input.charCodeAt(pos + 1) === 47) {
1347
1483
  pos += 2;
@@ -1355,7 +1491,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1355
1491
  }
1356
1492
  const text = input.slice(start, pos);
1357
1493
  this.pos = pos;
1358
- return new LexerToken("COMMENT", chunk5LI5EPGJ_cjs.tokenTypeId("COMMENT"), text, text, start, 0, this.line, startCol);
1494
+ return new LexerToken("COMMENT", chunkQFTDTX6K_cjs.tokenTypeId("COMMENT"), text, text, start, 0, this.line, startCol);
1359
1495
  }
1360
1496
  };
1361
1497
  _ExpressionLexer.CHAR_CLASS = buildCharClassTable();
@@ -1363,5 +1499,5 @@ var ExpressionLexer = _ExpressionLexer;
1363
1499
 
1364
1500
  exports.ExpressionLexer = ExpressionLexer;
1365
1501
  exports.LexerToken = LexerToken;
1366
- //# sourceMappingURL=chunk-YWQ6V4ZN.cjs.map
1367
- //# sourceMappingURL=chunk-YWQ6V4ZN.cjs.map
1502
+ //# sourceMappingURL=chunk-YTIYVHL7.cjs.map
1503
+ //# sourceMappingURL=chunk-YTIYVHL7.cjs.map