@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.umd.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /** ComputeEngineCore 0.55.2 */
1
+ /** ComputeEngineCore 0.55.4 */
2
2
  (function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComputeEngineCore = {}));})(this, (function (exports) { 'use strict';
3
3
  var ComputeEngineCore = (() => {
4
4
  var __defProp = Object.defineProperty;
@@ -17199,6 +17199,10 @@ var ComputeEngineCore = (() => {
17199
17199
  parser.nextToken();
17200
17200
  continue;
17201
17201
  }
17202
+ if (EMOJIS.test(id + token)) {
17203
+ id += parser.nextToken();
17204
+ continue;
17205
+ }
17202
17206
  const next = parseSymbolToken(parser, { toplevel: false });
17203
17207
  if (next === null) return null;
17204
17208
  id += next;
@@ -17238,6 +17242,7 @@ var ComputeEngineCore = (() => {
17238
17242
  function matchPrefixedSymbol(parser) {
17239
17243
  const prefix = SYMBOL_PREFIX[parser.peek] ?? null;
17240
17244
  if (prefix === null) return null;
17245
+ const start = parser.index;
17241
17246
  parser.nextToken();
17242
17247
  if (parser.match("<{>")) {
17243
17248
  let body = "";
@@ -17258,17 +17263,48 @@ var ComputeEngineCore = (() => {
17258
17263
  parser.nextToken();
17259
17264
  }
17260
17265
  body += parseSymbolBody(parser);
17261
- if (body === null || !parser.match("<}>")) return null;
17266
+ if (body === null || !parser.match("<}>")) {
17267
+ parser.index = start;
17268
+ return null;
17269
+ }
17262
17270
  if (prefix === "_upright" && body.length > 1) return body;
17263
17271
  return body + prefix;
17264
17272
  }
17273
+ parser.index = start;
17265
17274
  return null;
17266
17275
  }
17267
17276
  function parseInvalidSymbol(parser) {
17268
17277
  const start = parser.index;
17269
17278
  const id = matchPrefixedSymbol(parser);
17270
- if (id === null || isValidSymbol(id)) return null;
17271
- return parser.error(["invalid-symbol", { str: validateSymbol(id) }], start);
17279
+ if (id !== null) {
17280
+ if (isValidSymbol(id)) return null;
17281
+ return parser.error(["invalid-symbol", { str: validateSymbol(id) }], start);
17282
+ }
17283
+ parser.index = start;
17284
+ const prefix = SYMBOL_PREFIX[parser.peek] ?? null;
17285
+ if (prefix === null) return null;
17286
+ parser.nextToken();
17287
+ if (!parser.match("<{>")) {
17288
+ parser.index = start;
17289
+ return null;
17290
+ }
17291
+ const bodyStart = parser.index;
17292
+ let level = 0;
17293
+ while (!parser.atEnd && !(level === 0 && parser.peek === "<}>")) {
17294
+ if (parser.peek === "<{>") level += 1;
17295
+ if (parser.peek === "<}>") level -= 1;
17296
+ parser.nextToken();
17297
+ }
17298
+ const bodyText = parser.latex(bodyStart, parser.index);
17299
+ if (isValidSymbol(bodyText)) {
17300
+ parser.index = start;
17301
+ return null;
17302
+ }
17303
+ parser.match("<}>");
17304
+ return parser.error(
17305
+ ["invalid-symbol", { str: validateSymbol(bodyText) }],
17306
+ start
17307
+ );
17272
17308
  }
17273
17309
  function parseSymbol(parser) {
17274
17310
  if (/^[a-zA-Z]$/.test(parser.peek) || /^\p{XIDS}$/u.test(parser.peek)) {
@@ -18223,18 +18259,12 @@ var ComputeEngineCore = (() => {
18223
18259
  this.index = start;
18224
18260
  return false;
18225
18261
  }
18226
- const matchedToken = this.nextToken();
18227
- const useLatexCommand = matchedToken.startsWith("\\");
18262
+ this.nextToken();
18228
18263
  if (hasBracedDelimiter && !this.match("<}>")) {
18229
18264
  this.index = start;
18230
18265
  return false;
18231
18266
  }
18232
- const closeTokens = DELIMITER_SHORTHAND2[close[0]] ?? [
18233
- close[0]
18234
- ];
18235
- const closeToken = closeTokens.find(
18236
- (t) => useLatexCommand ? t.startsWith("\\") : !t.startsWith("\\")
18237
- ) ?? closeTokens[0];
18267
+ const closeToken = close[0];
18238
18268
  const closeBoundary3 = closePrefix ? hasBracedDelimiter ? [closePrefix, "<{>", closeToken, "<}>"] : [closePrefix, closeToken] : [closeToken];
18239
18269
  this.addBoundary(closeBoundary3);
18240
18270
  return true;
@@ -30731,8 +30761,7 @@ ${lines.join("\n")}`;
30731
30761
  broadcastable: true,
30732
30762
  idempotent: true,
30733
30763
  complexity: 1200,
30734
- signature: "(number) -> number",
30735
- type: ([x]) => x.type,
30764
+ signature: "(number) -> real",
30736
30765
  sgn: ([x]) => {
30737
30766
  if (x.isSame(0)) return "zero";
30738
30767
  if (isNumber(x)) return "positive";
@@ -39630,30 +39659,6 @@ ${e.message}
39630
39659
  "#ae2036",
39631
39660
  "#b40426"
39632
39661
  ];
39633
- var OCEAN_BALANCE = [
39634
- "#00441b",
39635
- "#006d5b",
39636
- "#1a8c7d",
39637
- "#2fa394",
39638
- "#4fb3a3",
39639
- "#6fc1b3",
39640
- "#8dcfc3",
39641
- "#a6dbd1",
39642
- "#bfe6de",
39643
- "#d7f0ea",
39644
- "#f7f7f7",
39645
- "#eeeeee",
39646
- "#ddd8e6",
39647
- "#c7bcda",
39648
- "#b3a0d0",
39649
- "#9f86c7",
39650
- "#8d6dbd",
39651
- "#7b56b1",
39652
- "#6a42a3",
39653
- "#5a3093",
39654
- "#4a1f82",
39655
- "#3b0f70"
39656
- ];
39657
39662
  var reversePalette = (palette) => palette.slice().reverse();
39658
39663
  var DIVERGING_PALETTES = {
39659
39664
  roma: ROMA,
@@ -39665,9 +39670,7 @@ ${e.message}
39665
39670
  rdbu: RDBU,
39666
39671
  "rdbu-reversed": reversePalette(RDBU),
39667
39672
  coolwarm: COOLWARM,
39668
- "coolwarm-reversed": reversePalette(COOLWARM),
39669
- "ocean-balance": OCEAN_BALANCE,
39670
- "ocean-balance-reversed": reversePalette(OCEAN_BALANCE)
39673
+ "coolwarm-reversed": reversePalette(COOLWARM)
39671
39674
  };
39672
39675
  var TURBO = [
39673
39676
  "#30123b",
@@ -41751,6 +41754,40 @@ ${e.message}
41751
41754
  "#eeeeee",
41752
41755
  "#ffffff"
41753
41756
  ];
41757
+ var CMOCEAN_PHASE = [
41758
+ "#a8780d",
41759
+ "#b3701b",
41760
+ "#be6828",
41761
+ "#c75f35",
41762
+ "#cf5643",
41763
+ "#d54b53",
41764
+ "#db4066",
41765
+ "#de357b",
41766
+ "#df2a93",
41767
+ "#dc25ad",
41768
+ "#d529c4",
41769
+ "#cc34d7",
41770
+ "#c041e5",
41771
+ "#b24fef",
41772
+ "#a25cf3",
41773
+ "#9168f4",
41774
+ "#7d73f0",
41775
+ "#687ce8",
41776
+ "#5285dc",
41777
+ "#3d8bcd",
41778
+ "#2c90bc",
41779
+ "#2093ac",
41780
+ "#19959c",
41781
+ "#12978c",
41782
+ "#0c987c",
41783
+ "#119a69",
41784
+ "#249a52",
41785
+ "#409839",
41786
+ "#5e9420",
41787
+ "#778d12",
41788
+ "#8b860d",
41789
+ "#9b7f0d"
41790
+ ];
41754
41791
  var reversePalette2 = (palette) => palette.slice().reverse();
41755
41792
  var SEQUENTIAL_PALETTES = {
41756
41793
  turbo: TURBO,
@@ -41774,7 +41811,9 @@ ${e.message}
41774
41811
  "rocket-reversed": reversePalette2(ROCKET),
41775
41812
  mako: MAKO,
41776
41813
  // blue to teal
41777
- "mako-reversed": reversePalette2(MAKO)
41814
+ "mako-reversed": reversePalette2(MAKO),
41815
+ "cmocean-phase": CMOCEAN_PHASE,
41816
+ "cmocean-phase-reversed": reversePalette2(CMOCEAN_PHASE)
41778
41817
  };
41779
41818
 
41780
41819
  // src/compute-engine/library/colors.ts
@@ -54283,8 +54322,11 @@ Error in definition of "${name}"`,
54283
54322
  for (const local of locals) {
54284
54323
  for (const arg of args) {
54285
54324
  if (isFunction2(arg, "Assign") && isSymbol2(arg.ops[0], local)) {
54286
- if (_BaseCompiler.isComplexValued(arg.ops[1])) {
54325
+ const rhs = arg.ops[1];
54326
+ if (_BaseCompiler.isComplexValued(rhs)) {
54287
54327
  typeHints[local] = isWGSL ? "vec2f" : "vec2";
54328
+ } else if (_BaseCompiler.isIntegerValued(rhs)) {
54329
+ typeHints[local] = isWGSL ? "i32" : "int";
54288
54330
  }
54289
54331
  break;
54290
54332
  }
@@ -54489,12 +54531,9 @@ Error in definition of "${name}"`,
54489
54531
  /**
54490
54532
  * Determine at compile time whether an expression produces a complex value.
54491
54533
  *
54492
- * Rules:
54493
- * - Numbers: complex if im !== 0
54494
- * - Symbols: ImaginaryUnit is complex; others use expr.isReal
54495
- * (undefined is treated as real -- assume-real policy)
54496
- * - Functions: Abs, Arg, Re, Im always return real.
54497
- * All others: complex if any operand is complex.
54534
+ * Uses the expression's declared type (from operator signatures) when
54535
+ * available. Falls back to operand inspection for functions whose
54536
+ * return type is unknown.
54498
54537
  */
54499
54538
  static isComplexValued(expr2) {
54500
54539
  if (isNumber(expr2)) return expr2.im !== 0;
@@ -54505,13 +54544,24 @@ Error in definition of "${name}"`,
54505
54544
  return t.matches("complex") && !t.matches("real");
54506
54545
  }
54507
54546
  if (isFunction2(expr2)) {
54508
- const op = expr2.operator;
54509
- if (op === "Abs" || op === "Arg" || op === "Re" || op === "Im")
54510
- return false;
54547
+ const t = expr2.type;
54548
+ if (t.matches("complex") && !t.matches("real")) return true;
54549
+ if (t.matches("real")) return false;
54511
54550
  return expr2.ops.some((arg) => _BaseCompiler.isComplexValued(arg));
54512
54551
  }
54513
54552
  return false;
54514
54553
  }
54554
+ /** True if the expression is provably integer-typed. */
54555
+ static isIntegerValued(expr2) {
54556
+ if (isNumber(expr2)) return expr2.im === 0 && Number.isInteger(expr2.re);
54557
+ const t = expr2.type;
54558
+ return t ? t.matches("integer") : false;
54559
+ }
54560
+ /** True if the expression is provably non-negative (sign ≥ 0). */
54561
+ static isNonNegative(expr2) {
54562
+ if (isNumber(expr2)) return expr2.im === 0 && expr2.re >= 0;
54563
+ return expr2.isNonNegative === true;
54564
+ }
54515
54565
  /**
54516
54566
  * Generate a temporary variable name
54517
54567
  */
@@ -54765,14 +54815,27 @@ Error in definition of "${name}"`,
54765
54815
  } catch (e) {
54766
54816
  if (options?.fallback ?? true) {
54767
54817
  console.warn(
54768
- `Compilation fallback for "${expr2.operator}": ${e.message}`
54818
+ `Compilation fallback for "${expr2.operator}" (target: ${options?.to ?? "javascript"}): ${e.message}`
54769
54819
  );
54820
+ const ce = expr2.engine;
54821
+ const fallbackRun = ((vars) => {
54822
+ ce.pushScope();
54823
+ try {
54824
+ if (vars && typeof vars === "object") {
54825
+ for (const [k, v] of Object.entries(vars))
54826
+ ce.assign(k, v);
54827
+ }
54828
+ return expr2.evaluate().re;
54829
+ } finally {
54830
+ ce.popScope();
54831
+ }
54832
+ });
54770
54833
  return {
54771
54834
  target: options?.to ?? "javascript",
54772
54835
  success: false,
54773
54836
  code: "",
54774
54837
  calling: "expression",
54775
- run: applicableN1(expr2)
54838
+ run: fallbackRun
54776
54839
  };
54777
54840
  }
54778
54841
  throw e;
@@ -59922,6 +59985,86 @@ Error in definition of "${name}"`,
59922
59985
  for (const symbol2 of Object.values(commonSymbols)) symbol2?.reset();
59923
59986
  }
59924
59987
 
59988
+ // src/compute-engine/compilation/constant-folding.ts
59989
+ function formatFloat(n) {
59990
+ const str = n.toString();
59991
+ if (!str.includes(".") && !str.includes("e") && !str.includes("E")) {
59992
+ return `${str}.0`;
59993
+ }
59994
+ return str;
59995
+ }
59996
+ function tryGetConstant(expr2) {
59997
+ if (!isNumber(expr2)) return void 0;
59998
+ if (expr2.im !== 0) return void 0;
59999
+ const re = expr2.re;
60000
+ if (!isFinite(re)) return void 0;
60001
+ return re;
60002
+ }
60003
+ var NUMERIC_LITERAL_RE = /^-?\d+(\.\d+)?$/;
60004
+ function foldTerms(terms, identity, op) {
60005
+ const identityValue = op === "+" ? 0 : 1;
60006
+ let numericAcc = null;
60007
+ const symbolic = [];
60008
+ for (const term of terms) {
60009
+ if (NUMERIC_LITERAL_RE.test(term)) {
60010
+ const val = parseFloat(term);
60011
+ if (op === "*" && val === 0) return "0.0";
60012
+ if (numericAcc === null) {
60013
+ numericAcc = val;
60014
+ } else {
60015
+ numericAcc = op === "+" ? numericAcc + val : numericAcc * val;
60016
+ }
60017
+ } else {
60018
+ symbolic.push(term);
60019
+ }
60020
+ }
60021
+ if (numericAcc !== null && numericAcc !== identityValue) {
60022
+ symbolic.unshift(formatFloat(numericAcc));
60023
+ }
60024
+ if (symbolic.length === 0) {
60025
+ if (numericAcc !== null) return formatFloat(numericAcc);
60026
+ return identity;
60027
+ }
60028
+ if (symbolic.length === 1) return symbolic[0];
60029
+ return symbolic.join(op === "+" ? " + " : " * ");
60030
+ }
60031
+ function tryGetComplexParts(expr2, compile3) {
60032
+ if (isSymbol2(expr2, "ImaginaryUnit")) {
60033
+ return { re: null, im: "1.0" };
60034
+ }
60035
+ if (isNumber(expr2) && expr2.im !== 0) {
60036
+ const re = expr2.re;
60037
+ const im = expr2.im;
60038
+ return {
60039
+ re: re !== 0 ? formatFloat(re) : null,
60040
+ im: formatFloat(im)
60041
+ };
60042
+ }
60043
+ if (isFunction2(expr2, "Multiply")) {
60044
+ const ops = expr2.ops;
60045
+ const iIndex = ops.findIndex(
60046
+ (op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
60047
+ );
60048
+ if (iIndex >= 0) {
60049
+ const iFactor = ops[iIndex];
60050
+ const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
60051
+ const remaining = ops.filter((_, idx) => idx !== iIndex);
60052
+ if (remaining.length === 0) {
60053
+ return { re: null, im: formatFloat(iScale) };
60054
+ }
60055
+ const compiledFactors = remaining.map((r) => compile3(r));
60056
+ if (iScale !== 1)
60057
+ compiledFactors.unshift(formatFloat(iScale));
60058
+ const imCode = foldTerms(compiledFactors, "1.0", "*");
60059
+ return { re: null, im: imCode };
60060
+ }
60061
+ }
60062
+ if (BaseCompiler.isComplexValued(expr2)) {
60063
+ return null;
60064
+ }
60065
+ return { re: compile3(expr2), im: null };
60066
+ }
60067
+
59925
60068
  // src/compute-engine/compilation/javascript-target.ts
59926
60069
  var JAVASCRIPT_OPERATORS = {
59927
60070
  Add: ["+", 11],
@@ -59945,12 +60088,21 @@ Error in definition of "${name}"`,
59945
60088
  Abs: (args, compile3) => {
59946
60089
  if (BaseCompiler.isComplexValued(args[0]))
59947
60090
  return `_SYS.cabs(${compile3(args[0])})`;
60091
+ if (BaseCompiler.isNonNegative(args[0])) return compile3(args[0]);
59948
60092
  return `Math.abs(${compile3(args[0])})`;
59949
60093
  },
59950
60094
  Add: (args, compile3) => {
59951
60095
  if (args.length === 1) return compile3(args[0]);
59952
60096
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
59953
- if (!anyComplex) return `(${args.map((x) => compile3(x)).join(" + ")})`;
60097
+ if (!anyComplex) {
60098
+ const constants = args.map(tryGetConstant);
60099
+ if (constants.every((c) => c !== void 0))
60100
+ return String(constants.reduce((a, b) => a + b, 0));
60101
+ const nonZero = args.filter((a) => tryGetConstant(a) !== 0);
60102
+ if (nonZero.length === 0) return "0";
60103
+ if (nonZero.length === 1) return compile3(nonZero[0]);
60104
+ return `(${nonZero.map((x) => compile3(x)).join(" + ")})`;
60105
+ }
59954
60106
  const parts = args.map((a) => {
59955
60107
  const code = compile3(a);
59956
60108
  return { code, isComplex: BaseCompiler.isComplexValued(a) };
@@ -60007,7 +60159,10 @@ Error in definition of "${name}"`,
60007
60159
  return `Math.atan(${compile3(args[0])})`;
60008
60160
  },
60009
60161
  Artanh: "Math.atanh",
60010
- Ceil: "Math.ceil",
60162
+ Ceil: (args, compile3) => {
60163
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60164
+ return `Math.ceil(${compile3(args[0])})`;
60165
+ },
60011
60166
  Chop: "_SYS.chop",
60012
60167
  Cos: (args, compile3) => {
60013
60168
  if (BaseCompiler.isComplexValued(args[0]))
@@ -60050,7 +60205,10 @@ Error in definition of "${name}"`,
60050
60205
  return `_SYS.cexp(${compile3(args[0])})`;
60051
60206
  return `Math.exp(${compile3(args[0])})`;
60052
60207
  },
60053
- Floor: "Math.floor",
60208
+ Floor: (args, compile3) => {
60209
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60210
+ return `Math.floor(${compile3(args[0])})`;
60211
+ },
60054
60212
  Fract: ([x], compile3) => {
60055
60213
  if (x === null) throw new Error("Fract: no argument");
60056
60214
  return BaseCompiler.inlineExpression("${x} - Math.floor(${x})", compile3(x));
@@ -60146,12 +60304,20 @@ Error in definition of "${name}"`,
60146
60304
  if (BaseCompiler.isComplexValued(base) || BaseCompiler.isComplexValued(exp3)) {
60147
60305
  return `_SYS.cpow(${compile3(base)}, ${compile3(exp3)})`;
60148
60306
  }
60149
- const expVal = exp3.re;
60150
- if (expVal === 0.5) return `Math.sqrt(${compile3(base)})`;
60151
- if (expVal === 1 / 3) return `Math.cbrt(${compile3(base)})`;
60152
- if (expVal === 1) return compile3(base);
60153
- if (expVal === -1) return `(1 / (${compile3(base)}))`;
60154
- if (expVal === -0.5) return `(1 / Math.sqrt(${compile3(base)}))`;
60307
+ const bConst = tryGetConstant(base);
60308
+ const eConst = tryGetConstant(exp3);
60309
+ if (bConst !== void 0 && eConst !== void 0)
60310
+ return String(Math.pow(bConst, eConst));
60311
+ if (eConst === 0) return "1";
60312
+ if (eConst === 1) return compile3(base);
60313
+ if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
60314
+ const code = compile3(base);
60315
+ return `(${code} * ${code})`;
60316
+ }
60317
+ if (eConst === -1) return `(1 / (${compile3(base)}))`;
60318
+ if (eConst === 0.5) return `Math.sqrt(${compile3(base)})`;
60319
+ if (eConst === 1 / 3) return `Math.cbrt(${compile3(base)})`;
60320
+ if (eConst === -0.5) return `(1 / Math.sqrt(${compile3(base)}))`;
60155
60321
  return `Math.pow(${compile3(base)}, ${compile3(exp3)})`;
60156
60322
  },
60157
60323
  Range: (args, compile3) => {
@@ -60188,16 +60354,29 @@ Error in definition of "${name}"`,
60188
60354
  Root: ([arg, exp3], compile3) => {
60189
60355
  if (arg === null) throw new Error("Root: no argument");
60190
60356
  if (exp3 === null) return `Math.sqrt(${compile3(arg)})`;
60191
- if (exp3?.re === 2) return `Math.sqrt(${compile3(arg)})`;
60192
- if (exp3?.re === 3) return `Math.cbrt(${compile3(arg)})`;
60193
- if (!isNaN(exp3?.re)) return `Math.pow(${compile3(arg)}, ${1 / exp3.re})`;
60357
+ const aConst = tryGetConstant(arg);
60358
+ const nConst = tryGetConstant(exp3);
60359
+ if (aConst !== void 0 && nConst !== void 0 && nConst !== 0)
60360
+ return String(Math.pow(aConst, 1 / nConst));
60361
+ if (nConst === 2) return `Math.sqrt(${compile3(arg)})`;
60362
+ if (nConst === 3) return `Math.cbrt(${compile3(arg)})`;
60363
+ if (nConst !== void 0) return `Math.pow(${compile3(arg)}, ${1 / nConst})`;
60194
60364
  return `Math.pow(${compile3(arg)}, 1 / (${compile3(exp3)}))`;
60195
60365
  },
60196
60366
  Random: "Math.random",
60197
- Round: "Math.round",
60367
+ Round: (args, compile3) => {
60368
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60369
+ return `Math.round(${compile3(args[0])})`;
60370
+ },
60198
60371
  Square: (args, compile3) => {
60199
60372
  const arg = args[0];
60200
60373
  if (arg === null) throw new Error("Square: no argument");
60374
+ const c = tryGetConstant(arg);
60375
+ if (c !== void 0) return String(c * c);
60376
+ if (isSymbol2(arg)) {
60377
+ const code = compile3(arg);
60378
+ return `(${code} * ${code})`;
60379
+ }
60201
60380
  return `Math.pow(${compile3(arg)}, 2)`;
60202
60381
  },
60203
60382
  Sec: (args, compile3) => {
@@ -60230,6 +60409,8 @@ Error in definition of "${name}"`,
60230
60409
  Sqrt: (args, compile3) => {
60231
60410
  if (BaseCompiler.isComplexValued(args[0]))
60232
60411
  return `_SYS.csqrt(${compile3(args[0])})`;
60412
+ const c = tryGetConstant(args[0]);
60413
+ if (c !== void 0) return String(Math.sqrt(c));
60233
60414
  return `Math.sqrt(${compile3(args[0])})`;
60234
60415
  },
60235
60416
  Tan: (args, compile3) => {
@@ -60246,9 +60427,14 @@ Error in definition of "${name}"`,
60246
60427
  if (a === null || b === null) throw new Error("Mod: missing argument");
60247
60428
  const ca = compile3(a);
60248
60429
  const cb = compile3(b);
60430
+ if (BaseCompiler.isIntegerValued(a) && BaseCompiler.isIntegerValued(b) && BaseCompiler.isNonNegative(a))
60431
+ return `(${ca} % ${cb})`;
60249
60432
  return `((${ca} % ${cb}) + ${cb}) % ${cb}`;
60250
60433
  },
60251
- Truncate: "Math.trunc",
60434
+ Truncate: (args, compile3) => {
60435
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
60436
+ return `Math.trunc(${compile3(args[0])})`;
60437
+ },
60252
60438
  Remainder: ([a, b], compile3) => {
60253
60439
  if (a === null || b === null)
60254
60440
  throw new Error("Remainder: missing argument");
@@ -60256,25 +60442,20 @@ Error in definition of "${name}"`,
60256
60442
  a
60257
60443
  )} / ${compile3(b)}))`;
60258
60444
  },
60259
- // Arithmetic operators handled as functions for completeness
60260
- Subtract: ([a, b], compile3) => {
60261
- if (a === null || b === null) throw new Error("Subtract: missing argument");
60262
- const ac = BaseCompiler.isComplexValued(a);
60263
- const bc = BaseCompiler.isComplexValued(b);
60264
- if (!ac && !bc) return `(${compile3(a)} - ${compile3(b)})`;
60265
- const ca = compile3(a);
60266
- const cb = compile3(b);
60267
- const reA = ac ? `(${ca}).re` : ca;
60268
- const imA = ac ? `(${ca}).im` : "0";
60269
- const reB = bc ? `(${cb}).re` : cb;
60270
- const imB = bc ? `(${cb}).im` : "0";
60271
- return `({ re: ${reA} - ${reB}, im: ${imA} - ${imB} })`;
60272
- },
60445
+ // No Subtract function handler Subtract canonicalizes to Add+Negate.
60446
+ // The operator entry in JAVASCRIPT_OPERATORS handles any edge cases.
60273
60447
  Divide: ([a, b], compile3) => {
60274
60448
  if (a === null || b === null) throw new Error("Divide: missing argument");
60275
60449
  const ac = BaseCompiler.isComplexValued(a);
60276
60450
  const bc = BaseCompiler.isComplexValued(b);
60277
- if (!ac && !bc) return `(${compile3(a)} / ${compile3(b)})`;
60451
+ if (!ac && !bc) {
60452
+ const ca = tryGetConstant(a);
60453
+ const cb = tryGetConstant(b);
60454
+ if (ca !== void 0 && cb !== void 0 && cb !== 0)
60455
+ return String(ca / cb);
60456
+ if (cb === 1) return compile3(a);
60457
+ return `(${compile3(a)} / ${compile3(b)})`;
60458
+ }
60278
60459
  if (ac && bc) {
60279
60460
  return `(() => { const _a = ${compile3(a)}, _b = ${compile3(
60280
60461
  b
@@ -60291,13 +60472,26 @@ Error in definition of "${name}"`,
60291
60472
  },
60292
60473
  Negate: ([x], compile3) => {
60293
60474
  if (x === null) throw new Error("Negate: no argument");
60294
- if (!BaseCompiler.isComplexValued(x)) return `(-${compile3(x)})`;
60475
+ if (!BaseCompiler.isComplexValued(x)) {
60476
+ const c = tryGetConstant(x);
60477
+ if (c !== void 0) return String(-c);
60478
+ return `(-${compile3(x)})`;
60479
+ }
60295
60480
  return `_SYS.cneg(${compile3(x)})`;
60296
60481
  },
60297
60482
  Multiply: (args, compile3) => {
60298
60483
  if (args.length === 1) return compile3(args[0]);
60299
60484
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
60300
- if (!anyComplex) return `(${args.map((x) => compile3(x)).join(" * ")})`;
60485
+ if (!anyComplex) {
60486
+ if (args.some((a) => tryGetConstant(a) === 0)) return "0";
60487
+ const constants = args.map(tryGetConstant);
60488
+ if (constants.every((c) => c !== void 0))
60489
+ return String(constants.reduce((a, b) => a * b, 1));
60490
+ const nonOne = args.filter((a) => tryGetConstant(a) !== 1);
60491
+ if (nonOne.length === 0) return "1";
60492
+ if (nonOne.length === 1) return compile3(nonOne[0]);
60493
+ return `(${nonOne.map((x) => compile3(x)).join(" * ")})`;
60494
+ }
60301
60495
  if (args.length === 2) {
60302
60496
  const ac = BaseCompiler.isComplexValued(args[0]);
60303
60497
  const bc = BaseCompiler.isComplexValued(args[1]);
@@ -60382,20 +60576,30 @@ Error in definition of "${name}"`,
60382
60576
  AiryAi: "_SYS.airyAi",
60383
60577
  AiryBi: "_SYS.airyBi",
60384
60578
  // Combinatorics
60579
+ Mandelbrot: ([c, maxIter], compile3) => {
60580
+ if (c === null || maxIter === null)
60581
+ throw new Error("Mandelbrot: missing arguments");
60582
+ return `_SYS.mandelbrot(${compile3(c)}, ${compile3(maxIter)})`;
60583
+ },
60584
+ Julia: ([z, c, maxIter], compile3) => {
60585
+ if (z === null || c === null || maxIter === null)
60586
+ throw new Error("Julia: missing arguments");
60587
+ return `_SYS.julia(${compile3(z)}, ${compile3(c)}, ${compile3(maxIter)})`;
60588
+ },
60385
60589
  Binomial: (args, compile3) => `_SYS.binomial(${compile3(args[0])}, ${compile3(args[1])})`,
60386
60590
  Fibonacci: "_SYS.fibonacci",
60387
60591
  // Complex-specific functions
60388
- Re: (args, compile3) => {
60592
+ Real: (args, compile3) => {
60389
60593
  if (BaseCompiler.isComplexValued(args[0]))
60390
60594
  return `(${compile3(args[0])}).re`;
60391
60595
  return compile3(args[0]);
60392
60596
  },
60393
- Im: (args, compile3) => {
60597
+ Imaginary: (args, compile3) => {
60394
60598
  if (BaseCompiler.isComplexValued(args[0]))
60395
60599
  return `(${compile3(args[0])}).im`;
60396
60600
  return "0";
60397
60601
  },
60398
- Arg: (args, compile3) => {
60602
+ Argument: (args, compile3) => {
60399
60603
  if (BaseCompiler.isComplexValued(args[0]))
60400
60604
  return `_SYS.carg(${compile3(args[0])})`;
60401
60605
  return `(${compile3(args[0])} >= 0 ? 0 : Math.PI)`;
@@ -60731,6 +60935,41 @@ Error in definition of "${name}"`,
60731
60935
  sinc,
60732
60936
  fresnelS,
60733
60937
  fresnelC,
60938
+ mandelbrot: (c, maxIter) => {
60939
+ let zx = 0, zy = 0;
60940
+ const cx = typeof c === "number" ? c : c.re;
60941
+ const cy = typeof c === "number" ? 0 : c.im;
60942
+ const n = Math.round(maxIter);
60943
+ for (let i = 0; i < n; i++) {
60944
+ const newZx = zx * zx - zy * zy + cx;
60945
+ zy = 2 * zx * zy + cy;
60946
+ zx = newZx;
60947
+ const mag2 = zx * zx + zy * zy;
60948
+ if (mag2 > 4) {
60949
+ const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
60950
+ return Math.max(0, Math.min(1, smooth));
60951
+ }
60952
+ }
60953
+ return 1;
60954
+ },
60955
+ julia: (z, c, maxIter) => {
60956
+ let zx = typeof z === "number" ? z : z.re;
60957
+ let zy = typeof z === "number" ? 0 : z.im;
60958
+ const cx = typeof c === "number" ? c : c.re;
60959
+ const cy = typeof c === "number" ? 0 : c.im;
60960
+ const n = Math.round(maxIter);
60961
+ for (let i = 0; i < n; i++) {
60962
+ const newZx = zx * zx - zy * zy + cx;
60963
+ zy = 2 * zx * zy + cy;
60964
+ zx = newZx;
60965
+ const mag2 = zx * zx + zy * zy;
60966
+ if (mag2 > 4) {
60967
+ const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
60968
+ return Math.max(0, Math.min(1, smooth));
60969
+ }
60970
+ }
60971
+ return 1;
60972
+ },
60734
60973
  binomial: choose,
60735
60974
  fibonacci,
60736
60975
  // Complex helpers
@@ -61071,11 +61310,39 @@ Error in definition of "${name}"`,
61071
61310
  return b;
61072
61311
  }
61073
61312
 
61313
+ // src/compute-engine/compilation/fractal-orbit.ts
61314
+ function computeReferenceOrbit(center, maxIter, precision) {
61315
+ const prevPrecision = BigDecimal.precision;
61316
+ BigDecimal.precision = precision;
61317
+ try {
61318
+ const cr = new BigDecimal(center[0]);
61319
+ const ci = new BigDecimal(center[1]);
61320
+ let zr = BigDecimal.ZERO;
61321
+ let zi = BigDecimal.ZERO;
61322
+ const ESCAPE = new BigDecimal(256);
61323
+ const points = [];
61324
+ for (let i = 0; i < maxIter; i++) {
61325
+ points.push(zr.toNumber(), zi.toNumber());
61326
+ const zr2 = zr.mul(zr).toPrecision(precision);
61327
+ const zi2 = zi.mul(zi).toPrecision(precision);
61328
+ const mag2 = zr2.add(zi2);
61329
+ if (mag2.cmp(ESCAPE) > 0) break;
61330
+ const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
61331
+ zr = zr2.sub(zi2).add(cr);
61332
+ zi = new_zi;
61333
+ }
61334
+ return new Float32Array(points);
61335
+ } finally {
61336
+ BigDecimal.precision = prevPrecision;
61337
+ }
61338
+ }
61339
+
61074
61340
  // src/compute-engine/compilation/gpu-target.ts
61075
61341
  var GPU_OPERATORS = {
61076
61342
  Add: ["+", 11],
61077
61343
  Negate: ["-", 14],
61078
61344
  Subtract: ["-", 11],
61345
+ // Subtract canonicalizes to Add+Negate; kept as fallback
61079
61346
  Multiply: ["*", 12],
61080
61347
  Divide: ["/", 13],
61081
61348
  Equal: ["==", 8],
@@ -61091,6 +61358,12 @@ Error in definition of "${name}"`,
61091
61358
  function gpuVec2(target) {
61092
61359
  return target?.language === "wgsl" ? "vec2f" : "vec2";
61093
61360
  }
61361
+ function compileIntArg(expr2, compile3, target) {
61362
+ const c = tryGetConstant(expr2);
61363
+ if (c !== void 0 && Number.isInteger(c)) return c.toString();
61364
+ const intCast = target?.language === "wgsl" ? "i32" : "int";
61365
+ return `${intCast}(${compile3(expr2)})`;
61366
+ }
61094
61367
  var GPU_UNROLL_LIMIT = 100;
61095
61368
  function compileGPUSumProduct(kind, args, _compile2, target) {
61096
61369
  if (!args[0]) throw new Error(`${kind}: no body`);
@@ -61147,94 +61420,126 @@ Error in definition of "${name}"`,
61147
61420
  ];
61148
61421
  return lines.join("\n");
61149
61422
  }
61423
+ function selectFractalStrategy(target) {
61424
+ const radius = target.hints?.viewport?.radius;
61425
+ if (radius === void 0) return "single";
61426
+ if (radius > 1e-6) return "single";
61427
+ if (radius > 1e-14) return "double";
61428
+ return "perturbation";
61429
+ }
61150
61430
  var GPU_FUNCTIONS = {
61151
61431
  // Variadic arithmetic (for function-call form, e.g., with vectors)
61152
61432
  Add: (args, compile3, target) => {
61153
61433
  if (args.length === 0) return "0.0";
61154
61434
  if (args.length === 1) return compile3(args[0]);
61155
61435
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61156
- if (!anyComplex) return args.map((x) => compile3(x)).join(" + ");
61157
- const v2 = gpuVec2(target);
61158
- return args.map((a) => {
61159
- const code = compile3(a);
61160
- return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61161
- }).join(" + ");
61162
- },
61163
- Multiply: (args, compile3, _target) => {
61164
- if (args.length === 0) return "1.0";
61165
- if (args.length === 1) return compile3(args[0]);
61166
- const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61167
- if (!anyComplex) return args.map((x) => compile3(x)).join(" * ");
61168
- let result = compile3(args[0]);
61169
- let resultIsComplex = BaseCompiler.isComplexValued(args[0]);
61170
- for (let i = 1; i < args.length; i++) {
61171
- const code = compile3(args[i]);
61172
- const argIsComplex = BaseCompiler.isComplexValued(args[i]);
61173
- if (!resultIsComplex && !argIsComplex) {
61174
- result = `(${result} * ${code})`;
61175
- } else if (resultIsComplex && !argIsComplex) {
61176
- result = `(${code} * ${result})`;
61177
- } else if (!resultIsComplex && argIsComplex) {
61178
- result = `(${result} * ${code})`;
61179
- resultIsComplex = true;
61180
- } else {
61181
- result = `_gpu_cmul(${result}, ${code})`;
61182
- }
61436
+ if (!anyComplex) {
61437
+ return foldTerms(
61438
+ args.map((x) => compile3(x)),
61439
+ "0.0",
61440
+ "+"
61441
+ );
61183
61442
  }
61184
- return result;
61185
- },
61186
- Subtract: (args, compile3, target) => {
61187
- if (args.length === 0) return "0.0";
61443
+ const parts = args.map((a) => tryGetComplexParts(a, compile3));
61444
+ if (parts.some((p) => p === null)) {
61445
+ const v2 = gpuVec2(target);
61446
+ return args.map((a) => {
61447
+ const code = compile3(a);
61448
+ return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61449
+ }).join(" + ");
61450
+ }
61451
+ const reParts = [];
61452
+ const imParts = [];
61453
+ for (const p of parts) {
61454
+ if (p.re !== null) reParts.push(p.re);
61455
+ if (p.im !== null) imParts.push(p.im);
61456
+ }
61457
+ const reSum = foldTerms(reParts, "0.0", "+");
61458
+ const imSum = foldTerms(imParts, "0.0", "+");
61459
+ return `${gpuVec2(target)}(${reSum}, ${imSum})`;
61460
+ },
61461
+ Multiply: (args, compile3, target) => {
61462
+ if (args.length === 0) return "1.0";
61188
61463
  if (args.length === 1) return compile3(args[0]);
61189
61464
  const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
61190
61465
  if (!anyComplex) {
61191
- if (args.length === 2) return `${compile3(args[0])} - ${compile3(args[1])}`;
61192
- let result2 = compile3(args[0]);
61193
- for (let i = 1; i < args.length; i++) {
61194
- result2 = `${result2} - ${compile3(args[i])}`;
61195
- }
61196
- return result2;
61197
- }
61198
- const v2 = gpuVec2(target);
61199
- const promote = (a) => {
61200
- const code = compile3(a);
61201
- return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
61202
- };
61203
- if (args.length === 2) return `${promote(args[0])} - ${promote(args[1])}`;
61204
- let result = promote(args[0]);
61205
- for (let i = 1; i < args.length; i++) {
61206
- result = `${result} - ${promote(args[i])}`;
61466
+ return foldTerms(
61467
+ args.map((x) => compile3(x)),
61468
+ "1.0",
61469
+ "*"
61470
+ );
61207
61471
  }
61472
+ const iIndex = args.findIndex(
61473
+ (op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
61474
+ );
61475
+ if (iIndex >= 0) {
61476
+ const iFactor = args[iIndex];
61477
+ const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
61478
+ const realFactors = args.filter((_, i) => i !== iIndex);
61479
+ const v2 = gpuVec2(target);
61480
+ if (realFactors.length === 0)
61481
+ return `${v2}(0.0, ${formatFloat(iScale)})`;
61482
+ const factors = realFactors.map((f) => compile3(f));
61483
+ if (iScale !== 1) factors.unshift(formatFloat(iScale));
61484
+ const imCode = foldTerms(factors, "1.0", "*");
61485
+ return `${v2}(0.0, ${imCode})`;
61486
+ }
61487
+ const realCodes = [];
61488
+ const complexCodes = [];
61489
+ for (const a of args) {
61490
+ if (BaseCompiler.isComplexValued(a)) complexCodes.push(compile3(a));
61491
+ else realCodes.push(compile3(a));
61492
+ }
61493
+ const scalarCode = foldTerms(realCodes, "1.0", "*");
61494
+ let result = complexCodes[0];
61495
+ for (let i = 1; i < complexCodes.length; i++) {
61496
+ result = `_gpu_cmul(${result}, ${complexCodes[i]})`;
61497
+ }
61498
+ if (scalarCode !== "1.0") result = `(${scalarCode} * ${result})`;
61208
61499
  return result;
61209
61500
  },
61501
+ // No Subtract function handler — Subtract canonicalizes to Add+Negate.
61502
+ // The operator entry in GPU_OPERATORS handles any edge cases.
61210
61503
  Divide: (args, compile3, target) => {
61211
61504
  if (args.length === 0) return "1.0";
61212
61505
  if (args.length === 1) return compile3(args[0]);
61213
61506
  const ac = BaseCompiler.isComplexValued(args[0]);
61214
61507
  const bc = args.length >= 2 && BaseCompiler.isComplexValued(args[1]);
61215
61508
  if (!ac && !bc) {
61216
- if (args.length === 2) return `${compile3(args[0])} / ${compile3(args[1])}`;
61509
+ if (args.length === 2) {
61510
+ const a = tryGetConstant(args[0]);
61511
+ const b = tryGetConstant(args[1]);
61512
+ if (a !== void 0 && b !== void 0 && b !== 0)
61513
+ return formatFloat(a / b);
61514
+ if (b === 1) return compile3(args[0]);
61515
+ return `${compile3(args[0])} / ${compile3(args[1])}`;
61516
+ }
61217
61517
  let result = compile3(args[0]);
61218
- for (let i = 1; i < args.length; i++) {
61518
+ for (let i = 1; i < args.length; i++)
61219
61519
  result = `${result} / ${compile3(args[i])}`;
61220
- }
61221
61520
  return result;
61222
61521
  }
61223
61522
  if (ac && bc) return `_gpu_cdiv(${compile3(args[0])}, ${compile3(args[1])})`;
61224
- if (ac && !bc) {
61225
- return `(${compile3(args[0])} / ${compile3(args[1])})`;
61226
- }
61523
+ if (ac && !bc) return `(${compile3(args[0])} / ${compile3(args[1])})`;
61227
61524
  const v2 = gpuVec2(target);
61228
61525
  return `_gpu_cdiv(${v2}(${compile3(args[0])}, 0.0), ${compile3(args[1])})`;
61229
61526
  },
61230
- Negate: ([x], compile3) => {
61527
+ Negate: ([x], compile3, target) => {
61231
61528
  if (x === null) throw new Error("Negate: no argument");
61529
+ const c = tryGetConstant(x);
61530
+ if (c !== void 0) return formatFloat(-c);
61531
+ if (isNumber(x) && x.im !== 0) {
61532
+ return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
61533
+ }
61534
+ if (isSymbol2(x, "ImaginaryUnit"))
61535
+ return `${gpuVec2(target)}(0.0, -1.0)`;
61232
61536
  return `(-${compile3(x)})`;
61233
61537
  },
61234
61538
  // Standard math functions with complex dispatch
61235
61539
  Abs: (args, compile3) => {
61236
61540
  if (BaseCompiler.isComplexValued(args[0]))
61237
61541
  return `length(${compile3(args[0])})`;
61542
+ if (BaseCompiler.isNonNegative(args[0])) return compile3(args[0]);
61238
61543
  return `abs(${compile3(args[0])})`;
61239
61544
  },
61240
61545
  Arccos: (args, compile3) => {
@@ -61252,7 +61557,10 @@ Error in definition of "${name}"`,
61252
61557
  return `_gpu_catan(${compile3(args[0])})`;
61253
61558
  return `atan(${compile3(args[0])})`;
61254
61559
  },
61255
- Ceil: "ceil",
61560
+ Ceil: (args, compile3) => {
61561
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61562
+ return `ceil(${compile3(args[0])})`;
61563
+ },
61256
61564
  Clamp: "clamp",
61257
61565
  Cos: (args, compile3) => {
61258
61566
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61266,7 +61574,10 @@ Error in definition of "${name}"`,
61266
61574
  return `exp(${compile3(args[0])})`;
61267
61575
  },
61268
61576
  Exp2: "exp2",
61269
- Floor: "floor",
61577
+ Floor: (args, compile3) => {
61578
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61579
+ return `floor(${compile3(args[0])})`;
61580
+ },
61270
61581
  Fract: "fract",
61271
61582
  Ln: (args, compile3) => {
61272
61583
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61288,10 +61599,25 @@ Error in definition of "${name}"`,
61288
61599
  const eCode = BaseCompiler.isComplexValued(exp3) ? compile3(exp3) : `${v2}(${compile3(exp3)}, 0.0)`;
61289
61600
  return `_gpu_cpow(${bCode}, ${eCode})`;
61290
61601
  }
61602
+ const bConst = tryGetConstant(base);
61603
+ const eConst = tryGetConstant(exp3);
61604
+ if (bConst !== void 0 && eConst !== void 0)
61605
+ return formatFloat(Math.pow(bConst, eConst));
61606
+ if (eConst === 0) return "1.0";
61607
+ if (eConst === 1) return compile3(base);
61608
+ if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
61609
+ const code = compile3(base);
61610
+ return `(${code} * ${code})`;
61611
+ }
61612
+ if (eConst === -1) return `(1.0 / ${compile3(base)})`;
61613
+ if (eConst === 0.5) return `sqrt(${compile3(base)})`;
61291
61614
  return `pow(${compile3(base)}, ${compile3(exp3)})`;
61292
61615
  },
61293
61616
  Radians: "radians",
61294
- Round: "round",
61617
+ Round: (args, compile3) => {
61618
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61619
+ return `round(${compile3(args[0])})`;
61620
+ },
61295
61621
  Sign: "sign",
61296
61622
  Sin: (args, compile3) => {
61297
61623
  if (BaseCompiler.isComplexValued(args[0]))
@@ -61302,6 +61628,8 @@ Error in definition of "${name}"`,
61302
61628
  Sqrt: (args, compile3) => {
61303
61629
  if (BaseCompiler.isComplexValued(args[0]))
61304
61630
  return `_gpu_csqrt(${compile3(args[0])})`;
61631
+ const c = tryGetConstant(args[0]);
61632
+ if (c !== void 0) return formatFloat(Math.sqrt(c));
61305
61633
  return `sqrt(${compile3(args[0])})`;
61306
61634
  },
61307
61635
  Step: "step",
@@ -61310,17 +61638,20 @@ Error in definition of "${name}"`,
61310
61638
  return `_gpu_ctan(${compile3(args[0])})`;
61311
61639
  return `tan(${compile3(args[0])})`;
61312
61640
  },
61313
- Truncate: "trunc",
61641
+ Truncate: (args, compile3) => {
61642
+ if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
61643
+ return `trunc(${compile3(args[0])})`;
61644
+ },
61314
61645
  // Complex-specific functions
61315
- Re: (args, compile3) => {
61646
+ Real: (args, compile3) => {
61316
61647
  if (BaseCompiler.isComplexValued(args[0])) return `(${compile3(args[0])}).x`;
61317
61648
  return compile3(args[0]);
61318
61649
  },
61319
- Im: (args, compile3) => {
61650
+ Imaginary: (args, compile3) => {
61320
61651
  if (BaseCompiler.isComplexValued(args[0])) return `(${compile3(args[0])}).y`;
61321
61652
  return "0.0";
61322
61653
  },
61323
- Arg: (args, compile3) => {
61654
+ Argument: (args, compile3) => {
61324
61655
  if (BaseCompiler.isComplexValued(args[0])) {
61325
61656
  const code = compile3(args[0]);
61326
61657
  return `atan(${code}.y, ${code}.x)`;
@@ -61535,13 +61866,20 @@ Error in definition of "${name}"`,
61535
61866
  },
61536
61867
  Square: ([x], compile3) => {
61537
61868
  if (x === null) throw new Error("Square: no argument");
61538
- const arg = compile3(x);
61539
- return `(${arg} * ${arg})`;
61869
+ if (isSymbol2(x) || isNumber(x)) {
61870
+ const arg = compile3(x);
61871
+ return `(${arg} * ${arg})`;
61872
+ }
61873
+ return `pow(${compile3(x)}, 2.0)`;
61540
61874
  },
61541
61875
  Root: ([x, n], compile3) => {
61542
61876
  if (x === null) throw new Error("Root: no argument");
61543
61877
  if (n === null || n === void 0) return `sqrt(${compile3(x)})`;
61544
- if (n?.re === 2) return `sqrt(${compile3(x)})`;
61878
+ const nConst = tryGetConstant(n);
61879
+ if (nConst === 2) return `sqrt(${compile3(x)})`;
61880
+ const xConst = tryGetConstant(x);
61881
+ if (xConst !== void 0 && nConst !== void 0)
61882
+ return formatFloat(Math.pow(xConst, 1 / nConst));
61545
61883
  return `pow(${compile3(x)}, 1.0 / ${compile3(n)})`;
61546
61884
  },
61547
61885
  // Color functions (pure-math, GPU-compilable)
@@ -61583,18 +61921,34 @@ Error in definition of "${name}"`,
61583
61921
  Mandelbrot: ([c, maxIter], compile3, target) => {
61584
61922
  if (c === null || maxIter === null)
61585
61923
  throw new Error("Mandelbrot: missing arguments");
61586
- const intCast = target?.language === "wgsl" ? "i32" : "int";
61587
- return `_fractal_mandelbrot(${compile3(c)}, ${intCast}(${compile3(
61588
- maxIter
61589
- )}))`;
61924
+ const iterCode = compileIntArg(maxIter, compile3, target);
61925
+ const strategy = selectFractalStrategy(target);
61926
+ if (strategy === "double") {
61927
+ const cCode = compile3(c);
61928
+ return `_fractal_mandelbrot_dp(vec4(${cCode}, vec2(0.0)), ${iterCode})`;
61929
+ }
61930
+ if (strategy === "perturbation") {
61931
+ const cCode = compile3(c);
61932
+ return `_fractal_mandelbrot_pt(${cCode}, ${iterCode})`;
61933
+ }
61934
+ return `_fractal_mandelbrot(${compile3(c)}, ${iterCode})`;
61590
61935
  },
61591
61936
  Julia: ([z, c, maxIter], compile3, target) => {
61592
61937
  if (z === null || c === null || maxIter === null)
61593
61938
  throw new Error("Julia: missing arguments");
61594
- const intCast = target?.language === "wgsl" ? "i32" : "int";
61595
- return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${intCast}(${compile3(
61596
- maxIter
61597
- )}))`;
61939
+ const iterCode = compileIntArg(maxIter, compile3, target);
61940
+ const strategy = selectFractalStrategy(target);
61941
+ if (strategy === "double") {
61942
+ const zCode = compile3(z);
61943
+ const cCode = compile3(c);
61944
+ return `_fractal_julia_dp(vec4(${zCode}, vec2(0.0)), vec4(${cCode}, vec2(0.0)), ${iterCode})`;
61945
+ }
61946
+ if (strategy === "perturbation") {
61947
+ const zCode = compile3(z);
61948
+ const cCode = compile3(c);
61949
+ return `_fractal_julia_pt(${zCode}, ${cCode}, ${iterCode})`;
61950
+ }
61951
+ return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${iterCode})`;
61598
61952
  },
61599
61953
  // Vector/Matrix operations
61600
61954
  Cross: "cross",
@@ -62190,6 +62544,200 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
62190
62544
  for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
62191
62545
  return sgn * vals[n] / norm;
62192
62546
  }
62547
+ `;
62548
+ var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
62549
+ // Split a float into high and low parts for exact multiplication
62550
+ vec2 ds_split(float a) {
62551
+ const float SPLIT = 4097.0; // 2^12 + 1
62552
+ float t = SPLIT * a;
62553
+ float hi = t - (t - a);
62554
+ float lo = a - hi;
62555
+ return vec2(hi, lo);
62556
+ }
62557
+
62558
+ // Create a double-single from a single float
62559
+ vec2 ds_from(float a) {
62560
+ return vec2(a, 0.0);
62561
+ }
62562
+
62563
+ // Error-free addition (Knuth TwoSum)
62564
+ vec2 ds_add(vec2 a, vec2 b) {
62565
+ float s = a.x + b.x;
62566
+ float v = s - a.x;
62567
+ float e = (a.x - (s - v)) + (b.x - v);
62568
+ float lo = (a.y + b.y) + e;
62569
+ float hi = s + lo;
62570
+ lo = lo - (hi - s);
62571
+ return vec2(hi, lo);
62572
+ }
62573
+
62574
+ // Double-single subtraction
62575
+ vec2 ds_sub(vec2 a, vec2 b) {
62576
+ return ds_add(a, vec2(-b.x, -b.y));
62577
+ }
62578
+
62579
+ // Error-free multiplication (Dekker TwoProduct)
62580
+ vec2 ds_mul(vec2 a, vec2 b) {
62581
+ float p = a.x * b.x;
62582
+ vec2 sa = ds_split(a.x);
62583
+ vec2 sb = ds_split(b.x);
62584
+ float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
62585
+ err += a.x * b.y + a.y * b.x;
62586
+ float hi = p + err;
62587
+ float lo = err - (hi - p);
62588
+ return vec2(hi, lo);
62589
+ }
62590
+
62591
+ // Optimized self-multiply
62592
+ vec2 ds_sqr(vec2 a) {
62593
+ float p = a.x * a.x;
62594
+ vec2 sa = ds_split(a.x);
62595
+ float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
62596
+ err += 2.0 * a.x * a.y;
62597
+ float hi = p + err;
62598
+ float lo = err - (hi - p);
62599
+ return vec2(hi, lo);
62600
+ }
62601
+
62602
+ // Compare magnitude: returns -1, 0, or 1
62603
+ float ds_cmp(vec2 a, vec2 b) {
62604
+ float d = a.x - b.x;
62605
+ if (d != 0.0) return sign(d);
62606
+ return sign(a.y - b.y);
62607
+ }
62608
+ `;
62609
+ var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
62610
+ fn ds_split(a: f32) -> vec2f {
62611
+ const SPLIT: f32 = 4097.0;
62612
+ let t = SPLIT * a;
62613
+ let hi = t - (t - a);
62614
+ let lo = a - hi;
62615
+ return vec2f(hi, lo);
62616
+ }
62617
+
62618
+ fn ds_from(a: f32) -> vec2f {
62619
+ return vec2f(a, 0.0);
62620
+ }
62621
+
62622
+ fn ds_add(a: vec2f, b: vec2f) -> vec2f {
62623
+ let s = a.x + b.x;
62624
+ let v = s - a.x;
62625
+ let e = (a.x - (s - v)) + (b.x - v);
62626
+ let lo_t = (a.y + b.y) + e;
62627
+ let hi = s + lo_t;
62628
+ let lo = lo_t - (hi - s);
62629
+ return vec2f(hi, lo);
62630
+ }
62631
+
62632
+ fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
62633
+ return ds_add(a, vec2f(-b.x, -b.y));
62634
+ }
62635
+
62636
+ fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
62637
+ let p = a.x * b.x;
62638
+ let sa = ds_split(a.x);
62639
+ let sb = ds_split(b.x);
62640
+ var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
62641
+ err += a.x * b.y + a.y * b.x;
62642
+ let hi = p + err;
62643
+ let lo = err - (hi - p);
62644
+ return vec2f(hi, lo);
62645
+ }
62646
+
62647
+ fn ds_sqr(a: vec2f) -> vec2f {
62648
+ let p = a.x * a.x;
62649
+ let sa = ds_split(a.x);
62650
+ var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
62651
+ err += 2.0 * a.x * a.y;
62652
+ let hi = p + err;
62653
+ let lo = err - (hi - p);
62654
+ return vec2f(hi, lo);
62655
+ }
62656
+
62657
+ fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
62658
+ let d = a.x - b.x;
62659
+ if (d != 0.0) { return sign(d); }
62660
+ return sign(a.y - b.y);
62661
+ }
62662
+ `;
62663
+ var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
62664
+ float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
62665
+ // c = (re_hi, im_hi, re_lo, im_lo)
62666
+ vec2 cr = vec2(c.x, c.z); // real part as ds
62667
+ vec2 ci = vec2(c.y, c.w); // imag part as ds
62668
+ vec2 zr = vec2(0.0, 0.0);
62669
+ vec2 zi = vec2(0.0, 0.0);
62670
+ for (int i = 0; i < maxIter; i++) {
62671
+ vec2 zr2 = ds_sqr(zr);
62672
+ vec2 zi2 = ds_sqr(zi);
62673
+ // |z|^2 > 4.0 ?
62674
+ vec2 mag2 = ds_add(zr2, zi2);
62675
+ if (mag2.x > 4.0)
62676
+ return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
62677
+ // z = z^2 + c
62678
+ vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
62679
+ zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
62680
+ zi = new_zi;
62681
+ }
62682
+ return 1.0;
62683
+ }
62684
+
62685
+ float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
62686
+ vec2 zr = vec2(z_in.x, z_in.z);
62687
+ vec2 zi = vec2(z_in.y, z_in.w);
62688
+ vec2 cr = vec2(c.x, c.z);
62689
+ vec2 ci = vec2(c.y, c.w);
62690
+ for (int i = 0; i < maxIter; i++) {
62691
+ vec2 zr2 = ds_sqr(zr);
62692
+ vec2 zi2 = ds_sqr(zi);
62693
+ vec2 mag2 = ds_add(zr2, zi2);
62694
+ if (mag2.x > 4.0)
62695
+ return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
62696
+ vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62697
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62698
+ zi = new_zi;
62699
+ }
62700
+ return 1.0;
62701
+ }
62702
+ `;
62703
+ var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
62704
+ fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
62705
+ let cr = vec2f(c.x, c.z);
62706
+ let ci = vec2f(c.y, c.w);
62707
+ var zr = vec2f(0.0, 0.0);
62708
+ var zi = vec2f(0.0, 0.0);
62709
+ for (var i: i32 = 0; i < maxIter; i++) {
62710
+ let zr2 = ds_sqr(zr);
62711
+ let zi2 = ds_sqr(zi);
62712
+ let mag2 = ds_add(zr2, zi2);
62713
+ if (mag2.x > 4.0) {
62714
+ return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
62715
+ }
62716
+ let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62717
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62718
+ zi = new_zi;
62719
+ }
62720
+ return 1.0;
62721
+ }
62722
+
62723
+ fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
62724
+ var zr = vec2f(z_in.x, z_in.z);
62725
+ var zi = vec2f(z_in.y, z_in.w);
62726
+ let cr = vec2f(c.x, c.z);
62727
+ let ci = vec2f(c.y, c.w);
62728
+ for (var i: i32 = 0; i < maxIter; i++) {
62729
+ let zr2 = ds_sqr(zr);
62730
+ let zi2 = ds_sqr(zi);
62731
+ let mag2 = ds_add(zr2, zi2);
62732
+ if (mag2.x > 4.0) {
62733
+ return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
62734
+ }
62735
+ let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
62736
+ zr = ds_add(ds_sub(zr2, zi2), cr);
62737
+ zi = new_zi;
62738
+ }
62739
+ return 1.0;
62740
+ }
62193
62741
  `;
62194
62742
  var GPU_FRACTAL_PREAMBLE_GLSL = `
62195
62743
  float _fractal_mandelbrot(vec2 c, int maxIter) {
@@ -62233,6 +62781,188 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
62233
62781
  }
62234
62782
  return 1.0;
62235
62783
  }
62784
+ `;
62785
+ var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
62786
+ uniform sampler2D _refOrbit;
62787
+ uniform int _refOrbitLen;
62788
+ uniform int _refOrbitTexWidth;
62789
+
62790
+ vec2 _pt_fetch_orbit(int i) {
62791
+ int y = i / _refOrbitTexWidth;
62792
+ int x = i - y * _refOrbitTexWidth;
62793
+ return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
62794
+ }
62795
+
62796
+ float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
62797
+ float dr = 0.0;
62798
+ float di = 0.0;
62799
+ int orbitLen = min(maxIter, _refOrbitLen);
62800
+ for (int i = 0; i < orbitLen; i++) {
62801
+ vec2 Zn = _pt_fetch_orbit(i);
62802
+ // delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
62803
+ float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62804
+ float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62805
+ dr = new_dr;
62806
+ di = new_di;
62807
+ // Full z = Z_{n+1} + delta for escape check
62808
+ vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
62809
+ float zr = Zn1.x + dr;
62810
+ float zi = Zn1.y + di;
62811
+ float mag2 = zr * zr + zi * zi;
62812
+ if (mag2 > 4.0)
62813
+ return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62814
+ // Glitch detection: |delta|^2 > |Z|^2
62815
+ float dmag2 = dr * dr + di * di;
62816
+ float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62817
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62818
+ // Rebase to absolute coordinates and continue with single-float
62819
+ float abs_zr = Zn1.x + dr;
62820
+ float abs_zi = Zn1.y + di;
62821
+ // Reconstruct absolute c from reference + delta
62822
+ // (Use ds_from for the concept, but single-float suffices for fallback)
62823
+ float cx = abs_zr - dr + delta_c.x;
62824
+ float cy = abs_zi - di + delta_c.y;
62825
+ for (int j = i + 1; j < maxIter; j++) {
62826
+ float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
62827
+ abs_zi = 2.0 * abs_zr * abs_zi + cy;
62828
+ abs_zr = new_zr;
62829
+ mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
62830
+ if (mag2 > 4.0)
62831
+ return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62832
+ }
62833
+ return 1.0;
62834
+ }
62835
+ }
62836
+ return 1.0;
62837
+ }
62838
+
62839
+ float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
62840
+ float dr = z_delta.x;
62841
+ float di = z_delta.y;
62842
+ int orbitLen = min(maxIter, _refOrbitLen);
62843
+ for (int i = 0; i < orbitLen; i++) {
62844
+ vec2 Zn = _pt_fetch_orbit(i);
62845
+ float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62846
+ float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62847
+ dr = new_dr;
62848
+ di = new_di;
62849
+ vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
62850
+ float zr = Zn1.x + dr;
62851
+ float zi = Zn1.y + di;
62852
+ float mag2 = zr * zr + zi * zi;
62853
+ if (mag2 > 4.0)
62854
+ return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62855
+ float dmag2 = dr * dr + di * di;
62856
+ float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62857
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62858
+ float abs_zr = Zn1.x + dr;
62859
+ float abs_zi = Zn1.y + di;
62860
+ float cx = delta_c.x;
62861
+ float cy = delta_c.y;
62862
+ for (int j = i + 1; j < maxIter; j++) {
62863
+ float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
62864
+ abs_zi = 2.0 * abs_zr * abs_zi + cy;
62865
+ abs_zr = new_zr;
62866
+ mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
62867
+ if (mag2 > 4.0)
62868
+ return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
62869
+ }
62870
+ return 1.0;
62871
+ }
62872
+ }
62873
+ return 1.0;
62874
+ }
62875
+ `;
62876
+ var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
62877
+ @group(0) @binding(1) var _refOrbit: texture_2d<f32>;
62878
+ var<uniform> _refOrbitLen: i32;
62879
+ var<uniform> _refOrbitTexWidth: i32;
62880
+
62881
+ fn _pt_fetch_orbit(i: i32) -> vec2f {
62882
+ let y = i / _refOrbitTexWidth;
62883
+ let x = i - y * _refOrbitTexWidth;
62884
+ return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
62885
+ }
62886
+
62887
+ fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
62888
+ var dr: f32 = 0.0;
62889
+ var di: f32 = 0.0;
62890
+ let orbitLen = min(maxIter, _refOrbitLen);
62891
+ for (var i: i32 = 0; i < orbitLen; i++) {
62892
+ let Zn = _pt_fetch_orbit(i);
62893
+ let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62894
+ let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62895
+ dr = new_dr;
62896
+ di = new_di;
62897
+ var Zn1 = vec2f(0.0);
62898
+ if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
62899
+ let zr = Zn1.x + dr;
62900
+ let zi = Zn1.y + di;
62901
+ var mag2 = zr * zr + zi * zi;
62902
+ if (mag2 > 4.0) {
62903
+ return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62904
+ }
62905
+ let dmag2 = dr * dr + di * di;
62906
+ let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62907
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62908
+ var f_zr = Zn1.x + dr;
62909
+ var f_zi = Zn1.y + di;
62910
+ let cx = delta_c.x;
62911
+ let cy = delta_c.y;
62912
+ for (var j: i32 = i + 1; j < maxIter; j++) {
62913
+ let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
62914
+ f_zi = 2.0 * f_zr * f_zi + cy;
62915
+ f_zr = t_zr;
62916
+ mag2 = f_zr * f_zr + f_zi * f_zi;
62917
+ if (mag2 > 4.0) {
62918
+ return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62919
+ }
62920
+ }
62921
+ return 1.0;
62922
+ }
62923
+ }
62924
+ return 1.0;
62925
+ }
62926
+
62927
+ fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
62928
+ var dr = z_delta.x;
62929
+ var di = z_delta.y;
62930
+ let orbitLen = min(maxIter, _refOrbitLen);
62931
+ for (var i: i32 = 0; i < orbitLen; i++) {
62932
+ let Zn = _pt_fetch_orbit(i);
62933
+ let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
62934
+ let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
62935
+ dr = new_dr;
62936
+ di = new_di;
62937
+ var Zn1 = vec2f(0.0);
62938
+ if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
62939
+ let zr = Zn1.x + dr;
62940
+ let zi = Zn1.y + di;
62941
+ var mag2 = zr * zr + zi * zi;
62942
+ if (mag2 > 4.0) {
62943
+ return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62944
+ }
62945
+ let dmag2 = dr * dr + di * di;
62946
+ let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
62947
+ if (dmag2 > Zmag2 && Zmag2 > 0.0) {
62948
+ var f_zr = Zn1.x + dr;
62949
+ var f_zi = Zn1.y + di;
62950
+ let cx = delta_c.x;
62951
+ let cy = delta_c.y;
62952
+ for (var j: i32 = i + 1; j < maxIter; j++) {
62953
+ let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
62954
+ f_zi = 2.0 * f_zr * f_zi + cy;
62955
+ f_zr = t_zr;
62956
+ mag2 = f_zr * f_zr + f_zi * f_zi;
62957
+ if (mag2 > 4.0) {
62958
+ return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
62959
+ }
62960
+ }
62961
+ return 1.0;
62962
+ }
62963
+ }
62964
+ return 1.0;
62965
+ }
62236
62966
  `;
62237
62967
  var GPU_COLOR_PREAMBLE_GLSL = `
62238
62968
  float _gpu_srgb_to_linear(float c) {
@@ -62672,6 +63402,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
62672
63402
  const constants = this.getConstants();
62673
63403
  const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
62674
63404
  const target = this.createTarget({
63405
+ hints: options.hints,
62675
63406
  functions: (id) => {
62676
63407
  if (userFunctions && id in userFunctions) {
62677
63408
  const fn = userFunctions[id];
@@ -62710,12 +63441,65 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
62710
63441
  if (code.includes("_gpu_besselJ"))
62711
63442
  preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
62712
63443
  if (code.includes("_fractal_")) {
62713
- preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
63444
+ if (code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) {
63445
+ preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
63446
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
63447
+ } else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
63448
+ preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
63449
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
63450
+ } else {
63451
+ preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
63452
+ }
62714
63453
  }
62715
63454
  if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
62716
63455
  preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
62717
63456
  }
62718
63457
  if (preamble) result.preamble = preamble;
63458
+ if (code.includes("_fractal_") && options.hints?.viewport) {
63459
+ const strategy = selectFractalStrategy(target);
63460
+ const radius = options.hints.viewport.radius;
63461
+ switch (strategy) {
63462
+ case "single":
63463
+ result.staleWhen = { radiusBelow: 1e-6 };
63464
+ break;
63465
+ case "double":
63466
+ result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
63467
+ break;
63468
+ case "perturbation":
63469
+ result.staleWhen = {
63470
+ radiusAbove: 1e-5,
63471
+ radiusBelow: radius * 0.01,
63472
+ centerDistance: radius * 2
63473
+ };
63474
+ break;
63475
+ }
63476
+ }
63477
+ if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
63478
+ const viewport = options.hints.viewport;
63479
+ const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
63480
+ const maxIter = 1e3;
63481
+ const orbit = computeReferenceOrbit(
63482
+ viewport.center,
63483
+ maxIter,
63484
+ digits
63485
+ );
63486
+ const orbitLen = orbit.length / 2;
63487
+ const texWidth = Math.min(orbitLen, 4096);
63488
+ const texHeight = Math.ceil(orbitLen / texWidth);
63489
+ result.textures = {
63490
+ _refOrbit: {
63491
+ data: orbit,
63492
+ width: texWidth,
63493
+ height: texHeight,
63494
+ format: "rg32f"
63495
+ }
63496
+ };
63497
+ result.uniforms = {
63498
+ ...result.uniforms,
63499
+ _refOrbitLen: orbitLen,
63500
+ _refOrbitTexWidth: texWidth
63501
+ };
63502
+ }
62719
63503
  return result;
62720
63504
  }
62721
63505
  compileToSource(expr2, _options = {}) {
@@ -64226,6 +65010,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
64226
65010
  Add: ["_IA.add", 20],
64227
65011
  Negate: ["_IA.negate", 20],
64228
65012
  Subtract: ["_IA.sub", 20],
65013
+ // Subtract canonicalizes to Add+Negate; kept as fallback
64229
65014
  Multiply: ["_IA.mul", 20],
64230
65015
  Divide: ["_IA.div", 20],
64231
65016
  // Comparisons return BoolInterval
@@ -64250,17 +65035,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
64250
65035
  }
64251
65036
  return result;
64252
65037
  },
64253
- Subtract: (args, compile3) => {
64254
- if (args.length === 0) return "_IA.point(0)";
64255
- if (args.length === 1) return `_IA.negate(${compile3(args[0])})`;
64256
- if (args.length === 2)
64257
- return `_IA.sub(${compile3(args[0])}, ${compile3(args[1])})`;
64258
- let result = compile3(args[0]);
64259
- for (let i = 1; i < args.length; i++) {
64260
- result = `_IA.sub(${result}, ${compile3(args[i])})`;
64261
- }
64262
- return result;
64263
- },
65038
+ // No Subtract handler canonicalizes to Add+Negate before compilation.
64264
65039
  Multiply: (args, compile3) => {
64265
65040
  if (args.length === 0) return "_IA.point(1)";
64266
65041
  if (args.length === 1) return compile3(args[0]);
@@ -67234,7 +68009,9 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
67234
68009
  }
67235
68010
  return new ExactNumericValue(value, makeNumericValue);
67236
68011
  }
67237
- throw Error("Unexpected value");
68012
+ throw Error(
68013
+ `Unexpected value: ${typeof value === "object" ? JSON.stringify(value) : String(value)}`
68014
+ );
67238
68015
  }
67239
68016
  /**
67240
68017
  * 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.
@@ -67705,7 +68482,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
67705
68482
  _setDefaultEngineFactory(() => new ComputeEngine());
67706
68483
 
67707
68484
  // src/core.ts
67708
- var version = "0.55.2";
68485
+ var version = "0.55.4";
67709
68486
  return __toCommonJS(core_exports);
67710
68487
  })();
67711
68488
  /*! Bundled license information: