solve-engine 1.0.0-beta.0 → 1.0.0-beta.2

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 (253) hide show
  1. package/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
  2. package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
  3. package/dist/Configuration-fVpd-HC-.d.cts +228 -0
  4. package/dist/Configuration-fVpd-HC-.d.ts +228 -0
  5. package/dist/EngineError-DvPSnhZi.d.cts +304 -0
  6. package/dist/EngineError-DvPSnhZi.d.ts +304 -0
  7. package/dist/Lexer-BJdhlnej.d.cts +531 -0
  8. package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
  9. package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
  10. package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
  11. package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
  12. package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
  13. package/dist/Parselet-CK8cQu2a.d.cts +299 -0
  14. package/dist/Parselet-ConOIdRO.d.ts +299 -0
  15. package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
  16. package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
  17. package/dist/Token-0jpvUdPY.d.cts +245 -0
  18. package/dist/Token-0jpvUdPY.d.ts +245 -0
  19. package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
  20. package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
  21. package/dist/Value-KtAQNHur.d.cts +295 -0
  22. package/dist/Value-KtAQNHur.d.ts +295 -0
  23. package/dist/chunk-2RWAXT6O.js +3 -0
  24. package/dist/chunk-2RWAXT6O.js.map +1 -0
  25. package/dist/chunk-34RRD7PC.js +1492 -0
  26. package/dist/chunk-34RRD7PC.js.map +1 -0
  27. package/dist/chunk-3PPFLFH4.js +5097 -0
  28. package/dist/chunk-3PPFLFH4.js.map +1 -0
  29. package/dist/chunk-3VGDNEE3.js +84 -0
  30. package/dist/chunk-3VGDNEE3.js.map +1 -0
  31. package/dist/chunk-3YNVWKR2.cjs +370 -0
  32. package/dist/chunk-3YNVWKR2.cjs.map +1 -0
  33. package/dist/chunk-47LRVGOT.cjs +316 -0
  34. package/dist/chunk-47LRVGOT.cjs.map +1 -0
  35. package/dist/chunk-4MG4XKO2.js +1644 -0
  36. package/dist/chunk-4MG4XKO2.js.map +1 -0
  37. package/dist/chunk-4QADQTWS.js +2392 -0
  38. package/dist/chunk-4QADQTWS.js.map +1 -0
  39. package/dist/chunk-53B6KDDJ.cjs +1651 -0
  40. package/dist/chunk-53B6KDDJ.cjs.map +1 -0
  41. package/dist/chunk-5X2PTP6F.cjs +104 -0
  42. package/dist/chunk-5X2PTP6F.cjs.map +1 -0
  43. package/dist/chunk-5YEMOYSE.js +264 -0
  44. package/dist/chunk-5YEMOYSE.js.map +1 -0
  45. package/dist/chunk-64W6GLLZ.js +481 -0
  46. package/dist/chunk-64W6GLLZ.js.map +1 -0
  47. package/dist/chunk-6BKTCEUP.cjs +233 -0
  48. package/dist/chunk-6BKTCEUP.cjs.map +1 -0
  49. package/dist/chunk-6NTVRDQV.cjs +1642 -0
  50. package/dist/chunk-6NTVRDQV.cjs.map +1 -0
  51. package/dist/chunk-6RDSQURE.js +290 -0
  52. package/dist/chunk-6RDSQURE.js.map +1 -0
  53. package/dist/chunk-75JP4BZX.js +93 -0
  54. package/dist/chunk-75JP4BZX.js.map +1 -0
  55. package/dist/chunk-B7LXJ6LC.cjs +36 -0
  56. package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
  57. package/dist/chunk-BVAR5J2F.js +257 -0
  58. package/dist/chunk-BVAR5J2F.js.map +1 -0
  59. package/dist/chunk-C4XZV6E7.cjs +269 -0
  60. package/dist/chunk-C4XZV6E7.cjs.map +1 -0
  61. package/dist/chunk-CCJPSHGI.cjs +40 -0
  62. package/dist/chunk-CCJPSHGI.cjs.map +1 -0
  63. package/dist/chunk-CLL7RUQV.cjs +316 -0
  64. package/dist/chunk-CLL7RUQV.cjs.map +1 -0
  65. package/dist/chunk-DM3LMRBC.js +329 -0
  66. package/dist/chunk-DM3LMRBC.js.map +1 -0
  67. package/dist/chunk-DUEZFTK2.js +38 -0
  68. package/dist/chunk-DUEZFTK2.js.map +1 -0
  69. package/dist/chunk-EBSPLUW4.cjs +489 -0
  70. package/dist/chunk-EBSPLUW4.cjs.map +1 -0
  71. package/dist/chunk-EHAHVROS.cjs +261 -0
  72. package/dist/chunk-EHAHVROS.cjs.map +1 -0
  73. package/dist/chunk-EIGTWK5N.js +167 -0
  74. package/dist/chunk-EIGTWK5N.js.map +1 -0
  75. package/dist/chunk-EPOXXJBK.js +96 -0
  76. package/dist/chunk-EPOXXJBK.js.map +1 -0
  77. package/dist/chunk-FEAIOR7N.cjs +91 -0
  78. package/dist/chunk-FEAIOR7N.cjs.map +1 -0
  79. package/dist/chunk-G535KJEG.js +312 -0
  80. package/dist/chunk-G535KJEG.js.map +1 -0
  81. package/dist/chunk-GCM5JHMX.js +88 -0
  82. package/dist/chunk-GCM5JHMX.js.map +1 -0
  83. package/dist/chunk-GOLDJNMZ.js +368 -0
  84. package/dist/chunk-GOLDJNMZ.js.map +1 -0
  85. package/dist/chunk-GW32KPCU.cjs +360 -0
  86. package/dist/chunk-GW32KPCU.cjs.map +1 -0
  87. package/dist/chunk-HTXVVJRA.cjs +1549 -0
  88. package/dist/chunk-HTXVVJRA.cjs.map +1 -0
  89. package/dist/chunk-HWSZJQCI.js +311 -0
  90. package/dist/chunk-HWSZJQCI.js.map +1 -0
  91. package/dist/chunk-IF532O7C.js +101 -0
  92. package/dist/chunk-IF532O7C.js.map +1 -0
  93. package/dist/chunk-J73SJHR3.cjs +2415 -0
  94. package/dist/chunk-J73SJHR3.cjs.map +1 -0
  95. package/dist/chunk-JBSYC7BB.cjs +7473 -0
  96. package/dist/chunk-JBSYC7BB.cjs.map +1 -0
  97. package/dist/chunk-KVILKGMS.js +228 -0
  98. package/dist/chunk-KVILKGMS.js.map +1 -0
  99. package/dist/chunk-LIPPNDBE.js +258 -0
  100. package/dist/chunk-LIPPNDBE.js.map +1 -0
  101. package/dist/chunk-LR7YASZF.cjs +172 -0
  102. package/dist/chunk-LR7YASZF.cjs.map +1 -0
  103. package/dist/chunk-M4N5GA5Z.cjs +309 -0
  104. package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
  105. package/dist/chunk-M5LX5AOO.js +7459 -0
  106. package/dist/chunk-M5LX5AOO.js.map +1 -0
  107. package/dist/chunk-MZOVP3WI.cjs +96 -0
  108. package/dist/chunk-MZOVP3WI.cjs.map +1 -0
  109. package/dist/chunk-N5YFR4UP.cjs +10 -0
  110. package/dist/chunk-N5YFR4UP.cjs.map +1 -0
  111. package/dist/chunk-NGBBNL4K.cjs +4 -0
  112. package/dist/chunk-NGBBNL4K.cjs.map +1 -0
  113. package/dist/chunk-NH2O2AUR.js +146 -0
  114. package/dist/chunk-NH2O2AUR.js.map +1 -0
  115. package/dist/chunk-NLNDMWZC.js +31 -0
  116. package/dist/chunk-NLNDMWZC.js.map +1 -0
  117. package/dist/chunk-NMCRQP3Z.cjs +778 -0
  118. package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
  119. package/dist/chunk-NMD5VRN4.cjs +1327 -0
  120. package/dist/chunk-NMD5VRN4.cjs.map +1 -0
  121. package/dist/chunk-OC6LTXYS.cjs +286 -0
  122. package/dist/chunk-OC6LTXYS.cjs.map +1 -0
  123. package/dist/chunk-OT6OJY7C.cjs +114 -0
  124. package/dist/chunk-OT6OJY7C.cjs.map +1 -0
  125. package/dist/chunk-PFSDGGYL.js +8 -0
  126. package/dist/chunk-PFSDGGYL.js.map +1 -0
  127. package/dist/chunk-QNJ4ACRT.cjs +155 -0
  128. package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
  129. package/dist/chunk-QWY3VEZN.js +1637 -0
  130. package/dist/chunk-QWY3VEZN.js.map +1 -0
  131. package/dist/chunk-RFYD5TJE.js +111 -0
  132. package/dist/chunk-RFYD5TJE.js.map +1 -0
  133. package/dist/chunk-RIN643A3.js +354 -0
  134. package/dist/chunk-RIN643A3.js.map +1 -0
  135. package/dist/chunk-RZCWSXTA.cjs +5122 -0
  136. package/dist/chunk-RZCWSXTA.cjs.map +1 -0
  137. package/dist/chunk-SDGRK7EP.js +774 -0
  138. package/dist/chunk-SDGRK7EP.js.map +1 -0
  139. package/dist/chunk-VEKIWQ3F.cjs +39 -0
  140. package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
  141. package/dist/chunk-WQTTOGXC.cjs +99 -0
  142. package/dist/chunk-WQTTOGXC.cjs.map +1 -0
  143. package/dist/chunk-X6K3HUOY.cjs +86 -0
  144. package/dist/chunk-X6K3HUOY.cjs.map +1 -0
  145. package/dist/chunk-XJCMXB2E.cjs +333 -0
  146. package/dist/chunk-XJCMXB2E.cjs.map +1 -0
  147. package/dist/chunk-XVWCOTR6.js +1324 -0
  148. package/dist/chunk-XVWCOTR6.js.map +1 -0
  149. package/dist/chunk-YLJ4XMA6.js +33 -0
  150. package/dist/chunk-YLJ4XMA6.js.map +1 -0
  151. package/dist/chunk-Z2XP767T.cjs +35 -0
  152. package/dist/chunk-Z2XP767T.cjs.map +1 -0
  153. package/dist/chunk-Z4X2RWOF.js +37 -0
  154. package/dist/chunk-Z4X2RWOF.js.map +1 -0
  155. package/dist/constants.cjs +22 -0
  156. package/dist/constants.cjs.map +1 -0
  157. package/dist/constants.d.cts +12 -0
  158. package/dist/constants.d.ts +12 -0
  159. package/dist/constants.js +5 -0
  160. package/dist/constants.js.map +1 -0
  161. package/dist/engine.cjs +79 -0
  162. package/dist/engine.cjs.map +1 -0
  163. package/dist/engine.d.cts +587 -0
  164. package/dist/engine.d.ts +587 -0
  165. package/dist/engine.js +34 -0
  166. package/dist/engine.js.map +1 -0
  167. package/dist/errors.cjs +81 -0
  168. package/dist/errors.cjs.map +1 -0
  169. package/dist/errors.d.cts +95 -0
  170. package/dist/errors.d.ts +95 -0
  171. package/dist/errors.js +4 -0
  172. package/dist/errors.js.map +1 -0
  173. package/dist/format.cjs +171 -0
  174. package/dist/format.cjs.map +1 -0
  175. package/dist/format.d.cts +51 -0
  176. package/dist/format.d.ts +51 -0
  177. package/dist/format.js +168 -0
  178. package/dist/format.js.map +1 -0
  179. package/dist/index.cjs +97 -0
  180. package/dist/index.cjs.map +1 -0
  181. package/dist/index.d.cts +152 -0
  182. package/dist/index.d.ts +152 -0
  183. package/dist/index.js +75 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/language.cjs +308 -0
  186. package/dist/language.cjs.map +1 -0
  187. package/dist/language.d.cts +110 -0
  188. package/dist/language.d.ts +110 -0
  189. package/dist/language.js +287 -0
  190. package/dist/language.js.map +1 -0
  191. package/dist/lexer.cjs +64 -0
  192. package/dist/lexer.cjs.map +1 -0
  193. package/dist/lexer.d.cts +56 -0
  194. package/dist/lexer.d.ts +56 -0
  195. package/dist/lexer.js +11 -0
  196. package/dist/lexer.js.map +1 -0
  197. package/dist/normalizer.cjs +40 -0
  198. package/dist/normalizer.cjs.map +1 -0
  199. package/dist/normalizer.d.cts +364 -0
  200. package/dist/normalizer.d.ts +364 -0
  201. package/dist/normalizer.js +11 -0
  202. package/dist/normalizer.js.map +1 -0
  203. package/dist/packages.cjs +121 -0
  204. package/dist/packages.cjs.map +1 -0
  205. package/dist/packages.d.cts +691 -0
  206. package/dist/packages.d.ts +691 -0
  207. package/dist/packages.js +24 -0
  208. package/dist/packages.js.map +1 -0
  209. package/dist/parser.cjs +55 -0
  210. package/dist/parser.cjs.map +1 -0
  211. package/dist/parser.d.cts +46 -0
  212. package/dist/parser.d.ts +46 -0
  213. package/dist/parser.js +10 -0
  214. package/dist/parser.js.map +1 -0
  215. package/dist/pipeline-CrsRPmsv.d.ts +285 -0
  216. package/dist/pipeline-DPUQt7yL.d.cts +285 -0
  217. package/dist/resolvers.cjs +13 -0
  218. package/dist/resolvers.cjs.map +1 -0
  219. package/dist/resolvers.d.cts +111 -0
  220. package/dist/resolvers.d.ts +111 -0
  221. package/dist/resolvers.js +4 -0
  222. package/dist/resolvers.js.map +1 -0
  223. package/dist/services.cjs +21 -0
  224. package/dist/services.cjs.map +1 -0
  225. package/dist/services.d.cts +30 -0
  226. package/dist/services.d.ts +30 -0
  227. package/dist/services.js +4 -0
  228. package/dist/services.js.map +1 -0
  229. package/dist/uom.cjs +56 -0
  230. package/dist/uom.cjs.map +1 -0
  231. package/dist/uom.d.cts +224 -0
  232. package/dist/uom.d.ts +224 -0
  233. package/dist/uom.js +11 -0
  234. package/dist/uom.js.map +1 -0
  235. package/dist/utilities.cjs +32 -0
  236. package/dist/utilities.cjs.map +1 -0
  237. package/dist/utilities.d.cts +113 -0
  238. package/dist/utilities.d.ts +113 -0
  239. package/dist/utilities.js +7 -0
  240. package/dist/utilities.js.map +1 -0
  241. package/dist/variables.cjs +17 -0
  242. package/dist/variables.cjs.map +1 -0
  243. package/dist/variables.d.cts +87 -0
  244. package/dist/variables.d.ts +87 -0
  245. package/dist/variables.js +4 -0
  246. package/dist/variables.js.map +1 -0
  247. package/dist/vm.cjs +284 -0
  248. package/dist/vm.cjs.map +1 -0
  249. package/dist/vm.d.cts +68 -0
  250. package/dist/vm.d.ts +68 -0
  251. package/dist/vm.js +194 -0
  252. package/dist/vm.js.map +1 -0
  253. package/package.json +4 -4
@@ -0,0 +1,2415 @@
1
+ 'use strict';
2
+
3
+ var chunkFEAIOR7N_cjs = require('./chunk-FEAIOR7N.cjs');
4
+ var chunkXJCMXB2E_cjs = require('./chunk-XJCMXB2E.cjs');
5
+ var chunkHTXVVJRA_cjs = require('./chunk-HTXVVJRA.cjs');
6
+ var chunkOC6LTXYS_cjs = require('./chunk-OC6LTXYS.cjs');
7
+ var chunkQNJ4ACRT_cjs = require('./chunk-QNJ4ACRT.cjs');
8
+ var chunkM4N5GA5Z_cjs = require('./chunk-M4N5GA5Z.cjs');
9
+
10
+ // src/symbolic/MultivariateFactor.ts
11
+ function exactRoot(value, degree) {
12
+ const rootOf = degree === 2 ? chunkHTXVVJRA_cjs.exactIntegerSqrt : chunkHTXVVJRA_cjs.exactIntegerCbrt;
13
+ const numerator = rootOf(value.n);
14
+ const denominator = rootOf(value.d);
15
+ return numerator === null || denominator === null ? null : { n: numerator, d: denominator };
16
+ }
17
+ function monomialRoot(key, degree) {
18
+ const monomial = chunkHTXVVJRA_cjs.monomialFromKey(key);
19
+ const root = /* @__PURE__ */ new Map();
20
+ for (const [name, exponent] of monomial) {
21
+ if (exponent % degree !== 0) return null;
22
+ root.set(name, exponent / degree);
23
+ }
24
+ return chunkHTXVVJRA_cjs.monomialToKey(root);
25
+ }
26
+ function monomialMul(a, b) {
27
+ const product2 = chunkHTXVVJRA_cjs.monomialFromKey(a);
28
+ for (const [name, exponent] of chunkHTXVVJRA_cjs.monomialFromKey(b)) {
29
+ product2.set(name, (product2.get(name) ?? 0) + exponent);
30
+ }
31
+ return chunkHTXVVJRA_cjs.monomialToKey(product2);
32
+ }
33
+ function monomialDiv(a, b) {
34
+ const quotient = chunkHTXVVJRA_cjs.monomialFromKey(a);
35
+ for (const [name, exponent] of chunkHTXVVJRA_cjs.monomialFromKey(b)) {
36
+ const remaining = (quotient.get(name) ?? 0) - exponent;
37
+ if (remaining <= 0) quotient.delete(name);
38
+ else quotient.set(name, remaining);
39
+ }
40
+ return chunkHTXVVJRA_cjs.monomialToKey(quotient);
41
+ }
42
+ function monomialGcd(a, b) {
43
+ const left = chunkHTXVVJRA_cjs.monomialFromKey(a);
44
+ const shared = /* @__PURE__ */ new Map();
45
+ for (const [name, exponent] of chunkHTXVVJRA_cjs.monomialFromKey(b)) {
46
+ const other = left.get(name);
47
+ if (other !== void 0) shared.set(name, Math.min(other, exponent));
48
+ }
49
+ return chunkHTXVVJRA_cjs.monomialToKey(shared);
50
+ }
51
+ function namesOf(keys) {
52
+ const names = /* @__PURE__ */ new Set();
53
+ for (const key of keys) for (const name of chunkHTXVVJRA_cjs.monomialFromKey(key).keys()) names.add(name);
54
+ return [...names].sort();
55
+ }
56
+ function termsToNode(terms) {
57
+ const map = /* @__PURE__ */ new Map();
58
+ for (const term of terms) map.set(term.key, term.coefficient);
59
+ return chunkHTXVVJRA_cjs.fromPolynomial({ terms: map, vars: namesOf(terms.map((term) => term.key)) });
60
+ }
61
+ function product(factors) {
62
+ let result = factors[0];
63
+ for (let i = 1; i < factors.length; i++) result = { kind: "mul", left: result, right: factors[i] };
64
+ return result;
65
+ }
66
+ function orderedTerms(p) {
67
+ const terms = [...p.terms].map(([key, coefficient]) => ({ key, coefficient }));
68
+ return terms.sort((a, b) => chunkHTXVVJRA_cjs.compareMonomials(a.key, b.key, p.vars));
69
+ }
70
+ function factorMultivariate(p) {
71
+ if (p.vars.length < 2) return null;
72
+ const terms = orderedTerms(p);
73
+ if (terms.length === 2) return factorBinomial(terms[0], terms[1]);
74
+ if (terms.length === 3) return factorPerfectSquare(terms);
75
+ if (terms.length === 4) return factorByGrouping(terms);
76
+ return null;
77
+ }
78
+ function factorBinomial(first, second) {
79
+ const firstPositive = first.coefficient.n > 0n;
80
+ const secondPositive = second.coefficient.n > 0n;
81
+ if (!firstPositive) return null;
82
+ const squares = asPowerPair(first, second, 2);
83
+ if (squares !== null && !secondPositive) {
84
+ return product([
85
+ termsToNode([squares.a, negated(squares.b)]),
86
+ termsToNode([squares.a, squares.b])
87
+ ]);
88
+ }
89
+ const cubes = asPowerPair(first, second, 3);
90
+ if (cubes === null) return null;
91
+ const linear = secondPositive ? termsToNode([cubes.a, cubes.b]) : termsToNode([cubes.a, negated(cubes.b)]);
92
+ const middle = secondPositive ? negated(multiplyTerms(cubes.a, cubes.b)) : multiplyTerms(cubes.a, cubes.b);
93
+ return product([linear, termsToNode([squareOf(cubes.a), middle, squareOf(cubes.b)])]);
94
+ }
95
+ function asPowerPair(first, second, degree) {
96
+ const magnitude = second.coefficient.n < 0n ? chunkHTXVVJRA_cjs.rationalNeg(second.coefficient) : second.coefficient;
97
+ const firstRoot = exactRoot(first.coefficient, degree);
98
+ const secondRoot = exactRoot(magnitude, degree);
99
+ if (firstRoot === null || secondRoot === null) return null;
100
+ const firstKey = monomialRoot(first.key, degree);
101
+ const secondKey = monomialRoot(second.key, degree);
102
+ if (firstKey === null || secondKey === null) return null;
103
+ return { a: { key: firstKey, coefficient: firstRoot }, b: { key: secondKey, coefficient: secondRoot } };
104
+ }
105
+ function negated(term) {
106
+ return { key: term.key, coefficient: chunkHTXVVJRA_cjs.rationalNeg(term.coefficient) };
107
+ }
108
+ function multiplyTerms(a, b) {
109
+ return { key: monomialMul(a.key, b.key), coefficient: chunkHTXVVJRA_cjs.rationalMul(a.coefficient, b.coefficient) };
110
+ }
111
+ function squareOf(term) {
112
+ return multiplyTerms(term, term);
113
+ }
114
+ function factorPerfectSquare(terms) {
115
+ const [first, middle, last] = terms;
116
+ if (first.coefficient.n < 0n || last.coefficient.n < 0n) return null;
117
+ const roots = asPowerPair(first, last, 2);
118
+ if (roots === null) return null;
119
+ const cross = multiplyTerms(roots.a, roots.b);
120
+ if (cross.key !== middle.key) return null;
121
+ const twice = chunkHTXVVJRA_cjs.rationalMul(cross.coefficient, { n: 2n, d: 1n });
122
+ const negative = middle.coefficient.n < 0n;
123
+ const magnitude = negative ? chunkHTXVVJRA_cjs.rationalNeg(middle.coefficient) : middle.coefficient;
124
+ if (!chunkHTXVVJRA_cjs.isRationalOne(chunkHTXVVJRA_cjs.rationalDiv(magnitude, twice))) return null;
125
+ const base = termsToNode([roots.a, negative ? negated(roots.b) : roots.b]);
126
+ return { kind: "pow", base, exponent: chunkHTXVVJRA_cjs.constNode(2) };
127
+ }
128
+ function factorByGrouping(terms) {
129
+ const pairings = [
130
+ [[0, 1], [2, 3]],
131
+ [[0, 2], [1, 3]],
132
+ [[0, 3], [1, 2]]
133
+ ];
134
+ for (const pairing of pairings) {
135
+ const first = splitPair(terms[pairing[0][0]], terms[pairing[0][1]]);
136
+ const second = splitPair(terms[pairing[1][0]], terms[pairing[1][1]]);
137
+ if (first === null || second === null) continue;
138
+ if (!cofactorsAgree(first.cofactor, second.cofactor)) continue;
139
+ return product([
140
+ termsToNode([first.common, second.common]),
141
+ termsToNode(first.cofactor)
142
+ ]);
143
+ }
144
+ return null;
145
+ }
146
+ function splitPair(first, second) {
147
+ const shared = monomialGcd(first.key, second.key);
148
+ const common = { key: shared, coefficient: first.coefficient };
149
+ const cofactor = [
150
+ { key: monomialDiv(first.key, shared), coefficient: { n: 1n, d: 1n } },
151
+ { key: monomialDiv(second.key, shared), coefficient: chunkHTXVVJRA_cjs.rationalDiv(second.coefficient, first.coefficient) }
152
+ ];
153
+ return cofactor[0].key === cofactor[1].key ? null : { common, cofactor };
154
+ }
155
+ function cofactorsAgree(a, b) {
156
+ if (a.length !== b.length) return false;
157
+ return a.every((term, index) => term.key === b[index].key && term.coefficient.n === b[index].coefficient.n && term.coefficient.d === b[index].coefficient.d);
158
+ }
159
+
160
+ // src/symbolic/Factor.ts
161
+ var FACTOR_MAX_DEGREE = 12;
162
+ var FACTOR_MAX_ROOT_CANDIDATES = 4096;
163
+ function gcd(a, b) {
164
+ let x = a < 0n ? -a : a;
165
+ let y = b < 0n ? -b : b;
166
+ while (y !== 0n) {
167
+ const remainder = x % y;
168
+ x = y;
169
+ y = remainder;
170
+ }
171
+ return x;
172
+ }
173
+ function lcm(a, b) {
174
+ if (a === 0n || b === 0n) return 0n;
175
+ return a / gcd(a, b) * b;
176
+ }
177
+ function divisors(value) {
178
+ const magnitude = value < 0n ? -value : value;
179
+ if (magnitude === 0n) return null;
180
+ const found = [];
181
+ for (let candidate = 1n; candidate * candidate <= magnitude; candidate++) {
182
+ if (magnitude % candidate !== 0n) continue;
183
+ found.push(candidate);
184
+ const paired = magnitude / candidate;
185
+ if (paired !== candidate) found.push(paired);
186
+ if (found.length > FACTOR_MAX_ROOT_CANDIDATES) return null;
187
+ }
188
+ return found;
189
+ }
190
+ function evaluateAt(descending, x) {
191
+ let total = chunkHTXVVJRA_cjs.RATIONAL_ZERO;
192
+ for (const coeff of descending) total = chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalMul(total, x), coeff);
193
+ return total;
194
+ }
195
+ function divideByRoot(descending, root) {
196
+ const quotient = [descending[0]];
197
+ for (let i = 1; i < descending.length - 1; i++) {
198
+ quotient.push(chunkHTXVVJRA_cjs.rationalAdd(descending[i], chunkHTXVVJRA_cjs.rationalMul(quotient[i - 1], root)));
199
+ }
200
+ return quotient;
201
+ }
202
+ function rationalRoots(descending) {
203
+ if (descending.length < 2) return [];
204
+ let multiplier = 1n;
205
+ for (const coeff of descending) multiplier = lcm(multiplier, coeff.d);
206
+ const integers = descending.map((coeff) => coeff.n * multiplier / coeff.d);
207
+ const leading = integers[0];
208
+ const trailing = integers[integers.length - 1];
209
+ if (trailing === 0n) return [];
210
+ const numeratorDivisors = divisors(trailing);
211
+ const denominatorDivisors = divisors(leading);
212
+ if (numeratorDivisors === null || denominatorDivisors === null) {
213
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
214
+ "SYMBOLIC_FACTOR_LIMIT_EXCEEDED",
215
+ "This polynomial's coefficients have too many divisors to search for rational roots.",
216
+ { limit: FACTOR_MAX_ROOT_CANDIDATES }
217
+ );
218
+ }
219
+ if (numeratorDivisors.length * denominatorDivisors.length > FACTOR_MAX_ROOT_CANDIDATES) {
220
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
221
+ "SYMBOLIC_FACTOR_LIMIT_EXCEEDED",
222
+ "This polynomial has too many candidate rational roots to test.",
223
+ { limit: FACTOR_MAX_ROOT_CANDIDATES }
224
+ );
225
+ }
226
+ const roots = [];
227
+ const seen = /* @__PURE__ */ new Set();
228
+ for (const p of numeratorDivisors) {
229
+ for (const q of denominatorDivisors) {
230
+ for (const sign of [1n, -1n]) {
231
+ const candidate = { n: sign * p / gcd(p, q), d: q / gcd(p, q) };
232
+ const key = `${candidate.n}/${candidate.d}`;
233
+ if (seen.has(key)) continue;
234
+ seen.add(key);
235
+ if (chunkHTXVVJRA_cjs.isRationalZero(evaluateAt(descending, candidate))) roots.push(candidate);
236
+ }
237
+ }
238
+ }
239
+ return roots;
240
+ }
241
+ function linearFactorNode(variable, root) {
242
+ if (chunkHTXVVJRA_cjs.isRationalZero(root)) return chunkHTXVVJRA_cjs.varNode(variable);
243
+ return root.n > 0n ? { kind: "sub", left: chunkHTXVVJRA_cjs.varNode(variable), right: chunkHTXVVJRA_cjs.constNode(root) } : { kind: "add", left: chunkHTXVVJRA_cjs.varNode(variable), right: chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalNeg(root)) };
244
+ }
245
+ function coefficientsToNode(descending, variable) {
246
+ const degree = descending.length - 1;
247
+ const terms = /* @__PURE__ */ new Map();
248
+ descending.forEach((coeff, index) => {
249
+ if (chunkHTXVVJRA_cjs.isRationalZero(coeff)) return;
250
+ const power2 = degree - index;
251
+ terms.set(power2 === 0 ? "" : power2 === 1 ? variable : `${variable}^${power2}`, coeff);
252
+ });
253
+ return chunkHTXVVJRA_cjs.fromPolynomial({ terms, vars: terms.size > 0 ? [variable] : [] });
254
+ }
255
+ function factorUnivariate(descending, variable) {
256
+ const factors = [];
257
+ let remaining = [...descending];
258
+ let roots = rationalRoots(remaining);
259
+ while (roots.length > 0 && remaining.length > 2) {
260
+ for (const root of roots) {
261
+ let multiplicity = 0;
262
+ while (remaining.length > 1 && chunkHTXVVJRA_cjs.isRationalZero(evaluateAt(remaining, root))) {
263
+ remaining = divideByRoot(remaining, root);
264
+ multiplicity++;
265
+ }
266
+ if (multiplicity > 0) factors.push({ base: linearFactorNode(variable, root), power: multiplicity });
267
+ }
268
+ roots = remaining.length > 2 ? rationalRoots(remaining) : [];
269
+ }
270
+ const leftoverDegree = remaining.length - 1;
271
+ if (leftoverDegree >= 1) {
272
+ factors.push({ base: coefficientsToNode(remaining, variable), power: 1 });
273
+ return { content: chunkHTXVVJRA_cjs.RATIONAL_ONE, factors };
274
+ }
275
+ return { content: remaining.length === 1 ? remaining[0] : chunkHTXVVJRA_cjs.RATIONAL_ONE, factors };
276
+ }
277
+ function factorizationToNode(factorization) {
278
+ const pieces = [];
279
+ if (!chunkHTXVVJRA_cjs.isRationalOne(factorization.content)) pieces.push(chunkHTXVVJRA_cjs.constNode(factorization.content));
280
+ for (const factor of factorization.factors) {
281
+ pieces.push(factor.power === 1 ? factor.base : chunkHTXVVJRA_cjs.powNode(factor.base, chunkHTXVVJRA_cjs.constNode({ n: BigInt(factor.power), d: 1n })));
282
+ }
283
+ if (pieces.length === 0) return chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ONE);
284
+ let result = pieces[0];
285
+ for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
286
+ return result;
287
+ }
288
+ function contentOf(p) {
289
+ let numeratorGcd = 0n;
290
+ let denominatorLcm = 1n;
291
+ for (const coeff of p.terms.values()) {
292
+ numeratorGcd = gcd(numeratorGcd, coeff.n);
293
+ denominatorLcm = lcm(denominatorLcm, coeff.d);
294
+ }
295
+ if (numeratorGcd === 0n) return chunkHTXVVJRA_cjs.RATIONAL_ONE;
296
+ return { n: numeratorGcd, d: denominatorLcm };
297
+ }
298
+ function extractCommonMonomial(p) {
299
+ const common = /* @__PURE__ */ new Map();
300
+ for (const name of p.vars) {
301
+ let lowest = Infinity;
302
+ for (const key of p.terms.keys()) {
303
+ const exponent = exponentOf(key, name);
304
+ if (exponent < lowest) lowest = exponent;
305
+ }
306
+ if (lowest > 0 && lowest !== Infinity) common.set(name, lowest);
307
+ }
308
+ if (common.size === 0) return { monomial: common, reduced: p };
309
+ const terms = /* @__PURE__ */ new Map();
310
+ for (const [key, coeff] of p.terms) {
311
+ const exponents = parseKey(key);
312
+ for (const [name, shared] of common) exponents.set(name, (exponents.get(name) ?? 0) - shared);
313
+ terms.set(buildKey(exponents), coeff);
314
+ }
315
+ const names = /* @__PURE__ */ new Set();
316
+ for (const key of terms.keys()) for (const name of parseKey(key).keys()) names.add(name);
317
+ return { monomial: common, reduced: { terms, vars: [...names].sort() } };
318
+ }
319
+ function exponentOf(key, name) {
320
+ return parseKey(key).get(name) ?? 0;
321
+ }
322
+ function parseKey(key) {
323
+ const exponents = /* @__PURE__ */ new Map();
324
+ if (key === "") return exponents;
325
+ for (const factor of key.split("*")) {
326
+ const caret = factor.indexOf("^");
327
+ if (caret === -1) exponents.set(factor, 1);
328
+ else exponents.set(factor.slice(0, caret), Number(factor.slice(caret + 1)));
329
+ }
330
+ return exponents;
331
+ }
332
+ function buildKey(exponents) {
333
+ const names = [...exponents.keys()].filter((name) => (exponents.get(name) ?? 0) > 0).sort();
334
+ return names.map((name) => exponents.get(name) === 1 ? name : `${name}^${exponents.get(name)}`).join("*");
335
+ }
336
+ function monomialNode(monomial) {
337
+ const names = [...monomial.keys()].sort();
338
+ let result = null;
339
+ for (const name of names) {
340
+ const exponent = monomial.get(name);
341
+ const factor = exponent === 1 ? chunkHTXVVJRA_cjs.varNode(name) : chunkHTXVVJRA_cjs.powNode(chunkHTXVVJRA_cjs.varNode(name), chunkHTXVVJRA_cjs.constNode({ n: BigInt(exponent), d: 1n }));
342
+ result = result === null ? factor : { kind: "mul", left: result, right: factor };
343
+ }
344
+ return result;
345
+ }
346
+ function factorSymbolic(node) {
347
+ const polynomial = chunkHTXVVJRA_cjs.toPolynomial(node);
348
+ if (polynomial === null || polynomial.terms.size === 0) return node;
349
+ if (chunkHTXVVJRA_cjs.polyDegree(polynomial) > FACTOR_MAX_DEGREE) return node;
350
+ if (polynomial.vars.length === 0) return node;
351
+ const content = contentOf(polynomial);
352
+ const primitive = chunkHTXVVJRA_cjs.isRationalOne(content) ? polynomial : scaleTerms(polynomial, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.RATIONAL_ONE, content));
353
+ const { monomial, reduced } = extractCommonMonomial(primitive);
354
+ const monomialFactor = monomialNode(monomial);
355
+ const variable = chunkHTXVVJRA_cjs.polyUnivariateVar(reduced);
356
+ if (variable === null) {
357
+ const patterned = factorMultivariate(reduced);
358
+ if (patterned !== null) return assemble(content, monomialFactor, patterned);
359
+ const pieces2 = buildPieces(content, monomialFactor, reduced);
360
+ return pieces2 ?? node;
361
+ }
362
+ const descending = [...chunkHTXVVJRA_cjs.polyCoefficients(reduced, variable)].reverse();
363
+ const factorization = factorUnivariate(descending, variable);
364
+ const combinedContent = chunkHTXVVJRA_cjs.rationalMul(content, factorization.content);
365
+ const isUnchanged = factorization.factors.length <= 1 && (factorization.factors[0]?.power ?? 1) === 1 && monomialFactor === null && chunkHTXVVJRA_cjs.isRationalOne(combinedContent);
366
+ if (isUnchanged) return node;
367
+ const pieces = [];
368
+ if (!chunkHTXVVJRA_cjs.isRationalOne(combinedContent)) pieces.push(chunkHTXVVJRA_cjs.constNode(combinedContent));
369
+ if (monomialFactor !== null) pieces.push(monomialFactor);
370
+ pieces.push(factorizationToNode({ content: chunkHTXVVJRA_cjs.RATIONAL_ONE, factors: factorization.factors }));
371
+ let result = pieces[0];
372
+ for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
373
+ return result;
374
+ }
375
+ function scaleTerms(p, k) {
376
+ const terms = /* @__PURE__ */ new Map();
377
+ for (const [key, coeff] of p.terms) terms.set(key, chunkHTXVVJRA_cjs.rationalMul(coeff, k));
378
+ return { terms, vars: p.vars };
379
+ }
380
+ function assemble(content, monomialFactor, factored) {
381
+ const pieces = [];
382
+ if (!chunkHTXVVJRA_cjs.isRationalOne(content)) pieces.push(chunkHTXVVJRA_cjs.constNode(content));
383
+ if (monomialFactor !== null) pieces.push(monomialFactor);
384
+ pieces.push(factored);
385
+ let result = pieces[0];
386
+ for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
387
+ return result;
388
+ }
389
+ function buildPieces(content, monomialFactor, reduced) {
390
+ if (monomialFactor === null && chunkHTXVVJRA_cjs.isRationalOne(content)) return null;
391
+ const pieces = [];
392
+ if (!chunkHTXVVJRA_cjs.isRationalOne(content)) pieces.push(chunkHTXVVJRA_cjs.constNode(content));
393
+ if (monomialFactor !== null) pieces.push(monomialFactor);
394
+ pieces.push(chunkHTXVVJRA_cjs.fromPolynomial(reduced));
395
+ let result = pieces[0];
396
+ for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
397
+ return result;
398
+ }
399
+
400
+ // src/symbolic/CubicQuartic.ts
401
+ var TWO = { n: 2n, d: 1n };
402
+ var THREE = { n: 3n, d: 1n };
403
+ var FOUR = { n: 4n, d: 1n };
404
+ function depressCubic(a, b, c, d) {
405
+ const shift = chunkHTXVVJRA_cjs.rationalNeg(chunkHTXVVJRA_cjs.rationalDiv(b, chunkHTXVVJRA_cjs.rationalMul(THREE, a)));
406
+ const p = chunkHTXVVJRA_cjs.rationalDiv(
407
+ chunkHTXVVJRA_cjs.rationalSub(chunkHTXVVJRA_cjs.rationalMul(THREE, chunkHTXVVJRA_cjs.rationalMul(a, c)), chunkHTXVVJRA_cjs.rationalMul(b, b)),
408
+ chunkHTXVVJRA_cjs.rationalMul(THREE, chunkHTXVVJRA_cjs.rationalMul(a, a))
409
+ );
410
+ const twoBCubed = chunkHTXVVJRA_cjs.rationalMul(TWO, chunkHTXVVJRA_cjs.rationalMul(b, chunkHTXVVJRA_cjs.rationalMul(b, b)));
411
+ const nineABC = chunkHTXVVJRA_cjs.rationalMul({ n: 9n, d: 1n }, chunkHTXVVJRA_cjs.rationalMul(a, chunkHTXVVJRA_cjs.rationalMul(b, c)));
412
+ const twentySevenAAD = chunkHTXVVJRA_cjs.rationalMul({ n: 27n, d: 1n }, chunkHTXVVJRA_cjs.rationalMul(chunkHTXVVJRA_cjs.rationalMul(a, a), d));
413
+ const q = chunkHTXVVJRA_cjs.rationalDiv(
414
+ chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalSub(twoBCubed, nineABC), twentySevenAAD),
415
+ chunkHTXVVJRA_cjs.rationalMul({ n: 27n, d: 1n }, chunkHTXVVJRA_cjs.rationalMul(a, chunkHTXVVJRA_cjs.rationalMul(a, a)))
416
+ );
417
+ return { p, q, shift };
418
+ }
419
+ function solveCubic(a, b, c, d) {
420
+ const { p, q, shift } = depressCubic(a, b, c, d);
421
+ const discriminant = chunkHTXVVJRA_cjs.rationalNeg(
422
+ chunkHTXVVJRA_cjs.rationalAdd(
423
+ chunkHTXVVJRA_cjs.rationalMul(FOUR, chunkHTXVVJRA_cjs.rationalMul(p, chunkHTXVVJRA_cjs.rationalMul(p, p))),
424
+ chunkHTXVVJRA_cjs.rationalMul({ n: 27n, d: 1n }, chunkHTXVVJRA_cjs.rationalMul(q, q))
425
+ )
426
+ );
427
+ if (chunkHTXVVJRA_cjs.rationalCompare(discriminant, chunkHTXVVJRA_cjs.RATIONAL_ZERO) > 0) {
428
+ return { exact: [], approximate: trigonometricRoots(p, q, shift) };
429
+ }
430
+ if (chunkHTXVVJRA_cjs.isRationalZero(discriminant)) return { exact: repeatedCubicRoots(p, q, shift), approximate: [] };
431
+ return { exact: cardanoRoots(p, q, shift), approximate: [] };
432
+ }
433
+ function repeatedCubicRoots(p, q, shift) {
434
+ if (chunkHTXVVJRA_cjs.isRationalZero(p)) return [chunkHTXVVJRA_cjs.constNode(shift)];
435
+ const simple = chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(THREE, q), p), shift);
436
+ const repeated = chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalNeg(chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(THREE, q), chunkHTXVVJRA_cjs.rationalMul(TWO, p))), shift);
437
+ const ordered = [simple, repeated].sort(chunkHTXVVJRA_cjs.rationalCompare);
438
+ return ordered.map(chunkHTXVVJRA_cjs.constNode);
439
+ }
440
+ function cardanoRoots(p, q, shift) {
441
+ const half = chunkHTXVVJRA_cjs.rationalNeg(chunkHTXVVJRA_cjs.rationalDiv(q, TWO));
442
+ const radicand = chunkHTXVVJRA_cjs.rationalAdd(
443
+ chunkHTXVVJRA_cjs.rationalMul(chunkHTXVVJRA_cjs.rationalDiv(q, TWO), chunkHTXVVJRA_cjs.rationalDiv(q, TWO)),
444
+ chunkHTXVVJRA_cjs.rationalMul(chunkHTXVVJRA_cjs.rationalDiv(p, THREE), chunkHTXVVJRA_cjs.rationalMul(chunkHTXVVJRA_cjs.rationalDiv(p, THREE), chunkHTXVVJRA_cjs.rationalDiv(p, THREE)))
445
+ );
446
+ const inner = chunkHTXVVJRA_cjs.surdNode(radicand);
447
+ const u = { kind: "call", name: "cbrt", args: [{ kind: "add", left: chunkHTXVVJRA_cjs.constNode(half), right: inner }] };
448
+ const v = { kind: "call", name: "cbrt", args: [{ kind: "sub", left: chunkHTXVVJRA_cjs.constNode(half), right: inner }] };
449
+ const sum = { kind: "add", left: u, right: v };
450
+ const difference = { kind: "sub", left: u, right: v };
451
+ const real = { kind: "add", left: chunkHTXVVJRA_cjs.constNode(shift), right: { kind: "div", left: { kind: "neg", operand: sum }, right: chunkHTXVVJRA_cjs.constNode(TWO) } };
452
+ const imaginary = {
453
+ kind: "mul",
454
+ left: { kind: "div", left: { kind: "mul", left: difference, right: chunkHTXVVJRA_cjs.surdNode(THREE) }, right: chunkHTXVVJRA_cjs.constNode(TWO) },
455
+ right: chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.COMPLEX_I)
456
+ };
457
+ return [
458
+ { kind: "add", left: chunkHTXVVJRA_cjs.constNode(shift), right: sum },
459
+ { kind: "sub", left: real, right: imaginary },
460
+ { kind: "add", left: real, right: imaginary }
461
+ ];
462
+ }
463
+ function trigonometricRoots(p, q, shift) {
464
+ const pNumber = chunkHTXVVJRA_cjs.rationalToNumber(p);
465
+ const qNumber = chunkHTXVVJRA_cjs.rationalToNumber(q);
466
+ const shiftNumber = chunkHTXVVJRA_cjs.rationalToNumber(shift);
467
+ const magnitude = 2 * Math.sqrt(-pNumber / 3);
468
+ const ratio = 3 * qNumber / (2 * pNumber) * Math.sqrt(-3 / pNumber);
469
+ const angle = Math.acos(Math.min(1, Math.max(-1, ratio))) / 3;
470
+ return [0, 1, 2].map((k) => magnitude * Math.cos(angle - 2 * Math.PI * k / 3) + shiftNumber).sort((left, right) => left - right);
471
+ }
472
+ function depressQuartic(b, c, d, e) {
473
+ const shift = chunkHTXVVJRA_cjs.rationalNeg(chunkHTXVVJRA_cjs.rationalDiv(b, FOUR));
474
+ const bb = chunkHTXVVJRA_cjs.rationalMul(b, b);
475
+ const p = chunkHTXVVJRA_cjs.rationalSub(c, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(THREE, bb), { n: 8n, d: 1n }));
476
+ const q = chunkHTXVVJRA_cjs.rationalAdd(
477
+ chunkHTXVVJRA_cjs.rationalSub(d, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(b, c), TWO)),
478
+ chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(bb, b), { n: 8n, d: 1n })
479
+ );
480
+ const r = chunkHTXVVJRA_cjs.rationalSub(
481
+ chunkHTXVVJRA_cjs.rationalAdd(
482
+ chunkHTXVVJRA_cjs.rationalSub(e, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(b, d), FOUR)),
483
+ chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(bb, c), { n: 16n, d: 1n })
484
+ ),
485
+ chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalMul(THREE, chunkHTXVVJRA_cjs.rationalMul(bb, bb)), { n: 256n, d: 1n })
486
+ );
487
+ return { p, q, r, shift };
488
+ }
489
+ function solveQuartic(a, b, c, d, e, solveQuadratic2) {
490
+ const monic = (value) => chunkHTXVVJRA_cjs.rationalDiv(value, a);
491
+ const { p, q, r, shift } = depressQuartic(monic(b), monic(c), monic(d), monic(e));
492
+ const roots = chunkHTXVVJRA_cjs.isRationalZero(q) ? biquadraticRoots(p, r) : splitQuarticRoots(p, q, r, solveQuadratic2);
493
+ if (roots === null) return null;
494
+ const shifted = chunkHTXVVJRA_cjs.isRationalZero(shift) ? roots : roots.map((root) => ({ kind: "add", left: chunkHTXVVJRA_cjs.constNode(shift), right: root }));
495
+ return { exact: distinct(shifted), approximate: [] };
496
+ }
497
+ function distinct(roots) {
498
+ const seen = /* @__PURE__ */ new Set();
499
+ const unique = [];
500
+ for (const root of roots) {
501
+ const key = chunkHTXVVJRA_cjs.symbolicKey(chunkHTXVVJRA_cjs.simplifySymbolic(root));
502
+ if (seen.has(key)) continue;
503
+ seen.add(key);
504
+ unique.push(root);
505
+ }
506
+ return unique;
507
+ }
508
+ function biquadraticRoots(p, r) {
509
+ const discriminant = chunkHTXVVJRA_cjs.rationalSub(chunkHTXVVJRA_cjs.rationalMul(p, p), chunkHTXVVJRA_cjs.rationalMul(FOUR, r));
510
+ if (chunkHTXVVJRA_cjs.rationalCompare(discriminant, chunkHTXVVJRA_cjs.RATIONAL_ZERO) < 0) return complexBiquadraticRoots(p, r);
511
+ const root = chunkHTXVVJRA_cjs.exactRationalSqrt(discriminant);
512
+ if (root !== null) return rationalSquareRoots(chunkHTXVVJRA_cjs.rationalNeg(p), root, chunkHTXVVJRA_cjs.isRationalZero(discriminant));
513
+ return nestedSquareRoots(p, r, discriminant);
514
+ }
515
+ function rationalSquareRoots(negatedP, root, repeated) {
516
+ const values = repeated ? [chunkHTXVVJRA_cjs.rationalDiv(negatedP, TWO)] : [chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalAdd(negatedP, root), TWO), chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalSub(negatedP, root), TWO)];
517
+ const roots = [];
518
+ for (const value of values) {
519
+ if (chunkHTXVVJRA_cjs.isRationalZero(value)) {
520
+ roots.push(chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ZERO));
521
+ continue;
522
+ }
523
+ const square = chunkHTXVVJRA_cjs.signedSurdNode(value);
524
+ roots.push({ kind: "neg", operand: square }, square);
525
+ }
526
+ return roots;
527
+ }
528
+ function nestedSquareRoots(p, r, discriminant) {
529
+ const negatedP = chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalNeg(p));
530
+ const surd = chunkHTXVVJRA_cjs.surdNode(discriminant);
531
+ const negativeP = chunkHTXVVJRA_cjs.rationalCompare(p, chunkHTXVVJRA_cjs.RATIONAL_ZERO) <= 0;
532
+ const solutions = [
533
+ { node: halved({ kind: "add", left: negatedP, right: surd }), positive: negativeP || chunkHTXVVJRA_cjs.rationalCompare(r, chunkHTXVVJRA_cjs.RATIONAL_ZERO) <= 0 },
534
+ { node: halved({ kind: "sub", left: negatedP, right: surd }), positive: negativeP && chunkHTXVVJRA_cjs.rationalCompare(r, chunkHTXVVJRA_cjs.RATIONAL_ZERO) >= 0 }
535
+ ];
536
+ const roots = [];
537
+ for (const { node, positive } of solutions) {
538
+ const radicand = positive ? node : { kind: "neg", operand: node };
539
+ const magnitude = { kind: "call", name: "sqrt", args: [radicand] };
540
+ const square = positive ? magnitude : { kind: "mul", left: magnitude, right: chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.COMPLEX_I) };
541
+ roots.push({ kind: "neg", operand: square }, square);
542
+ }
543
+ return roots;
544
+ }
545
+ function halved(node) {
546
+ return { kind: "div", left: node, right: chunkHTXVVJRA_cjs.constNode(TWO) };
547
+ }
548
+ function complexBiquadraticRoots(p, r) {
549
+ const modulus = chunkHTXVVJRA_cjs.exactRationalSqrt(r);
550
+ if (modulus === null) return null;
551
+ const realPart = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalAdd(modulus, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalNeg(p), TWO)), TWO);
552
+ const imaginaryPart = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalSub(modulus, chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalNeg(p), TWO)), TWO);
553
+ if (chunkHTXVVJRA_cjs.rationalCompare(realPart, chunkHTXVVJRA_cjs.RATIONAL_ZERO) < 0 || chunkHTXVVJRA_cjs.rationalCompare(imaginaryPart, chunkHTXVVJRA_cjs.RATIONAL_ZERO) < 0) return null;
554
+ const re = chunkHTXVVJRA_cjs.surdNode(realPart);
555
+ const im = { kind: "mul", left: chunkHTXVVJRA_cjs.surdNode(imaginaryPart), right: chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.COMPLEX_I) };
556
+ const first = { kind: "add", left: re, right: im };
557
+ const second = { kind: "sub", left: re, right: im };
558
+ return [
559
+ { kind: "neg", operand: first },
560
+ { kind: "neg", operand: second },
561
+ second,
562
+ first
563
+ ];
564
+ }
565
+ function splitQuarticRoots(p, q, r, solveQuadratic2) {
566
+ const resolvent = [
567
+ { n: 1n, d: 1n },
568
+ chunkHTXVVJRA_cjs.rationalMul(TWO, p),
569
+ chunkHTXVVJRA_cjs.rationalSub(chunkHTXVVJRA_cjs.rationalMul(p, p), chunkHTXVVJRA_cjs.rationalMul(FOUR, r)),
570
+ chunkHTXVVJRA_cjs.rationalNeg(chunkHTXVVJRA_cjs.rationalMul(q, q))
571
+ ];
572
+ for (const z of rationalRoots(resolvent)) {
573
+ if (chunkHTXVVJRA_cjs.rationalCompare(z, chunkHTXVVJRA_cjs.RATIONAL_ZERO) <= 0) continue;
574
+ const alpha = chunkHTXVVJRA_cjs.exactRationalSqrt(z);
575
+ if (alpha === null) continue;
576
+ const sum = chunkHTXVVJRA_cjs.rationalAdd(p, z);
577
+ const difference = chunkHTXVVJRA_cjs.rationalDiv(q, alpha);
578
+ const beta = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalSub(sum, difference), TWO);
579
+ const gamma = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalAdd(sum, difference), TWO);
580
+ const one2 = { n: 1n, d: 1n };
581
+ return [
582
+ ...solveQuadratic2(one2, alpha, beta),
583
+ ...solveQuadratic2(one2, chunkHTXVVJRA_cjs.rationalNeg(alpha), gamma)
584
+ ];
585
+ }
586
+ return null;
587
+ }
588
+
589
+ // src/symbolic/Solve.ts
590
+ var SOLVE_MAX_DEGREE = 8;
591
+ var NEWTON_MAX_ITERATIONS = 100;
592
+ var NEWTON_TOLERANCE = 1e-12;
593
+ var NUMERIC_SCAN_STEPS = 2e3;
594
+ function evaluateRational(descending, x) {
595
+ let total = chunkHTXVVJRA_cjs.RATIONAL_ZERO;
596
+ for (const coeff of descending) total = chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalMul(total, x), coeff);
597
+ return total;
598
+ }
599
+ function evaluateNumeric(descending, x) {
600
+ let total = 0;
601
+ for (const coeff of descending) total = total * x + chunkHTXVVJRA_cjs.rationalToNumber(coeff);
602
+ return total;
603
+ }
604
+ function divideByRoot2(descending, root) {
605
+ const quotient = [descending[0]];
606
+ for (let i = 1; i < descending.length - 1; i++) {
607
+ quotient.push(chunkHTXVVJRA_cjs.rationalAdd(descending[i], chunkHTXVVJRA_cjs.rationalMul(quotient[i - 1], root)));
608
+ }
609
+ return quotient;
610
+ }
611
+ function solveQuadratic(a, b, c) {
612
+ const discriminant = chunkHTXVVJRA_cjs.rationalSub(chunkHTXVVJRA_cjs.rationalMul(b, b), chunkHTXVVJRA_cjs.rationalMul(rational4(), chunkHTXVVJRA_cjs.rationalMul(a, c)));
613
+ const twoA = chunkHTXVVJRA_cjs.rationalMul(rational2(), a);
614
+ if (chunkHTXVVJRA_cjs.rationalCompare(discriminant, chunkHTXVVJRA_cjs.RATIONAL_ZERO) < 0) {
615
+ return complexQuadraticRoots(chunkHTXVVJRA_cjs.rationalNeg(b), discriminant, twoA);
616
+ }
617
+ if (chunkHTXVVJRA_cjs.isRationalZero(discriminant)) return [chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalNeg(b), twoA))];
618
+ const rootN = chunkHTXVVJRA_cjs.exactIntegerSqrt(discriminant.n);
619
+ const rootD = chunkHTXVVJRA_cjs.exactIntegerSqrt(discriminant.d);
620
+ if (rootN !== null && rootD !== null) {
621
+ const root = { n: rootN, d: rootD };
622
+ const plus = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalAdd(chunkHTXVVJRA_cjs.rationalNeg(b), root), twoA);
623
+ const minus = chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalSub(chunkHTXVVJRA_cjs.rationalNeg(b), root), twoA);
624
+ return chunkHTXVVJRA_cjs.rationalCompare(minus, plus) <= 0 ? [chunkHTXVVJRA_cjs.constNode(minus), chunkHTXVVJRA_cjs.constNode(plus)] : [chunkHTXVVJRA_cjs.constNode(plus), chunkHTXVVJRA_cjs.constNode(minus)];
625
+ }
626
+ const surd = chunkHTXVVJRA_cjs.surdNode(discriminant);
627
+ const ascending = chunkHTXVVJRA_cjs.rationalCompare(twoA, chunkHTXVVJRA_cjs.RATIONAL_ZERO) > 0;
628
+ const lower = { kind: "div", left: { kind: "sub", left: chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalNeg(b)), right: surd }, right: chunkHTXVVJRA_cjs.constNode(twoA) };
629
+ const upper = { kind: "div", left: { kind: "add", left: chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalNeg(b)), right: surd }, right: chunkHTXVVJRA_cjs.constNode(twoA) };
630
+ return ascending ? [lower, upper] : [upper, lower];
631
+ }
632
+ function complexQuadraticRoots(negatedB, discriminant, twoA) {
633
+ const magnitude = chunkHTXVVJRA_cjs.rationalNeg(discriminant);
634
+ const rootN = chunkHTXVVJRA_cjs.exactIntegerSqrt(magnitude.n);
635
+ const rootD = chunkHTXVVJRA_cjs.exactIntegerSqrt(magnitude.d);
636
+ if (rootN !== null && rootD !== null) {
637
+ const imaginary2 = chunkHTXVVJRA_cjs.rationalDiv({ n: rootN, d: rootD }, twoA);
638
+ const real2 = chunkHTXVVJRA_cjs.rationalDiv(negatedB, twoA);
639
+ return [
640
+ chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.complex(real2, chunkHTXVVJRA_cjs.rationalNeg(imaginary2))),
641
+ chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.complex(real2, imaginary2))
642
+ ];
643
+ }
644
+ const real = chunkHTXVVJRA_cjs.rationalDiv(negatedB, twoA);
645
+ const scaledRadicand = chunkHTXVVJRA_cjs.rationalDiv(magnitude, chunkHTXVVJRA_cjs.rationalMul(twoA, twoA));
646
+ const imaginary = { kind: "mul", left: chunkHTXVVJRA_cjs.surdNode(scaledRadicand), right: chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.COMPLEX_I) };
647
+ if (chunkHTXVVJRA_cjs.isRationalZero(real)) {
648
+ return [{ kind: "neg", operand: imaginary }, imaginary];
649
+ }
650
+ return [
651
+ { kind: "sub", left: chunkHTXVVJRA_cjs.constNode(real), right: imaginary },
652
+ { kind: "add", left: chunkHTXVVJRA_cjs.constNode(real), right: imaginary }
653
+ ];
654
+ }
655
+ function rational2() {
656
+ return { n: 2n, d: 1n };
657
+ }
658
+ function rational4() {
659
+ return { n: 4n, d: 1n };
660
+ }
661
+ function numericRoots(descending) {
662
+ const leading = chunkHTXVVJRA_cjs.rationalToNumber(descending[0]);
663
+ if (leading === 0) return [];
664
+ let bound = 0;
665
+ for (let i = 1; i < descending.length; i++) {
666
+ const ratio = Math.abs(chunkHTXVVJRA_cjs.rationalToNumber(descending[i]) / leading);
667
+ if (ratio > bound) bound = ratio;
668
+ }
669
+ bound += 1;
670
+ const roots = [];
671
+ const step = 2 * bound / NUMERIC_SCAN_STEPS;
672
+ let previousX = -bound;
673
+ let previousY = evaluateNumeric(descending, previousX);
674
+ for (let i = 1; i <= NUMERIC_SCAN_STEPS; i++) {
675
+ const x = -bound + i * step;
676
+ const y = evaluateNumeric(descending, x);
677
+ if (previousY === 0) roots.push(previousX);
678
+ else if (previousY < 0 !== y < 0) roots.push(bisect(descending, previousX, x));
679
+ previousX = x;
680
+ previousY = y;
681
+ }
682
+ return roots;
683
+ }
684
+ function bisect(descending, low, high) {
685
+ let left = low;
686
+ let right = high;
687
+ let leftValue = evaluateNumeric(descending, left);
688
+ for (let i = 0; i < NEWTON_MAX_ITERATIONS && right - left > NEWTON_TOLERANCE; i++) {
689
+ const middle = (left + right) / 2;
690
+ const middleValue = evaluateNumeric(descending, middle);
691
+ if (leftValue < 0 === middleValue < 0) {
692
+ left = middle;
693
+ leftValue = middleValue;
694
+ } else {
695
+ right = middle;
696
+ }
697
+ }
698
+ return (left + right) / 2;
699
+ }
700
+ function solveForVariable(lhs, rhs, variable) {
701
+ const polynomial = chunkHTXVVJRA_cjs.toPolynomial({ kind: "sub", left: lhs, right: rhs });
702
+ if (polynomial === null) {
703
+ return {
704
+ kind: "unsupported",
705
+ reason: "this is not a polynomial equation (it divides by an unknown, or calls a function of one)"
706
+ };
707
+ }
708
+ const others = polynomial.vars.filter((name) => name !== variable);
709
+ const degree = chunkHTXVVJRA_cjs.polyDegree(polynomial, variable);
710
+ if (others.length > 0) {
711
+ if (degree !== 1) {
712
+ return {
713
+ kind: "unsupported",
714
+ reason: `solving for "${variable}" needs the equation to be linear in it when other unknowns (${others.join(", ")}) are present`
715
+ };
716
+ }
717
+ return solveLinearWithOtherUnknowns(polynomial, variable);
718
+ }
719
+ if (degree === 0) {
720
+ return polynomial.terms.size === 0 ? { kind: "identity" } : { kind: "contradiction" };
721
+ }
722
+ if (degree > SOLVE_MAX_DEGREE) {
723
+ return { kind: "unsupported", reason: `degree ${degree} is above the supported maximum of ${SOLVE_MAX_DEGREE}` };
724
+ }
725
+ const descending = [...chunkHTXVVJRA_cjs.polyCoefficients(polynomial, variable)].reverse();
726
+ return solveUnivariate(descending);
727
+ }
728
+ function solveLinearWithOtherUnknowns(polynomial, variable) {
729
+ const coefficientTerms = /* @__PURE__ */ new Map();
730
+ const constantTerms = /* @__PURE__ */ new Map();
731
+ for (const [key, coeff] of polynomial.terms) {
732
+ const factors = key.split("*").filter((part) => part.length > 0);
733
+ const index = factors.indexOf(variable);
734
+ if (index === -1) {
735
+ constantTerms.set(key, coeff);
736
+ } else {
737
+ factors.splice(index, 1);
738
+ coefficientTerms.set(factors.join("*"), coeff);
739
+ }
740
+ }
741
+ const namesOf2 = (terms) => {
742
+ const names = /* @__PURE__ */ new Set();
743
+ for (const key of terms.keys()) {
744
+ for (const part of key.split("*")) {
745
+ if (part.length > 0) names.add(part.split("^")[0]);
746
+ }
747
+ }
748
+ return [...names].sort();
749
+ };
750
+ const coefficient = chunkHTXVVJRA_cjs.fromPolynomial({ terms: coefficientTerms, vars: namesOf2(coefficientTerms) });
751
+ const constant = chunkHTXVVJRA_cjs.fromPolynomial({ terms: constantTerms, vars: namesOf2(constantTerms) });
752
+ return {
753
+ kind: "roots",
754
+ exact: [{ kind: "div", left: { kind: "neg", operand: constant }, right: coefficient }],
755
+ approximate: []
756
+ };
757
+ }
758
+ function closedFormRoots(descending) {
759
+ if (descending.length === 4) {
760
+ return solveCubic(descending[0], descending[1], descending[2], descending[3]);
761
+ }
762
+ if (descending.length === 5) {
763
+ return solveQuartic(descending[0], descending[1], descending[2], descending[3], descending[4], solveQuadratic);
764
+ }
765
+ return null;
766
+ }
767
+ function solveUnivariate(descending) {
768
+ const exact = [];
769
+ let remaining = [...descending];
770
+ let roots = [...rationalRoots(remaining)].sort(chunkHTXVVJRA_cjs.rationalCompare);
771
+ while (roots.length > 0 && remaining.length > 1) {
772
+ for (const root of roots) {
773
+ while (remaining.length > 1 && chunkHTXVVJRA_cjs.isRationalZero(evaluateRational(remaining, root))) {
774
+ remaining = divideByRoot2(remaining, root);
775
+ }
776
+ exact.push(chunkHTXVVJRA_cjs.constNode(root));
777
+ }
778
+ roots = remaining.length > 1 ? [...rationalRoots(remaining)].sort(chunkHTXVVJRA_cjs.rationalCompare) : [];
779
+ }
780
+ const leftoverDegree = remaining.length - 1;
781
+ if (leftoverDegree === 1) {
782
+ exact.push(chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalDiv(chunkHTXVVJRA_cjs.rationalNeg(remaining[1]), remaining[0])));
783
+ return { kind: "roots", exact, approximate: [] };
784
+ }
785
+ if (leftoverDegree === 2) {
786
+ const quadratic = solveQuadratic(remaining[0], remaining[1], remaining[2]);
787
+ return { kind: "roots", exact: [...exact, ...quadratic], approximate: [] };
788
+ }
789
+ if (leftoverDegree <= 0) {
790
+ return exact.length > 0 ? { kind: "roots", exact, approximate: [] } : { kind: "no-real-solutions", reason: "there is no value that satisfies this equation" };
791
+ }
792
+ const closedForm = closedFormRoots(remaining);
793
+ if (closedForm !== null) {
794
+ return { kind: "roots", exact: [...exact, ...closedForm.exact], approximate: closedForm.approximate };
795
+ }
796
+ const approximate = numericRoots(remaining);
797
+ if (exact.length === 0 && approximate.length === 0) {
798
+ return { kind: "no-real-solutions", reason: "no real root was found within the polynomial's root bound" };
799
+ }
800
+ return { kind: "roots", exact, approximate };
801
+ }
802
+
803
+ // src/vm/SymbolicOps.ts
804
+ var SYMBOLIC_BUILTIN_NAMES = {
805
+ 0: "sqrt",
806
+ 1: "abs",
807
+ 2: "sin",
808
+ 3: "cos",
809
+ 4: "tan",
810
+ 5: "log",
811
+ 6: "ceil",
812
+ 7: "floor",
813
+ 8: "round",
814
+ 11: "asin",
815
+ 12: "acos",
816
+ 13: "atan",
817
+ 14: "atan2",
818
+ 15: "sinh",
819
+ 16: "cosh",
820
+ 17: "tanh",
821
+ 18: "asinh",
822
+ 19: "acosh",
823
+ 20: "atanh",
824
+ 21: "cbrt",
825
+ 23: "expm1",
826
+ 24: "exp",
827
+ 26: "hypot",
828
+ 28: "log10",
829
+ 29: "log1p",
830
+ 30: "log2",
831
+ 33: "sign",
832
+ 34: "trunc",
833
+ // Spelled exactly as `builtinNameToIndex` accepts them, all lower case. A
834
+ // `call` node's name is what gets displayed, so a name the parser would not
835
+ // accept back would render an expression the user cannot retype.
836
+ 35: "degtorad",
837
+ 36: "radtodeg",
838
+ 61: "root",
839
+ 62: "fact"
840
+ };
841
+ var POW_BUILTIN_INDEX = 31;
842
+ var SYMBOLIC_NATIVE_BUILTINS = /* @__PURE__ */ new Set([67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79]);
843
+ function valueToSymbolic(v) {
844
+ if (v.type === 9 /* Symbolic */) return v.value;
845
+ if (v.type === 13 /* Error */ || v.type === 12 /* Pending */) return null;
846
+ const numeric = v.toNumber();
847
+ if (!Number.isFinite(numeric)) return null;
848
+ return chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalFromNumber(numeric));
849
+ }
850
+ function symbolicToValue(node) {
851
+ const simplified = chunkHTXVVJRA_cjs.simplifySymbolic(node);
852
+ if (simplified.kind === "const") return chunkOC6LTXYS_cjs.numberValue(chunkHTXVVJRA_cjs.rationalToNumber(simplified.value));
853
+ return chunkOC6LTXYS_cjs.symbolicValue(simplified);
854
+ }
855
+ function unsupported(what) {
856
+ return chunkOC6LTXYS_cjs.errorValue(
857
+ "SYMBOLIC_UNSUPPORTED_FUNCTION",
858
+ `"${what}" cannot be applied to an expression that still contains an unknown.`
859
+ );
860
+ }
861
+ function symbolicPow(l, r) {
862
+ const base = valueToSymbolic(l);
863
+ const exponent = valueToSymbolic(r);
864
+ if (base === null || exponent === null) return unsupported("^");
865
+ return symbolicToValue(chunkHTXVVJRA_cjs.powNode(base, exponent));
866
+ }
867
+ function symbolicNeg(v) {
868
+ const operand = valueToSymbolic(v);
869
+ if (operand === null) return unsupported("-");
870
+ return symbolicToValue({ kind: "neg", operand });
871
+ }
872
+ function symbolicBuiltin(index, args) {
873
+ const nodes = [];
874
+ for (const arg of args) {
875
+ if (arg.type === 13 /* Error */) return arg;
876
+ const node = valueToSymbolic(arg);
877
+ if (node === null) return unsupported(SYMBOLIC_BUILTIN_NAMES[index] ?? `builtin ${index}`);
878
+ nodes.push(node);
879
+ }
880
+ if (index === POW_BUILTIN_INDEX && nodes.length === 2) {
881
+ return symbolicToValue(chunkHTXVVJRA_cjs.powNode(nodes[0], nodes[1]));
882
+ }
883
+ const name = SYMBOLIC_BUILTIN_NAMES[index];
884
+ if (name === void 0) return unsupported(`builtin ${index}`);
885
+ return symbolicToValue(chunkHTXVVJRA_cjs.callNode(name, nodes));
886
+ }
887
+ function rootToValue(root) {
888
+ const value = symbolicToValue(root);
889
+ if (value.type === 0 /* Number */ && !Number.isInteger(value.toNumber())) return chunkOC6LTXYS_cjs.symbolicValue(root);
890
+ return value;
891
+ }
892
+ function solveOutcomeToValue(outcome) {
893
+ switch (outcome.kind) {
894
+ case "identity":
895
+ return chunkOC6LTXYS_cjs.stringValue("true for every value");
896
+ case "contradiction":
897
+ return chunkOC6LTXYS_cjs.stringValue("no solution");
898
+ case "no-real-solutions":
899
+ return chunkOC6LTXYS_cjs.stringValue(`no real solutions (${outcome.reason})`);
900
+ case "unsupported":
901
+ return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_SOLVE_UNSUPPORTED", `Cannot solve this equation: ${outcome.reason}.`);
902
+ case "roots": {
903
+ const values = outcome.exact.map(rootToValue);
904
+ for (const approximate of outcome.approximate) values.push(chunkOC6LTXYS_cjs.numberValue(approximate));
905
+ if (values.length === 0) return chunkOC6LTXYS_cjs.stringValue("no solution");
906
+ if (values.length === 1) return values[0];
907
+ return chunkOC6LTXYS_cjs.matrixValue(1, values.length, values.map((v) => v.type === 9 /* Symbolic */ ? v.value : v.toNumber()));
908
+ }
909
+ }
910
+ }
911
+ function solveEquationValues(lhsValue, rhsValue, variable) {
912
+ const lhs = valueToSymbolic(lhsValue);
913
+ const rhs = valueToSymbolic(rhsValue);
914
+ if (lhs === null || rhs === null) {
915
+ return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "An equation side has no exact value to solve with.");
916
+ }
917
+ return solveOutcomeToValue(solveForVariable(lhs, rhs, variable));
918
+ }
919
+
920
+ // src/vm/VMConversion.ts
921
+ function unifyUom(l, r) {
922
+ if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
923
+ if (l.unit === r.unit) {
924
+ return { lv: l.toNumber(), rv: r.toNumber(), unit: l.unit, sameMeasure: true };
925
+ }
926
+ const lMeasure = chunkQNJ4ACRT_cjs.getMeasure(l.unit);
927
+ const rMeasure = chunkQNJ4ACRT_cjs.getMeasure(r.unit);
928
+ const isCurrency = chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(l.unit) && chunkXJCMXB2E_cjs.sharedCurrencyExchange.isCurrency(r.unit);
929
+ if (lMeasure && lMeasure === rMeasure) {
930
+ const rvConverted = chunkQNJ4ACRT_cjs.convertUnit(r.toNumber(), r.unit, l.unit);
931
+ return { lv: l.toNumber(), rv: rvConverted, unit: l.unit, sameMeasure: true };
932
+ }
933
+ if (isCurrency) {
934
+ const rvConverted = chunkXJCMXB2E_cjs.sharedCurrencyExchange.convertSync(r.toNumber(), r.unit, l.unit);
935
+ if (rvConverted !== null) {
936
+ return { lv: l.toNumber(), rv: rvConverted, unit: l.unit, sameMeasure: true };
937
+ }
938
+ }
939
+ return { lv: l.toNumber(), rv: r.toNumber(), unit: void 0, sameMeasure: false };
940
+ }
941
+ if (l.type === 6 /* Uom */) {
942
+ return { lv: l.toNumber(), rv: r.toNumber(), unit: l.unit, sameMeasure: true };
943
+ }
944
+ if (r.type === 6 /* Uom */) {
945
+ return { lv: l.toNumber(), rv: r.toNumber(), unit: r.unit, sameMeasure: true };
946
+ }
947
+ return { lv: l.toNumber(), rv: r.toNumber(), unit: void 0, sameMeasure: true };
948
+ }
949
+ function binaryOp(l, r, op, bigOp, symbolicOp) {
950
+ if (l.type === 13 /* Error */) return l;
951
+ if (r.type === 13 /* Error */) return r;
952
+ if (l.type === 12 /* Pending */) return l;
953
+ if (r.type === 12 /* Pending */) return r;
954
+ if (symbolicOp && (l.type === 9 /* Symbolic */ || r.type === 9 /* Symbolic */)) {
955
+ const left = valueToSymbolic(l);
956
+ const right = valueToSymbolic(r);
957
+ if (left === null || right === null) {
958
+ return chunkOC6LTXYS_cjs.errorValue(
959
+ "SYMBOLIC_NONFINITE_OPERAND",
960
+ "A symbolic expression cannot combine with a value that has no exact number (NaN or infinity)."
961
+ );
962
+ }
963
+ const node = { kind: symbolicOp, left, right };
964
+ return chunkOC6LTXYS_cjs.symbolicValue(chunkHTXVVJRA_cjs.simplifySymbolic(node));
965
+ }
966
+ if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
967
+ return chunkOC6LTXYS_cjs.numberValue(op(l.value, r.value));
968
+ }
969
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
970
+ const lb = l.type === 2 /* BigInt */ ? l.value : BigInt(l.toNumber());
971
+ const rb = r.type === 2 /* BigInt */ ? r.value : BigInt(r.toNumber());
972
+ if (bigOp) return chunkOC6LTXYS_cjs.bigIntValue(bigOp(lb, rb));
973
+ return chunkOC6LTXYS_cjs.bigIntValue(lb + rb);
974
+ }
975
+ if (l.type === 6 /* Uom */ || r.type === 6 /* Uom */) {
976
+ const { lv, rv, unit, sameMeasure } = unifyUom(l, r);
977
+ if (isNaN(lv) || isNaN(rv)) return chunkOC6LTXYS_cjs.numberValue(0);
978
+ if (!sameMeasure) {
979
+ const lUnit = l.type === 6 /* Uom */ ? l.unit : void 0;
980
+ const rUnit = r.type === 6 /* Uom */ ? r.unit : void 0;
981
+ return chunkOC6LTXYS_cjs.errorValue("INCOMPATIBLE_UNITS", `Cannot combine incompatible units: ${lUnit ?? "?"} and ${rUnit ?? "?"}`);
982
+ }
983
+ return chunkOC6LTXYS_cjs.uomValue(op(lv, rv), unit);
984
+ }
985
+ if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
986
+ const lm = l.value;
987
+ const rm = r.value;
988
+ if (!chunkHTXVVJRA_cjs.sameShape(lm, rm)) {
989
+ return chunkOC6LTXYS_cjs.errorValue("DIMENSION_MISMATCH", `Cannot combine matrices of different shapes: ${lm.rows}x${lm.cols} and ${rm.rows}x${rm.cols}`);
990
+ }
991
+ const result = new Array(lm.data.length);
992
+ for (let i = 0; i < lm.data.length; i++) result[i] = op(lm.data[i], rm.data[i]);
993
+ return chunkOC6LTXYS_cjs.matrixValue(lm.rows, lm.cols, result);
994
+ }
995
+ if (l.type === 7 /* Matrix */) {
996
+ const lm = l.value;
997
+ const scalar = r.toNumber();
998
+ const result = lm.data.map((v) => op(v, scalar));
999
+ return chunkOC6LTXYS_cjs.matrixValue(lm.rows, lm.cols, result);
1000
+ }
1001
+ if (r.type === 7 /* Matrix */) {
1002
+ const rm = r.value;
1003
+ const scalar = l.toNumber();
1004
+ const result = rm.data.map((v) => op(scalar, v));
1005
+ return chunkOC6LTXYS_cjs.matrixValue(rm.rows, rm.cols, result);
1006
+ }
1007
+ const lNum = l.toNumber();
1008
+ const rNum = r.toNumber();
1009
+ if (isNaN(lNum) || isNaN(rNum)) return chunkOC6LTXYS_cjs.numberValue(0);
1010
+ return chunkOC6LTXYS_cjs.numberValue(op(lNum, rNum));
1011
+ }
1012
+
1013
+ // src/vm/OpRegistry.ts
1014
+ var MAX_OPCODE = 254;
1015
+ var DYNAMIC_OPCODE_START = 200;
1016
+ var OpRegistry = class {
1017
+ constructor() {
1018
+ this.handlers = /* @__PURE__ */ new Map();
1019
+ this.nextOpcode = DYNAMIC_OPCODE_START + 1;
1020
+ }
1021
+ register(registration) {
1022
+ this.handlers.set(registration.opcode, registration.handler);
1023
+ }
1024
+ /**
1025
+ * Remove a previously registered opcode handler.
1026
+ * Used by package unregistration to reverse shared-registry contributions.
1027
+ */
1028
+ unregister(opcode) {
1029
+ this.handlers.delete(opcode);
1030
+ }
1031
+ get(opcode) {
1032
+ return this.handlers.get(opcode);
1033
+ }
1034
+ has(opcode) {
1035
+ return this.handlers.has(opcode);
1036
+ }
1037
+ /**
1038
+ * Allocate a unique opcode for a plugin's custom bytecode handler.
1039
+ *
1040
+ * Returns the next available opcode (starting at 201). Each call
1041
+ * returns a distinct value. Plugins should call this once during
1042
+ * registration and store the result.
1043
+ *
1044
+ * @throws If the dynamic opcode pool is exhausted.
1045
+ * @returns A unique opcode number for the calling plugin.
1046
+ */
1047
+ allocateOpcode() {
1048
+ if (this.nextOpcode > MAX_OPCODE) {
1049
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.config(
1050
+ "OPCODE_POOL_EXHAUSTED",
1051
+ `OpRegistry: dynamic opcode pool exhausted (max ${MAX_OPCODE - DYNAMIC_OPCODE_START} allocations).`
1052
+ );
1053
+ }
1054
+ return this.nextOpcode++;
1055
+ }
1056
+ };
1057
+ var sharedOpRegistry = new OpRegistry();
1058
+
1059
+ // src/symbolic/PartialFractions.ts
1060
+ var APART_MAX_DEGREE = 12;
1061
+ function multiply(a, b) {
1062
+ if (a.length === 0 || b.length === 0) return [];
1063
+ const product2 = new Array(a.length + b.length - 1).fill(chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1064
+ a.forEach((left, i) => {
1065
+ b.forEach((right, j) => {
1066
+ product2[i + j] = chunkHTXVVJRA_cjs.rationalAdd(product2[i + j], chunkHTXVVJRA_cjs.rationalMul(left, right));
1067
+ });
1068
+ });
1069
+ return product2;
1070
+ }
1071
+ function power(base, exponent) {
1072
+ let result = [chunkHTXVVJRA_cjs.RATIONAL_ONE];
1073
+ for (let i = 0; i < exponent; i++) result = multiply(result, base);
1074
+ return result;
1075
+ }
1076
+ function scale(coefficients, factor) {
1077
+ return coefficients.map((coefficient) => chunkHTXVVJRA_cjs.rationalDiv(coefficient, factor));
1078
+ }
1079
+ function denominatorFactors(ascending, variable) {
1080
+ const factors = [];
1081
+ let lowest = 0;
1082
+ while (lowest < ascending.length && chunkHTXVVJRA_cjs.isRationalZero(ascending[lowest])) lowest++;
1083
+ if (lowest > 0) factors.push({ base: [chunkHTXVVJRA_cjs.RATIONAL_ZERO, chunkHTXVVJRA_cjs.RATIONAL_ONE], power: lowest });
1084
+ const remaining = ascending.slice(lowest);
1085
+ if (remaining.length > 1) {
1086
+ const factorization = factorUnivariate([...remaining].reverse(), variable);
1087
+ for (const factor of factorization.factors) {
1088
+ const polynomial = chunkHTXVVJRA_cjs.toPolynomial(factor.base);
1089
+ if (polynomial === null) return null;
1090
+ factors.push({ base: [...chunkHTXVVJRA_cjs.polyCoefficients(polynomial, variable)], power: factor.power });
1091
+ }
1092
+ }
1093
+ return factors.length > 0 ? factors : null;
1094
+ }
1095
+ function enumerateUnknowns(factors) {
1096
+ const unknowns = [];
1097
+ factors.forEach((factor, index) => {
1098
+ const factorDegree = factor.base.length - 1;
1099
+ for (let p = 1; p <= factor.power; p++) {
1100
+ for (let degree = 0; degree < factorDegree; degree++) {
1101
+ unknowns.push({ factor: index, power: p, degree });
1102
+ }
1103
+ }
1104
+ });
1105
+ return unknowns;
1106
+ }
1107
+ function unknownColumn(unknown, factors, denominator) {
1108
+ const divisor = power(factors[unknown.factor].base, unknown.power);
1109
+ const { quotient, remainder } = chunkHTXVVJRA_cjs.polynomialDivide(denominator, divisor);
1110
+ if (!chunkHTXVVJRA_cjs.isZeroPolynomial(remainder)) return null;
1111
+ const shift = new Array(unknown.degree).fill(chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1112
+ shift.push(chunkHTXVVJRA_cjs.RATIONAL_ONE);
1113
+ return multiply(quotient, shift);
1114
+ }
1115
+ function solveLinearSystem(matrix, target) {
1116
+ const size = target.length;
1117
+ for (let column = 0; column < size; column++) {
1118
+ let pivot = -1;
1119
+ for (let row = column; row < size; row++) {
1120
+ if (!chunkHTXVVJRA_cjs.isRationalZero(matrix[row][column])) {
1121
+ pivot = row;
1122
+ break;
1123
+ }
1124
+ }
1125
+ if (pivot === -1) return null;
1126
+ [matrix[column], matrix[pivot]] = [matrix[pivot], matrix[column]];
1127
+ [target[column], target[pivot]] = [target[pivot], target[column]];
1128
+ for (let row = 0; row < size; row++) {
1129
+ if (row === column || chunkHTXVVJRA_cjs.isRationalZero(matrix[row][column])) continue;
1130
+ const factor = chunkHTXVVJRA_cjs.rationalDiv(matrix[row][column], matrix[column][column]);
1131
+ for (let k = column; k < size; k++) {
1132
+ matrix[row][k] = chunkHTXVVJRA_cjs.rationalSub(matrix[row][k], chunkHTXVVJRA_cjs.rationalMul(factor, matrix[column][k]));
1133
+ }
1134
+ target[row] = chunkHTXVVJRA_cjs.rationalSub(target[row], chunkHTXVVJRA_cjs.rationalMul(factor, target[column]));
1135
+ }
1136
+ }
1137
+ return target.map((value, index) => chunkHTXVVJRA_cjs.rationalDiv(value, matrix[index][index]));
1138
+ }
1139
+ function partialFractions(numerator, denominator, variable) {
1140
+ if (denominator.length < 2 || denominator.length - 1 > APART_MAX_DEGREE) return null;
1141
+ const shared = chunkHTXVVJRA_cjs.coefficientGcd(numerator, denominator);
1142
+ const reducedNumerator = shared.length > 1 ? chunkHTXVVJRA_cjs.polynomialDivide(numerator, shared).quotient : [...numerator];
1143
+ const reducedDenominator = shared.length > 1 ? chunkHTXVVJRA_cjs.polynomialDivide(denominator, shared).quotient : [...denominator];
1144
+ if (reducedDenominator.length === 1) {
1145
+ return { polynomial: scale(reducedNumerator, reducedDenominator[0]), terms: [] };
1146
+ }
1147
+ if (reducedDenominator.length === 0) return null;
1148
+ const leading = reducedDenominator[reducedDenominator.length - 1];
1149
+ const monicDenominator = scale(reducedDenominator, leading);
1150
+ const scaledNumerator = scale(reducedNumerator, leading);
1151
+ const { quotient, remainder } = chunkHTXVVJRA_cjs.polynomialDivide(scaledNumerator, monicDenominator);
1152
+ if (chunkHTXVVJRA_cjs.isZeroPolynomial(remainder)) return { polynomial: quotient, terms: [] };
1153
+ const factors = denominatorFactors(monicDenominator, variable);
1154
+ if (factors === null) return null;
1155
+ const terms = solveForNumerators(factors, monicDenominator, remainder);
1156
+ return terms === null ? null : { polynomial: quotient, terms };
1157
+ }
1158
+ function solveForNumerators(factors, denominator, remainder) {
1159
+ const unknowns = enumerateUnknowns(factors);
1160
+ const size = denominator.length - 1;
1161
+ if (unknowns.length !== size) return null;
1162
+ const columns = [];
1163
+ for (const unknown of unknowns) {
1164
+ const column = unknownColumn(unknown, factors, denominator);
1165
+ if (column === null) return null;
1166
+ columns.push(column);
1167
+ }
1168
+ const matrix = [];
1169
+ for (let row = 0; row < size; row++) {
1170
+ matrix.push(columns.map((column) => column[row] ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO));
1171
+ }
1172
+ const target = [];
1173
+ for (let row = 0; row < size; row++) target.push(remainder[row] ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1174
+ const solution = solveLinearSystem(matrix, target);
1175
+ if (solution === null) return null;
1176
+ return groupSolution(unknowns, solution, factors);
1177
+ }
1178
+ function groupSolution(unknowns, solution, factors) {
1179
+ const grouped = /* @__PURE__ */ new Map();
1180
+ unknowns.forEach((unknown, index) => {
1181
+ const key = `${unknown.factor}:${unknown.power}`;
1182
+ const existing = grouped.get(key) ?? [];
1183
+ existing[unknown.degree] = solution[index];
1184
+ grouped.set(key, existing);
1185
+ });
1186
+ const terms = [];
1187
+ for (const [key, coefficients] of grouped) {
1188
+ const [factorIndex, termPower] = key.split(":").map(Number);
1189
+ const filled = [...coefficients].map((value) => value ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1190
+ if (filled.every(chunkHTXVVJRA_cjs.isRationalZero)) continue;
1191
+ terms.push({ numerator: filled, base: factors[factorIndex].base, power: termPower });
1192
+ }
1193
+ return terms;
1194
+ }
1195
+ function coefficientsToNode2(coefficients, variable) {
1196
+ const terms = /* @__PURE__ */ new Map();
1197
+ coefficients.forEach((coefficient, exponent) => {
1198
+ if (chunkHTXVVJRA_cjs.isRationalZero(coefficient)) return;
1199
+ terms.set(exponent === 0 ? "" : exponent === 1 ? variable : `${variable}^${exponent}`, coefficient);
1200
+ });
1201
+ if (terms.size === 0) return chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1202
+ return chunkHTXVVJRA_cjs.fromPolynomial({ terms, vars: coefficients.length > 1 ? [variable] : [] });
1203
+ }
1204
+ function apartSymbolic(node) {
1205
+ const parts = asRationalFunction(node);
1206
+ if (parts === null) return node;
1207
+ const decomposition = partialFractions(parts.numerator, parts.denominator, parts.variable);
1208
+ if (decomposition === null || decomposition.terms.length === 0) return node;
1209
+ let result = decomposition.polynomial.length > 0 ? coefficientsToNode2(decomposition.polynomial, parts.variable) : null;
1210
+ for (const term of decomposition.terms) {
1211
+ const base = coefficientsToNode2(term.base, parts.variable);
1212
+ const denominator = term.power === 1 ? base : chunkHTXVVJRA_cjs.powNode(base, chunkHTXVVJRA_cjs.constNode({ n: BigInt(term.power), d: 1n }));
1213
+ const negative = isNegativeNumerator(term.numerator);
1214
+ const numerator = negative ? term.numerator.map((coefficient) => chunkHTXVVJRA_cjs.rationalNeg(coefficient)) : term.numerator;
1215
+ const piece = {
1216
+ kind: "div",
1217
+ left: coefficientsToNode2(numerator, parts.variable),
1218
+ right: denominator
1219
+ };
1220
+ if (result === null) result = negative ? { kind: "neg", operand: piece } : piece;
1221
+ else result = { kind: negative ? "sub" : "add", left: result, right: piece };
1222
+ }
1223
+ return result === null ? node : chunkHTXVVJRA_cjs.simplifySymbolic(result);
1224
+ }
1225
+ function isNegativeNumerator(coefficients) {
1226
+ return coefficients.some((coefficient) => coefficient.n < 0n) && coefficients.every((coefficient) => coefficient.n <= 0n);
1227
+ }
1228
+ function asRationalFunction(node) {
1229
+ if (node.kind !== "div") return null;
1230
+ const numerator = chunkHTXVVJRA_cjs.toPolynomial(node.left);
1231
+ const denominator = chunkHTXVVJRA_cjs.toPolynomial(node.right);
1232
+ if (numerator === null || denominator === null) return null;
1233
+ const variable = chunkHTXVVJRA_cjs.polyUnivariateVar(denominator);
1234
+ if (variable === null) return null;
1235
+ if (numerator.vars.some((name) => name !== variable)) return null;
1236
+ return {
1237
+ numerator: chunkHTXVVJRA_cjs.polyCoefficients(numerator, variable),
1238
+ denominator: chunkHTXVVJRA_cjs.polyCoefficients(denominator, variable),
1239
+ variable
1240
+ };
1241
+ }
1242
+
1243
+ // src/symbolic/Derivative.ts
1244
+ var DERIVATIVE_MAX_ORDER = 16;
1245
+ function zero() {
1246
+ return chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1247
+ }
1248
+ function one() {
1249
+ return chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ONE);
1250
+ }
1251
+ function functionDerivative(name, argument) {
1252
+ switch (name) {
1253
+ case "sin":
1254
+ return chunkHTXVVJRA_cjs.callNode("cos", [argument]);
1255
+ case "cos":
1256
+ return { kind: "neg", operand: chunkHTXVVJRA_cjs.callNode("sin", [argument]) };
1257
+ case "tan":
1258
+ return { kind: "div", left: one(), right: chunkHTXVVJRA_cjs.powNode(chunkHTXVVJRA_cjs.callNode("cos", [argument]), chunkHTXVVJRA_cjs.constNode(2)) };
1259
+ case "exp":
1260
+ return chunkHTXVVJRA_cjs.callNode("exp", [argument]);
1261
+ case "log":
1262
+ return { kind: "div", left: one(), right: argument };
1263
+ case "sqrt":
1264
+ return {
1265
+ kind: "div",
1266
+ left: one(),
1267
+ right: { kind: "mul", left: chunkHTXVVJRA_cjs.constNode(2), right: chunkHTXVVJRA_cjs.callNode("sqrt", [argument]) }
1268
+ };
1269
+ case "asin":
1270
+ return { kind: "div", left: one(), right: chunkHTXVVJRA_cjs.callNode("sqrt", [oneMinusSquare(argument)]) };
1271
+ case "acos":
1272
+ return { kind: "neg", operand: { kind: "div", left: one(), right: chunkHTXVVJRA_cjs.callNode("sqrt", [oneMinusSquare(argument)]) } };
1273
+ case "atan":
1274
+ return { kind: "div", left: one(), right: onePlusSquare(argument) };
1275
+ case "sinh":
1276
+ return chunkHTXVVJRA_cjs.callNode("cosh", [argument]);
1277
+ case "cosh":
1278
+ return chunkHTXVVJRA_cjs.callNode("sinh", [argument]);
1279
+ case "tanh":
1280
+ return { kind: "div", left: one(), right: chunkHTXVVJRA_cjs.powNode(chunkHTXVVJRA_cjs.callNode("cosh", [argument]), chunkHTXVVJRA_cjs.constNode(2)) };
1281
+ case "abs":
1282
+ return chunkHTXVVJRA_cjs.callNode("sign", [argument]);
1283
+ default:
1284
+ return null;
1285
+ }
1286
+ }
1287
+ function oneMinusSquare(argument) {
1288
+ return { kind: "sub", left: one(), right: chunkHTXVVJRA_cjs.powNode(argument, chunkHTXVVJRA_cjs.constNode(2)) };
1289
+ }
1290
+ function onePlusSquare(argument) {
1291
+ return { kind: "add", left: one(), right: chunkHTXVVJRA_cjs.powNode(argument, chunkHTXVVJRA_cjs.constNode(2)) };
1292
+ }
1293
+ function differentiate(node, variable, order = 1) {
1294
+ if (order < 0 || !Number.isInteger(order)) {
1295
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("SYMBOLIC_DERIVATIVE_ORDER_LIMIT", "A derivative order must be a whole number, at least zero.");
1296
+ }
1297
+ if (order > DERIVATIVE_MAX_ORDER) {
1298
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1299
+ "SYMBOLIC_DERIVATIVE_ORDER_LIMIT",
1300
+ `A derivative order above ${DERIVATIVE_MAX_ORDER} is not supported.`,
1301
+ { limit: DERIVATIVE_MAX_ORDER }
1302
+ );
1303
+ }
1304
+ let result = chunkHTXVVJRA_cjs.simplifySymbolic(node);
1305
+ for (let i = 0; i < order; i++) result = chunkHTXVVJRA_cjs.simplifySymbolic(derive(result, variable));
1306
+ return result;
1307
+ }
1308
+ function derive(node, variable) {
1309
+ switch (node.kind) {
1310
+ case "const":
1311
+ case "complex":
1312
+ return zero();
1313
+ case "var":
1314
+ return node.name === variable ? one() : zero();
1315
+ case "add":
1316
+ return { kind: "add", left: derive(node.left, variable), right: derive(node.right, variable) };
1317
+ case "sub":
1318
+ return { kind: "sub", left: derive(node.left, variable), right: derive(node.right, variable) };
1319
+ case "neg":
1320
+ return { kind: "neg", operand: derive(node.operand, variable) };
1321
+ case "mul":
1322
+ return {
1323
+ kind: "add",
1324
+ left: { kind: "mul", left: derive(node.left, variable), right: node.right },
1325
+ right: { kind: "mul", left: node.left, right: derive(node.right, variable) }
1326
+ };
1327
+ case "div":
1328
+ return {
1329
+ kind: "div",
1330
+ left: {
1331
+ kind: "sub",
1332
+ left: { kind: "mul", left: derive(node.left, variable), right: node.right },
1333
+ right: { kind: "mul", left: node.left, right: derive(node.right, variable) }
1334
+ },
1335
+ right: chunkHTXVVJRA_cjs.powNode(node.right, chunkHTXVVJRA_cjs.constNode(2))
1336
+ };
1337
+ case "pow":
1338
+ return derivePow(node, variable);
1339
+ case "call": {
1340
+ if (node.args.length !== 1) return unevaluated(node, variable);
1341
+ const outer = functionDerivative(node.name, node.args[0]);
1342
+ if (outer === null) return unevaluated(node, variable);
1343
+ return { kind: "mul", left: outer, right: derive(node.args[0], variable) };
1344
+ }
1345
+ }
1346
+ }
1347
+ function derivePow(node, variable) {
1348
+ if (node.exponent.kind === "const") {
1349
+ const reduced = chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalSub(node.exponent.value, chunkHTXVVJRA_cjs.RATIONAL_ONE));
1350
+ return {
1351
+ kind: "mul",
1352
+ left: { kind: "mul", left: node.exponent, right: chunkHTXVVJRA_cjs.powNode(node.base, reduced) },
1353
+ right: derive(node.base, variable)
1354
+ };
1355
+ }
1356
+ if (node.base.kind === "const" && node.base.value.n > 0n) {
1357
+ return {
1358
+ kind: "mul",
1359
+ left: { kind: "mul", left: node, right: chunkHTXVVJRA_cjs.callNode("log", [node.base]) },
1360
+ right: derive(node.exponent, variable)
1361
+ };
1362
+ }
1363
+ return unevaluated(node, variable);
1364
+ }
1365
+ function unevaluated(node, variable) {
1366
+ return chunkHTXVVJRA_cjs.callNode("der", [node, chunkHTXVVJRA_cjs.varNode(variable)]);
1367
+ }
1368
+
1369
+ // src/symbolic/Integral.ts
1370
+ function asLinear(node, variable) {
1371
+ const polynomial = chunkHTXVVJRA_cjs.toPolynomial(node);
1372
+ if (polynomial === null) return null;
1373
+ const others = polynomial.vars.filter((name) => name !== variable);
1374
+ if (others.length > 0) return null;
1375
+ if (chunkHTXVVJRA_cjs.polyDegree(polynomial, variable) > 1) return null;
1376
+ const ascending = chunkHTXVVJRA_cjs.polyCoefficients(polynomial, variable);
1377
+ const intercept = ascending[0] ?? { n: 0n, d: 1n };
1378
+ const slope = ascending[1] ?? { n: 0n, d: 1n };
1379
+ return chunkHTXVVJRA_cjs.isRationalZero(slope) ? null : { slope, intercept };
1380
+ }
1381
+ function integratePolynomial(node, variable) {
1382
+ const polynomial = chunkHTXVVJRA_cjs.toPolynomial(node);
1383
+ if (polynomial === null) return null;
1384
+ const others = polynomial.vars.filter((name) => name !== variable);
1385
+ if (others.length > 0) {
1386
+ return { ok: false, reason: `it involves more than one unknown (${others.join(", ")})` };
1387
+ }
1388
+ const ascending = chunkHTXVVJRA_cjs.polyCoefficients(polynomial, variable);
1389
+ let result = chunkHTXVVJRA_cjs.constNode(0);
1390
+ ascending.forEach((coeff, power2) => {
1391
+ if (chunkHTXVVJRA_cjs.isRationalZero(coeff)) return;
1392
+ const nextPower = power2 + 1;
1393
+ const scaled = chunkHTXVVJRA_cjs.rationalDiv(coeff, { n: BigInt(nextPower), d: 1n });
1394
+ const term = {
1395
+ kind: "mul",
1396
+ left: chunkHTXVVJRA_cjs.constNode(scaled),
1397
+ right: nextPower === 1 ? chunkHTXVVJRA_cjs.varNode(variable) : chunkHTXVVJRA_cjs.powNode(chunkHTXVVJRA_cjs.varNode(variable), chunkHTXVVJRA_cjs.constNode(nextPower))
1398
+ };
1399
+ result = { kind: "add", left: result, right: term };
1400
+ });
1401
+ return { ok: true, value: chunkHTXVVJRA_cjs.simplifySymbolic(result) };
1402
+ }
1403
+ function integrateStandardForm(node, variable) {
1404
+ if (node.kind !== "call" || node.args.length !== 1) return null;
1405
+ const linear = asLinear(node.args[0], variable);
1406
+ if (linear === null) return null;
1407
+ const inner = node.args[0];
1408
+ const divideBySlope = (value) => chunkHTXVVJRA_cjs.simplifySymbolic({ kind: "div", left: value, right: chunkHTXVVJRA_cjs.constNode(linear.slope) });
1409
+ switch (node.name) {
1410
+ case "exp":
1411
+ return { ok: true, value: divideBySlope(chunkHTXVVJRA_cjs.callNode("exp", [inner])) };
1412
+ case "sin":
1413
+ return { ok: true, value: divideBySlope({ kind: "neg", operand: chunkHTXVVJRA_cjs.callNode("cos", [inner]) }) };
1414
+ case "cos":
1415
+ return { ok: true, value: divideBySlope(chunkHTXVVJRA_cjs.callNode("sin", [inner])) };
1416
+ case "log":
1417
+ return {
1418
+ ok: true,
1419
+ value: divideBySlope({
1420
+ kind: "sub",
1421
+ left: { kind: "mul", left: inner, right: chunkHTXVVJRA_cjs.callNode("log", [inner]) },
1422
+ right: inner
1423
+ })
1424
+ };
1425
+ default:
1426
+ return null;
1427
+ }
1428
+ }
1429
+ function integrateReciprocalForms(node, variable) {
1430
+ if (node.kind !== "div") return null;
1431
+ if (node.left.kind !== "const" || !isRationalOneNode(node.left.value)) return null;
1432
+ const linear = asLinear(node.right, variable);
1433
+ if (linear !== null) {
1434
+ return {
1435
+ ok: true,
1436
+ value: chunkHTXVVJRA_cjs.simplifySymbolic({
1437
+ kind: "div",
1438
+ left: chunkHTXVVJRA_cjs.callNode("log", [node.right]),
1439
+ right: chunkHTXVVJRA_cjs.constNode(linear.slope)
1440
+ })
1441
+ };
1442
+ }
1443
+ const denominator = chunkHTXVVJRA_cjs.toPolynomial(node.right);
1444
+ if (denominator !== null && denominator.vars.length === 1 && denominator.vars[0] === variable) {
1445
+ const ascending = chunkHTXVVJRA_cjs.polyCoefficients(denominator, variable);
1446
+ const isOnePlusSquare = ascending.length === 3 && isRationalOneNode(ascending[0]) && chunkHTXVVJRA_cjs.isRationalZero(ascending[1]) && isRationalOneNode(ascending[2]);
1447
+ if (isOnePlusSquare) return { ok: true, value: chunkHTXVVJRA_cjs.callNode("atan", [chunkHTXVVJRA_cjs.varNode(variable)]) };
1448
+ }
1449
+ return null;
1450
+ }
1451
+ function isRationalOneNode(value) {
1452
+ return value.n === 1n && value.d === 1n;
1453
+ }
1454
+ function integrateRationalFunction(node, variable) {
1455
+ const parts = asRationalFunction(node);
1456
+ if (parts === null || parts.variable !== variable) return null;
1457
+ const decomposition = partialFractions(parts.numerator, parts.denominator, variable);
1458
+ if (decomposition === null) return null;
1459
+ let result = decomposition.polynomial.length > 0 ? polynomialAntiderivative(decomposition.polynomial, variable) : chunkHTXVVJRA_cjs.constNode(0);
1460
+ for (const term of decomposition.terms) {
1461
+ const piece = integrateTerm(term, variable);
1462
+ if (piece === null) {
1463
+ return {
1464
+ ok: false,
1465
+ reason: "its denominator has a repeated irreducible quadratic factor, which needs a reduction formula this does not have"
1466
+ };
1467
+ }
1468
+ result = { kind: "add", left: result, right: piece };
1469
+ }
1470
+ return { ok: true, value: chunkHTXVVJRA_cjs.simplifySymbolic(result) };
1471
+ }
1472
+ function integrateTerm(term, variable) {
1473
+ const baseDegree = term.base.length - 1;
1474
+ const base = coefficientsToNode2(term.base, variable);
1475
+ if (baseDegree === 1) {
1476
+ const coefficient = term.numerator[0] ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO;
1477
+ if (term.power === 1) {
1478
+ return { kind: "mul", left: chunkHTXVVJRA_cjs.constNode(coefficient), right: chunkHTXVVJRA_cjs.callNode("log", [base]) };
1479
+ }
1480
+ const reduced = term.power - 1;
1481
+ const scaled = chunkHTXVVJRA_cjs.rationalDiv(coefficient, { n: BigInt(-reduced), d: 1n });
1482
+ return {
1483
+ kind: "div",
1484
+ left: chunkHTXVVJRA_cjs.constNode(scaled),
1485
+ right: chunkHTXVVJRA_cjs.powNode(base, chunkHTXVVJRA_cjs.constNode({ n: BigInt(reduced), d: 1n }))
1486
+ };
1487
+ }
1488
+ if (baseDegree !== 2 || term.power !== 1) return null;
1489
+ return integrateQuadraticTerm(term, variable, base);
1490
+ }
1491
+ function integrateQuadraticTerm(term, variable, base) {
1492
+ const constant = term.numerator[0] ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO;
1493
+ const linear = term.numerator[1] ?? chunkHTXVVJRA_cjs.RATIONAL_ZERO;
1494
+ const [q, p] = term.base;
1495
+ const half = { n: 1n, d: 2n };
1496
+ const halfP = chunkHTXVVJRA_cjs.rationalMul(p, half);
1497
+ const logarithm = {
1498
+ kind: "mul",
1499
+ left: chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.rationalMul(linear, half)),
1500
+ right: chunkHTXVVJRA_cjs.callNode("log", [base])
1501
+ };
1502
+ const leftover = chunkHTXVVJRA_cjs.rationalSub(constant, chunkHTXVVJRA_cjs.rationalMul(linear, halfP));
1503
+ if (chunkHTXVVJRA_cjs.isRationalZero(leftover)) return logarithm;
1504
+ const width = chunkHTXVVJRA_cjs.surdNode(chunkHTXVVJRA_cjs.rationalSub(q, chunkHTXVVJRA_cjs.rationalMul(halfP, halfP)));
1505
+ const shifted = {
1506
+ kind: "add",
1507
+ left: chunkHTXVVJRA_cjs.varNode(variable),
1508
+ right: chunkHTXVVJRA_cjs.constNode(halfP)
1509
+ };
1510
+ const arctangent = {
1511
+ kind: "mul",
1512
+ left: { kind: "div", left: chunkHTXVVJRA_cjs.constNode(leftover), right: width },
1513
+ right: chunkHTXVVJRA_cjs.callNode("atan", [{ kind: "div", left: shifted, right: width }])
1514
+ };
1515
+ return chunkHTXVVJRA_cjs.isRationalZero(linear) ? arctangent : { kind: "add", left: logarithm, right: arctangent };
1516
+ }
1517
+ function polynomialAntiderivative(ascending, variable) {
1518
+ let result = chunkHTXVVJRA_cjs.constNode(0);
1519
+ ascending.forEach((coeff, exponent) => {
1520
+ if (chunkHTXVVJRA_cjs.isRationalZero(coeff)) return;
1521
+ const nextPower = exponent + 1;
1522
+ const scaled = chunkHTXVVJRA_cjs.rationalDiv(coeff, { n: BigInt(nextPower), d: 1n });
1523
+ const term = {
1524
+ kind: "mul",
1525
+ left: chunkHTXVVJRA_cjs.constNode(scaled),
1526
+ right: nextPower === 1 ? chunkHTXVVJRA_cjs.varNode(variable) : chunkHTXVVJRA_cjs.powNode(chunkHTXVVJRA_cjs.varNode(variable), chunkHTXVVJRA_cjs.constNode(nextPower))
1527
+ };
1528
+ result = { kind: "add", left: result, right: term };
1529
+ });
1530
+ return result;
1531
+ }
1532
+ function integrate(node, variable) {
1533
+ const simplified = chunkHTXVVJRA_cjs.simplifySymbolic(node);
1534
+ if (!chunkHTXVVJRA_cjs.freeVariables(simplified).has(variable)) {
1535
+ return { ok: true, value: chunkHTXVVJRA_cjs.simplifySymbolic({ kind: "mul", left: simplified, right: chunkHTXVVJRA_cjs.varNode(variable) }) };
1536
+ }
1537
+ const polynomial = integratePolynomial(simplified, variable);
1538
+ if (polynomial !== null) return polynomial;
1539
+ const standard = integrateStandardForm(simplified, variable);
1540
+ if (standard !== null) return standard;
1541
+ const reciprocal = integrateReciprocalForms(simplified, variable);
1542
+ if (reciprocal !== null) return reciprocal;
1543
+ const rationalFunction = integrateRationalFunction(simplified, variable);
1544
+ if (rationalFunction !== null) return rationalFunction;
1545
+ if (simplified.kind === "add" || simplified.kind === "sub") {
1546
+ const left = integrate(simplified.left, variable);
1547
+ if (!left.ok) return left;
1548
+ const right = integrate(simplified.right, variable);
1549
+ if (!right.ok) return right;
1550
+ return {
1551
+ ok: true,
1552
+ value: chunkHTXVVJRA_cjs.simplifySymbolic({ kind: simplified.kind, left: left.value, right: right.value })
1553
+ };
1554
+ }
1555
+ if (simplified.kind === "mul" && simplified.left.kind === "const") {
1556
+ const inner = integrate(simplified.right, variable);
1557
+ if (!inner.ok) return inner;
1558
+ return { ok: true, value: chunkHTXVVJRA_cjs.simplifySymbolic({ kind: "mul", left: simplified.left, right: inner.value }) };
1559
+ }
1560
+ return {
1561
+ ok: false,
1562
+ reason: "no elementary antiderivative is known for this expression"
1563
+ };
1564
+ }
1565
+
1566
+ // src/symbolic/Taylor.ts
1567
+ var TAYLOR_MAX_DEGREE = 16;
1568
+ function taylorSeries(node, variable, point, degree) {
1569
+ if (degree < 0 || !Number.isInteger(degree) || degree > TAYLOR_MAX_DEGREE) {
1570
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1571
+ "SYMBOLIC_TAYLOR_DEGREE_LIMIT",
1572
+ `A Taylor degree must be a whole number from 0 to ${TAYLOR_MAX_DEGREE}.`,
1573
+ { limit: TAYLOR_MAX_DEGREE }
1574
+ );
1575
+ }
1576
+ const pointNode = chunkHTXVVJRA_cjs.constNode(point);
1577
+ let factorial = 1n;
1578
+ let result = chunkHTXVVJRA_cjs.constNode(chunkHTXVVJRA_cjs.RATIONAL_ZERO);
1579
+ for (let order = 0; order <= degree; order++) {
1580
+ if (order > 0) factorial *= BigInt(order);
1581
+ const derivative = differentiate(node, variable, order);
1582
+ const atPoint = chunkHTXVVJRA_cjs.simplifySymbolic(chunkHTXVVJRA_cjs.substitute(derivative, variable, pointNode));
1583
+ if (atPoint.kind !== "const") {
1584
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1585
+ "SYMBOLIC_TAYLOR_INEXACT",
1586
+ `The derivative of order ${order} does not reduce to an exact number at the expansion point, so this series cannot be computed exactly.`,
1587
+ { order }
1588
+ );
1589
+ }
1590
+ const coefficient = chunkHTXVVJRA_cjs.rationalDiv(atPoint.value, { n: factorial, d: 1n });
1591
+ if (chunkHTXVVJRA_cjs.isRationalZero(coefficient)) continue;
1592
+ const shifted = chunkHTXVVJRA_cjs.isRationalZero(point) ? chunkHTXVVJRA_cjs.varNode(variable) : { kind: "sub", left: chunkHTXVVJRA_cjs.varNode(variable), right: pointNode };
1593
+ const power2 = order === 0 ? chunkHTXVVJRA_cjs.constNode(1) : order === 1 ? shifted : chunkHTXVVJRA_cjs.powNode(shifted, chunkHTXVVJRA_cjs.constNode(order));
1594
+ result = { kind: "add", left: result, right: { kind: "mul", left: chunkHTXVVJRA_cjs.constNode(coefficient), right: power2 } };
1595
+ }
1596
+ return chunkHTXVVJRA_cjs.simplifySymbolic(result);
1597
+ }
1598
+ function jacobian(functions, variables) {
1599
+ return functions.map((fn) => variables.map((variable) => differentiate(fn, variable)));
1600
+ }
1601
+
1602
+ // src/engine/EngineContext.ts
1603
+ function createEngineContext() {
1604
+ return {
1605
+ pluginFunctions: {},
1606
+ opRegistry: new OpRegistry(),
1607
+ variableResolver: new chunkFEAIOR7N_cjs.VariableResolver(),
1608
+ pluginFunctionOwners: {}
1609
+ };
1610
+ }
1611
+ var defaultEngineContext = createEngineContext();
1612
+
1613
+ // src/packages/finance/data/CpiTable.ts
1614
+ var CPI_TABLE = {
1615
+ 1970: 38.8,
1616
+ 1971: 40.5,
1617
+ 1972: 41.8,
1618
+ 1973: 44.4,
1619
+ 1974: 49.3,
1620
+ 1975: 53.8,
1621
+ 1976: 56.9,
1622
+ 1977: 60.6,
1623
+ 1978: 65.2,
1624
+ 1979: 72.6,
1625
+ 1980: 82.4,
1626
+ 1981: 90.9,
1627
+ 1982: 96.5,
1628
+ 1983: 99.6,
1629
+ 1984: 103.9,
1630
+ 1985: 107.6,
1631
+ 1986: 109.6,
1632
+ 1987: 113.6,
1633
+ 1988: 118.3,
1634
+ 1989: 124,
1635
+ 1990: 130.7,
1636
+ 1991: 136.2,
1637
+ 1992: 140.3,
1638
+ 1993: 144.5,
1639
+ 1994: 148.2,
1640
+ 1995: 152.4,
1641
+ 1996: 156.9,
1642
+ 1997: 160.5,
1643
+ 1998: 163,
1644
+ 1999: 166.6,
1645
+ 2e3: 172.2,
1646
+ 2001: 177.1,
1647
+ 2002: 179.9,
1648
+ 2003: 184,
1649
+ 2004: 188.9,
1650
+ 2005: 195.3,
1651
+ 2006: 201.6,
1652
+ 2007: 207.3,
1653
+ 2008: 215.3,
1654
+ 2009: 214.5,
1655
+ 2010: 218.1,
1656
+ 2011: 224.9,
1657
+ 2012: 229.6,
1658
+ 2013: 233,
1659
+ 2014: 236.7,
1660
+ 2015: 237,
1661
+ 2016: 240,
1662
+ 2017: 245.1,
1663
+ 2018: 251.1,
1664
+ 2019: 255.7,
1665
+ 2020: 258.8,
1666
+ 2021: 271,
1667
+ 2022: 292.7,
1668
+ 2023: 304.7,
1669
+ 2024: 313.7,
1670
+ // 2025-2026: preliminary/projected estimates. See doc comment above.
1671
+ 2025: 320.6,
1672
+ 2026: 327.4
1673
+ };
1674
+ var CPI_MIN_YEAR = 1970;
1675
+ var CPI_MAX_YEAR = 2026;
1676
+ function getCpi(year) {
1677
+ return CPI_TABLE[Math.trunc(year)];
1678
+ }
1679
+ function inflationRatio(fromYear, toYear) {
1680
+ const fromCpi = getCpi(fromYear);
1681
+ const toCpi = getCpi(toYear);
1682
+ if (fromCpi === void 0 || toCpi === void 0 || fromCpi === 0) return void 0;
1683
+ return toCpi / fromCpi;
1684
+ }
1685
+ function adjustForInflation(amount, fromYear, toYear) {
1686
+ const ratio = inflationRatio(fromYear, toYear);
1687
+ if (ratio === void 0) return void 0;
1688
+ return amount * ratio;
1689
+ }
1690
+
1691
+ // src/vm/VMBuiltins.ts
1692
+ var builtinFunctions = {
1693
+ // ── Populated below ──
1694
+ // sqrt: a negative argument has a complex answer now that there is a complex
1695
+ // number to give, so this no longer quietly returns NaN. The exact path runs
1696
+ // first, so sqrt(-4) is 2i rather than an approximation.
1697
+ 0: (args) => {
1698
+ const value = args[0].toNumber();
1699
+ if (value >= 0) return chunkOC6LTXYS_cjs.numberValue(Math.sqrt(value));
1700
+ return symbolicToValue(chunkHTXVVJRA_cjs.callNode("sqrt", [chunkHTXVVJRA_cjs.constNode(value)]));
1701
+ },
1702
+ // abs(a): for a Matrix, "|a|" (Calca's determinant-pipe notation) is a
1703
+ // valid alias for det(a) (index 64), reusing the SAME implementation
1704
+ // not a separate one. Plain-number abs is unaffected.
1705
+ 1: (args) => args[0].type === 7 /* Matrix */ ? chunkHTXVVJRA_cjs.determinant(args[0].value) : chunkOC6LTXYS_cjs.numberValue(Math.abs(args[0].toNumber())),
1706
+ 2: (args) => chunkOC6LTXYS_cjs.numberValue(Math.sin(args[0].toNumber())),
1707
+ 3: (args) => chunkOC6LTXYS_cjs.numberValue(Math.cos(args[0].toNumber())),
1708
+ 4: (args) => chunkOC6LTXYS_cjs.numberValue(Math.tan(args[0].toNumber())),
1709
+ 5: (args) => chunkOC6LTXYS_cjs.numberValue(Math.log(args[0].toNumber())),
1710
+ 6: (args) => chunkOC6LTXYS_cjs.numberValue(Math.ceil(args[0].toNumber())),
1711
+ 7: (args) => chunkOC6LTXYS_cjs.numberValue(Math.floor(args[0].toNumber())),
1712
+ 8: (args) => chunkOC6LTXYS_cjs.numberValue(Math.round(args[0].toNumber())),
1713
+ // min/max: a plain loop replicating Math.min/Math.max's exact semantics
1714
+ // (NaN poisons the result regardless of position; empty args -> ±Infinity)
1715
+ // avoids the intermediate array .map()+spread allocates on every call.
1716
+ 9: (args) => {
1717
+ let result = Infinity;
1718
+ let hasNaN = false;
1719
+ for (const a of args) {
1720
+ const n = a.toNumber();
1721
+ if (Number.isNaN(n)) hasNaN = true;
1722
+ else if (n < result) result = n;
1723
+ }
1724
+ return chunkOC6LTXYS_cjs.numberValue(hasNaN ? NaN : result);
1725
+ },
1726
+ 10: (args) => {
1727
+ let result = -Infinity;
1728
+ let hasNaN = false;
1729
+ for (const a of args) {
1730
+ const n = a.toNumber();
1731
+ if (Number.isNaN(n)) hasNaN = true;
1732
+ else if (n > result) result = n;
1733
+ }
1734
+ return chunkOC6LTXYS_cjs.numberValue(hasNaN ? NaN : result);
1735
+ },
1736
+ 11: (args) => chunkOC6LTXYS_cjs.numberValue(Math.asin(args[0].toNumber())),
1737
+ 12: (args) => chunkOC6LTXYS_cjs.numberValue(Math.acos(args[0].toNumber())),
1738
+ 13: (args) => chunkOC6LTXYS_cjs.numberValue(Math.atan(args[0].toNumber())),
1739
+ 14: (args) => chunkOC6LTXYS_cjs.numberValue(Math.atan2(args[0].toNumber(), args[1].toNumber())),
1740
+ 15: (args) => chunkOC6LTXYS_cjs.numberValue(Math.sinh(args[0].toNumber())),
1741
+ 16: (args) => chunkOC6LTXYS_cjs.numberValue(Math.cosh(args[0].toNumber())),
1742
+ 17: (args) => chunkOC6LTXYS_cjs.numberValue(Math.tanh(args[0].toNumber())),
1743
+ 18: (args) => chunkOC6LTXYS_cjs.numberValue(Math.asinh(args[0].toNumber())),
1744
+ 19: (args) => chunkOC6LTXYS_cjs.numberValue(Math.acosh(args[0].toNumber())),
1745
+ 20: (args) => chunkOC6LTXYS_cjs.numberValue(Math.atanh(args[0].toNumber())),
1746
+ 21: (args) => chunkOC6LTXYS_cjs.numberValue(Math.cbrt(args[0].toNumber())),
1747
+ 22: (args) => chunkOC6LTXYS_cjs.numberValue(Math.clz32(args[0].toNumber())),
1748
+ 23: (args) => chunkOC6LTXYS_cjs.numberValue(Math.expm1(args[0].toNumber())),
1749
+ 24: (args) => chunkOC6LTXYS_cjs.numberValue(Math.exp(args[0].toNumber())),
1750
+ 25: (args) => chunkOC6LTXYS_cjs.numberValue(Math.fround(args[0].toNumber())),
1751
+ // hypot: left as .map()+spread (unlike min/max above), Math.hypot uses
1752
+ // a numerically-stable scaling algorithm internally to avoid overflow
1753
+ // for very large/small inputs; a naive manual reimplementation risks
1754
+ // silently changing results at the extremes, so the tiny array
1755
+ // allocation here is the safer trade.
1756
+ 26: (args) => chunkOC6LTXYS_cjs.numberValue(Math.hypot(...args.map((a) => a.toNumber()))),
1757
+ 27: (args) => chunkOC6LTXYS_cjs.numberValue(Math.imul(args[0].toNumber(), args[1].toNumber())),
1758
+ 28: (args) => chunkOC6LTXYS_cjs.numberValue(Math.log10(args[0].toNumber())),
1759
+ 29: (args) => chunkOC6LTXYS_cjs.numberValue(Math.log1p(args[0].toNumber())),
1760
+ 30: (args) => chunkOC6LTXYS_cjs.numberValue(Math.log2(args[0].toNumber())),
1761
+ 31: (args) => chunkOC6LTXYS_cjs.numberValue(Math.pow(args[0].toNumber(), args[1].toNumber())),
1762
+ 32: () => chunkOC6LTXYS_cjs.numberValue(Math.random()),
1763
+ // takes no arguments, unlike its neighbours
1764
+ 33: (args) => chunkOC6LTXYS_cjs.numberValue(Math.sign(args[0].toNumber())),
1765
+ 34: (args) => chunkOC6LTXYS_cjs.numberValue(Math.trunc(args[0].toNumber())),
1766
+ 35: (args) => chunkOC6LTXYS_cjs.numberValue(args[0].toNumber() * Math.PI / 180),
1767
+ 36: (args) => chunkOC6LTXYS_cjs.numberValue(args[0].toNumber() * 180 / Math.PI),
1768
+ // 37: diceRoll(from, to), random integer in range [from, to] inclusive.
1769
+ // A reversed range (from > to) used to silently produce values outside
1770
+ // [to, from] via a negative-length Math.random() spread (e.g.
1771
+ // "roll(6, 1)" returning values like 2-5, never 1 or 6) instead of
1772
+ // erroring on the invalid input.
1773
+ 37: (args) => {
1774
+ const from = args[0].toNumber();
1775
+ const to = args[1].toNumber();
1776
+ if (from > to) {
1777
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `roll: invalid range, ${from} is greater than ${to}`);
1778
+ }
1779
+ return chunkOC6LTXYS_cjs.numberValue(Math.floor(Math.random() * (to - from + 1)) + from);
1780
+ },
1781
+ // gcd(a, b), Euclidean algorithm. Negative inputs are treated by
1782
+ // magnitude (gcd is conventionally defined over non-negative integers).
1783
+ 38: (args) => {
1784
+ let a = Math.trunc(Math.abs(args[0].toNumber()));
1785
+ let b = Math.trunc(Math.abs(args[1].toNumber()));
1786
+ while (b !== 0) {
1787
+ const t = b;
1788
+ b = a % b;
1789
+ a = t;
1790
+ }
1791
+ return chunkOC6LTXYS_cjs.numberValue(a);
1792
+ },
1793
+ // lcm(a, b) = |a*b| / gcd(a, b), via the same Euclidean gcd inline
1794
+ // (a standalone gcd() call site, no shared helper needed for two uses).
1795
+ 39: (args) => {
1796
+ const a = Math.trunc(Math.abs(args[0].toNumber()));
1797
+ const b = Math.trunc(Math.abs(args[1].toNumber()));
1798
+ if (a === 0 || b === 0) return chunkOC6LTXYS_cjs.numberValue(0);
1799
+ let x = a, y = b;
1800
+ while (y !== 0) {
1801
+ const t = y;
1802
+ y = x % y;
1803
+ x = t;
1804
+ }
1805
+ return chunkOC6LTXYS_cjs.numberValue(a / x * b);
1806
+ },
1807
+ // permutation(n, r) = n! / (n-r)!, computed as a running product
1808
+ // rather than two full factorials, so it stays exact for n well
1809
+ // beyond where n! itself would exceed Number.MAX_SAFE_INTEGER.
1810
+ 40: (args) => {
1811
+ const n = Math.trunc(args[0].toNumber());
1812
+ const r = Math.trunc(args[1].toNumber());
1813
+ if (n < 0 || r < 0 || r > n) {
1814
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `permutation: invalid n=${n}, r=${r} (require 0 <= r <= n)`);
1815
+ }
1816
+ let result = 1;
1817
+ for (let i = 0; i < r; i++) result *= n - i;
1818
+ return chunkOC6LTXYS_cjs.numberValue(result);
1819
+ },
1820
+ // combination(n, r) = n! / (r! * (n-r)!), multiply-then-divide one
1821
+ // step at a time (standard technique) keeps every intermediate result
1822
+ // an integer, avoiding the overflow a naive factorial-ratio would hit.
1823
+ 41: (args) => {
1824
+ const n = Math.trunc(args[0].toNumber());
1825
+ const r = Math.trunc(args[1].toNumber());
1826
+ if (n < 0 || r < 0 || r > n) {
1827
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `combination: invalid n=${n}, r=${r} (require 0 <= r <= n)`);
1828
+ }
1829
+ const k = Math.min(r, n - r);
1830
+ let result = 1;
1831
+ for (let i = 0; i < k; i++) result = result * (n - i) / (i + 1);
1832
+ return chunkOC6LTXYS_cjs.numberValue(Math.round(result));
1833
+ },
1834
+ // average(...), arithmetic mean of any number of arguments. Backs the
1835
+ // MathPhrases package's "average of X, Y, Z" (packages/mathphrases/).
1836
+ 42: (args) => {
1837
+ if (args.length === 0) return chunkOC6LTXYS_cjs.numberValue(0);
1838
+ const sum = args.reduce((acc, a) => acc + a.toNumber(), 0);
1839
+ return chunkOC6LTXYS_cjs.numberValue(sum / args.length);
1840
+ },
1841
+ // median(...), middle value; average of the two middle values for an
1842
+ // even argument count.
1843
+ 43: (args) => {
1844
+ if (args.length === 0) return chunkOC6LTXYS_cjs.numberValue(0);
1845
+ const sorted = args.map((a) => a.toNumber()).sort((a, b) => a - b);
1846
+ const mid = Math.floor(sorted.length / 2);
1847
+ return chunkOC6LTXYS_cjs.numberValue(
1848
+ sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]
1849
+ );
1850
+ },
1851
+ // total(...), sum of any number of arguments.
1852
+ 44: (args) => chunkOC6LTXYS_cjs.numberValue(args.reduce((acc, a) => acc + a.toNumber(), 0)),
1853
+ // count(...), number of arguments passed.
1854
+ 45: (args) => chunkOC6LTXYS_cjs.numberValue(args.length),
1855
+ // proportion(a, b, c) -> d such that a:b = c:d, i.e. d = c * (b/a)
1856
+ // "A is to B as C is to what". Unit-aware via unifyUom: "5 km is to
1857
+ // 500m as 5 cm is to what" unifies 5km/500m to a 10:1 ratio (500m ==
1858
+ // 0.5km), so 5cm at the same ratio -> 0.5cm. Falls back to plain
1859
+ // toNumber() ratios when the units aren't the same measure (unifyUom's
1860
+ // own fallback) rather than guessing at an unsupported conversion.
1861
+ 46: (args) => {
1862
+ const [a, b, c] = args;
1863
+ const { lv: aNum, rv: bNum } = unifyUom(a, b);
1864
+ if (aNum === 0) {
1865
+ return chunkOC6LTXYS_cjs.errorValue("PROPORTION_DIVIDE_BY_ZERO", `Cannot compute proportion: "${a.value}" is zero`);
1866
+ }
1867
+ const result = c.toNumber() * (bNum / aNum);
1868
+ return c.type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(result, c.unit) : chunkOC6LTXYS_cjs.numberValue(result);
1869
+ },
1870
+ // clamp(value, lo, hi), restrict value to [lo, hi]. Backs
1871
+ // "clamp X between Y and Z" / "clamp X from Y to Z".
1872
+ 47: (args) => {
1873
+ const value = args[0].toNumber();
1874
+ const lo = args[1].toNumber();
1875
+ const hi = args[2].toNumber();
1876
+ if (lo > hi) {
1877
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `clamp: invalid range, ${lo} is greater than ${hi}`);
1878
+ }
1879
+ return chunkOC6LTXYS_cjs.numberValue(Math.min(Math.max(value, lo), hi));
1880
+ },
1881
+ // hex(n), Python/JS-style call-syntax hex formatting, e.g. hex(255) ->
1882
+ // "0xFF". Distinct from the Converters package's `255 as hex` (see
1883
+ // packages/converters/parselets/AsConverterParselet.ts): "as hex"
1884
+ // produces a ValueType.Hex (a typed NUMBER that still participates in
1885
+ // arithmetic, formatted specially on display), while hex() is a plain
1886
+ // function call that returns an ordinary String value, matching
1887
+ // Python's hex()/JS convention of a function returning display text,
1888
+ // not a numeric type.
1889
+ 48: (args) => chunkOC6LTXYS_cjs.hexValue(args[0].toNumber()),
1890
+ // bin(n). Same call-syntax shape as hex() above, e.g. bin(10) -> "0b1010".
1891
+ 49: (args) => chunkOC6LTXYS_cjs.hexValue(args[0].toNumber(), "bin"),
1892
+ // int(x), coerce ANY value (Number, Percentage, Uom, String, Hex, ...)
1893
+ // to a plain integer Number, truncating any fractional part toward
1894
+ // zero (Math.trunc semantics: int(5.7) -> 5, int(-5.7) -> -5). Distinct
1895
+ // from the Converters package's `x as number` (TO_NUMBER opcode),
1896
+ // which only strips a unit/percentage wrapper and keeps any decimal
1897
+ // part (e.g. "5.7 as number" -> 5.7), int() additionally truncates.
1898
+ 50: (args) => chunkOC6LTXYS_cjs.numberValue(Math.trunc(args[0].toNumber())),
1899
+ // ── Finance (packages/finance/) ──────────────────────────────────────
1900
+ // All finance builtins preserve the principal/amount argument's Uom
1901
+ // unit (e.g. a currency like "$") onto the result, matching
1902
+ // ProportionParselet's convention (index 46, above), a plain-number
1903
+ // input produces a plain-number result.
1904
+ //
1905
+ // `rate` arguments are always a decimal fraction (e.g. 0.07 for 7%)
1906
+ // this is how "%" already normalizes everywhere else in this codebase
1907
+ // (see packages/percentage/parselets/PercentParselet.ts: "7%" divides
1908
+ // by 100 at parse time, producing a plain Number 0.07, not a distinct
1909
+ // percentage type). Writing "at 7" instead of "at 7%" in a phrase form
1910
+ // passes 7 as-is (not 0.07), the "%" is not implicit.
1911
+ // compoundFutureValue(principal, rate, years) -> FV = P*(1+r)^years.
1912
+ // Backs "compound interest on $P over Y years at R%" and the
1913
+ // compoundInterest(principal, rate, years) function-call form.
1914
+ 51: (args) => {
1915
+ const principal = args[0].toNumber();
1916
+ const rate = args[1].toNumber();
1917
+ const years = args[2].toNumber();
1918
+ if (1 + rate <= 0) {
1919
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `compoundInterest: rate ${rate} makes (1 + rate) non-positive`);
1920
+ }
1921
+ const fv = principal * Math.pow(1 + rate, years);
1922
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(fv, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(fv);
1923
+ },
1924
+ // compoundInterestEarned(principal, rate, years) -> FV - principal, the
1925
+ // interest-only portion. Backs "interest on $P over Y years at R%" and
1926
+ // the interestEarned(principal, rate, years) function-call form.
1927
+ 52: (args) => {
1928
+ const principal = args[0].toNumber();
1929
+ const rate = args[1].toNumber();
1930
+ const years = args[2].toNumber();
1931
+ if (1 + rate <= 0) {
1932
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `interestEarned: rate ${rate} makes (1 + rate) non-positive`);
1933
+ }
1934
+ const interest = principal * (Math.pow(1 + rate, years) - 1);
1935
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(interest, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(interest);
1936
+ },
1937
+ // compoundInterestRate(principal, futureValue, years) -> the rate (as a
1938
+ // decimal fraction) needed to grow principal to futureValue over years.
1939
+ // Function-call only, no clean phrase form for a reverse calculation
1940
+ // like this without inventing awkward new keywords, so it's scoped to
1941
+ // compoundInterestRate(...) rather than a natural-language phrase.
1942
+ 53: (args) => {
1943
+ const principal = args[0].toNumber();
1944
+ const futureValue = args[1].toNumber();
1945
+ const years = args[2].toNumber();
1946
+ if (principal <= 0 || futureValue <= 0) {
1947
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `compoundInterestRate: principal and futureValue must both be positive`);
1948
+ }
1949
+ if (years <= 0) {
1950
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `compoundInterestRate: years must be greater than 0`);
1951
+ }
1952
+ return chunkOC6LTXYS_cjs.numberValue(Math.pow(futureValue / principal, 1 / years) - 1);
1953
+ },
1954
+ // compoundInterestYears(principal, futureValue, rate) -> the number of
1955
+ // years needed to grow principal to futureValue at a fixed rate.
1956
+ // Function-call only, same reasoning as index 53 above.
1957
+ 54: (args) => {
1958
+ const principal = args[0].toNumber();
1959
+ const futureValue = args[1].toNumber();
1960
+ const rate = args[2].toNumber();
1961
+ if (principal <= 0 || futureValue <= 0) {
1962
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `compoundInterestYears: principal and futureValue must both be positive`);
1963
+ }
1964
+ if (1 + rate <= 0 || rate === 0) {
1965
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `compoundInterestYears: rate ${rate} is not usable (must be > -1 and not 0)`);
1966
+ }
1967
+ return chunkOC6LTXYS_cjs.numberValue(Math.log(futureValue / principal) / Math.log(1 + rate));
1968
+ },
1969
+ // loanRepayment(principal, rate, years, periodsPerYear), standard
1970
+ // amortizing-loan repayment (mortgage formula), redistributed evenly
1971
+ // across `periodsPerYear` periods/year: 365=daily, 12=monthly, 1=annual,
1972
+ // 0=total over the life of the loan. The loan is ALWAYS amortized
1973
+ // monthly internally (the standard mortgage convention) regardless of
1974
+ // periodsPerYear, "daily"/"annual"/"total" are the same total
1975
+ // repayment redistributed, not separately-amortized loans. Verified
1976
+ // against real worked numbers (principal=$10,000, rate=6%, years=6):
1977
+ // monthly $165.73, annual $1,988.75 (== total/years exactly), daily
1978
+ // $5.45 (== total/(years*365)), total $11,932.48.
1979
+ // Backs "daily/monthly/annual/total repayment on $P over Y years at R%".
1980
+ 55: (args) => {
1981
+ const principal = args[0].toNumber();
1982
+ const rate = args[1].toNumber();
1983
+ const years = args[2].toNumber();
1984
+ const periodsPerYear = args[3].toNumber();
1985
+ if (principal <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanRepayment: principal must be positive`);
1986
+ if (years <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanRepayment: years must be positive`);
1987
+ if (rate < 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `loanRepayment: rate must not be negative`);
1988
+ if (periodsPerYear < 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanRepayment: periodsPerYear must not be negative`);
1989
+ const { totalRepayment } = amortizeLoan(principal, rate, years);
1990
+ const result = periodsPerYear === 0 ? totalRepayment : totalRepayment / (years * periodsPerYear);
1991
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(result, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(result);
1992
+ },
1993
+ // loanInterest(principal, rate, years, periodsPerYear), the interest
1994
+ // portion of index 55's repayment, same periodsPerYear convention.
1995
+ // Backs "daily/monthly/annual/total interest on $P over Y years at R%".
1996
+ 56: (args) => {
1997
+ const principal = args[0].toNumber();
1998
+ const rate = args[1].toNumber();
1999
+ const years = args[2].toNumber();
2000
+ const periodsPerYear = args[3].toNumber();
2001
+ if (principal <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanInterest: principal must be positive`);
2002
+ if (years <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanInterest: years must be positive`);
2003
+ if (rate < 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `loanInterest: rate must not be negative`);
2004
+ if (periodsPerYear < 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `loanInterest: periodsPerYear must not be negative`);
2005
+ const { totalInterest } = amortizeLoan(principal, rate, years);
2006
+ const result = periodsPerYear === 0 ? totalInterest : totalInterest / (years * periodsPerYear);
2007
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(result, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(result);
2008
+ },
2009
+ // monthlyPayment(principal, rate, years), convenience 3-arg wrapper
2010
+ // around index 55's monthly case, for direct function-call use without
2011
+ // the periodsPerYear parameter (the task's minimum-ask function form).
2012
+ 57: (args) => {
2013
+ const principal = args[0].toNumber();
2014
+ const rate = args[1].toNumber();
2015
+ const years = args[2].toNumber();
2016
+ if (principal <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `monthlyPayment: principal must be positive`);
2017
+ if (years <= 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE", `monthlyPayment: years must be positive`);
2018
+ if (rate < 0) return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `monthlyPayment: rate must not be negative`);
2019
+ const { monthlyPayment } = amortizeLoan(principal, rate, years);
2020
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(monthlyPayment, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(monthlyPayment);
2021
+ },
2022
+ // taxAdd(amount, rate) -> amount * (1 + rate). Backs "tax on $X at R%" /
2023
+ // "VAT on $X at R%". No default rate is baked in anywhere, the caller
2024
+ // always supplies one explicitly, since tax rates vary by region and
2025
+ // change over time; this package makes no assumption about which rate
2026
+ // applies.
2027
+ 58: (args) => {
2028
+ const amount = args[0].toNumber();
2029
+ const rate = args[1].toNumber();
2030
+ const result = amount * (1 + rate);
2031
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(result, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(result);
2032
+ },
2033
+ // taxRemove(amount, rate) -> amount / (1 + rate), extracts the
2034
+ // pre-tax amount from a tax-INCLUSIVE total. Backs "tax off $X at R%" /
2035
+ // "VAT off $X at R%".
2036
+ 59: (args) => {
2037
+ const amount = args[0].toNumber();
2038
+ const rate = args[1].toNumber();
2039
+ if (1 + rate <= 0) {
2040
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_RATE", `taxRemove: rate ${rate} makes (1 + rate) non-positive`);
2041
+ }
2042
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(amount / (1 + rate), args[0].unit) : chunkOC6LTXYS_cjs.numberValue(amount / (1 + rate));
2043
+ },
2044
+ // inflationAdjust(amount, fromYear, toYear) -- CPI-based inflation
2045
+ // adjustment between two arbitrary years, using the bundled CPI-U
2046
+ // table (packages/finance/data/CpiTable.ts -- see its doc comment for
2047
+ // vintage/accuracy notes). Backs the function-call form
2048
+ // inflationAdjust(...) (FunctionCallParselet's builtinNameToIndex map)
2049
+ // and the "what is $X in fromYear worth in toYear" phrase form
2050
+ // (InflationQueryParselet.ts). The two present-year-relative phrase
2051
+ // forms ("what is $X from year" / "what was $X worth in year" / "$X
2052
+ // in year dollars") and the flat-rate future-value projection ("value
2053
+ // of $X in year assuming N% inflation") are collision-safe
2054
+ // pluginFunctions instead, not indices here -- see
2055
+ // packages/finance/parselets/InflationPluginFunctions.ts.
2056
+ 60: (args) => {
2057
+ const amount = args[0].toNumber();
2058
+ const fromYear = args[1].toNumber();
2059
+ const toYear = args[2].toNumber();
2060
+ const ratio = inflationRatio(fromYear, toYear);
2061
+ if (ratio === void 0) {
2062
+ return chunkOC6LTXYS_cjs.errorValue(
2063
+ "INFLATION_YEAR_OUT_OF_RANGE",
2064
+ `inflationAdjust: fromYear ${fromYear} or toYear ${toYear} is outside the bundled CPI table's range (${CPI_MIN_YEAR}-${CPI_MAX_YEAR})`
2065
+ );
2066
+ }
2067
+ const result = amount * ratio;
2068
+ return args[0].type === 6 /* Uom */ ? chunkOC6LTXYS_cjs.uomValue(result, args[0].unit) : chunkOC6LTXYS_cjs.numberValue(result);
2069
+ },
2070
+ // root(n, x) -- the n-th root of x (Numi's `root n (x)` phrasing maps
2071
+ // to this same call-style form; see FunctionCallParselet's name map).
2072
+ // No native Math.root exists (unlike Math.cbrt for n=3 specifically),
2073
+ // so this is Math.pow(x, 1/n) directly -- exact for n=2/n=3 modulo the
2074
+ // usual floating-point pow() rounding, same precision class as every
2075
+ // other builtin here.
2076
+ 61: (args) => {
2077
+ const n = args[0].toNumber();
2078
+ const x = args[1].toNumber();
2079
+ return chunkOC6LTXYS_cjs.numberValue(Math.pow(x, 1 / n));
2080
+ },
2081
+ // fact(n) / factorial(n) -- integer factorial. Deliberately rejects
2082
+ // negative or non-integer input (factorial isn't defined for either
2083
+ // without a gamma-function generalization this engine doesn't need) and
2084
+ // caps at 170 -- Number.MAX_VALUE overflows to Infinity at 171!, so
2085
+ // returning a silently-wrong (or silently-infinite) result past that
2086
+ // point would be worse than a clear error.
2087
+ 62: (args) => {
2088
+ const n = args[0].toNumber();
2089
+ if (!Number.isInteger(n) || n < 0) {
2090
+ return chunkOC6LTXYS_cjs.errorValue("INVALID_FACTORIAL_INPUT", `fact: ${n} is not a non-negative integer`);
2091
+ }
2092
+ if (n > 170) {
2093
+ return chunkOC6LTXYS_cjs.errorValue("FACTORIAL_OVERFLOW", `fact: ${n}! exceeds the maximum representable double (170! is the largest finite factorial)`);
2094
+ }
2095
+ let result = 1;
2096
+ for (let i = 2; i <= n; i++) result *= i;
2097
+ return chunkOC6LTXYS_cjs.numberValue(result);
2098
+ },
2099
+ // ── Matrix (packages/matrix/) ────────────────────────────────────────
2100
+ // transpose(a)/det(a)/inv(a)/dot(a,b), reachable both via ordinary
2101
+ // function-call syntax (this map) and via operator syntax (`^T`, `^-1`
2102
+ //. See PrecedenceParser.ts's CARET special-casing, which emits these
2103
+ // SAME indices) and `|a|` (abs()'s Matrix branch, index 1 above).
2104
+ // Real linear-algebra work lives in vm/MatrixOps.ts, shared by both
2105
+ // entry points rather than duplicated.
2106
+ // transpose(a), for a Matrix, swaps rows/cols. A plain Number is its
2107
+ // own transpose (a 1x1 "matrix" transposed is itself), matches this
2108
+ // engine's existing convention of treating a scalar as a trivial 1x1
2109
+ // matrix (see Value.ts's toNumber()/isNaN() 1x1 special case).
2110
+ 63: (args) => args[0].type === 7 /* Matrix */ ? chunkHTXVVJRA_cjs.transpose(args[0].value) : args[0],
2111
+ // det(a), determinant. A plain Number's "determinant" is itself (the
2112
+ // determinant of a 1x1 matrix [x] is x).
2113
+ 64: (args) => args[0].type === 7 /* Matrix */ ? chunkHTXVVJRA_cjs.determinant(args[0].value) : chunkOC6LTXYS_cjs.numberValue(args[0].toNumber()),
2114
+ // inv(a), matrix inverse for a Matrix; for a plain Number, `1/x`
2115
+ // (byte-identical to `Math.pow(x, -1)`, which is what `x^-1` computed
2116
+ // before this feature existed. See PrecedenceParser.ts's `^-1`
2117
+ // special-case doc comment for why this must stay exact).
2118
+ 65: (args) => {
2119
+ if (args[0].type === 7 /* Matrix */) return chunkHTXVVJRA_cjs.inverse(args[0].value);
2120
+ return chunkOC6LTXYS_cjs.numberValue(1 / args[0].toNumber());
2121
+ },
2122
+ // dot(a, b), matrix product / scalar-broadcast, the SAME dispatch as
2123
+ // the `*` operator between two matrices (vm/VM.ts's MUL case). Plain
2124
+ // Number operands multiply directly; a Number mixed with a Matrix
2125
+ // promotes the Number to a 1x1 Matrix first, so it broadcasts exactly
2126
+ // like matrixMultiply()'s own 1x1-scalar case.
2127
+ 66: (args) => {
2128
+ const [a, b] = args;
2129
+ if (a.type === 0 /* Number */ && b.type === 0 /* Number */) {
2130
+ return chunkOC6LTXYS_cjs.numberValue(a.toNumber() * b.toNumber());
2131
+ }
2132
+ const toMatrix = (v) => v.type === 7 /* Matrix */ ? v.value : { rows: 1, cols: 1, data: [v.toNumber()], hasSymbolic: false };
2133
+ return chunkHTXVVJRA_cjs.matrixMultiply(toMatrix(a), toMatrix(b));
2134
+ },
2135
+ // ── Symbolic algebra (packages/symbolic/) ──
2136
+ // expand(expr), multiplying out every product and power. Reached only
2137
+ // through its own parselet, never the builtinNameToIndex name map, so that
2138
+ // `expand` keeps working as an ordinary variable name; see
2139
+ // packages/symbolic/normalizer/SymbolicCallNormalizerRule.ts.
2140
+ //
2141
+ // A non-symbolic argument has nothing to expand and is returned unchanged,
2142
+ // which is why this does not go through the CALL_BUILTIN symbolic dispatch:
2143
+ // `expand(2+3)` is simply 5.
2144
+ 67: (args) => {
2145
+ const [value] = args;
2146
+ if (value.type !== 9 /* Symbolic */) return value;
2147
+ return symbolicToValue(chunkHTXVVJRA_cjs.expandSymbolic(value.value));
2148
+ },
2149
+ // factor(expr), writing a polynomial as a product of irreducible factors
2150
+ // over the RATIONALS. x^2-2 and x^2+1 come back unchanged, which is the
2151
+ // correct answer over that field rather than a failure; see symbolic/Factor.ts.
2152
+ 68: (args) => {
2153
+ const [value] = args;
2154
+ if (value.type !== 9 /* Symbolic */) return value;
2155
+ return symbolicToValue(factorSymbolic(value.value));
2156
+ },
2157
+ // solve(equation, variable), emitted by its own parselet as three stack
2158
+ // values: the two sides of the equation, then the variable NAME as a
2159
+ // String. Reading the name as a string rather than compiling it as a
2160
+ // variable read is what lets `solve(x^2-4=0, x)` work without `x` existing.
2161
+ 69: (args) => {
2162
+ const [lhsValue, rhsValue, variableValue] = args;
2163
+ if (variableValue?.type !== 3 /* String */) {
2164
+ return chunkOC6LTXYS_cjs.errorValue("SOLVE_REQUIRES_VARIABLE_NAME", "solve's second argument must be the name of the unknown.");
2165
+ }
2166
+ return solveEquationValues(lhsValue, rhsValue, variableValue.value);
2167
+ },
2168
+ // der(expr, variable, order), the symbolic derivative. Genuinely symbolic
2169
+ // rather than a finite difference, so it is exact.
2170
+ 70: (args) => {
2171
+ const [target, variableValue, orderValue] = args;
2172
+ const variable = symbolicVariableName(variableValue, "der");
2173
+ if (typeof variable !== "string") return variable;
2174
+ const expression = valueToSymbolic(target);
2175
+ if (expression === null) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "der needs an expression with an exact value.");
2176
+ return symbolicToValue(differentiate(expression, variable, orderValue?.toNumber() ?? 1));
2177
+ },
2178
+ // integral(expr, variable), the indefinite integral without a constant of
2179
+ // integration. Reports what it cannot do rather than approximating; see
2180
+ // symbolic/Integral.ts.
2181
+ 71: (args) => {
2182
+ const [target, variableValue] = args;
2183
+ const variable = symbolicVariableName(variableValue, "integral");
2184
+ if (typeof variable !== "string") return variable;
2185
+ const expression = valueToSymbolic(target);
2186
+ if (expression === null) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "integral needs an expression with an exact value.");
2187
+ const result = integrate(expression, variable);
2188
+ if (!result.ok) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_INTEGRAL_UNSUPPORTED", `Cannot integrate this: ${result.reason}.`);
2189
+ return symbolicToValue(result.value);
2190
+ },
2191
+ // taylor(expr, variable = point, degree).
2192
+ 72: (args) => {
2193
+ const [target, variableValue, pointValue, degreeValue] = args;
2194
+ const variable = symbolicVariableName(variableValue, "taylor");
2195
+ if (typeof variable !== "string") return variable;
2196
+ const expression = valueToSymbolic(target);
2197
+ const point = valueToSymbolic(pointValue);
2198
+ if (expression === null || point === null || point.kind !== "const") {
2199
+ return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "taylor needs an expression and an exact expansion point.");
2200
+ }
2201
+ return symbolicToValue(taylorSeries(expression, variable, point.value, degreeValue.toNumber()));
2202
+ },
2203
+ // jacobian(f1, f2, ...), variadic. The variables are not named: they come
2204
+ // from the union of the functions' own unknowns, sorted, matching Calca.
2205
+ 73: (args) => {
2206
+ const functions = [];
2207
+ for (const arg of args) {
2208
+ const node = valueToSymbolic(arg);
2209
+ if (node === null) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "jacobian needs expressions with exact values.");
2210
+ functions.push(node);
2211
+ }
2212
+ const variables = /* @__PURE__ */ new Set();
2213
+ for (const fn of functions) for (const name of chunkHTXVVJRA_cjs.freeVariables(fn)) variables.add(name);
2214
+ const sorted = [...variables].sort();
2215
+ if (sorted.length === 0) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_JACOBIAN_NO_VARIABLES", "jacobian needs at least one unknown to differentiate against.");
2216
+ const rows = jacobian(functions, sorted);
2217
+ const rowMajor = [];
2218
+ for (const row of rows) {
2219
+ for (const cell of row) rowMajor.push(chunkHTXVVJRA_cjs.symbolicToEntry(cell));
2220
+ }
2221
+ return chunkOC6LTXYS_cjs.matrixValue(rows.length, sorted.length, chunkHTXVVJRA_cjs.rowMajorToColumnMajor(rows.length, sorted.length, rowMajor));
2222
+ },
2223
+ // An imaginary literal, 3i. The parselet pushes the numeric part and this
2224
+ // turns it into an exact imaginary value.
2225
+ 74: (args) => symbolicToValue(chunkHTXVVJRA_cjs.complexNode(chunkHTXVVJRA_cjs.complex(chunkHTXVVJRA_cjs.RATIONAL_ZERO, chunkHTXVVJRA_cjs.rationalFromNumber(args[0].toNumber())))),
2226
+ // conj(z), re(z) and im(z). Each folds immediately for a literal and stays
2227
+ // symbolic for anything still carrying an unknown.
2228
+ 75: (args) => applyComplexAccessor("conj", args[0]),
2229
+ 76: (args) => applyComplexAccessor("re", args[0]),
2230
+ 77: (args) => applyComplexAccessor("im", args[0]),
2231
+ // cancel(expr), reducing a quotient of polynomials to lowest terms.
2232
+ 78: (args) => {
2233
+ const value = args[0];
2234
+ if (value.type !== 9 /* Symbolic */) return value;
2235
+ return symbolicToValue(chunkHTXVVJRA_cjs.cancelSymbolic(value.value));
2236
+ },
2237
+ // apart(expr), the partial-fraction decomposition of a rational function.
2238
+ 79: (args) => {
2239
+ const value = args[0];
2240
+ if (value.type !== 9 /* Symbolic */) return value;
2241
+ return symbolicToValue(apartSymbolic(value.value));
2242
+ }
2243
+ };
2244
+ function applyComplexAccessor(name, value) {
2245
+ const node = valueToSymbolic(value);
2246
+ if (node === null) return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", name + " needs a value with an exact number.");
2247
+ return symbolicToValue(chunkHTXVVJRA_cjs.callNode(name, [node]));
2248
+ }
2249
+ function symbolicVariableName(value, verb) {
2250
+ if (value?.type !== 3 /* String */) {
2251
+ return chunkOC6LTXYS_cjs.errorValue("SYMBOLIC_REQUIRES_VARIABLE_NAME", `${verb} needs the name of an unknown.`);
2252
+ }
2253
+ return value.value;
2254
+ }
2255
+ function amortizeLoan(principal, annualRate, years) {
2256
+ const n = years * 12;
2257
+ const rMonthly = annualRate / 12;
2258
+ const monthlyPayment = rMonthly === 0 ? principal / n : principal * rMonthly / (1 - Math.pow(1 + rMonthly, -n));
2259
+ const totalRepayment = monthlyPayment * n;
2260
+ const totalInterest = totalRepayment - principal;
2261
+ return { monthlyPayment, totalRepayment, totalInterest };
2262
+ }
2263
+ var pluginFunctionRegistry = defaultEngineContext.pluginFunctions;
2264
+ var MAX_PLUGIN_FUNCTION_INDEX = 255;
2265
+ var nextPluginFunctionIndex = 0;
2266
+ function allocatePluginFunctionIndex() {
2267
+ if (nextPluginFunctionIndex > MAX_PLUGIN_FUNCTION_INDEX) {
2268
+ throw chunkM4N5GA5Z_cjs.ErrorFactory.config(
2269
+ "PLUGIN_FUNCTION_INDEX_POOL_EXHAUSTED",
2270
+ `allocatePluginFunctionIndex: pool exhausted (max ${MAX_PLUGIN_FUNCTION_INDEX + 1} allocations).`
2271
+ );
2272
+ }
2273
+ return nextPluginFunctionIndex++;
2274
+ }
2275
+ var asConverterRegistry = /* @__PURE__ */ new Map();
2276
+ function registerAsConverter(name, handler) {
2277
+ const key = name.toLowerCase();
2278
+ const existing = asConverterRegistry.get(key);
2279
+ if (existing && existing !== handler) {
2280
+ console.warn(`[asConverterRegistry] Converter name "${key}" is already registered \u2014 overwriting.`);
2281
+ }
2282
+ asConverterRegistry.set(key, handler);
2283
+ }
2284
+ function unregisterAsConverter(name) {
2285
+ asConverterRegistry.delete(name.toLowerCase());
2286
+ }
2287
+
2288
+ // src/vm/GlobalVariableStore.ts
2289
+ var _GlobalVariableStore = class _GlobalVariableStore {
2290
+ constructor() {
2291
+ this.values = /* @__PURE__ */ new Map();
2292
+ this.listeners = /* @__PURE__ */ new Set();
2293
+ this.notifyDepth = 0;
2294
+ }
2295
+ get(name) {
2296
+ return this.values.get(name);
2297
+ }
2298
+ has(name) {
2299
+ return this.values.has(name);
2300
+ }
2301
+ /**
2302
+ * Last-write-wins: any document may call this for any name at any time.
2303
+ * Notifies listeners synchronously, within the same call, before
2304
+ * returning, so that ThreeTierEvaluator's dirty-marking (a listener)
2305
+ * and GlobalVariableAsyncResolver's first-write promise (also a
2306
+ * listener) both observe the new value immediately, no microtask delay.
2307
+ *
2308
+ * A write that does not CHANGE the stored value notifies nobody. This
2309
+ * is not just an optimisation, it is what stops a re-evaluation cycle
2310
+ * from sustaining itself. Every listener re-runs work in response to a
2311
+ * write (ThreeTierEvaluator marks dependent lines dirty; the playground
2312
+ * worker refreshes other documents), and those re-runs re-execute the
2313
+ * very STORE_GLOBAL_VAR opcode that produced this write. Re-evaluating
2314
+ * an unchanged `global :x = 5` line therefore used to re-notify, which
2315
+ * re-triggered the listeners, which re-evaluated... bounded only by
2316
+ * MAX_NOTIFY_DEPTH below, and only in DEPTH, so with more than one
2317
+ * writer the work per keystroke grew exponentially. Nothing observable
2318
+ * changed, so there is nothing for a listener to react to.
2319
+ */
2320
+ set(name, value) {
2321
+ const previous = this.values.get(name);
2322
+ this.values.set(name, value);
2323
+ if (previous !== void 0 && sameValue(previous, value)) return;
2324
+ this.notify(name, value);
2325
+ }
2326
+ notify(name, value) {
2327
+ if (this.notifyDepth >= _GlobalVariableStore.MAX_NOTIFY_DEPTH) return;
2328
+ this.notifyDepth++;
2329
+ try {
2330
+ for (const listener of this.listeners) listener(name, value);
2331
+ } finally {
2332
+ this.notifyDepth--;
2333
+ }
2334
+ }
2335
+ /**
2336
+ * Subscribe to every global-variable write (all names, callers filter
2337
+ * for the name(s) they care about). Returns an unsubscribe function;
2338
+ * callers MUST invoke it when disposing (e.g. ThreeTierEvaluator's
2339
+ * terminateWorker()) to avoid leaking listeners for closed documents.
2340
+ */
2341
+ subscribe(listener) {
2342
+ this.listeners.add(listener);
2343
+ return () => {
2344
+ this.listeners.delete(listener);
2345
+ };
2346
+ }
2347
+ /**
2348
+ * Full reset, test-only. Never called from production code paths;
2349
+ * globals must outlive any single engine's own clear()/dispose cycle.
2350
+ * Tests MUST call this in beforeEach/afterEach since this is a
2351
+ * module-level singleton whose state and listeners otherwise leak
2352
+ * across test cases and files.
2353
+ */
2354
+ clear() {
2355
+ this.values.clear();
2356
+ this.listeners.clear();
2357
+ this.notifyDepth = 0;
2358
+ }
2359
+ };
2360
+ /**
2361
+ * Guards against runaway cross-document write cycles: doc A's write
2362
+ * notifies doc B, whose dirty line, once evaluated, writes a global
2363
+ * that notifies doc C, ... eventually back to A. Same philosophy as the
2364
+ * VM's own instruction-limit safety net: stop propagating past the
2365
+ * limit rather than let a genuine cycle recurse unboundedly. The store
2366
+ * itself is left in a well-defined state either way. This only bounds
2367
+ * *notification* depth, never the value actually stored.
2368
+ */
2369
+ _GlobalVariableStore.MAX_NOTIFY_DEPTH = 64;
2370
+ var GlobalVariableStore = _GlobalVariableStore;
2371
+ function sameValue(a, b) {
2372
+ if (a.type !== b.type) return false;
2373
+ if (a.unit !== b.unit) return false;
2374
+ if ((a.timedOut ?? false) !== (b.timedOut ?? false)) return false;
2375
+ const av = a.value;
2376
+ const bv = b.value;
2377
+ if (Array.isArray(av) || Array.isArray(bv)) {
2378
+ if (!Array.isArray(av) || !Array.isArray(bv)) return false;
2379
+ if (av.length !== bv.length) return false;
2380
+ for (let i = 0; i < av.length; i++) {
2381
+ if (!Object.is(av[i], bv[i])) return false;
2382
+ }
2383
+ return true;
2384
+ }
2385
+ return Object.is(av, bv);
2386
+ }
2387
+ var sharedGlobalVariableStore = new GlobalVariableStore();
2388
+ function globalDagKey(name) {
2389
+ return `global:${name}`;
2390
+ }
2391
+
2392
+ exports.CPI_MAX_YEAR = CPI_MAX_YEAR;
2393
+ exports.CPI_MIN_YEAR = CPI_MIN_YEAR;
2394
+ exports.OpRegistry = OpRegistry;
2395
+ exports.SYMBOLIC_NATIVE_BUILTINS = SYMBOLIC_NATIVE_BUILTINS;
2396
+ exports.adjustForInflation = adjustForInflation;
2397
+ exports.allocatePluginFunctionIndex = allocatePluginFunctionIndex;
2398
+ exports.asConverterRegistry = asConverterRegistry;
2399
+ exports.binaryOp = binaryOp;
2400
+ exports.builtinFunctions = builtinFunctions;
2401
+ exports.createEngineContext = createEngineContext;
2402
+ exports.defaultEngineContext = defaultEngineContext;
2403
+ exports.globalDagKey = globalDagKey;
2404
+ exports.pluginFunctionRegistry = pluginFunctionRegistry;
2405
+ exports.registerAsConverter = registerAsConverter;
2406
+ exports.sharedGlobalVariableStore = sharedGlobalVariableStore;
2407
+ exports.sharedOpRegistry = sharedOpRegistry;
2408
+ exports.solveEquationValues = solveEquationValues;
2409
+ exports.symbolicBuiltin = symbolicBuiltin;
2410
+ exports.symbolicNeg = symbolicNeg;
2411
+ exports.symbolicPow = symbolicPow;
2412
+ exports.unifyUom = unifyUom;
2413
+ exports.unregisterAsConverter = unregisterAsConverter;
2414
+ //# sourceMappingURL=chunk-J73SJHR3.cjs.map
2415
+ //# sourceMappingURL=chunk-J73SJHR3.cjs.map