@classytic/stage 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/atomic/aufbau.d.mts +144 -0
  3. package/dist/atomic/aufbau.mjs +384 -0
  4. package/dist/atomic/elements.d.mts +67 -0
  5. package/dist/atomic/elements.mjs +785 -0
  6. package/dist/atomic/emission.d.mts +112 -0
  7. package/dist/atomic/emission.mjs +179 -0
  8. package/dist/atomic/index.d.mts +8 -0
  9. package/dist/atomic/index.mjs +9 -0
  10. package/dist/atomic/periodic.d.mts +82 -0
  11. package/dist/atomic/periodic.mjs +231 -0
  12. package/dist/atomic/properties.d.mts +100 -0
  13. package/dist/atomic/properties.mjs +574 -0
  14. package/dist/atomic/shells.d.mts +137 -0
  15. package/dist/atomic/shells.mjs +170 -0
  16. package/dist/atomic/trends.d.mts +148 -0
  17. package/dist/atomic/trends.mjs +225 -0
  18. package/dist/chem/chromatography.d.mts +66 -0
  19. package/dist/chem/chromatography.mjs +63 -0
  20. package/dist/chem/complex.d.mts +114 -0
  21. package/dist/chem/complex.mjs +234 -0
  22. package/dist/chem/cycle.d.mts +75 -0
  23. package/dist/chem/cycle.mjs +145 -0
  24. package/dist/chem/equation.d.mts +86 -0
  25. package/dist/chem/equation.mjs +168 -0
  26. package/dist/chem/formula.d.mts +90 -0
  27. package/dist/chem/formula.mjs +201 -0
  28. package/dist/chem/functional-groups.d.mts +31 -0
  29. package/dist/chem/functional-groups.mjs +187 -0
  30. package/dist/chem/hazard.d.mts +94 -0
  31. package/dist/chem/hazard.mjs +329 -0
  32. package/dist/chem/index.d.mts +34 -33
  33. package/dist/chem/index.mjs +34 -28
  34. package/dist/chem/ionic.d.mts +98 -0
  35. package/dist/chem/ionic.mjs +156 -0
  36. package/dist/chem/layout.d.mts +46 -0
  37. package/dist/chem/layout.mjs +342 -0
  38. package/dist/chem/lewis.d.mts +79 -0
  39. package/dist/chem/lewis.mjs +163 -0
  40. package/dist/chem/molecular-orbital.d.mts +114 -0
  41. package/dist/chem/molecular-orbital.mjs +201 -0
  42. package/dist/chem/molecule.d.mts +154 -0
  43. package/dist/chem/molecule.mjs +282 -0
  44. package/dist/chem/nmr.d.mts +153 -0
  45. package/dist/chem/nmr.mjs +165 -0
  46. package/dist/chem/polymer.d.mts +65 -0
  47. package/dist/chem/polymer.mjs +179 -0
  48. package/dist/chem/redox.d.mts +138 -0
  49. package/dist/chem/redox.mjs +328 -0
  50. package/dist/chem/relations.d.mts +183 -0
  51. package/dist/chem/relations.mjs +299 -0
  52. package/dist/chem/skeleton.d.mts +51 -0
  53. package/dist/chem/skeleton.mjs +186 -0
  54. package/dist/chem/solution.d.mts +116 -0
  55. package/dist/chem/solution.mjs +186 -0
  56. package/dist/chem/species.d.mts +47 -0
  57. package/dist/chem/species.mjs +128 -0
  58. package/dist/chem/stereo.d.mts +108 -0
  59. package/dist/chem/stereo.mjs +286 -0
  60. package/dist/chem/stoichiometry.d.mts +95 -0
  61. package/dist/chem/stoichiometry.mjs +145 -0
  62. package/dist/chem/synthesis.d.mts +113 -0
  63. package/dist/chem/synthesis.mjs +281 -0
  64. package/dist/chem/vsepr.d.mts +80 -0
  65. package/dist/chem/vsepr.mjs +247 -0
  66. package/dist/circuit/ac.d.mts +163 -0
  67. package/dist/circuit/ac.mjs +452 -0
  68. package/dist/circuit/dc.d.mts +92 -0
  69. package/dist/circuit/dc.mjs +333 -0
  70. package/dist/circuit/index.d.mts +5 -92
  71. package/dist/circuit/index.mjs +5 -332
  72. package/dist/circuit/network.d.mts +99 -0
  73. package/dist/circuit/network.mjs +440 -0
  74. package/dist/circuit/topology.d.mts +102 -0
  75. package/dist/circuit/topology.mjs +143 -0
  76. package/dist/colour/absorption.d.mts +79 -0
  77. package/dist/colour/absorption.mjs +137 -0
  78. package/dist/colour/index.d.mts +6 -0
  79. package/dist/colour/index.mjs +7 -0
  80. package/dist/colour/name.d.mts +14 -0
  81. package/dist/colour/name.mjs +76 -0
  82. package/dist/colour/observer.d.mts +31 -0
  83. package/dist/colour/observer.mjs +46 -0
  84. package/dist/colour/spectrum.d.mts +61 -0
  85. package/dist/colour/spectrum.mjs +108 -0
  86. package/dist/colour/srgb.d.mts +49 -0
  87. package/dist/colour/srgb.mjs +108 -0
  88. package/dist/core/constants.d.mts +138 -0
  89. package/dist/core/constants.mjs +139 -0
  90. package/dist/core/index.d.mts +3 -1
  91. package/dist/core/index.mjs +3 -1
  92. package/dist/core/vec3.d.mts +94 -0
  93. package/dist/core/vec3.mjs +123 -0
  94. package/dist/core/worked.d.mts +35 -0
  95. package/dist/core/worked.mjs +44 -0
  96. package/dist/electro/cell.d.mts +102 -0
  97. package/dist/electro/cell.mjs +170 -0
  98. package/dist/electro/conductivity.d.mts +157 -0
  99. package/dist/electro/conductivity.mjs +156 -0
  100. package/dist/electro/couples.d.mts +114 -0
  101. package/dist/electro/couples.mjs +334 -0
  102. package/dist/electro/electrolysis.d.mts +96 -0
  103. package/dist/electro/electrolysis.mjs +274 -0
  104. package/dist/electro/faraday.d.mts +150 -0
  105. package/dist/electro/faraday.mjs +118 -0
  106. package/dist/electro/index.d.mts +6 -0
  107. package/dist/electro/index.mjs +7 -0
  108. package/dist/finance/accounting/adjustments.d.mts +17 -0
  109. package/dist/finance/accounting/adjustments.mjs +202 -0
  110. package/dist/finance/accounting/analysis.d.mts +8 -0
  111. package/dist/finance/accounting/analysis.mjs +205 -0
  112. package/dist/finance/accounting/clubs.d.mts +21 -0
  113. package/dist/finance/accounting/clubs.mjs +217 -0
  114. package/dist/finance/accounting/company-statements.d.mts +7 -0
  115. package/dist/finance/accounting/company-statements.mjs +150 -0
  116. package/dist/finance/accounting/harness.d.mts +7 -0
  117. package/dist/finance/accounting/harness.mjs +45 -0
  118. package/dist/finance/accounting/index.d.mts +18 -0
  119. package/dist/finance/accounting/index.mjs +18 -0
  120. package/dist/finance/accounting/journalize.d.mts +16 -0
  121. package/dist/finance/accounting/journalize.mjs +128 -0
  122. package/dist/finance/accounting/manufacturing.d.mts +8 -0
  123. package/dist/finance/accounting/manufacturing.mjs +236 -0
  124. package/dist/finance/accounting/partnership.d.mts +7 -0
  125. package/dist/finance/accounting/partnership.mjs +152 -0
  126. package/dist/finance/accounting/period-case.d.mts +6 -0
  127. package/dist/finance/accounting/period-case.mjs +71 -0
  128. package/dist/finance/accounting/post.d.mts +9 -0
  129. package/dist/finance/accounting/post.mjs +84 -0
  130. package/dist/finance/accounting/precision.d.mts +9 -0
  131. package/dist/finance/accounting/precision.mjs +15 -0
  132. package/dist/finance/accounting/rules.d.mts +21 -0
  133. package/dist/finance/accounting/rules.mjs +37 -0
  134. package/dist/finance/accounting/solve.d.mts +28 -0
  135. package/dist/finance/accounting/solve.mjs +92 -0
  136. package/dist/finance/accounting/statements.d.mts +7 -0
  137. package/dist/finance/accounting/statements.mjs +142 -0
  138. package/dist/finance/accounting/types.d.mts +649 -0
  139. package/dist/finance/accounting/validate.d.mts +7 -0
  140. package/dist/finance/accounting/validate.mjs +67 -0
  141. package/dist/finance/accounting/verification.d.mts +24 -0
  142. package/dist/finance/accounting/verification.mjs +386 -0
  143. package/dist/finance/bizsim.d.mts +21 -39
  144. package/dist/finance/bizsim.mjs +276 -97
  145. package/dist/finance/index.d.mts +20 -43
  146. package/dist/finance/index.mjs +19 -77
  147. package/dist/finance/investment-math.d.mts +7 -0
  148. package/dist/finance/investment-math.mjs +18 -0
  149. package/dist/finance/management-accounting/budgeting.d.mts +7 -0
  150. package/dist/finance/management-accounting/budgeting.mjs +189 -0
  151. package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
  152. package/dist/finance/management-accounting/cash-budget.mjs +154 -0
  153. package/dist/finance/management-accounting/costing.d.mts +8 -0
  154. package/dist/finance/management-accounting/costing.mjs +175 -0
  155. package/dist/finance/management-accounting/decisions.d.mts +8 -0
  156. package/dist/finance/management-accounting/decisions.mjs +164 -0
  157. package/dist/finance/management-accounting/index.d.mts +13 -0
  158. package/dist/finance/management-accounting/index.mjs +13 -0
  159. package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
  160. package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
  161. package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
  162. package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
  163. package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
  164. package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
  165. package/dist/finance/management-accounting/management-case.d.mts +8 -0
  166. package/dist/finance/management-accounting/management-case.mjs +91 -0
  167. package/dist/finance/management-accounting/master-budget.d.mts +7 -0
  168. package/dist/finance/management-accounting/master-budget.mjs +137 -0
  169. package/dist/finance/management-accounting/production-costing.d.mts +8 -0
  170. package/dist/finance/management-accounting/production-costing.mjs +214 -0
  171. package/dist/finance/management-accounting/types.d.mts +644 -0
  172. package/dist/finance/management-accounting/variances.d.mts +7 -0
  173. package/dist/finance/management-accounting/variances.mjs +150 -0
  174. package/dist/index.d.mts +6 -6
  175. package/dist/index.mjs +1 -1
  176. package/dist/math/analysis.d.mts +61 -0
  177. package/dist/math/analysis.mjs +187 -0
  178. package/dist/math/answer-check.d.mts +50 -0
  179. package/dist/math/answer-check.mjs +106 -0
  180. package/dist/math/calculus.d.mts +4 -9
  181. package/dist/math/calculus.mjs +216 -7
  182. package/dist/math/complex.d.mts +93 -0
  183. package/dist/math/complex.mjs +239 -0
  184. package/dist/math/expr.d.mts +23 -0
  185. package/dist/math/expr.mjs +36 -0
  186. package/dist/math/index.d.mts +8 -22
  187. package/dist/math/index.mjs +8 -37
  188. package/dist/math/latex.mjs +2 -1
  189. package/dist/math/parse.mjs +1 -1
  190. package/dist/math/poly.d.mts +55 -0
  191. package/dist/math/poly.mjs +273 -0
  192. package/dist/math/rearrange.d.mts +14 -0
  193. package/dist/math/rearrange.mjs +125 -0
  194. package/dist/math/solve.d.mts +21 -0
  195. package/dist/math/solve.mjs +75 -0
  196. package/dist/networking/addressing.d.mts +26 -0
  197. package/dist/networking/addressing.mjs +33 -0
  198. package/dist/networking/cloud/access.d.mts +36 -0
  199. package/dist/networking/cloud/access.mjs +95 -0
  200. package/dist/networking/cloud/containers.d.mts +43 -0
  201. package/dist/networking/cloud/containers.mjs +54 -0
  202. package/dist/networking/cloud/edge.d.mts +17 -0
  203. package/dist/networking/cloud/edge.mjs +31 -0
  204. package/dist/networking/cloud/failure-domains.d.mts +19 -0
  205. package/dist/networking/cloud/failure-domains.mjs +22 -0
  206. package/dist/networking/cloud/geo-routing.d.mts +22 -0
  207. package/dist/networking/cloud/geo-routing.mjs +64 -0
  208. package/dist/networking/cloud/index.d.mts +18 -0
  209. package/dist/networking/cloud/index.mjs +19 -0
  210. package/dist/networking/cloud/inference-reliability.d.mts +30 -0
  211. package/dist/networking/cloud/inference-reliability.mjs +76 -0
  212. package/dist/networking/cloud/inference.d.mts +118 -0
  213. package/dist/networking/cloud/inference.mjs +179 -0
  214. package/dist/networking/cloud/infrastructure.d.mts +45 -0
  215. package/dist/networking/cloud/infrastructure.mjs +96 -0
  216. package/dist/networking/cloud/observability.d.mts +24 -0
  217. package/dist/networking/cloud/observability.mjs +34 -0
  218. package/dist/networking/cloud/orchestration.d.mts +32 -0
  219. package/dist/networking/cloud/orchestration.mjs +38 -0
  220. package/dist/networking/cloud/recovery.d.mts +21 -0
  221. package/dist/networking/cloud/recovery.mjs +27 -0
  222. package/dist/networking/cloud/releases.d.mts +42 -0
  223. package/dist/networking/cloud/releases.mjs +135 -0
  224. package/dist/networking/cloud/scaling.d.mts +25 -0
  225. package/dist/networking/cloud/scaling.mjs +65 -0
  226. package/dist/networking/cloud/secrets.d.mts +39 -0
  227. package/dist/networking/cloud/secrets.mjs +68 -0
  228. package/dist/networking/cloud/server-deployment.d.mts +29 -0
  229. package/dist/networking/cloud/server-deployment.mjs +72 -0
  230. package/dist/networking/cloud/storage.d.mts +16 -0
  231. package/dist/networking/cloud/storage.mjs +58 -0
  232. package/dist/networking/cloud/vpc.d.mts +18 -0
  233. package/dist/networking/cloud/vpc.mjs +100 -0
  234. package/dist/networking/delivery.d.mts +34 -0
  235. package/dist/networking/delivery.mjs +52 -0
  236. package/dist/networking/index.d.mts +47 -0
  237. package/dist/networking/index.mjs +47 -0
  238. package/dist/networking/ipv6.d.mts +28 -0
  239. package/dist/networking/ipv6.mjs +17 -0
  240. package/dist/networking/journeys.d.mts +83 -0
  241. package/dist/networking/journeys.mjs +161 -0
  242. package/dist/networking/models/airtime.d.mts +87 -0
  243. package/dist/networking/models/airtime.mjs +130 -0
  244. package/dist/networking/models/cellular.d.mts +157 -0
  245. package/dist/networking/models/cellular.mjs +252 -0
  246. package/dist/networking/models/encapsulation.d.mts +98 -0
  247. package/dist/networking/models/encapsulation.mjs +132 -0
  248. package/dist/networking/models/handover.d.mts +116 -0
  249. package/dist/networking/models/handover.mjs +209 -0
  250. package/dist/networking/models/handshake.d.mts +90 -0
  251. package/dist/networking/models/handshake.mjs +122 -0
  252. package/dist/networking/models/index.d.mts +14 -0
  253. package/dist/networking/models/index.mjs +15 -0
  254. package/dist/networking/models/media.d.mts +82 -0
  255. package/dist/networking/models/media.mjs +188 -0
  256. package/dist/networking/models/satellite.d.mts +86 -0
  257. package/dist/networking/models/satellite.mjs +121 -0
  258. package/dist/networking/models/spectrum.d.mts +83 -0
  259. package/dist/networking/models/spectrum.mjs +235 -0
  260. package/dist/networking/models/switch.d.mts +80 -0
  261. package/dist/networking/models/switch.mjs +155 -0
  262. package/dist/networking/models/vlan.d.mts +62 -0
  263. package/dist/networking/models/vlan.mjs +100 -0
  264. package/dist/networking/models/vpn.d.mts +66 -0
  265. package/dist/networking/models/vpn.mjs +125 -0
  266. package/dist/networking/models/wifi-privacy.d.mts +82 -0
  267. package/dist/networking/models/wifi-privacy.mjs +130 -0
  268. package/dist/networking/models/wifi.d.mts +240 -0
  269. package/dist/networking/models/wifi.mjs +562 -0
  270. package/dist/networking/nat-traversal.d.mts +24 -0
  271. package/dist/networking/nat-traversal.mjs +38 -0
  272. package/dist/networking/protocols.d.mts +17 -0
  273. package/dist/networking/protocols.mjs +57 -0
  274. package/dist/networking/queue.d.mts +12 -0
  275. package/dist/networking/queue.mjs +18 -0
  276. package/dist/networking/route-learning.d.mts +23 -0
  277. package/dist/networking/route-learning.mjs +43 -0
  278. package/dist/networking/routing.d.mts +11 -0
  279. package/dist/networking/routing.mjs +25 -0
  280. package/dist/networking/signals.d.mts +26 -0
  281. package/dist/networking/signals.mjs +35 -0
  282. package/dist/networking/subnet.d.mts +49 -0
  283. package/dist/networking/subnet.mjs +89 -0
  284. package/dist/networking/tcp-reliability.d.mts +24 -0
  285. package/dist/networking/tcp-reliability.mjs +38 -0
  286. package/dist/networking/topology/contract.d.mts +123 -0
  287. package/dist/networking/topology/index.d.mts +4 -0
  288. package/dist/networking/topology/index.mjs +4 -0
  289. package/dist/networking/topology/presets.d.mts +7 -0
  290. package/dist/networking/topology/presets.mjs +302 -0
  291. package/dist/networking/topology/simulation.d.mts +8 -0
  292. package/dist/networking/topology/simulation.mjs +179 -0
  293. package/dist/networking/wireless.d.mts +11 -0
  294. package/dist/networking/wireless.mjs +17 -0
  295. package/dist/optics/imaging.d.mts +218 -0
  296. package/dist/optics/imaging.mjs +276 -0
  297. package/dist/optics/index.d.mts +7 -0
  298. package/dist/optics/index.mjs +8 -0
  299. package/dist/optics/laws.d.mts +70 -0
  300. package/dist/optics/laws.mjs +195 -0
  301. package/dist/optics/prism.d.mts +148 -0
  302. package/dist/optics/prism.mjs +197 -0
  303. package/dist/optics/refraction.d.mts +201 -0
  304. package/dist/optics/refraction.mjs +270 -0
  305. package/dist/optics/wave-optics.d.mts +171 -0
  306. package/dist/optics/wave-optics.mjs +259 -0
  307. package/dist/physics/ac/index.d.mts +183 -0
  308. package/dist/physics/ac/index.mjs +203 -0
  309. package/dist/physics/dynamics/forces.d.mts +98 -0
  310. package/dist/physics/dynamics/forces.mjs +153 -0
  311. package/dist/physics/dynamics/friction.d.mts +76 -0
  312. package/dist/physics/dynamics/friction.mjs +119 -0
  313. package/dist/physics/dynamics/system.d.mts +68 -0
  314. package/dist/physics/dynamics/system.mjs +125 -0
  315. package/dist/physics/electrostatics/index.d.mts +169 -0
  316. package/dist/physics/electrostatics/index.mjs +249 -0
  317. package/dist/physics/energy/centre-of-mass.d.mts +115 -0
  318. package/dist/physics/energy/centre-of-mass.mjs +180 -0
  319. package/dist/physics/energy/conservation.d.mts +81 -0
  320. package/dist/physics/energy/conservation.mjs +129 -0
  321. package/dist/physics/energy/power.d.mts +90 -0
  322. package/dist/physics/energy/power.mjs +167 -0
  323. package/dist/physics/energy/spring.d.mts +73 -0
  324. package/dist/physics/energy/spring.mjs +129 -0
  325. package/dist/physics/energy/store.d.mts +63 -0
  326. package/dist/physics/energy/store.mjs +108 -0
  327. package/dist/physics/energy/theorem.d.mts +65 -0
  328. package/dist/physics/energy/theorem.mjs +113 -0
  329. package/dist/physics/energy/work.d.mts +114 -0
  330. package/dist/physics/energy/work.mjs +219 -0
  331. package/dist/physics/gravitation/body.d.mts +85 -0
  332. package/dist/physics/gravitation/body.mjs +168 -0
  333. package/dist/physics/gravitation/kepler.d.mts +127 -0
  334. package/dist/physics/gravitation/kepler.mjs +216 -0
  335. package/dist/physics/gravitation/law.d.mts +117 -0
  336. package/dist/physics/gravitation/law.mjs +175 -0
  337. package/dist/physics/gravitation/orbit.d.mts +119 -0
  338. package/dist/physics/gravitation/orbit.mjs +202 -0
  339. package/dist/physics/gravitation/potential.d.mts +114 -0
  340. package/dist/physics/gravitation/potential.mjs +202 -0
  341. package/dist/physics/gravitation/variation.d.mts +97 -0
  342. package/dist/physics/gravitation/variation.mjs +175 -0
  343. package/dist/physics/index.d.mts +35 -0
  344. package/dist/physics/index.mjs +36 -0
  345. package/dist/physics/integral-sweep.d.mts +63 -0
  346. package/dist/physics/integral-sweep.mjs +126 -0
  347. package/dist/physics/kinematics/equations.d.mts +47 -0
  348. package/dist/physics/kinematics/equations.mjs +126 -0
  349. package/dist/physics/kinematics/free-fall.d.mts +53 -0
  350. package/dist/physics/kinematics/free-fall.mjs +71 -0
  351. package/dist/physics/kinematics/given.d.mts +16 -0
  352. package/dist/physics/kinematics/given.mjs +55 -0
  353. package/dist/physics/kinematics/roots.d.mts +41 -0
  354. package/dist/physics/kinematics/roots.mjs +72 -0
  355. package/dist/physics/kinematics/solve.d.mts +52 -0
  356. package/dist/physics/kinematics/solve.mjs +172 -0
  357. package/dist/physics/magnetism/biot-savart.d.mts +161 -0
  358. package/dist/physics/magnetism/biot-savart.mjs +353 -0
  359. package/dist/physics/magnetism/flux.d.mts +94 -0
  360. package/dist/physics/magnetism/flux.mjs +313 -0
  361. package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
  362. package/dist/physics/magnetism/geomagnetism.mjs +184 -0
  363. package/dist/physics/magnetism/index.d.mts +12 -0
  364. package/dist/physics/magnetism/index.mjs +74 -0
  365. package/dist/physics/magnetism/lorentz.d.mts +28 -0
  366. package/dist/physics/magnetism/lorentz.mjs +88 -0
  367. package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
  368. package/dist/physics/magnetism/magnetic-force.mjs +169 -0
  369. package/dist/physics/momentum/collide.d.mts +77 -0
  370. package/dist/physics/momentum/collide.mjs +115 -0
  371. package/dist/physics/momentum/impulse.d.mts +89 -0
  372. package/dist/physics/momentum/impulse.mjs +159 -0
  373. package/dist/physics/momentum/planar.d.mts +60 -0
  374. package/dist/physics/momentum/planar.mjs +110 -0
  375. package/dist/physics/projectile.d.mts +107 -0
  376. package/dist/physics/projectile.mjs +185 -0
  377. package/dist/physics/rotation/angular.d.mts +85 -0
  378. package/dist/physics/rotation/angular.mjs +130 -0
  379. package/dist/physics/rotation/circular.d.mts +79 -0
  380. package/dist/physics/rotation/circular.mjs +131 -0
  381. package/dist/physics/rotation/inertia.d.mts +164 -0
  382. package/dist/physics/rotation/inertia.mjs +332 -0
  383. package/dist/physics/rotation/torque.d.mts +65 -0
  384. package/dist/physics/rotation/torque.mjs +134 -0
  385. package/dist/physics/vectors.d.mts +64 -0
  386. package/dist/physics/vectors.mjs +114 -0
  387. package/dist/quantity/index.d.mts +119 -0
  388. package/dist/quantity/index.mjs +417 -0
  389. package/dist/relation/derive.d.mts +74 -0
  390. package/dist/relation/derive.mjs +73 -0
  391. package/dist/relation/index.d.mts +56 -0
  392. package/dist/relation/index.mjs +234 -0
  393. package/dist/scene/evaluators.mjs +1 -1
  394. package/dist/sim/thermal.mjs +45 -20
  395. package/dist/thermo/calorimetry.d.mts +207 -0
  396. package/dist/thermo/calorimetry.mjs +345 -0
  397. package/dist/thermo/cycles.d.mts +142 -0
  398. package/dist/thermo/cycles.mjs +256 -0
  399. package/dist/thermo/entropy.d.mts +87 -0
  400. package/dist/thermo/entropy.mjs +140 -0
  401. package/dist/thermo/expansion.d.mts +130 -0
  402. package/dist/thermo/expansion.mjs +178 -0
  403. package/dist/thermo/gas.d.mts +197 -0
  404. package/dist/thermo/gas.mjs +279 -0
  405. package/dist/thermo/heat-transfer.d.mts +164 -0
  406. package/dist/thermo/heat-transfer.mjs +217 -0
  407. package/dist/thermo/index.d.mts +9 -82
  408. package/dist/thermo/index.mjs +9 -132
  409. package/dist/thermo/processes.d.mts +95 -0
  410. package/dist/thermo/processes.mjs +154 -0
  411. package/dist/thermo/temperature.d.mts +174 -0
  412. package/dist/thermo/temperature.mjs +236 -0
  413. package/dist/waves/damping.d.mts +224 -0
  414. package/dist/waves/damping.mjs +317 -0
  415. package/dist/waves/doppler.d.mts +72 -0
  416. package/dist/waves/doppler.mjs +125 -0
  417. package/dist/waves/index.d.mts +10 -0
  418. package/dist/waves/index.mjs +10 -0
  419. package/dist/waves/pendulum.d.mts +130 -0
  420. package/dist/waves/pendulum.mjs +211 -0
  421. package/dist/waves/pitch.d.mts +125 -0
  422. package/dist/waves/pitch.mjs +158 -0
  423. package/dist/waves/shm.d.mts +170 -0
  424. package/dist/waves/shm.mjs +279 -0
  425. package/dist/waves/springs.d.mts +103 -0
  426. package/dist/waves/springs.mjs +176 -0
  427. package/dist/waves/superposition.d.mts +124 -0
  428. package/dist/waves/superposition.mjs +196 -0
  429. package/dist/waves/wave.d.mts +154 -0
  430. package/dist/waves/wave.mjs +178 -0
  431. package/package.json +74 -2
@@ -0,0 +1,66 @@
1
+ //#region src/chem/chromatography.d.ts
2
+ /**
3
+ * chromatography, identifying a component by where it stops.
4
+ *
5
+ * WHAT THIS IS FOR. The arithmetic of a retention factor is one division, and one division is not an
6
+ * engine. What is worth computing is the IDENTIFICATION: given a set of reference values and a spot,
7
+ * which references does it match, and is that match unique?
8
+ *
9
+ * The answer is often "not unique", and that is the whole reason a second solvent exists. A learner
10
+ * told to run two solvents without being shown a case where one fails has been given a ritual. So
11
+ * {@link identify} reports ambiguity as a result rather than hiding it, and {@link resolvedBy} finds
12
+ * the solvent that breaks a tie.
13
+ *
14
+ * ## Why a tolerance, and why it is not optional
15
+ *
16
+ * An Rf is reproducible to about ±0.02 in practice, and less than that if the tank was not saturated
17
+ * or the temperature drifted. Matching on exact equality would make every real measurement fail and
18
+ * would teach that chromatography is more precise than it is. The tolerance is a parameter because
19
+ * it is a property of the experiment, not of the chemistry.
20
+ *
21
+ * Pure: no React, no pixels.
22
+ */
23
+ /** A substance and where it stops in each solvent the lab offers. */
24
+ interface Component {
25
+ readonly id: string;
26
+ readonly name: string;
27
+ /** Retention factor in each solvent, keyed by solvent id. Always between 0 and 1. */
28
+ readonly rf: Readonly<Record<string, number>>;
29
+ }
30
+ /**
31
+ * The retention factor: how far the spot went as a fraction of how far the solvent went.
32
+ *
33
+ * Both distances are measured from the pencil baseline. Refuses a spot that has overtaken the
34
+ * solvent front, which is not a measurement error to round away: it means the distances were
35
+ * measured from different places, usually the bottom of the plate rather than the baseline.
36
+ */
37
+ declare function retentionFactor(spotCm: number, frontCm: number): number;
38
+ /** Where a component's spot sits, given how far the solvent has run. */
39
+ declare const spotDistance: (component: Component, solvent: string, frontCm: number) => number;
40
+ /** What an identification attempt produced. */
41
+ interface Identification {
42
+ /** Every reference within tolerance, best match first. */
43
+ readonly matches: readonly Component[];
44
+ /** True when exactly one reference matches, so the spot is named. */
45
+ readonly unique: boolean;
46
+ }
47
+ /**
48
+ * Which references a measured Rf could be.
49
+ *
50
+ * Returns every candidate rather than the closest one. A spot that sits between two references has
51
+ * not identified anything, and reporting the nearest would turn a failed experiment into a confident
52
+ * wrong answer.
53
+ */
54
+ declare function identify(rf: number, references: readonly Component[], solvent: string, tolerance?: number): Identification;
55
+ /**
56
+ * A solvent in which two components can be told apart, or `undefined` if none can.
57
+ *
58
+ * This is the argument for running a second solvent, made as a computation. Two components that sit
59
+ * on top of each other in one solvent will usually separate in another, because the competition
60
+ * between the phases depends on the solvent as much as on the substance.
61
+ */
62
+ declare function resolvedBy(a: Component, b: Component, solvents: readonly string[], tolerance?: number): string | undefined;
63
+ /** Pairs that cannot be told apart in a given solvent, which is what makes a mixture ambiguous. */
64
+ declare function unresolvedPairs(components: readonly Component[], solvent: string, tolerance?: number): [Component, Component][];
65
+ //#endregion
66
+ export { Component, Identification, identify, resolvedBy, retentionFactor, spotDistance, unresolvedPairs };
@@ -0,0 +1,63 @@
1
+ //#region src/chem/chromatography.ts
2
+ /**
3
+ * The retention factor: how far the spot went as a fraction of how far the solvent went.
4
+ *
5
+ * Both distances are measured from the pencil baseline. Refuses a spot that has overtaken the
6
+ * solvent front, which is not a measurement error to round away: it means the distances were
7
+ * measured from different places, usually the bottom of the plate rather than the baseline.
8
+ */
9
+ function retentionFactor(spotCm, frontCm) {
10
+ if (frontCm <= 0) throw new Error("The solvent front has not moved, so there is no Rf to report.");
11
+ if (spotCm < 0) throw new Error("A spot cannot move backwards from the baseline.");
12
+ if (spotCm > frontCm) throw new Error(`A spot at ${spotCm} cm cannot be past a front at ${frontCm} cm: the solvent carries it, so Rf is at most 1. Measure both from the pencil baseline.`);
13
+ return spotCm / frontCm;
14
+ }
15
+ /** Where a component's spot sits, given how far the solvent has run. */
16
+ const spotDistance = (component, solvent, frontCm) => {
17
+ const rf = component.rf[solvent];
18
+ if (rf === void 0) throw new Error(`${component.name} has no measured Rf in ${solvent}.`);
19
+ return rf * frontCm;
20
+ };
21
+ /**
22
+ * Which references a measured Rf could be.
23
+ *
24
+ * Returns every candidate rather than the closest one. A spot that sits between two references has
25
+ * not identified anything, and reporting the nearest would turn a failed experiment into a confident
26
+ * wrong answer.
27
+ */
28
+ function identify(rf, references, solvent, tolerance = .03) {
29
+ const matches = references.filter((c) => c.rf[solvent] !== void 0 && Math.abs(c.rf[solvent] - rf) <= tolerance).sort((a, b) => Math.abs(a.rf[solvent] - rf) - Math.abs(b.rf[solvent] - rf));
30
+ return {
31
+ matches,
32
+ unique: matches.length === 1
33
+ };
34
+ }
35
+ /**
36
+ * A solvent in which two components can be told apart, or `undefined` if none can.
37
+ *
38
+ * This is the argument for running a second solvent, made as a computation. Two components that sit
39
+ * on top of each other in one solvent will usually separate in another, because the competition
40
+ * between the phases depends on the solvent as much as on the substance.
41
+ */
42
+ function resolvedBy(a, b, solvents, tolerance = .03) {
43
+ return solvents.find((s) => {
44
+ const ra = a.rf[s];
45
+ const rb = b.rf[s];
46
+ return ra !== void 0 && rb !== void 0 && Math.abs(ra - rb) > tolerance;
47
+ });
48
+ }
49
+ /** Pairs that cannot be told apart in a given solvent, which is what makes a mixture ambiguous. */
50
+ function unresolvedPairs(components, solvent, tolerance = .03) {
51
+ const out = [];
52
+ for (let i = 0; i < components.length; i += 1) for (let j = i + 1; j < components.length; j += 1) {
53
+ const a = components[i];
54
+ const b = components[j];
55
+ const ra = a.rf[solvent];
56
+ const rb = b.rf[solvent];
57
+ if (ra !== void 0 && rb !== void 0 && Math.abs(ra - rb) <= tolerance) out.push([a, b]);
58
+ }
59
+ return out;
60
+ }
61
+
62
+ //#endregion
63
+ export { identify, resolvedBy, retentionFactor, spotDistance, unresolvedPairs };
@@ -0,0 +1,114 @@
1
+ //#region src/chem/complex.d.ts
2
+ /**
3
+ * complex, the geometry and colour of a transition-metal complex ion.
4
+ *
5
+ * Three questions the syllabus asks about every complex, and they are all answered from the same
6
+ * declaration: what shape is it, how many isomers has it, and why is it that colour.
7
+ *
8
+ * ## Coordination number is not the number of ligands
9
+ *
10
+ * It is the number of COORDINATE BONDS, so a bidentate ligand counts twice. That single sentence
11
+ * settles a question learners routinely get wrong: [Cu(en)₂]²⁺ has two ligands and a coordination
12
+ * number of four, and [Cr(C₂O₄)₃]³⁻ has three ligands and a coordination number of six.
13
+ *
14
+ * ## Why shape follows from the number and not from the metal, except when it does not
15
+ *
16
+ * Six is octahedral and two is linear, with no exceptions worth teaching. Four is the interesting
17
+ * one: usually tetrahedral, but square planar for platinum and palladium. That is not a detail. A
18
+ * square-planar complex shows cis-trans isomerism and a tetrahedral one CANNOT, because in a
19
+ * tetrahedron every position is adjacent to every other, so there is no "opposite" to be trans to.
20
+ *
21
+ * Cisplatin is the case that matters: it is the cis isomer of a square-planar platinum complex and
22
+ * it is a cancer drug, while the trans isomer is not. Had the geometry been tetrahedral there would
23
+ * have been no two isomers to tell apart.
24
+ *
25
+ * ## Colour is what is NOT absorbed
26
+ *
27
+ * A d-block ion's d orbitals split, and the gap ΔE corresponds to a wavelength in the visible
28
+ * range. The ion absorbs that wavelength and what reaches the eye is the rest, which is why copper
29
+ * sulfate is blue BECAUSE it absorbs orange. Stating it the other way round, that it is blue
30
+ * because it absorbs blue, is the commonest sentence in a wrong answer.
31
+ *
32
+ * Pure: no React, no pixels.
33
+ */
34
+ /** Planck constant, J s. */
35
+ declare const PLANCK = 6.626e-34;
36
+ /** Speed of light, m/s. */
37
+ declare const LIGHT_SPEED = 299800000;
38
+ /** Avogadro constant, per mole. */
39
+ declare const AVOGADRO = 6.022e+23;
40
+ type Geometry = 'linear' | 'tetrahedral' | 'square-planar' | 'octahedral';
41
+ interface Ligand {
42
+ readonly name: string;
43
+ /** As it appears inside the square brackets. */
44
+ readonly formula: string;
45
+ /** Charge on the ligand itself. 0 for a neutral one. */
46
+ readonly charge: number;
47
+ /** Coordinate bonds it forms. 2 for a bidentate ligand. */
48
+ readonly denticity: number;
49
+ }
50
+ /** The ligands the syllabus actually uses. */
51
+ declare const LIGANDS: Readonly<Record<string, Ligand>>;
52
+ interface ComplexSpec {
53
+ /** Symbol of the central metal, e.g. 'Cu'. */
54
+ readonly metal: string;
55
+ /** Its oxidation number. */
56
+ readonly oxidation: number;
57
+ readonly ligands: readonly {
58
+ readonly ligand: Ligand;
59
+ readonly count: number;
60
+ }[];
61
+ /**
62
+ * Force a geometry the coordination number would not give.
63
+ *
64
+ * Only ever needed at four, where platinum and palladium are square planar and everything else is
65
+ * tetrahedral. Provided as an override rather than a longer metal table, because the exceptions
66
+ * are a syllabus fact rather than a rule anyone can derive.
67
+ */
68
+ readonly geometry?: Geometry;
69
+ }
70
+ /** Coordinate bonds, NOT the number of ligands. A bidentate ligand counts twice. */
71
+ declare const coordinationNumber: (spec: ComplexSpec) => number;
72
+ /** Overall charge: the metal's oxidation number plus every ligand's own charge. */
73
+ declare const complexCharge: (spec: ComplexSpec) => number;
74
+ declare function geometryOf(spec: ComplexSpec): Geometry;
75
+ /** The bond angle a shape gives, in degrees. */
76
+ declare function bondAngle(geometry: Geometry): number;
77
+ /** `[Cu(H2O)6]2+`, with the charge written the way a data book writes it. */
78
+ declare function complexFormula(spec: ComplexSpec): string;
79
+ interface StereoResult {
80
+ readonly count: number;
81
+ /** 'cis', 'trans', 'fac', 'mer', 'optical pair'. */
82
+ readonly kinds: readonly string[];
83
+ /** Why there are that many, in a sentence a mark scheme would accept. */
84
+ readonly reason: string;
85
+ }
86
+ /**
87
+ * How many stereoisomers a complex has, and what kind.
88
+ *
89
+ * Covers the shapes the syllabus sets and refuses to guess beyond them. The important NEGATIVE
90
+ * result is the tetrahedral one: no cis-trans isomerism at any composition, because a tetrahedron
91
+ * has no two positions opposite each other.
92
+ */
93
+ declare function stereoisomers(spec: ComplexSpec): StereoResult;
94
+ /** The splitting energy ΔE for light of this wavelength, in joules per photon. */
95
+ declare const splittingEnergy: (wavelengthNm: number) => number;
96
+ /** The same energy per mole, in kJ/mol, which is the form a question asks for. */
97
+ declare const splittingEnergyPerMole: (wavelengthNm: number) => number;
98
+ /** The wavelength whose photon energy is ΔE joules. */
99
+ declare const wavelengthFor: (joules: number) => number;
100
+ interface ColourResult {
101
+ readonly absorbed: string;
102
+ readonly seen: string;
103
+ readonly wavelengthNm: number;
104
+ }
105
+ /**
106
+ * What colour a solution looks, given the wavelength it absorbs.
107
+ *
108
+ * The answer is the COMPLEMENTARY colour, never the absorbed one. Copper sulfate absorbs orange
109
+ * light at about 600 nm and therefore looks blue, and a learner who says it looks blue because it
110
+ * absorbs blue has the physics exactly backwards.
111
+ */
112
+ declare function observedColour(wavelengthNm: number): ColourResult;
113
+ //#endregion
114
+ export { AVOGADRO, ColourResult, ComplexSpec, Geometry, LIGANDS, LIGHT_SPEED, Ligand, PLANCK, StereoResult, bondAngle, complexCharge, complexFormula, coordinationNumber, geometryOf, observedColour, splittingEnergy, splittingEnergyPerMole, stereoisomers, wavelengthFor };
@@ -0,0 +1,234 @@
1
+ //#region src/chem/complex.ts
2
+ /**
3
+ * complex, the geometry and colour of a transition-metal complex ion.
4
+ *
5
+ * Three questions the syllabus asks about every complex, and they are all answered from the same
6
+ * declaration: what shape is it, how many isomers has it, and why is it that colour.
7
+ *
8
+ * ## Coordination number is not the number of ligands
9
+ *
10
+ * It is the number of COORDINATE BONDS, so a bidentate ligand counts twice. That single sentence
11
+ * settles a question learners routinely get wrong: [Cu(en)₂]²⁺ has two ligands and a coordination
12
+ * number of four, and [Cr(C₂O₄)₃]³⁻ has three ligands and a coordination number of six.
13
+ *
14
+ * ## Why shape follows from the number and not from the metal, except when it does not
15
+ *
16
+ * Six is octahedral and two is linear, with no exceptions worth teaching. Four is the interesting
17
+ * one: usually tetrahedral, but square planar for platinum and palladium. That is not a detail. A
18
+ * square-planar complex shows cis-trans isomerism and a tetrahedral one CANNOT, because in a
19
+ * tetrahedron every position is adjacent to every other, so there is no "opposite" to be trans to.
20
+ *
21
+ * Cisplatin is the case that matters: it is the cis isomer of a square-planar platinum complex and
22
+ * it is a cancer drug, while the trans isomer is not. Had the geometry been tetrahedral there would
23
+ * have been no two isomers to tell apart.
24
+ *
25
+ * ## Colour is what is NOT absorbed
26
+ *
27
+ * A d-block ion's d orbitals split, and the gap ΔE corresponds to a wavelength in the visible
28
+ * range. The ion absorbs that wavelength and what reaches the eye is the rest, which is why copper
29
+ * sulfate is blue BECAUSE it absorbs orange. Stating it the other way round, that it is blue
30
+ * because it absorbs blue, is the commonest sentence in a wrong answer.
31
+ *
32
+ * Pure: no React, no pixels.
33
+ */
34
+ /** Planck constant, J s. */
35
+ const PLANCK = 6626e-37;
36
+ /** Speed of light, m/s. */
37
+ const LIGHT_SPEED = 2998e5;
38
+ /** Avogadro constant, per mole. */
39
+ const AVOGADRO = 6022e20;
40
+ const ligand = (name, formula, charge, denticity = 1) => ({
41
+ name,
42
+ formula,
43
+ charge,
44
+ denticity
45
+ });
46
+ /** The ligands the syllabus actually uses. */
47
+ const LIGANDS = {
48
+ water: ligand("water", "H2O", 0),
49
+ ammonia: ligand("ammonia", "NH3", 0),
50
+ chloride: ligand("chloride", "Cl", -1),
51
+ cyanide: ligand("cyanide", "CN", -1),
52
+ hydroxide: ligand("hydroxide", "OH", -1),
53
+ /** 1,2-diaminoethane, the standard neutral bidentate ligand. */
54
+ en: ligand("1,2-diaminoethane", "en", 0, 2),
55
+ /** Ethanedioate, the standard charged bidentate ligand. */
56
+ ethanedioate: ligand("ethanedioate", "C2O4", -2, 2)
57
+ };
58
+ /** Metals that are square planar at coordination number four. */
59
+ const SQUARE_PLANAR = new Set(["Pt", "Pd"]);
60
+ /** Coordinate bonds, NOT the number of ligands. A bidentate ligand counts twice. */
61
+ const coordinationNumber = (spec) => spec.ligands.reduce((n, l) => n + l.count * l.ligand.denticity, 0);
62
+ /** Overall charge: the metal's oxidation number plus every ligand's own charge. */
63
+ const complexCharge = (spec) => spec.ligands.reduce((q, l) => q + l.count * l.ligand.charge, spec.oxidation);
64
+ function geometryOf(spec) {
65
+ if (spec.geometry) return spec.geometry;
66
+ const n = coordinationNumber(spec);
67
+ if (n === 6) return "octahedral";
68
+ if (n === 2) return "linear";
69
+ if (n === 4) return SQUARE_PLANAR.has(spec.metal) ? "square-planar" : "tetrahedral";
70
+ throw new Error(`Coordination number ${n} for ${spec.metal} has no shape in this kernel. The syllabus uses 2, 4 and 6.`);
71
+ }
72
+ /** The bond angle a shape gives, in degrees. */
73
+ function bondAngle(geometry) {
74
+ switch (geometry) {
75
+ case "linear": return 180;
76
+ case "tetrahedral": return 109.5;
77
+ case "square-planar": return 90;
78
+ case "octahedral": return 90;
79
+ }
80
+ }
81
+ /** `[Cu(H2O)6]2+`, with the charge written the way a data book writes it. */
82
+ function complexFormula(spec) {
83
+ const inner = spec.ligands.map((l) => l.count === 1 ? `(${l.ligand.formula})` : `(${l.ligand.formula})${l.count}`).join("");
84
+ const q = complexCharge(spec);
85
+ const sign = q === 0 ? "" : q > 0 ? `${Math.abs(q) === 1 ? "" : Math.abs(q)}+` : `${Math.abs(q) === 1 ? "" : Math.abs(q)}-`;
86
+ return `[${spec.metal}${inner}]${sign}`;
87
+ }
88
+ /**
89
+ * How many stereoisomers a complex has, and what kind.
90
+ *
91
+ * Covers the shapes the syllabus sets and refuses to guess beyond them. The important NEGATIVE
92
+ * result is the tetrahedral one: no cis-trans isomerism at any composition, because a tetrahedron
93
+ * has no two positions opposite each other.
94
+ */
95
+ function stereoisomers(spec) {
96
+ const geometry = geometryOf(spec);
97
+ const mono = spec.ligands.filter((l) => l.ligand.denticity === 1);
98
+ const bi = spec.ligands.filter((l) => l.ligand.denticity === 2);
99
+ const counts = mono.map((l) => l.count).sort((a, b) => b - a);
100
+ const biTotal = bi.reduce((n, l) => n + l.count, 0);
101
+ if (geometry === "linear") return {
102
+ count: 1,
103
+ kinds: [],
104
+ reason: "Two ligands on a straight line have only one arrangement."
105
+ };
106
+ if (geometry === "tetrahedral") return {
107
+ count: 1,
108
+ kinds: [],
109
+ reason: "A tetrahedron has no two positions opposite each other, so there is nothing for a ligand to be trans to. Tetrahedral complexes show no cis-trans isomerism at all."
110
+ };
111
+ if (geometry === "square-planar") {
112
+ if (counts.length === 2 && counts[0] === 2 && counts[1] === 2) return {
113
+ count: 2,
114
+ kinds: ["cis", "trans"],
115
+ reason: "Two pairs in a square: the identical ligands are either adjacent (cis) or opposite (trans). This is the cisplatin case, where only the cis isomer is the drug."
116
+ };
117
+ return {
118
+ count: 1,
119
+ kinds: [],
120
+ reason: "Only one arrangement of these ligands in a square."
121
+ };
122
+ }
123
+ if (biTotal === 3) return {
124
+ count: 2,
125
+ kinds: ["optical pair"],
126
+ reason: "Three bidentate ligands around an octahedron make a propeller, and a propeller has a handedness. The two forms are non-superimposable mirror images."
127
+ };
128
+ if (biTotal === 2 && counts.length === 1 && counts[0] === 2) return {
129
+ count: 3,
130
+ kinds: ["cis (optical pair)", "trans"],
131
+ reason: "The two single ligands are adjacent or opposite. The trans form has a mirror plane; the cis form does not, so it is itself a pair of optical isomers. Two plus one is three."
132
+ };
133
+ if (counts.length === 2 && counts[0] === 4 && counts[1] === 2) return {
134
+ count: 2,
135
+ kinds: ["cis", "trans"],
136
+ reason: "The two odd ligands sit next to each other (cis) or on opposite corners (trans)."
137
+ };
138
+ if (counts.length === 2 && counts[0] === 3 && counts[1] === 3) return {
139
+ count: 2,
140
+ kinds: ["fac", "mer"],
141
+ reason: "Three and three: the matching set occupies one triangular face (fac) or a meridian running around the ion (mer)."
142
+ };
143
+ if (counts.length === 1) return {
144
+ count: 1,
145
+ kinds: [],
146
+ reason: "Six identical ligands have one arrangement."
147
+ };
148
+ return {
149
+ count: 1,
150
+ kinds: [],
151
+ reason: "No stereoisomerism for this combination in the cases the syllabus sets."
152
+ };
153
+ }
154
+ /** The splitting energy ΔE for light of this wavelength, in joules per photon. */
155
+ const splittingEnergy = (wavelengthNm) => PLANCK * LIGHT_SPEED / (wavelengthNm * 1e-9);
156
+ /** The same energy per mole, in kJ/mol, which is the form a question asks for. */
157
+ const splittingEnergyPerMole = (wavelengthNm) => splittingEnergy(wavelengthNm) * AVOGADRO / 1e3;
158
+ /** The wavelength whose photon energy is ΔE joules. */
159
+ const wavelengthFor = (joules) => PLANCK * LIGHT_SPEED / joules / 1e-9;
160
+ const WHEEL = [
161
+ {
162
+ from: 400,
163
+ to: 435,
164
+ absorbed: "violet",
165
+ seen: "yellow-green"
166
+ },
167
+ {
168
+ from: 435,
169
+ to: 480,
170
+ absorbed: "blue",
171
+ seen: "yellow"
172
+ },
173
+ {
174
+ from: 480,
175
+ to: 490,
176
+ absorbed: "green-blue",
177
+ seen: "orange"
178
+ },
179
+ {
180
+ from: 490,
181
+ to: 500,
182
+ absorbed: "blue-green",
183
+ seen: "red"
184
+ },
185
+ {
186
+ from: 500,
187
+ to: 560,
188
+ absorbed: "green",
189
+ seen: "purple"
190
+ },
191
+ {
192
+ from: 560,
193
+ to: 580,
194
+ absorbed: "yellow-green",
195
+ seen: "violet"
196
+ },
197
+ {
198
+ from: 580,
199
+ to: 595,
200
+ absorbed: "yellow",
201
+ seen: "blue"
202
+ },
203
+ {
204
+ from: 595,
205
+ to: 650,
206
+ absorbed: "orange",
207
+ seen: "blue-green"
208
+ },
209
+ {
210
+ from: 650,
211
+ to: 750,
212
+ absorbed: "red",
213
+ seen: "green-blue"
214
+ }
215
+ ];
216
+ /**
217
+ * What colour a solution looks, given the wavelength it absorbs.
218
+ *
219
+ * The answer is the COMPLEMENTARY colour, never the absorbed one. Copper sulfate absorbs orange
220
+ * light at about 600 nm and therefore looks blue, and a learner who says it looks blue because it
221
+ * absorbs blue has the physics exactly backwards.
222
+ */
223
+ function observedColour(wavelengthNm) {
224
+ const band = WHEEL.find((b) => wavelengthNm >= b.from && wavelengthNm < b.to);
225
+ if (!band) throw new Error(`${wavelengthNm} nm is outside the visible range (400-750 nm), so the complex would look colourless.`);
226
+ return {
227
+ absorbed: band.absorbed,
228
+ seen: band.seen,
229
+ wavelengthNm
230
+ };
231
+ }
232
+
233
+ //#endregion
234
+ export { AVOGADRO, LIGANDS, LIGHT_SPEED, PLANCK, bondAngle, complexCharge, complexFormula, coordinationNumber, geometryOf, observedColour, splittingEnergy, splittingEnergyPerMole, stereoisomers, wavelengthFor };
@@ -0,0 +1,75 @@
1
+ import { Quantity } from "../quantity/index.mjs";
2
+ import { Worked } from "../core/worked.mjs";
3
+
4
+ //#region src/chem/cycle.d.ts
5
+ /** kJ mol⁻¹ is what every data book and every mark scheme uses. */
6
+ declare const DEFAULT_CYCLE_UNIT = "kJ/mol";
7
+ interface CycleTerm {
8
+ /** "first ionisation energy of Na". Shown in the working. */
9
+ readonly label: string;
10
+ /** The enthalpy change for this step as written. Omit for the unknown. */
11
+ readonly value?: number | Quantity;
12
+ /** Stoichiometric multiplier, e.g. 2 chlorine atomisations in MgCl₂. Default 1. */
13
+ readonly per?: number;
14
+ /** The datum is quoted for the REVERSE of the step as written, so negate it. */
15
+ readonly reversed?: boolean;
16
+ }
17
+ interface CycleSpec {
18
+ readonly title?: string;
19
+ /** Unit for bare numbers. Default kJ/mol. */
20
+ readonly unit?: string;
21
+ /** The route: the steps that must sum to the total. */
22
+ readonly route: readonly CycleTerm[];
23
+ /** The overall change the route must add up to. */
24
+ readonly total: CycleTerm;
25
+ }
26
+ interface CycleSolution {
27
+ readonly label: string;
28
+ readonly value: number;
29
+ readonly unit: string;
30
+ readonly quantity: Quantity;
31
+ /** Negative is exothermic, by the convention above. */
32
+ readonly exothermic: boolean;
33
+ /** True when the solved term was the overall change rather than a step. */
34
+ readonly isTotal: boolean;
35
+ }
36
+ declare class Cycle {
37
+ readonly title: string;
38
+ readonly unit: string;
39
+ readonly route: readonly CycleTerm[];
40
+ readonly total: CycleTerm;
41
+ constructor(spec: CycleSpec);
42
+ /** The signed contribution of a term, in `this.unit`, with `per` and `reversed` applied. */
43
+ contribution(term: CycleTerm): number;
44
+ /** Sum of the steps that have values. */
45
+ private sumKnownSteps;
46
+ /**
47
+ * The one unknown term.
48
+ *
49
+ * If a step is unknown: step = total − (the other steps).
50
+ * If the total is unknown: total = the sum of the steps.
51
+ */
52
+ solve(): CycleSolution;
53
+ private report;
54
+ /**
55
+ * With every term known, how far the route misses the total by.
56
+ *
57
+ * Zero is a cycle that is self-consistent. This is the check worth running over an authored
58
+ * lesson: five data-book enthalpies and a quoted formation enthalpy that do NOT close to within a
59
+ * kilojoule mean one of the six numbers is wrong, and the lesson cannot say which.
60
+ */
61
+ residual(): number;
62
+ /** True when the cycle closes to within `tol` (default 1 kJ/mol, the data-book rounding). */
63
+ closes(tol?: number): boolean;
64
+ /**
65
+ * The working: every step with its sign, then the rearrangement and the answer.
66
+ *
67
+ * A `per` factor is shown as `2 × 122`, not as `244`, because the per-mole datum is the thing the
68
+ * mark scheme wants to see quoted.
69
+ */
70
+ steps(sf?: number): Worked;
71
+ }
72
+ /** `cycle({ route: [...], total: {...} })`. */
73
+ declare const cycle: (spec: CycleSpec) => Cycle;
74
+ //#endregion
75
+ export { Cycle, CycleSolution, CycleSpec, CycleTerm, DEFAULT_CYCLE_UNIT, cycle };