solve-engine 1.0.2 → 1.1.1

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-DpjdaQ98.d.cts → Lexer-BOs7euZe.d.cts} +28 -1
  10. package/dist/{Lexer-CNmWxabg.d.ts → Lexer-CSI_lwbW.d.ts} +28 -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-zuzqt51V.d.cts → PackageRegistry-BHWJP83F.d.cts} +449 -11
  14. package/dist/{PackageRegistry-ClIFXxAe.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-YXCTLWOH.js → chunk-4HQKTMWG.js} +1530 -57
  38. package/dist/chunk-4HQKTMWG.js.map +1 -0
  39. package/dist/{chunk-TY3TLZAW.cjs → chunk-536WPM2V.cjs} +18 -2
  40. package/dist/chunk-536WPM2V.cjs.map +1 -0
  41. package/dist/chunk-5HRB36DK.js +405 -0
  42. package/dist/chunk-5HRB36DK.js.map +1 -0
  43. package/dist/chunk-5ON7PUAZ.js +12 -0
  44. package/dist/chunk-5ON7PUAZ.js.map +1 -0
  45. package/dist/{chunk-KV7UW6T6.js → chunk-7KYSUDQO.js} +12 -5
  46. package/dist/chunk-7KYSUDQO.js.map +1 -0
  47. package/dist/{chunk-6WFMPTGB.cjs → chunk-7ZX6B7SY.cjs} +774 -528
  48. package/dist/chunk-7ZX6B7SY.cjs.map +1 -0
  49. package/dist/chunk-ALYRJ72W.cjs +434 -0
  50. package/dist/chunk-ALYRJ72W.cjs.map +1 -0
  51. package/dist/{chunk-5KMIY374.cjs → chunk-B4HBEFTB.cjs} +17 -2
  52. package/dist/chunk-B4HBEFTB.cjs.map +1 -0
  53. package/dist/chunk-B7NLZMQ3.cjs +74 -0
  54. package/dist/chunk-B7NLZMQ3.cjs.map +1 -0
  55. package/dist/{chunk-UQ3UIZJC.js → chunk-BLI4NIQY.js} +6 -2
  56. package/dist/chunk-BLI4NIQY.js.map +1 -0
  57. package/dist/{chunk-IP7ASJEW.js → chunk-BYJBUL7U.js} +5 -5
  58. package/dist/{chunk-IP7ASJEW.js.map → chunk-BYJBUL7U.js.map} +1 -1
  59. package/dist/{chunk-G535KJEG.js → chunk-CCBZZQAE.js} +2 -2
  60. package/dist/{chunk-G535KJEG.js.map → chunk-CCBZZQAE.js.map} +1 -1
  61. package/dist/chunk-CKQMXMHR.cjs +219 -0
  62. package/dist/chunk-CKQMXMHR.cjs.map +1 -0
  63. package/dist/{chunk-T556MJDZ.cjs → chunk-CUR2WLI4.cjs} +11 -11
  64. package/dist/{chunk-T556MJDZ.cjs.map → chunk-CUR2WLI4.cjs.map} +1 -1
  65. package/dist/{chunk-AA3KTWTX.js → chunk-DLEBSLF4.js} +4 -4
  66. package/dist/{chunk-AA3KTWTX.js.map → chunk-DLEBSLF4.js.map} +1 -1
  67. package/dist/{chunk-524F3ATQ.cjs → chunk-E23GZEWL.cjs} +15 -9
  68. package/dist/chunk-E23GZEWL.cjs.map +1 -0
  69. package/dist/{chunk-PFUESQTW.cjs → chunk-EJ3ILXX6.cjs} +48 -2
  70. package/dist/chunk-EJ3ILXX6.cjs.map +1 -0
  71. package/dist/{chunk-526PMQOA.js → chunk-ENKKJYD3.js} +10 -4
  72. package/dist/chunk-ENKKJYD3.js.map +1 -0
  73. package/dist/{chunk-5X2PTP6F.cjs → chunk-ENRIK36Q.cjs} +2 -12
  74. package/dist/chunk-ENRIK36Q.cjs.map +1 -0
  75. package/dist/{chunk-3D7V24DG.js → chunk-ERCOHGXD.js} +17 -2
  76. package/dist/chunk-ERCOHGXD.js.map +1 -0
  77. package/dist/{chunk-IF532O7C.js → chunk-FD5ZZHEU.js} +3 -12
  78. package/dist/chunk-FD5ZZHEU.js.map +1 -0
  79. package/dist/{chunk-7FSDNNNC.js → chunk-GLA4JXBO.js} +11 -5
  80. package/dist/chunk-GLA4JXBO.js.map +1 -0
  81. package/dist/{chunk-UM6BVY2S.cjs → chunk-HIQ5HSZL.cjs} +175 -43
  82. package/dist/chunk-HIQ5HSZL.cjs.map +1 -0
  83. package/dist/{chunk-HVQFNJKE.cjs → chunk-HVRVSI2Z.cjs} +104 -86
  84. package/dist/chunk-HVRVSI2Z.cjs.map +1 -0
  85. package/dist/{chunk-3LAEG75D.js → chunk-I4GAWIPW.js} +24 -6
  86. package/dist/chunk-I4GAWIPW.js.map +1 -0
  87. package/dist/{chunk-PA4VC73I.cjs → chunk-J45BCEZ4.cjs} +33 -27
  88. package/dist/chunk-J45BCEZ4.cjs.map +1 -0
  89. package/dist/{chunk-FQGX2PA2.js → chunk-JG6ZJ2WU.js} +128 -4
  90. package/dist/chunk-JG6ZJ2WU.js.map +1 -0
  91. package/dist/chunk-L2TE7PMO.cjs +14 -0
  92. package/dist/chunk-L2TE7PMO.cjs.map +1 -0
  93. package/dist/chunk-LHZ6VOA7.js +1764 -0
  94. package/dist/chunk-LHZ6VOA7.js.map +1 -0
  95. package/dist/{chunk-SESSWASV.cjs → chunk-MN3LHRGV.cjs} +1868 -393
  96. package/dist/chunk-MN3LHRGV.cjs.map +1 -0
  97. package/dist/{chunk-R3PY4G7J.js → chunk-MVTOCRV2.js} +48 -3
  98. package/dist/chunk-MVTOCRV2.js.map +1 -0
  99. package/dist/{chunk-FE23VSSA.cjs → chunk-N5NNW4VG.cjs} +6 -6
  100. package/dist/{chunk-FE23VSSA.cjs.map → chunk-N5NNW4VG.cjs.map} +1 -1
  101. package/dist/{chunk-Y7FT4IQT.js → chunk-NKW7LKYU.js} +266 -28
  102. package/dist/chunk-NKW7LKYU.js.map +1 -0
  103. package/dist/{chunk-O3ANBHSA.js → chunk-NNQ2TYDF.js} +123 -5
  104. package/dist/chunk-NNQ2TYDF.js.map +1 -0
  105. package/dist/{chunk-NG2JHZHE.js → chunk-NNZAEUDW.js} +1853 -2640
  106. package/dist/chunk-NNZAEUDW.js.map +1 -0
  107. package/dist/{chunk-5LI5EPGJ.cjs → chunk-QFTDTX6K.cjs} +40 -3
  108. package/dist/chunk-QFTDTX6K.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-HBVFFBRR.cjs → chunk-T6ZYQJ63.cjs} +1962 -2748
  114. package/dist/chunk-T6ZYQJ63.cjs.map +1 -0
  115. package/dist/{chunk-AJA6LUI7.js → chunk-UO6BUV6K.js} +18 -2
  116. package/dist/chunk-UO6BUV6K.js.map +1 -0
  117. package/dist/chunk-WWQEY7BV.js +67 -0
  118. package/dist/chunk-WWQEY7BV.js.map +1 -0
  119. package/dist/{chunk-5WVP4YHP.js → chunk-WXEHD6TT.js} +333 -33
  120. package/dist/chunk-WXEHD6TT.js.map +1 -0
  121. package/dist/{chunk-47LRVGOT.cjs → chunk-XA4CKRML.cjs} +2 -2
  122. package/dist/{chunk-47LRVGOT.cjs.map → chunk-XA4CKRML.cjs.map} +1 -1
  123. package/dist/{chunk-6KFYJ6TD.cjs → chunk-XIYYHA65.cjs} +6 -2
  124. package/dist/chunk-XIYYHA65.cjs.map +1 -0
  125. package/dist/chunk-YRIKITGF.cjs +1768 -0
  126. package/dist/chunk-YRIKITGF.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-R7YVBHCV.cjs → chunk-ZMW6NU2K.cjs} +197 -73
  130. package/dist/chunk-ZMW6NU2K.cjs.map +1 -0
  131. package/dist/{chunk-A2N2GFCG.cjs → chunk-ZVTWQLK4.cjs} +10 -10
  132. package/dist/{chunk-A2N2GFCG.cjs.map → chunk-ZVTWQLK4.cjs.map} +1 -1
  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-3D7V24DG.js.map +0 -1
  205. package/dist/chunk-3LAEG75D.js.map +0 -1
  206. package/dist/chunk-4B2CNWQU.cjs.map +0 -1
  207. package/dist/chunk-524F3ATQ.cjs.map +0 -1
  208. package/dist/chunk-526PMQOA.js.map +0 -1
  209. package/dist/chunk-5KMIY374.cjs.map +0 -1
  210. package/dist/chunk-5LI5EPGJ.cjs.map +0 -1
  211. package/dist/chunk-5WVP4YHP.js.map +0 -1
  212. package/dist/chunk-5X2PTP6F.cjs.map +0 -1
  213. package/dist/chunk-6KFYJ6TD.cjs.map +0 -1
  214. package/dist/chunk-6WFMPTGB.cjs.map +0 -1
  215. package/dist/chunk-7FSDNNNC.js.map +0 -1
  216. package/dist/chunk-AJA6LUI7.js.map +0 -1
  217. package/dist/chunk-FQGX2PA2.js.map +0 -1
  218. package/dist/chunk-GQCOSXMG.js.map +0 -1
  219. package/dist/chunk-HBVFFBRR.cjs.map +0 -1
  220. package/dist/chunk-HDP7VK3C.cjs.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-NG2JHZHE.js.map +0 -1
  226. package/dist/chunk-O3ANBHSA.js.map +0 -1
  227. package/dist/chunk-PA4VC73I.cjs.map +0 -1
  228. package/dist/chunk-PFUESQTW.cjs.map +0 -1
  229. package/dist/chunk-R3PY4G7J.js.map +0 -1
  230. package/dist/chunk-R7YVBHCV.cjs.map +0 -1
  231. package/dist/chunk-SESSWASV.cjs.map +0 -1
  232. package/dist/chunk-TY3TLZAW.cjs.map +0 -1
  233. package/dist/chunk-UM6BVY2S.cjs.map +0 -1
  234. package/dist/chunk-UQ3UIZJC.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-YXCTLWOH.js.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 }
@@ -541,20 +551,20 @@ var _ExpressionLexer = class _ExpressionLexer {
541
551
  switch (cc) {
542
552
  case 2 /* DIGIT */:
543
553
  case 4 /* DOT */:
544
- 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);
545
555
  tokenIndex++;
546
556
  break;
547
557
  case 3 /* ALPHA */: {
548
558
  const input2 = this.input;
549
559
  const identLower = input2.toLowerCase();
550
560
  if (this.mergedUnits.has(input2)) {
551
- 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);
552
562
  } else {
553
563
  const kwType = this.mergedKeywords.get(identLower);
554
564
  if (kwType) {
555
- 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);
556
566
  } else {
557
- 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);
558
568
  }
559
569
  }
560
570
  tokenIndex++;
@@ -563,7 +573,7 @@ var _ExpressionLexer = class _ExpressionLexer {
563
573
  case 5 /* OPERATOR */: {
564
574
  const opType = OP_MAP[c0];
565
575
  if (opType) {
566
- 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);
567
577
  tokenIndex++;
568
578
  }
569
579
  break;
@@ -579,61 +589,64 @@ var _ExpressionLexer = class _ExpressionLexer {
579
589
  tokenIndex++;
580
590
  break;
581
591
  case 8 /* DOLLAR */:
582
- 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);
583
593
  tokenIndex++;
584
594
  break;
585
595
  case 11 /* BACKTICK */:
586
- 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);
587
597
  tokenIndex++;
588
598
  break;
589
599
  default: {
590
600
  if (isUnicodeSpace(c0)) ; else if (c0 === 215) {
591
- 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);
592
602
  tokenIndex++;
593
603
  } else if (c0 === 247) {
594
- 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);
595
608
  tokenIndex++;
596
609
  } else if (c0 === 8800) {
597
- 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);
598
611
  tokenIndex++;
599
612
  } else if (c0 === 163) {
600
- 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);
601
614
  tokenIndex++;
602
615
  } else if (c0 === 8364) {
603
- 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);
604
617
  tokenIndex++;
605
618
  } else if (c0 === 165) {
606
- 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);
607
620
  tokenIndex++;
608
621
  } else if (c0 === 8381) {
609
- 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);
610
623
  tokenIndex++;
611
624
  } else if (c0 === 8361) {
612
- 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);
613
626
  tokenIndex++;
614
627
  } else if (c0 === 8377) {
615
- 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);
616
629
  tokenIndex++;
617
630
  } else if (c0 === 8378) {
618
- 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);
619
632
  tokenIndex++;
620
633
  } else if (c0 === 8372) {
621
- 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);
622
635
  tokenIndex++;
623
636
  } else if (c0 === 8362) {
624
- 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);
625
638
  tokenIndex++;
626
639
  } else if (c0 === 8363) {
627
- 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);
628
641
  tokenIndex++;
629
642
  } else if (c0 === 8358) {
630
- 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);
631
644
  tokenIndex++;
632
645
  } else if (c0 === 8369) {
633
- 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);
634
647
  tokenIndex++;
635
648
  } else if (c0 >= 128) {
636
- 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);
637
650
  tokenIndex++;
638
651
  }
639
652
  break;
@@ -643,6 +656,7 @@ var _ExpressionLexer = class _ExpressionLexer {
643
656
  return;
644
657
  }
645
658
  const input = this.input;
659
+ this.groupingStack.length = 0;
646
660
  while (this.pos < len) {
647
661
  const c0 = input.charCodeAt(this.pos);
648
662
  const cc = _ExpressionLexer.CHAR_CLASS[c0] ?? 0 /* SKIP */;
@@ -657,12 +671,14 @@ var _ExpressionLexer = class _ExpressionLexer {
657
671
  if (c0 === 10) {
658
672
  this.line++;
659
673
  this.lineStartPos = this.pos;
674
+ this.groupingStack.length = 0;
660
675
  } else if (c0 === 13) {
661
676
  this.line++;
662
677
  if (this.pos < len && input.charCodeAt(this.pos) === 10) {
663
678
  this.pos++;
664
679
  }
665
680
  this.lineStartPos = this.pos;
681
+ this.groupingStack.length = 0;
666
682
  }
667
683
  break;
668
684
  // ── Digit, inline number tokenizer ───────────────────────────
@@ -688,12 +704,12 @@ var _ExpressionLexer = class _ExpressionLexer {
688
704
  yield this.tokenizeNumber();
689
705
  } else {
690
706
  const col = this.pos - this.lineStartPos + 1;
691
- 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);
692
708
  this.pos++;
693
709
  }
694
710
  } else {
695
711
  const col = this.pos - this.lineStartPos + 1;
696
- 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);
697
713
  this.pos++;
698
714
  }
699
715
  tokenIndex++;
@@ -716,7 +732,7 @@ var _ExpressionLexer = class _ExpressionLexer {
716
732
  // ── Dollar sign $ ─────────────────────────────────────────────
717
733
  case 8 /* DOLLAR */: {
718
734
  const col = this.pos - this.lineStartPos + 1;
719
- 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);
720
736
  this.pos++;
721
737
  tokenIndex++;
722
738
  break;
@@ -724,7 +740,7 @@ var _ExpressionLexer = class _ExpressionLexer {
724
740
  // ── Backtick ` ───────────────────────────────────────────────
725
741
  case 11 /* BACKTICK */: {
726
742
  const col = this.pos - this.lineStartPos + 1;
727
- 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);
728
744
  this.pos++;
729
745
  if (openSpan) {
730
746
  const span = openSpan;
@@ -751,63 +767,67 @@ var _ExpressionLexer = class _ExpressionLexer {
751
767
  this.lineStartPos = this.pos;
752
768
  }
753
769
  } else if (c0 === 215) {
754
- 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);
755
771
  this.pos++;
756
772
  tokenIndex++;
757
773
  } else if (c0 === 247) {
758
- 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);
759
779
  this.pos++;
760
780
  tokenIndex++;
761
781
  } else if (c0 === 8800) {
762
- 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);
763
783
  this.pos++;
764
784
  tokenIndex++;
765
785
  } else if (c0 === 163) {
766
- 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);
767
787
  this.pos++;
768
788
  tokenIndex++;
769
789
  } else if (c0 === 8364) {
770
- 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);
771
791
  this.pos++;
772
792
  tokenIndex++;
773
793
  } else if (c0 === 165) {
774
- 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);
775
795
  this.pos++;
776
796
  tokenIndex++;
777
797
  } else if (c0 === 8381) {
778
- 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);
779
799
  this.pos++;
780
800
  tokenIndex++;
781
801
  } else if (c0 === 8361) {
782
- 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);
783
803
  this.pos++;
784
804
  tokenIndex++;
785
805
  } else if (c0 === 8377) {
786
- 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);
787
807
  this.pos++;
788
808
  tokenIndex++;
789
809
  } else if (c0 === 8378) {
790
- 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);
791
811
  this.pos++;
792
812
  tokenIndex++;
793
813
  } else if (c0 === 8372) {
794
- 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);
795
815
  this.pos++;
796
816
  tokenIndex++;
797
817
  } else if (c0 === 8362) {
798
- 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);
799
819
  this.pos++;
800
820
  tokenIndex++;
801
821
  } else if (c0 === 8363) {
802
- 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);
803
823
  this.pos++;
804
824
  tokenIndex++;
805
825
  } else if (c0 === 8358) {
806
- 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);
807
827
  this.pos++;
808
828
  tokenIndex++;
809
829
  } else if (c0 === 8369) {
810
- 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);
811
831
  this.pos++;
812
832
  tokenIndex++;
813
833
  } else if (c0 >= 128) {
@@ -848,7 +868,7 @@ var _ExpressionLexer = class _ExpressionLexer {
848
868
  }
849
869
  const text2 = input.slice(start, pos);
850
870
  this.pos = pos;
851
- 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);
852
872
  }
853
873
  if (next === 98 || next === 66) {
854
874
  pos += 2;
@@ -857,7 +877,7 @@ var _ExpressionLexer = class _ExpressionLexer {
857
877
  }
858
878
  const text2 = input.slice(start, pos);
859
879
  this.pos = pos;
860
- 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);
861
881
  }
862
882
  if (next === 111 || next === 79) {
863
883
  pos += 2;
@@ -866,7 +886,7 @@ var _ExpressionLexer = class _ExpressionLexer {
866
886
  }
867
887
  const text2 = input.slice(start, pos);
868
888
  this.pos = pos;
869
- 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);
870
890
  }
871
891
  }
872
892
  let hasIntPart = false;
@@ -875,6 +895,9 @@ var _ExpressionLexer = class _ExpressionLexer {
875
895
  pos++;
876
896
  }
877
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
+ }
878
901
  if (pos + 4 <= len) {
879
902
  const d1 = input.charCodeAt(pos + 1);
880
903
  const d2 = input.charCodeAt(pos + 2);
@@ -924,12 +947,12 @@ var _ExpressionLexer = class _ExpressionLexer {
924
947
  pos++;
925
948
  const text2 = input.slice(start, pos);
926
949
  this.pos = pos;
927
- 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);
928
951
  }
929
952
  }
930
953
  const text = input.slice(start, pos);
931
954
  this.pos = pos;
932
- 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);
933
956
  }
934
957
  // ── Inline identifier / keyword tokenizer ──────────────────────────────
935
958
  /**
@@ -961,22 +984,22 @@ var _ExpressionLexer = class _ExpressionLexer {
961
984
  pos++;
962
985
  this.pos = pos;
963
986
  const fullText = input.slice(start, pos);
964
- 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);
965
988
  }
966
989
  const isKnownUnit = this.mergedUnits.has(identText);
967
990
  if (isKnownUnit) {
968
991
  if (!this.isFollowedByLParen(pos)) {
969
992
  this.pos = pos;
970
- 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);
971
994
  }
972
995
  }
973
996
  const localeKwType = this.mergedKeywords.get(identLower);
974
997
  if (localeKwType) {
975
998
  this.pos = pos;
976
- 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);
977
1000
  }
978
1001
  this.pos = pos;
979
- 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);
980
1003
  }
981
1004
  /**
982
1005
  * Peek past in-expression whitespace (space, tab) from `pos` to check
@@ -994,6 +1017,42 @@ var _ExpressionLexer = class _ExpressionLexer {
994
1017
  return false;
995
1018
  }
996
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
+ }
997
1056
  /**
998
1057
  * Reads an operator/punctuation token.
999
1058
  * Handles two-char operators (==, !=, >=, <=, **) and the special
@@ -1013,7 +1072,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1013
1072
  if (twoCharType) {
1014
1073
  const text2 = input.slice(pos, pos + 2);
1015
1074
  this.pos = pos + 2;
1016
- 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);
1017
1076
  }
1018
1077
  }
1019
1078
  if (c0 === 47 && c1 === 47) {
@@ -1025,19 +1084,19 @@ var _ExpressionLexer = class _ExpressionLexer {
1025
1084
  }
1026
1085
  const text2 = input.slice(pos, commentPos);
1027
1086
  this.pos = commentPos;
1028
- 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);
1029
1088
  }
1030
1089
  if (c0 === 60 && c1 === 60) {
1031
1090
  this.pos = pos + 2;
1032
- 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);
1033
1092
  }
1034
1093
  if (c0 === 62 && c1 === 62) {
1035
1094
  if (input.charCodeAt(pos + 2) === 62) {
1036
1095
  this.pos = pos + 3;
1037
- 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);
1038
1097
  }
1039
1098
  this.pos = pos + 2;
1040
- 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);
1041
1100
  }
1042
1101
  if (this.hasPluginOps) {
1043
1102
  const pluginInner = this.pluginOperators.get(c0);
@@ -1046,15 +1105,22 @@ var _ExpressionLexer = class _ExpressionLexer {
1046
1105
  if (pluginType) {
1047
1106
  const text2 = input.slice(pos, pos + 2);
1048
1107
  this.pos = pos + 2;
1049
- 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);
1050
1109
  }
1051
1110
  }
1052
1111
  }
1053
1112
  }
1054
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
+ }
1055
1121
  const opType = OP_MAP[c0];
1056
1122
  const text = input.charAt(pos);
1057
- 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);
1058
1124
  }
1059
1125
  // ── String literal tokenizer ──────────────────────────────────────────
1060
1126
  /**
@@ -1090,7 +1156,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1090
1156
  const text = input.slice(start, pos);
1091
1157
  const value = input.slice(start + 1, pos - 1);
1092
1158
  this.pos = pos;
1093
- 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);
1094
1160
  }
1095
1161
  if (c0 === 92 && pos + 1 < len) {
1096
1162
  pos += 2;
@@ -1104,7 +1170,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1104
1170
  pos++;
1105
1171
  }
1106
1172
  this.pos = pos;
1107
- throw chunk5KMIY374_cjs.ErrorFactory.parsing(
1173
+ throw chunkB4HBEFTB_cjs.ErrorFactory.parsing(
1108
1174
  "UNTERMINATED_STRING",
1109
1175
  `Unterminated string literal: ${input.slice(start, pos)}`,
1110
1176
  { literal: input.slice(start, pos), offset: start }
@@ -1164,6 +1230,36 @@ var _ExpressionLexer = class _ExpressionLexer {
1164
1230
  }
1165
1231
  return pos;
1166
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
+ }
1167
1263
  classifyFromPositions(start, end) {
1168
1264
  const len = end;
1169
1265
  if (start >= len) {
@@ -1182,6 +1278,13 @@ var _ExpressionLexer = class _ExpressionLexer {
1182
1278
  const c0 = input.charCodeAt(pos);
1183
1279
  let hasInline;
1184
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
+ }
1185
1288
  let hashCount = 1;
1186
1289
  while (pos + hashCount < len && input.charCodeAt(pos + hashCount) === 35) {
1187
1290
  hashCount++;
@@ -1294,6 +1397,19 @@ var _ExpressionLexer = class _ExpressionLexer {
1294
1397
  const idx = input.indexOf("s`", pos);
1295
1398
  hasInline = idx !== -1 && idx < len;
1296
1399
  }
1400
+ if (!hasInline) {
1401
+ let onlySkippable = true;
1402
+ for (let i = pos; i < len; i++) {
1403
+ const code = input.charCodeAt(i);
1404
+ if (code >= 128 || _ExpressionLexer.CHAR_CLASS[code] > 1 /* WHITESPACE */) {
1405
+ onlySkippable = false;
1406
+ break;
1407
+ }
1408
+ }
1409
+ if (onlySkippable) {
1410
+ return { type: "empty", skip: true, hasInlineSolve: false };
1411
+ }
1412
+ }
1297
1413
  return { type: "expression", skip: false, hasInlineSolve: hasInline };
1298
1414
  }
1299
1415
  /**
@@ -1367,6 +1483,14 @@ var _ExpressionLexer = class _ExpressionLexer {
1367
1483
  const len = this.len;
1368
1484
  const start = this.pos;
1369
1485
  const startCol = start - this.lineStartPos + 1;
1486
+ if (input.charCodeAt(start) === 35) {
1487
+ const hexEnd = this.matchHexColourEnd(start, len);
1488
+ if (hexEnd !== -1) {
1489
+ const text2 = input.slice(start, hexEnd);
1490
+ this.pos = hexEnd;
1491
+ return new LexerToken("HEX_COLOUR", chunkQFTDTX6K_cjs.tokenTypeId("HEX_COLOUR"), text2, text2, start, 0, this.line, startCol);
1492
+ }
1493
+ }
1370
1494
  let pos = this.pos;
1371
1495
  if (pos + 1 < len && input.charCodeAt(pos + 1) === 47) {
1372
1496
  pos += 2;
@@ -1380,7 +1504,7 @@ var _ExpressionLexer = class _ExpressionLexer {
1380
1504
  }
1381
1505
  const text = input.slice(start, pos);
1382
1506
  this.pos = pos;
1383
- return new LexerToken("COMMENT", chunk5LI5EPGJ_cjs.tokenTypeId("COMMENT"), text, text, start, 0, this.line, startCol);
1507
+ return new LexerToken("COMMENT", chunkQFTDTX6K_cjs.tokenTypeId("COMMENT"), text, text, start, 0, this.line, startCol);
1384
1508
  }
1385
1509
  };
1386
1510
  _ExpressionLexer.CHAR_CLASS = buildCharClassTable();
@@ -1388,5 +1512,5 @@ var ExpressionLexer = _ExpressionLexer;
1388
1512
 
1389
1513
  exports.ExpressionLexer = ExpressionLexer;
1390
1514
  exports.LexerToken = LexerToken;
1391
- //# sourceMappingURL=chunk-R7YVBHCV.cjs.map
1392
- //# sourceMappingURL=chunk-R7YVBHCV.cjs.map
1515
+ //# sourceMappingURL=chunk-ZMW6NU2K.cjs.map
1516
+ //# sourceMappingURL=chunk-ZMW6NU2K.cjs.map