@cortex-js/compute-engine 0.55.2 → 0.55.4

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 (258) hide show
  1. package/dist/compile.esm.js +908 -176
  2. package/dist/compile.min.esm.js +441 -71
  3. package/dist/compile.min.umd.cjs +442 -72
  4. package/dist/compile.umd.cjs +908 -176
  5. package/dist/compute-engine.esm.js +954 -185
  6. package/dist/compute-engine.min.esm.js +444 -74
  7. package/dist/compute-engine.min.umd.cjs +444 -74
  8. package/dist/compute-engine.umd.cjs +954 -185
  9. package/dist/core.esm.js +951 -174
  10. package/dist/core.min.esm.js +442 -72
  11. package/dist/core.min.umd.cjs +442 -72
  12. package/dist/core.umd.cjs +951 -174
  13. package/dist/interval.esm.js +2 -2
  14. package/dist/interval.min.esm.js +2 -2
  15. package/dist/interval.min.umd.cjs +2 -2
  16. package/dist/interval.umd.cjs +2 -2
  17. package/dist/latex-syntax.esm.js +43 -13
  18. package/dist/latex-syntax.min.esm.js +5 -5
  19. package/dist/latex-syntax.min.umd.cjs +5 -5
  20. package/dist/latex-syntax.umd.cjs +43 -13
  21. package/dist/math-json.esm.js +2 -2
  22. package/dist/math-json.min.esm.js +2 -2
  23. package/dist/math-json.min.umd.cjs +2 -2
  24. package/dist/math-json.umd.cjs +2 -2
  25. package/dist/numerics.esm.js +2 -2
  26. package/dist/numerics.min.esm.js +2 -2
  27. package/dist/numerics.min.umd.cjs +2 -2
  28. package/dist/numerics.umd.cjs +2 -2
  29. package/dist/types/big-decimal/big-decimal.d.ts +1 -1
  30. package/dist/types/big-decimal/index.d.ts +1 -1
  31. package/dist/types/big-decimal/transcendentals.d.ts +1 -1
  32. package/dist/types/big-decimal/utils.d.ts +1 -1
  33. package/dist/types/common/ansi-codes.d.ts +1 -1
  34. package/dist/types/common/configuration-change.d.ts +1 -1
  35. package/dist/types/common/fuzzy-string-match.d.ts +1 -1
  36. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  37. package/dist/types/common/interruptible.d.ts +1 -1
  38. package/dist/types/common/one-of.d.ts +1 -1
  39. package/dist/types/common/signals.d.ts +1 -1
  40. package/dist/types/common/type/ast-nodes.d.ts +1 -1
  41. package/dist/types/common/type/boxed-type.d.ts +1 -1
  42. package/dist/types/common/type/lexer.d.ts +1 -1
  43. package/dist/types/common/type/parse.d.ts +1 -1
  44. package/dist/types/common/type/parser.d.ts +1 -1
  45. package/dist/types/common/type/primitive.d.ts +1 -1
  46. package/dist/types/common/type/reduce.d.ts +1 -1
  47. package/dist/types/common/type/serialize.d.ts +1 -1
  48. package/dist/types/common/type/subtype.d.ts +1 -1
  49. package/dist/types/common/type/type-builder.d.ts +1 -1
  50. package/dist/types/common/type/types.d.ts +1 -1
  51. package/dist/types/common/type/utils.d.ts +1 -1
  52. package/dist/types/common/utils.d.ts +1 -1
  53. package/dist/types/compile.d.ts +1 -1
  54. package/dist/types/compute-engine/assume.d.ts +1 -1
  55. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
  56. package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
  57. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
  58. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
  59. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
  60. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  61. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  62. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  63. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  64. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  65. package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
  66. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  67. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  68. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  69. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
  70. package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
  71. package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
  72. package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
  73. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  74. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  75. package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
  76. package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
  77. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  78. package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
  79. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  80. package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
  81. package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
  82. package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
  83. package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
  84. package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
  85. package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
  86. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
  87. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  88. package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
  89. package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
  90. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  91. package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
  92. package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
  93. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  94. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  95. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  96. package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
  97. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
  98. package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
  99. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
  100. package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
  101. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  102. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  103. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  104. package/dist/types/compute-engine/compilation/base-compiler.d.ts +8 -7
  105. package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
  106. package/dist/types/compute-engine/compilation/constant-folding.d.ts +50 -0
  107. package/dist/types/compute-engine/compilation/fractal-orbit.d.ts +13 -0
  108. package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
  109. package/dist/types/compute-engine/compilation/gpu-target.d.ts +47 -1
  110. package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
  111. package/dist/types/compute-engine/compilation/javascript-target.d.ts +23 -1
  112. package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
  113. package/dist/types/compute-engine/compilation/types.d.ts +48 -1
  114. package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
  115. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  116. package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
  117. package/dist/types/compute-engine/engine-cache.d.ts +1 -1
  118. package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
  119. package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
  120. package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
  121. package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
  122. package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
  123. package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
  124. package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
  125. package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
  126. package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
  127. package/dist/types/compute-engine/engine-scope.d.ts +1 -1
  128. package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
  129. package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
  130. package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
  131. package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
  132. package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
  133. package/dist/types/compute-engine/free-functions.d.ts +1 -1
  134. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  135. package/dist/types/compute-engine/global-types.d.ts +1 -1
  136. package/dist/types/compute-engine/index.d.ts +1 -1
  137. package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
  138. package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
  139. package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
  140. package/dist/types/compute-engine/interval/index.d.ts +1 -1
  141. package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
  142. package/dist/types/compute-engine/interval/types.d.ts +1 -1
  143. package/dist/types/compute-engine/interval/util.d.ts +1 -1
  144. package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
  145. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  146. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  147. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  148. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  149. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  150. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  151. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  152. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  153. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  154. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  155. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  156. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  157. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  158. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
  159. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  160. package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
  161. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  162. package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
  163. package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
  164. package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
  165. package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
  166. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  167. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  168. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  169. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  170. package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
  171. package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
  172. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  173. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  174. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  175. package/dist/types/compute-engine/library/colors.d.ts +1 -1
  176. package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
  177. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  178. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  179. package/dist/types/compute-engine/library/core.d.ts +1 -1
  180. package/dist/types/compute-engine/library/fractals.d.ts +1 -1
  181. package/dist/types/compute-engine/library/library.d.ts +1 -1
  182. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  183. package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
  184. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  185. package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
  186. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  187. package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
  188. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  189. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  190. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  191. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  192. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  193. package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
  194. package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
  195. package/dist/types/compute-engine/library/units.d.ts +1 -1
  196. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  197. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
  198. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
  199. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
  200. package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
  201. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  202. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  203. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  204. package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
  205. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  206. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  207. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  208. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  209. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  210. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  211. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  212. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  213. package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
  214. package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
  215. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  216. package/dist/types/compute-engine/numerics/types.d.ts +1 -1
  217. package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
  218. package/dist/types/compute-engine/oeis.d.ts +1 -1
  219. package/dist/types/compute-engine/sequence.d.ts +1 -1
  220. package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
  221. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  222. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  223. package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
  224. package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
  225. package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
  226. package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
  227. package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
  228. package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
  229. package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
  230. package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
  231. package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
  232. package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
  233. package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
  234. package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
  235. package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
  236. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  237. package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
  238. package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
  239. package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
  240. package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
  241. package/dist/types/compute-engine/types-definitions.d.ts +1 -1
  242. package/dist/types/compute-engine/types-engine.d.ts +1 -1
  243. package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
  244. package/dist/types/compute-engine/types-expression.d.ts +1 -1
  245. package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
  246. package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
  247. package/dist/types/compute-engine/types-serialization.d.ts +1 -1
  248. package/dist/types/compute-engine/types.d.ts +1 -1
  249. package/dist/types/compute-engine.d.ts +1 -1
  250. package/dist/types/core.d.ts +1 -1
  251. package/dist/types/interval.d.ts +1 -1
  252. package/dist/types/latex-syntax.d.ts +2 -2
  253. package/dist/types/math-json/symbols.d.ts +1 -1
  254. package/dist/types/math-json/types.d.ts +1 -1
  255. package/dist/types/math-json/utils.d.ts +1 -1
  256. package/dist/types/math-json.d.ts +2 -2
  257. package/dist/types/numerics.d.ts +1 -1
  258. package/package.json +3 -3
package/dist/core.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.55.2 */
1
+ /** Compute Engine 0.55.4 */
2
2
 
3
3
  // node_modules/complex-esm/dist/src/complex.js
4
4
  var cosh = Math.cosh || function(x) {
@@ -17152,6 +17152,10 @@ function parseSymbolBody(parser) {
17152
17152
  parser.nextToken();
17153
17153
  continue;
17154
17154
  }
17155
+ if (EMOJIS.test(id + token)) {
17156
+ id += parser.nextToken();
17157
+ continue;
17158
+ }
17155
17159
  const next = parseSymbolToken(parser, { toplevel: false });
17156
17160
  if (next === null) return null;
17157
17161
  id += next;
@@ -17191,6 +17195,7 @@ function parseSymbolBody(parser) {
17191
17195
  function matchPrefixedSymbol(parser) {
17192
17196
  const prefix = SYMBOL_PREFIX[parser.peek] ?? null;
17193
17197
  if (prefix === null) return null;
17198
+ const start = parser.index;
17194
17199
  parser.nextToken();
17195
17200
  if (parser.match("<{>")) {
17196
17201
  let body = "";
@@ -17211,17 +17216,48 @@ function matchPrefixedSymbol(parser) {
17211
17216
  parser.nextToken();
17212
17217
  }
17213
17218
  body += parseSymbolBody(parser);
17214
- if (body === null || !parser.match("<}>")) return null;
17219
+ if (body === null || !parser.match("<}>")) {
17220
+ parser.index = start;
17221
+ return null;
17222
+ }
17215
17223
  if (prefix === "_upright" && body.length > 1) return body;
17216
17224
  return body + prefix;
17217
17225
  }
17226
+ parser.index = start;
17218
17227
  return null;
17219
17228
  }
17220
17229
  function parseInvalidSymbol(parser) {
17221
17230
  const start = parser.index;
17222
17231
  const id = matchPrefixedSymbol(parser);
17223
- if (id === null || isValidSymbol(id)) return null;
17224
- return parser.error(["invalid-symbol", { str: validateSymbol(id) }], start);
17232
+ if (id !== null) {
17233
+ if (isValidSymbol(id)) return null;
17234
+ return parser.error(["invalid-symbol", { str: validateSymbol(id) }], start);
17235
+ }
17236
+ parser.index = start;
17237
+ const prefix = SYMBOL_PREFIX[parser.peek] ?? null;
17238
+ if (prefix === null) return null;
17239
+ parser.nextToken();
17240
+ if (!parser.match("<{>")) {
17241
+ parser.index = start;
17242
+ return null;
17243
+ }
17244
+ const bodyStart = parser.index;
17245
+ let level = 0;
17246
+ while (!parser.atEnd && !(level === 0 && parser.peek === "<}>")) {
17247
+ if (parser.peek === "<{>") level += 1;
17248
+ if (parser.peek === "<}>") level -= 1;
17249
+ parser.nextToken();
17250
+ }
17251
+ const bodyText = parser.latex(bodyStart, parser.index);
17252
+ if (isValidSymbol(bodyText)) {
17253
+ parser.index = start;
17254
+ return null;
17255
+ }
17256
+ parser.match("<}>");
17257
+ return parser.error(
17258
+ ["invalid-symbol", { str: validateSymbol(bodyText) }],
17259
+ start
17260
+ );
17225
17261
  }
17226
17262
  function parseSymbol(parser) {
17227
17263
  if (/^[a-zA-Z]$/.test(parser.peek) || /^\p{XIDS}$/u.test(parser.peek)) {
@@ -18176,18 +18212,12 @@ var _Parser = class __Parser {
18176
18212
  this.index = start;
18177
18213
  return false;
18178
18214
  }
18179
- const matchedToken = this.nextToken();
18180
- const useLatexCommand = matchedToken.startsWith("\\");
18215
+ this.nextToken();
18181
18216
  if (hasBracedDelimiter && !this.match("<}>")) {
18182
18217
  this.index = start;
18183
18218
  return false;
18184
18219
  }
18185
- const closeTokens = DELIMITER_SHORTHAND2[close[0]] ?? [
18186
- close[0]
18187
- ];
18188
- const closeToken = closeTokens.find(
18189
- (t) => useLatexCommand ? t.startsWith("\\") : !t.startsWith("\\")
18190
- ) ?? closeTokens[0];
18220
+ const closeToken = close[0];
18191
18221
  const closeBoundary3 = closePrefix ? hasBracedDelimiter ? [closePrefix, "<{>", closeToken, "<}>"] : [closePrefix, closeToken] : [closeToken];
18192
18222
  this.addBoundary(closeBoundary3);
18193
18223
  return true;
@@ -30684,8 +30714,7 @@ var ARITHMETIC_LIBRARY = [
30684
30714
  broadcastable: true,
30685
30715
  idempotent: true,
30686
30716
  complexity: 1200,
30687
- signature: "(number) -> number",
30688
- type: ([x]) => x.type,
30717
+ signature: "(number) -> real",
30689
30718
  sgn: ([x]) => {
30690
30719
  if (x.isSame(0)) return "zero";
30691
30720
  if (isNumber(x)) return "positive";
@@ -39583,30 +39612,6 @@ var COOLWARM = [
39583
39612
  "#ae2036",
39584
39613
  "#b40426"
39585
39614
  ];
39586
- var OCEAN_BALANCE = [
39587
- "#00441b",
39588
- "#006d5b",
39589
- "#1a8c7d",
39590
- "#2fa394",
39591
- "#4fb3a3",
39592
- "#6fc1b3",
39593
- "#8dcfc3",
39594
- "#a6dbd1",
39595
- "#bfe6de",
39596
- "#d7f0ea",
39597
- "#f7f7f7",
39598
- "#eeeeee",
39599
- "#ddd8e6",
39600
- "#c7bcda",
39601
- "#b3a0d0",
39602
- "#9f86c7",
39603
- "#8d6dbd",
39604
- "#7b56b1",
39605
- "#6a42a3",
39606
- "#5a3093",
39607
- "#4a1f82",
39608
- "#3b0f70"
39609
- ];
39610
39615
  var reversePalette = (palette) => palette.slice().reverse();
39611
39616
  var DIVERGING_PALETTES = {
39612
39617
  roma: ROMA,
@@ -39618,9 +39623,7 @@ var DIVERGING_PALETTES = {
39618
39623
  rdbu: RDBU,
39619
39624
  "rdbu-reversed": reversePalette(RDBU),
39620
39625
  coolwarm: COOLWARM,
39621
- "coolwarm-reversed": reversePalette(COOLWARM),
39622
- "ocean-balance": OCEAN_BALANCE,
39623
- "ocean-balance-reversed": reversePalette(OCEAN_BALANCE)
39626
+ "coolwarm-reversed": reversePalette(COOLWARM)
39624
39627
  };
39625
39628
  var TURBO = [
39626
39629
  "#30123b",
@@ -41704,6 +41707,40 @@ var GREY = [
41704
41707
  "#eeeeee",
41705
41708
  "#ffffff"
41706
41709
  ];
41710
+ var CMOCEAN_PHASE = [
41711
+ "#a8780d",
41712
+ "#b3701b",
41713
+ "#be6828",
41714
+ "#c75f35",
41715
+ "#cf5643",
41716
+ "#d54b53",
41717
+ "#db4066",
41718
+ "#de357b",
41719
+ "#df2a93",
41720
+ "#dc25ad",
41721
+ "#d529c4",
41722
+ "#cc34d7",
41723
+ "#c041e5",
41724
+ "#b24fef",
41725
+ "#a25cf3",
41726
+ "#9168f4",
41727
+ "#7d73f0",
41728
+ "#687ce8",
41729
+ "#5285dc",
41730
+ "#3d8bcd",
41731
+ "#2c90bc",
41732
+ "#2093ac",
41733
+ "#19959c",
41734
+ "#12978c",
41735
+ "#0c987c",
41736
+ "#119a69",
41737
+ "#249a52",
41738
+ "#409839",
41739
+ "#5e9420",
41740
+ "#778d12",
41741
+ "#8b860d",
41742
+ "#9b7f0d"
41743
+ ];
41707
41744
  var reversePalette2 = (palette) => palette.slice().reverse();
41708
41745
  var SEQUENTIAL_PALETTES = {
41709
41746
  turbo: TURBO,
@@ -41727,7 +41764,9 @@ var SEQUENTIAL_PALETTES = {
41727
41764
  "rocket-reversed": reversePalette2(ROCKET),
41728
41765
  mako: MAKO,
41729
41766
  // blue to teal
41730
- "mako-reversed": reversePalette2(MAKO)
41767
+ "mako-reversed": reversePalette2(MAKO),
41768
+ "cmocean-phase": CMOCEAN_PHASE,
41769
+ "cmocean-phase-reversed": reversePalette2(CMOCEAN_PHASE)
41731
41770
  };
41732
41771
 
41733
41772
  // src/compute-engine/library/colors.ts
@@ -54236,8 +54275,11 @@ var BaseCompiler = class _BaseCompiler {
54236
54275
  for (const local of locals) {
54237
54276
  for (const arg of args) {
54238
54277
  if (isFunction2(arg, "Assign") && isSymbol2(arg.ops[0], local)) {
54239
- if (_BaseCompiler.isComplexValued(arg.ops[1])) {
54278
+ const rhs = arg.ops[1];
54279
+ if (_BaseCompiler.isComplexValued(rhs)) {
54240
54280
  typeHints[local] = isWGSL ? "vec2f" : "vec2";
54281
+ } else if (_BaseCompiler.isIntegerValued(rhs)) {
54282
+ typeHints[local] = isWGSL ? "i32" : "int";
54241
54283
  }
54242
54284
  break;
54243
54285
  }
@@ -54442,12 +54484,9 @@ var BaseCompiler = class _BaseCompiler {
54442
54484
  /**
54443
54485
  * Determine at compile time whether an expression produces a complex value.
54444
54486
  *
54445
- * Rules:
54446
- * - Numbers: complex if im !== 0
54447
- * - Symbols: ImaginaryUnit is complex; others use expr.isReal
54448
- * (undefined is treated as real -- assume-real policy)
54449
- * - Functions: Abs, Arg, Re, Im always return real.
54450
- * All others: complex if any operand is complex.
54487
+ * Uses the expression's declared type (from operator signatures) when
54488
+ * available. Falls back to operand inspection for functions whose
54489
+ * return type is unknown.
54451
54490
  */
54452
54491
  static isComplexValued(expr2) {
54453
54492
  if (isNumber(expr2)) return expr2.im !== 0;
@@ -54458,13 +54497,24 @@ var BaseCompiler = class _BaseCompiler {
54458
54497
  return t.matches("complex") && !t.matches("real");
54459
54498
  }
54460
54499
  if (isFunction2(expr2)) {
54461
- const op = expr2.operator;
54462
- if (op === "Abs" || op === "Arg" || op === "Re" || op === "Im")
54463
- return false;
54500
+ const t = expr2.type;
54501
+ if (t.matches("complex") && !t.matches("real")) return true;
54502
+ if (t.matches("real")) return false;
54464
54503
  return expr2.ops.some((arg) => _BaseCompiler.isComplexValued(arg));
54465
54504
  }
54466
54505
  return false;
54467
54506
  }
54507
+ /** True if the expression is provably integer-typed. */
54508
+ static isIntegerValued(expr2) {
54509
+ if (isNumber(expr2)) return expr2.im === 0 && Number.isInteger(expr2.re);
54510
+ const t = expr2.type;
54511
+ return t ? t.matches("integer") : false;
54512
+ }
54513
+ /** True if the expression is provably non-negative (sign ≥ 0). */
54514
+ static isNonNegative(expr2) {
54515
+ if (isNumber(expr2)) return expr2.im === 0 && expr2.re >= 0;
54516
+ return expr2.isNonNegative === true;
54517
+ }
54468
54518
  /**
54469
54519
  * Generate a temporary variable name
54470
54520
  */
@@ -54718,14 +54768,27 @@ function compile(expr2, options) {
54718
54768
  } catch (e) {
54719
54769
  if (options?.fallback ?? true) {
54720
54770
  console.warn(
54721
- `Compilation fallback for "${expr2.operator}": ${e.message}`
54771
+ `Compilation fallback for "${expr2.operator}" (target: ${options?.to ?? "javascript"}): ${e.message}`
54722
54772
  );
54773
+ const ce = expr2.engine;
54774
+ const fallbackRun = ((vars) => {
54775
+ ce.pushScope();
54776
+ try {
54777
+ if (vars && typeof vars === "object") {
54778
+ for (const [k, v] of Object.entries(vars))
54779
+ ce.assign(k, v);
54780
+ }
54781
+ return expr2.evaluate().re;
54782
+ } finally {
54783
+ ce.popScope();
54784
+ }
54785
+ });
54723
54786
  return {
54724
54787
  target: options?.to ?? "javascript",
54725
54788
  success: false,
54726
54789
  code: "",
54727
54790
  calling: "expression",
54728
- run: applicableN1(expr2)
54791
+ run: fallbackRun
54729
54792
  };
54730
54793
  }
54731
54794
  throw e;
@@ -59875,6 +59938,86 @@ function resetCommonSymbols(commonSymbols) {
59875
59938
  for (const symbol2 of Object.values(commonSymbols)) symbol2?.reset();
59876
59939
  }
59877
59940
 
59941
+ // src/compute-engine/compilation/constant-folding.ts
59942
+ function formatFloat(n) {
59943
+ const str = n.toString();
59944
+ if (!str.includes(".") && !str.includes("e") && !str.includes("E")) {
59945
+ return `${str}.0`;
59946
+ }
59947
+ return str;
59948
+ }
59949
+ function tryGetConstant(expr2) {
59950
+ if (!isNumber(expr2)) return void 0;
59951
+ if (expr2.im !== 0) return void 0;
59952
+ const re = expr2.re;
59953
+ if (!isFinite(re)) return void 0;
59954
+ return re;
59955
+ }
59956
+ var NUMERIC_LITERAL_RE = /^-?\d+(\.\d+)?$/;
59957
+ function foldTerms(terms, identity, op) {
59958
+ const identityValue = op === "+" ? 0 : 1;
59959
+ let numericAcc = null;
59960
+ const symbolic = [];
59961
+ for (const term of terms) {
59962
+ if (NUMERIC_LITERAL_RE.test(term)) {
59963
+ const val = parseFloat(term);
59964
+ if (op === "*" && val === 0) return "0.0";
59965
+ if (numericAcc === null) {
59966
+ numericAcc = val;
59967
+ } else {
59968
+ numericAcc = op === "+" ? numericAcc + val : numericAcc * val;
59969
+ }
59970
+ } else {
59971
+ symbolic.push(term);
59972
+ }
59973
+ }
59974
+ if (numericAcc !== null && numericAcc !== identityValue) {
59975
+ symbolic.unshift(formatFloat(numericAcc));
59976
+ }
59977
+ if (symbolic.length === 0) {
59978
+ if (numericAcc !== null) return formatFloat(numericAcc);
59979
+ return identity;
59980
+ }
59981
+ if (symbolic.length === 1) return symbolic[0];
59982
+ return symbolic.join(op === "+" ? " + " : " * ");
59983
+ }
59984
+ function tryGetComplexParts(expr2, compile3) {
59985
+ if (isSymbol2(expr2, "ImaginaryUnit")) {
59986
+ return { re: null, im: "1.0" };
59987
+ }
59988
+ if (isNumber(expr2) && expr2.im !== 0) {
59989
+ const re = expr2.re;
59990
+ const im = expr2.im;
59991
+ return {
59992
+ re: re !== 0 ? formatFloat(re) : null,
59993
+ im: formatFloat(im)
59994
+ };
59995
+ }
59996
+ if (isFunction2(expr2, "Multiply")) {
59997
+ const ops = expr2.ops;
59998
+ const iIndex = ops.findIndex(
59999
+ (op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
60000
+ );
60001
+ if (iIndex >= 0) {
60002
+ const iFactor = ops[iIndex];
60003
+ const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
60004
+ const remaining = ops.filter((_, idx) => idx !== iIndex);
60005
+ if (remaining.length === 0) {
60006
+ return { re: null, im: formatFloat(iScale) };
60007
+ }
60008
+ const compiledFactors = remaining.map((r) => compile3(r));
60009
+ if (iScale !== 1)
60010
+ compiledFactors.unshift(formatFloat(iScale));
60011
+ const imCode = foldTerms(compiledFactors, "1.0", "*");
60012
+ return { re: null, im: imCode };
60013
+ }
60014
+ }
60015
+ if (BaseCompiler.isComplexValued(expr2)) {
60016
+ return null;
60017
+ }
60018
+ return { re: compile3(expr2), im: null };
60019
+ }
60020
+
59878
60021
  // src/compute-engine/compilation/javascript-target.ts
59879
60022
  var JAVASCRIPT_OPERATORS = {
59880
60023
  Add: ["+", 11],
@@ -59898,12 +60041,21 @@ var JAVASCRIPT_FUNCTIONS = {
59898
60041
  Abs: (args, compile3) => {
59899
60042
  if (BaseCompiler.isComplexValued(args[0]))
59900
60043
  return `_SYS.cabs(${compile3(args[0])})`;
60044
+ if (BaseCompiler.isNonNegative(args[0])) return compile3(args[0]);
59901
60045
  return `Math.abs(${compile3(args[0])})`;
59902
60046
  },
59903
60047
  Add: (args, compile3) => {
59904
60048
  if (args.length === 1) return compile3(args[0]);
59905
60049
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
59906
- if (!anyComplex) return `(${args.map((x) => compile3(x)).join(" + ")})`;
60050
+ if (!anyComplex) {
60051
+ const constants = args.map(tryGetConstant);
60052
+ if (constants.every((c) => c !== void 0))
60053
+ return String(constants.reduce((a, b) => a + b, 0));
60054
+ const nonZero = args.filter((a) => tryGetConstant(a) !== 0);
60055
+ if (nonZero.length === 0) return "0";
60056
+ if (nonZero.length === 1) return compile3(nonZero[0]);
60057
+ return `(${nonZero.map((x) => compile3(x)).join(" + ")})`;
60058
+ }
59907
60059
  const parts = args.map((a) => {
59908
60060
  const code = compile3(a);
59909
60061
  return { code, isComplex: BaseCompiler.isComplexValued(a) };
@@ -59960,7 +60112,10 @@ var JAVASCRIPT_FUNCTIONS = {
59960
60112
  return `Math.atan(${compile3(args[0])})`;
59961
60113
  },
59962
60114
  Artanh: "Math.atanh",
59963
- Ceil: "Math.ceil",
60115
+ Ceil: (args, compile3) => {
60116
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60117
+ return `Math.ceil(${compile3(args[0])})`;
60118
+ },
59964
60119
  Chop: "_SYS.chop",
59965
60120
  Cos: (args, compile3) => {
59966
60121
  if (BaseCompiler.isComplexValued(args[0]))
@@ -60003,7 +60158,10 @@ var JAVASCRIPT_FUNCTIONS = {
60003
60158
  return `_SYS.cexp(${compile3(args[0])})`;
60004
60159
  return `Math.exp(${compile3(args[0])})`;
60005
60160
  },
60006
- Floor: "Math.floor",
60161
+ Floor: (args, compile3) => {
60162
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60163
+ return `Math.floor(${compile3(args[0])})`;
60164
+ },
60007
60165
  Fract: ([x], compile3) => {
60008
60166
  if (x === null) throw new Error("Fract: no argument");
60009
60167
  return BaseCompiler.inlineExpression("${x} - Math.floor(${x})", compile3(x));
@@ -60099,12 +60257,20 @@ var JAVASCRIPT_FUNCTIONS = {
60099
60257
  if (BaseCompiler.isComplexValued(base) || BaseCompiler.isComplexValued(exp3)) {
60100
60258
  return `_SYS.cpow(${compile3(base)}, ${compile3(exp3)})`;
60101
60259
  }
60102
- const expVal = exp3.re;
60103
- if (expVal === 0.5) return `Math.sqrt(${compile3(base)})`;
60104
- if (expVal === 1 / 3) return `Math.cbrt(${compile3(base)})`;
60105
- if (expVal === 1) return compile3(base);
60106
- if (expVal === -1) return `(1 / (${compile3(base)}))`;
60107
- if (expVal === -0.5) return `(1 / Math.sqrt(${compile3(base)}))`;
60260
+ const bConst = tryGetConstant(base);
60261
+ const eConst = tryGetConstant(exp3);
60262
+ if (bConst !== void 0 && eConst !== void 0)
60263
+ return String(Math.pow(bConst, eConst));
60264
+ if (eConst === 0) return "1";
60265
+ if (eConst === 1) return compile3(base);
60266
+ if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
60267
+ const code = compile3(base);
60268
+ return `(${code} * ${code})`;
60269
+ }
60270
+ if (eConst === -1) return `(1 / (${compile3(base)}))`;
60271
+ if (eConst === 0.5) return `Math.sqrt(${compile3(base)})`;
60272
+ if (eConst === 1 / 3) return `Math.cbrt(${compile3(base)})`;
60273
+ if (eConst === -0.5) return `(1 / Math.sqrt(${compile3(base)}))`;
60108
60274
  return `Math.pow(${compile3(base)}, ${compile3(exp3)})`;
60109
60275
  },
60110
60276
  Range: (args, compile3) => {
@@ -60141,16 +60307,29 @@ var JAVASCRIPT_FUNCTIONS = {
60141
60307
  Root: ([arg, exp3], compile3) => {
60142
60308
  if (arg === null) throw new Error("Root: no argument");
60143
60309
  if (exp3 === null) return `Math.sqrt(${compile3(arg)})`;
60144
- if (exp3?.re === 2) return `Math.sqrt(${compile3(arg)})`;
60145
- if (exp3?.re === 3) return `Math.cbrt(${compile3(arg)})`;
60146
- if (!isNaN(exp3?.re)) return `Math.pow(${compile3(arg)}, ${1 / exp3.re})`;
60310
+ const aConst = tryGetConstant(arg);
60311
+ const nConst = tryGetConstant(exp3);
60312
+ if (aConst !== void 0 && nConst !== void 0 && nConst !== 0)
60313
+ return String(Math.pow(aConst, 1 / nConst));
60314
+ if (nConst === 2) return `Math.sqrt(${compile3(arg)})`;
60315
+ if (nConst === 3) return `Math.cbrt(${compile3(arg)})`;
60316
+ if (nConst !== void 0) return `Math.pow(${compile3(arg)}, ${1 / nConst})`;
60147
60317
  return `Math.pow(${compile3(arg)}, 1 / (${compile3(exp3)}))`;
60148
60318
  },
60149
60319
  Random: "Math.random",
60150
- Round: "Math.round",
60320
+ Round: (args, compile3) => {
60321
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60322
+ return `Math.round(${compile3(args[0])})`;
60323
+ },
60151
60324
  Square: (args, compile3) => {
60152
60325
  const arg = args[0];
60153
60326
  if (arg === null) throw new Error("Square: no argument");
60327
+ const c = tryGetConstant(arg);
60328
+ if (c !== void 0) return String(c * c);
60329
+ if (isSymbol2(arg)) {
60330
+ const code = compile3(arg);
60331
+ return `(${code} * ${code})`;
60332
+ }
60154
60333
  return `Math.pow(${compile3(arg)}, 2)`;
60155
60334
  },
60156
60335
  Sec: (args, compile3) => {
@@ -60183,6 +60362,8 @@ var JAVASCRIPT_FUNCTIONS = {
60183
60362
  Sqrt: (args, compile3) => {
60184
60363
  if (BaseCompiler.isComplexValued(args[0]))
60185
60364
  return `_SYS.csqrt(${compile3(args[0])})`;
60365
+ const c = tryGetConstant(args[0]);
60366
+ if (c !== void 0) return String(Math.sqrt(c));
60186
60367
  return `Math.sqrt(${compile3(args[0])})`;
60187
60368
  },
60188
60369
  Tan: (args, compile3) => {
@@ -60199,9 +60380,14 @@ var JAVASCRIPT_FUNCTIONS = {
60199
60380
  if (a === null || b === null) throw new Error("Mod: missing argument");
60200
60381
  const ca = compile3(a);
60201
60382
  const cb = compile3(b);
60383
+ if (BaseCompiler.isIntegerValued(a) && BaseCompiler.isIntegerValued(b) && BaseCompiler.isNonNegative(a))
60384
+ return `(${ca} % ${cb})`;
60202
60385
  return `((${ca} % ${cb}) + ${cb}) % ${cb}`;
60203
60386
  },
60204
- Truncate: "Math.trunc",
60387
+ Truncate: (args, compile3) => {
60388
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60389
+ return `Math.trunc(${compile3(args[0])})`;
60390
+ },
60205
60391
  Remainder: ([a, b], compile3) => {
60206
60392
  if (a === null || b === null)
60207
60393
  throw new Error("Remainder: missing argument");
@@ -60209,25 +60395,20 @@ var JAVASCRIPT_FUNCTIONS = {
60209
60395
  a
60210
60396
  )} / ${compile3(b)}))`;
60211
60397
  },
60212
- // Arithmetic operators handled as functions for completeness
60213
- Subtract: ([a, b], compile3) => {
60214
- if (a === null || b === null) throw new Error("Subtract: missing argument");
60215
- const ac = BaseCompiler.isComplexValued(a);
60216
- const bc = BaseCompiler.isComplexValued(b);
60217
- if (!ac && !bc) return `(${compile3(a)} - ${compile3(b)})`;
60218
- const ca = compile3(a);
60219
- const cb = compile3(b);
60220
- const reA = ac ? `(${ca}).re` : ca;
60221
- const imA = ac ? `(${ca}).im` : "0";
60222
- const reB = bc ? `(${cb}).re` : cb;
60223
- const imB = bc ? `(${cb}).im` : "0";
60224
- return `({ re: ${reA} - ${reB}, im: ${imA} - ${imB} })`;
60225
- },
60398
+ // No Subtract function handler Subtract canonicalizes to Add+Negate.
60399
+ // The operator entry in JAVASCRIPT_OPERATORS handles any edge cases.
60226
60400
  Divide: ([a, b], compile3) => {
60227
60401
  if (a === null || b === null) throw new Error("Divide: missing argument");
60228
60402
  const ac = BaseCompiler.isComplexValued(a);
60229
60403
  const bc = BaseCompiler.isComplexValued(b);
60230
- if (!ac && !bc) return `(${compile3(a)} / ${compile3(b)})`;
60404
+ if (!ac && !bc) {
60405
+ const ca = tryGetConstant(a);
60406
+ const cb = tryGetConstant(b);
60407
+ if (ca !== void 0 && cb !== void 0 && cb !== 0)
60408
+ return String(ca / cb);
60409
+ if (cb === 1) return compile3(a);
60410
+ return `(${compile3(a)} / ${compile3(b)})`;
60411
+ }
60231
60412
  if (ac && bc) {
60232
60413
  return `(() => { const _a = ${compile3(a)}, _b = ${compile3(
60233
60414
  b
@@ -60244,13 +60425,26 @@ var JAVASCRIPT_FUNCTIONS = {
60244
60425
  },
60245
60426
  Negate: ([x], compile3) => {
60246
60427
  if (x === null) throw new Error("Negate: no argument");
60247
- if (!BaseCompiler.isComplexValued(x)) return `(-${compile3(x)})`;
60428
+ if (!BaseCompiler.isComplexValued(x)) {
60429
+ const c = tryGetConstant(x);
60430
+ if (c !== void 0) return String(-c);
60431
+ return `(-${compile3(x)})`;
60432
+ }
60248
60433
  return `_SYS.cneg(${compile3(x)})`;
60249
60434
  },
60250
60435
  Multiply: (args, compile3) => {
60251
60436
  if (args.length === 1) return compile3(args[0]);
60252
60437
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
60253
- if (!anyComplex) return `(${args.map((x) => compile3(x)).join(" * ")})`;
60438
+ if (!anyComplex) {
60439
+ if (args.some((a) => tryGetConstant(a) === 0)) return "0";
60440
+ const constants = args.map(tryGetConstant);
60441
+ if (constants.every((c) => c !== void 0))
60442
+ return String(constants.reduce((a, b) => a * b, 1));
60443
+ const nonOne = args.filter((a) => tryGetConstant(a) !== 1);
60444
+ if (nonOne.length === 0) return "1";
60445
+ if (nonOne.length === 1) return compile3(nonOne[0]);
60446
+ return `(${nonOne.map((x) => compile3(x)).join(" * ")})`;
60447
+ }
60254
60448
  if (args.length === 2) {
60255
60449
  const ac = BaseCompiler.isComplexValued(args[0]);
60256
60450
  const bc = BaseCompiler.isComplexValued(args[1]);
@@ -60335,20 +60529,30 @@ var JAVASCRIPT_FUNCTIONS = {
60335
60529
  AiryAi: "_SYS.airyAi",
60336
60530
  AiryBi: "_SYS.airyBi",
60337
60531
  // Combinatorics
60532
+ Mandelbrot: ([c, maxIter], compile3) => {
60533
+ if (c === null || maxIter === null)
60534
+ throw new Error("Mandelbrot: missing arguments");
60535
+ return `_SYS.mandelbrot(${compile3(c)}, ${compile3(maxIter)})`;
60536
+ },
60537
+ Julia: ([z, c, maxIter], compile3) => {
60538
+ if (z === null || c === null || maxIter === null)
60539
+ throw new Error("Julia: missing arguments");
60540
+ return `_SYS.julia(${compile3(z)}, ${compile3(c)}, ${compile3(maxIter)})`;
60541
+ },
60338
60542
  Binomial: (args, compile3) => `_SYS.binomial(${compile3(args[0])}, ${compile3(args[1])})`,
60339
60543
  Fibonacci: "_SYS.fibonacci",
60340
60544
  // Complex-specific functions
60341
- Re: (args, compile3) => {
60545
+ Real: (args, compile3) => {
60342
60546
  if (BaseCompiler.isComplexValued(args[0]))
60343
60547
  return `(${compile3(args[0])}).re`;
60344
60548
  return compile3(args[0]);
60345
60549
  },
60346
- Im: (args, compile3) => {
60550
+ Imaginary: (args, compile3) => {
60347
60551
  if (BaseCompiler.isComplexValued(args[0]))
60348
60552
  return `(${compile3(args[0])}).im`;
60349
60553
  return "0";
60350
60554
  },
60351
- Arg: (args, compile3) => {
60555
+ Argument: (args, compile3) => {
60352
60556
  if (BaseCompiler.isComplexValued(args[0]))
60353
60557
  return `_SYS.carg(${compile3(args[0])})`;
60354
60558
  return `(${compile3(args[0])} >= 0 ? 0 : Math.PI)`;
@@ -60684,6 +60888,41 @@ var SYS_HELPERS = {
60684
60888
  sinc,
60685
60889
  fresnelS,
60686
60890
  fresnelC,
60891
+ mandelbrot: (c, maxIter) => {
60892
+ let zx = 0, zy = 0;
60893
+ const cx = typeof c === "number" ? c : c.re;
60894
+ const cy = typeof c === "number" ? 0 : c.im;
60895
+ const n = Math.round(maxIter);
60896
+ for (let i = 0; i < n; i++) {
60897
+ const newZx = zx * zx - zy * zy + cx;
60898
+ zy = 2 * zx * zy + cy;
60899
+ zx = newZx;
60900
+ const mag2 = zx * zx + zy * zy;
60901
+ if (mag2 > 4) {
60902
+ const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
60903
+ return Math.max(0, Math.min(1, smooth));
60904
+ }
60905
+ }
60906
+ return 1;
60907
+ },
60908
+ julia: (z, c, maxIter) => {
60909
+ let zx = typeof z === "number" ? z : z.re;
60910
+ let zy = typeof z === "number" ? 0 : z.im;
60911
+ const cx = typeof c === "number" ? c : c.re;
60912
+ const cy = typeof c === "number" ? 0 : c.im;
60913
+ const n = Math.round(maxIter);
60914
+ for (let i = 0; i < n; i++) {
60915
+ const newZx = zx * zx - zy * zy + cx;
60916
+ zy = 2 * zx * zy + cy;
60917
+ zx = newZx;
60918
+ const mag2 = zx * zx + zy * zy;
60919
+ if (mag2 > 4) {
60920
+ const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
60921
+ return Math.max(0, Math.min(1, smooth));
60922
+ }
60923
+ }
60924
+ return 1;
60925
+ },
60687
60926
  binomial: choose,
60688
60927
  fibonacci,
60689
60928
  // Complex helpers
@@ -61024,11 +61263,39 @@ function fibonacci(n) {
61024
61263
  return b;
61025
61264
  }
61026
61265
 
61266
+ // src/compute-engine/compilation/fractal-orbit.ts
61267
+ function computeReferenceOrbit(center, maxIter, precision) {
61268
+ const prevPrecision = BigDecimal.precision;
61269
+ BigDecimal.precision = precision;
61270
+ try {
61271
+ const cr = new BigDecimal(center[0]);
61272
+ const ci = new BigDecimal(center[1]);
61273
+ let zr = BigDecimal.ZERO;
61274
+ let zi = BigDecimal.ZERO;
61275
+ const ESCAPE = new BigDecimal(256);
61276
+ const points = [];
61277
+ for (let i = 0; i < maxIter; i++) {
61278
+ points.push(zr.toNumber(), zi.toNumber());
61279
+ const zr2 = zr.mul(zr).toPrecision(precision);
61280
+ const zi2 = zi.mul(zi).toPrecision(precision);
61281
+ const mag2 = zr2.add(zi2);
61282
+ if (mag2.cmp(ESCAPE) > 0) break;
61283
+ const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
61284
+ zr = zr2.sub(zi2).add(cr);
61285
+ zi = new_zi;
61286
+ }
61287
+ return new Float32Array(points);
61288
+ } finally {
61289
+ BigDecimal.precision = prevPrecision;
61290
+ }
61291
+ }
61292
+
61027
61293
  // src/compute-engine/compilation/gpu-target.ts
61028
61294
  var GPU_OPERATORS = {
61029
61295
  Add: ["+", 11],
61030
61296
  Negate: ["-", 14],
61031
61297
  Subtract: ["-", 11],
61298
+ // Subtract canonicalizes to Add+Negate; kept as fallback
61032
61299
  Multiply: ["*", 12],
61033
61300
  Divide: ["/", 13],
61034
61301
  Equal: ["==", 8],
@@ -61044,6 +61311,12 @@ var GPU_OPERATORS = {
61044
61311
  function gpuVec2(target) {
61045
61312
  return target?.language === "wgsl" ? "vec2f" : "vec2";
61046
61313
  }
61314
+ function compileIntArg(expr2, compile3, target) {
61315
+ const c = tryGetConstant(expr2);
61316
+ if (c !== void 0 && Number.isInteger(c)) return c.toString();
61317
+ const intCast = target?.language === "wgsl" ? "i32" : "int";
61318
+ return `${intCast}(${compile3(expr2)})`;
61319
+ }
61047
61320
  var GPU_UNROLL_LIMIT = 100;
61048
61321
  function compileGPUSumProduct(kind, args, _compile2, target) {
61049
61322
  if (!args[0]) throw new Error(`${kind}: no body`);
@@ -61100,94 +61373,126 @@ function compileGPUSumProduct(kind, args, _compile2, target) {
61100
61373
  ];
61101
61374
  return lines.join("\n");
61102
61375
  }
61376
+ function selectFractalStrategy(target) {
61377
+ const radius = target.hints?.viewport?.radius;
61378
+ if (radius === void 0) return "single";
61379
+ if (radius > 1e-6) return "single";
61380
+ if (radius > 1e-14) return "double";
61381
+ return "perturbation";
61382
+ }
61103
61383
  var GPU_FUNCTIONS = {
61104
61384
  // Variadic arithmetic (for function-call form, e.g., with vectors)
61105
61385
  Add: (args, compile3, target) => {
61106
61386
  if (args.length === 0) return "0.0";
61107
61387
  if (args.length === 1) return compile3(args[0]);
61108
61388
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61109
- if (!anyComplex) return args.map((x) => compile3(x)).join(" + ");
61110
- const v2 = gpuVec2(target);
61111
- return args.map((a) => {
61112
- const code = compile3(a);
61113
- return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61114
- }).join(" + ");
61115
- },
61116
- Multiply: (args, compile3, _target) => {
61117
- if (args.length === 0) return "1.0";
61118
- if (args.length === 1) return compile3(args[0]);
61119
- const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61120
- if (!anyComplex) return args.map((x) => compile3(x)).join(" * ");
61121
- let result = compile3(args[0]);
61122
- let resultIsComplex = BaseCompiler.isComplexValued(args[0]);
61123
- for (let i = 1; i < args.length; i++) {
61124
- const code = compile3(args[i]);
61125
- const argIsComplex = BaseCompiler.isComplexValued(args[i]);
61126
- if (!resultIsComplex && !argIsComplex) {
61127
- result = `(${result} * ${code})`;
61128
- } else if (resultIsComplex && !argIsComplex) {
61129
- result = `(${code} * ${result})`;
61130
- } else if (!resultIsComplex && argIsComplex) {
61131
- result = `(${result} * ${code})`;
61132
- resultIsComplex = true;
61133
- } else {
61134
- result = `_gpu_cmul(${result}, ${code})`;
61135
- }
61389
+ if (!anyComplex) {
61390
+ return foldTerms(
61391
+ args.map((x) => compile3(x)),
61392
+ "0.0",
61393
+ "+"
61394
+ );
61136
61395
  }
61137
- return result;
61138
- },
61139
- Subtract: (args, compile3, target) => {
61140
- if (args.length === 0) return "0.0";
61396
+ const parts = args.map((a) => tryGetComplexParts(a, compile3));
61397
+ if (parts.some((p) => p === null)) {
61398
+ const v2 = gpuVec2(target);
61399
+ return args.map((a) => {
61400
+ const code = compile3(a);
61401
+ return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61402
+ }).join(" + ");
61403
+ }
61404
+ const reParts = [];
61405
+ const imParts = [];
61406
+ for (const p of parts) {
61407
+ if (p.re !== null) reParts.push(p.re);
61408
+ if (p.im !== null) imParts.push(p.im);
61409
+ }
61410
+ const reSum = foldTerms(reParts, "0.0", "+");
61411
+ const imSum = foldTerms(imParts, "0.0", "+");
61412
+ return `${gpuVec2(target)}(${reSum}, ${imSum})`;
61413
+ },
61414
+ Multiply: (args, compile3, target) => {
61415
+ if (args.length === 0) return "1.0";
61141
61416
  if (args.length === 1) return compile3(args[0]);
61142
61417
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61143
61418
  if (!anyComplex) {
61144
- if (args.length === 2) return `${compile3(args[0])} - ${compile3(args[1])}`;
61145
- let result2 = compile3(args[0]);
61146
- for (let i = 1; i < args.length; i++) {
61147
- result2 = `${result2} - ${compile3(args[i])}`;
61148
- }
61149
- return result2;
61150
- }
61151
- const v2 = gpuVec2(target);
61152
- const promote = (a) => {
61153
- const code = compile3(a);
61154
- return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61155
- };
61156
- if (args.length === 2) return `${promote(args[0])} - ${promote(args[1])}`;
61157
- let result = promote(args[0]);
61158
- for (let i = 1; i < args.length; i++) {
61159
- result = `${result} - ${promote(args[i])}`;
61419
+ return foldTerms(
61420
+ args.map((x) => compile3(x)),
61421
+ "1.0",
61422
+ "*"
61423
+ );
61160
61424
  }
61425
+ const iIndex = args.findIndex(
61426
+ (op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
61427
+ );
61428
+ if (iIndex >= 0) {
61429
+ const iFactor = args[iIndex];
61430
+ const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
61431
+ const realFactors = args.filter((_, i) => i !== iIndex);
61432
+ const v2 = gpuVec2(target);
61433
+ if (realFactors.length === 0)
61434
+ return `${v2}(0.0, ${formatFloat(iScale)})`;
61435
+ const factors = realFactors.map((f) => compile3(f));
61436
+ if (iScale !== 1) factors.unshift(formatFloat(iScale));
61437
+ const imCode = foldTerms(factors, "1.0", "*");
61438
+ return `${v2}(0.0, ${imCode})`;
61439
+ }
61440
+ const realCodes = [];
61441
+ const complexCodes = [];
61442
+ for (const a of args) {
61443
+ if (BaseCompiler.isComplexValued(a)) complexCodes.push(compile3(a));
61444
+ else realCodes.push(compile3(a));
61445
+ }
61446
+ const scalarCode = foldTerms(realCodes, "1.0", "*");
61447
+ let result = complexCodes[0];
61448
+ for (let i = 1; i < complexCodes.length; i++) {
61449
+ result = `_gpu_cmul(${result}, ${complexCodes[i]})`;
61450
+ }
61451
+ if (scalarCode !== "1.0") result = `(${scalarCode} * ${result})`;
61161
61452
  return result;
61162
61453
  },
61454
+ // No Subtract function handler — Subtract canonicalizes to Add+Negate.
61455
+ // The operator entry in GPU_OPERATORS handles any edge cases.
61163
61456
  Divide: (args, compile3, target) => {
61164
61457
  if (args.length === 0) return "1.0";
61165
61458
  if (args.length === 1) return compile3(args[0]);
61166
61459
  const ac = BaseCompiler.isComplexValued(args[0]);
61167
61460
  const bc = args.length >= 2 && BaseCompiler.isComplexValued(args[1]);
61168
61461
  if (!ac && !bc) {
61169
- if (args.length === 2) return `${compile3(args[0])} / ${compile3(args[1])}`;
61462
+ if (args.length === 2) {
61463
+ const a = tryGetConstant(args[0]);
61464
+ const b = tryGetConstant(args[1]);
61465
+ if (a !== void 0 && b !== void 0 && b !== 0)
61466
+ return formatFloat(a / b);
61467
+ if (b === 1) return compile3(args[0]);
61468
+ return `${compile3(args[0])} / ${compile3(args[1])}`;
61469
+ }
61170
61470
  let result = compile3(args[0]);
61171
- for (let i = 1; i < args.length; i++) {
61471
+ for (let i = 1; i < args.length; i++)
61172
61472
  result = `${result} / ${compile3(args[i])}`;
61173
- }
61174
61473
  return result;
61175
61474
  }
61176
61475
  if (ac && bc) return `_gpu_cdiv(${compile3(args[0])}, ${compile3(args[1])})`;
61177
- if (ac && !bc) {
61178
- return `(${compile3(args[0])} / ${compile3(args[1])})`;
61179
- }
61476
+ if (ac && !bc) return `(${compile3(args[0])} / ${compile3(args[1])})`;
61180
61477
  const v2 = gpuVec2(target);
61181
61478
  return `_gpu_cdiv(${v2}(${compile3(args[0])}, 0.0), ${compile3(args[1])})`;
61182
61479
  },
61183
- Negate: ([x], compile3) => {
61480
+ Negate: ([x], compile3, target) => {
61184
61481
  if (x === null) throw new Error("Negate: no argument");
61482
+ const c = tryGetConstant(x);
61483
+ if (c !== void 0) return formatFloat(-c);
61484
+ if (isNumber(x) && x.im !== 0) {
61485
+ return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
61486
+ }
61487
+ if (isSymbol2(x, "ImaginaryUnit"))
61488
+ return `${gpuVec2(target)}(0.0, -1.0)`;
61185
61489
  return `(-${compile3(x)})`;
61186
61490
  },
61187
61491
  // Standard math functions with complex dispatch
61188
61492
  Abs: (args, compile3) => {
61189
61493
  if (BaseCompiler.isComplexValued(args[0]))
61190
61494
  return `length(${compile3(args[0])})`;
61495
+ if (BaseCompiler.isNonNegative(args[0])) return compile3(args[0]);
61191
61496
  return `abs(${compile3(args[0])})`;
61192
61497
  },
61193
61498
  Arccos: (args, compile3) => {
@@ -61205,7 +61510,10 @@ var GPU_FUNCTIONS = {
61205
61510
  return `_gpu_catan(${compile3(args[0])})`;
61206
61511
  return `atan(${compile3(args[0])})`;
61207
61512
  },
61208
- Ceil: "ceil",
61513
+ Ceil: (args, compile3) => {
61514
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61515
+ return `ceil(${compile3(args[0])})`;
61516
+ },
61209
61517
  Clamp: "clamp",
61210
61518
  Cos: (args, compile3) => {
61211
61519
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61219,7 +61527,10 @@ var GPU_FUNCTIONS = {
61219
61527
  return `exp(${compile3(args[0])})`;
61220
61528
  },
61221
61529
  Exp2: "exp2",
61222
- Floor: "floor",
61530
+ Floor: (args, compile3) => {
61531
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61532
+ return `floor(${compile3(args[0])})`;
61533
+ },
61223
61534
  Fract: "fract",
61224
61535
  Ln: (args, compile3) => {
61225
61536
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61241,10 +61552,25 @@ var GPU_FUNCTIONS = {
61241
61552
  const eCode = BaseCompiler.isComplexValued(exp3) ? compile3(exp3) : `${v2}(${compile3(exp3)}, 0.0)`;
61242
61553
  return `_gpu_cpow(${bCode}, ${eCode})`;
61243
61554
  }
61555
+ const bConst = tryGetConstant(base);
61556
+ const eConst = tryGetConstant(exp3);
61557
+ if (bConst !== void 0 && eConst !== void 0)
61558
+ return formatFloat(Math.pow(bConst, eConst));
61559
+ if (eConst === 0) return "1.0";
61560
+ if (eConst === 1) return compile3(base);
61561
+ if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
61562
+ const code = compile3(base);
61563
+ return `(${code} * ${code})`;
61564
+ }
61565
+ if (eConst === -1) return `(1.0 / ${compile3(base)})`;
61566
+ if (eConst === 0.5) return `sqrt(${compile3(base)})`;
61244
61567
  return `pow(${compile3(base)}, ${compile3(exp3)})`;
61245
61568
  },
61246
61569
  Radians: "radians",
61247
- Round: "round",
61570
+ Round: (args, compile3) => {
61571
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61572
+ return `round(${compile3(args[0])})`;
61573
+ },
61248
61574
  Sign: "sign",
61249
61575
  Sin: (args, compile3) => {
61250
61576
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61255,6 +61581,8 @@ var GPU_FUNCTIONS = {
61255
61581
  Sqrt: (args, compile3) => {
61256
61582
  if (BaseCompiler.isComplexValued(args[0]))
61257
61583
  return `_gpu_csqrt(${compile3(args[0])})`;
61584
+ const c = tryGetConstant(args[0]);
61585
+ if (c !== void 0) return formatFloat(Math.sqrt(c));
61258
61586
  return `sqrt(${compile3(args[0])})`;
61259
61587
  },
61260
61588
  Step: "step",
@@ -61263,17 +61591,20 @@ var GPU_FUNCTIONS = {
61263
61591
  return `_gpu_ctan(${compile3(args[0])})`;
61264
61592
  return `tan(${compile3(args[0])})`;
61265
61593
  },
61266
- Truncate: "trunc",
61594
+ Truncate: (args, compile3) => {
61595
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61596
+ return `trunc(${compile3(args[0])})`;
61597
+ },
61267
61598
  // Complex-specific functions
61268
- Re: (args, compile3) => {
61599
+ Real: (args, compile3) => {
61269
61600
  if (BaseCompiler.isComplexValued(args[0])) return `(${compile3(args[0])}).x`;
61270
61601
  return compile3(args[0]);
61271
61602
  },
61272
- Im: (args, compile3) => {
61603
+ Imaginary: (args, compile3) => {
61273
61604
  if (BaseCompiler.isComplexValued(args[0])) return `(${compile3(args[0])}).y`;
61274
61605
  return "0.0";
61275
61606
  },
61276
- Arg: (args, compile3) => {
61607
+ Argument: (args, compile3) => {
61277
61608
  if (BaseCompiler.isComplexValued(args[0])) {
61278
61609
  const code = compile3(args[0]);
61279
61610
  return `atan(${code}.y, ${code}.x)`;
@@ -61488,13 +61819,20 @@ var GPU_FUNCTIONS = {
61488
61819
  },
61489
61820
  Square: ([x], compile3) => {
61490
61821
  if (x === null) throw new Error("Square: no argument");
61491
- const arg = compile3(x);
61492
- return `(${arg} * ${arg})`;
61822
+ if (isSymbol2(x) || isNumber(x)) {
61823
+ const arg = compile3(x);
61824
+ return `(${arg} * ${arg})`;
61825
+ }
61826
+ return `pow(${compile3(x)}, 2.0)`;
61493
61827
  },
61494
61828
  Root: ([x, n], compile3) => {
61495
61829
  if (x === null) throw new Error("Root: no argument");
61496
61830
  if (n === null || n === void 0) return `sqrt(${compile3(x)})`;
61497
- if (n?.re === 2) return `sqrt(${compile3(x)})`;
61831
+ const nConst = tryGetConstant(n);
61832
+ if (nConst === 2) return `sqrt(${compile3(x)})`;
61833
+ const xConst = tryGetConstant(x);
61834
+ if (xConst !== void 0 && nConst !== void 0)
61835
+ return formatFloat(Math.pow(xConst, 1 / nConst));
61498
61836
  return `pow(${compile3(x)}, 1.0 / ${compile3(n)})`;
61499
61837
  },
61500
61838
  // Color functions (pure-math, GPU-compilable)
@@ -61536,18 +61874,34 @@ var GPU_FUNCTIONS = {
61536
61874
  Mandelbrot: ([c, maxIter], compile3, target) => {
61537
61875
  if (c === null || maxIter === null)
61538
61876
  throw new Error("Mandelbrot: missing arguments");
61539
- const intCast = target?.language === "wgsl" ? "i32" : "int";
61540
- return `_fractal_mandelbrot(${compile3(c)}, ${intCast}(${compile3(
61541
- maxIter
61542
- )}))`;
61877
+ const iterCode = compileIntArg(maxIter, compile3, target);
61878
+ const strategy = selectFractalStrategy(target);
61879
+ if (strategy === "double") {
61880
+ const cCode = compile3(c);
61881
+ return `_fractal_mandelbrot_dp(vec4(${cCode}, vec2(0.0)), ${iterCode})`;
61882
+ }
61883
+ if (strategy === "perturbation") {
61884
+ const cCode = compile3(c);
61885
+ return `_fractal_mandelbrot_pt(${cCode}, ${iterCode})`;
61886
+ }
61887
+ return `_fractal_mandelbrot(${compile3(c)}, ${iterCode})`;
61543
61888
  },
61544
61889
  Julia: ([z, c, maxIter], compile3, target) => {
61545
61890
  if (z === null || c === null || maxIter === null)
61546
61891
  throw new Error("Julia: missing arguments");
61547
- const intCast = target?.language === "wgsl" ? "i32" : "int";
61548
- return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${intCast}(${compile3(
61549
- maxIter
61550
- )}))`;
61892
+ const iterCode = compileIntArg(maxIter, compile3, target);
61893
+ const strategy = selectFractalStrategy(target);
61894
+ if (strategy === "double") {
61895
+ const zCode = compile3(z);
61896
+ const cCode = compile3(c);
61897
+ return `_fractal_julia_dp(vec4(${zCode}, vec2(0.0)), vec4(${cCode}, vec2(0.0)), ${iterCode})`;
61898
+ }
61899
+ if (strategy === "perturbation") {
61900
+ const zCode = compile3(z);
61901
+ const cCode = compile3(c);
61902
+ return `_fractal_julia_pt(${zCode}, ${cCode}, ${iterCode})`;
61903
+ }
61904
+ return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${iterCode})`;
61551
61905
  },
61552
61906
  // Vector/Matrix operations
61553
61907
  Cross: "cross",
@@ -62144,6 +62498,200 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
62144
62498
  return sgn * vals[n] / norm;
62145
62499
  }
62146
62500
  `;
62501
+ var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
62502
+ // Split a float into high and low parts for exact multiplication
62503
+ vec2 ds_split(float a) {
62504
+ const float SPLIT = 4097.0; // 2^12 + 1
62505
+ float t = SPLIT * a;
62506
+ float hi = t - (t - a);
62507
+ float lo = a - hi;
62508
+ return vec2(hi, lo);
62509
+ }
62510
+
62511
+ // Create a double-single from a single float
62512
+ vec2 ds_from(float a) {
62513
+ return vec2(a, 0.0);
62514
+ }
62515
+
62516
+ // Error-free addition (Knuth TwoSum)
62517
+ vec2 ds_add(vec2 a, vec2 b) {
62518
+ float s = a.x + b.x;
62519
+ float v = s - a.x;
62520
+ float e = (a.x - (s - v)) + (b.x - v);
62521
+ float lo = (a.y + b.y) + e;
62522
+ float hi = s + lo;
62523
+ lo = lo - (hi - s);
62524
+ return vec2(hi, lo);
62525
+ }
62526
+
62527
+ // Double-single subtraction
62528
+ vec2 ds_sub(vec2 a, vec2 b) {
62529
+ return ds_add(a, vec2(-b.x, -b.y));
62530
+ }
62531
+
62532
+ // Error-free multiplication (Dekker TwoProduct)
62533
+ vec2 ds_mul(vec2 a, vec2 b) {
62534
+ float p = a.x * b.x;
62535
+ vec2 sa = ds_split(a.x);
62536
+ vec2 sb = ds_split(b.x);
62537
+ float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
62538
+ err += a.x * b.y + a.y * b.x;
62539
+ float hi = p + err;
62540
+ float lo = err - (hi - p);
62541
+ return vec2(hi, lo);
62542
+ }
62543
+
62544
+ // Optimized self-multiply
62545
+ vec2 ds_sqr(vec2 a) {
62546
+ float p = a.x * a.x;
62547
+ vec2 sa = ds_split(a.x);
62548
+ float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
62549
+ err += 2.0 * a.x * a.y;
62550
+ float hi = p + err;
62551
+ float lo = err - (hi - p);
62552
+ return vec2(hi, lo);
62553
+ }
62554
+
62555
+ // Compare magnitude: returns -1, 0, or 1
62556
+ float ds_cmp(vec2 a, vec2 b) {
62557
+ float d = a.x - b.x;
62558
+ if (d != 0.0) return sign(d);
62559
+ return sign(a.y - b.y);
62560
+ }
62561
+ `;
62562
+ var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
62563
+ fn ds_split(a: f32) -> vec2f {
62564
+ const SPLIT: f32 = 4097.0;
62565
+ let t = SPLIT * a;
62566
+ let hi = t - (t - a);
62567
+ let lo = a - hi;
62568
+ return vec2f(hi, lo);
62569
+ }
62570
+
62571
+ fn ds_from(a: f32) -> vec2f {
62572
+ return vec2f(a, 0.0);
62573
+ }
62574
+
62575
+ fn ds_add(a: vec2f, b: vec2f) -> vec2f {
62576
+ let s = a.x + b.x;
62577
+ let v = s - a.x;
62578
+ let e = (a.x - (s - v)) + (b.x - v);
62579
+ let lo_t = (a.y + b.y) + e;
62580
+ let hi = s + lo_t;
62581
+ let lo = lo_t - (hi - s);
62582
+ return vec2f(hi, lo);
62583
+ }
62584
+
62585
+ fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
62586
+ return ds_add(a, vec2f(-b.x, -b.y));
62587
+ }
62588
+
62589
+ fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
62590
+ let p = a.x * b.x;
62591
+ let sa = ds_split(a.x);
62592
+ let sb = ds_split(b.x);
62593
+ var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
62594
+ err += a.x * b.y + a.y * b.x;
62595
+ let hi = p + err;
62596
+ let lo = err - (hi - p);
62597
+ return vec2f(hi, lo);
62598
+ }
62599
+
62600
+ fn ds_sqr(a: vec2f) -> vec2f {
62601
+ let p = a.x * a.x;
62602
+ let sa = ds_split(a.x);
62603
+ var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
62604
+ err += 2.0 * a.x * a.y;
62605
+ let hi = p + err;
62606
+ let lo = err - (hi - p);
62607
+ return vec2f(hi, lo);
62608
+ }
62609
+
62610
+ fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
62611
+ let d = a.x - b.x;
62612
+ if (d != 0.0) { return sign(d); }
62613
+ return sign(a.y - b.y);
62614
+ }
62615
+ `;
62616
+ var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
62617
+ float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
62618
+ // c = (re_hi, im_hi, re_lo, im_lo)
62619
+ vec2 cr = vec2(c.x, c.z); // real part as ds
62620
+ vec2 ci = vec2(c.y, c.w); // imag part as ds
62621
+ vec2 zr = vec2(0.0, 0.0);
62622
+ vec2 zi = vec2(0.0, 0.0);
62623
+ for (int i = 0; i < maxIter; i++) {
62624
+ vec2 zr2 = ds_sqr(zr);
62625
+ vec2 zi2 = ds_sqr(zi);
62626
+ // |z|^2 > 4.0 ?
62627
+ vec2 mag2 = ds_add(zr2, zi2);
62628
+ if (mag2.x > 4.0)
62629
+ return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
62630
+ // z = z^2 + c
62631
+ vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
62632
+ zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
62633
+ zi = new_zi;
62634
+ }
62635
+ return 1.0;
62636
+ }
62637
+
62638
+ float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
62639
+ vec2 zr = vec2(z_in.x, z_in.z);
62640
+ vec2 zi = vec2(z_in.y, z_in.w);
62641
+ vec2 cr = vec2(c.x, c.z);
62642
+ vec2 ci = vec2(c.y, c.w);
62643
+ for (int i = 0; i < maxIter; i++) {
62644
+ vec2 zr2 = ds_sqr(zr);
62645
+ vec2 zi2 = ds_sqr(zi);
62646
+ vec2 mag2 = ds_add(zr2, zi2);
62647
+ if (mag2.x > 4.0)
62648
+ return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
62649
+ vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62650
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62651
+ zi = new_zi;
62652
+ }
62653
+ return 1.0;
62654
+ }
62655
+ `;
62656
+ var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
62657
+ fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
62658
+ let cr = vec2f(c.x, c.z);
62659
+ let ci = vec2f(c.y, c.w);
62660
+ var zr = vec2f(0.0, 0.0);
62661
+ var zi = vec2f(0.0, 0.0);
62662
+ for (var i: i32 = 0; i < maxIter; i++) {
62663
+ let zr2 = ds_sqr(zr);
62664
+ let zi2 = ds_sqr(zi);
62665
+ let mag2 = ds_add(zr2, zi2);
62666
+ if (mag2.x > 4.0) {
62667
+ return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
62668
+ }
62669
+ let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62670
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62671
+ zi = new_zi;
62672
+ }
62673
+ return 1.0;
62674
+ }
62675
+
62676
+ fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
62677
+ var zr = vec2f(z_in.x, z_in.z);
62678
+ var zi = vec2f(z_in.y, z_in.w);
62679
+ let cr = vec2f(c.x, c.z);
62680
+ let ci = vec2f(c.y, c.w);
62681
+ for (var i: i32 = 0; i < maxIter; i++) {
62682
+ let zr2 = ds_sqr(zr);
62683
+ let zi2 = ds_sqr(zi);
62684
+ let mag2 = ds_add(zr2, zi2);
62685
+ if (mag2.x > 4.0) {
62686
+ return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
62687
+ }
62688
+ let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62689
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62690
+ zi = new_zi;
62691
+ }
62692
+ return 1.0;
62693
+ }
62694
+ `;
62147
62695
  var GPU_FRACTAL_PREAMBLE_GLSL = `
62148
62696
  float _fractal_mandelbrot(vec2 c, int maxIter) {
62149
62697
  vec2 z = vec2(0.0, 0.0);
@@ -62187,6 +62735,188 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
62187
62735
  return 1.0;
62188
62736
  }
62189
62737
  `;
62738
+ var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
62739
+ uniform sampler2D _refOrbit;
62740
+ uniform int _refOrbitLen;
62741
+ uniform int _refOrbitTexWidth;
62742
+
62743
+ vec2 _pt_fetch_orbit(int i) {
62744
+ int y = i / _refOrbitTexWidth;
62745
+ int x = i - y * _refOrbitTexWidth;
62746
+ return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
62747
+ }
62748
+
62749
+ float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
62750
+ float dr = 0.0;
62751
+ float di = 0.0;
62752
+ int orbitLen = min(maxIter, _refOrbitLen);
62753
+ for (int i = 0; i < orbitLen; i++) {
62754
+ vec2 Zn = _pt_fetch_orbit(i);
62755
+ // delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
62756
+ float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62757
+ float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62758
+ dr = new_dr;
62759
+ di = new_di;
62760
+ // Full z = Z_{n+1} + delta for escape check
62761
+ vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
62762
+ float zr = Zn1.x + dr;
62763
+ float zi = Zn1.y + di;
62764
+ float mag2 = zr * zr + zi * zi;
62765
+ if (mag2 > 4.0)
62766
+ return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62767
+ // Glitch detection: |delta|^2 > |Z|^2
62768
+ float dmag2 = dr * dr + di * di;
62769
+ float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62770
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62771
+ // Rebase to absolute coordinates and continue with single-float
62772
+ float abs_zr = Zn1.x + dr;
62773
+ float abs_zi = Zn1.y + di;
62774
+ // Reconstruct absolute c from reference + delta
62775
+ // (Use ds_from for the concept, but single-float suffices for fallback)
62776
+ float cx = abs_zr - dr + delta_c.x;
62777
+ float cy = abs_zi - di + delta_c.y;
62778
+ for (int j = i + 1; j < maxIter; j++) {
62779
+ float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
62780
+ abs_zi = 2.0 * abs_zr * abs_zi + cy;
62781
+ abs_zr = new_zr;
62782
+ mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
62783
+ if (mag2 > 4.0)
62784
+ return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62785
+ }
62786
+ return 1.0;
62787
+ }
62788
+ }
62789
+ return 1.0;
62790
+ }
62791
+
62792
+ float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
62793
+ float dr = z_delta.x;
62794
+ float di = z_delta.y;
62795
+ int orbitLen = min(maxIter, _refOrbitLen);
62796
+ for (int i = 0; i < orbitLen; i++) {
62797
+ vec2 Zn = _pt_fetch_orbit(i);
62798
+ float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62799
+ float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62800
+ dr = new_dr;
62801
+ di = new_di;
62802
+ vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
62803
+ float zr = Zn1.x + dr;
62804
+ float zi = Zn1.y + di;
62805
+ float mag2 = zr * zr + zi * zi;
62806
+ if (mag2 > 4.0)
62807
+ return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62808
+ float dmag2 = dr * dr + di * di;
62809
+ float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62810
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62811
+ float abs_zr = Zn1.x + dr;
62812
+ float abs_zi = Zn1.y + di;
62813
+ float cx = delta_c.x;
62814
+ float cy = delta_c.y;
62815
+ for (int j = i + 1; j < maxIter; j++) {
62816
+ float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
62817
+ abs_zi = 2.0 * abs_zr * abs_zi + cy;
62818
+ abs_zr = new_zr;
62819
+ mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
62820
+ if (mag2 > 4.0)
62821
+ return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62822
+ }
62823
+ return 1.0;
62824
+ }
62825
+ }
62826
+ return 1.0;
62827
+ }
62828
+ `;
62829
+ var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
62830
+ @group(0) @binding(1) var _refOrbit: texture_2d<f32>;
62831
+ var<uniform> _refOrbitLen: i32;
62832
+ var<uniform> _refOrbitTexWidth: i32;
62833
+
62834
+ fn _pt_fetch_orbit(i: i32) -> vec2f {
62835
+ let y = i / _refOrbitTexWidth;
62836
+ let x = i - y * _refOrbitTexWidth;
62837
+ return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
62838
+ }
62839
+
62840
+ fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
62841
+ var dr: f32 = 0.0;
62842
+ var di: f32 = 0.0;
62843
+ let orbitLen = min(maxIter, _refOrbitLen);
62844
+ for (var i: i32 = 0; i < orbitLen; i++) {
62845
+ let Zn = _pt_fetch_orbit(i);
62846
+ let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62847
+ let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62848
+ dr = new_dr;
62849
+ di = new_di;
62850
+ var Zn1 = vec2f(0.0);
62851
+ if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
62852
+ let zr = Zn1.x + dr;
62853
+ let zi = Zn1.y + di;
62854
+ var mag2 = zr * zr + zi * zi;
62855
+ if (mag2 > 4.0) {
62856
+ return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62857
+ }
62858
+ let dmag2 = dr * dr + di * di;
62859
+ let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62860
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62861
+ var f_zr = Zn1.x + dr;
62862
+ var f_zi = Zn1.y + di;
62863
+ let cx = delta_c.x;
62864
+ let cy = delta_c.y;
62865
+ for (var j: i32 = i + 1; j < maxIter; j++) {
62866
+ let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
62867
+ f_zi = 2.0 * f_zr * f_zi + cy;
62868
+ f_zr = t_zr;
62869
+ mag2 = f_zr * f_zr + f_zi * f_zi;
62870
+ if (mag2 > 4.0) {
62871
+ return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62872
+ }
62873
+ }
62874
+ return 1.0;
62875
+ }
62876
+ }
62877
+ return 1.0;
62878
+ }
62879
+
62880
+ fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
62881
+ var dr = z_delta.x;
62882
+ var di = z_delta.y;
62883
+ let orbitLen = min(maxIter, _refOrbitLen);
62884
+ for (var i: i32 = 0; i < orbitLen; i++) {
62885
+ let Zn = _pt_fetch_orbit(i);
62886
+ let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62887
+ let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62888
+ dr = new_dr;
62889
+ di = new_di;
62890
+ var Zn1 = vec2f(0.0);
62891
+ if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
62892
+ let zr = Zn1.x + dr;
62893
+ let zi = Zn1.y + di;
62894
+ var mag2 = zr * zr + zi * zi;
62895
+ if (mag2 > 4.0) {
62896
+ return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62897
+ }
62898
+ let dmag2 = dr * dr + di * di;
62899
+ let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62900
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62901
+ var f_zr = Zn1.x + dr;
62902
+ var f_zi = Zn1.y + di;
62903
+ let cx = delta_c.x;
62904
+ let cy = delta_c.y;
62905
+ for (var j: i32 = i + 1; j < maxIter; j++) {
62906
+ let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
62907
+ f_zi = 2.0 * f_zr * f_zi + cy;
62908
+ f_zr = t_zr;
62909
+ mag2 = f_zr * f_zr + f_zi * f_zi;
62910
+ if (mag2 > 4.0) {
62911
+ return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62912
+ }
62913
+ }
62914
+ return 1.0;
62915
+ }
62916
+ }
62917
+ return 1.0;
62918
+ }
62919
+ `;
62190
62920
  var GPU_COLOR_PREAMBLE_GLSL = `
62191
62921
  float _gpu_srgb_to_linear(float c) {
62192
62922
  if (c <= 0.04045) return c / 12.92;
@@ -62625,6 +63355,7 @@ var GPUShaderTarget = class {
62625
63355
  const constants = this.getConstants();
62626
63356
  const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
62627
63357
  const target = this.createTarget({
63358
+ hints: options.hints,
62628
63359
  functions: (id) => {
62629
63360
  if (userFunctions && id in userFunctions) {
62630
63361
  const fn = userFunctions[id];
@@ -62663,12 +63394,65 @@ var GPUShaderTarget = class {
62663
63394
  if (code.includes("_gpu_besselJ"))
62664
63395
  preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
62665
63396
  if (code.includes("_fractal_")) {
62666
- preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
63397
+ if (code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) {
63398
+ preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
63399
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
63400
+ } else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
63401
+ preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
63402
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
63403
+ } else {
63404
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
63405
+ }
62667
63406
  }
62668
63407
  if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
62669
63408
  preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
62670
63409
  }
62671
63410
  if (preamble) result.preamble = preamble;
63411
+ if (code.includes("_fractal_") && options.hints?.viewport) {
63412
+ const strategy = selectFractalStrategy(target);
63413
+ const radius = options.hints.viewport.radius;
63414
+ switch (strategy) {
63415
+ case "single":
63416
+ result.staleWhen = { radiusBelow: 1e-6 };
63417
+ break;
63418
+ case "double":
63419
+ result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
63420
+ break;
63421
+ case "perturbation":
63422
+ result.staleWhen = {
63423
+ radiusAbove: 1e-5,
63424
+ radiusBelow: radius * 0.01,
63425
+ centerDistance: radius * 2
63426
+ };
63427
+ break;
63428
+ }
63429
+ }
63430
+ if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
63431
+ const viewport = options.hints.viewport;
63432
+ const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
63433
+ const maxIter = 1e3;
63434
+ const orbit = computeReferenceOrbit(
63435
+ viewport.center,
63436
+ maxIter,
63437
+ digits
63438
+ );
63439
+ const orbitLen = orbit.length / 2;
63440
+ const texWidth = Math.min(orbitLen, 4096);
63441
+ const texHeight = Math.ceil(orbitLen / texWidth);
63442
+ result.textures = {
63443
+ _refOrbit: {
63444
+ data: orbit,
63445
+ width: texWidth,
63446
+ height: texHeight,
63447
+ format: "rg32f"
63448
+ }
63449
+ };
63450
+ result.uniforms = {
63451
+ ...result.uniforms,
63452
+ _refOrbitLen: orbitLen,
63453
+ _refOrbitTexWidth: texWidth
63454
+ };
63455
+ }
62672
63456
  return result;
62673
63457
  }
62674
63458
  compileToSource(expr2, _options = {}) {
@@ -64179,6 +64963,7 @@ var INTERVAL_JAVASCRIPT_OPERATORS = {
64179
64963
  Add: ["_IA.add", 20],
64180
64964
  Negate: ["_IA.negate", 20],
64181
64965
  Subtract: ["_IA.sub", 20],
64966
+ // Subtract canonicalizes to Add+Negate; kept as fallback
64182
64967
  Multiply: ["_IA.mul", 20],
64183
64968
  Divide: ["_IA.div", 20],
64184
64969
  // Comparisons return BoolInterval
@@ -64203,17 +64988,7 @@ var INTERVAL_JAVASCRIPT_FUNCTIONS = {
64203
64988
  }
64204
64989
  return result;
64205
64990
  },
64206
- Subtract: (args, compile3) => {
64207
- if (args.length === 0) return "_IA.point(0)";
64208
- if (args.length === 1) return `_IA.negate(${compile3(args[0])})`;
64209
- if (args.length === 2)
64210
- return `_IA.sub(${compile3(args[0])}, ${compile3(args[1])})`;
64211
- let result = compile3(args[0]);
64212
- for (let i = 1; i < args.length; i++) {
64213
- result = `_IA.sub(${result}, ${compile3(args[i])})`;
64214
- }
64215
- return result;
64216
- },
64991
+ // No Subtract handler canonicalizes to Add+Negate before compilation.
64217
64992
  Multiply: (args, compile3) => {
64218
64993
  if (args.length === 0) return "_IA.point(1)";
64219
64994
  if (args.length === 1) return compile3(args[0]);
@@ -67187,7 +67962,9 @@ var ComputeEngine = class _ComputeEngine {
67187
67962
  }
67188
67963
  return new ExactNumericValue(value, makeNumericValue);
67189
67964
  }
67190
- throw Error("Unexpected value");
67965
+ throw Error(
67966
+ `Unexpected value: ${typeof value === "object" ? JSON.stringify(value) : String(value)}`
67967
+ );
67191
67968
  }
67192
67969
  /**
67193
67970
  * The cost function is used to determine the "cost" of an expression. For example, when simplifying an expression, the simplification that results in the lowest cost is chosen.
@@ -67658,7 +68435,7 @@ var ComputeEngine = class _ComputeEngine {
67658
68435
  _setDefaultEngineFactory(() => new ComputeEngine());
67659
68436
 
67660
68437
  // src/core.ts
67661
- var version = "0.55.2";
68438
+ var version = "0.55.4";
67662
68439
  export {
67663
68440
  ComputeEngine,
67664
68441
  N,