@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,114 @@
1
+ import { Worked } from "../../core/worked.mjs";
2
+
3
+ //#region src/physics/energy/work.d.ts
4
+ /**
5
+ * Scalar or vector, with the REASON attached.
6
+ *
7
+ * This table exists because the confusion it settles is a reliable source of lost marks and is never
8
+ * addressed head-on: a student who can recite "work is a scalar" will still write a direction beside
9
+ * a work answer, because they were told the fact and not the cause. The cause is that work is a dot
10
+ * product, and a dot product of two vectors is a scalar by construction. Once that is the reason,
11
+ * power and energy follow for free, and momentum and impulse fall on the other side for the equally
12
+ * concrete reason that nothing divided them into a projection.
13
+ */
14
+ interface QuantityKind {
15
+ readonly name: string;
16
+ readonly kind: 'scalar' | 'vector';
17
+ readonly unit: string;
18
+ /** Why it lands on that side. Never "because the book says so". */
19
+ readonly because: string;
20
+ }
21
+ declare const MECHANICAL_KINDS: readonly QuantityKind[];
22
+ /** Look one up by name. Returns undefined rather than throwing: a lab may ask about anything. */
23
+ declare const kindOf: (name: string) => QuantityKind | undefined;
24
+ /** What a given piece of work is DOING to the body's energy. */
25
+ type WorkSign = 'positive' | 'negative' | 'none';
26
+ interface WorkResult {
27
+ /** Joules, signed. */
28
+ readonly value: number;
29
+ readonly sign: WorkSign;
30
+ /** The component of the force that actually did anything: `F cos θ`. */
31
+ readonly effectiveForce: number;
32
+ readonly worked: Worked;
33
+ }
34
+ /**
35
+ * Which of the three a work value is, with the tolerance measured RELATIVE to the scale of the
36
+ * quantities involved.
37
+ *
38
+ * `scale` should be `F × d`: the largest the work could possibly have been. A perpendicular force
39
+ * gives a `cos` that is 6.1e-17 rather than 0, and multiplying that by a large force and a long
40
+ * distance produces a number that beats any fixed epsilon while still being nothing at all. Judging
41
+ * it against what the work COULD have been is the only test that holds at every size.
42
+ */
43
+ declare function signOfWork(value: number, scale?: number): WorkSign;
44
+ /**
45
+ * `W = F d cos θ`, where `θ` is the angle between the force and the displacement.
46
+ *
47
+ * The parameter is named `angleToDisplacementDeg` and not `angle` on purpose. Half of all lost marks
48
+ * on this topic are a correct multiplication of the wrong angle, and a name that states which two
49
+ * lines the angle sits between is the cheapest possible fix for that.
50
+ */
51
+ declare function workDone(force: number, displacement: number, angleToDisplacementDeg?: number, sf?: number): WorkResult;
52
+ /**
53
+ * Work from components, when both vectors are already resolved: `W = Fx dx + Fy dy (+ Fz dz)`.
54
+ *
55
+ * The same quantity by the other route, and worth having because it is how a 3D question must be
56
+ * done and because seeing `F d cos θ` and the component sum agree is what makes the dot product
57
+ * stop being two unrelated definitions.
58
+ */
59
+ declare function workFromComponents(force: readonly number[], displacement: readonly number[], sf?: number): WorkResult;
60
+ /** The angle between two vectors, recovered from the work they produced. */
61
+ declare function angleFromWork(work: number, force: number, displacement: number): number;
62
+ interface LiftWorkResult {
63
+ readonly value: number;
64
+ /** The work gravity itself did: the same size, opposite sign. */
65
+ readonly workByGravity: number;
66
+ readonly worked: Worked;
67
+ }
68
+ /**
69
+ * Work done against gravity in raising a mass through a height gain.
70
+ *
71
+ * The whole point, and the reason this is a named function rather than a call to `workDone`, is the
72
+ * thing it deliberately does NOT take: a path. Stairs, a ramp, a ladder, a winding road. Gravity
73
+ * charges for the height and for nothing else, so a 2 m staircase at 30 degrees and a 1 m vertical
74
+ * climb cost the same. Students who carry the slope length into this are answering the question the
75
+ * diagram invited rather than the one gravity asks.
76
+ *
77
+ * `heightGain` is signed, so a descent returns negative work, which is correct and is how a lowering
78
+ * question should be posed.
79
+ */
80
+ declare function workAgainstGravity(mass: number, heightGain: number, g?: number, sf?: number): LiftWorkResult;
81
+ /**
82
+ * The height gain of a body dragged along a slope, and the work that costs.
83
+ *
84
+ * Their standard picture: a slope of a stated LENGTH and ANGLE, or of a stated length and height.
85
+ * Both are here because both appear, and because the resolution `h = L sin θ` is the single line
86
+ * that connects them.
87
+ */
88
+ declare function workUpSlope(mass: number, slopeLength: number, angleDeg: number, g?: number, sf?: number): LiftWorkResult & {
89
+ readonly heightGain: number;
90
+ readonly forceAlongSlope: number;
91
+ };
92
+ /**
93
+ * The work a stated force does in dragging a body up a rough slope: the full three-term account.
94
+ *
95
+ * Kept separate from `workUpSlope` because the moment friction enters, the applied force is no
96
+ * longer determined by the geometry and must be given. Returns each contribution so a lab can show
97
+ * where the energy went, which is the only way the sum stops looking arbitrary.
98
+ */
99
+ declare function slopeEnergyAudit(mass: number, slopeLength: number, angleDeg: number, frictionCoefficient: number, g?: number, sf?: number): {
100
+ readonly againstGravity: number;
101
+ readonly againstFriction: number;
102
+ readonly value: number;
103
+ readonly normalForce: number;
104
+ readonly worked: Worked;
105
+ };
106
+ /**
107
+ * Work by a force that is itself a vector, against a displacement that is a vector.
108
+ *
109
+ * A convenience over `workFromComponents` for the common 2D case where both are given in polar
110
+ * form, which is how a question phrases it in words.
111
+ */
112
+ declare function workFromPolar(force: number, forceAngleDeg: number, displacement: number, displacementAngleDeg: number, sf?: number): WorkResult;
113
+ //#endregion
114
+ export { LiftWorkResult, MECHANICAL_KINDS, QuantityKind, WorkResult, WorkSign, angleFromWork, kindOf, signOfWork, slopeEnergyAudit, workAgainstGravity, workDone, workFromComponents, workFromPolar, workUpSlope };
@@ -0,0 +1,219 @@
1
+ import { calc, texSigFigs } from "../../core/worked.mjs";
2
+ import { compose, resolve, toDegrees } from "../vectors.mjs";
3
+ import { G_EARTH } from "../kinematics/free-fall.mjs";
4
+ import { frictionOn } from "../dynamics/friction.mjs";
5
+
6
+ //#region src/physics/energy/work.ts
7
+ /**
8
+ * Work: the dot product, wearing a physics hat.
9
+ *
10
+ * Every formula in this file is `W = F·d`. The list of cases a textbook prints (work by a constant
11
+ * force, work going up a slope, work against gravity, work done by friction) is not a list of
12
+ * formulas. It is one formula asked about four geometries, and the only thing that changes is which
13
+ * angle you feed it.
14
+ *
15
+ * TWO IDEAS DO ALL THE LIFTING HERE, and both are about the `cos θ`:
16
+ *
17
+ * 1. `θ` is the angle between the FORCE and the DISPLACEMENT. Not between the force and the
18
+ * ground, not between the force and the slope. Learners lose marks by pairing the angle with
19
+ * whichever line is drawn most prominently in the diagram, which is usually neither of those.
20
+ * 2. `cos θ` carries a SIGN, and the sign is the physics. Positive work puts energy in, negative
21
+ * work takes it out, and `θ = 90°` does nothing at all: this is why carrying a bag along a
22
+ * level corridor is no work on the bag however much your arm disagrees, and why the tension in
23
+ * a string does no work on a body going round a circle.
24
+ *
25
+ * Pure: no React, no pixels.
26
+ */
27
+ const MECHANICAL_KINDS = [
28
+ {
29
+ name: "work",
30
+ kind: "scalar",
31
+ unit: "J",
32
+ because: "a dot product of force and displacement, and a dot product returns a plain number"
33
+ },
34
+ {
35
+ name: "energy",
36
+ kind: "scalar",
37
+ unit: "J",
38
+ because: "it is what work deposits, so it inherits work being a scalar"
39
+ },
40
+ {
41
+ name: "power",
42
+ kind: "scalar",
43
+ unit: "W",
44
+ because: "a scalar (work) divided by a scalar (time) stays a scalar"
45
+ },
46
+ {
47
+ name: "force",
48
+ kind: "vector",
49
+ unit: "N",
50
+ because: "a push has a direction, and two pushes add by the triangle rule rather than by adding numbers"
51
+ },
52
+ {
53
+ name: "displacement",
54
+ kind: "vector",
55
+ unit: "m",
56
+ because: "it is the straight line from start to finish, which needs a direction to be stated at all"
57
+ },
58
+ {
59
+ name: "momentum",
60
+ kind: "vector",
61
+ unit: "kg m s^-1",
62
+ because: "mass times velocity, and multiplying a vector by a plain number leaves it a vector"
63
+ },
64
+ {
65
+ name: "impulse",
66
+ kind: "vector",
67
+ unit: "N s",
68
+ because: "force times time, with nothing projecting it onto anything, so the direction survives"
69
+ }
70
+ ];
71
+ /** Look one up by name. Returns undefined rather than throwing: a lab may ask about anything. */
72
+ const kindOf = (name) => MECHANICAL_KINDS.find((k) => k.name === name.toLowerCase());
73
+ const describeSign = (sign) => sign === "positive" ? "positive: the force has a component along the motion, so it feeds energy in" : sign === "negative" ? "negative: the force opposes the motion, so it takes energy out" : "zero: the force is perpendicular to the motion, so it transfers nothing however large it is";
74
+ /**
75
+ * Which of the three a work value is, with the tolerance measured RELATIVE to the scale of the
76
+ * quantities involved.
77
+ *
78
+ * `scale` should be `F × d`: the largest the work could possibly have been. A perpendicular force
79
+ * gives a `cos` that is 6.1e-17 rather than 0, and multiplying that by a large force and a long
80
+ * distance produces a number that beats any fixed epsilon while still being nothing at all. Judging
81
+ * it against what the work COULD have been is the only test that holds at every size.
82
+ */
83
+ function signOfWork(value, scale = 1) {
84
+ if (Math.abs(value) <= Math.max(Math.abs(scale), 1) * 1e-12) return "none";
85
+ return value > 0 ? "positive" : "negative";
86
+ }
87
+ /**
88
+ * `W = F d cos θ`, where `θ` is the angle between the force and the displacement.
89
+ *
90
+ * The parameter is named `angleToDisplacementDeg` and not `angle` on purpose. Half of all lost marks
91
+ * on this topic are a correct multiplication of the wrong angle, and a name that states which two
92
+ * lines the angle sits between is the cheapest possible fix for that.
93
+ */
94
+ function workDone(force, displacement, angleToDisplacementDeg = 0, sf = 3) {
95
+ const effectiveForce = resolve(force, angleToDisplacementDeg).x;
96
+ const value = effectiveForce * displacement;
97
+ const sign = signOfWork(value, force * displacement);
98
+ return {
99
+ value,
100
+ sign,
101
+ effectiveForce,
102
+ worked: calc().step("W = \\vec{F} \\cdot \\vec{d} = F d \\cos\\theta", "theta is the angle between the force and the DISPLACEMENT, not between the force and the ground").step(`W = ${texSigFigs(force, sf)} \\times ${texSigFigs(displacement, sf)} \\times \\cos ${texSigFigs(angleToDisplacementDeg, sf)}^\\circ`).step(`F\\cos\\theta = ${texSigFigs(effectiveForce, sf)}\\ \\mathrm{N}`, "only this component lies along the motion. The rest of the force does nothing to the energy").step(`W = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, describeSign(sign)).done(value)
103
+ };
104
+ }
105
+ /**
106
+ * Work from components, when both vectors are already resolved: `W = Fx dx + Fy dy (+ Fz dz)`.
107
+ *
108
+ * The same quantity by the other route, and worth having because it is how a 3D question must be
109
+ * done and because seeing `F d cos θ` and the component sum agree is what makes the dot product
110
+ * stop being two unrelated definitions.
111
+ */
112
+ function workFromComponents(force, displacement, sf = 3) {
113
+ if (force.length !== displacement.length) throw new Error(`A force with ${force.length} components cannot be dotted with a displacement with ${displacement.length}. Both vectors must live in the same number of dimensions.`);
114
+ let value = 0;
115
+ for (let i = 0; i < force.length; i++) value += force[i] * displacement[i];
116
+ const dMag = Math.hypot(...displacement);
117
+ const sign = signOfWork(value, Math.hypot(...force) * dMag);
118
+ const terms = force.map((f, i) => `(${texSigFigs(f, sf)})(${texSigFigs(displacement[i], sf)})`);
119
+ const worked = calc().step("\\vec{F} \\cdot \\vec{d} = F_x d_x + F_y d_y + F_z d_z", "multiply matching components and add. No angle is needed, because the components already encode it").step(`W = ${terms.join(" + ")}`).step(`W = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, describeSign(sign)).done(value);
120
+ return {
121
+ value,
122
+ sign,
123
+ effectiveForce: dMag === 0 ? 0 : value / dMag,
124
+ worked
125
+ };
126
+ }
127
+ /** The angle between two vectors, recovered from the work they produced. */
128
+ function angleFromWork(work, force, displacement) {
129
+ const product = force * displacement;
130
+ if (product === 0) throw new Error("With a zero force or a zero displacement the angle is not defined by the work.");
131
+ const cos = Math.max(-1, Math.min(1, work / product));
132
+ return toDegrees(Math.acos(cos));
133
+ }
134
+ /**
135
+ * Work done against gravity in raising a mass through a height gain.
136
+ *
137
+ * The whole point, and the reason this is a named function rather than a call to `workDone`, is the
138
+ * thing it deliberately does NOT take: a path. Stairs, a ramp, a ladder, a winding road. Gravity
139
+ * charges for the height and for nothing else, so a 2 m staircase at 30 degrees and a 1 m vertical
140
+ * climb cost the same. Students who carry the slope length into this are answering the question the
141
+ * diagram invited rather than the one gravity asks.
142
+ *
143
+ * `heightGain` is signed, so a descent returns negative work, which is correct and is how a lowering
144
+ * question should be posed.
145
+ */
146
+ function workAgainstGravity(mass, heightGain, g = G_EARTH, sf = 3) {
147
+ const value = mass * g * heightGain;
148
+ const worked = calc().step("W = mgh", "the path is not in this formula. Only the height gain is, so every route between the same two levels costs the same").step(`W = ${texSigFigs(mass, sf)} \\times ${texSigFigs(g, sf)} \\times ${texSigFigs(heightGain, sf)}`).step(`W = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, heightGain >= 0 ? "done against gravity, so it is stored and can be got back" : "gravity did this work on the body, so energy came out").done(value);
149
+ return {
150
+ value,
151
+ workByGravity: -value,
152
+ worked
153
+ };
154
+ }
155
+ /**
156
+ * The height gain of a body dragged along a slope, and the work that costs.
157
+ *
158
+ * Their standard picture: a slope of a stated LENGTH and ANGLE, or of a stated length and height.
159
+ * Both are here because both appear, and because the resolution `h = L sin θ` is the single line
160
+ * that connects them.
161
+ */
162
+ function workUpSlope(mass, slopeLength, angleDeg, g = G_EARTH, sf = 3) {
163
+ const heightGain = resolve(slopeLength, angleDeg).y;
164
+ const forceAlongSlope = frictionOn({
165
+ mass,
166
+ muStatic: 0,
167
+ inclineDeg: angleDeg,
168
+ g
169
+ }).driving;
170
+ const value = forceAlongSlope * slopeLength;
171
+ const worked = calc().step("F = mg\\sin\\theta", "on a smooth slope the only thing to push against is the component of the weight that lies along it").step(`F = ${texSigFigs(mass, sf)} \\times ${texSigFigs(g, sf)} \\times \\sin ${texSigFigs(angleDeg, sf)}^\\circ = ${texSigFigs(forceAlongSlope, sf)}\\ \\mathrm{N}`).step(`W = F L = ${texSigFigs(forceAlongSlope, sf)} \\times ${texSigFigs(slopeLength, sf)} = ${texSigFigs(value, sf)}\\ \\mathrm{J}`).step(`h = L\\sin\\theta = ${texSigFigs(heightGain, sf)}\\ \\mathrm{m}, \\quad mgh = ${texSigFigs(mass * g * heightGain, sf)}\\ \\mathrm{J}`, "the same answer by the height alone. The slope changed the force and the distance in exactly compensating ways").done(value);
172
+ return {
173
+ value,
174
+ workByGravity: -value,
175
+ heightGain,
176
+ forceAlongSlope,
177
+ worked
178
+ };
179
+ }
180
+ /**
181
+ * The work a stated force does in dragging a body up a rough slope: the full three-term account.
182
+ *
183
+ * Kept separate from `workUpSlope` because the moment friction enters, the applied force is no
184
+ * longer determined by the geometry and must be given. Returns each contribution so a lab can show
185
+ * where the energy went, which is the only way the sum stops looking arbitrary.
186
+ */
187
+ function slopeEnergyAudit(mass, slopeLength, angleDeg, frictionCoefficient, g = G_EARTH, sf = 3) {
188
+ const onSlope = frictionOn({
189
+ mass,
190
+ muStatic: frictionCoefficient,
191
+ inclineDeg: angleDeg,
192
+ g
193
+ });
194
+ const normalForce = onSlope.normal;
195
+ const againstGravity = onSlope.driving * slopeLength;
196
+ const againstFriction = onSlope.limiting * slopeLength;
197
+ const value = againstGravity + againstFriction;
198
+ return {
199
+ againstGravity,
200
+ againstFriction,
201
+ value,
202
+ normalForce,
203
+ worked: calc().step("W = W_{\\text{gravity}} + W_{\\text{friction}}", "two things resist the drag, and they resist for different reasons, so they are counted separately").step(`W_{\\text{gravity}} = mg\\sin\\theta \\cdot L = ${texSigFigs(againstGravity, sf)}\\ \\mathrm{J}`, "recoverable: let the body slide back and you get this returned").step(`N = mg\\cos\\theta = ${texSigFigs(normalForce, sf)}\\ \\mathrm{N}`, "the slope only presses back on the component pressing into it").step(`W_{\\text{friction}} = \\mu N L = ${texSigFigs(frictionCoefficient, sf)} \\times ${texSigFigs(normalForce, sf)} \\times ${texSigFigs(slopeLength, sf)} = ${texSigFigs(againstFriction, sf)}\\ \\mathrm{J}`, "gone as heat. Sliding back down does not give it back, and sliding back costs it again").step(`W = ${texSigFigs(value, sf)}\\ \\mathrm{J}`).done(value)
204
+ };
205
+ }
206
+ /**
207
+ * Work by a force that is itself a vector, against a displacement that is a vector.
208
+ *
209
+ * A convenience over `workFromComponents` for the common 2D case where both are given in polar
210
+ * form, which is how a question phrases it in words.
211
+ */
212
+ function workFromPolar(force, forceAngleDeg, displacement, displacementAngleDeg, sf = 3) {
213
+ const f = resolve(force, forceAngleDeg);
214
+ const d = resolve(displacement, displacementAngleDeg);
215
+ return workDone(force, displacement, compose(d.x, d.y).angleDeg - compose(f.x, f.y).angleDeg, sf);
216
+ }
217
+
218
+ //#endregion
219
+ export { MECHANICAL_KINDS, angleFromWork, kindOf, signOfWork, slopeEnergyAudit, workAgainstGravity, workDone, workFromComponents, workFromPolar, workUpSlope };
@@ -0,0 +1,85 @@
1
+ import { Worked } from "../../core/worked.mjs";
2
+
3
+ //#region src/physics/gravitation/body.d.ts
4
+ /**
5
+ * A spherically symmetric attracting body.
6
+ *
7
+ * Spherical symmetry is doing real work here and is not a simplifying lie: by the shell theorem it
8
+ * is exactly why a planet can be treated as a point at its centre, which is the assumption every
9
+ * formula in this kernel rests on. `potential.ts` proves it rather than asserting it.
10
+ */
11
+ interface CentralBody {
12
+ readonly name: string;
13
+ /** Mass, kg. Present for teaching; prefer `mu` for anything that must be accurate. */
14
+ readonly mass: number;
15
+ /** Mean radius, m. */
16
+ readonly radius: number;
17
+ /** Standard gravitational parameter `GM`, m³/s². The number the physics actually uses. */
18
+ readonly mu: number;
19
+ /**
20
+ * Sidereal rotation period, s, where the body has one.
21
+ *
22
+ * The SIDEREAL day, not the solar day: 86164 s for the Earth, not 86400. A geostationary
23
+ * satellite has to keep pace with the Earth's rotation against the stars, and using 86400 puts
24
+ * the orbit about 80 km too high. The difference is four minutes and it is not rounding.
25
+ */
26
+ readonly rotationPeriodS?: number;
27
+ }
28
+ /** A body from its mass and radius, the textbook pair. `mu` is derived, so it inherits `G`'s error. */
29
+ declare function bodyFromMass(name: string, mass: number, radius: number, G?: number): CentralBody;
30
+ /**
31
+ * A body from its MEAN DENSITY and radius: `M = (4/3)πR³ρ`, so `g = (4/3)πGρR`.
32
+ *
33
+ * The form worth knowing, because it says the thing the mass form hides: at equal density, surface
34
+ * gravity is proportional to RADIUS ALONE. A planet twice the size of another made of the same
35
+ * stuff has twice the surface gravity, not four times and not eight. Students reliably guess one of
36
+ * the other two, because they are reasoning from `M/R²` without noticing `M` carries an `R³`.
37
+ */
38
+ declare function bodyFromDensity(name: string, meanDensity: number, radius: number, G?: number): CentralBody;
39
+ /**
40
+ * A body from its SURFACE GRAVITY and radius: `mu = gR²`.
41
+ *
42
+ * The most accurate route available in a classroom, and the one to prefer whenever a question gives
43
+ * you `g`, because it never touches `G` at all. `gR²` for the Earth is 9.81 × (6.371×10⁶)² which
44
+ * lands within a fraction of a percent of the measured `mu`, whereas going via `M` and `G` throws
45
+ * away four figures for nothing.
46
+ */
47
+ declare function bodyFromSurfaceGravity(name: string, surfaceG: number, radius: number, G?: number): CentralBody;
48
+ /** Surface gravity, m/s²: `g = mu/R²`. What a scale at the poles would read per kilogram. */
49
+ declare const surfaceGravity: (body: CentralBody) => number;
50
+ /** Mean density, kg/m³: mass over the volume of the sphere. */
51
+ declare const meanDensity: (body: CentralBody) => number;
52
+ /** The body's volume, m³. Separated out because the density questions ask for it directly. */
53
+ declare const bodyVolume: (body: CentralBody) => number;
54
+ /**
55
+ * Surface gravity worked through from the density, showing why radius alone decides it.
56
+ *
57
+ * Exists as a `Worked` rather than a bare number because the CANCELLATION is the lesson: the `R³`
58
+ * in the mass meets the `R²` underneath and one `R` survives.
59
+ */
60
+ declare function surfaceGravityFromDensity(meanDensityKgM3: number, radius: number, G?: number, sf?: number): Worked;
61
+ /**
62
+ * The ratio of surface gravities of two bodies: `g₁/g₂ = (M₁/M₂)(R₂/R₁)²`.
63
+ *
64
+ * The single commonest exam framing in the chapter ("the Moon's mass is 1/81 of the Earth's and its
65
+ * radius 1/4, so what does an 80 kg astronaut weigh there?"), and the one where students halve when
66
+ * they should quarter. Note `G` never appears: a ratio question needs no constant, and reaching for
67
+ * one is the sign of a student solving it the long way.
68
+ */
69
+ declare function surfaceGravityRatio(a: CentralBody, b: CentralBody, sf?: number): Worked;
70
+ /** Earth. Mean radius; the equatorial radius is 6.3781×10⁶ m and matters for latitude questions. */
71
+ declare const EARTH: CentralBody;
72
+ /** The Moon. Its mass is 1/81.3 of the Earth's, which is the "81" every textbook problem uses. */
73
+ declare const MOON: CentralBody;
74
+ /** The Sun. */
75
+ declare const SUN: CentralBody;
76
+ /** Mars. A sidereal day of 24 h 37 min, which is why its "areostationary" orbit is a nice exercise. */
77
+ declare const MARS: CentralBody;
78
+ /** Jupiter. Ten hours to turn once, and 318 Earth masses. */
79
+ declare const JUPITER: CentralBody;
80
+ /** Mean Earth-Moon centre separation, m. The distance the null-point questions are set at. */
81
+ declare const EARTH_MOON_DISTANCE = 384400000;
82
+ /** Mean Earth-Sun separation, m. One astronomical unit. */
83
+ declare const EARTH_SUN_DISTANCE = 149597870700;
84
+ //#endregion
85
+ export { CentralBody, EARTH, EARTH_MOON_DISTANCE, EARTH_SUN_DISTANCE, JUPITER, MARS, MOON, SUN, bodyFromDensity, bodyFromMass, bodyFromSurfaceGravity, bodyVolume, meanDensity, surfaceGravity, surfaceGravityFromDensity, surfaceGravityRatio };
@@ -0,0 +1,168 @@
1
+ import { GRAVITATIONAL_CONSTANT } from "../../core/constants.mjs";
2
+ import { calc, texSigFigs } from "../../core/worked.mjs";
3
+
4
+ //#region src/physics/gravitation/body.ts
5
+ /**
6
+ * The attracting body, as ONE object that every other function in this kernel takes.
7
+ *
8
+ * ── Why this file exists at all ─────────────────────────────────────────────────────────────────
9
+ * A gravitation chapter looks like twenty formulas. Written out, they are:
10
+ *
11
+ * g = GM/R² g' = GM/(R+h)² g' = g(1 − d/R) g = (4/3)πGρR
12
+ * V = −GM/r E = −GM/r² v_e = √(2GM/R) v_e = √(2gR)
13
+ * v = √(GM/r) T² = 4π²r³/GM E = −GMm/2r ...
14
+ *
15
+ * Every one of them contains `GM` and a distance. Nothing else. `G`, `M`, `R` and `ρ` never appear
16
+ * independently: they appear as the product `GM` and as a length. So the twenty formulas are two
17
+ * numbers wearing different hats, and a student who has memorised them as twenty separate facts is
18
+ * carrying eighteen unnecessary things and will still pick the wrong one under exam pressure.
19
+ *
20
+ * A kernel can either reproduce that confusion, by taking `(G, M, R)` as three loose arguments in
21
+ * every function, or it can say the true thing in its types: there is a BODY, and it has a `mu`.
22
+ * That is what this is. Pass a body and a radius, get physics.
23
+ *
24
+ * ── Why `mu` is stored rather than computed ─────────────────────────────────────────────────────
25
+ * `mu = GM` is the standard gravitational parameter, and for every real body it is known FAR more
26
+ * precisely than `G` or `M` are known separately: it is measured directly from how things orbit,
27
+ * to ten significant figures for the Earth, while `M` on its own is known to four because getting
28
+ * it means dividing by `G` (see `GRAVITATIONAL_CONSTANT`, the worst-measured constant in physics).
29
+ *
30
+ * So `EARTH.mu` is the measured 3.986004418×10¹⁴, NOT `G × EARTH.mass`, and those two differ in the
31
+ * fifth figure. A lab quoting the Earth's mass to six figures is quoting precision that does not
32
+ * exist. This is not pedantry about digits: it is the reason satellite navigation works at all
33
+ * without anyone knowing what the Earth weighs.
34
+ *
35
+ * ── Why the constructors take different pairs ───────────────────────────────────────────────────
36
+ * Exam questions do not hand you a mass. They hand you a density and a radius, or a surface `g` and
37
+ * a radius, or a moon's period and orbit, and the FIRST step is always recovering the body. Making
38
+ * that step a named constructor means the kernel can show its working for it, instead of a lesson
39
+ * doing the algebra inline and the kernel picking up afterwards.
40
+ *
41
+ * Pure: no React, no pixels.
42
+ */
43
+ const positive = (value, what) => {
44
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive and finite`);
45
+ return value;
46
+ };
47
+ /** A body from its mass and radius, the textbook pair. `mu` is derived, so it inherits `G`'s error. */
48
+ function bodyFromMass(name, mass, radius, G = GRAVITATIONAL_CONSTANT) {
49
+ return {
50
+ name,
51
+ mass: positive(mass, "mass"),
52
+ radius: positive(radius, "radius"),
53
+ mu: G * mass
54
+ };
55
+ }
56
+ /**
57
+ * A body from its MEAN DENSITY and radius: `M = (4/3)πR³ρ`, so `g = (4/3)πGρR`.
58
+ *
59
+ * The form worth knowing, because it says the thing the mass form hides: at equal density, surface
60
+ * gravity is proportional to RADIUS ALONE. A planet twice the size of another made of the same
61
+ * stuff has twice the surface gravity, not four times and not eight. Students reliably guess one of
62
+ * the other two, because they are reasoning from `M/R²` without noticing `M` carries an `R³`.
63
+ */
64
+ function bodyFromDensity(name, meanDensity, radius, G = GRAVITATIONAL_CONSTANT) {
65
+ const r = positive(radius, "radius");
66
+ const mass = 4 / 3 * Math.PI * r ** 3 * positive(meanDensity, "density");
67
+ return {
68
+ name,
69
+ mass,
70
+ radius: r,
71
+ mu: G * mass
72
+ };
73
+ }
74
+ /**
75
+ * A body from its SURFACE GRAVITY and radius: `mu = gR²`.
76
+ *
77
+ * The most accurate route available in a classroom, and the one to prefer whenever a question gives
78
+ * you `g`, because it never touches `G` at all. `gR²` for the Earth is 9.81 × (6.371×10⁶)² which
79
+ * lands within a fraction of a percent of the measured `mu`, whereas going via `M` and `G` throws
80
+ * away four figures for nothing.
81
+ */
82
+ function bodyFromSurfaceGravity(name, surfaceG, radius, G = GRAVITATIONAL_CONSTANT) {
83
+ const r = positive(radius, "radius");
84
+ const mu = positive(surfaceG, "surface gravity") * r * r;
85
+ return {
86
+ name,
87
+ mass: mu / G,
88
+ radius: r,
89
+ mu
90
+ };
91
+ }
92
+ /** Surface gravity, m/s²: `g = mu/R²`. What a scale at the poles would read per kilogram. */
93
+ const surfaceGravity = (body) => body.mu / body.radius ** 2;
94
+ /** Mean density, kg/m³: mass over the volume of the sphere. */
95
+ const meanDensity = (body) => body.mass / (4 / 3 * Math.PI * body.radius ** 3);
96
+ /** The body's volume, m³. Separated out because the density questions ask for it directly. */
97
+ const bodyVolume = (body) => 4 / 3 * Math.PI * body.radius ** 3;
98
+ /**
99
+ * Surface gravity worked through from the density, showing why radius alone decides it.
100
+ *
101
+ * Exists as a `Worked` rather than a bare number because the CANCELLATION is the lesson: the `R³`
102
+ * in the mass meets the `R²` underneath and one `R` survives.
103
+ */
104
+ function surfaceGravityFromDensity(meanDensityKgM3, radius, G = GRAVITATIONAL_CONSTANT, sf = 3) {
105
+ const r = positive(radius, "radius");
106
+ const rho = positive(meanDensityKgM3, "density");
107
+ const value = 4 / 3 * Math.PI * G * rho * r;
108
+ return calc().step("g = \\frac{GM}{R^2}", "the surface is just r = R in the field equation").step("M = \\tfrac{4}{3}\\pi R^3 \\rho", "a sphere of uniform density").step("g = \\frac{G}{R^2}\\cdot\\tfrac{4}{3}\\pi R^3 \\rho = \\tfrac{4}{3}\\pi G \\rho R", "the R cubed meets the R squared and ONE power of R survives: at equal density, g goes as the radius").step(`g = \\tfrac{4}{3}\\pi \\times ${texSigFigs(G, 4)} \\times ${texSigFigs(rho, sf)} \\times ${texSigFigs(r, sf)}`).step(`g = ${texSigFigs(value, sf)}\\ \\mathrm{m\\,s^{-2}}`).done(value);
109
+ }
110
+ /**
111
+ * The ratio of surface gravities of two bodies: `g₁/g₂ = (M₁/M₂)(R₂/R₁)²`.
112
+ *
113
+ * The single commonest exam framing in the chapter ("the Moon's mass is 1/81 of the Earth's and its
114
+ * radius 1/4, so what does an 80 kg astronaut weigh there?"), and the one where students halve when
115
+ * they should quarter. Note `G` never appears: a ratio question needs no constant, and reaching for
116
+ * one is the sign of a student solving it the long way.
117
+ */
118
+ function surfaceGravityRatio(a, b, sf = 3) {
119
+ const value = surfaceGravity(a) / surfaceGravity(b);
120
+ return calc().step("\\frac{g_1}{g_2} = \\frac{GM_1/R_1^2}{GM_2/R_2^2}", "write both out").step("\\frac{g_1}{g_2} = \\frac{M_1}{M_2}\\left(\\frac{R_2}{R_1}\\right)^{2}", "G cancels. A ratio question never needs the constant, and never needs either mass on its own").step(`\\frac{g_1}{g_2} = ${texSigFigs(a.mass / b.mass, sf)} \\times \\left(${texSigFigs(b.radius / a.radius, sf)}\\right)^{-2}`, `${a.name} against ${b.name}`).step(`\\frac{g_1}{g_2} = ${texSigFigs(value, sf)}`).done(value);
121
+ }
122
+ /** Earth. Mean radius; the equatorial radius is 6.3781×10⁶ m and matters for latitude questions. */
123
+ const EARTH = {
124
+ name: "Earth",
125
+ mass: 59722e20,
126
+ radius: 6371e3,
127
+ mu: 3986004418e5,
128
+ rotationPeriodS: 86164.0905
129
+ };
130
+ /** The Moon. Its mass is 1/81.3 of the Earth's, which is the "81" every textbook problem uses. */
131
+ const MOON = {
132
+ name: "Moon",
133
+ mass: 7346e19,
134
+ radius: 1737400,
135
+ mu: 49048695e5,
136
+ rotationPeriodS: 2360591.5
137
+ };
138
+ /** The Sun. */
139
+ const SUN = {
140
+ name: "Sun",
141
+ mass: 198847e25,
142
+ radius: 6957e5,
143
+ mu: 0x731c14d0e4439c000,
144
+ rotationPeriodS: 2192832
145
+ };
146
+ /** Mars. A sidereal day of 24 h 37 min, which is why its "areostationary" orbit is a nice exercise. */
147
+ const MARS = {
148
+ name: "Mars",
149
+ mass: 64171e19,
150
+ radius: 3389500,
151
+ mu: 4282837e7,
152
+ rotationPeriodS: 88642.66
153
+ };
154
+ /** Jupiter. Ten hours to turn once, and 318 Earth masses. */
155
+ const JUPITER = {
156
+ name: "Jupiter",
157
+ mass: 18982e23,
158
+ radius: 69911e3,
159
+ mu: 0x1c214bb40e53c00,
160
+ rotationPeriodS: 35730
161
+ };
162
+ /** Mean Earth-Moon centre separation, m. The distance the null-point questions are set at. */
163
+ const EARTH_MOON_DISTANCE = 3844e5;
164
+ /** Mean Earth-Sun separation, m. One astronomical unit. */
165
+ const EARTH_SUN_DISTANCE = 149597870700;
166
+
167
+ //#endregion
168
+ export { EARTH, EARTH_MOON_DISTANCE, EARTH_SUN_DISTANCE, JUPITER, MARS, MOON, SUN, bodyFromDensity, bodyFromMass, bodyFromSurfaceGravity, bodyVolume, meanDensity, surfaceGravity, surfaceGravityFromDensity, surfaceGravityRatio };