@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
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Classytic
3
+ Copyright (c) 2026 Classytic LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -14,7 +14,7 @@ npm i @classytic/stage react react-dom
14
14
 
15
15
  Everything is also re‑exported from the root for convenience, but prefer subpaths so
16
16
  your bundle pulls only what it uses (ESM, per‑file emit; `sideEffects` are scoped to
17
- `**/*.css` + `**/assets/**`, so JS treeshakes while styles/assets are preserved):
17
+ `**/*.css`, so JavaScript tree-shakes while the shared stylesheet is preserved):
18
18
 
19
19
  | Subpath | What's in it |
20
20
  |---|---|
@@ -63,3 +63,7 @@ export function Demo() {
63
63
  ## License
64
64
 
65
65
  MIT
66
+
67
+ ## Trademark
68
+
69
+ MIT-licensed code. "Classytic"/"arc" names + logos are trademarks of Classytic LLC — see [TRADEMARK.md](TRADEMARK.md).
@@ -0,0 +1,18 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ }
11
+ if (!no_symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
15
+ };
16
+
17
+ //#endregion
18
+ export { __exportAll };
@@ -1,5 +1,4 @@
1
1
  import { StageAssetDefs } from "./kit/svg-defs.mjs";
2
2
  import { BucketGlyph, HangerHook, WeightGlyph, XBlockGlyph } from "./kit/glyphs.mjs";
3
- import "./kit/index.mjs";
4
3
 
5
4
  export { BucketGlyph, HangerHook, StageAssetDefs, WeightGlyph, XBlockGlyph };
@@ -0,0 +1,144 @@
1
+ //#region src/atomic/aufbau.d.ts
2
+ /**
3
+ * Electron configuration, built by the rules rather than looked up.
4
+ *
5
+ * ## The filling order is generated, not memorised
6
+ *
7
+ * Textbooks print the sequence 1s 2s 2p 3s 3p 4s 3d 4p 5s 4d 5p 6s 4f … and expect it to be learnt,
8
+ * usually with a diagonal-arrow diagram. It is not a sequence to learn. It is one rule:
9
+ *
10
+ * lower (n + l) fills first; where two subshells tie, the lower n fills first
11
+ *
12
+ * That is the Madelung rule, and {@link fillingOrder} generates the sequence from it. So 4s fills
13
+ * before 3d because 4 + 0 = 4 beats 3 + 2 = 5, which is the explanation, and the arrow diagram is
14
+ * only a way of reading the same rule off a grid. Ask for more shells than any book prints and the
15
+ * order keeps going, correctly.
16
+ *
17
+ * ## Hund's rule is about orbitals, not subshells
18
+ *
19
+ * Electrons occupy the orbitals of a subshell singly, with parallel spins, before any orbital takes
20
+ * a second. {@link orbitalDiagram} places them that way, which is what makes the boxes-and-arrows
21
+ * diagram derivable instead of drawn by hand, and it is why nitrogen has three unpaired electrons.
22
+ *
23
+ * ## The exceptions are real physics, and they are listed rather than derived
24
+ *
25
+ * Chromium is [Ar]3d⁵4s¹, not 3d⁴4s². A filled or half-filled d subshell is lower in energy than
26
+ * the plain filling order predicts, by enough to move one electron. That effect is not something
27
+ * the Madelung rule contains, so pretending to derive it would be a lie: {@link ANOMALIES} states
28
+ * each one with its reason, and {@link configurationOf} applies them.
29
+ *
30
+ * ## Ions lose their outermost electrons, not the last one added
31
+ *
32
+ * The single most-missed point in this topic. Iron fills 4s before 3d, so it is tempting to empty
33
+ * 3d first on the way back out. It does not: once 3d is occupied it drops below 4s, so Fe²⁺ is
34
+ * [Ar]3d⁶ with 4s empty, not [Ar]3d⁴4s². {@link ionConfigurationOf} removes from the highest n
35
+ * first, and the doc on it says so, because a learner who gets this wrong gets every transition
36
+ * metal wrong.
37
+ *
38
+ * Pure: no React, no pixels.
39
+ */
40
+ /** One occupied subshell. */
41
+ interface Occupancy {
42
+ readonly n: number;
43
+ readonly l: number;
44
+ /** How many electrons are in it. */
45
+ readonly electrons: number;
46
+ }
47
+ /**
48
+ * A full electron configuration, in SHELL order.
49
+ *
50
+ * Subshells fill in one order and are written in another, and conflating the two is a real source
51
+ * of confusion. Iron fills 4s before 3d, but it is written 3d⁶ 4s², grouped by shell, because that
52
+ * is how the data booklet prints it and because grouping by shell is what makes the outer shell
53
+ * visible at the end of the line. {@link fillingOrder} is the other order, kept separate.
54
+ */
55
+ type Configuration = readonly Occupancy[];
56
+ /**
57
+ * Subshells in the order they fill, by the Madelung (n+l) rule.
58
+ *
59
+ * Generated, so it does not stop where a printed table stops.
60
+ */
61
+ declare function fillingOrder(maxN?: number): {
62
+ n: number;
63
+ l: number;
64
+ }[];
65
+ /** How a subshell is written: 3d. */
66
+ declare const occupancyLabel: (o: {
67
+ n: number;
68
+ l: number;
69
+ }) => string;
70
+ /**
71
+ * A configuration as it is written: 1s² 2s² 2p⁶.
72
+ *
73
+ * The electron count is SUPERSCRIPTED, because "1s2 2s2 2p6" reads as a string of digits and the
74
+ * whole notation depends on the counts being visibly above the line.
75
+ */
76
+ declare const formatConfiguration: (configuration: Configuration) => string;
77
+ /**
78
+ * The plain filling order applied to Z electrons, with no anomalies.
79
+ *
80
+ * Exported because "what the rule predicts" is half of what makes chromium interesting: the other
81
+ * half is {@link configurationOf}, and a learner needs to see both to see that they differ.
82
+ */
83
+ declare function aufbauConfiguration(electrons: number): Configuration;
84
+ interface Anomaly {
85
+ /** Proton number. */
86
+ readonly Z: number;
87
+ /** The subshells that differ from the plain filling order, as {label: electrons}. */
88
+ readonly actual: Readonly<Record<string, number>>;
89
+ /** Why the electron moves. Stated, because the filling rule does not predict it. */
90
+ readonly reason: string;
91
+ }
92
+ /**
93
+ * Ground states that the filling order gets wrong.
94
+ *
95
+ * Each is a measured fact, not a derivation. The list is the commonly examined set plus the ones
96
+ * that follow the same two reasons; an element not listed follows the plain order.
97
+ */
98
+ declare const ANOMALIES: readonly Anomaly[];
99
+ /** The anomaly for this element, if it has one. */
100
+ declare const anomalyFor: (Z: number) => Anomaly | undefined;
101
+ /**
102
+ * The ground-state configuration of a neutral atom: the filling order, with any anomaly applied.
103
+ *
104
+ * The anomaly is applied by OVERRIDING the named subshells and giving the electrons they release to
105
+ * the subshells the anomaly names, so the total is checked rather than assumed. A configuration
106
+ * that did not conserve electrons would be a silent error in a table nobody recounts.
107
+ */
108
+ declare function configurationOf(Z: number): Configuration;
109
+ /**
110
+ * The configuration written from the last noble gas: [Ar] 3d⁵ 4s¹.
111
+ *
112
+ * This is how a chemist writes it, because the core is the part that never takes part in anything.
113
+ */
114
+ declare function condensedConfiguration(Z: number): string;
115
+ /**
116
+ * The configuration of an ion.
117
+ *
118
+ * Electrons are removed from the HIGHEST n first, and within that from the highest l. This is the
119
+ * point everyone loses marks on: iron fills 4s before 3d, but it empties 4s before 3d too, because
120
+ * once 3d is occupied it sits below 4s. So Fe²⁺ is [Ar]3d⁶, never [Ar]3d⁴4s².
121
+ *
122
+ * A negative charge adds electrons in the ordinary filling order.
123
+ */
124
+ declare function ionConfigurationOf(Z: number, charge: number): Configuration;
125
+ /** One orbital in a diagram: how many electrons, and which way they point. */
126
+ interface OrbitalBox {
127
+ readonly m: number;
128
+ /** 0, 1 or 2 electrons. */
129
+ readonly electrons: number;
130
+ /** true when the box holds two opposed electrons. */
131
+ readonly paired: boolean;
132
+ }
133
+ /**
134
+ * The boxes-and-arrows diagram for one subshell, placed by Hund's rule.
135
+ *
136
+ * Every orbital takes one electron, all with the same spin, before any takes a second. So the
137
+ * diagram is derived from the electron count, and a 2p³ is three separate up arrows rather than one
138
+ * pair and a single, which is the whole reason nitrogen behaves as it does.
139
+ */
140
+ declare function orbitalDiagram(l: number, electrons: number): OrbitalBox[];
141
+ /** How many unpaired electrons an atom has, which is what makes it paramagnetic. */
142
+ declare function unpairedElectrons(Z: number): number;
143
+ //#endregion
144
+ export { ANOMALIES, Anomaly, Configuration, Occupancy, OrbitalBox, anomalyFor, aufbauConfiguration, condensedConfiguration, configurationOf, fillingOrder, formatConfiguration, ionConfigurationOf, occupancyLabel, orbitalDiagram, unpairedElectrons };
@@ -0,0 +1,384 @@
1
+ import { magneticNumbers, subshellCapacity, subshellLetter } from "./shells.mjs";
2
+
3
+ //#region src/atomic/aufbau.ts
4
+ /**
5
+ * Electron configuration, built by the rules rather than looked up.
6
+ *
7
+ * ## The filling order is generated, not memorised
8
+ *
9
+ * Textbooks print the sequence 1s 2s 2p 3s 3p 4s 3d 4p 5s 4d 5p 6s 4f … and expect it to be learnt,
10
+ * usually with a diagonal-arrow diagram. It is not a sequence to learn. It is one rule:
11
+ *
12
+ * lower (n + l) fills first; where two subshells tie, the lower n fills first
13
+ *
14
+ * That is the Madelung rule, and {@link fillingOrder} generates the sequence from it. So 4s fills
15
+ * before 3d because 4 + 0 = 4 beats 3 + 2 = 5, which is the explanation, and the arrow diagram is
16
+ * only a way of reading the same rule off a grid. Ask for more shells than any book prints and the
17
+ * order keeps going, correctly.
18
+ *
19
+ * ## Hund's rule is about orbitals, not subshells
20
+ *
21
+ * Electrons occupy the orbitals of a subshell singly, with parallel spins, before any orbital takes
22
+ * a second. {@link orbitalDiagram} places them that way, which is what makes the boxes-and-arrows
23
+ * diagram derivable instead of drawn by hand, and it is why nitrogen has three unpaired electrons.
24
+ *
25
+ * ## The exceptions are real physics, and they are listed rather than derived
26
+ *
27
+ * Chromium is [Ar]3d⁵4s¹, not 3d⁴4s². A filled or half-filled d subshell is lower in energy than
28
+ * the plain filling order predicts, by enough to move one electron. That effect is not something
29
+ * the Madelung rule contains, so pretending to derive it would be a lie: {@link ANOMALIES} states
30
+ * each one with its reason, and {@link configurationOf} applies them.
31
+ *
32
+ * ## Ions lose their outermost electrons, not the last one added
33
+ *
34
+ * The single most-missed point in this topic. Iron fills 4s before 3d, so it is tempting to empty
35
+ * 3d first on the way back out. It does not: once 3d is occupied it drops below 4s, so Fe²⁺ is
36
+ * [Ar]3d⁶ with 4s empty, not [Ar]3d⁴4s². {@link ionConfigurationOf} removes from the highest n
37
+ * first, and the doc on it says so, because a learner who gets this wrong gets every transition
38
+ * metal wrong.
39
+ *
40
+ * Pure: no React, no pixels.
41
+ */
42
+ /** Written order: by shell, then by subshell within it. */
43
+ const byShell = (a, b) => a.n - b.n || a.l - b.l;
44
+ /**
45
+ * Subshells in the order they fill, by the Madelung (n+l) rule.
46
+ *
47
+ * Generated, so it does not stop where a printed table stops.
48
+ */
49
+ function fillingOrder(maxN = 8) {
50
+ const all = [];
51
+ for (let n = 1; n <= maxN; n += 1) for (let l = 0; l < n; l += 1) all.push({
52
+ n,
53
+ l
54
+ });
55
+ return all.sort((a, b) => a.n + a.l - (b.n + b.l) || a.n - b.n);
56
+ }
57
+ /** How a subshell is written: 3d. */
58
+ const occupancyLabel = (o) => `${o.n}${subshellLetter(o.l)}`;
59
+ const SUPERSCRIPT = "⁰¹²³⁴⁵⁶⁷⁸⁹";
60
+ const superscript = (value) => String(value).split("").map((d) => SUPERSCRIPT[Number(d)] ?? d).join("");
61
+ /**
62
+ * A configuration as it is written: 1s² 2s² 2p⁶.
63
+ *
64
+ * The electron count is SUPERSCRIPTED, because "1s2 2s2 2p6" reads as a string of digits and the
65
+ * whole notation depends on the counts being visibly above the line.
66
+ */
67
+ const formatConfiguration = (configuration) => configuration.map((o) => `${occupancyLabel(o)}${superscript(o.electrons)}`).join(" ");
68
+ /**
69
+ * The plain filling order applied to Z electrons, with no anomalies.
70
+ *
71
+ * Exported because "what the rule predicts" is half of what makes chromium interesting: the other
72
+ * half is {@link configurationOf}, and a learner needs to see both to see that they differ.
73
+ */
74
+ function aufbauConfiguration(electrons) {
75
+ if (!Number.isInteger(electrons) || electrons < 0) throw new Error(`electron count must be a non-negative whole number, got ${electrons}`);
76
+ const filled = [];
77
+ let left = electrons;
78
+ for (const { n, l } of fillingOrder()) {
79
+ if (left <= 0) break;
80
+ const take = Math.min(left, subshellCapacity(l));
81
+ filled.push({
82
+ n,
83
+ l,
84
+ electrons: take
85
+ });
86
+ left -= take;
87
+ }
88
+ if (left > 0) throw new Error(`${electrons} electrons do not fit in the shells this engine enumerates`);
89
+ return filled.sort(byShell);
90
+ }
91
+ const HALF_FILLED = "a half-filled subshell is unusually stable, so one s electron moves into it";
92
+ const FILLED = "a filled subshell is unusually stable, so one s electron moves into it";
93
+ const D_BEFORE_F = "the first d electron is lower in energy here than the first f electron, so d fills first";
94
+ /**
95
+ * Ground states that the filling order gets wrong.
96
+ *
97
+ * Each is a measured fact, not a derivation. The list is the commonly examined set plus the ones
98
+ * that follow the same two reasons; an element not listed follows the plain order.
99
+ */
100
+ const ANOMALIES = [
101
+ {
102
+ Z: 24,
103
+ actual: {
104
+ "3d": 5,
105
+ "4s": 1
106
+ },
107
+ reason: HALF_FILLED
108
+ },
109
+ {
110
+ Z: 29,
111
+ actual: {
112
+ "3d": 10,
113
+ "4s": 1
114
+ },
115
+ reason: FILLED
116
+ },
117
+ {
118
+ Z: 41,
119
+ actual: {
120
+ "4d": 4,
121
+ "5s": 1
122
+ },
123
+ reason: "the 4d and 5s levels are so close that a single s electron is enough to lower the total"
124
+ },
125
+ {
126
+ Z: 42,
127
+ actual: {
128
+ "4d": 5,
129
+ "5s": 1
130
+ },
131
+ reason: HALF_FILLED
132
+ },
133
+ {
134
+ Z: 44,
135
+ actual: {
136
+ "4d": 7,
137
+ "5s": 1
138
+ },
139
+ reason: "the 4d and 5s levels are nearly equal, so the d subshell takes the extra electron"
140
+ },
141
+ {
142
+ Z: 45,
143
+ actual: {
144
+ "4d": 8,
145
+ "5s": 1
146
+ },
147
+ reason: "the 4d and 5s levels are nearly equal, so the d subshell takes the extra electron"
148
+ },
149
+ {
150
+ Z: 46,
151
+ actual: {
152
+ "4d": 10,
153
+ "5s": 0
154
+ },
155
+ reason: "the only atom whose outermost s subshell is empty: filling 4d completely pays for both s electrons"
156
+ },
157
+ {
158
+ Z: 47,
159
+ actual: {
160
+ "4d": 10,
161
+ "5s": 1
162
+ },
163
+ reason: FILLED
164
+ },
165
+ {
166
+ Z: 57,
167
+ actual: {
168
+ "4f": 0,
169
+ "5d": 1
170
+ },
171
+ reason: D_BEFORE_F
172
+ },
173
+ {
174
+ Z: 58,
175
+ actual: {
176
+ "4f": 1,
177
+ "5d": 1
178
+ },
179
+ reason: D_BEFORE_F
180
+ },
181
+ {
182
+ Z: 64,
183
+ actual: {
184
+ "4f": 7,
185
+ "5d": 1
186
+ },
187
+ reason: HALF_FILLED
188
+ },
189
+ {
190
+ Z: 78,
191
+ actual: {
192
+ "5d": 9,
193
+ "6s": 1
194
+ },
195
+ reason: "the 5d and 6s levels are nearly equal, so the d subshell takes the extra electron"
196
+ },
197
+ {
198
+ Z: 79,
199
+ actual: {
200
+ "5d": 10,
201
+ "6s": 1
202
+ },
203
+ reason: FILLED
204
+ },
205
+ {
206
+ Z: 89,
207
+ actual: {
208
+ "5f": 0,
209
+ "6d": 1
210
+ },
211
+ reason: D_BEFORE_F
212
+ },
213
+ {
214
+ Z: 90,
215
+ actual: {
216
+ "5f": 0,
217
+ "6d": 2
218
+ },
219
+ reason: D_BEFORE_F
220
+ },
221
+ {
222
+ Z: 91,
223
+ actual: {
224
+ "5f": 2,
225
+ "6d": 1
226
+ },
227
+ reason: D_BEFORE_F
228
+ },
229
+ {
230
+ Z: 92,
231
+ actual: {
232
+ "5f": 3,
233
+ "6d": 1
234
+ },
235
+ reason: D_BEFORE_F
236
+ },
237
+ {
238
+ Z: 93,
239
+ actual: {
240
+ "5f": 4,
241
+ "6d": 1
242
+ },
243
+ reason: D_BEFORE_F
244
+ },
245
+ {
246
+ Z: 96,
247
+ actual: {
248
+ "5f": 7,
249
+ "6d": 1
250
+ },
251
+ reason: HALF_FILLED
252
+ }
253
+ ];
254
+ /** The anomaly for this element, if it has one. */
255
+ const anomalyFor = (Z) => ANOMALIES.find((a) => a.Z === Z);
256
+ /**
257
+ * The ground-state configuration of a neutral atom: the filling order, with any anomaly applied.
258
+ *
259
+ * The anomaly is applied by OVERRIDING the named subshells and giving the electrons they release to
260
+ * the subshells the anomaly names, so the total is checked rather than assumed. A configuration
261
+ * that did not conserve electrons would be a silent error in a table nobody recounts.
262
+ */
263
+ function configurationOf(Z) {
264
+ const base = aufbauConfiguration(Z);
265
+ const anomaly = anomalyFor(Z);
266
+ if (!anomaly) return base;
267
+ const byLabel = new Map(base.map((o) => [occupancyLabel(o), o]));
268
+ for (const [label, electrons] of Object.entries(anomaly.actual)) {
269
+ const existing = byLabel.get(label);
270
+ if (existing) byLabel.set(label, {
271
+ ...existing,
272
+ electrons
273
+ });
274
+ else {
275
+ const n = Number(label[0]);
276
+ const l = "spdfghi".indexOf(label.slice(1));
277
+ byLabel.set(label, {
278
+ n,
279
+ l,
280
+ electrons
281
+ });
282
+ }
283
+ }
284
+ const result = [...byLabel.values()].filter((o) => o.electrons > 0).sort(byShell);
285
+ const total = result.reduce((sum, o) => sum + o.electrons, 0);
286
+ if (total !== Z) throw new Error(`the anomaly for Z=${Z} accounts for ${total} electrons, not ${Z}`);
287
+ return result;
288
+ }
289
+ /** Proton numbers of the noble gases, used to abbreviate a configuration. */
290
+ const NOBLE_GASES = [
291
+ {
292
+ Z: 2,
293
+ symbol: "He"
294
+ },
295
+ {
296
+ Z: 10,
297
+ symbol: "Ne"
298
+ },
299
+ {
300
+ Z: 18,
301
+ symbol: "Ar"
302
+ },
303
+ {
304
+ Z: 36,
305
+ symbol: "Kr"
306
+ },
307
+ {
308
+ Z: 54,
309
+ symbol: "Xe"
310
+ },
311
+ {
312
+ Z: 86,
313
+ symbol: "Rn"
314
+ }
315
+ ];
316
+ /**
317
+ * The configuration written from the last noble gas: [Ar] 3d⁵ 4s¹.
318
+ *
319
+ * This is how a chemist writes it, because the core is the part that never takes part in anything.
320
+ */
321
+ function condensedConfiguration(Z) {
322
+ const core = [...NOBLE_GASES].reverse().find((g) => g.Z < Z);
323
+ const full = configurationOf(Z);
324
+ if (!core) return formatConfiguration(full);
325
+ const outer = full.filter((o) => {
326
+ const inCore = configurationOf(core.Z).find((c) => c.n === o.n && c.l === o.l);
327
+ return !inCore || inCore.electrons !== o.electrons;
328
+ });
329
+ return `[${core.symbol}] ${formatConfiguration(outer)}`;
330
+ }
331
+ /**
332
+ * The configuration of an ion.
333
+ *
334
+ * Electrons are removed from the HIGHEST n first, and within that from the highest l. This is the
335
+ * point everyone loses marks on: iron fills 4s before 3d, but it empties 4s before 3d too, because
336
+ * once 3d is occupied it sits below 4s. So Fe²⁺ is [Ar]3d⁶, never [Ar]3d⁴4s².
337
+ *
338
+ * A negative charge adds electrons in the ordinary filling order.
339
+ */
340
+ function ionConfigurationOf(Z, charge) {
341
+ if (charge <= 0) return aufbauConfiguration(Z - charge);
342
+ if (charge > Z) throw new Error(`cannot remove ${charge} electrons from an atom with ${Z}`);
343
+ const shells = configurationOf(Z).map((o) => ({ ...o }));
344
+ let toRemove = charge;
345
+ while (toRemove > 0) {
346
+ const outermost = shells.filter((o) => o.electrons > 0).sort((a, b) => b.n - a.n || b.l - a.l)[0];
347
+ if (!outermost) throw new Error("ran out of electrons");
348
+ const take = Math.min(toRemove, outermost.electrons);
349
+ outermost.electrons -= take;
350
+ toRemove -= take;
351
+ }
352
+ return shells.filter((o) => o.electrons > 0).sort(byShell);
353
+ }
354
+ /**
355
+ * The boxes-and-arrows diagram for one subshell, placed by Hund's rule.
356
+ *
357
+ * Every orbital takes one electron, all with the same spin, before any takes a second. So the
358
+ * diagram is derived from the electron count, and a 2p³ is three separate up arrows rather than one
359
+ * pair and a single, which is the whole reason nitrogen behaves as it does.
360
+ */
361
+ function orbitalDiagram(l, electrons) {
362
+ const capacity = subshellCapacity(l);
363
+ if (electrons > capacity) throw new Error(`a ${subshellLetter(l)} subshell holds ${capacity} electrons, not ${electrons}`);
364
+ const boxes = magneticNumbers(l).map((m) => ({
365
+ m,
366
+ electrons: 0
367
+ }));
368
+ for (let placed = 0; placed < electrons; placed += 1) {
369
+ const box = boxes[placed % boxes.length];
370
+ box.electrons += 1;
371
+ }
372
+ return boxes.map((b) => ({
373
+ m: b.m,
374
+ electrons: b.electrons,
375
+ paired: b.electrons === 2
376
+ }));
377
+ }
378
+ /** How many unpaired electrons an atom has, which is what makes it paramagnetic. */
379
+ function unpairedElectrons(Z) {
380
+ return configurationOf(Z).reduce((total, o) => total + orbitalDiagram(o.l, o.electrons).filter((b) => b.electrons === 1).length, 0);
381
+ }
382
+
383
+ //#endregion
384
+ export { ANOMALIES, anomalyFor, aufbauConfiguration, condensedConfiguration, configurationOf, fillingOrder, formatConfiguration, ionConfigurationOf, occupancyLabel, orbitalDiagram, unpairedElectrons };
@@ -0,0 +1,67 @@
1
+ //#region src/atomic/elements.d.ts
2
+ /**
3
+ * The elements: proton number, symbol, name and standard atomic weight.
4
+ *
5
+ * ## Why this is data and the rest of the engine is not
6
+ *
7
+ * Everything about WHERE an element sits is computed from its electrons, so this file holds none of
8
+ * it: no groups, no periods, no blocks, no families. What it holds is the part that cannot be
9
+ * derived, only measured, and that has to come from somewhere authoritative.
10
+ *
11
+ * Standard atomic weights are the IUPAC Commission on Isotopic Abundances and Atomic Weights (CIAAW)
12
+ * 2021 conventional values, which is what exam data booklets are built from. For elements with no
13
+ * stable isotope the convention is the mass number of the longest-lived one, and those are marked,
14
+ * because a value in brackets means something different from a measured average and a learner who
15
+ * treats [98] as a weighted mean has misunderstood what they are holding.
16
+ *
17
+ * ## The order is not monotonic, and that is the point
18
+ *
19
+ * Atomic weight mostly rises with proton number and in four places it does not: argon above
20
+ * potassium, cobalt above nickel, tellurium above iodine, thorium above protactinium. Mendeleev
21
+ * ordered by weight and had to put tellurium before iodine anyway to make the chemistry work, which
22
+ * is the historical evidence that proton number, not weight, is what orders the table. A test
23
+ * asserts exactly these four inversions and no others, so a transcription slip anywhere in this
24
+ * file shows up as a fifth.
25
+ *
26
+ * Pure: no React, no pixels.
27
+ */
28
+ interface ElementRecord {
29
+ /** Proton number, which is what orders the table. */
30
+ readonly Z: number;
31
+ readonly symbol: string;
32
+ readonly name: string;
33
+ /**
34
+ * Standard atomic weight, IUPAC CIAAW 2021 conventional value.
35
+ *
36
+ * For an element with no stable isotope this is a MASS NUMBER, not a weighted mean over isotopes.
37
+ * {@link ElementRecord.weightIsMassNumber} says which, because the two are different quantities
38
+ * that happen to be printed in the same column.
39
+ */
40
+ readonly atomicWeight: number;
41
+ readonly weightIsMassNumber: boolean;
42
+ }
43
+ /** Every element, in proton-number order. */
44
+ declare const ELEMENTS: readonly ElementRecord[];
45
+ /** The element with this proton number. */
46
+ declare const elementOf: (Z: number) => ElementRecord | undefined;
47
+ /** Look up by symbol, case-insensitively, so "NA", "Na" and "na" all find sodium. */
48
+ declare const elementBySymbol: (symbol: string) => ElementRecord | undefined;
49
+ /** Look up by name, spelled as IUPAC spells it. */
50
+ declare const elementByName: (name: string) => ElementRecord | undefined;
51
+ /** The symbol for a proton number, which is what a decay equation needs. */
52
+ declare const symbolOf: (Z: number) => string | undefined;
53
+ /**
54
+ * The four places where MEASURED atomic weight falls as proton number rises.
55
+ *
56
+ * Kept as a named export rather than buried in a test, because these pairs ARE the evidence that
57
+ * the table is ordered by proton number: Mendeleev ordered by weight and still had to place
58
+ * tellurium before iodine to keep the chemistry right, which was the anomaly that proton number
59
+ * later explained.
60
+ *
61
+ * Measured weights only. An element with no stable isotope carries the mass number of its
62
+ * longest-lived one, and which isotope lives longest does not rise smoothly with proton number, so
63
+ * those steps down are not inversions in this sense and are not listed.
64
+ */
65
+ declare const MASS_INVERSIONS: readonly (readonly [string, string])[];
66
+ //#endregion
67
+ export { ELEMENTS, ElementRecord, MASS_INVERSIONS, elementByName, elementBySymbol, elementOf, symbolOf };