@cortex-js/compute-engine 0.57.0 → 0.59.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 (270) hide show
  1. package/README.md +4 -0
  2. package/dist/compile.esm.js +2376 -501
  3. package/dist/compile.min.esm.js +316 -68
  4. package/dist/compile.min.umd.cjs +316 -68
  5. package/dist/compile.umd.cjs +2376 -501
  6. package/dist/compute-engine.esm.js +15717 -12444
  7. package/dist/compute-engine.min.esm.js +331 -83
  8. package/dist/compute-engine.min.umd.cjs +330 -82
  9. package/dist/compute-engine.umd.cjs +15717 -12444
  10. package/dist/core.esm.js +15716 -12443
  11. package/dist/core.min.esm.js +329 -81
  12. package/dist/core.min.umd.cjs +329 -81
  13. package/dist/core.umd.cjs +15716 -12443
  14. package/dist/identities.esm.js +1921 -0
  15. package/dist/identities.min.esm.js +2 -0
  16. package/dist/identities.min.umd.cjs +4 -0
  17. package/dist/identities.umd.cjs +1946 -0
  18. package/dist/interval.esm.js +779 -339
  19. package/dist/interval.min.esm.js +8 -8
  20. package/dist/interval.min.umd.cjs +8 -8
  21. package/dist/interval.umd.cjs +779 -339
  22. package/dist/latex-syntax.esm.js +971 -608
  23. package/dist/latex-syntax.min.esm.js +7 -7
  24. package/dist/latex-syntax.min.umd.cjs +7 -7
  25. package/dist/latex-syntax.umd.cjs +971 -608
  26. package/dist/math-json.esm.js +8 -12
  27. package/dist/math-json.min.esm.js +2 -2
  28. package/dist/math-json.min.umd.cjs +2 -2
  29. package/dist/math-json.umd.cjs +8 -12
  30. package/dist/numerics.esm.js +1382 -226
  31. package/dist/numerics.min.esm.js +16 -5
  32. package/dist/numerics.min.umd.cjs +16 -5
  33. package/dist/numerics.umd.cjs +1382 -226
  34. package/dist/types/big-decimal/big-decimal.d.ts +1 -1
  35. package/dist/types/big-decimal/index.d.ts +1 -1
  36. package/dist/types/big-decimal/transcendentals.d.ts +1 -1
  37. package/dist/types/big-decimal/utils.d.ts +1 -1
  38. package/dist/types/common/ansi-codes.d.ts +1 -1
  39. package/dist/types/common/configuration-change.d.ts +1 -1
  40. package/dist/types/common/fuzzy-string-match.d.ts +1 -1
  41. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  42. package/dist/types/common/interruptible.d.ts +1 -1
  43. package/dist/types/common/one-of.d.ts +1 -1
  44. package/dist/types/common/signals.d.ts +1 -1
  45. package/dist/types/common/type/ast-nodes.d.ts +1 -1
  46. package/dist/types/common/type/boxed-type.d.ts +1 -1
  47. package/dist/types/common/type/lexer.d.ts +1 -1
  48. package/dist/types/common/type/parse.d.ts +1 -208
  49. package/dist/types/common/type/parser.d.ts +124 -2
  50. package/dist/types/common/type/primitive.d.ts +5 -1
  51. package/dist/types/common/type/reduce.d.ts +1 -1
  52. package/dist/types/common/type/serialize.d.ts +1 -1
  53. package/dist/types/common/type/subtype.d.ts +18 -1
  54. package/dist/types/common/type/type-builder.d.ts +1 -1
  55. package/dist/types/common/type/types.d.ts +1 -1
  56. package/dist/types/common/type/utils.d.ts +1 -1
  57. package/dist/types/common/utils.d.ts +1 -1
  58. package/dist/types/compile.d.ts +1 -1
  59. package/dist/types/compute-engine/assume.d.ts +13 -6
  60. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +3 -1
  61. package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
  62. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
  63. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
  64. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
  65. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  66. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  67. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  68. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  69. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  70. package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +7 -1
  71. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  72. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  73. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +3 -3
  74. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
  75. package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
  76. package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
  77. package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
  78. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  79. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  80. package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
  81. package/dist/types/compute-engine/boxed-expression/constraint-subject.d.ts +140 -0
  82. package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
  83. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  84. package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
  85. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  86. package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
  87. package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +34 -12
  88. package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
  89. package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
  90. package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
  91. package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
  92. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
  93. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  94. package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
  95. package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
  96. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  97. package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
  98. package/dist/types/compute-engine/boxed-expression/rule-index.d.ts +112 -0
  99. package/dist/types/compute-engine/boxed-expression/rules.d.ts +2 -1
  100. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  101. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  102. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  103. package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
  104. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
  105. package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
  106. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
  107. package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
  108. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  109. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  110. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  111. package/dist/types/compute-engine/compilation/base-compiler.d.ts +8 -1
  112. package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
  113. package/dist/types/compute-engine/compilation/constant-folding.d.ts +16 -1
  114. package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
  115. package/dist/types/compute-engine/compilation/gpu-target.d.ts +58 -5
  116. package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +4 -4
  117. package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
  118. package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
  119. package/dist/types/compute-engine/compilation/types.d.ts +1 -1
  120. package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
  121. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  122. package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
  123. package/dist/types/compute-engine/engine-cache.d.ts +1 -1
  124. package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
  125. package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
  126. package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
  127. package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
  128. package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
  129. package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
  130. package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
  131. package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
  132. package/dist/types/compute-engine/engine-runtime-state.d.ts +4 -1
  133. package/dist/types/compute-engine/engine-scope.d.ts +1 -1
  134. package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
  135. package/dist/types/compute-engine/engine-simplification-rules.d.ts +10 -2
  136. package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
  137. package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
  138. package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
  139. package/dist/types/compute-engine/free-functions.d.ts +1 -1
  140. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  141. package/dist/types/compute-engine/fungrim/loader.d.ts +13 -0
  142. package/dist/types/compute-engine/fungrim/types.d.ts +160 -0
  143. package/dist/types/compute-engine/global-types.d.ts +1 -1
  144. package/dist/types/compute-engine/index.d.ts +63 -2
  145. package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
  146. package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
  147. package/dist/types/compute-engine/interval/elementary.d.ts +10 -2
  148. package/dist/types/compute-engine/interval/index.d.ts +2 -2
  149. package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
  150. package/dist/types/compute-engine/interval/types.d.ts +1 -1
  151. package/dist/types/compute-engine/interval/util.d.ts +1 -1
  152. package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
  153. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  154. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  155. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  156. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +1 -1
  157. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  158. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  159. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  160. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  161. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  162. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  163. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  164. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  165. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  166. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  167. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
  168. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  169. package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +4 -1
  170. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  171. package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
  172. package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
  173. package/dist/types/compute-engine/latex-syntax/parse.d.ts +3 -2
  174. package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
  175. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -11
  176. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  177. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  178. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  179. package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
  180. package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
  181. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  182. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  183. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  184. package/dist/types/compute-engine/library/colors.d.ts +1 -1
  185. package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
  186. package/dist/types/compute-engine/library/complex.d.ts +13 -1
  187. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  188. package/dist/types/compute-engine/library/core.d.ts +1 -1
  189. package/dist/types/compute-engine/library/fractals.d.ts +1 -1
  190. package/dist/types/compute-engine/library/library.d.ts +1 -1
  191. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  192. package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
  193. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  194. package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
  195. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  196. package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
  197. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  198. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  199. package/dist/types/compute-engine/library/sets.d.ts +27 -1
  200. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  201. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  202. package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
  203. package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
  204. package/dist/types/compute-engine/library/units.d.ts +1 -1
  205. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  206. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
  207. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +7 -1
  208. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
  209. package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
  210. package/dist/types/compute-engine/numerics/bernoulli.d.ts +39 -0
  211. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  212. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  213. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  214. package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
  215. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  216. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  217. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  218. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +12 -1
  219. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  220. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  221. package/dist/types/compute-engine/numerics/random.d.ts +23 -0
  222. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  223. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  224. package/dist/types/compute-engine/numerics/special-functions.d.ts +78 -10
  225. package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
  226. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  227. package/dist/types/compute-engine/numerics/types.d.ts +1 -1
  228. package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
  229. package/dist/types/compute-engine/oeis.d.ts +1 -1
  230. package/dist/types/compute-engine/sequence.d.ts +1 -1
  231. package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
  232. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  233. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  234. package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
  235. package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
  236. package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
  237. package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
  238. package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
  239. package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
  240. package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
  241. package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
  242. package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
  243. package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
  244. package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
  245. package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
  246. package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
  247. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  248. package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
  249. package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
  250. package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
  251. package/dist/types/compute-engine/tensor/tensors.d.ts +3 -3
  252. package/dist/types/compute-engine/types-definitions.d.ts +1 -1
  253. package/dist/types/compute-engine/types-engine.d.ts +52 -3
  254. package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
  255. package/dist/types/compute-engine/types-expression.d.ts +85 -14
  256. package/dist/types/compute-engine/types-kernel-evaluation.d.ts +32 -1
  257. package/dist/types/compute-engine/types-kernel-serialization.d.ts +45 -3
  258. package/dist/types/compute-engine/types-serialization.d.ts +1 -1
  259. package/dist/types/compute-engine/types.d.ts +1 -1
  260. package/dist/types/compute-engine.d.ts +1 -1
  261. package/dist/types/core.d.ts +1 -1
  262. package/dist/types/identities.d.ts +3 -0
  263. package/dist/types/interval.d.ts +1 -1
  264. package/dist/types/latex-syntax.d.ts +2 -2
  265. package/dist/types/math-json/symbols.d.ts +1 -1
  266. package/dist/types/math-json/types.d.ts +1 -1
  267. package/dist/types/math-json/utils.d.ts +1 -1
  268. package/dist/types/math-json.d.ts +2 -2
  269. package/dist/types/numerics.d.ts +1 -1
  270. package/package.json +9 -3
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.57.0 */
1
+ /** Compute Engine 0.59.0 */
2
2
 
3
3
  // src/math-json/utils.ts
4
4
  var MISSING = ["Error", "'missing'"];
@@ -92,12 +92,14 @@ function dictionaryFromExpression(expr) {
92
92
  if (expr === null) return null;
93
93
  if (isDictionaryObject(expr)) return expr;
94
94
  const kv = keyValuePair(expr);
95
- if (kv) return { [kv[0]]: kv[1] };
95
+ if (kv)
96
+ return {
97
+ dict: { [kv[0]]: expressionToDictionaryValue(kv[1]) ?? "Nothing" }
98
+ };
96
99
  if (operator(expr) === "Dictionary") {
97
100
  const dict = {};
98
- const ops = operands(expr);
99
- for (let i = 1; i < nops(expr); i++) {
100
- const kv2 = keyValuePair(ops[i]);
101
+ for (const op of operands(expr)) {
102
+ const kv2 = keyValuePair(op);
101
103
  if (kv2) {
102
104
  dict[kv2[0]] = expressionToDictionaryValue(kv2[1]) ?? "Nothing";
103
105
  }
@@ -436,11 +438,27 @@ var UNICODE_SUBSCRIPT_MAP = {
436
438
  "\u208B": "-"
437
439
  // ₋
438
440
  };
441
+ var STICKY_REGEX_CACHE = /* @__PURE__ */ new Map();
442
+ function stickyRegex(regEx) {
443
+ let result = STICKY_REGEX_CACHE.get(regEx.source);
444
+ if (!result) {
445
+ const source = regEx.source.startsWith("^") ? regEx.source.slice(1) : regEx.source;
446
+ result = new RegExp(source, "y");
447
+ STICKY_REGEX_CACHE.set(regEx.source, result);
448
+ }
449
+ return result;
450
+ }
439
451
  var Tokenizer = class {
440
452
  s;
441
453
  pos;
454
+ /** The input as a plain string (joined graphemes), used by `match()` */
455
+ joined;
456
+ /** For grapheme-array inputs: code-unit offset of each grapheme in
457
+ * `joined` (length `s.length + 1`, last entry is `joined.length`) */
458
+ offsets = null;
442
459
  obeyspaces = false;
443
460
  constructor(s) {
461
+ s = s.normalize("NFC");
444
462
  s = s.replace(/[\u200E\u200F\u2066-\u2069\u202A-\u202E]/g, "");
445
463
  s = s.replace(/\u2212/g, "-");
446
464
  s = s.replace(/[⁰¹²³⁴⁵⁶⁷⁸⁹⁻ⁱⁿ]+/g, (m) => {
@@ -453,6 +471,19 @@ var Tokenizer = class {
453
471
  });
454
472
  this.s = splitGraphemes(s);
455
473
  this.pos = 0;
474
+ if (typeof this.s === "string") {
475
+ this.joined = this.s;
476
+ } else {
477
+ this.joined = this.s.join("");
478
+ const offsets = new Array(this.s.length + 1);
479
+ let offset = 0;
480
+ for (let i = 0; i < this.s.length; i++) {
481
+ offsets[i] = offset;
482
+ offset += this.s[i].length;
483
+ }
484
+ offsets[this.s.length] = offset;
485
+ this.offsets = offsets;
486
+ }
456
487
  }
457
488
  /**
458
489
  * @return True if we reached the end of the stream
@@ -476,12 +507,13 @@ var Tokenizer = class {
476
507
  * Return the next substring matching regEx and advance.
477
508
  */
478
509
  match(regEx) {
479
- let execResult;
510
+ const re = stickyRegex(regEx);
480
511
  if (typeof this.s === "string") {
481
- execResult = regEx.exec(this.s.slice(this.pos));
512
+ re.lastIndex = this.pos;
482
513
  } else {
483
- execResult = regEx.exec(this.s.slice(this.pos).join(""));
514
+ re.lastIndex = this.offsets[this.pos < this.s.length ? this.pos : this.s.length];
484
515
  }
516
+ const execResult = re.exec(this.joined);
485
517
  if (execResult?.[0]) {
486
518
  this.pos += execResult[0].length;
487
519
  return execResult[0];
@@ -588,25 +620,13 @@ function expand(lex, args) {
588
620
  }
589
621
  }
590
622
  } else if (token === "\\csname") {
591
- while (lex.peek() === "<space>") {
592
- lex.next();
593
- }
594
623
  let command = "";
595
624
  let done = false;
596
625
  let tokens = [];
597
626
  do {
598
627
  if (tokens.length === 0) {
599
- if (/^#[0-9?]$/.test(lex.peek())) {
600
- const param = lex.get().slice(1);
601
- tokens = tokenize(
602
- args?.[param] ?? args?.["?"] ?? "\\placeholder{}",
603
- args
604
- );
605
- token = tokens[0];
606
- } else {
607
- token = lex.next();
608
- tokens = token ? [token] : [];
609
- }
628
+ token = lex.next();
629
+ tokens = token ? [token] : [];
610
630
  }
611
631
  done = tokens.length === 0;
612
632
  if (!done && token === "\\endcsname") {
@@ -679,7 +699,7 @@ function tokensToString(tokens) {
679
699
  if (Array.isArray(tokens)) {
680
700
  for (const item of tokens) {
681
701
  if (Array.isArray(item)) {
682
- flat = [...flat, ...item];
702
+ for (const token of item) flat.push(token);
683
703
  } else {
684
704
  flat.push(item);
685
705
  }
@@ -1164,172 +1184,23 @@ var PRIMITIVE_TYPES = [
1164
1184
  "error",
1165
1185
  ...EXPRESSION_TYPES
1166
1186
  ];
1187
+ var NUMERIC_TYPES_SET = new Set(
1188
+ NUMERIC_TYPES
1189
+ );
1190
+ var COLLECTION_TYPES_SET = new Set(
1191
+ COLLECTION_TYPES
1192
+ );
1193
+ var SCALAR_TYPES_SET = new Set(
1194
+ SCALAR_TYPES
1195
+ );
1196
+ var PRIMITIVE_TYPES_SET = new Set(
1197
+ PRIMITIVE_TYPES
1198
+ );
1167
1199
  function isValidType(t) {
1168
- if (typeof t === "string")
1169
- return PRIMITIVE_TYPES.includes(t);
1200
+ if (typeof t === "string") return PRIMITIVE_TYPES_SET.has(t);
1170
1201
  if (typeof t !== "object") return false;
1171
1202
  if (!("kind" in t)) return false;
1172
- return t.kind === "signature" || t.kind === "union" || t.kind === "intersection" || t.kind === "negation" || t.kind === "tuple" || t.kind === "list" || t.kind === "record" || t.kind === "dictionary" || t.kind === "set" || t.kind === "function" || t.kind === "collection" || t.kind === "indexed_collection" || t.kind === "reference";
1173
- }
1174
-
1175
- // src/common/type/serialize.ts
1176
- var NEGATION_PRECEDENCE = 3;
1177
- var UNION_PRECEDENCE = 1;
1178
- var INTERSECTION_PRECEDENCE = 2;
1179
- var LIST_PRECEDENCE = 4;
1180
- var RECORD_PRECEDENCE = 5;
1181
- var DICTIONARY_PRECEDENCE = 6;
1182
- var SET_PRECEDENCE = 7;
1183
- var COLLECTION_PRECEDENCE = 8;
1184
- var TUPLE_PRECEDENCE = 9;
1185
- var SIGNATURE_PRECEDENCE = 10;
1186
- var VALUE_PRECEDENCE = 11;
1187
- function typeToString(type, precedence = 0) {
1188
- if (typeof type === "string") return type;
1189
- let result = "";
1190
- switch (type.kind) {
1191
- case "value":
1192
- if (typeof type.value === "string") result = `"${type.value}"`;
1193
- else if (typeof type.value === "boolean")
1194
- result = type.value ? "true" : "false";
1195
- else result = type.value.toString();
1196
- break;
1197
- case "reference":
1198
- result = type.name;
1199
- break;
1200
- case "negation":
1201
- result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
1202
- break;
1203
- case "union":
1204
- result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
1205
- break;
1206
- case "intersection":
1207
- result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
1208
- break;
1209
- case "expression":
1210
- result = `expression<${symbolName(type.operator)}>`;
1211
- break;
1212
- case "symbol":
1213
- result = `symbol<${symbolName(type.name)}>`;
1214
- break;
1215
- case "numeric":
1216
- if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
1217
- result = `${type.type}<${type.lower}..${type.upper}>`;
1218
- } else if (Number.isFinite(type.lower)) {
1219
- result = `${type.type}<${type.lower}..>`;
1220
- } else if (Number.isFinite(type.upper)) {
1221
- result = `${type.type}<..${type.upper}>`;
1222
- } else {
1223
- result = `${type.type}`;
1224
- }
1225
- break;
1226
- case "list":
1227
- if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES.includes(type.elements)) {
1228
- if (type.dimensions === void 0) {
1229
- if (type.elements === "number") result = "tensor";
1230
- } else if (type.dimensions.length === 1) {
1231
- if (type.elements === "number") {
1232
- if (type.dimensions[0] < 0) result = "vector";
1233
- else result = `vector<${type.dimensions[0]}>`;
1234
- } else {
1235
- if (type.dimensions[0] < 0)
1236
- result = `vector<${typeToString(type.elements)}>`;
1237
- else
1238
- result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
1239
- }
1240
- } else if (type.dimensions.length === 2) {
1241
- const dims = type.dimensions;
1242
- if (type.elements === "number") {
1243
- if (dims[0] < 0 && dims[1] < 0) result = "matrix";
1244
- else result = `matrix<${dims[0]}x${dims[1]}>`;
1245
- } else {
1246
- if (dims[0] < 0 && dims[1] < 0)
1247
- result = `matrix<${typeToString(type.elements)}>`;
1248
- else
1249
- result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
1250
- }
1251
- }
1252
- }
1253
- if (!result) {
1254
- const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
1255
- result = `list<${typeToString(type.elements)}${dimensions}>`;
1256
- }
1257
- break;
1258
- case "record":
1259
- const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
1260
- result = `record<${elements}>`;
1261
- break;
1262
- case "dictionary":
1263
- result = `dictionary<${typeToString(type.values)}>`;
1264
- break;
1265
- case "set":
1266
- result = `set<${typeToString(type.elements)}>`;
1267
- break;
1268
- case "collection":
1269
- result = `collection<${typeToString(type.elements)}>`;
1270
- break;
1271
- case "indexed_collection":
1272
- result = `indexed_collection<${typeToString(type.elements)}>`;
1273
- break;
1274
- case "tuple":
1275
- if (type.elements.length === 0) result = "tuple";
1276
- else if (type.elements.length === 1) {
1277
- const [el] = type.elements;
1278
- result = `tuple<${namedElement(el)}>`;
1279
- } else {
1280
- result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
1281
- }
1282
- break;
1283
- case "signature":
1284
- const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
1285
- const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
1286
- const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
1287
- const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
1288
- result = `(${argsList}) -> ${typeToString(type.result)}`;
1289
- break;
1290
- default:
1291
- result = "error";
1292
- }
1293
- if (precedence > 0 && precedence > getPrecedence(type.kind))
1294
- return `(${result})`;
1295
- return result;
1296
- }
1297
- function namedElement(el) {
1298
- if (el.name) return `${el.name}: ${typeToString(el.type)}`;
1299
- return typeToString(el.type);
1300
- }
1301
- function symbolName(name) {
1302
- if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
1303
- return `\`${name}\``;
1304
- }
1305
- function getPrecedence(kind) {
1306
- switch (kind) {
1307
- case "negation":
1308
- return NEGATION_PRECEDENCE;
1309
- case "union":
1310
- return UNION_PRECEDENCE;
1311
- case "intersection":
1312
- return INTERSECTION_PRECEDENCE;
1313
- case "list":
1314
- return LIST_PRECEDENCE;
1315
- case "record":
1316
- return RECORD_PRECEDENCE;
1317
- case "dictionary":
1318
- return DICTIONARY_PRECEDENCE;
1319
- case "set":
1320
- return SET_PRECEDENCE;
1321
- case "collection":
1322
- case "indexed_collection":
1323
- return COLLECTION_PRECEDENCE;
1324
- case "tuple":
1325
- return TUPLE_PRECEDENCE;
1326
- case "signature":
1327
- return SIGNATURE_PRECEDENCE;
1328
- case "value":
1329
- return VALUE_PRECEDENCE;
1330
- default:
1331
- return 0;
1332
- }
1203
+ return t.kind === "signature" || t.kind === "union" || t.kind === "intersection" || t.kind === "negation" || t.kind === "value" || t.kind === "tuple" || t.kind === "list" || t.kind === "record" || t.kind === "dictionary" || t.kind === "set" || t.kind === "symbol" || t.kind === "expression" || t.kind === "numeric" || t.kind === "collection" || t.kind === "indexed_collection" || t.kind === "reference";
1333
1204
  }
1334
1205
 
1335
1206
  // src/common/type/lexer.ts
@@ -2039,19 +1910,13 @@ var Parser = class {
2039
1910
  );
2040
1911
  let dimensions;
2041
1912
  if (this.match("<")) {
2042
- dimensions = this.parseDimensionWithX();
2043
- if (!dimensions) {
2044
- dimensions = this.parseDimensions();
2045
- }
1913
+ dimensions = this.parseDimensions();
2046
1914
  if (!dimensions) {
2047
1915
  const type = this.parseUnionType();
2048
1916
  if (type) {
2049
1917
  elementType = type;
2050
1918
  if (this.match("^")) {
2051
- dimensions = this.parseDimensionWithX();
2052
- if (!dimensions) {
2053
- dimensions = this.parseDimensions();
2054
- }
1919
+ dimensions = this.parseCaretDimensions();
2055
1920
  }
2056
1921
  }
2057
1922
  }
@@ -2092,19 +1957,13 @@ var Parser = class {
2092
1957
  );
2093
1958
  let dimensions;
2094
1959
  if (this.match("<")) {
2095
- dimensions = this.parseDimensionWithX();
2096
- if (!dimensions) {
2097
- dimensions = this.parseDimensions();
2098
- }
1960
+ dimensions = this.parseDimensions();
2099
1961
  if (!dimensions) {
2100
1962
  const type = this.parseUnionType();
2101
1963
  if (type) {
2102
1964
  elementType = type;
2103
1965
  if (this.match("^")) {
2104
- dimensions = this.parseDimensionWithX();
2105
- if (!dimensions) {
2106
- dimensions = this.parseDimensions();
2107
- }
1966
+ dimensions = this.parseCaretDimensions();
2108
1967
  }
2109
1968
  }
2110
1969
  }
@@ -2135,16 +1994,30 @@ var Parser = class {
2135
1994
  return this.createNode("tensor", { elementType });
2136
1995
  }
2137
1996
  parseDimensions() {
2138
- const dimensions = [];
2139
1997
  const firstDim = this.parseDimension();
2140
1998
  if (!firstDim) return void 0;
2141
- dimensions.push(firstDim);
2142
- while (this.match("x")) {
2143
- const dim = this.parseDimension();
2144
- if (!dim) {
2145
- this.error("Expected dimension after x");
1999
+ const dimensions = [firstDim];
2000
+ for (; ; ) {
2001
+ const tok = this.current;
2002
+ if (tok.type === "IDENTIFIER" && /^(x\d+)+$/.test(tok.value)) {
2003
+ this.advance();
2004
+ for (const m of tok.value.match(/x(\d+)/g))
2005
+ dimensions.push(
2006
+ this.createNode("dimension", {
2007
+ size: parseInt(m.slice(1))
2008
+ })
2009
+ );
2010
+ } else if (tok.type === "IDENTIFIER" && tok.value === "x") {
2011
+ const next = this.lexer.peekToken();
2012
+ if (next.type !== "NUMBER_LITERAL" && next.type !== "?")
2013
+ this.error(
2014
+ "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2015
+ );
2016
+ this.advance();
2017
+ dimensions.push(this.parseDimension());
2018
+ } else {
2019
+ break;
2146
2020
  }
2147
- dimensions.push(dim);
2148
2021
  }
2149
2022
  return dimensions;
2150
2023
  }
@@ -2158,35 +2031,11 @@ var Parser = class {
2158
2031
  }
2159
2032
  return void 0;
2160
2033
  }
2161
- parseDimensionWithX() {
2162
- if (this.current.type === "NUMBER_LITERAL") {
2163
- const dimensions = [];
2164
- const firstDim = parseInt(this.advance().value);
2165
- dimensions.push(
2166
- this.createNode("dimension", { size: firstDim })
2167
- );
2168
- if (this.current.type === "IDENTIFIER" && this.current.value.startsWith("x")) {
2169
- const dimString = this.current.value;
2170
- const matches = dimString.match(/x(\d+)/g);
2171
- if (matches && matches.join("") === dimString) {
2172
- this.advance();
2173
- for (const match of matches) {
2174
- const dimValue = parseInt(match.substring(1));
2175
- dimensions.push(
2176
- this.createNode("dimension", { size: dimValue })
2177
- );
2178
- }
2179
- } else if (dimString === "x" || dimString.startsWith("x")) {
2180
- this.error(
2181
- "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2182
- );
2183
- }
2184
- }
2185
- if (dimensions.length > 1) {
2186
- return dimensions;
2187
- }
2188
- }
2189
- return void 0;
2034
+ parseCaretDimensions() {
2035
+ const paren = this.match("(");
2036
+ const dimensions = this.parseDimensions();
2037
+ if (paren) this.expect(")");
2038
+ return dimensions;
2190
2039
  }
2191
2040
  parseTupleType() {
2192
2041
  if (this.current.type === "IDENTIFIER" && this.current.value === "tuple") {
@@ -2371,6 +2220,18 @@ var Parser = class {
2371
2220
  this.expect("..");
2372
2221
  const upperBound = this.parseValue();
2373
2222
  this.expect(">");
2223
+ const lower = lowerBound?.value ?? -Infinity;
2224
+ const upper = upperBound?.value ?? Infinity;
2225
+ if (Number.isNaN(lower) || Number.isNaN(upper))
2226
+ this.error(
2227
+ "Invalid numeric type",
2228
+ "Lower and upper bounds must be valid numbers"
2229
+ );
2230
+ if (lower > upper)
2231
+ this.error(
2232
+ `Invalid range: ${lower}..${upper}`,
2233
+ "The lower bound must be less than the upper bound"
2234
+ );
2374
2235
  return this.createNode("numeric", {
2375
2236
  baseType,
2376
2237
  lowerBound,
@@ -2385,7 +2246,7 @@ var Parser = class {
2385
2246
  parsePrimitiveType() {
2386
2247
  if (this.current.type === "IDENTIFIER") {
2387
2248
  const name = this.current.value;
2388
- if (PRIMITIVE_TYPES.includes(name)) {
2249
+ if (PRIMITIVE_TYPES_SET.has(name)) {
2389
2250
  this.advance();
2390
2251
  return this.createNode("primitive", { name });
2391
2252
  }
@@ -2719,14 +2580,32 @@ function buildTypeFromAST(node, typeResolver) {
2719
2580
  }
2720
2581
 
2721
2582
  // src/common/type/parse.ts
2583
+ var TYPE_CACHE = /* @__PURE__ */ new Map();
2584
+ var TYPE_CACHE_MAX_SIZE = 2048;
2585
+ function deepFreeze(obj) {
2586
+ if (obj === null || typeof obj !== "object") return obj;
2587
+ if (Object.isFrozen(obj)) return obj;
2588
+ Object.freeze(obj);
2589
+ for (const value of Object.values(obj)) deepFreeze(value);
2590
+ return obj;
2591
+ }
2722
2592
  function parseType(s, typeResolver) {
2723
2593
  if (s === void 0) return void 0;
2724
2594
  if (isValidType(s)) return s;
2725
2595
  if (typeof s !== "string") return void 0;
2596
+ const cacheable = typeResolver === void 0;
2597
+ if (cacheable) {
2598
+ const cached = TYPE_CACHE.get(s);
2599
+ if (cached !== void 0) return cached;
2600
+ }
2726
2601
  try {
2727
2602
  const parser = new Parser(s, { typeResolver });
2728
2603
  const ast = parser.parseType();
2729
2604
  const type = buildTypeFromAST(ast, typeResolver);
2605
+ if (cacheable) {
2606
+ if (TYPE_CACHE.size >= TYPE_CACHE_MAX_SIZE) TYPE_CACHE.clear();
2607
+ TYPE_CACHE.set(s, deepFreeze(type));
2608
+ }
2730
2609
  return type;
2731
2610
  } catch (error) {
2732
2611
  throw new Error(
@@ -2801,19 +2680,36 @@ var PRIMITIVE_SUBTYPES = {
2801
2680
  color: [],
2802
2681
  expression: EXPRESSION_TYPES
2803
2682
  };
2683
+ var PRIMITIVE_SUBTYPES_CLOSURE = (() => {
2684
+ const closure = {};
2685
+ const closeOver = (t) => {
2686
+ if (closure[t]) return closure[t];
2687
+ const result = /* @__PURE__ */ new Set([t]);
2688
+ closure[t] = result;
2689
+ for (const sub of PRIMITIVE_SUBTYPES[t]) {
2690
+ if (sub === t) continue;
2691
+ for (const s of closeOver(sub)) result.add(s);
2692
+ }
2693
+ return result;
2694
+ };
2695
+ for (const t of Object.keys(PRIMITIVE_SUBTYPES))
2696
+ closeOver(t);
2697
+ return closure;
2698
+ })();
2804
2699
  function isPrimitiveSubtype(lhs, rhs) {
2805
2700
  if (rhs === "any") return true;
2806
2701
  if (lhs === "never") return true;
2807
2702
  if (lhs === "unknown" || rhs === "unknown") return false;
2808
2703
  if (lhs === rhs) return true;
2809
- return PRIMITIVE_SUBTYPES[rhs].includes(lhs);
2704
+ return PRIMITIVE_SUBTYPES_CLOSURE[rhs].has(lhs);
2810
2705
  }
2811
2706
  function isSubtype(lhs, rhs) {
2812
- if (typeof lhs === "string" && !PRIMITIVE_TYPES.includes(lhs))
2707
+ if (typeof lhs === "string" && !PRIMITIVE_TYPES_SET.has(lhs))
2813
2708
  lhs = parseType(lhs);
2814
- if (typeof rhs === "string" && !PRIMITIVE_TYPES.includes(rhs))
2709
+ if (typeof rhs === "string" && !PRIMITIVE_TYPES_SET.has(rhs))
2815
2710
  rhs = parseType(rhs);
2816
2711
  if (rhs === "any") return true;
2712
+ if (lhs === "never") return true;
2817
2713
  if (rhs === "never") return false;
2818
2714
  if (rhs === "error") return lhs === "error";
2819
2715
  if (rhs === "nothing") return lhs === "nothing";
@@ -2828,7 +2724,7 @@ function isSubtype(lhs, rhs) {
2828
2724
  if (typeof lhs.value === "number") {
2829
2725
  if (Number.isInteger(lhs.value))
2830
2726
  return isPrimitiveSubtype("integer", rhs);
2831
- return isPrimitiveSubtype("number", rhs);
2727
+ return isPrimitiveSubtype("real", rhs);
2832
2728
  }
2833
2729
  if (typeof lhs.value === "boolean")
2834
2730
  return isPrimitiveSubtype("boolean", rhs);
@@ -3054,127 +2950,340 @@ function isSubtype(lhs, rhs) {
3054
2950
  }
3055
2951
  if (typeof lhs.value === "string") return isSubtype("string", rhs);
3056
2952
  }
3057
- return false;
3058
- }
3059
- function isNumeric(type) {
3060
- if (typeof type === "string")
3061
- return NUMERIC_TYPES.includes(type);
3062
- if (type.kind === "value") return typeof type.value === "number";
3063
- if (type.kind === "numeric") return true;
3064
- return false;
3065
- }
3066
- function isScalar(type) {
3067
- if (isNumeric(type)) return true;
3068
- if (typeof type === "string")
3069
- return SCALAR_TYPES.includes(type);
3070
- if (type.kind === "value")
3071
- return ["string", "boolean", "number"].includes(typeof type.value);
3072
- return false;
3073
- }
3074
- function isCollection(type) {
3075
- if (isIndexedCollection(type)) return true;
3076
- if (typeof type === "string")
3077
- return COLLECTION_TYPES.includes(type);
3078
- return ["collection", "set", "record", "dictionary"].includes(type.kind);
3079
- }
3080
- function isIndexedCollection(type) {
3081
- if (typeof type === "string") return false;
3082
- return ["indexed_collection", "list", "tuple"].includes(type.kind);
3083
- }
3084
- function isValue(type) {
3085
- return isScalar(type) || isCollection(type);
3086
- }
3087
- function isFunction(type) {
3088
- return type === "function" || typeof type !== "string" && type.kind === "signature";
3089
- }
3090
- function isExpression(type) {
3091
- if (typeof type === "string" && ["expression", "symbol", "function"].includes(type))
3092
- return true;
3093
- if (isValue(type) || isFunction(type) || isSymbol(type)) return true;
3094
- if (typeof type === "string") return false;
3095
- if (type.kind === "expression") return true;
3096
- return false;
3097
- }
3098
- function isSymbol(type) {
3099
- if (type === "symbol") return true;
3100
- if (typeof type === "string") return false;
3101
- if (type.kind === "symbol") return true;
3102
- if (type.kind === "expression") return type.operator === "Symbol";
3103
- return false;
3104
- }
3105
- function narrow2(a, b) {
3106
- if (a === b) return a;
3107
- if (a === "nothing" || b === "nothing") return "nothing";
3108
- if (a === "any") return b;
3109
- if (b === "any") return a;
3110
- if (a === "never") return b;
3111
- if (b === "never") return a;
3112
- if (a === "unknown") return b;
3113
- if (b === "unknown") return a;
3114
- if (isSubtype(a, b)) return a;
3115
- if (isSubtype(b, a)) return b;
3116
- return superType(a, b);
3117
- }
3118
- function widen2(a, b) {
3119
- if (a === b) return a;
3120
- if (a === "any" || b === "any") return "any";
3121
- if (a === "never") return b;
3122
- if (b === "never") return a;
3123
- if (a === "unknown") return b;
3124
- if (b === "unknown") return a;
3125
- if (a === "nothing") return b;
3126
- if (b === "nothing") return a;
3127
- if (isSubtype(a, b)) return b;
3128
- if (isSubtype(b, a)) return a;
3129
- return superType(a, b);
3130
- }
3131
- function narrow(...types) {
3132
- if (types.length === 0) return "nothing";
3133
- if (types.length === 1) return types[0];
3134
- return types.reduce((a, b) => narrow2(a, b));
2953
+ return false;
2954
+ }
2955
+ function isNumeric(type) {
2956
+ if (typeof type === "string")
2957
+ return NUMERIC_TYPES_SET.has(type);
2958
+ if (type.kind === "value") return typeof type.value === "number";
2959
+ if (type.kind === "numeric") return true;
2960
+ return false;
2961
+ }
2962
+ function isScalar(type) {
2963
+ if (isNumeric(type)) return true;
2964
+ if (typeof type === "string")
2965
+ return SCALAR_TYPES_SET.has(type);
2966
+ if (type.kind === "value")
2967
+ return ["string", "boolean", "number"].includes(typeof type.value);
2968
+ return false;
2969
+ }
2970
+ function isCollection(type) {
2971
+ if (isIndexedCollection(type)) return true;
2972
+ if (typeof type === "string")
2973
+ return COLLECTION_TYPES_SET.has(type);
2974
+ return ["collection", "set", "record", "dictionary"].includes(type.kind);
2975
+ }
2976
+ function isIndexedCollection(type) {
2977
+ if (typeof type === "string") return false;
2978
+ return ["indexed_collection", "list", "tuple"].includes(type.kind);
2979
+ }
2980
+ function isValue(type) {
2981
+ return isScalar(type) || isCollection(type);
2982
+ }
2983
+ function isFunction(type) {
2984
+ return type === "function" || typeof type !== "string" && type.kind === "signature";
2985
+ }
2986
+ function isExpression(type) {
2987
+ if (typeof type === "string" && ["expression", "symbol", "function"].includes(type))
2988
+ return true;
2989
+ if (isValue(type) || isFunction(type) || isSymbol(type)) return true;
2990
+ if (typeof type === "string") return false;
2991
+ if (type.kind === "expression") return true;
2992
+ return false;
2993
+ }
2994
+ function isSymbol(type) {
2995
+ if (type === "symbol") return true;
2996
+ if (typeof type === "string") return false;
2997
+ if (type.kind === "symbol") return true;
2998
+ if (type.kind === "expression") return type.operator === "Symbol";
2999
+ return false;
3000
+ }
3001
+ function narrow2(a, b) {
3002
+ if (a === b) return a;
3003
+ if (a === "nothing" || b === "nothing") return "nothing";
3004
+ if (a === "any") return b;
3005
+ if (b === "any") return a;
3006
+ if (a === "never") return b;
3007
+ if (b === "never") return a;
3008
+ if (a === "unknown") return b;
3009
+ if (b === "unknown") return a;
3010
+ if (isSubtype(a, b)) return a;
3011
+ if (isSubtype(b, a)) return b;
3012
+ return "never";
3013
+ }
3014
+ function widen2(a, b) {
3015
+ if (a === b) return a;
3016
+ if (a === "any" || b === "any") return "any";
3017
+ if (a === "never") return b;
3018
+ if (b === "never") return a;
3019
+ if (a === "unknown") return b;
3020
+ if (b === "unknown") return a;
3021
+ if (a === "nothing") return b;
3022
+ if (b === "nothing") return a;
3023
+ if (isSubtype(a, b)) return b;
3024
+ if (isSubtype(b, a)) return a;
3025
+ const sup = superType(a, b);
3026
+ if (LOSSY_SUPERTYPE.has(sup)) return unionTypes(a, b);
3027
+ return sup;
3028
+ }
3029
+ var LOSSY_SUPERTYPE = /* @__PURE__ */ new Set([
3030
+ "scalar",
3031
+ "value",
3032
+ "function",
3033
+ "expression",
3034
+ "collection",
3035
+ "indexed_collection",
3036
+ "list",
3037
+ "set",
3038
+ "tuple",
3039
+ "record",
3040
+ "dictionary",
3041
+ "map",
3042
+ "any"
3043
+ ]);
3044
+ function unionTypes(a, b) {
3045
+ const members = [];
3046
+ const keys = /* @__PURE__ */ new Set();
3047
+ const push = (t) => {
3048
+ if (typeof t === "object" && t.kind === "union") {
3049
+ for (const m of t.types) push(m);
3050
+ return;
3051
+ }
3052
+ const key = typeof t === "string" ? t : JSON.stringify(t);
3053
+ if (!keys.has(key)) {
3054
+ keys.add(key);
3055
+ members.push(t);
3056
+ }
3057
+ };
3058
+ push(a);
3059
+ push(b);
3060
+ if (members.length === 1) return members[0];
3061
+ return { kind: "union", types: members };
3062
+ }
3063
+ function narrow(...types) {
3064
+ if (types.length === 0) return "nothing";
3065
+ if (types.length === 1) return types[0];
3066
+ return types.reduce((a, b) => narrow2(a, b));
3067
+ }
3068
+ function widen(...types) {
3069
+ if (types.length === 0) return "nothing";
3070
+ if (types.length === 1) return types[0];
3071
+ return types.reduce((a, b) => widen2(a, b));
3072
+ }
3073
+ var SUPERTYPE_PROBE_ORDER = [
3074
+ "non_finite_number",
3075
+ "finite_integer",
3076
+ "integer",
3077
+ "finite_rational",
3078
+ "rational",
3079
+ "finite_real",
3080
+ "real",
3081
+ "imaginary",
3082
+ "finite_complex",
3083
+ "complex",
3084
+ "finite_number",
3085
+ "number",
3086
+ "list",
3087
+ "record",
3088
+ "dictionary",
3089
+ "set",
3090
+ "tuple",
3091
+ "indexed_collection",
3092
+ "collection",
3093
+ "scalar",
3094
+ "value",
3095
+ "function",
3096
+ "expression"
3097
+ ];
3098
+ var PRIMITIVE_SUPERTYPE_CACHE = /* @__PURE__ */ new Map();
3099
+ function superType(a, b) {
3100
+ if (a === b) return a;
3101
+ if (a === "any" || b === "any") return "any";
3102
+ if (a === "never") return b;
3103
+ if (b === "never") return a;
3104
+ if (a === "unknown") return b;
3105
+ if (b === "unknown") return a;
3106
+ if (a === "nothing") return b;
3107
+ if (b === "nothing") return a;
3108
+ if (typeof a === "string" && typeof b === "string") {
3109
+ const key = a < b ? `${a}|${b}` : `${b}|${a}`;
3110
+ let result = PRIMITIVE_SUPERTYPE_CACHE.get(key);
3111
+ if (result === void 0) {
3112
+ result = "any";
3113
+ for (const ancestor of SUPERTYPE_PROBE_ORDER) {
3114
+ const subtypes = PRIMITIVE_SUBTYPES_CLOSURE[ancestor];
3115
+ if (subtypes.has(a) && subtypes.has(b)) {
3116
+ result = ancestor;
3117
+ break;
3118
+ }
3119
+ }
3120
+ PRIMITIVE_SUPERTYPE_CACHE.set(key, result);
3121
+ }
3122
+ return result;
3123
+ }
3124
+ for (const ancestor of SUPERTYPE_PROBE_ORDER)
3125
+ if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return ancestor;
3126
+ return "any";
3127
+ }
3128
+
3129
+ // src/common/type/serialize.ts
3130
+ var NEGATION_PRECEDENCE = 3;
3131
+ var UNION_PRECEDENCE = 1;
3132
+ var INTERSECTION_PRECEDENCE = 2;
3133
+ var LIST_PRECEDENCE = 4;
3134
+ var RECORD_PRECEDENCE = 5;
3135
+ var DICTIONARY_PRECEDENCE = 6;
3136
+ var SET_PRECEDENCE = 7;
3137
+ var COLLECTION_PRECEDENCE = 8;
3138
+ var TUPLE_PRECEDENCE = 9;
3139
+ var SIGNATURE_PRECEDENCE = 10;
3140
+ var VALUE_PRECEDENCE = 11;
3141
+ function typeToString(type, precedence = 0) {
3142
+ if (typeof type === "string") return type;
3143
+ let result = "";
3144
+ switch (type.kind) {
3145
+ case "value":
3146
+ if (typeof type.value === "string") result = `"${type.value}"`;
3147
+ else if (typeof type.value === "boolean")
3148
+ result = type.value ? "true" : "false";
3149
+ else result = type.value.toString();
3150
+ break;
3151
+ case "reference":
3152
+ result = type.name;
3153
+ break;
3154
+ case "negation":
3155
+ result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
3156
+ break;
3157
+ case "union":
3158
+ result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
3159
+ break;
3160
+ case "intersection":
3161
+ result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
3162
+ break;
3163
+ case "expression":
3164
+ result = `expression<${symbolName(type.operator)}>`;
3165
+ break;
3166
+ case "symbol":
3167
+ result = `symbol<${symbolName(type.name)}>`;
3168
+ break;
3169
+ case "numeric":
3170
+ if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
3171
+ result = `${type.type}<${type.lower}..${type.upper}>`;
3172
+ } else if (Number.isFinite(type.lower)) {
3173
+ result = `${type.type}<${type.lower}..>`;
3174
+ } else if (Number.isFinite(type.upper)) {
3175
+ result = `${type.type}<..${type.upper}>`;
3176
+ } else {
3177
+ result = `${type.type}`;
3178
+ }
3179
+ break;
3180
+ case "list":
3181
+ if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES_SET.has(type.elements)) {
3182
+ if (type.dimensions === void 0) {
3183
+ if (type.elements === "number") result = "tensor";
3184
+ } else if (type.dimensions.length === 1) {
3185
+ if (type.elements === "number") {
3186
+ if (type.dimensions[0] < 0) result = "vector";
3187
+ else result = `vector<${type.dimensions[0]}>`;
3188
+ } else {
3189
+ if (type.dimensions[0] < 0)
3190
+ result = `vector<${typeToString(type.elements)}>`;
3191
+ else
3192
+ result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
3193
+ }
3194
+ } else if (type.dimensions.length === 2) {
3195
+ const dims = type.dimensions;
3196
+ if (type.elements === "number") {
3197
+ if (dims[0] < 0 && dims[1] < 0) result = "matrix";
3198
+ else result = `matrix<${dims[0]}x${dims[1]}>`;
3199
+ } else {
3200
+ if (dims[0] < 0 && dims[1] < 0)
3201
+ result = `matrix<${typeToString(type.elements)}>`;
3202
+ else
3203
+ result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
3204
+ }
3205
+ }
3206
+ }
3207
+ if (!result) {
3208
+ const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
3209
+ result = `list<${typeToString(type.elements)}${dimensions}>`;
3210
+ }
3211
+ break;
3212
+ case "record":
3213
+ const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
3214
+ result = `record<${elements}>`;
3215
+ break;
3216
+ case "dictionary":
3217
+ result = `dictionary<${typeToString(type.values)}>`;
3218
+ break;
3219
+ case "set":
3220
+ result = `set<${typeToString(type.elements)}>`;
3221
+ break;
3222
+ case "collection":
3223
+ result = `collection<${typeToString(type.elements)}>`;
3224
+ break;
3225
+ case "indexed_collection":
3226
+ result = `indexed_collection<${typeToString(type.elements)}>`;
3227
+ break;
3228
+ case "tuple":
3229
+ if (type.elements.length === 0) result = "tuple";
3230
+ else if (type.elements.length === 1) {
3231
+ const [el] = type.elements;
3232
+ result = `tuple<${namedElement(el)}>`;
3233
+ } else {
3234
+ result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
3235
+ }
3236
+ break;
3237
+ case "signature":
3238
+ const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
3239
+ const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
3240
+ const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
3241
+ const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
3242
+ result = `(${argsList}) -> ${typeToString(type.result)}`;
3243
+ break;
3244
+ default:
3245
+ result = "error";
3246
+ }
3247
+ if (precedence > 0 && precedence > getPrecedence(type.kind))
3248
+ return `(${result})`;
3249
+ return result;
3135
3250
  }
3136
- function widen(...types) {
3137
- if (types.length === 0) return "nothing";
3138
- if (types.length === 1) return types[0];
3139
- return types.reduce((a, b) => widen2(a, b));
3251
+ function namedElement(el) {
3252
+ if (el.name) return `${el.name}: ${typeToString(el.type)}`;
3253
+ return typeToString(el.type);
3140
3254
  }
3141
- function superType(a, b) {
3142
- if (a === b) return a;
3143
- if (a === "any" || b === "any") return "any";
3144
- if (a === "never") return b;
3145
- if (b === "never") return a;
3146
- if (a === "unknown") return b;
3147
- if (b === "unknown") return a;
3148
- if (a === "nothing") return b;
3149
- if (b === "nothing") return a;
3150
- if (commonSupertype(a, b, "non_finite_number")) return "non_finite_number";
3151
- if (commonSupertype(a, b, "finite_integer")) return "finite_integer";
3152
- if (commonSupertype(a, b, "integer")) return "integer";
3153
- if (commonSupertype(a, b, "finite_rational")) return "finite_rational";
3154
- if (commonSupertype(a, b, "rational")) return "rational";
3155
- if (commonSupertype(a, b, "finite_real")) return "finite_real";
3156
- if (commonSupertype(a, b, "real")) return "real";
3157
- if (commonSupertype(a, b, "imaginary")) return "imaginary";
3158
- if (commonSupertype(a, b, "finite_complex")) return "finite_complex";
3159
- if (commonSupertype(a, b, "complex")) return "complex";
3160
- if (commonSupertype(a, b, "finite_number")) return "finite_number";
3161
- if (commonSupertype(a, b, "number")) return "number";
3162
- if (commonSupertype(a, b, "list")) return "list";
3163
- if (commonSupertype(a, b, "record")) return "record";
3164
- if (commonSupertype(a, b, "dictionary")) return "dictionary";
3165
- if (commonSupertype(a, b, "set")) return "set";
3166
- if (commonSupertype(a, b, "tuple")) return "tuple";
3167
- if (commonSupertype(a, b, "indexed_collection")) return "indexed_collection";
3168
- if (commonSupertype(a, b, "collection")) return "collection";
3169
- if (commonSupertype(a, b, "scalar")) return "scalar";
3170
- if (commonSupertype(a, b, "value")) return "value";
3171
- if (commonSupertype(a, b, "function")) return "function";
3172
- if (commonSupertype(a, b, "expression")) return "expression";
3173
- return "any";
3255
+ function symbolName(name) {
3256
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
3257
+ return `\`${name}\``;
3174
3258
  }
3175
- function commonSupertype(a, b, ancestor) {
3176
- if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return true;
3177
- return false;
3259
+ function getPrecedence(kind) {
3260
+ switch (kind) {
3261
+ case "negation":
3262
+ return NEGATION_PRECEDENCE;
3263
+ case "union":
3264
+ return UNION_PRECEDENCE;
3265
+ case "intersection":
3266
+ return INTERSECTION_PRECEDENCE;
3267
+ case "list":
3268
+ return LIST_PRECEDENCE;
3269
+ case "record":
3270
+ return RECORD_PRECEDENCE;
3271
+ case "dictionary":
3272
+ return DICTIONARY_PRECEDENCE;
3273
+ case "set":
3274
+ return SET_PRECEDENCE;
3275
+ case "collection":
3276
+ case "indexed_collection":
3277
+ return COLLECTION_PRECEDENCE;
3278
+ case "tuple":
3279
+ return TUPLE_PRECEDENCE;
3280
+ case "signature":
3281
+ return SIGNATURE_PRECEDENCE;
3282
+ case "value":
3283
+ return VALUE_PRECEDENCE;
3284
+ default:
3285
+ return 0;
3286
+ }
3178
3287
  }
3179
3288
 
3180
3289
  // src/common/type/boxed-type.ts
@@ -4014,15 +4123,16 @@ var DEFINITIONS_CORE = [
4014
4123
  precedence: ASSIGNMENT_PRECEDENCE,
4015
4124
  parse: parseAssign
4016
4125
  },
4017
- // General colon operator (type annotation, mapping notation)
4018
- // Precedence below assignment (260) so `:=` takes priority,
4019
- // and below arrows (270) so `f: A \to B` parses as `Colon(f, To(A, B))`
4126
+ // General colon operator (type annotation, mapping notation, Desmos piecewise)
4127
+ // Precedence below comparisons (245) so `cond : val` (Desmos compact piecewise)
4128
+ // parses as `Colon(cond, val)`, and below arrows (270) so
4129
+ // `f: A \to B` parses as `Colon(f, To(A, B))`.
4020
4130
  {
4021
4131
  name: "Colon",
4022
4132
  latexTrigger: ":",
4023
4133
  kind: "infix",
4024
4134
  associativity: "right",
4025
- precedence: 250,
4135
+ precedence: 240,
4026
4136
  serialize: (serializer, expr) => joinLatex([
4027
4137
  serializer.serialize(operand(expr, 1)),
4028
4138
  "\\colon",
@@ -4033,7 +4143,7 @@ var DEFINITIONS_CORE = [
4033
4143
  latexTrigger: "\\colon",
4034
4144
  kind: "infix",
4035
4145
  associativity: "right",
4036
- precedence: 250,
4146
+ precedence: 240,
4037
4147
  parse: "Colon"
4038
4148
  },
4039
4149
  {
@@ -5009,6 +5119,7 @@ var DEFINITIONS_CORE = [
5009
5119
  }
5010
5120
  }
5011
5121
  if (!variable) return null;
5122
+ if (symbol(variable) === null) return null;
5012
5123
  parser.skipSpace();
5013
5124
  const fn = parser.parseExpression({ minPrec: 740 });
5014
5125
  if (!fn) return null;
@@ -5195,7 +5306,7 @@ function parseTextRun(parser, style) {
5195
5306
  if (runs.length === 1) body = runs[0];
5196
5307
  else {
5197
5308
  if (runs.every((x) => stringValue(x) !== null))
5198
- body = "'" + runs.map((x) => stringValue(x)).join() + "'";
5309
+ body = "'" + runs.map((x) => stringValue(x)).join("") + "'";
5199
5310
  else body = ["Text", ...runs];
5200
5311
  }
5201
5312
  return style ? ["Annotated", body, dictionaryFromEntries(style)] : body;
@@ -5603,7 +5714,10 @@ function parseForComprehension(parser, lhs, until) {
5603
5714
  p.skipVisualSpace();
5604
5715
  const isComma = p.peek === ",";
5605
5716
  p.index = saved;
5606
- return isComma;
5717
+ if (isComma) return true;
5718
+ if (peekKeyword(p, "where")) return true;
5719
+ if (peekKeyword(p, "with")) return true;
5720
+ return false;
5607
5721
  }
5608
5722
  };
5609
5723
  const elements = [];
@@ -5644,6 +5758,25 @@ function parseWhereExpression(parser, lhs, until) {
5644
5758
  parser.skipVisualSpace();
5645
5759
  } while (parser.match(","));
5646
5760
  if (bindings.length === 0) return null;
5761
+ const forStart = parser.index;
5762
+ if (matchKeyword(parser, "for")) {
5763
+ const loop = parseForComprehension(parser, lhs, until);
5764
+ if (loop) {
5765
+ const block2 = [];
5766
+ for (const b of bindings) {
5767
+ const normalized = normalizeLocalAssign(b);
5768
+ if (operator(normalized) === "Assign") {
5769
+ block2.push(["Declare", operand(normalized, 1)]);
5770
+ block2.push(normalized);
5771
+ } else {
5772
+ block2.push(normalized);
5773
+ }
5774
+ }
5775
+ block2.push(loop);
5776
+ return ["Block", ...block2];
5777
+ }
5778
+ parser.index = forStart;
5779
+ }
5647
5780
  const block = [];
5648
5781
  for (const b of bindings) {
5649
5782
  const normalized = normalizeLocalAssign(b);
@@ -5857,6 +5990,17 @@ function parseIntervalBody(body, openLeft, openRight) {
5857
5990
  const upperExpr = openRight ? ["Open", upper] : upper;
5858
5991
  return ["Interval", lowerExpr, upperExpr];
5859
5992
  }
5993
+ var COMPARISON_HEADS = /* @__PURE__ */ new Set([
5994
+ "Less",
5995
+ "LessEqual",
5996
+ "Greater",
5997
+ "GreaterEqual",
5998
+ "Equal",
5999
+ "NotEqual",
6000
+ "And",
6001
+ "Or",
6002
+ "Not"
6003
+ ]);
5860
6004
  var DEFINITIONS_SETS = [
5861
6005
  //
5862
6006
  // Constants
@@ -6115,18 +6259,58 @@ var DEFINITIONS_SETS = [
6115
6259
  closeTrigger: "}",
6116
6260
  parse: (_parser, body) => {
6117
6261
  if (isEmptySequence(body)) return "EmptySet";
6262
+ if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
6263
+ body = operand(body, 1);
6264
+ }
6118
6265
  const h = operator(body);
6119
- if (h === "Divides" || h === "Colon") {
6266
+ if (h === "Divides") {
6120
6267
  const expr = operand(body, 1);
6121
6268
  const condition = operand(body, 2);
6122
6269
  if (expr !== null && condition !== null)
6123
6270
  return ["Set", expr, ["Condition", condition]];
6124
6271
  }
6125
- if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
6126
- body = operand(body, 1);
6272
+ if (h === "Colon") {
6273
+ const lhs = operand(body, 1);
6274
+ const rhs = operand(body, 2);
6275
+ if (lhs !== null && rhs !== null) {
6276
+ const lhsOp = operator(lhs);
6277
+ if (lhsOp !== null && COMPARISON_HEADS.has(lhsOp)) {
6278
+ return ["Which", lhs, rhs];
6279
+ }
6280
+ return ["Set", lhs, ["Condition", rhs]];
6281
+ }
6282
+ }
6283
+ if (h === "Sequence") {
6284
+ const elements = operands(body);
6285
+ const colonElements = elements.filter((el) => operator(el) === "Colon");
6286
+ const allPiecewise = colonElements.length > 0 && colonElements.every((el) => {
6287
+ const lhs = operand(el, 1);
6288
+ const lhsOp = lhs !== null ? operator(lhs) : null;
6289
+ return lhsOp !== null && COMPARISON_HEADS.has(lhsOp);
6290
+ });
6291
+ if (allPiecewise) {
6292
+ const whichOps = [];
6293
+ for (let i = 0; i < elements.length; i++) {
6294
+ const el = elements[i];
6295
+ if (operator(el) === "Colon") {
6296
+ const cond = operand(el, 1);
6297
+ const val = operand(el, 2);
6298
+ if (cond === null || val === null) {
6299
+ return ["Set", ...elements];
6300
+ }
6301
+ whichOps.push(cond, val);
6302
+ } else {
6303
+ if (i !== elements.length - 1) {
6304
+ return ["Set", ...elements];
6305
+ }
6306
+ whichOps.push("True", el);
6307
+ }
6308
+ }
6309
+ return ["Which", ...whichOps];
6310
+ }
6311
+ return ["Set", ...elements];
6127
6312
  }
6128
- if (operator(body) !== "Sequence") return ["Set", body];
6129
- return ["Set", ...operands(body)];
6313
+ return ["Set", body];
6130
6314
  },
6131
6315
  serialize: (serializer, expr) => {
6132
6316
  if (nops(expr) === 2 && operator(operand(expr, 2)) === "Condition") {
@@ -6685,6 +6869,8 @@ function serializeMultiply(serializer, expr) {
6685
6869
  const h = operator(arg);
6686
6870
  if (prevWasNumber && (h === "Divide" || h === "Rational")) {
6687
6871
  result = latexTemplate(serializer.options.multiply, result, term);
6872
+ } else if (/^\d/.test(term)) {
6873
+ result = latexTemplate(serializer.options.multiply, result, term);
6688
6874
  } else if (!serializer.options.invisibleMultiply) {
6689
6875
  result = joinLatex([result, term]);
6690
6876
  } else {
@@ -8130,7 +8316,9 @@ function parseTrig(op) {
8130
8316
  minPrec: MULTIPLICATION_PRECEDENCE,
8131
8317
  condition: (parser2) => trigCommands[parser2.peek] || (until?.condition?.(parser2) ?? false)
8132
8318
  });
8133
- const appliedFn = args === null ? fn : typeof fn === "string" ? [fn, ...args] : ["Apply", fn, ...args];
8319
+ const isTwoArgArctan = args?.length === 2 && (fn === "Arctan" || Array.isArray(fn) && fn[0] === "InverseFunction" && fn[1] === "Tan");
8320
+ const head = isTwoArgArctan ? "Arctan2" : fn;
8321
+ const appliedFn = args === null ? fn : typeof head === "string" ? [head, ...args] : ["Apply", head, ...args];
8134
8322
  return sup === null ? appliedFn : ["Power", appliedFn, sup];
8135
8323
  };
8136
8324
  }
@@ -10253,10 +10441,17 @@ var DEFINITIONS_OTHERS = [
10253
10441
  // The capitalized library entries already exist; these are pure parse
10254
10442
  // aliases so the lowercase names don't land in `unsupported-operator`.
10255
10443
  // ---------------------------------------------------------------------------
10444
+ { latexTrigger: "\\operatorname{count}", parse: "Length" },
10256
10445
  { latexTrigger: "\\operatorname{random}", parse: "Random" },
10257
10446
  { latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
10258
10447
  { latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
10259
10448
  { latexTrigger: "\\operatorname{join}", parse: "Join" },
10449
+ { latexTrigger: "\\operatorname{range}", parse: "Range" },
10450
+ // Note: `\operatorname{with}` (Desmos's local-binding clause) is intentionally
10451
+ // NOT registered here. Use the math-notation equivalent `\operatorname{where}`
10452
+ // (with `\coloneq` for bindings), or register `with` as a custom dictionary
10453
+ // entry at the integration layer — see the "Desmos-Specific Syntax — Prefer
10454
+ // Custom LaTeX Dictionary" section in COMPUTE_ENGINE.md for a worked example.
10260
10455
  // ---------------------------------------------------------------------------
10261
10456
  // Geometric primitive heads. Registered as known typed heads so consumers
10262
10457
  // can branch on the operator name; CE itself doesn't render them. The
@@ -10629,10 +10824,41 @@ function indexLatexDictionary(dic, onError) {
10629
10824
  postfixByTrigger: /* @__PURE__ */ new Map(),
10630
10825
  functionByTrigger: /* @__PURE__ */ new Map(),
10631
10826
  symbolByTrigger: /* @__PURE__ */ new Map(),
10632
- expressionByTrigger: /* @__PURE__ */ new Map()
10827
+ expressionByTrigger: /* @__PURE__ */ new Map(),
10828
+ operatorByTrigger: /* @__PURE__ */ new Map(),
10829
+ universalDefs: /* @__PURE__ */ new Map(),
10830
+ symbolTriggerDefs: /* @__PURE__ */ new Map()
10633
10831
  };
10634
10832
  for (const entry of dic)
10635
10833
  addEntry(result, entry, onError);
10834
+ for (let i = result.defs.length - 1; i >= 0; i--) {
10835
+ const def = result.defs[i];
10836
+ const isOperator = def.kind === "infix" || def.kind === "prefix" || def.kind === "postfix";
10837
+ const kinds = isOperator ? [def.kind, "operator"] : [def.kind];
10838
+ for (const kind of kinds) {
10839
+ if (def.latexTrigger === "") {
10840
+ const defs = result.universalDefs.get(kind);
10841
+ if (defs) defs.push(def);
10842
+ else result.universalDefs.set(kind, [def]);
10843
+ }
10844
+ if (def.symbolTrigger) {
10845
+ let byTrigger = result.symbolTriggerDefs.get(kind);
10846
+ if (!byTrigger) {
10847
+ byTrigger = /* @__PURE__ */ new Map();
10848
+ result.symbolTriggerDefs.set(kind, byTrigger);
10849
+ }
10850
+ const defs = byTrigger.get(def.symbolTrigger);
10851
+ if (defs) defs.push(def);
10852
+ else byTrigger.set(def.symbolTrigger, [def]);
10853
+ }
10854
+ if (kind === "operator" && def.latexTrigger && def.latexTrigger !== "") {
10855
+ const operatorDef = def;
10856
+ const defs = result.operatorByTrigger.get(def.latexTrigger);
10857
+ if (defs) defs.push(operatorDef);
10858
+ else result.operatorByTrigger.set(def.latexTrigger, [operatorDef]);
10859
+ }
10860
+ }
10861
+ }
10636
10862
  const COMPLEMENTARY_PAIRS = {
10637
10863
  "(": [")", "\\rparen"],
10638
10864
  "\\lparen": [")", "\\rparen"],
@@ -10997,7 +11223,7 @@ function isValidEntry(entry, onError) {
10997
11223
  }
10998
11224
  }
10999
11225
  if (isMatchfixEntry(entry)) {
11000
- if ("latexTrigger" in entry || "symbolTrigger" in isPrefixEntry) {
11226
+ if ("latexTrigger" in entry || "symbolTrigger" in entry) {
11001
11227
  onError({
11002
11228
  severity: "warning",
11003
11229
  message: [
@@ -11096,6 +11322,15 @@ function isValidEntry(entry, onError) {
11096
11322
  }
11097
11323
 
11098
11324
  // src/compute-engine/latex-syntax/parse-symbol.ts
11325
+ var _symbolNameByLatex = null;
11326
+ function getSymbolNameByLatex() {
11327
+ if (!_symbolNameByLatex) {
11328
+ _symbolNameByLatex = /* @__PURE__ */ new Map();
11329
+ for (const [name, latex] of SYMBOLS)
11330
+ if (!_symbolNameByLatex.has(latex)) _symbolNameByLatex.set(latex, name);
11331
+ }
11332
+ return _symbolNameByLatex;
11333
+ }
11099
11334
  var SYMBOL_PREFIX = {
11100
11335
  // Those are "grouping" prefix that also specify spacing
11101
11336
  // around the symbol. We ignore the spacing, though.
@@ -11174,10 +11409,10 @@ function parseSymbolToken(parser, options) {
11174
11409
  parser.nextToken();
11175
11410
  return special;
11176
11411
  }
11177
- const i = SYMBOLS.findIndex((x) => x[1] === token);
11178
- if (i >= 0) {
11412
+ const symbolName2 = getSymbolNameByLatex().get(token);
11413
+ if (symbolName2 !== void 0) {
11179
11414
  parser.nextToken();
11180
- return SYMBOLS[i][0];
11415
+ return symbolName2;
11181
11416
  }
11182
11417
  const c = parser.parseChar();
11183
11418
  if (c !== null) {
@@ -11274,11 +11509,12 @@ function matchPrefixedSymbol(parser) {
11274
11509
  body = digit;
11275
11510
  parser.nextToken();
11276
11511
  }
11277
- body += parseSymbolBody(parser);
11278
- if (body === null || !parser.match("<}>")) {
11512
+ const rest = parseSymbolBody(parser);
11513
+ if (rest === null || !parser.match("<}>")) {
11279
11514
  parser.index = start;
11280
11515
  return null;
11281
11516
  }
11517
+ body += rest;
11282
11518
  if (prefix === "_upright" && body.length > 1) return body;
11283
11519
  return body + prefix;
11284
11520
  }
@@ -11489,6 +11725,7 @@ function fpexp(x, scale) {
11489
11725
  return sum;
11490
11726
  }
11491
11727
  function fpln(x, scale) {
11728
+ if (x <= 0n) throw new RangeError("fpln: input must be positive");
11492
11729
  if (x === scale) return 0n;
11493
11730
  const xNum = Number(x);
11494
11731
  const scaleNum = Number(scale);
@@ -12138,9 +12375,11 @@ var BigDecimal = class _BigDecimal {
12138
12375
  if (Number.isFinite(thisExp) && Number.isFinite(otherExp)) {
12139
12376
  if (other.significand === 0n) return _BigDecimal.NAN;
12140
12377
  if (this.significand === 0n) return fromRaw(0n, 0);
12141
- return this.sub(this.div(other).trunc().mul(other)).toPrecision(
12142
- _BigDecimal.precision
12143
- );
12378
+ const ediff = thisExp - otherExp;
12379
+ const num = ediff >= 0 ? this.significand * pow10(ediff) : this.significand;
12380
+ const den = ediff >= 0 ? other.significand : other.significand * pow10(-ediff);
12381
+ const q = num / den;
12382
+ return this.sub(fromRaw(q, 0).mul(other));
12144
12383
  }
12145
12384
  if (thisExp !== thisExp || otherExp !== otherExp) return _BigDecimal.NAN;
12146
12385
  if (!Number.isFinite(thisExp)) return _BigDecimal.NAN;
@@ -12185,7 +12424,10 @@ var BigDecimal = class _BigDecimal {
12185
12424
  return this.pow(n.neg()).inv();
12186
12425
  }
12187
12426
  const absSig = this.significand < 0n ? -this.significand : this.significand;
12188
- const thisLog10 = bigintDigits(absSig) + this.exponent;
12427
+ const sigDigits = bigintDigits(absSig);
12428
+ const dropped = sigDigits > 15 ? sigDigits - 15 : 0;
12429
+ const lead = dropped > 0 ? Number(absSig / 10n ** BigInt(dropped)) : Number(absSig);
12430
+ const thisLog10 = Math.log10(lead) + dropped + this.exponent;
12189
12431
  const resultLog10 = Number(expValue) * thisLog10;
12190
12432
  if (resultLog10 > 9e15) {
12191
12433
  return this.significand < 0n && expValue % 2n !== 0n ? _BigDecimal.NEGATIVE_INFINITY : _BigDecimal.POSITIVE_INFINITY;
@@ -12218,7 +12460,19 @@ var BigDecimal = class _BigDecimal {
12218
12460
  return _BigDecimal.POSITIVE_INFINITY;
12219
12461
  }
12220
12462
  if (this.significand < 0n) return _BigDecimal.NAN;
12221
- return n.mul(this.ln()).exp();
12463
+ const baseSig = this.significand;
12464
+ const decExpBase = this.exponent + bigintDigits(baseSig) - 1;
12465
+ const nSig = n.significand < 0n ? -n.significand : n.significand;
12466
+ const decExpN = n.exponent + bigintDigits(nSig) - 1;
12467
+ const argMag = decExpN + Math.log10(Math.abs(decExpBase) * 2.303 + 3) + 1;
12468
+ const extra = Math.min(20, Math.max(2, Math.ceil(argMag) + 2));
12469
+ const savedPrec = _BigDecimal.precision;
12470
+ _BigDecimal.precision = savedPrec + extra;
12471
+ try {
12472
+ return n.mul(this.ln()).exp().toPrecision(savedPrec);
12473
+ } finally {
12474
+ _BigDecimal.precision = savedPrec;
12475
+ }
12222
12476
  }
12223
12477
  // ---------- Conversion methods ----------
12224
12478
  /** Convert to a JavaScript number. May lose precision for large values. */
@@ -12459,6 +12713,20 @@ function fromFixedPoint(fp, scale, targetPrecision) {
12459
12713
  const sig = negative ? -absFp : absFp;
12460
12714
  return fromRaw(sig, resultExp);
12461
12715
  }
12716
+ function decimalExponent(x) {
12717
+ const sig = x.significand < 0n ? -x.significand : x.significand;
12718
+ return x.exponent + bigintDigits(sig) - 1;
12719
+ }
12720
+ var MAX_SAFE_EXPONENT = BigInt(Number.MAX_SAFE_INTEGER);
12721
+ var _ln10Fp = null;
12722
+ var _ln10Scale = null;
12723
+ function ln10Fixed(scale) {
12724
+ if (_ln10Scale !== scale) {
12725
+ _ln10Fp = fpln(10n * scale, scale);
12726
+ _ln10Scale = scale;
12727
+ }
12728
+ return _ln10Fp;
12729
+ }
12462
12730
  BigDecimal.prototype.sqrt = function() {
12463
12731
  if (this.isNaN()) return BigDecimal.NAN;
12464
12732
  if (this.isZero()) return BigDecimal.ZERO;
@@ -12469,9 +12737,13 @@ BigDecimal.prototype.sqrt = function() {
12469
12737
  if (this.significand < 0n) return BigDecimal.NAN;
12470
12738
  const targetPrec = BigDecimal.precision;
12471
12739
  const workingPrec = targetPrec + 10;
12472
- const [fp, scale] = toFixedPoint(this, workingPrec);
12740
+ const e = decimalExponent(this);
12741
+ const k = Math.floor(e / 2);
12742
+ const m = fromRaw(this.significand, this.exponent - 2 * k);
12743
+ const [fp, scale] = toFixedPoint(m, workingPrec);
12473
12744
  const sqrtFp = fpsqrt(fp, scale);
12474
- return fromFixedPoint(sqrtFp, scale, targetPrec);
12745
+ const root = fromFixedPoint(sqrtFp, scale, targetPrec);
12746
+ return fromRaw(root.significand, root.exponent + k);
12475
12747
  };
12476
12748
  BigDecimal.prototype.cbrt = function() {
12477
12749
  if (this.isNaN()) return BigDecimal.NAN;
@@ -12485,10 +12757,13 @@ BigDecimal.prototype.cbrt = function() {
12485
12757
  }
12486
12758
  const targetPrec = BigDecimal.precision;
12487
12759
  const workingPrec = targetPrec + 10;
12488
- const [fp, scale] = toFixedPoint(this, workingPrec);
12760
+ const e = decimalExponent(this);
12761
+ const k = Math.floor(e / 3);
12762
+ const m = fromRaw(this.significand, this.exponent - 3 * k);
12763
+ const [fp, scale] = toFixedPoint(m, workingPrec);
12489
12764
  const C = fp * scale * scale;
12490
12765
  let x;
12491
- const numVal = this.toNumber();
12766
+ const numVal = m.toNumber();
12492
12767
  const scaleNum = Number(scale);
12493
12768
  if (Number.isFinite(numVal) && numVal > 0 && Number.isFinite(scaleNum)) {
12494
12769
  const approx = Math.cbrt(numVal);
@@ -12517,7 +12792,8 @@ BigDecimal.prototype.cbrt = function() {
12517
12792
  const diffNext = bigintAbs(next * next * next - C);
12518
12793
  if (diffNext < diffX) x = next;
12519
12794
  }
12520
- return fromFixedPoint(x, scale, targetPrec);
12795
+ const root = fromFixedPoint(x, scale, targetPrec);
12796
+ return fromRaw(root.significand, root.exponent + k);
12521
12797
  };
12522
12798
  BigDecimal.sqrt = function(x) {
12523
12799
  return x.sqrt();
@@ -12532,11 +12808,27 @@ BigDecimal.prototype.exp = function() {
12532
12808
  return BigDecimal.ZERO;
12533
12809
  }
12534
12810
  if (this.isZero()) return BigDecimal.ONE;
12811
+ if (decimalExponent(this) >= 17)
12812
+ return this.significand > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
12535
12813
  const targetPrec = BigDecimal.precision;
12536
- const workingPrec = targetPrec + 15;
12537
- const [fp, scale] = toFixedPoint(this, workingPrec);
12538
- const expFp = fpexp(fp, scale);
12539
- return fromFixedPoint(expFp, scale, targetPrec);
12814
+ const absSig = this.significand < 0n ? -this.significand : this.significand;
12815
+ const magnitude = Math.max(0, this.exponent + bigintDigits(absSig));
12816
+ const workingPrec = targetPrec + 20 + magnitude;
12817
+ const [xFp, scale] = toFixedPoint(this, workingPrec);
12818
+ const l10 = ln10Fixed(scale);
12819
+ let k = xFp / l10;
12820
+ let rFp = xFp - k * l10;
12821
+ if (rFp < 0n) {
12822
+ k -= 1n;
12823
+ rFp += l10;
12824
+ }
12825
+ if (k > MAX_SAFE_EXPONENT || k < -MAX_SAFE_EXPONENT)
12826
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
12827
+ const expR = fromFixedPoint(fpexp(rFp, scale), scale, targetPrec);
12828
+ const newExp = expR.exponent + Number(k);
12829
+ if (!Number.isSafeInteger(newExp))
12830
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
12831
+ return fromRaw(expR.significand, newExp);
12540
12832
  };
12541
12833
  BigDecimal.prototype.ln = function() {
12542
12834
  if (this.isNaN()) return BigDecimal.NAN;
@@ -12548,10 +12840,16 @@ BigDecimal.prototype.ln = function() {
12548
12840
  if (this.significand < 0n) return BigDecimal.NAN;
12549
12841
  if (this.eq(1)) return BigDecimal.ZERO;
12550
12842
  const targetPrec = BigDecimal.precision;
12551
- const workingPrec = targetPrec + 15;
12552
- const [fp, scale] = toFixedPoint(this, workingPrec);
12553
- const lnFp = fpln(fp, scale);
12554
- return fromFixedPoint(lnFp, scale, targetPrec);
12843
+ const sig = this.significand;
12844
+ const digits = bigintDigits(sig);
12845
+ const e = this.exponent + digits - 1;
12846
+ const m = fromRaw(sig, -(digits - 1));
12847
+ const eDigits = Math.abs(e).toString().length;
12848
+ const workingPrec = targetPrec + 20 + eDigits;
12849
+ const [mFp, scale] = toFixedPoint(m, workingPrec);
12850
+ const l10 = ln10Fixed(scale);
12851
+ const resultFp = fpln(mFp, scale) + BigInt(e) * l10;
12852
+ return fromFixedPoint(resultFp, scale, targetPrec);
12555
12853
  };
12556
12854
  BigDecimal.prototype.log = function(base) {
12557
12855
  const b = base instanceof BigDecimal ? base : new BigDecimal(base);
@@ -12571,7 +12869,10 @@ BigDecimal.prototype.sin = function() {
12571
12869
  if (!this.isFinite()) return BigDecimal.NAN;
12572
12870
  if (this.isZero()) return BigDecimal.ZERO;
12573
12871
  const targetPrec = BigDecimal.precision;
12574
- const workingPrec = targetPrec + 15;
12872
+ const e = decimalExponent(this);
12873
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
12874
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
12875
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
12575
12876
  const [fp, scale] = toFixedPoint(this, workingPrec);
12576
12877
  const [sinFp] = fpsincos(fp, scale);
12577
12878
  return fromFixedPoint(sinFp, scale, targetPrec);
@@ -12582,6 +12883,8 @@ BigDecimal.prototype.cos = function() {
12582
12883
  if (this.isZero()) return BigDecimal.ONE;
12583
12884
  const targetPrec = BigDecimal.precision;
12584
12885
  const workingPrec = targetPrec + 15;
12886
+ const e = decimalExponent(this);
12887
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
12585
12888
  const [fp, scale] = toFixedPoint(this, workingPrec);
12586
12889
  const [, cosFp] = fpsincos(fp, scale);
12587
12890
  return fromFixedPoint(cosFp, scale, targetPrec);
@@ -12591,7 +12894,10 @@ BigDecimal.prototype.tan = function() {
12591
12894
  if (!this.isFinite()) return BigDecimal.NAN;
12592
12895
  if (this.isZero()) return BigDecimal.ZERO;
12593
12896
  const targetPrec = BigDecimal.precision;
12594
- const workingPrec = targetPrec + 15;
12897
+ const e = decimalExponent(this);
12898
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
12899
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
12900
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
12595
12901
  const [fp, scale] = toFixedPoint(this, workingPrec);
12596
12902
  const [sinFp, cosFp] = fpsincos(fp, scale);
12597
12903
  if (cosFp === 0n) {
@@ -12609,7 +12915,9 @@ BigDecimal.prototype.atan = function() {
12609
12915
  return piHalf.neg();
12610
12916
  }
12611
12917
  const targetPrec = BigDecimal.precision;
12612
- const workingPrec = targetPrec + 15;
12918
+ const e = decimalExponent(this);
12919
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
12920
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
12613
12921
  const [fp, scale] = toFixedPoint(this, workingPrec);
12614
12922
  const atanFp = fpatan(fp, scale);
12615
12923
  return fromFixedPoint(atanFp, scale, targetPrec);
@@ -12626,7 +12934,9 @@ BigDecimal.prototype.asin = function() {
12626
12934
  return this.significand > 0n ? piHalf : piHalf.neg();
12627
12935
  }
12628
12936
  const targetPrec = BigDecimal.precision;
12629
- const workingPrec = targetPrec + 20;
12937
+ const e = decimalExponent(this);
12938
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
12939
+ const workingPrec = targetPrec + 20 + (e < 0 ? -e : 0);
12630
12940
  const [xFp, scale] = toFixedPoint(this, workingPrec);
12631
12941
  const x2 = fpmul(xFp, xFp, scale);
12632
12942
  const oneMinusX2 = scale - x2;
@@ -12689,6 +12999,23 @@ BigDecimal.prototype.sinh = function() {
12689
12999
  if (this.significand > 0n) return BigDecimal.POSITIVE_INFINITY;
12690
13000
  return BigDecimal.NEGATIVE_INFINITY;
12691
13001
  }
13002
+ const targetPrec = BigDecimal.precision;
13003
+ const e = decimalExponent(this);
13004
+ if (e < 0) {
13005
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
13006
+ const saved = BigDecimal.precision;
13007
+ BigDecimal.precision = targetPrec - e + 5;
13008
+ try {
13009
+ const expX2 = this.exp();
13010
+ return expX2.sub(expX2.inv()).div(BigDecimal.TWO).toPrecision(targetPrec);
13011
+ } finally {
13012
+ BigDecimal.precision = saved;
13013
+ }
13014
+ }
13015
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3)) {
13016
+ const h = this.abs().exp().div(BigDecimal.TWO);
13017
+ return this.significand > 0n ? h : h.neg();
13018
+ }
12692
13019
  const expX = this.exp();
12693
13020
  const expNegX = expX.inv();
12694
13021
  return expX.sub(expNegX).div(BigDecimal.TWO);
@@ -12699,6 +13026,9 @@ BigDecimal.prototype.cosh = function() {
12699
13026
  if (!this.isFinite()) {
12700
13027
  return BigDecimal.POSITIVE_INFINITY;
12701
13028
  }
13029
+ const targetPrec = BigDecimal.precision;
13030
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
13031
+ return this.abs().exp().div(BigDecimal.TWO);
12702
13032
  const expX = this.exp();
12703
13033
  const expNegX = expX.inv();
12704
13034
  return expX.add(expNegX).div(BigDecimal.TWO);
@@ -12710,6 +13040,21 @@ BigDecimal.prototype.tanh = function() {
12710
13040
  if (this.significand > 0n) return BigDecimal.ONE;
12711
13041
  return BigDecimal.NEGATIVE_ONE;
12712
13042
  }
13043
+ const targetPrec = BigDecimal.precision;
13044
+ const e = decimalExponent(this);
13045
+ if (e < 0) {
13046
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
13047
+ const saved = BigDecimal.precision;
13048
+ BigDecimal.precision = targetPrec - e + 5;
13049
+ try {
13050
+ const exp2x2 = this.mul(BigDecimal.TWO).exp();
13051
+ return exp2x2.sub(BigDecimal.ONE).div(exp2x2.add(BigDecimal.ONE)).toPrecision(targetPrec);
13052
+ } finally {
13053
+ BigDecimal.precision = saved;
13054
+ }
13055
+ }
13056
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
13057
+ return this.significand > 0n ? BigDecimal.ONE : BigDecimal.NEGATIVE_ONE;
12713
13058
  const exp2x = this.mul(BigDecimal.TWO).exp();
12714
13059
  return exp2x.sub(BigDecimal.ONE).div(exp2x.add(BigDecimal.ONE));
12715
13060
  };
@@ -12858,7 +13203,7 @@ function mayBeRepeatingDigits(parser) {
12858
13203
  const peek = parser.peek;
12859
13204
  if (peek === "\\overline") return true;
12860
13205
  if (peek === "\\overset") return true;
12861
- if (peek === "\\wideparent" || peek === "\\overarc") return true;
13206
+ if (peek === "\\wideparen" || peek === "\\overarc") return true;
12862
13207
  if (peek === "(") return true;
12863
13208
  if (peek === "\\left") return true;
12864
13209
  return false;
@@ -13025,6 +13370,106 @@ function parseNumber(parser, fmt) {
13025
13370
  }
13026
13371
 
13027
13372
  // src/compute-engine/latex-syntax/parse.ts
13373
+ var PARSE_TOKEN_EXCLUDED = /* @__PURE__ */ new Set([
13374
+ ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
13375
+ "\\left",
13376
+ "\\bigl",
13377
+ "\\mleft"
13378
+ ]);
13379
+ var VISUAL_SPACE_COMMANDS = /* @__PURE__ */ new Set([
13380
+ "\\!",
13381
+ "\\,",
13382
+ "\\:",
13383
+ "\\;",
13384
+ "\\enskip",
13385
+ "\\enspace",
13386
+ "\\space",
13387
+ "\\quad",
13388
+ "\\qquad"
13389
+ ]);
13390
+ var TEX_UNIT_TOKENS = [
13391
+ "pt",
13392
+ "em",
13393
+ "mu",
13394
+ "ex",
13395
+ "mm",
13396
+ "cm",
13397
+ "in",
13398
+ "bp",
13399
+ "sp",
13400
+ "dd",
13401
+ "cc",
13402
+ "pc",
13403
+ "nc",
13404
+ "nd"
13405
+ ].map((unit) => [...unit]);
13406
+ var BARE_FUNCTION_MAP = {
13407
+ // Trigonometric
13408
+ sin: "Sin",
13409
+ cos: "Cos",
13410
+ tan: "Tan",
13411
+ cot: "Cot",
13412
+ sec: "Sec",
13413
+ csc: "Csc",
13414
+ // Hyperbolic
13415
+ sinh: "Sinh",
13416
+ cosh: "Cosh",
13417
+ tanh: "Tanh",
13418
+ coth: "Coth",
13419
+ sech: "Sech",
13420
+ csch: "Csch",
13421
+ // Inverse trigonometric
13422
+ arcsin: "Arcsin",
13423
+ arccos: "Arccos",
13424
+ arctan: "Arctan",
13425
+ arccot: "Arccot",
13426
+ arcsec: "Arcsec",
13427
+ arccsc: "Arccsc",
13428
+ asin: "Arcsin",
13429
+ acos: "Arccos",
13430
+ atan: "Arctan",
13431
+ // Inverse hyperbolic
13432
+ arcsinh: "Arsinh",
13433
+ arccosh: "Arcosh",
13434
+ arctanh: "Artanh",
13435
+ arccoth: "Arcoth",
13436
+ arcsech: "Arsech",
13437
+ arccsch: "Arcsch",
13438
+ asinh: "Arsinh",
13439
+ acosh: "Arcosh",
13440
+ atanh: "Artanh",
13441
+ // Logarithms and exponentials
13442
+ log: "Log",
13443
+ ln: "Ln",
13444
+ exp: "Exp",
13445
+ lg: "Lg",
13446
+ lb: "Lb",
13447
+ // Other common functions
13448
+ sqrt: "Sqrt",
13449
+ abs: "Abs",
13450
+ sgn: "Sgn",
13451
+ sign: "Sgn",
13452
+ floor: "Floor",
13453
+ ceil: "Ceil",
13454
+ round: "Round",
13455
+ max: "Max",
13456
+ min: "Min",
13457
+ gcd: "Gcd",
13458
+ lcm: "Lcm",
13459
+ // Roots
13460
+ cbrt: "Root",
13461
+ // Special-cased in `tryParseBareFunction` to add index 3
13462
+ // Combinatorics
13463
+ binom: "Binomial",
13464
+ nCr: "Binomial"
13465
+ };
13466
+ var LOOKAHEAD_TOKEN_TO_STRING = {
13467
+ "<space>": " ",
13468
+ "<$$>": "$$",
13469
+ "<$>": "$",
13470
+ "<{>": "{",
13471
+ "<}>": "}"
13472
+ };
13028
13473
  var _symbolToUnicode = null;
13029
13474
  function getSymbolToUnicode() {
13030
13475
  if (!_symbolToUnicode) {
@@ -13126,7 +13571,7 @@ var _Parser = class __Parser {
13126
13571
  }
13127
13572
  addSymbol(id, type) {
13128
13573
  if (typeof type === "string") type = new BoxedType(type);
13129
- if (id in this.symbolTable.ids && this.symbolTable.ids[id].is(type.type))
13574
+ if (id in this.symbolTable.ids && !this.symbolTable.ids[id].is(type.type))
13130
13575
  throw new Error(`Symbol ${id} already declared as a different type`);
13131
13576
  this.symbolTable.ids[id] = type;
13132
13577
  }
@@ -13180,6 +13625,10 @@ var _Parser = class __Parser {
13180
13625
  // Those two properties are used to detect infinite loops while parsing
13181
13626
  _lastPeek = "";
13182
13627
  _peekCounter = 0;
13628
+ // Cache for `lookAhead()`: the token stream and the dictionary are
13629
+ // immutable, so the result only depends on the current index
13630
+ _lookAheadCache = null;
13631
+ _lookAheadIndex = -1;
13183
13632
  constructor(tokens, dictionary, options) {
13184
13633
  this._tokens = tokens;
13185
13634
  this.options = options;
@@ -13336,9 +13785,6 @@ var _Parser = class __Parser {
13336
13785
  latex(start, end) {
13337
13786
  return tokensToString(this._tokens.slice(start, end));
13338
13787
  }
13339
- latexAhead(n) {
13340
- return this.latex(this.index, this.index + n);
13341
- }
13342
13788
  // latexBefore(): string {
13343
13789
  // return this.latex(0, this.index);
13344
13790
  // }
@@ -13360,77 +13806,72 @@ var _Parser = class __Parser {
13360
13806
  *
13361
13807
  */
13362
13808
  lookAhead() {
13363
- let n = Math.min(
13809
+ if (this._lookAheadIndex === this.index && this._lookAheadCache !== null)
13810
+ return this._lookAheadCache;
13811
+ const n = Math.min(
13364
13812
  this._dictionary.lookahead,
13365
13813
  this._tokens.length - this.index
13366
13814
  );
13367
- if (n <= 0) return [];
13368
13815
  const result = [];
13369
- while (n > 0) result.push([n, this.latexAhead(n--)]);
13816
+ let s = "";
13817
+ let sep = "";
13818
+ for (let i = 0; i < n; i++) {
13819
+ const token = this._tokens[this.index + i];
13820
+ const segment = LOOKAHEAD_TOKEN_TO_STRING[token] ?? token;
13821
+ if (/[a-zA-Z]/.test(segment[0])) s += sep;
13822
+ sep = /\\[a-zA-Z]+\*?$/.test(segment) ? " " : "";
13823
+ s += segment;
13824
+ result[n - 1 - i] = [i + 1, s];
13825
+ }
13826
+ this._lookAheadCache = result;
13827
+ this._lookAheadIndex = this.index;
13370
13828
  return result;
13371
13829
  }
13372
13830
  peekDefinitions(kind) {
13373
13831
  if (this.atEnd) return [];
13374
13832
  const result = [];
13833
+ const dictionary = this._dictionary;
13375
13834
  let triggerIndex;
13376
13835
  switch (kind) {
13377
13836
  case "infix":
13378
- triggerIndex = this._dictionary.infixByTrigger;
13837
+ triggerIndex = dictionary.infixByTrigger;
13379
13838
  break;
13380
13839
  case "prefix":
13381
- triggerIndex = this._dictionary.prefixByTrigger;
13840
+ triggerIndex = dictionary.prefixByTrigger;
13382
13841
  break;
13383
13842
  case "postfix":
13384
- triggerIndex = this._dictionary.postfixByTrigger;
13843
+ triggerIndex = dictionary.postfixByTrigger;
13385
13844
  break;
13386
13845
  case "function":
13387
- triggerIndex = this._dictionary.functionByTrigger;
13846
+ triggerIndex = dictionary.functionByTrigger;
13388
13847
  break;
13389
13848
  case "symbol":
13390
- triggerIndex = this._dictionary.symbolByTrigger;
13849
+ triggerIndex = dictionary.symbolByTrigger;
13391
13850
  break;
13392
13851
  case "expression":
13393
- triggerIndex = this._dictionary.expressionByTrigger;
13852
+ triggerIndex = dictionary.expressionByTrigger;
13394
13853
  break;
13395
13854
  case "operator":
13396
- triggerIndex = void 0;
13855
+ triggerIndex = dictionary.operatorByTrigger;
13397
13856
  break;
13398
13857
  }
13399
- if (triggerIndex) {
13400
- const defsNeedingIteration = [];
13401
- for (const def of this.getDefs(kind)) {
13402
- if (def.latexTrigger === "" || def.symbolTrigger) {
13403
- defsNeedingIteration.push(def);
13404
- }
13405
- }
13406
- for (const def of defsNeedingIteration) {
13407
- if (def.latexTrigger === "") result.push([def, 0]);
13408
- }
13409
- for (const [n, tokens] of this.lookAhead()) {
13410
- const defs = triggerIndex.get(tokens);
13411
- if (defs) {
13412
- for (const def of defs) result.push([def, n]);
13413
- }
13414
- }
13415
- for (const def of defsNeedingIteration) {
13416
- if (def.symbolTrigger) {
13417
- const n = parseComplexId(this, def.symbolTrigger);
13418
- if (n > 0) result.push([def, n]);
13419
- }
13858
+ const universalDefs = dictionary.universalDefs.get(kind);
13859
+ if (universalDefs) for (const def of universalDefs) result.push([def, 0]);
13860
+ for (const [n, tokens] of this.lookAhead()) {
13861
+ const defs = triggerIndex.get(tokens);
13862
+ if (defs) {
13863
+ for (const def of defs) result.push([def, n]);
13420
13864
  }
13421
- } else {
13422
- const defs = [...this.getDefs(kind)];
13423
- for (const def of defs)
13424
- if (def.latexTrigger === "") result.push([def, 0]);
13425
- for (const [n, tokens] of this.lookAhead()) {
13426
- for (const def of defs)
13427
- if (def.latexTrigger === tokens) result.push([def, n]);
13428
- }
13429
- for (const def of defs) {
13430
- if (def.symbolTrigger) {
13431
- const n = parseComplexId(this, def.symbolTrigger);
13432
- if (n > 0) result.push([def, n]);
13433
- }
13865
+ }
13866
+ const symbolTriggerDefs = dictionary.symbolTriggerDefs.get(kind);
13867
+ if (symbolTriggerDefs) {
13868
+ const start = this.index;
13869
+ const candidate = parseSymbol(this)?.trim();
13870
+ const n = this.index - start;
13871
+ this.index = start;
13872
+ if (candidate && n > 0) {
13873
+ const defs = symbolTriggerDefs.get(candidate);
13874
+ if (defs) for (const def of defs) result.push([def, n]);
13434
13875
  }
13435
13876
  }
13436
13877
  return result;
@@ -13468,17 +13909,7 @@ var _Parser = class __Parser {
13468
13909
  skipVisualSpace() {
13469
13910
  if (!this.options.skipSpace) return;
13470
13911
  this.skipSpace();
13471
- if ([
13472
- "\\!",
13473
- "\\,",
13474
- "\\:",
13475
- "\\;",
13476
- "\\enskip",
13477
- "\\enspace",
13478
- "\\space",
13479
- "\\quad",
13480
- "\\qquad"
13481
- ].includes(this.peek)) {
13912
+ if (VISUAL_SPACE_COMMANDS.has(this.peek)) {
13482
13913
  this.nextToken();
13483
13914
  this.skipVisualSpace();
13484
13915
  }
@@ -13491,23 +13922,8 @@ var _Parser = class __Parser {
13491
13922
  this.skipSpace();
13492
13923
  if (!this.match("-")) this.match("+");
13493
13924
  while (/^[\d.]$/.test(this.peek)) this.nextToken();
13494
- for (const unit of [
13495
- "pt",
13496
- "em",
13497
- "mu",
13498
- "ex",
13499
- "mm",
13500
- "cm",
13501
- "in",
13502
- "bp",
13503
- "sp",
13504
- "dd",
13505
- "cc",
13506
- "pc",
13507
- "nc",
13508
- "nd"
13509
- ]) {
13510
- if (this.matchAll([...unit])) break;
13925
+ for (const unit of TEX_UNIT_TOKENS) {
13926
+ if (this.matchAll(unit)) break;
13511
13927
  }
13512
13928
  this.skipVisualSpace();
13513
13929
  }
@@ -13760,13 +14176,7 @@ var _Parser = class __Parser {
13760
14176
  // tokens (e.g. `\sqrt\frac12` or `\sqrt\operatorname{speed}`).
13761
14177
  parseToken() {
13762
14178
  this.skipSpace();
13763
- const excluding = [
13764
- ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
13765
- "\\left",
13766
- "\\bigl",
13767
- "\\mleft"
13768
- ];
13769
- if (excluding.includes(this.peek)) return null;
14179
+ if (PARSE_TOKEN_EXCLUDED.has(this.peek)) return null;
13770
14180
  if (/^[0-9]$/.test(this.peek)) return parseInt(this.nextToken(), 10);
13771
14181
  return this.parseGenericExpression() ?? this.parseSymbol();
13772
14182
  }
@@ -13833,7 +14243,7 @@ var _Parser = class __Parser {
13833
14243
  const start = this.index;
13834
14244
  let result = "";
13835
14245
  let level = 0;
13836
- while (!this.atBoundary || level > 0) {
14246
+ while (!this.atEnd && (!this.atBoundary || level > 0)) {
13837
14247
  const token = this.nextToken();
13838
14248
  if (token === "<$>" || token === "<$$>") {
13839
14249
  this.index = start;
@@ -14220,66 +14630,6 @@ var _Parser = class __Parser {
14220
14630
  this.index = start;
14221
14631
  return null;
14222
14632
  }
14223
- const BARE_FUNCTION_MAP = {
14224
- // Trigonometric
14225
- sin: "Sin",
14226
- cos: "Cos",
14227
- tan: "Tan",
14228
- cot: "Cot",
14229
- sec: "Sec",
14230
- csc: "Csc",
14231
- // Hyperbolic
14232
- sinh: "Sinh",
14233
- cosh: "Cosh",
14234
- tanh: "Tanh",
14235
- coth: "Coth",
14236
- sech: "Sech",
14237
- csch: "Csch",
14238
- // Inverse trigonometric
14239
- arcsin: "Arcsin",
14240
- arccos: "Arccos",
14241
- arctan: "Arctan",
14242
- arccot: "Arccot",
14243
- arcsec: "Arcsec",
14244
- arccsc: "Arccsc",
14245
- asin: "Arcsin",
14246
- acos: "Arccos",
14247
- atan: "Arctan",
14248
- // Inverse hyperbolic
14249
- arcsinh: "Arsinh",
14250
- arccosh: "Arcosh",
14251
- arctanh: "Artanh",
14252
- arccoth: "Arcoth",
14253
- arcsech: "Arsech",
14254
- arccsch: "Arcsch",
14255
- asinh: "Arsinh",
14256
- acosh: "Arcosh",
14257
- atanh: "Artanh",
14258
- // Logarithms and exponentials
14259
- log: "Log",
14260
- ln: "Ln",
14261
- exp: "Exp",
14262
- lg: "Lg",
14263
- lb: "Lb",
14264
- // Other common functions
14265
- sqrt: "Sqrt",
14266
- abs: "Abs",
14267
- sgn: "Sgn",
14268
- sign: "Sgn",
14269
- floor: "Floor",
14270
- ceil: "Ceil",
14271
- round: "Round",
14272
- max: "Max",
14273
- min: "Min",
14274
- gcd: "Gcd",
14275
- lcm: "Lcm",
14276
- // Roots
14277
- cbrt: "Root",
14278
- // Special-cased below to add index 3
14279
- // Combinatorics
14280
- binom: "Binomial",
14281
- nCr: "Binomial"
14282
- };
14283
14633
  const fnName = BARE_FUNCTION_MAP[name];
14284
14634
  if (!fnName) {
14285
14635
  this.index = start;
@@ -14460,9 +14810,7 @@ var _Parser = class __Parser {
14460
14810
  }
14461
14811
  let result = lhs;
14462
14812
  if (subscripts.length > 0) {
14463
- const defs = [...this.getDefs("infix")].filter(
14464
- (x) => x.latexTrigger === "_"
14465
- );
14813
+ const defs = this._dictionary.infixByTrigger.get("_") ?? [];
14466
14814
  if (defs) {
14467
14815
  const arg = [
14468
14816
  "Subscript",
@@ -14478,9 +14826,7 @@ var _Parser = class __Parser {
14478
14826
  }
14479
14827
  }
14480
14828
  if (superscripts.length > 0) {
14481
- const defs = [...this.getDefs("infix")].filter(
14482
- (x) => x.latexTrigger === "^"
14483
- );
14829
+ const defs = this._dictionary.infixByTrigger.get("^") ?? [];
14484
14830
  if (defs) {
14485
14831
  const nonEmptySuperscripts = superscripts.filter(
14486
14832
  (x) => !isEmptySequence(x)
@@ -14694,6 +15040,15 @@ var _Parser = class __Parser {
14694
15040
  if (result === null) {
14695
15041
  result = this.options.parseUnexpectedToken?.(null, this) ?? null;
14696
15042
  if (result === null && this.peek.startsWith("\\")) {
15043
+ if (this.peek === "\\") {
15044
+ const saved = this.index;
15045
+ this.nextToken();
15046
+ this.skipVisualSpace();
15047
+ if (this.atEnd) {
15048
+ return this.decorate(null, start);
15049
+ }
15050
+ this.index = saved;
15051
+ }
14697
15052
  this.nextToken();
14698
15053
  result = this.error("unexpected-command", start);
14699
15054
  }
@@ -14840,14 +15195,6 @@ var _Parser = class __Parser {
14840
15195
  }
14841
15196
  }
14842
15197
  };
14843
- function parseComplexId(parser, id) {
14844
- const start = parser.index;
14845
- const candidate = parseSymbol(parser)?.trim();
14846
- if (candidate === null) return 0;
14847
- const result = candidate !== id ? 0 : parser.index - start;
14848
- parser.index = start;
14849
- return result;
14850
- }
14851
15198
  function isDelimiterCommand(parser) {
14852
15199
  const command = parser.peek;
14853
15200
  if (Object.values(CLOSE_DELIMITER).includes(command) || CLOSE_DELIMITER[command]) {
@@ -15344,9 +15691,9 @@ var Serializer5 = class {
15344
15691
  if ((openFence === "." || closeFence === ".") && style === "normal")
15345
15692
  style = "scaled";
15346
15693
  if (style === "scaled")
15347
- return `\\left${openFence}${s}\\right${closeFence}}`;
15694
+ return `\\left${openFence}${s}\\right${closeFence}`;
15348
15695
  if (style === "big")
15349
- return `${`\\Bigl${openFence}`}${s}${`\\Bigr${closeFence}`})`;
15696
+ return `\\Bigl${openFence}${s}\\Bigr${closeFence}`;
15350
15697
  return openFence + s + closeFence;
15351
15698
  }
15352
15699
  wrapArguments(expr) {
@@ -15423,6 +15770,55 @@ var Serializer5 = class {
15423
15770
  return this.options.numericSetStyle(expr, level);
15424
15771
  }
15425
15772
  };
15773
+ var _latexBySymbolName = null;
15774
+ function getLatexBySymbolName() {
15775
+ if (!_latexBySymbolName) {
15776
+ _latexBySymbolName = /* @__PURE__ */ new Map();
15777
+ for (const [name, latex] of SYMBOLS)
15778
+ if (!_latexBySymbolName.has(name)) _latexBySymbolName.set(name, latex);
15779
+ }
15780
+ return _latexBySymbolName;
15781
+ }
15782
+ var _latexByCodepoint = null;
15783
+ function getLatexByCodepoint() {
15784
+ if (!_latexByCodepoint) {
15785
+ _latexByCodepoint = /* @__PURE__ */ new Map();
15786
+ for (const [, latex, codepoint] of SYMBOLS)
15787
+ if (!_latexByCodepoint.has(codepoint))
15788
+ _latexByCodepoint.set(codepoint, latex);
15789
+ }
15790
+ return _latexByCodepoint;
15791
+ }
15792
+ var SPELLED_OUT_DIGITS = /* @__PURE__ */ new Map([
15793
+ ["zero", "0"],
15794
+ ["one", "1"],
15795
+ ["two", "2"],
15796
+ ["three", "3"],
15797
+ ["four", "4"],
15798
+ ["five", "5"],
15799
+ ["six", "6"],
15800
+ ["seven", "7"],
15801
+ ["eight", "8"],
15802
+ ["nine", "9"],
15803
+ ["ten", "10"]
15804
+ ]);
15805
+ var EXTRA_SYMBOLS = /* @__PURE__ */ new Map([
15806
+ ["plus", "+"],
15807
+ ["minus", "-"],
15808
+ ["pm", "\\pm"],
15809
+ ["ast", "\\ast"],
15810
+ ["dag", "\\dag"],
15811
+ ["ddag", "\\ddag"],
15812
+ ["hash", "\\#"],
15813
+ ["bottom", "\\bot"],
15814
+ ["top", "\\top"],
15815
+ ["bullet", "\\bullet"],
15816
+ ["circle", "\\circ"],
15817
+ ["diamond", "\\diamond"],
15818
+ ["times", "\\times"],
15819
+ ["square", "\\square"],
15820
+ ["star", "\\star"]
15821
+ ]);
15426
15822
  function specialName(s) {
15427
15823
  const unicodeMatch = s.match(/^____([0-9A-Fa-f]{6})(.*)/s);
15428
15824
  if (unicodeMatch) {
@@ -15431,51 +15827,18 @@ function specialName(s) {
15431
15827
  return [`\\unicode{"${paddedHex}}`, unicodeMatch[2]];
15432
15828
  }
15433
15829
  const prefix = s.match(/^([^_]+)/)?.[1] ?? "";
15434
- let i = SYMBOLS.findIndex((x) => prefix === x[0]);
15435
- if (i >= 0) return [SYMBOLS[i][1], s.substring(SYMBOLS[i][0].length)];
15436
- const DIGITS = {
15437
- zero: "0",
15438
- one: "1",
15439
- two: "2",
15440
- three: "3",
15441
- four: "4",
15442
- five: "5",
15443
- six: "6",
15444
- seven: "7",
15445
- eight: "8",
15446
- nine: "9",
15447
- ten: "10"
15448
- };
15449
- i = Object.keys(DIGITS).findIndex((x) => s.startsWith(x));
15450
- if (i >= 0) {
15451
- const key = Object.keys(DIGITS)[i];
15452
- return [DIGITS[key], s.substring(key.length)];
15453
- }
15830
+ const symbolLatex = getLatexBySymbolName().get(prefix);
15831
+ if (symbolLatex !== void 0)
15832
+ return [symbolLatex, s.substring(prefix.length)];
15833
+ const digit = SPELLED_OUT_DIGITS.get(prefix);
15834
+ if (digit !== void 0) return [digit, s.substring(prefix.length)];
15454
15835
  const code = s.codePointAt(0);
15455
- i = SYMBOLS.findIndex((x) => x[2] === code);
15456
- if (i >= 0) return [SYMBOLS[i][1], s.substring(1)];
15457
- const EXTRA_SYMBOLS = {
15458
- plus: "+",
15459
- minus: "-",
15460
- pm: "\\pm",
15461
- ast: "\\ast",
15462
- dag: "\\dag",
15463
- ddag: "\\ddag",
15464
- hash: "\\#",
15465
- bottom: "\\bot",
15466
- top: "\\top",
15467
- bullet: "\\bullet",
15468
- circle: "\\circ",
15469
- diamond: "\\diamond",
15470
- times: "\\times",
15471
- square: "\\square",
15472
- star: "\\star"
15473
- };
15474
- i = Object.keys(EXTRA_SYMBOLS).findIndex((x) => prefix === x);
15475
- if (i >= 0) {
15476
- const key = Object.keys(EXTRA_SYMBOLS)[i];
15477
- return [EXTRA_SYMBOLS[key], s.substring(key.length)];
15836
+ if (code !== void 0) {
15837
+ const latex = getLatexByCodepoint().get(code);
15838
+ if (latex !== void 0) return [latex, s.substring(1)];
15478
15839
  }
15840
+ const extra = EXTRA_SYMBOLS.get(prefix);
15841
+ if (extra !== void 0) return [extra, s.substring(prefix.length)];
15479
15842
  return [prefix, s.substring(prefix.length)];
15480
15843
  }
15481
15844
  function parseModifiers(s) {
@@ -15710,7 +16073,7 @@ function serialize(expr) {
15710
16073
  }
15711
16074
 
15712
16075
  // src/latex-syntax.ts
15713
- var version = "0.57.0";
16076
+ var version = "0.59.0";
15714
16077
  export {
15715
16078
  DEFINITIONS_ALGEBRA as ALGEBRA_DICTIONARY,
15716
16079
  DEFINITIONS_ARITHMETIC as ARITHMETIC_DICTIONARY,