@classytic/stage 0.2.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 (458) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -1
  3. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  4. package/dist/assets/index.mjs +0 -1
  5. package/dist/atomic/aufbau.d.mts +144 -0
  6. package/dist/atomic/aufbau.mjs +384 -0
  7. package/dist/atomic/elements.d.mts +67 -0
  8. package/dist/atomic/elements.mjs +785 -0
  9. package/dist/atomic/emission.d.mts +112 -0
  10. package/dist/atomic/emission.mjs +179 -0
  11. package/dist/atomic/index.d.mts +8 -0
  12. package/dist/atomic/index.mjs +9 -0
  13. package/dist/atomic/periodic.d.mts +82 -0
  14. package/dist/atomic/periodic.mjs +231 -0
  15. package/dist/atomic/properties.d.mts +100 -0
  16. package/dist/atomic/properties.mjs +574 -0
  17. package/dist/atomic/shells.d.mts +137 -0
  18. package/dist/atomic/shells.mjs +170 -0
  19. package/dist/atomic/trends.d.mts +148 -0
  20. package/dist/atomic/trends.mjs +225 -0
  21. package/dist/builder/Palette.mjs +50 -89
  22. package/dist/builder/SceneBuilder.mjs +15 -73
  23. package/dist/chem/chromatography.d.mts +66 -0
  24. package/dist/chem/chromatography.mjs +63 -0
  25. package/dist/chem/complex.d.mts +114 -0
  26. package/dist/chem/complex.mjs +234 -0
  27. package/dist/chem/cycle.d.mts +75 -0
  28. package/dist/chem/cycle.mjs +145 -0
  29. package/dist/chem/equation.d.mts +86 -0
  30. package/dist/chem/equation.mjs +168 -0
  31. package/dist/chem/formula.d.mts +90 -0
  32. package/dist/chem/formula.mjs +201 -0
  33. package/dist/chem/functional-groups.d.mts +31 -0
  34. package/dist/chem/functional-groups.mjs +187 -0
  35. package/dist/chem/hazard.d.mts +94 -0
  36. package/dist/chem/hazard.mjs +329 -0
  37. package/dist/chem/index.d.mts +34 -33
  38. package/dist/chem/index.mjs +34 -28
  39. package/dist/chem/ionic.d.mts +98 -0
  40. package/dist/chem/ionic.mjs +156 -0
  41. package/dist/chem/layout.d.mts +46 -0
  42. package/dist/chem/layout.mjs +342 -0
  43. package/dist/chem/lewis.d.mts +79 -0
  44. package/dist/chem/lewis.mjs +163 -0
  45. package/dist/chem/molecular-orbital.d.mts +114 -0
  46. package/dist/chem/molecular-orbital.mjs +201 -0
  47. package/dist/chem/molecule.d.mts +154 -0
  48. package/dist/chem/molecule.mjs +282 -0
  49. package/dist/chem/nmr.d.mts +153 -0
  50. package/dist/chem/nmr.mjs +165 -0
  51. package/dist/chem/polymer.d.mts +65 -0
  52. package/dist/chem/polymer.mjs +179 -0
  53. package/dist/chem/redox.d.mts +138 -0
  54. package/dist/chem/redox.mjs +328 -0
  55. package/dist/chem/relations.d.mts +183 -0
  56. package/dist/chem/relations.mjs +299 -0
  57. package/dist/chem/skeleton.d.mts +51 -0
  58. package/dist/chem/skeleton.mjs +186 -0
  59. package/dist/chem/solution.d.mts +116 -0
  60. package/dist/chem/solution.mjs +186 -0
  61. package/dist/chem/species.d.mts +47 -0
  62. package/dist/chem/species.mjs +128 -0
  63. package/dist/chem/stereo.d.mts +108 -0
  64. package/dist/chem/stereo.mjs +286 -0
  65. package/dist/chem/stoichiometry.d.mts +95 -0
  66. package/dist/chem/stoichiometry.mjs +145 -0
  67. package/dist/chem/synthesis.d.mts +113 -0
  68. package/dist/chem/synthesis.mjs +281 -0
  69. package/dist/chem/vsepr.d.mts +80 -0
  70. package/dist/chem/vsepr.mjs +247 -0
  71. package/dist/circuit/ac.d.mts +163 -0
  72. package/dist/circuit/ac.mjs +452 -0
  73. package/dist/circuit/dc.d.mts +92 -0
  74. package/dist/circuit/dc.mjs +333 -0
  75. package/dist/circuit/index.d.mts +5 -92
  76. package/dist/circuit/index.mjs +5 -332
  77. package/dist/circuit/network.d.mts +99 -0
  78. package/dist/circuit/network.mjs +440 -0
  79. package/dist/circuit/topology.d.mts +102 -0
  80. package/dist/circuit/topology.mjs +143 -0
  81. package/dist/colour/absorption.d.mts +79 -0
  82. package/dist/colour/absorption.mjs +137 -0
  83. package/dist/colour/index.d.mts +6 -0
  84. package/dist/colour/index.mjs +7 -0
  85. package/dist/colour/name.d.mts +14 -0
  86. package/dist/colour/name.mjs +76 -0
  87. package/dist/colour/observer.d.mts +31 -0
  88. package/dist/colour/observer.mjs +46 -0
  89. package/dist/colour/spectrum.d.mts +61 -0
  90. package/dist/colour/spectrum.mjs +108 -0
  91. package/dist/colour/srgb.d.mts +49 -0
  92. package/dist/colour/srgb.mjs +108 -0
  93. package/dist/core/constants.d.mts +138 -0
  94. package/dist/core/constants.mjs +139 -0
  95. package/dist/core/index.d.mts +4 -1
  96. package/dist/core/index.mjs +4 -1
  97. package/dist/core/math.d.mts +26 -0
  98. package/dist/core/math.mjs +37 -0
  99. package/dist/core/vec3.d.mts +94 -0
  100. package/dist/core/vec3.mjs +123 -0
  101. package/dist/core/worked.d.mts +35 -0
  102. package/dist/core/worked.mjs +44 -0
  103. package/dist/electro/cell.d.mts +102 -0
  104. package/dist/electro/cell.mjs +170 -0
  105. package/dist/electro/conductivity.d.mts +157 -0
  106. package/dist/electro/conductivity.mjs +156 -0
  107. package/dist/electro/couples.d.mts +114 -0
  108. package/dist/electro/couples.mjs +334 -0
  109. package/dist/electro/electrolysis.d.mts +96 -0
  110. package/dist/electro/electrolysis.mjs +274 -0
  111. package/dist/electro/faraday.d.mts +150 -0
  112. package/dist/electro/faraday.mjs +118 -0
  113. package/dist/electro/index.d.mts +6 -0
  114. package/dist/electro/index.mjs +7 -0
  115. package/dist/finance/accounting/adjustments.d.mts +17 -0
  116. package/dist/finance/accounting/adjustments.mjs +202 -0
  117. package/dist/finance/accounting/analysis.d.mts +8 -0
  118. package/dist/finance/accounting/analysis.mjs +205 -0
  119. package/dist/finance/accounting/clubs.d.mts +21 -0
  120. package/dist/finance/accounting/clubs.mjs +217 -0
  121. package/dist/finance/accounting/company-statements.d.mts +7 -0
  122. package/dist/finance/accounting/company-statements.mjs +150 -0
  123. package/dist/finance/accounting/harness.d.mts +7 -0
  124. package/dist/finance/accounting/harness.mjs +45 -0
  125. package/dist/finance/accounting/index.d.mts +18 -0
  126. package/dist/finance/accounting/index.mjs +18 -0
  127. package/dist/finance/accounting/journalize.d.mts +16 -0
  128. package/dist/finance/accounting/journalize.mjs +128 -0
  129. package/dist/finance/accounting/manufacturing.d.mts +8 -0
  130. package/dist/finance/accounting/manufacturing.mjs +236 -0
  131. package/dist/finance/accounting/partnership.d.mts +7 -0
  132. package/dist/finance/accounting/partnership.mjs +152 -0
  133. package/dist/finance/accounting/period-case.d.mts +6 -0
  134. package/dist/finance/accounting/period-case.mjs +71 -0
  135. package/dist/finance/accounting/post.d.mts +9 -0
  136. package/dist/finance/accounting/post.mjs +84 -0
  137. package/dist/finance/accounting/precision.d.mts +9 -0
  138. package/dist/finance/accounting/precision.mjs +15 -0
  139. package/dist/finance/accounting/rules.d.mts +21 -0
  140. package/dist/finance/accounting/rules.mjs +37 -0
  141. package/dist/finance/accounting/solve.d.mts +28 -0
  142. package/dist/finance/accounting/solve.mjs +92 -0
  143. package/dist/finance/accounting/statements.d.mts +7 -0
  144. package/dist/finance/accounting/statements.mjs +142 -0
  145. package/dist/finance/accounting/types.d.mts +649 -0
  146. package/dist/finance/accounting/validate.d.mts +7 -0
  147. package/dist/finance/accounting/validate.mjs +67 -0
  148. package/dist/finance/accounting/verification.d.mts +24 -0
  149. package/dist/finance/accounting/verification.mjs +386 -0
  150. package/dist/finance/bizsim.d.mts +75 -0
  151. package/dist/finance/bizsim.mjs +296 -0
  152. package/dist/finance/index.d.mts +95 -0
  153. package/dist/finance/index.mjs +145 -0
  154. package/dist/finance/investment-math.d.mts +7 -0
  155. package/dist/finance/investment-math.mjs +18 -0
  156. package/dist/finance/management-accounting/budgeting.d.mts +7 -0
  157. package/dist/finance/management-accounting/budgeting.mjs +189 -0
  158. package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
  159. package/dist/finance/management-accounting/cash-budget.mjs +154 -0
  160. package/dist/finance/management-accounting/costing.d.mts +8 -0
  161. package/dist/finance/management-accounting/costing.mjs +175 -0
  162. package/dist/finance/management-accounting/decisions.d.mts +8 -0
  163. package/dist/finance/management-accounting/decisions.mjs +164 -0
  164. package/dist/finance/management-accounting/index.d.mts +13 -0
  165. package/dist/finance/management-accounting/index.mjs +13 -0
  166. package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
  167. package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
  168. package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
  169. package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
  170. package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
  171. package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
  172. package/dist/finance/management-accounting/management-case.d.mts +8 -0
  173. package/dist/finance/management-accounting/management-case.mjs +91 -0
  174. package/dist/finance/management-accounting/master-budget.d.mts +7 -0
  175. package/dist/finance/management-accounting/master-budget.mjs +137 -0
  176. package/dist/finance/management-accounting/production-costing.d.mts +8 -0
  177. package/dist/finance/management-accounting/production-costing.mjs +214 -0
  178. package/dist/finance/management-accounting/types.d.mts +644 -0
  179. package/dist/finance/management-accounting/variances.d.mts +7 -0
  180. package/dist/finance/management-accounting/variances.mjs +150 -0
  181. package/dist/index.d.mts +9 -8
  182. package/dist/index.mjs +5 -5
  183. package/dist/interaction/MovableDot.mjs +19 -0
  184. package/dist/interaction/useDraggable.mjs +24 -4
  185. package/dist/math/analysis.d.mts +61 -0
  186. package/dist/math/analysis.mjs +187 -0
  187. package/dist/math/answer-check.d.mts +50 -0
  188. package/dist/math/answer-check.mjs +106 -0
  189. package/dist/math/calculus.d.mts +17 -1
  190. package/dist/math/calculus.mjs +365 -2
  191. package/dist/math/complex.d.mts +93 -0
  192. package/dist/math/complex.mjs +239 -0
  193. package/dist/math/expr.d.mts +23 -0
  194. package/dist/math/expr.mjs +36 -0
  195. package/dist/math/index.d.mts +9 -23
  196. package/dist/math/index.mjs +9 -38
  197. package/dist/math/latex.mjs +10 -1
  198. package/dist/math/parse.mjs +1 -1
  199. package/dist/math/poly.d.mts +55 -0
  200. package/dist/math/poly.mjs +273 -0
  201. package/dist/math/rearrange.d.mts +14 -0
  202. package/dist/math/rearrange.mjs +125 -0
  203. package/dist/math/solve.d.mts +21 -0
  204. package/dist/math/solve.mjs +75 -0
  205. package/dist/networking/addressing.d.mts +26 -0
  206. package/dist/networking/addressing.mjs +33 -0
  207. package/dist/networking/cloud/access.d.mts +36 -0
  208. package/dist/networking/cloud/access.mjs +95 -0
  209. package/dist/networking/cloud/containers.d.mts +43 -0
  210. package/dist/networking/cloud/containers.mjs +54 -0
  211. package/dist/networking/cloud/edge.d.mts +17 -0
  212. package/dist/networking/cloud/edge.mjs +31 -0
  213. package/dist/networking/cloud/failure-domains.d.mts +19 -0
  214. package/dist/networking/cloud/failure-domains.mjs +22 -0
  215. package/dist/networking/cloud/geo-routing.d.mts +22 -0
  216. package/dist/networking/cloud/geo-routing.mjs +64 -0
  217. package/dist/networking/cloud/index.d.mts +18 -0
  218. package/dist/networking/cloud/index.mjs +19 -0
  219. package/dist/networking/cloud/inference-reliability.d.mts +30 -0
  220. package/dist/networking/cloud/inference-reliability.mjs +76 -0
  221. package/dist/networking/cloud/inference.d.mts +118 -0
  222. package/dist/networking/cloud/inference.mjs +179 -0
  223. package/dist/networking/cloud/infrastructure.d.mts +45 -0
  224. package/dist/networking/cloud/infrastructure.mjs +96 -0
  225. package/dist/networking/cloud/observability.d.mts +24 -0
  226. package/dist/networking/cloud/observability.mjs +34 -0
  227. package/dist/networking/cloud/orchestration.d.mts +32 -0
  228. package/dist/networking/cloud/orchestration.mjs +38 -0
  229. package/dist/networking/cloud/recovery.d.mts +21 -0
  230. package/dist/networking/cloud/recovery.mjs +27 -0
  231. package/dist/networking/cloud/releases.d.mts +42 -0
  232. package/dist/networking/cloud/releases.mjs +135 -0
  233. package/dist/networking/cloud/scaling.d.mts +25 -0
  234. package/dist/networking/cloud/scaling.mjs +65 -0
  235. package/dist/networking/cloud/secrets.d.mts +39 -0
  236. package/dist/networking/cloud/secrets.mjs +68 -0
  237. package/dist/networking/cloud/server-deployment.d.mts +29 -0
  238. package/dist/networking/cloud/server-deployment.mjs +72 -0
  239. package/dist/networking/cloud/storage.d.mts +16 -0
  240. package/dist/networking/cloud/storage.mjs +58 -0
  241. package/dist/networking/cloud/vpc.d.mts +18 -0
  242. package/dist/networking/cloud/vpc.mjs +100 -0
  243. package/dist/networking/delivery.d.mts +34 -0
  244. package/dist/networking/delivery.mjs +52 -0
  245. package/dist/networking/index.d.mts +47 -0
  246. package/dist/networking/index.mjs +47 -0
  247. package/dist/networking/ipv6.d.mts +28 -0
  248. package/dist/networking/ipv6.mjs +17 -0
  249. package/dist/networking/journeys.d.mts +83 -0
  250. package/dist/networking/journeys.mjs +161 -0
  251. package/dist/networking/models/airtime.d.mts +87 -0
  252. package/dist/networking/models/airtime.mjs +130 -0
  253. package/dist/networking/models/cellular.d.mts +157 -0
  254. package/dist/networking/models/cellular.mjs +252 -0
  255. package/dist/networking/models/encapsulation.d.mts +98 -0
  256. package/dist/networking/models/encapsulation.mjs +132 -0
  257. package/dist/networking/models/handover.d.mts +116 -0
  258. package/dist/networking/models/handover.mjs +209 -0
  259. package/dist/networking/models/handshake.d.mts +90 -0
  260. package/dist/networking/models/handshake.mjs +122 -0
  261. package/dist/networking/models/index.d.mts +14 -0
  262. package/dist/networking/models/index.mjs +15 -0
  263. package/dist/networking/models/media.d.mts +82 -0
  264. package/dist/networking/models/media.mjs +188 -0
  265. package/dist/networking/models/satellite.d.mts +86 -0
  266. package/dist/networking/models/satellite.mjs +121 -0
  267. package/dist/networking/models/spectrum.d.mts +83 -0
  268. package/dist/networking/models/spectrum.mjs +235 -0
  269. package/dist/networking/models/switch.d.mts +80 -0
  270. package/dist/networking/models/switch.mjs +155 -0
  271. package/dist/networking/models/vlan.d.mts +62 -0
  272. package/dist/networking/models/vlan.mjs +100 -0
  273. package/dist/networking/models/vpn.d.mts +66 -0
  274. package/dist/networking/models/vpn.mjs +125 -0
  275. package/dist/networking/models/wifi-privacy.d.mts +82 -0
  276. package/dist/networking/models/wifi-privacy.mjs +130 -0
  277. package/dist/networking/models/wifi.d.mts +240 -0
  278. package/dist/networking/models/wifi.mjs +562 -0
  279. package/dist/networking/nat-traversal.d.mts +24 -0
  280. package/dist/networking/nat-traversal.mjs +38 -0
  281. package/dist/networking/protocols.d.mts +17 -0
  282. package/dist/networking/protocols.mjs +57 -0
  283. package/dist/networking/queue.d.mts +12 -0
  284. package/dist/networking/queue.mjs +18 -0
  285. package/dist/networking/route-learning.d.mts +23 -0
  286. package/dist/networking/route-learning.mjs +43 -0
  287. package/dist/networking/routing.d.mts +11 -0
  288. package/dist/networking/routing.mjs +25 -0
  289. package/dist/networking/signals.d.mts +26 -0
  290. package/dist/networking/signals.mjs +35 -0
  291. package/dist/networking/subnet.d.mts +49 -0
  292. package/dist/networking/subnet.mjs +89 -0
  293. package/dist/networking/tcp-reliability.d.mts +24 -0
  294. package/dist/networking/tcp-reliability.mjs +38 -0
  295. package/dist/networking/topology/contract.d.mts +123 -0
  296. package/dist/networking/topology/index.d.mts +4 -0
  297. package/dist/networking/topology/index.mjs +4 -0
  298. package/dist/networking/topology/presets.d.mts +7 -0
  299. package/dist/networking/topology/presets.mjs +302 -0
  300. package/dist/networking/topology/simulation.d.mts +8 -0
  301. package/dist/networking/topology/simulation.mjs +179 -0
  302. package/dist/networking/wireless.d.mts +11 -0
  303. package/dist/networking/wireless.mjs +17 -0
  304. package/dist/optics/imaging.d.mts +218 -0
  305. package/dist/optics/imaging.mjs +276 -0
  306. package/dist/optics/index.d.mts +7 -0
  307. package/dist/optics/index.mjs +8 -0
  308. package/dist/optics/laws.d.mts +70 -0
  309. package/dist/optics/laws.mjs +195 -0
  310. package/dist/optics/prism.d.mts +148 -0
  311. package/dist/optics/prism.mjs +197 -0
  312. package/dist/optics/refraction.d.mts +201 -0
  313. package/dist/optics/refraction.mjs +270 -0
  314. package/dist/optics/wave-optics.d.mts +171 -0
  315. package/dist/optics/wave-optics.mjs +259 -0
  316. package/dist/physics/ac/index.d.mts +183 -0
  317. package/dist/physics/ac/index.mjs +203 -0
  318. package/dist/physics/dynamics/forces.d.mts +98 -0
  319. package/dist/physics/dynamics/forces.mjs +153 -0
  320. package/dist/physics/dynamics/friction.d.mts +76 -0
  321. package/dist/physics/dynamics/friction.mjs +119 -0
  322. package/dist/physics/dynamics/system.d.mts +68 -0
  323. package/dist/physics/dynamics/system.mjs +125 -0
  324. package/dist/physics/electrostatics/index.d.mts +169 -0
  325. package/dist/physics/electrostatics/index.mjs +249 -0
  326. package/dist/physics/energy/centre-of-mass.d.mts +115 -0
  327. package/dist/physics/energy/centre-of-mass.mjs +180 -0
  328. package/dist/physics/energy/conservation.d.mts +81 -0
  329. package/dist/physics/energy/conservation.mjs +129 -0
  330. package/dist/physics/energy/power.d.mts +90 -0
  331. package/dist/physics/energy/power.mjs +167 -0
  332. package/dist/physics/energy/spring.d.mts +73 -0
  333. package/dist/physics/energy/spring.mjs +129 -0
  334. package/dist/physics/energy/store.d.mts +63 -0
  335. package/dist/physics/energy/store.mjs +108 -0
  336. package/dist/physics/energy/theorem.d.mts +65 -0
  337. package/dist/physics/energy/theorem.mjs +113 -0
  338. package/dist/physics/energy/work.d.mts +114 -0
  339. package/dist/physics/energy/work.mjs +219 -0
  340. package/dist/physics/gravitation/body.d.mts +85 -0
  341. package/dist/physics/gravitation/body.mjs +168 -0
  342. package/dist/physics/gravitation/kepler.d.mts +127 -0
  343. package/dist/physics/gravitation/kepler.mjs +216 -0
  344. package/dist/physics/gravitation/law.d.mts +117 -0
  345. package/dist/physics/gravitation/law.mjs +175 -0
  346. package/dist/physics/gravitation/orbit.d.mts +119 -0
  347. package/dist/physics/gravitation/orbit.mjs +202 -0
  348. package/dist/physics/gravitation/potential.d.mts +114 -0
  349. package/dist/physics/gravitation/potential.mjs +202 -0
  350. package/dist/physics/gravitation/variation.d.mts +97 -0
  351. package/dist/physics/gravitation/variation.mjs +175 -0
  352. package/dist/physics/index.d.mts +35 -0
  353. package/dist/physics/index.mjs +36 -0
  354. package/dist/physics/integral-sweep.d.mts +63 -0
  355. package/dist/physics/integral-sweep.mjs +126 -0
  356. package/dist/physics/kinematics/equations.d.mts +47 -0
  357. package/dist/physics/kinematics/equations.mjs +126 -0
  358. package/dist/physics/kinematics/free-fall.d.mts +53 -0
  359. package/dist/physics/kinematics/free-fall.mjs +71 -0
  360. package/dist/physics/kinematics/given.d.mts +16 -0
  361. package/dist/physics/kinematics/given.mjs +55 -0
  362. package/dist/physics/kinematics/roots.d.mts +41 -0
  363. package/dist/physics/kinematics/roots.mjs +72 -0
  364. package/dist/physics/kinematics/solve.d.mts +52 -0
  365. package/dist/physics/kinematics/solve.mjs +172 -0
  366. package/dist/physics/magnetism/biot-savart.d.mts +161 -0
  367. package/dist/physics/magnetism/biot-savart.mjs +353 -0
  368. package/dist/physics/magnetism/flux.d.mts +94 -0
  369. package/dist/physics/magnetism/flux.mjs +313 -0
  370. package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
  371. package/dist/physics/magnetism/geomagnetism.mjs +184 -0
  372. package/dist/physics/magnetism/index.d.mts +12 -0
  373. package/dist/physics/magnetism/index.mjs +74 -0
  374. package/dist/physics/magnetism/lorentz.d.mts +28 -0
  375. package/dist/physics/magnetism/lorentz.mjs +88 -0
  376. package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
  377. package/dist/physics/magnetism/magnetic-force.mjs +169 -0
  378. package/dist/physics/momentum/collide.d.mts +77 -0
  379. package/dist/physics/momentum/collide.mjs +115 -0
  380. package/dist/physics/momentum/impulse.d.mts +89 -0
  381. package/dist/physics/momentum/impulse.mjs +159 -0
  382. package/dist/physics/momentum/planar.d.mts +60 -0
  383. package/dist/physics/momentum/planar.mjs +110 -0
  384. package/dist/physics/projectile.d.mts +107 -0
  385. package/dist/physics/projectile.mjs +185 -0
  386. package/dist/physics/rotation/angular.d.mts +85 -0
  387. package/dist/physics/rotation/angular.mjs +130 -0
  388. package/dist/physics/rotation/circular.d.mts +79 -0
  389. package/dist/physics/rotation/circular.mjs +131 -0
  390. package/dist/physics/rotation/inertia.d.mts +164 -0
  391. package/dist/physics/rotation/inertia.mjs +332 -0
  392. package/dist/physics/rotation/torque.d.mts +65 -0
  393. package/dist/physics/rotation/torque.mjs +134 -0
  394. package/dist/physics/vectors.d.mts +64 -0
  395. package/dist/physics/vectors.mjs +114 -0
  396. package/dist/primitives/Dot.d.mts +2 -15
  397. package/dist/primitives/Dot.mjs +6 -4
  398. package/dist/primitives/Grid.d.mts +33 -17
  399. package/dist/primitives/Grid.mjs +89 -17
  400. package/dist/primitives/Label.d.mts +1 -14
  401. package/dist/primitives/Label.mjs +3 -2
  402. package/dist/primitives/Lines.d.mts +4 -32
  403. package/dist/primitives/Lines.mjs +10 -8
  404. package/dist/primitives/Shapes.d.mts +5 -43
  405. package/dist/primitives/Shapes.mjs +12 -10
  406. package/dist/primitives/index.d.mts +2 -2
  407. package/dist/primitives/index.mjs +2 -2
  408. package/dist/primitives/props.mjs +31 -0
  409. package/dist/quantity/index.d.mts +119 -0
  410. package/dist/quantity/index.mjs +417 -0
  411. package/dist/relation/derive.d.mts +74 -0
  412. package/dist/relation/derive.mjs +73 -0
  413. package/dist/relation/index.d.mts +56 -0
  414. package/dist/relation/index.mjs +234 -0
  415. package/dist/scene/Scene.d.mts +6 -1
  416. package/dist/scene/Scene.mjs +15 -40
  417. package/dist/scene/evaluators.mjs +1 -1
  418. package/dist/sim/thermal.mjs +45 -20
  419. package/dist/thermo/calorimetry.d.mts +207 -0
  420. package/dist/thermo/calorimetry.mjs +345 -0
  421. package/dist/thermo/cycles.d.mts +142 -0
  422. package/dist/thermo/cycles.mjs +256 -0
  423. package/dist/thermo/entropy.d.mts +87 -0
  424. package/dist/thermo/entropy.mjs +140 -0
  425. package/dist/thermo/expansion.d.mts +130 -0
  426. package/dist/thermo/expansion.mjs +178 -0
  427. package/dist/thermo/gas.d.mts +197 -0
  428. package/dist/thermo/gas.mjs +279 -0
  429. package/dist/thermo/heat-transfer.d.mts +164 -0
  430. package/dist/thermo/heat-transfer.mjs +217 -0
  431. package/dist/thermo/index.d.mts +9 -82
  432. package/dist/thermo/index.mjs +9 -132
  433. package/dist/thermo/processes.d.mts +95 -0
  434. package/dist/thermo/processes.mjs +154 -0
  435. package/dist/thermo/temperature.d.mts +174 -0
  436. package/dist/thermo/temperature.mjs +236 -0
  437. package/dist/view/Stage.mjs +4 -11
  438. package/dist/waves/damping.d.mts +224 -0
  439. package/dist/waves/damping.mjs +317 -0
  440. package/dist/waves/doppler.d.mts +72 -0
  441. package/dist/waves/doppler.mjs +125 -0
  442. package/dist/waves/index.d.mts +10 -0
  443. package/dist/waves/index.mjs +10 -0
  444. package/dist/waves/pendulum.d.mts +130 -0
  445. package/dist/waves/pendulum.mjs +211 -0
  446. package/dist/waves/pitch.d.mts +125 -0
  447. package/dist/waves/pitch.mjs +158 -0
  448. package/dist/waves/shm.d.mts +170 -0
  449. package/dist/waves/shm.mjs +279 -0
  450. package/dist/waves/springs.d.mts +103 -0
  451. package/dist/waves/springs.mjs +176 -0
  452. package/dist/waves/superposition.d.mts +124 -0
  453. package/dist/waves/superposition.mjs +196 -0
  454. package/dist/waves/wave.d.mts +154 -0
  455. package/dist/waves/wave.mjs +178 -0
  456. package/package.json +103 -23
  457. package/styles.css +125 -8
  458. package/dist/assets/kit/index.mjs +0 -4
@@ -0,0 +1,137 @@
1
+ //#region src/atomic/shells.d.ts
2
+ /**
3
+ * Shells, subshells and orbitals, enumerated from the four quantum numbers.
4
+ *
5
+ * ## Why this is computed and not typed out
6
+ *
7
+ * Every textbook prints the same table: shell K/L/M/N, subshells 1s / 2s2p / 3s3p3d, the m values,
8
+ * how many orbitals, 2(2l+1) electrons each, 2n² in the shell. It is printed because it is tedious,
9
+ * and because it is printed it stops at n=4 and cannot be re-asked with different numbers.
10
+ *
11
+ * It is not a table. It is four rules:
12
+ *
13
+ * n = 1, 2, 3, … which shell
14
+ * l = 0 … n-1 which subshell, named s p d f g h
15
+ * m = -l … +l which orbital in it, so 2l+1 of them
16
+ * s = +1/2 or -1/2 which of the two electrons in that orbital
17
+ *
18
+ * Everything else follows. 2l+1 orbitals holding two electrons each is 2(2l+1) per subshell, and
19
+ * summing that over l = 0…n-1 is 2n², which is why the shell capacities are 2, 8, 18, 32 and why
20
+ * they are not four numbers to memorise.
21
+ *
22
+ * ## What Pauli actually says here
23
+ *
24
+ * No two electrons in one atom share all four numbers. Since n, l and m name a single orbital, and
25
+ * s has two values, an orbital holds at most two electrons and they must be opposed. So the
26
+ * exclusion principle is not an extra fact on top of the table: it is the reason the table has the
27
+ * capacities it has, and {@link isPauliValid} enforces it rather than restating it.
28
+ *
29
+ * Pure: no React, no pixels.
30
+ */
31
+ /**
32
+ * Subshell letters in l order.
33
+ *
34
+ * s, p, d and f are historical, from the spectral lines they were first seen in: sharp, principal,
35
+ * diffuse, fundamental. From g onward the sequence is simply alphabetical, except that j is skipped
36
+ * because it was too easily confused with i in print.
37
+ *
38
+ * It runs to l=7 so that the (n+l) filling order can be generated for n=8, which is past every
39
+ * element that exists but is where a generated sequence naturally stops.
40
+ */
41
+ declare const SUBSHELL_LETTERS: readonly ["s", "p", "d", "f", "g", "h", "i", "k"];
42
+ type SubshellLetter = (typeof SUBSHELL_LETTERS)[number];
43
+ /** The letter for a subshell, so l=2 reads as "d" rather than as a number. */
44
+ declare function subshellLetter(l: number): SubshellLetter;
45
+ /** The shell letter, K for n=1. Undefined past Q, which no atom reaches. */
46
+ declare const shellLetter: (n: number) => string | undefined;
47
+ /** How many orbitals a subshell has: 2l+1, one for each m from -l to +l. */
48
+ declare const orbitalsInSubshell: (l: number) => number;
49
+ /**
50
+ * Electrons one orbital can hold, which is the Pauli exclusion principle and nothing else.
51
+ *
52
+ * Named rather than written as a bare 2, because that 2 is the principle itself and appears in
53
+ * every capacity in this file. An orbital is fixed by n, l and m; the only quantum number left free
54
+ * is spin, which has two values; no two electrons may share all four. So an orbital holds two
55
+ * electrons with opposed spins, a subshell holds 2(2l+1), and a shell holds 2n². Those are not
56
+ * three facts to learn, they are one fact counted three ways.
57
+ *
58
+ * {@link isPauliValid} enforces the same principle on an explicit set of electrons, which is the
59
+ * form it takes when the question is whether a given arrangement is allowed.
60
+ */
61
+ declare const ELECTRONS_PER_ORBITAL = 2;
62
+ /** The m values of a subshell, in the order they are conventionally written. */
63
+ declare function magneticNumbers(l: number): number[];
64
+ /** Electrons a subshell holds: two per orbital, so 2(2l+1). */
65
+ declare const subshellCapacity: (l: number) => number;
66
+ /**
67
+ * Electrons a shell holds.
68
+ *
69
+ * Returned as the SUM over its subshells rather than as the formula 2n², because the sum is the
70
+ * reason and the formula is the consequence. A test asserts the two agree, which is the only place
71
+ * 2n² is written down.
72
+ */
73
+ declare const shellCapacity: (n: number) => number;
74
+ /** The l values present in shell n: 0 up to n-1, which is why n=1 has only an s subshell. */
75
+ declare function subshellsOf(n: number): number[];
76
+ interface Subshell {
77
+ /** Principal quantum number. */
78
+ readonly n: number;
79
+ /** Azimuthal quantum number, 0 for s. */
80
+ readonly l: number;
81
+ /** How it is written: "3d". */
82
+ readonly label: string;
83
+ /** The m value of each orbital, -l to +l. */
84
+ readonly magnetic: readonly number[];
85
+ readonly orbitals: number;
86
+ readonly capacity: number;
87
+ }
88
+ /** One subshell, described. */
89
+ declare function subshell(n: number, l: number): Subshell;
90
+ interface Shell {
91
+ readonly n: number;
92
+ /** K, L, M, N. Undefined past Q. */
93
+ readonly letter: string | undefined;
94
+ readonly subshells: readonly Subshell[];
95
+ readonly orbitals: number;
96
+ readonly capacity: number;
97
+ }
98
+ /**
99
+ * One shell and everything in it: the row of the table every textbook prints, for any n.
100
+ *
101
+ * Nothing here is looked up. Ask for n=7 and you get a correct row that no book contains.
102
+ */
103
+ declare function shell(n: number): Shell;
104
+ /** A complete address for one electron. */
105
+ interface QuantumNumbers {
106
+ readonly n: number;
107
+ readonly l: number;
108
+ readonly m: number;
109
+ /** Spin, +1/2 or -1/2. */
110
+ readonly s: number;
111
+ }
112
+ /**
113
+ * Why a set of four quantum numbers cannot describe an electron, or undefined if it can.
114
+ *
115
+ * Returns the REASON rather than a boolean, because "which of these sets is impossible" is the
116
+ * standard exam question and the mark is for saying which rule is broken. A checker that answers
117
+ * true or false can mark the question but cannot teach it.
118
+ */
119
+ declare function quantumNumbersRefusal(q: QuantumNumbers): string | undefined;
120
+ /** Whether four quantum numbers describe a possible electron. */
121
+ declare const isValidQuantumNumbers: (q: QuantumNumbers) => boolean;
122
+ /**
123
+ * Whether a set of electrons could coexist in one atom.
124
+ *
125
+ * Two electrons sharing all four numbers is the exclusion principle violated. This is what limits
126
+ * an orbital to two electrons, so it is checked here rather than asserted as a separate capacity.
127
+ */
128
+ declare function isPauliValid(electrons: readonly QuantumNumbers[]): boolean;
129
+ /** Every orbital in a shell, as its address. Used to lay out an orbital diagram. */
130
+ declare function orbitalsOf(n: number): {
131
+ n: number;
132
+ l: number;
133
+ m: number;
134
+ label: string;
135
+ }[];
136
+ //#endregion
137
+ export { ELECTRONS_PER_ORBITAL, QuantumNumbers, SUBSHELL_LETTERS, Shell, Subshell, SubshellLetter, isPauliValid, isValidQuantumNumbers, magneticNumbers, orbitalsInSubshell, orbitalsOf, quantumNumbersRefusal, shell, shellCapacity, shellLetter, subshell, subshellCapacity, subshellLetter, subshellsOf };
@@ -0,0 +1,170 @@
1
+ //#region src/atomic/shells.ts
2
+ /**
3
+ * Shells, subshells and orbitals, enumerated from the four quantum numbers.
4
+ *
5
+ * ## Why this is computed and not typed out
6
+ *
7
+ * Every textbook prints the same table: shell K/L/M/N, subshells 1s / 2s2p / 3s3p3d, the m values,
8
+ * how many orbitals, 2(2l+1) electrons each, 2n² in the shell. It is printed because it is tedious,
9
+ * and because it is printed it stops at n=4 and cannot be re-asked with different numbers.
10
+ *
11
+ * It is not a table. It is four rules:
12
+ *
13
+ * n = 1, 2, 3, … which shell
14
+ * l = 0 … n-1 which subshell, named s p d f g h
15
+ * m = -l … +l which orbital in it, so 2l+1 of them
16
+ * s = +1/2 or -1/2 which of the two electrons in that orbital
17
+ *
18
+ * Everything else follows. 2l+1 orbitals holding two electrons each is 2(2l+1) per subshell, and
19
+ * summing that over l = 0…n-1 is 2n², which is why the shell capacities are 2, 8, 18, 32 and why
20
+ * they are not four numbers to memorise.
21
+ *
22
+ * ## What Pauli actually says here
23
+ *
24
+ * No two electrons in one atom share all four numbers. Since n, l and m name a single orbital, and
25
+ * s has two values, an orbital holds at most two electrons and they must be opposed. So the
26
+ * exclusion principle is not an extra fact on top of the table: it is the reason the table has the
27
+ * capacities it has, and {@link isPauliValid} enforces it rather than restating it.
28
+ *
29
+ * Pure: no React, no pixels.
30
+ */
31
+ /**
32
+ * Subshell letters in l order.
33
+ *
34
+ * s, p, d and f are historical, from the spectral lines they were first seen in: sharp, principal,
35
+ * diffuse, fundamental. From g onward the sequence is simply alphabetical, except that j is skipped
36
+ * because it was too easily confused with i in print.
37
+ *
38
+ * It runs to l=7 so that the (n+l) filling order can be generated for n=8, which is past every
39
+ * element that exists but is where a generated sequence naturally stops.
40
+ */
41
+ const SUBSHELL_LETTERS = [
42
+ "s",
43
+ "p",
44
+ "d",
45
+ "f",
46
+ "g",
47
+ "h",
48
+ "i",
49
+ "k"
50
+ ];
51
+ /** Spectroscopic shell names, still used for X-ray notation. K is n=1, not n=0. */
52
+ const SHELL_LETTERS = [
53
+ "K",
54
+ "L",
55
+ "M",
56
+ "N",
57
+ "O",
58
+ "P",
59
+ "Q"
60
+ ];
61
+ /** The letter for a subshell, so l=2 reads as "d" rather than as a number. */
62
+ function subshellLetter(l) {
63
+ const letter = SUBSHELL_LETTERS[l];
64
+ if (!letter) throw new Error(`no subshell letter for l=${l}: only l=0..${SUBSHELL_LETTERS.length - 1} are named`);
65
+ return letter;
66
+ }
67
+ /** The shell letter, K for n=1. Undefined past Q, which no atom reaches. */
68
+ const shellLetter = (n) => SHELL_LETTERS[n - 1];
69
+ /** How many orbitals a subshell has: 2l+1, one for each m from -l to +l. */
70
+ const orbitalsInSubshell = (l) => 2 * l + 1;
71
+ /**
72
+ * Electrons one orbital can hold, which is the Pauli exclusion principle and nothing else.
73
+ *
74
+ * Named rather than written as a bare 2, because that 2 is the principle itself and appears in
75
+ * every capacity in this file. An orbital is fixed by n, l and m; the only quantum number left free
76
+ * is spin, which has two values; no two electrons may share all four. So an orbital holds two
77
+ * electrons with opposed spins, a subshell holds 2(2l+1), and a shell holds 2n². Those are not
78
+ * three facts to learn, they are one fact counted three ways.
79
+ *
80
+ * {@link isPauliValid} enforces the same principle on an explicit set of electrons, which is the
81
+ * form it takes when the question is whether a given arrangement is allowed.
82
+ */
83
+ const ELECTRONS_PER_ORBITAL = 2;
84
+ /** The m values of a subshell, in the order they are conventionally written. */
85
+ function magneticNumbers(l) {
86
+ if (l < 0 || !Number.isInteger(l)) throw new Error(`l must be a non-negative integer, got ${l}`);
87
+ return Array.from({ length: orbitalsInSubshell(l) }, (_, k) => k - l);
88
+ }
89
+ /** Electrons a subshell holds: two per orbital, so 2(2l+1). */
90
+ const subshellCapacity = (l) => 2 * orbitalsInSubshell(l);
91
+ /**
92
+ * Electrons a shell holds.
93
+ *
94
+ * Returned as the SUM over its subshells rather than as the formula 2n², because the sum is the
95
+ * reason and the formula is the consequence. A test asserts the two agree, which is the only place
96
+ * 2n² is written down.
97
+ */
98
+ const shellCapacity = (n) => subshellsOf(n).reduce((total, l) => total + subshellCapacity(l), 0);
99
+ /** The l values present in shell n: 0 up to n-1, which is why n=1 has only an s subshell. */
100
+ function subshellsOf(n) {
101
+ if (n < 1 || !Number.isInteger(n)) throw new Error(`n must be a positive integer, got ${n}`);
102
+ return Array.from({ length: n }, (_, l) => l);
103
+ }
104
+ /** One subshell, described. */
105
+ function subshell(n, l) {
106
+ if (l >= n) throw new Error(`no ${n}${SUBSHELL_LETTERS[l] ?? `l=${l}`} subshell: l must be less than n`);
107
+ const magnetic = magneticNumbers(l);
108
+ return {
109
+ n,
110
+ l,
111
+ label: `${n}${subshellLetter(l)}`,
112
+ magnetic,
113
+ orbitals: magnetic.length,
114
+ capacity: subshellCapacity(l)
115
+ };
116
+ }
117
+ /**
118
+ * One shell and everything in it: the row of the table every textbook prints, for any n.
119
+ *
120
+ * Nothing here is looked up. Ask for n=7 and you get a correct row that no book contains.
121
+ */
122
+ function shell(n) {
123
+ const subshells = subshellsOf(n).map((l) => subshell(n, l));
124
+ return {
125
+ n,
126
+ letter: shellLetter(n),
127
+ subshells,
128
+ orbitals: subshells.reduce((total, s) => total + s.orbitals, 0),
129
+ capacity: subshells.reduce((total, s) => total + s.capacity, 0)
130
+ };
131
+ }
132
+ /**
133
+ * Why a set of four quantum numbers cannot describe an electron, or undefined if it can.
134
+ *
135
+ * Returns the REASON rather than a boolean, because "which of these sets is impossible" is the
136
+ * standard exam question and the mark is for saying which rule is broken. A checker that answers
137
+ * true or false can mark the question but cannot teach it.
138
+ */
139
+ function quantumNumbersRefusal(q) {
140
+ if (!Number.isInteger(q.n) || q.n < 1) return "n must be a whole number of at least 1: there is no shell below the first";
141
+ if (!Number.isInteger(q.l) || q.l < 0) return "l must be a whole number of at least 0";
142
+ if (q.l >= q.n) return `l must be less than n, so shell ${q.n} has no ${subshellLetter(q.l) ?? "such"} subshell`;
143
+ if (!Number.isInteger(q.m)) return "m must be a whole number";
144
+ if (Math.abs(q.m) > q.l) return `m must lie between -l and +l, so a ${subshellLetter(q.l)} subshell has no m = ${q.m}`;
145
+ if (Math.abs(q.s) !== .5) return "spin is +1/2 or -1/2 and has no other value";
146
+ }
147
+ /** Whether four quantum numbers describe a possible electron. */
148
+ const isValidQuantumNumbers = (q) => quantumNumbersRefusal(q) === void 0;
149
+ /**
150
+ * Whether a set of electrons could coexist in one atom.
151
+ *
152
+ * Two electrons sharing all four numbers is the exclusion principle violated. This is what limits
153
+ * an orbital to two electrons, so it is checked here rather than asserted as a separate capacity.
154
+ */
155
+ function isPauliValid(electrons) {
156
+ if (electrons.some((e) => !isValidQuantumNumbers(e))) return false;
157
+ return new Set(electrons.map((e) => `${e.n}|${e.l}|${e.m}|${e.s}`)).size === electrons.length;
158
+ }
159
+ /** Every orbital in a shell, as its address. Used to lay out an orbital diagram. */
160
+ function orbitalsOf(n) {
161
+ return subshellsOf(n).flatMap((l) => magneticNumbers(l).map((m) => ({
162
+ n,
163
+ l,
164
+ m,
165
+ label: `${n}${subshellLetter(l)}`
166
+ })));
167
+ }
168
+
169
+ //#endregion
170
+ export { ELECTRONS_PER_ORBITAL, SUBSHELL_LETTERS, isPauliValid, isValidQuantumNumbers, magneticNumbers, orbitalsInSubshell, orbitalsOf, quantumNumbersRefusal, shell, shellCapacity, shellLetter, subshell, subshellCapacity, subshellLetter, subshellsOf };
@@ -0,0 +1,148 @@
1
+ //#region src/atomic/trends.d.ts
2
+ /**
3
+ * Periodic trends, read off the measurements rather than asserted.
4
+ *
5
+ * ## Why a trend should be found and not stated
6
+ *
7
+ * A book prints "atomic radius decreases across a period" with an arrow, and the statement is the
8
+ * whole of the teaching. But the statement is a CONCLUSION, and handing someone a conclusion is
9
+ * the one thing that guarantees they never do the work that produces it. If the measurements are
10
+ * there instead, a learner can lay them out, see the direction for themselves, predict the next
11
+ * one, and be told whether they were right. {@link trendOf} is what makes that possible: it takes
12
+ * a run of real values and reports which way they go and where they break.
13
+ *
14
+ * So nothing in this file stores a trend. Every direction below comes out of the numbers.
15
+ *
16
+ * ## The exceptions are the point, not the small print
17
+ *
18
+ * First ionisation energy rises across period 3, except twice. Between magnesium and aluminium it
19
+ * falls, and between phosphorus and sulfur it falls again. Those two dips are usually taught as
20
+ * things to remember. They are the opposite: they are the evidence.
21
+ *
22
+ * The first dip happens because aluminium's outer electron is in a 3p orbital, higher in energy
23
+ * than magnesium's filled 3s, so it comes away more easily despite the greater nuclear charge. That
24
+ * is a direct measurement of the fact that a shell has subshells inside it. The second happens
25
+ * because sulfur has its first PAIRED p electron, and two electrons sharing one orbital repel each
26
+ * other, so one leaves more easily than from phosphorus's half-filled subshell. That is a direct
27
+ * measurement of electron pairing.
28
+ *
29
+ * Neither could be deduced from the filling rules. Both are visible in the numbers. So
30
+ * {@link IONISATION_ANOMALIES} carries them with the reasoning attached, and a test asserts that
31
+ * these are the ONLY breaks in the run, which also means a mistyped energy anywhere shows up as a
32
+ * third.
33
+ *
34
+ * ## Bond character is a curve, not a table
35
+ *
36
+ * The usual table says a difference under 0.5 is non-polar, up to 1.7 is polar, and above that is
37
+ * ionic. Those boundaries are conventions drawn across something continuous. Pauling's own relation
38
+ * gives the proportion of ionic character directly, and the familiar 1.7 is simply where it passes
39
+ * a half. {@link ionicCharacter} computes it, and the band names are labels put on the curve rather
40
+ * than the thing itself.
41
+ *
42
+ * Pure: no React, no pixels.
43
+ */
44
+ /** A property that can be plotted across a period or down a group. */
45
+ type PropertyName = 'covalentRadius' | 'firstIonisationEnergy' | 'electronegativity';
46
+ interface DataPoint {
47
+ readonly Z: number;
48
+ readonly symbol: string;
49
+ readonly value: number;
50
+ }
51
+ /**
52
+ * A property across one period, in group order.
53
+ *
54
+ * Elements with no measurement are left out rather than given a zero, so a gap in the data shows as
55
+ * a shorter run and never as a spurious plunge to the axis.
56
+ */
57
+ declare function acrossPeriod(period: number, property: PropertyName): DataPoint[];
58
+ /** A property down one group, in period order. */
59
+ declare function downGroup(group: number, property: PropertyName): DataPoint[];
60
+ type Direction = 'rising' | 'falling' | 'flat';
61
+ interface Trend {
62
+ readonly direction: Direction;
63
+ /** Steps that go against the overall direction, as the pair they sit between. */
64
+ readonly exceptions: readonly (readonly [string, string])[];
65
+ readonly points: readonly DataPoint[];
66
+ }
67
+ /**
68
+ * Which way a run of measurements goes, and where it breaks.
69
+ *
70
+ * The direction is decided by the whole run rather than step by step, so a couple of dips do not
71
+ * flip a rise into "no pattern". The dips come back as exceptions instead, which is the shape the
72
+ * chemistry actually has: a strong trend with a small number of informative breaks in it.
73
+ */
74
+ declare function trendOf(points: readonly DataPoint[]): Trend;
75
+ interface IonisationAnomaly {
76
+ /** The element before the dip. */
77
+ readonly before: string;
78
+ /** The element whose ionisation energy is lower than the one before it. */
79
+ readonly after: string;
80
+ /** What the dip is evidence OF. */
81
+ readonly reason: string;
82
+ }
83
+ /**
84
+ * Every place first ionisation energy falls as it crosses a period, with what it demonstrates.
85
+ *
86
+ * Four of them, two per period, and they are the same two causes each time: a new subshell starting,
87
+ * and a p orbital taking its second electron.
88
+ */
89
+ declare const IONISATION_ANOMALIES: readonly IonisationAnomaly[];
90
+ /** The anomaly between two named elements, if there is one. */
91
+ declare const ionisationAnomalyFor: (before: string, after: string) => IonisationAnomaly | undefined;
92
+ interface ShellEvidence {
93
+ /** Electrons in the outermost shell, which is the group for a main-group element. */
94
+ readonly outerElectrons: number;
95
+ /** How many times bigger the jump is than the step before it. */
96
+ readonly jumpRatio: number;
97
+ /** The ionisation the jump happens at, counting from one. */
98
+ readonly atIonisation: number;
99
+ }
100
+ /**
101
+ * Read the number of outer-shell electrons off a run of successive ionisation energies.
102
+ *
103
+ * The argument for shells, run as a calculation. Removing electrons from the outer shell gets
104
+ * steadily harder; breaking into the shell beneath is suddenly far harder, because that shell is
105
+ * closer to the nucleus and fully shielded. So the position of the big jump counts the outer shell.
106
+ *
107
+ * Returns undefined when no jump in the data is decisive. That is the honest answer for a run that
108
+ * stops before it reaches the next shell, which is exactly what published runs for neon and argon
109
+ * do: eight ionisation energies, all from the same shell, and no break to find. Returning a number
110
+ * anyway would be inventing a conclusion the measurements do not support.
111
+ */
112
+ declare function outerElectronsFromIonisation(energies: readonly number[], minimumRatio?: number): ShellEvidence | undefined;
113
+ /** The same, for an element this engine has a published run for. */
114
+ declare function outerElectronsOf(symbol: string): ShellEvidence | undefined;
115
+ /** The gap in electronegativity between two elements, which sets how a bond between them behaves. */
116
+ declare function electronegativityGap(a: string, b: string): number;
117
+ /**
118
+ * The proportion of ionic character in a bond, from Pauling's relation.
119
+ *
120
+ * ionic character = 1 - exp(-(difference / 2)^2)
121
+ *
122
+ * A curve, not a table. The familiar boundary at a difference of 1.7 is simply where this passes a
123
+ * half, and it is a convention placed on something continuous rather than a line the physics draws.
124
+ */
125
+ declare const ionicCharacter: (difference: number) => number;
126
+ type BondCharacter = 'nonpolar covalent' | 'polar covalent' | 'ionic';
127
+ /**
128
+ * The name usually given to a bond with this electronegativity difference.
129
+ *
130
+ * The boundaries are the conventional ones. They are labels on {@link ionicCharacter}'s curve, and
131
+ * a bond just either side of one of them is very nearly the same bond, which is worth saying out
132
+ * loud whenever this function's answer is shown to anyone.
133
+ */
134
+ declare function bondCharacter(difference: number): BondCharacter;
135
+ /** The character of the bond between two named elements. */
136
+ declare const bondBetween: (a: string, b: string) => BondCharacter;
137
+ /**
138
+ * Which of two elements holds its outer electrons more tightly, and why.
139
+ *
140
+ * Answers with the reasoning, because "which has the higher ionisation energy" is never the real
141
+ * question: the real question is what about their positions makes it so.
142
+ */
143
+ declare function compareIonisationEnergy(a: string, b: string): {
144
+ higher: string;
145
+ reason: string;
146
+ } | undefined;
147
+ //#endregion
148
+ export { BondCharacter, DataPoint, Direction, IONISATION_ANOMALIES, IonisationAnomaly, PropertyName, ShellEvidence, Trend, acrossPeriod, bondBetween, bondCharacter, compareIonisationEnergy, downGroup, electronegativityGap, ionicCharacter, ionisationAnomalyFor, outerElectronsFromIonisation, outerElectronsOf, trendOf };
@@ -0,0 +1,225 @@
1
+ import { groupOf, periodOf } from "./periodic.mjs";
2
+ import { elementBySymbol, symbolOf } from "./elements.mjs";
3
+ import { PROPERTIES, SUCCESSIVE_IONISATION_ENERGIES, covalentRadius, electronegativity, firstIonisationEnergy } from "./properties.mjs";
4
+
5
+ //#region src/atomic/trends.ts
6
+ /**
7
+ * Periodic trends, read off the measurements rather than asserted.
8
+ *
9
+ * ## Why a trend should be found and not stated
10
+ *
11
+ * A book prints "atomic radius decreases across a period" with an arrow, and the statement is the
12
+ * whole of the teaching. But the statement is a CONCLUSION, and handing someone a conclusion is
13
+ * the one thing that guarantees they never do the work that produces it. If the measurements are
14
+ * there instead, a learner can lay them out, see the direction for themselves, predict the next
15
+ * one, and be told whether they were right. {@link trendOf} is what makes that possible: it takes
16
+ * a run of real values and reports which way they go and where they break.
17
+ *
18
+ * So nothing in this file stores a trend. Every direction below comes out of the numbers.
19
+ *
20
+ * ## The exceptions are the point, not the small print
21
+ *
22
+ * First ionisation energy rises across period 3, except twice. Between magnesium and aluminium it
23
+ * falls, and between phosphorus and sulfur it falls again. Those two dips are usually taught as
24
+ * things to remember. They are the opposite: they are the evidence.
25
+ *
26
+ * The first dip happens because aluminium's outer electron is in a 3p orbital, higher in energy
27
+ * than magnesium's filled 3s, so it comes away more easily despite the greater nuclear charge. That
28
+ * is a direct measurement of the fact that a shell has subshells inside it. The second happens
29
+ * because sulfur has its first PAIRED p electron, and two electrons sharing one orbital repel each
30
+ * other, so one leaves more easily than from phosphorus's half-filled subshell. That is a direct
31
+ * measurement of electron pairing.
32
+ *
33
+ * Neither could be deduced from the filling rules. Both are visible in the numbers. So
34
+ * {@link IONISATION_ANOMALIES} carries them with the reasoning attached, and a test asserts that
35
+ * these are the ONLY breaks in the run, which also means a mistyped energy anywhere shows up as a
36
+ * third.
37
+ *
38
+ * ## Bond character is a curve, not a table
39
+ *
40
+ * The usual table says a difference under 0.5 is non-polar, up to 1.7 is polar, and above that is
41
+ * ionic. Those boundaries are conventions drawn across something continuous. Pauling's own relation
42
+ * gives the proportion of ionic character directly, and the familiar 1.7 is simply where it passes
43
+ * a half. {@link ionicCharacter} computes it, and the band names are labels put on the curve rather
44
+ * than the thing itself.
45
+ *
46
+ * Pure: no React, no pixels.
47
+ */
48
+ const READERS = {
49
+ covalentRadius,
50
+ firstIonisationEnergy,
51
+ electronegativity
52
+ };
53
+ const pointsFor = (elements, property) => elements.map((Z) => ({
54
+ Z,
55
+ symbol: symbolOf(Z),
56
+ value: READERS[property](Z)
57
+ })).filter((p) => p.value !== void 0);
58
+ /**
59
+ * A property across one period, in group order.
60
+ *
61
+ * Elements with no measurement are left out rather than given a zero, so a gap in the data shows as
62
+ * a shorter run and never as a spurious plunge to the axis.
63
+ */
64
+ function acrossPeriod(period, property) {
65
+ return pointsFor(PROPERTIES.map((p) => p.Z).filter((Z) => periodOf(Z) === period).sort((a, b) => groupOf(a) - groupOf(b)), property);
66
+ }
67
+ /** A property down one group, in period order. */
68
+ function downGroup(group, property) {
69
+ return pointsFor(PROPERTIES.map((p) => p.Z).filter((Z) => groupOf(Z) === group).sort((a, b) => periodOf(a) - periodOf(b)), property);
70
+ }
71
+ /**
72
+ * Which way a run of measurements goes, and where it breaks.
73
+ *
74
+ * The direction is decided by the whole run rather than step by step, so a couple of dips do not
75
+ * flip a rise into "no pattern". The dips come back as exceptions instead, which is the shape the
76
+ * chemistry actually has: a strong trend with a small number of informative breaks in it.
77
+ */
78
+ function trendOf(points) {
79
+ if (points.length < 2) return {
80
+ direction: "flat",
81
+ exceptions: [],
82
+ points
83
+ };
84
+ const overall = points[points.length - 1].value - points[0].value;
85
+ const span = Math.abs(points[0].value) || 1;
86
+ const direction = Math.abs(overall) / span < .02 ? "flat" : overall > 0 ? "rising" : "falling";
87
+ const exceptions = [];
88
+ for (let i = 1; i < points.length; i += 1) {
89
+ const step = points[i].value - points[i - 1].value;
90
+ if (direction === "rising" ? step < 0 : direction === "falling" ? step > 0 : false) exceptions.push([points[i - 1].symbol, points[i].symbol]);
91
+ }
92
+ return {
93
+ direction,
94
+ exceptions,
95
+ points
96
+ };
97
+ }
98
+ /**
99
+ * Every place first ionisation energy falls as it crosses a period, with what it demonstrates.
100
+ *
101
+ * Four of them, two per period, and they are the same two causes each time: a new subshell starting,
102
+ * and a p orbital taking its second electron.
103
+ */
104
+ const IONISATION_ANOMALIES = [
105
+ {
106
+ before: "Be",
107
+ after: "B",
108
+ reason: "boron's outermost electron is in a 2p orbital, which is higher in energy than beryllium's filled 2s, so it comes away more easily despite boron having the larger nuclear charge. The dip is evidence that a shell contains subshells."
109
+ },
110
+ {
111
+ before: "N",
112
+ after: "O",
113
+ reason: "oxygen has the first PAIRED electron in its 2p subshell, and two electrons sharing one orbital repel each other, so one of them leaves more easily than any electron in nitrogen's half-filled subshell. The dip is evidence of electron pairing."
114
+ },
115
+ {
116
+ before: "Mg",
117
+ after: "Al",
118
+ reason: "aluminium's outermost electron is in a 3p orbital, higher in energy than magnesium's filled 3s, so it comes away more easily. The same subshell effect as beryllium to boron, one period down."
119
+ },
120
+ {
121
+ before: "P",
122
+ after: "S",
123
+ reason: "sulfur has the first paired electron in its 3p subshell, and the repulsion between the two electrons in that orbital makes one easier to remove than any in phosphorus's half-filled subshell. The same pairing effect as nitrogen to oxygen."
124
+ }
125
+ ];
126
+ /** The anomaly between two named elements, if there is one. */
127
+ const ionisationAnomalyFor = (before, after) => IONISATION_ANOMALIES.find((a) => a.before === before && a.after === after);
128
+ /**
129
+ * Read the number of outer-shell electrons off a run of successive ionisation energies.
130
+ *
131
+ * The argument for shells, run as a calculation. Removing electrons from the outer shell gets
132
+ * steadily harder; breaking into the shell beneath is suddenly far harder, because that shell is
133
+ * closer to the nucleus and fully shielded. So the position of the big jump counts the outer shell.
134
+ *
135
+ * Returns undefined when no jump in the data is decisive. That is the honest answer for a run that
136
+ * stops before it reaches the next shell, which is exactly what published runs for neon and argon
137
+ * do: eight ionisation energies, all from the same shell, and no break to find. Returning a number
138
+ * anyway would be inventing a conclusion the measurements do not support.
139
+ */
140
+ function outerElectronsFromIonisation(energies, minimumRatio = 2) {
141
+ if (energies.length < 2) return void 0;
142
+ let best = {
143
+ ratio: 0,
144
+ at: 0
145
+ };
146
+ for (let i = 1; i < energies.length; i += 1) {
147
+ const ratio = energies[i] / energies[i - 1];
148
+ if (ratio > best.ratio) best = {
149
+ ratio,
150
+ at: i
151
+ };
152
+ }
153
+ if (best.ratio < minimumRatio) return void 0;
154
+ return {
155
+ outerElectrons: best.at,
156
+ jumpRatio: best.ratio,
157
+ atIonisation: best.at + 1
158
+ };
159
+ }
160
+ /** The same, for an element this engine has a published run for. */
161
+ function outerElectronsOf(symbol) {
162
+ const energies = SUCCESSIVE_IONISATION_ENERGIES[symbol];
163
+ if (!energies) throw new Error(`no successive ionisation energies for ${symbol}`);
164
+ return outerElectronsFromIonisation(energies);
165
+ }
166
+ /** The gap in electronegativity between two elements, which sets how a bond between them behaves. */
167
+ function electronegativityGap(a, b) {
168
+ const first = elementBySymbol(a);
169
+ const second = elementBySymbol(b);
170
+ if (!first || !second) throw new Error(`no element with symbol "${first ? b : a}"`);
171
+ const x = electronegativity(first.Z);
172
+ const y = electronegativity(second.Z);
173
+ if (x === void 0 || y === void 0) throw new Error(`the Pauling scale has no value for ${x === void 0 ? a : b}, so no difference can be taken`);
174
+ return Math.abs(x - y);
175
+ }
176
+ /**
177
+ * The proportion of ionic character in a bond, from Pauling's relation.
178
+ *
179
+ * ionic character = 1 - exp(-(difference / 2)^2)
180
+ *
181
+ * A curve, not a table. The familiar boundary at a difference of 1.7 is simply where this passes a
182
+ * half, and it is a convention placed on something continuous rather than a line the physics draws.
183
+ */
184
+ const ionicCharacter = (difference) => 1 - Math.exp(-((difference / 2) ** 2));
185
+ /**
186
+ * The name usually given to a bond with this electronegativity difference.
187
+ *
188
+ * The boundaries are the conventional ones. They are labels on {@link ionicCharacter}'s curve, and
189
+ * a bond just either side of one of them is very nearly the same bond, which is worth saying out
190
+ * loud whenever this function's answer is shown to anyone.
191
+ */
192
+ function bondCharacter(difference) {
193
+ if (difference < .5) return "nonpolar covalent";
194
+ if (difference < 1.7) return "polar covalent";
195
+ return "ionic";
196
+ }
197
+ /** The character of the bond between two named elements. */
198
+ const bondBetween = (a, b) => bondCharacter(electronegativityGap(a, b));
199
+ /**
200
+ * Which of two elements holds its outer electrons more tightly, and why.
201
+ *
202
+ * Answers with the reasoning, because "which has the higher ionisation energy" is never the real
203
+ * question: the real question is what about their positions makes it so.
204
+ */
205
+ function compareIonisationEnergy(a, b) {
206
+ const first = elementBySymbol(a);
207
+ const second = elementBySymbol(b);
208
+ if (!first || !second) return void 0;
209
+ const x = firstIonisationEnergy(first.Z);
210
+ const y = firstIonisationEnergy(second.Z);
211
+ if (x === void 0 || y === void 0) return void 0;
212
+ const higher = x > y ? a : b;
213
+ const anomaly = ionisationAnomalyFor(a, b) ?? ionisationAnomalyFor(b, a);
214
+ if (anomaly) return {
215
+ higher,
216
+ reason: anomaly.reason
217
+ };
218
+ return {
219
+ higher,
220
+ reason: periodOf(first.Z) === periodOf(second.Z) ? "they are in the same period, so the electron comes from the same shell, and the one further right has more protons pulling on it" : "the one lower down has its outer electron in a shell further from the nucleus and better shielded by the shells between, so it is held less tightly"
221
+ };
222
+ }
223
+
224
+ //#endregion
225
+ export { IONISATION_ANOMALIES, acrossPeriod, bondBetween, bondCharacter, compareIonisationEnergy, downGroup, electronegativityGap, ionicCharacter, ionisationAnomalyFor, outerElectronsFromIonisation, outerElectronsOf, trendOf };