@classytic/labs 0.1.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 (547) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist/biology/enzyme-rate/index.d.mts +1 -0
  4. package/dist/biology/enzyme-rate/preset.d.mts +25 -0
  5. package/dist/biology/enzyme-rate/preset.mjs +256 -0
  6. package/dist/biology/genetic-cross/core.d.mts +64 -0
  7. package/dist/biology/genetic-cross/core.mjs +147 -0
  8. package/dist/biology/genetic-cross/grid.mjs +239 -0
  9. package/dist/biology/genetic-cross/index.d.mts +3 -0
  10. package/dist/biology/genetic-cross/preset.d.mts +26 -0
  11. package/dist/biology/genetic-cross/preset.mjs +184 -0
  12. package/dist/biology/genetic-cross/sex-linked.d.mts +27 -0
  13. package/dist/biology/genetic-cross/sex-linked.mjs +226 -0
  14. package/dist/biology/index.d.mts +11 -0
  15. package/dist/biology/index.mjs +12 -0
  16. package/dist/biology/photosynthesis-factors/index.d.mts +1 -0
  17. package/dist/biology/photosynthesis-factors/preset.d.mts +25 -0
  18. package/dist/biology/photosynthesis-factors/preset.mjs +270 -0
  19. package/dist/biology/punnett-cross/index.d.mts +1 -0
  20. package/dist/biology/punnett-cross/preset.d.mts +27 -0
  21. package/dist/biology/punnett-cross/preset.mjs +21 -0
  22. package/dist/biology/respiration/index.d.mts +1 -0
  23. package/dist/biology/respiration/preset.d.mts +17 -0
  24. package/dist/biology/respiration/preset.mjs +179 -0
  25. package/dist/biology/sequence/central-dogma.d.mts +17 -0
  26. package/dist/biology/sequence/central-dogma.mjs +339 -0
  27. package/dist/biology/sequence/core.d.mts +38 -0
  28. package/dist/biology/sequence/core.mjs +178 -0
  29. package/dist/biology/sequence/index.d.mts +3 -0
  30. package/dist/biology/sequence/preset.d.mts +20 -0
  31. package/dist/biology/sequence/preset.mjs +235 -0
  32. package/dist/blocks/accounting.d.mts +142 -0
  33. package/dist/blocks/accounting.mjs +446 -0
  34. package/dist/blocks/authoring.d.mts +12 -0
  35. package/dist/blocks/authoring.mjs +705 -0
  36. package/dist/blocks/biology.d.mts +197 -0
  37. package/dist/blocks/biology.mjs +513 -0
  38. package/dist/blocks/chem.d.mts +128 -0
  39. package/dist/blocks/chem.mjs +486 -0
  40. package/dist/blocks/circuits.d.mts +86 -0
  41. package/dist/blocks/circuits.mjs +348 -0
  42. package/dist/blocks/discrete.d.mts +62 -0
  43. package/dist/blocks/discrete.mjs +314 -0
  44. package/dist/blocks/economics.d.mts +56 -0
  45. package/dist/blocks/economics.mjs +203 -0
  46. package/dist/blocks/geography.d.mts +58 -0
  47. package/dist/blocks/geography.mjs +115 -0
  48. package/dist/blocks/geometry.d.mts +28 -0
  49. package/dist/blocks/geometry.mjs +160 -0
  50. package/dist/blocks/ict.d.mts +65 -0
  51. package/dist/blocks/ict.mjs +197 -0
  52. package/dist/blocks/index.d.mts +4555 -0
  53. package/dist/blocks/index.mjs +120 -0
  54. package/dist/blocks/lab-block.d.mts +16 -0
  55. package/dist/blocks/lab-block.mjs +74 -0
  56. package/dist/blocks/lab-config.d.mts +23 -0
  57. package/dist/blocks/lab-config.mjs +200 -0
  58. package/dist/blocks/lab-gallery.d.mts +30 -0
  59. package/dist/blocks/lab-gallery.mjs +208 -0
  60. package/dist/blocks/language.d.mts +349 -0
  61. package/dist/blocks/language.mjs +750 -0
  62. package/dist/blocks/lesson.d.mts +43 -0
  63. package/dist/blocks/lesson.mjs +140 -0
  64. package/dist/blocks/math.d.mts +411 -0
  65. package/dist/blocks/math.mjs +1536 -0
  66. package/dist/blocks/ml.d.mts +84 -0
  67. package/dist/blocks/ml.mjs +146 -0
  68. package/dist/blocks/physics.d.mts +259 -0
  69. package/dist/blocks/physics.mjs +868 -0
  70. package/dist/blocks/statistics.d.mts +29 -0
  71. package/dist/blocks/statistics.mjs +123 -0
  72. package/dist/catalog/index.d.mts +3 -0
  73. package/dist/catalog/index.mjs +8 -0
  74. package/dist/catalog/registry.d.mts +46 -0
  75. package/dist/catalog/registry.mjs +56 -0
  76. package/dist/catalog/templates.d.mts +11 -0
  77. package/dist/catalog/templates.mjs +141 -0
  78. package/dist/chem/battery.d.mts +16 -0
  79. package/dist/chem/battery.mjs +311 -0
  80. package/dist/chem/bohr-atom.d.mts +16 -0
  81. package/dist/chem/bohr-atom.mjs +212 -0
  82. package/dist/chem/diffusion/asset.mjs +76 -0
  83. package/dist/chem/diffusion/index.d.mts +1 -0
  84. package/dist/chem/diffusion/preset.d.mts +15 -0
  85. package/dist/chem/diffusion/preset.mjs +188 -0
  86. package/dist/chem/electrochem/index.d.mts +1 -0
  87. package/dist/chem/electrochem/preset.d.mts +23 -0
  88. package/dist/chem/electrochem/preset.mjs +402 -0
  89. package/dist/chem/equilibrium/index.d.mts +1 -0
  90. package/dist/chem/equilibrium/preset.d.mts +36 -0
  91. package/dist/chem/equilibrium/preset.mjs +416 -0
  92. package/dist/chem/gas-box/index.d.mts +1 -0
  93. package/dist/chem/gas-box/preset.d.mts +27 -0
  94. package/dist/chem/gas-box/preset.mjs +395 -0
  95. package/dist/chem/index.d.mts +16 -0
  96. package/dist/chem/index.mjs +17 -0
  97. package/dist/chem/kinetics/index.d.mts +1 -0
  98. package/dist/chem/kinetics/preset.d.mts +31 -0
  99. package/dist/chem/kinetics/preset.mjs +478 -0
  100. package/dist/chem/periodic-trends/index.d.mts +1 -0
  101. package/dist/chem/periodic-trends/preset.d.mts +21 -0
  102. package/dist/chem/periodic-trends/preset.mjs +831 -0
  103. package/dist/chem/reaction-lab.d.mts +18 -0
  104. package/dist/chem/reaction-lab.mjs +165 -0
  105. package/dist/chem/reaction-profile.d.mts +21 -0
  106. package/dist/chem/reaction-profile.mjs +287 -0
  107. package/dist/chem/solution/dilution.d.mts +27 -0
  108. package/dist/chem/solution/dilution.mjs +199 -0
  109. package/dist/chem/solution/field.d.mts +30 -0
  110. package/dist/chem/solution/field.mjs +145 -0
  111. package/dist/chem/solution/index.d.mts +3 -0
  112. package/dist/chem/solution/solution-box.d.mts +28 -0
  113. package/dist/chem/solution/solution-box.mjs +140 -0
  114. package/dist/chem/stoichiometry/index.d.mts +1 -0
  115. package/dist/chem/stoichiometry/preset.d.mts +29 -0
  116. package/dist/chem/stoichiometry/preset.mjs +392 -0
  117. package/dist/chem/titration/index.d.mts +1 -0
  118. package/dist/chem/titration/preset.d.mts +29 -0
  119. package/dist/chem/titration/preset.mjs +436 -0
  120. package/dist/circuits/ac-dc/asset.mjs +295 -0
  121. package/dist/circuits/ac-dc/index.d.mts +1 -0
  122. package/dist/circuits/ac-dc/preset.d.mts +16 -0
  123. package/dist/circuits/ac-dc/preset.mjs +134 -0
  124. package/dist/circuits/capacitor-leak/index.d.mts +1 -0
  125. package/dist/circuits/capacitor-leak/preset.d.mts +32 -0
  126. package/dist/circuits/capacitor-leak/preset.mjs +271 -0
  127. package/dist/circuits/circuit/asset.d.mts +6 -0
  128. package/dist/circuits/circuit/asset.mjs +367 -0
  129. package/dist/circuits/circuit/index.d.mts +2 -0
  130. package/dist/circuits/circuit/preset.d.mts +46 -0
  131. package/dist/circuits/circuit/preset.mjs +235 -0
  132. package/dist/circuits/circuit-builder.d.mts +30 -0
  133. package/dist/circuits/circuit-builder.mjs +412 -0
  134. package/dist/circuits/circuit-lab.d.mts +20 -0
  135. package/dist/circuits/circuit-lab.mjs +400 -0
  136. package/dist/circuits/index.d.mts +7 -0
  137. package/dist/circuits/index.mjs +8 -0
  138. package/dist/commerce/accounting/core.d.mts +48 -0
  139. package/dist/commerce/accounting/core.mjs +57 -0
  140. package/dist/commerce/accounting/equation-balance.d.mts +35 -0
  141. package/dist/commerce/accounting/equation-balance.mjs +292 -0
  142. package/dist/commerce/accounting/index.d.mts +4 -0
  143. package/dist/commerce/accounting/journal-poster.d.mts +29 -0
  144. package/dist/commerce/accounting/journal-poster.mjs +472 -0
  145. package/dist/commerce/accounting/statement-sorter.d.mts +25 -0
  146. package/dist/commerce/accounting/statement-sorter.mjs +304 -0
  147. package/dist/commerce/economics/core.d.mts +33 -0
  148. package/dist/commerce/economics/core.mjs +26 -0
  149. package/dist/commerce/economics/demand-shift-vs-move.d.mts +35 -0
  150. package/dist/commerce/economics/demand-shift-vs-move.mjs +324 -0
  151. package/dist/commerce/economics/elasticity-revenue.d.mts +31 -0
  152. package/dist/commerce/economics/elasticity-revenue.mjs +253 -0
  153. package/dist/commerce/economics/index.d.mts +4 -0
  154. package/dist/commerce/economics/market-equilibrium.d.mts +33 -0
  155. package/dist/commerce/economics/market-equilibrium.mjs +340 -0
  156. package/dist/commerce/index.d.mts +9 -0
  157. package/dist/commerce/index.mjs +10 -0
  158. package/dist/core/easing.d.mts +28 -0
  159. package/dist/core/easing.mjs +66 -0
  160. package/dist/core/index.d.mts +10 -0
  161. package/dist/core/index.mjs +11 -0
  162. package/dist/core/numeric.d.mts +37 -0
  163. package/dist/core/numeric.mjs +75 -0
  164. package/dist/core/reactive.d.mts +24 -0
  165. package/dist/core/reactive.mjs +51 -0
  166. package/dist/core/rng.d.mts +21 -0
  167. package/dist/core/rng.mjs +39 -0
  168. package/dist/core/tex.d.mts +14 -0
  169. package/dist/core/tex.mjs +44 -0
  170. package/dist/core/timeline.d.mts +34 -0
  171. package/dist/core/timeline.mjs +77 -0
  172. package/dist/core/util.d.mts +19 -0
  173. package/dist/core/util.mjs +31 -0
  174. package/dist/discrete/arrangements/preset.d.mts +28 -0
  175. package/dist/discrete/arrangements/preset.mjs +304 -0
  176. package/dist/discrete/bayes/preset.d.mts +33 -0
  177. package/dist/discrete/bayes/preset.mjs +476 -0
  178. package/dist/discrete/binomial/preset.d.mts +25 -0
  179. package/dist/discrete/binomial/preset.mjs +333 -0
  180. package/dist/discrete/core/combinatorics.d.mts +23 -0
  181. package/dist/discrete/core/combinatorics.mjs +57 -0
  182. package/dist/discrete/core/inclusionExclusion.d.mts +19 -0
  183. package/dist/discrete/core/inclusionExclusion.mjs +30 -0
  184. package/dist/discrete/core/pigeonhole.d.mts +15 -0
  185. package/dist/discrete/core/pigeonhole.mjs +24 -0
  186. package/dist/discrete/core/probability.d.mts +29 -0
  187. package/dist/discrete/core/probability.mjs +43 -0
  188. package/dist/discrete/core/sets.d.mts +21 -0
  189. package/dist/discrete/core/sets.mjs +45 -0
  190. package/dist/discrete/counting-slots/preset.d.mts +30 -0
  191. package/dist/discrete/counting-slots/preset.mjs +553 -0
  192. package/dist/discrete/counting-tree/index.d.mts +1 -0
  193. package/dist/discrete/counting-tree/preset.d.mts +44 -0
  194. package/dist/discrete/counting-tree/preset.mjs +364 -0
  195. package/dist/discrete/expected-value/preset.d.mts +28 -0
  196. package/dist/discrete/expected-value/preset.mjs +352 -0
  197. package/dist/discrete/hypergeometric/preset.d.mts +25 -0
  198. package/dist/discrete/hypergeometric/preset.mjs +330 -0
  199. package/dist/discrete/index.d.mts +26 -0
  200. package/dist/discrete/index.mjs +27 -0
  201. package/dist/discrete/karnaugh/index.d.mts +1 -0
  202. package/dist/discrete/karnaugh/preset.d.mts +30 -0
  203. package/dist/discrete/karnaugh/preset.mjs +452 -0
  204. package/dist/discrete/lln/asset.mjs +206 -0
  205. package/dist/discrete/lln/index.d.mts +1 -0
  206. package/dist/discrete/lln/preset.d.mts +17 -0
  207. package/dist/discrete/lln/preset.mjs +152 -0
  208. package/dist/discrete/logic-circuit/index.d.mts +1 -0
  209. package/dist/discrete/logic-circuit/preset.d.mts +47 -0
  210. package/dist/discrete/logic-circuit/preset.mjs +307 -0
  211. package/dist/discrete/monte-carlo/index.d.mts +1 -0
  212. package/dist/discrete/monte-carlo/preset.d.mts +64 -0
  213. package/dist/discrete/monte-carlo/preset.mjs +446 -0
  214. package/dist/discrete/monty-hall/index.d.mts +1 -0
  215. package/dist/discrete/monty-hall/preset.d.mts +23 -0
  216. package/dist/discrete/monty-hall/preset.mjs +491 -0
  217. package/dist/discrete/outcome-builder/preset.d.mts +24 -0
  218. package/dist/discrete/outcome-builder/preset.mjs +283 -0
  219. package/dist/discrete/pascal/preset.d.mts +24 -0
  220. package/dist/discrete/pascal/preset.mjs +372 -0
  221. package/dist/discrete/sample-space/index.d.mts +1 -0
  222. package/dist/discrete/sample-space/preset.d.mts +42 -0
  223. package/dist/discrete/sample-space/preset.mjs +395 -0
  224. package/dist/discrete/selection/preset.d.mts +33 -0
  225. package/dist/discrete/selection/preset.mjs +406 -0
  226. package/dist/discrete/truth-table/index.d.mts +1 -0
  227. package/dist/discrete/truth-table/preset.d.mts +30 -0
  228. package/dist/discrete/truth-table/preset.mjs +456 -0
  229. package/dist/discrete/venn/index.d.mts +1 -0
  230. package/dist/discrete/venn/preset.d.mts +32 -0
  231. package/dist/discrete/venn/preset.mjs +461 -0
  232. package/dist/geography/cycle-lab/index.d.mts +1 -0
  233. package/dist/geography/cycle-lab/preset.d.mts +25 -0
  234. package/dist/geography/cycle-lab/preset.mjs +254 -0
  235. package/dist/geography/cycles.d.mts +21 -0
  236. package/dist/geography/cycles.mjs +205 -0
  237. package/dist/geography/index.d.mts +4 -0
  238. package/dist/geography/index.mjs +5 -0
  239. package/dist/geometry/board/index.d.mts +1 -0
  240. package/dist/geometry/board/preset.d.mts +71 -0
  241. package/dist/geometry/board/preset.mjs +148 -0
  242. package/dist/geometry/builder.d.mts +18 -0
  243. package/dist/geometry/builder.mjs +332 -0
  244. package/dist/geometry/index.d.mts +4 -0
  245. package/dist/geometry/index.mjs +5 -0
  246. package/dist/geometry/intersecting-circles.d.mts +17 -0
  247. package/dist/geometry/intersecting-circles.mjs +104 -0
  248. package/dist/ict/index.d.mts +5 -0
  249. package/dist/ict/index.mjs +6 -0
  250. package/dist/ict/number-systems/base-odometer.d.mts +34 -0
  251. package/dist/ict/number-systems/base-odometer.mjs +160 -0
  252. package/dist/ict/number-systems/bit-grouper.d.mts +32 -0
  253. package/dist/ict/number-systems/bit-grouper.mjs +190 -0
  254. package/dist/ict/number-systems/index.d.mts +4 -0
  255. package/dist/ict/number-systems/place-value-dial.d.mts +29 -0
  256. package/dist/ict/number-systems/place-value-dial.mjs +153 -0
  257. package/dist/ict/number-systems/wheel.d.mts +73 -0
  258. package/dist/ict/number-systems/wheel.mjs +279 -0
  259. package/dist/index.d.mts +10 -0
  260. package/dist/index.mjs +11 -0
  261. package/dist/kit/anim.mjs +52 -0
  262. package/dist/kit/annotate.mjs +116 -0
  263. package/dist/kit/answer-check.d.mts +38 -0
  264. package/dist/kit/answer-check.mjs +65 -0
  265. package/dist/kit/asset-util.mjs +15 -0
  266. package/dist/kit/controls.mjs +77 -0
  267. package/dist/kit/cycle.d.mts +44 -0
  268. package/dist/kit/cycle.mjs +188 -0
  269. package/dist/kit/diagram.mjs +176 -0
  270. package/dist/kit/electronics.mjs +357 -0
  271. package/dist/kit/expr-analysis.d.mts +37 -0
  272. package/dist/kit/expr-analysis.mjs +111 -0
  273. package/dist/kit/frame.d.mts +70 -0
  274. package/dist/kit/frame.mjs +205 -0
  275. package/dist/kit/freq-tree.mjs +99 -0
  276. package/dist/kit/gameshow.mjs +315 -0
  277. package/dist/kit/index.d.mts +5 -0
  278. package/dist/kit/index.mjs +6 -0
  279. package/dist/kit/logic-gates.d.mts +6 -0
  280. package/dist/kit/logic-gates.mjs +210 -0
  281. package/dist/kit/molecules.mjs +178 -0
  282. package/dist/kit/pedagogy.d.mts +126 -0
  283. package/dist/kit/pedagogy.mjs +331 -0
  284. package/dist/kit/play.d.mts +21 -0
  285. package/dist/kit/play.mjs +52 -0
  286. package/dist/kit/probability.mjs +141 -0
  287. package/dist/kit/proportion.mjs +112 -0
  288. package/dist/kit/reaction.mjs +102 -0
  289. package/dist/kit/rich.d.mts +10 -0
  290. package/dist/kit/rich.mjs +21 -0
  291. package/dist/kit/scale.mjs +230 -0
  292. package/dist/kit/space.mjs +326 -0
  293. package/dist/kit/steps.d.mts +24 -0
  294. package/dist/kit/steps.mjs +57 -0
  295. package/dist/kit/thermal.mjs +289 -0
  296. package/dist/language/agreement/index.d.mts +1 -0
  297. package/dist/language/agreement/preset.d.mts +27 -0
  298. package/dist/language/agreement/preset.mjs +113 -0
  299. package/dist/language/article-lens/index.d.mts +1 -0
  300. package/dist/language/article-lens/preset.d.mts +31 -0
  301. package/dist/language/article-lens/preset.mjs +125 -0
  302. package/dist/language/deck.d.mts +45 -0
  303. package/dist/language/deck.mjs +61 -0
  304. package/dist/language/icon.d.mts +40 -0
  305. package/dist/language/icon.mjs +73 -0
  306. package/dist/language/index.d.mts +10 -0
  307. package/dist/language/index.mjs +11 -0
  308. package/dist/language/preposition-scene/index.d.mts +1 -0
  309. package/dist/language/preposition-scene/preset.d.mts +34 -0
  310. package/dist/language/preposition-scene/preset.mjs +234 -0
  311. package/dist/language/sentence-builder/index.d.mts +1 -0
  312. package/dist/language/sentence-builder/preset.d.mts +32 -0
  313. package/dist/language/sentence-builder/preset.mjs +122 -0
  314. package/dist/language/transform/index.d.mts +1 -0
  315. package/dist/language/transform/preset.d.mts +31 -0
  316. package/dist/language/transform/preset.mjs +137 -0
  317. package/dist/language/ui.d.mts +53 -0
  318. package/dist/language/ui.mjs +88 -0
  319. package/dist/language/word-match/index.d.mts +1 -0
  320. package/dist/language/word-match/preset.d.mts +22 -0
  321. package/dist/language/word-match/preset.mjs +148 -0
  322. package/dist/math/area-model/asset.d.mts +6 -0
  323. package/dist/math/area-model/asset.mjs +270 -0
  324. package/dist/math/area-model/index.d.mts +2 -0
  325. package/dist/math/area-model/preset.d.mts +29 -0
  326. package/dist/math/area-model/preset.mjs +243 -0
  327. package/dist/math/balance-algebra/asset.d.mts +6 -0
  328. package/dist/math/balance-algebra/asset.mjs +150 -0
  329. package/dist/math/balance-algebra/index.d.mts +2 -0
  330. package/dist/math/balance-algebra/preset.d.mts +30 -0
  331. package/dist/math/balance-algebra/preset.mjs +228 -0
  332. package/dist/math/derivation.d.mts +22 -0
  333. package/dist/math/derivation.mjs +113 -0
  334. package/dist/math/derivative-explorer/index.d.mts +1 -0
  335. package/dist/math/derivative-explorer/preset.d.mts +19 -0
  336. package/dist/math/derivative-explorer/preset.mjs +227 -0
  337. package/dist/math/function-machine/index.d.mts +1 -0
  338. package/dist/math/function-machine/preset.d.mts +21 -0
  339. package/dist/math/function-machine/preset.mjs +177 -0
  340. package/dist/math/gradient-descent.d.mts +23 -0
  341. package/dist/math/gradient-descent.mjs +473 -0
  342. package/dist/math/grapher/index.d.mts +1 -0
  343. package/dist/math/grapher/preset.d.mts +40 -0
  344. package/dist/math/grapher/preset.mjs +313 -0
  345. package/dist/math/harmonic-form/index.d.mts +1 -0
  346. package/dist/math/harmonic-form/preset.d.mts +21 -0
  347. package/dist/math/harmonic-form/preset.mjs +387 -0
  348. package/dist/math/index.d.mts +25 -0
  349. package/dist/math/index.mjs +26 -0
  350. package/dist/math/integral-explorer/index.d.mts +1 -0
  351. package/dist/math/integral-explorer/preset.d.mts +23 -0
  352. package/dist/math/integral-explorer/preset.mjs +217 -0
  353. package/dist/math/interactive/index.d.mts +1 -0
  354. package/dist/math/interactive/preset.d.mts +72 -0
  355. package/dist/math/interactive/preset.mjs +202 -0
  356. package/dist/math/limit-explorer/index.d.mts +1 -0
  357. package/dist/math/limit-explorer/preset.d.mts +19 -0
  358. package/dist/math/limit-explorer/preset.mjs +216 -0
  359. package/dist/math/linear-system/index.d.mts +1 -0
  360. package/dist/math/linear-system/preset.d.mts +28 -0
  361. package/dist/math/linear-system/preset.mjs +164 -0
  362. package/dist/math/mystery-bucket/asset.d.mts +6 -0
  363. package/dist/math/mystery-bucket/asset.mjs +145 -0
  364. package/dist/math/mystery-bucket/index.d.mts +2 -0
  365. package/dist/math/mystery-bucket/preset.d.mts +36 -0
  366. package/dist/math/mystery-bucket/preset.mjs +116 -0
  367. package/dist/math/number-line/index.d.mts +1 -0
  368. package/dist/math/number-line/preset.d.mts +24 -0
  369. package/dist/math/number-line/preset.mjs +142 -0
  370. package/dist/math/parabola/index.d.mts +1 -0
  371. package/dist/math/parabola/preset.d.mts +13 -0
  372. package/dist/math/parabola/preset.mjs +79 -0
  373. package/dist/math/pattern/asset.d.mts +6 -0
  374. package/dist/math/pattern/asset.mjs +102 -0
  375. package/dist/math/pattern/index.d.mts +2 -0
  376. package/dist/math/pattern/preset.d.mts +32 -0
  377. package/dist/math/pattern/preset.mjs +294 -0
  378. package/dist/math/triangle-trig/index.d.mts +1 -0
  379. package/dist/math/triangle-trig/preset.d.mts +47 -0
  380. package/dist/math/triangle-trig/preset.mjs +245 -0
  381. package/dist/math/trig-explorer.d.mts +18 -0
  382. package/dist/math/trig-explorer.mjs +209 -0
  383. package/dist/ml/boundary/index.d.mts +1 -0
  384. package/dist/ml/boundary/preset.d.mts +24 -0
  385. package/dist/ml/boundary/preset.mjs +385 -0
  386. package/dist/ml/classifier/index.d.mts +1 -0
  387. package/dist/ml/classifier/preset.d.mts +25 -0
  388. package/dist/ml/classifier/preset.mjs +315 -0
  389. package/dist/ml/index.d.mts +6 -0
  390. package/dist/ml/index.mjs +7 -0
  391. package/dist/ml/kmeans/index.d.mts +1 -0
  392. package/dist/ml/kmeans/preset.d.mts +33 -0
  393. package/dist/ml/kmeans/preset.mjs +236 -0
  394. package/dist/ml/knn/index.d.mts +1 -0
  395. package/dist/ml/knn/preset.d.mts +28 -0
  396. package/dist/ml/knn/preset.mjs +279 -0
  397. package/dist/ml/regression/index.d.mts +1 -0
  398. package/dist/ml/regression/preset.d.mts +32 -0
  399. package/dist/ml/regression/preset.mjs +394 -0
  400. package/dist/physics/atwood/index.d.mts +1 -0
  401. package/dist/physics/atwood/preset.d.mts +23 -0
  402. package/dist/physics/atwood/preset.mjs +312 -0
  403. package/dist/physics/bullet-walls/index.d.mts +1 -0
  404. package/dist/physics/bullet-walls/preset.d.mts +28 -0
  405. package/dist/physics/bullet-walls/preset.mjs +373 -0
  406. package/dist/physics/carnot/index.d.mts +1 -0
  407. package/dist/physics/carnot/preset.d.mts +27 -0
  408. package/dist/physics/carnot/preset.mjs +427 -0
  409. package/dist/physics/circular-motion/index.d.mts +1 -0
  410. package/dist/physics/circular-motion/preset.d.mts +25 -0
  411. package/dist/physics/circular-motion/preset.mjs +293 -0
  412. package/dist/physics/collision-track/index.d.mts +1 -0
  413. package/dist/physics/collision-track/preset.d.mts +27 -0
  414. package/dist/physics/collision-track/preset.mjs +352 -0
  415. package/dist/physics/efficiency/index.d.mts +1 -0
  416. package/dist/physics/efficiency/preset.d.mts +33 -0
  417. package/dist/physics/efficiency/preset.mjs +343 -0
  418. package/dist/physics/electric-field/index.d.mts +1 -0
  419. package/dist/physics/electric-field/preset.d.mts +15 -0
  420. package/dist/physics/electric-field/preset.mjs +306 -0
  421. package/dist/physics/energy-skate/index.d.mts +1 -0
  422. package/dist/physics/energy-skate/preset.d.mts +25 -0
  423. package/dist/physics/energy-skate/preset.mjs +254 -0
  424. package/dist/physics/entropy/index.d.mts +1 -0
  425. package/dist/physics/entropy/preset.d.mts +18 -0
  426. package/dist/physics/entropy/preset.mjs +416 -0
  427. package/dist/physics/expansion/index.d.mts +1 -0
  428. package/dist/physics/expansion/preset.d.mts +26 -0
  429. package/dist/physics/expansion/preset.mjs +609 -0
  430. package/dist/physics/exponential/asset.mjs +221 -0
  431. package/dist/physics/exponential/index.d.mts +1 -0
  432. package/dist/physics/exponential/preset.d.mts +17 -0
  433. package/dist/physics/exponential/preset.mjs +182 -0
  434. package/dist/physics/gas-process/index.d.mts +1 -0
  435. package/dist/physics/gas-process/preset.d.mts +30 -0
  436. package/dist/physics/gas-process/preset.mjs +384 -0
  437. package/dist/physics/gravitation/index.d.mts +1 -0
  438. package/dist/physics/gravitation/preset.d.mts +24 -0
  439. package/dist/physics/gravitation/preset.mjs +345 -0
  440. package/dist/physics/gravity-drop.d.mts +9 -0
  441. package/dist/physics/gravity-drop.mjs +187 -0
  442. package/dist/physics/heat-transfer/index.d.mts +1 -0
  443. package/dist/physics/heat-transfer/preset.d.mts +27 -0
  444. package/dist/physics/heat-transfer/preset.mjs +626 -0
  445. package/dist/physics/impulse/index.d.mts +1 -0
  446. package/dist/physics/impulse/preset.d.mts +29 -0
  447. package/dist/physics/impulse/preset.mjs +453 -0
  448. package/dist/physics/index.d.mts +43 -0
  449. package/dist/physics/index.mjs +44 -0
  450. package/dist/physics/kepler/index.d.mts +1 -0
  451. package/dist/physics/kepler/preset.d.mts +27 -0
  452. package/dist/physics/kepler/preset.mjs +257 -0
  453. package/dist/physics/lever/asset.d.mts +6 -0
  454. package/dist/physics/lever/asset.mjs +220 -0
  455. package/dist/physics/lever/index.d.mts +2 -0
  456. package/dist/physics/lever/preset.d.mts +31 -0
  457. package/dist/physics/lever/preset.mjs +261 -0
  458. package/dist/physics/lorentz/index.d.mts +1 -0
  459. package/dist/physics/lorentz/preset.d.mts +29 -0
  460. package/dist/physics/lorentz/preset.mjs +367 -0
  461. package/dist/physics/magnetism/index.d.mts +1 -0
  462. package/dist/physics/magnetism/preset.d.mts +15 -0
  463. package/dist/physics/magnetism/preset.mjs +334 -0
  464. package/dist/physics/optics/asset.d.mts +6 -0
  465. package/dist/physics/optics/asset.mjs +234 -0
  466. package/dist/physics/optics/index.d.mts +2 -0
  467. package/dist/physics/optics/preset.d.mts +14 -0
  468. package/dist/physics/optics/preset.mjs +202 -0
  469. package/dist/physics/orbit-lab.d.mts +6 -0
  470. package/dist/physics/orbit-lab.mjs +222 -0
  471. package/dist/physics/projectile-lab.d.mts +10 -0
  472. package/dist/physics/projectile-lab.mjs +354 -0
  473. package/dist/physics/rain-relative/index.d.mts +1 -0
  474. package/dist/physics/rain-relative/preset.d.mts +19 -0
  475. package/dist/physics/rain-relative/preset.mjs +358 -0
  476. package/dist/physics/ramp-forces/index.d.mts +1 -0
  477. package/dist/physics/ramp-forces/preset.d.mts +36 -0
  478. package/dist/physics/ramp-forces/preset.mjs +550 -0
  479. package/dist/physics/river-boat.d.mts +22 -0
  480. package/dist/physics/river-boat.mjs +498 -0
  481. package/dist/physics/shm/index.d.mts +1 -0
  482. package/dist/physics/shm/preset.d.mts +33 -0
  483. package/dist/physics/shm/preset.mjs +554 -0
  484. package/dist/physics/stopping-distance/index.d.mts +1 -0
  485. package/dist/physics/stopping-distance/preset.d.mts +29 -0
  486. package/dist/physics/stopping-distance/preset.mjs +662 -0
  487. package/dist/physics/temperature-scales/index.d.mts +1 -0
  488. package/dist/physics/temperature-scales/preset.d.mts +15 -0
  489. package/dist/physics/temperature-scales/preset.mjs +353 -0
  490. package/dist/physics/terminal-velocity/index.d.mts +1 -0
  491. package/dist/physics/terminal-velocity/preset.d.mts +26 -0
  492. package/dist/physics/terminal-velocity/preset.mjs +404 -0
  493. package/dist/physics/thermal/index.d.mts +1 -0
  494. package/dist/physics/thermal/preset.d.mts +44 -0
  495. package/dist/physics/thermal/preset.mjs +373 -0
  496. package/dist/physics/vector-board/index.d.mts +1 -0
  497. package/dist/physics/vector-board/preset.d.mts +65 -0
  498. package/dist/physics/vector-board/preset.mjs +273 -0
  499. package/dist/physics/vector-board/view.d.mts +49 -0
  500. package/dist/physics/vector-board/view.mjs +58 -0
  501. package/dist/physics/vector-scene.d.mts +41 -0
  502. package/dist/physics/vector-scene.mjs +211 -0
  503. package/dist/physics/vector-types/index.d.mts +1 -0
  504. package/dist/physics/vector-types/preset.d.mts +27 -0
  505. package/dist/physics/vector-types/preset.mjs +192 -0
  506. package/dist/physics/water-density/index.d.mts +1 -0
  507. package/dist/physics/water-density/preset.d.mts +18 -0
  508. package/dist/physics/water-density/preset.mjs +439 -0
  509. package/dist/physics/waves/core.mjs +33 -0
  510. package/dist/physics/waves/doppler.d.mts +23 -0
  511. package/dist/physics/waves/doppler.mjs +260 -0
  512. package/dist/physics/waves/index.d.mts +4 -0
  513. package/dist/physics/waves/preset.d.mts +30 -0
  514. package/dist/physics/waves/preset.mjs +488 -0
  515. package/dist/physics/waves/ripple.d.mts +26 -0
  516. package/dist/physics/waves/ripple.mjs +234 -0
  517. package/dist/physics/waves/string.d.mts +29 -0
  518. package/dist/physics/waves/string.mjs +289 -0
  519. package/dist/physics/work-energy/index.d.mts +1 -0
  520. package/dist/physics/work-energy/preset.d.mts +17 -0
  521. package/dist/physics/work-energy/preset.mjs +341 -0
  522. package/dist/schemas/index.d.mts +235 -0
  523. package/dist/schemas/index.mjs +145 -0
  524. package/dist/statistics/center-spread/preset.d.mts +34 -0
  525. package/dist/statistics/center-spread/preset.mjs +323 -0
  526. package/dist/statistics/core/descriptive.d.mts +35 -0
  527. package/dist/statistics/core/descriptive.mjs +64 -0
  528. package/dist/statistics/core/normal.d.mts +21 -0
  529. package/dist/statistics/core/normal.mjs +37 -0
  530. package/dist/statistics/core/sequences.d.mts +27 -0
  531. package/dist/statistics/core/sequences.mjs +35 -0
  532. package/dist/statistics/galton/preset.d.mts +27 -0
  533. package/dist/statistics/galton/preset.mjs +331 -0
  534. package/dist/statistics/histogram/preset.d.mts +27 -0
  535. package/dist/statistics/histogram/preset.mjs +385 -0
  536. package/dist/statistics/index.d.mts +11 -0
  537. package/dist/statistics/index.mjs +12 -0
  538. package/dist/statistics/normal/preset.d.mts +30 -0
  539. package/dist/statistics/normal/preset.mjs +400 -0
  540. package/dist/statistics/sampling/preset.d.mts +32 -0
  541. package/dist/statistics/sampling/preset.mjs +406 -0
  542. package/dist/statistics/sequence/preset.d.mts +28 -0
  543. package/dist/statistics/sequence/preset.mjs +302 -0
  544. package/dist/statistics/z-table/preset.d.mts +28 -0
  545. package/dist/statistics/z-table/preset.mjs +348 -0
  546. package/package.json +266 -0
  547. package/styles.css +267 -0
@@ -0,0 +1,192 @@
1
+ 'use client';
2
+
3
+ import { LabFrame } from "../../kit/frame.mjs";
4
+ import { Fragment } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Dot, Label, Stage, Vector } from "@classytic/stage";
7
+
8
+ //#region src/physics/vector-types/preset.tsx
9
+ /**
10
+ * VectorTypes — a labeled reference figure for the vectors chapter opener:
11
+ * equal, negative, null, unit, parallel, position. These are DEFINITIONAL
12
+ * (no manipulation builds intuition here), so per the engine's video-vs-
13
+ * interactive rule it's a clean figure, not a puzzle. Data-driven: a creator
14
+ * can pass their own panels; the default is the standard CAIE/IGCSE set.
15
+ *
16
+ * Reuses @classytic/stage `Vector`/`Dot`/`Label` — one mini <Stage> per panel.
17
+ */
18
+ const A = "var(--stage-accent)";
19
+ const A2 = "var(--stage-accent-2)";
20
+ const DEFAULT_TYPES = [
21
+ {
22
+ name: "Equal",
23
+ caption: "Same magnitude AND direction.",
24
+ vectors: [{
25
+ tail: {
26
+ x: -1.4,
27
+ y: .7
28
+ },
29
+ comp: {
30
+ x: 2,
31
+ y: 0
32
+ },
33
+ color: A
34
+ }, {
35
+ tail: {
36
+ x: -1.4,
37
+ y: -.8
38
+ },
39
+ comp: {
40
+ x: 2,
41
+ y: 0
42
+ },
43
+ color: A
44
+ }]
45
+ },
46
+ {
47
+ name: "Negative (−a)",
48
+ caption: "Same magnitude, opposite direction.",
49
+ vectors: [{
50
+ tail: {
51
+ x: -1.2,
52
+ y: .6
53
+ },
54
+ comp: {
55
+ x: 2,
56
+ y: 0
57
+ },
58
+ color: A,
59
+ label: "a"
60
+ }, {
61
+ tail: {
62
+ x: 1.2,
63
+ y: -.7
64
+ },
65
+ comp: {
66
+ x: -2,
67
+ y: 0
68
+ },
69
+ color: A2,
70
+ label: "−a"
71
+ }]
72
+ },
73
+ {
74
+ name: "Null (0)",
75
+ caption: "Zero magnitude, no direction.",
76
+ origin: true
77
+ },
78
+ {
79
+ name: "Unit (â)",
80
+ caption: "Magnitude 1 — direction only.",
81
+ vectors: [{
82
+ comp: {
83
+ x: 1,
84
+ y: 0
85
+ },
86
+ color: "var(--stage-good)",
87
+ label: "â"
88
+ }],
89
+ origin: true
90
+ },
91
+ {
92
+ name: "Parallel",
93
+ caption: "Same direction, any magnitude.",
94
+ vectors: [{
95
+ tail: {
96
+ x: -1.4,
97
+ y: .7
98
+ },
99
+ comp: {
100
+ x: 1.2,
101
+ y: 0
102
+ },
103
+ color: A
104
+ }, {
105
+ tail: {
106
+ x: -1.4,
107
+ y: -.8
108
+ },
109
+ comp: {
110
+ x: 2.6,
111
+ y: 0
112
+ },
113
+ color: A
114
+ }]
115
+ },
116
+ {
117
+ name: "Position (r)",
118
+ caption: "From a fixed origin O to a point.",
119
+ vectors: [{
120
+ comp: {
121
+ x: 1.5,
122
+ y: 1.1
123
+ },
124
+ color: A2,
125
+ label: "r"
126
+ }],
127
+ origin: true
128
+ }
129
+ ];
130
+ function Panel({ p }) {
131
+ return /* @__PURE__ */ jsxs("div", {
132
+ className: "lang-typecard",
133
+ children: [
134
+ /* @__PURE__ */ jsxs(Stage, {
135
+ view: {
136
+ xMin: -2,
137
+ xMax: 2,
138
+ yMin: -1.6,
139
+ yMax: 1.6
140
+ },
141
+ height: 110,
142
+ preserveAspect: true,
143
+ ariaLabel: `${p.name}: ${p.caption}`,
144
+ children: [p.origin && /* @__PURE__ */ jsx(Dot, {
145
+ x: 0,
146
+ y: 0,
147
+ r: 4,
148
+ color: "var(--stage-muted)"
149
+ }), (p.vectors ?? []).map((v, i) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Vector, {
150
+ tail: v.tail ?? {
151
+ x: 0,
152
+ y: 0
153
+ },
154
+ tip: {
155
+ x: (v.tail?.x ?? 0) + v.comp.x,
156
+ y: (v.tail?.y ?? 0) + v.comp.y
157
+ },
158
+ color: v.color ?? A,
159
+ weight: 3
160
+ }), v.label && /* @__PURE__ */ jsx(Label, {
161
+ x: (v.tail?.x ?? 0) + v.comp.x,
162
+ y: (v.tail?.y ?? 0) + v.comp.y,
163
+ text: v.label,
164
+ color: v.color ?? A,
165
+ dx: 8,
166
+ dy: -6,
167
+ size: 13
168
+ })] }, i))]
169
+ }),
170
+ /* @__PURE__ */ jsx("p", {
171
+ className: "lang-typename",
172
+ children: p.name
173
+ }),
174
+ /* @__PURE__ */ jsx("p", {
175
+ className: "lang-typecap",
176
+ children: p.caption
177
+ })
178
+ ]
179
+ });
180
+ }
181
+ function VectorTypesLab({ types = DEFAULT_TYPES, title = "Types of vectors" }) {
182
+ return /* @__PURE__ */ jsx(LabFrame, {
183
+ title,
184
+ children: /* @__PURE__ */ jsx("div", {
185
+ className: "lang-typegrid",
186
+ children: types.map((p, i) => /* @__PURE__ */ jsx(Panel, { p }, i))
187
+ })
188
+ });
189
+ }
190
+
191
+ //#endregion
192
+ export { VectorTypesLab };
@@ -0,0 +1 @@
1
+ import { WaterDensityLab, WaterDensityProps } from "./preset.mjs";
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/physics/water-density/preset.d.ts
4
+ type Mode = 'anomaly' | 'lake';
5
+ interface WaterDensityProps {
6
+ mode?: Mode;
7
+ title?: string;
8
+ prompt?: string;
9
+ objectives?: string[];
10
+ }
11
+ declare function WaterDensityLab({
12
+ mode: mode0,
13
+ title,
14
+ prompt,
15
+ objectives
16
+ }?: WaterDensityProps): ReactNode;
17
+ //#endregion
18
+ export { WaterDensityLab, WaterDensityProps };
@@ -0,0 +1,439 @@
1
+ 'use client';
2
+
3
+ import { Chip, Slider } from "../../kit/controls.mjs";
4
+ import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
5
+ import { thermalColor } from "../../kit/thermal.mjs";
6
+ import { useState } from "react";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
+
9
+ //#region src/physics/water-density/preset.tsx
10
+ /**
11
+ * WaterDensityLab — water's strange, life-saving anomaly. Almost everything gets
12
+ * denser as it cools, but water is DENSEST at about 4 °C; cool it further toward 0
13
+ * and it expands again, and ice is less dense still — so ice floats.
14
+ *
15
+ * • THE 4 °C ANOMALY — a density–temperature curve that peaks at 4 °C (zoomed in,
16
+ * because the bump is tiny). Drag the temperature and watch the density rise to
17
+ * a maximum at 4 °C, then fall.
18
+ * • WHY LAKES FREEZE TOP-DOWN — a lake cross-section: the densest 4 °C water sinks
19
+ * to the bottom, colder water sits above it, and ice forms on the surface. The
20
+ * ice blanket insulates the liquid water below, so fish survive the winter.
21
+ *
22
+ * If water behaved "normally", lakes would freeze solid from the bottom up and kill
23
+ * everything in them. Interactive, no simulation loop. Pure SVG, themed.
24
+ */
25
+ const W = 640, H = 360;
26
+ const SAMPLES = [
27
+ [0, 999.84],
28
+ [1, 999.9],
29
+ [2, 999.94],
30
+ [3, 999.96],
31
+ [4, 999.97],
32
+ [5, 999.96],
33
+ [6, 999.94],
34
+ [8, 999.85],
35
+ [10, 999.7],
36
+ [15, 999.1],
37
+ [20, 998.2],
38
+ [25, 997.05]
39
+ ];
40
+ const ICE_RHO = 916.7;
41
+ const T_MAX = 25, RHO_LO = 997, RHO_HI = 1000.15;
42
+ function densityOf(t) {
43
+ const tc = Math.max(0, Math.min(T_MAX, t));
44
+ for (let i = 0; i < SAMPLES.length - 1; i++) {
45
+ const [t0, r0] = SAMPLES[i], [t1, r1] = SAMPLES[i + 1];
46
+ if (tc <= t1) return r0 + (r1 - r0) * ((tc - t0) / (t1 - t0));
47
+ }
48
+ return SAMPLES[SAMPLES.length - 1][1];
49
+ }
50
+ function WaterDensityLab({ mode: mode0 = "anomaly", title = "Water’s 4 °C anomaly — why ice floats", prompt = "Almost everything shrinks as it cools, but water is densest at 4 °C and expands again toward freezing — so ice floats and lakes freeze from the top down.", objectives = [
51
+ "See water reach maximum density at about 4 °C (not at 0 °C)",
52
+ "Explain why ice floats — it is LESS dense than liquid water",
53
+ "Explain why a lake freezes top-down, leaving 4 °C water (and fish) below"
54
+ ] } = {}) {
55
+ const [mode, setMode] = useState(mode0);
56
+ const [tC, setTC] = useState(12);
57
+ const GX0 = 70, GX1 = 600, GY0 = 40, GY1 = 300;
58
+ const PX = (t) => GX0 + t / T_MAX * (GX1 - GX0);
59
+ const PY = (r) => GY1 - (r - RHO_LO) / (RHO_HI - RHO_LO) * (GY1 - GY0);
60
+ const rho = densityOf(tC);
61
+ let figure;
62
+ if (mode === "anomaly") {
63
+ const curve = SAMPLES.map(([t, r]) => `${PX(t).toFixed(1)},${PY(r).toFixed(1)}`).join(" ");
64
+ figure = /* @__PURE__ */ jsx("div", {
65
+ style: fwrap,
66
+ children: /* @__PURE__ */ jsxs("svg", {
67
+ viewBox: `0 0 ${W} ${H}`,
68
+ width: "100%",
69
+ role: "img",
70
+ "aria-label": `Water density ${rho.toFixed(2)} kilograms per cubic metre at ${tC} degrees`,
71
+ children: [
72
+ /* @__PURE__ */ jsx("line", {
73
+ x1: GX0,
74
+ y1: GY0,
75
+ x2: GX0,
76
+ y2: GY1,
77
+ stroke: "var(--stage-fg)",
78
+ strokeWidth: 1.5
79
+ }),
80
+ /* @__PURE__ */ jsx("line", {
81
+ x1: GX0,
82
+ y1: GY1,
83
+ x2: GX1,
84
+ y2: GY1,
85
+ stroke: "var(--stage-fg)",
86
+ strokeWidth: 1.5
87
+ }),
88
+ /* @__PURE__ */ jsx("text", {
89
+ x: GX0 - 6,
90
+ y: 42,
91
+ textAnchor: "end",
92
+ fontSize: 10,
93
+ fill: "var(--stage-muted)",
94
+ children: "ρ (kg/m³)"
95
+ }),
96
+ /* @__PURE__ */ jsx("text", {
97
+ x: 670 / 2,
98
+ y: 332,
99
+ textAnchor: "middle",
100
+ fontSize: 10,
101
+ fill: "var(--stage-muted)",
102
+ children: "temperature (°C) →"
103
+ }),
104
+ [
105
+ 0,
106
+ 4,
107
+ 10,
108
+ 15,
109
+ 20,
110
+ 25
111
+ ].map((t) => /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("line", {
112
+ x1: PX(t),
113
+ y1: GY1,
114
+ x2: PX(t),
115
+ y2: 304,
116
+ stroke: "var(--stage-muted)",
117
+ strokeWidth: 1
118
+ }), /* @__PURE__ */ jsx("text", {
119
+ x: PX(t),
120
+ y: 316,
121
+ textAnchor: "middle",
122
+ fontSize: 10,
123
+ fill: "var(--stage-muted)",
124
+ children: t
125
+ })] }, t)),
126
+ /* @__PURE__ */ jsx("line", {
127
+ x1: PX(4),
128
+ y1: GY0,
129
+ x2: PX(4),
130
+ y2: GY1,
131
+ stroke: "var(--stage-good)",
132
+ strokeWidth: 1,
133
+ strokeDasharray: "4 4"
134
+ }),
135
+ /* @__PURE__ */ jsx("text", {
136
+ x: PX(4) + 5,
137
+ y: 52,
138
+ fontSize: 11,
139
+ fontWeight: 700,
140
+ fill: "var(--stage-good)",
141
+ children: "densest at 4 °C"
142
+ }),
143
+ /* @__PURE__ */ jsx("polyline", {
144
+ points: curve,
145
+ fill: "none",
146
+ stroke: "var(--stage-accent)",
147
+ strokeWidth: 3,
148
+ strokeLinejoin: "round",
149
+ strokeLinecap: "round"
150
+ }),
151
+ /* @__PURE__ */ jsx("circle", {
152
+ cx: PX(4),
153
+ cy: PY(999.97),
154
+ r: 5,
155
+ fill: "var(--stage-good)"
156
+ }),
157
+ /* @__PURE__ */ jsx("circle", {
158
+ cx: PX(tC),
159
+ cy: PY(rho),
160
+ r: 6,
161
+ fill: thermalColor(tC / T_MAX),
162
+ stroke: "var(--stage-bg)",
163
+ strokeWidth: 2
164
+ }),
165
+ /* @__PURE__ */ jsx("line", {
166
+ x1: PX(tC),
167
+ y1: PY(rho),
168
+ x2: PX(tC),
169
+ y2: GY1,
170
+ stroke: "var(--stage-muted)",
171
+ strokeWidth: 1,
172
+ strokeDasharray: "3 3",
173
+ opacity: .5
174
+ }),
175
+ /* @__PURE__ */ jsx("text", {
176
+ x: PX(15),
177
+ y: PY(998),
178
+ fontSize: 10,
179
+ fill: "var(--stage-muted)",
180
+ children: "cooling 25→4 °C: denser → sinks"
181
+ }),
182
+ /* @__PURE__ */ jsx("text", {
183
+ x: PX(.4),
184
+ y: PY(999.6),
185
+ fontSize: 10,
186
+ fill: "var(--stage-muted)",
187
+ children: "4→0 °C: lighter → rises"
188
+ })
189
+ ]
190
+ })
191
+ });
192
+ } else {
193
+ const lx = 60, rx = 580, top = 60, bot = 300;
194
+ const iceBot = 94;
195
+ figure = /* @__PURE__ */ jsx("div", {
196
+ style: fwrap,
197
+ children: /* @__PURE__ */ jsxs("svg", {
198
+ viewBox: `0 0 ${W} ${H}`,
199
+ width: "100%",
200
+ role: "img",
201
+ "aria-label": "Lake cross-section freezing from the top down with 4 degree water at the bottom",
202
+ children: [
203
+ /* @__PURE__ */ jsx("rect", {
204
+ x: lx,
205
+ y: top - 30,
206
+ width: rx - lx,
207
+ height: 30,
208
+ fill: "color-mix(in oklab, var(--stage-accent) 8%, var(--stage-bg))"
209
+ }),
210
+ /* @__PURE__ */ jsx("text", {
211
+ x: 68,
212
+ y: top - 12,
213
+ fontSize: 11,
214
+ fill: "var(--stage-muted)",
215
+ children: "cold air ❄"
216
+ }),
217
+ [
218
+ {
219
+ y0: iceBot,
220
+ y1: 150,
221
+ t: 0,
222
+ label: "0 °C — just above freezing"
223
+ },
224
+ {
225
+ y0: 150,
226
+ y1: 210,
227
+ t: 2,
228
+ label: "2 °C"
229
+ },
230
+ {
231
+ y0: 210,
232
+ y1: 270,
233
+ t: 3,
234
+ label: "3 °C"
235
+ },
236
+ {
237
+ y0: 270,
238
+ y1: bot,
239
+ t: 4,
240
+ label: "4 °C — densest water sinks here"
241
+ }
242
+ ].map((b, i) => /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
243
+ x: lx,
244
+ y: b.y0,
245
+ width: rx - lx,
246
+ height: b.y1 - b.y0,
247
+ fill: thermalColor(b.t / T_MAX),
248
+ opacity: .4
249
+ }), /* @__PURE__ */ jsx("text", {
250
+ x: rx - 10,
251
+ y: (b.y0 + b.y1) / 2 + 4,
252
+ textAnchor: "end",
253
+ fontSize: 11,
254
+ fill: "var(--stage-fg)",
255
+ children: b.label
256
+ })] }, i)),
257
+ /* @__PURE__ */ jsx("rect", {
258
+ x: lx,
259
+ y: top,
260
+ width: rx - lx,
261
+ height: iceBot - top,
262
+ fill: "color-mix(in oklab, #cfeaff 75%, var(--stage-bg))",
263
+ stroke: "color-mix(in oklab, #2b7fff 40%, transparent)",
264
+ strokeWidth: 1.5
265
+ }),
266
+ /* @__PURE__ */ jsx("text", {
267
+ x: 70,
268
+ y: 82,
269
+ fontSize: 12,
270
+ fontWeight: 800,
271
+ fill: "#2b6fb8",
272
+ children: "ICE floats (less dense)"
273
+ }),
274
+ [
275
+ [140, 270],
276
+ [250, 282],
277
+ [430, 268]
278
+ ].map(([fx, fy], i) => /* @__PURE__ */ jsxs("g", {
279
+ fill: "var(--stage-fg)",
280
+ opacity: .75,
281
+ children: [
282
+ /* @__PURE__ */ jsx("ellipse", {
283
+ cx: fx,
284
+ cy: fy,
285
+ rx: 12,
286
+ ry: 6
287
+ }),
288
+ /* @__PURE__ */ jsx("polygon", { points: `${fx + 11},${fy} ${fx + 20},${fy - 5} ${fx + 20},${fy + 5}` }),
289
+ /* @__PURE__ */ jsx("circle", {
290
+ cx: fx - 6,
291
+ cy: fy - 1,
292
+ r: 1.4,
293
+ fill: "var(--stage-bg)"
294
+ })
295
+ ]
296
+ }, i)),
297
+ /* @__PURE__ */ jsx("path", {
298
+ d: `M ${lx} ${top} L ${lx} ${bot} L ${rx} ${bot} L ${rx} ${top}`,
299
+ fill: "none",
300
+ stroke: "var(--stage-metal)",
301
+ strokeWidth: 3
302
+ }),
303
+ /* @__PURE__ */ jsx("text", {
304
+ x: 90,
305
+ y: bot - 14,
306
+ fontSize: 16,
307
+ fill: "var(--stage-accent)",
308
+ children: "↓ 4 °C sinks"
309
+ })
310
+ ]
311
+ })
312
+ });
313
+ }
314
+ return /* @__PURE__ */ jsx(LabFrame, {
315
+ title,
316
+ prompt,
317
+ objectives,
318
+ aside: mode === "anomaly" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Callout, {
319
+ tone: "result",
320
+ children: /* @__PURE__ */ jsxs("span", {
321
+ style: {
322
+ fontVariantNumeric: "tabular-nums",
323
+ fontWeight: 800
324
+ },
325
+ children: [
326
+ /* @__PURE__ */ jsxs("span", {
327
+ style: { fontSize: 16 },
328
+ children: [
329
+ "ρ = ",
330
+ rho.toFixed(2),
331
+ " kg/m³"
332
+ ]
333
+ }),
334
+ /* @__PURE__ */ jsx("br", {}),
335
+ "at ",
336
+ tC,
337
+ " °C",
338
+ Math.abs(tC - 4) < .6 ? " — maximum!" : ""
339
+ ]
340
+ })
341
+ }), /* @__PURE__ */ jsxs("div", {
342
+ style: {
343
+ display: "grid",
344
+ gap: 8,
345
+ padding: "8px 2px 0",
346
+ fontSize: 13,
347
+ color: "var(--stage-muted)"
348
+ },
349
+ children: [/* @__PURE__ */ jsxs("span", { children: [
350
+ "As liquid water cools it gets denser — but only down to ",
351
+ /* @__PURE__ */ jsx("strong", {
352
+ style: { color: "var(--stage-fg)" },
353
+ children: "4 °C"
354
+ }),
355
+ ". Cool it further and the molecules begin lining up into the open hexagonal structure of ice, so it ",
356
+ /* @__PURE__ */ jsx("strong", {
357
+ style: { color: "var(--stage-fg)" },
358
+ children: "expands"
359
+ }),
360
+ "."
361
+ ] }), /* @__PURE__ */ jsxs("span", { children: [
362
+ "Ice itself is only ",
363
+ /* @__PURE__ */ jsxs("strong", {
364
+ style: { color: "var(--stage-fg)" },
365
+ children: [ICE_RHO, " kg/m³"]
366
+ }),
367
+ " — much less than water — which is why it floats."
368
+ ] })]
369
+ })] }) : /* @__PURE__ */ jsxs("div", {
370
+ style: {
371
+ display: "grid",
372
+ gap: 8,
373
+ padding: "2px 2px 0",
374
+ fontSize: 13,
375
+ color: "var(--stage-muted)"
376
+ },
377
+ children: [/* @__PURE__ */ jsx(Callout, {
378
+ tone: "info",
379
+ children: /* @__PURE__ */ jsxs("span", { children: [
380
+ "Because the densest water is at ",
381
+ /* @__PURE__ */ jsx("strong", {
382
+ style: { color: "var(--stage-fg)" },
383
+ children: "4 °C"
384
+ }),
385
+ ", it sinks to the bottom. Colder water (0–3 °C) is lighter and stays on top, where it finally freezes into floating ice."
386
+ ] })
387
+ }), /* @__PURE__ */ jsxs("span", { children: [
388
+ "The ice blanket ",
389
+ /* @__PURE__ */ jsx("strong", {
390
+ style: { color: "var(--stage-fg)" },
391
+ children: "insulates"
392
+ }),
393
+ " the water beneath, so the lake never freezes solid — and the fish survive at 4 °C. If water were \"normal\", lakes would freeze bottom-up and kill everything."
394
+ ] })]
395
+ }),
396
+ controls: /* @__PURE__ */ jsxs("div", {
397
+ style: {
398
+ display: "grid",
399
+ gap: 10
400
+ },
401
+ children: [/* @__PURE__ */ jsx(ControlBar, { children: /* @__PURE__ */ jsx(Field, {
402
+ label: "view",
403
+ children: /* @__PURE__ */ jsxs("span", {
404
+ className: "lab-field-row",
405
+ children: [/* @__PURE__ */ jsx(Chip, {
406
+ selected: mode === "anomaly",
407
+ onClick: () => setMode("anomaly"),
408
+ children: "the 4 °C anomaly"
409
+ }), /* @__PURE__ */ jsx(Chip, {
410
+ selected: mode === "lake",
411
+ onClick: () => setMode("lake"),
412
+ children: "why lakes freeze top-down"
413
+ })]
414
+ })
415
+ }) }), mode === "anomaly" && /* @__PURE__ */ jsx(ControlBar, { children: /* @__PURE__ */ jsx(Field, {
416
+ label: "temperature",
417
+ value: `${tC} °C`,
418
+ children: /* @__PURE__ */ jsx(Slider, {
419
+ value: tC,
420
+ min: 0,
421
+ max: 25,
422
+ step: 1,
423
+ onChange: setTC,
424
+ ariaLabel: "water temperature (Celsius)"
425
+ })
426
+ }) })]
427
+ }),
428
+ children: figure
429
+ });
430
+ }
431
+ const fwrap = {
432
+ borderRadius: 14,
433
+ overflow: "hidden",
434
+ background: "var(--stage-bg)",
435
+ border: "1px solid var(--stage-grid)"
436
+ };
437
+
438
+ //#endregion
439
+ export { WaterDensityLab };
@@ -0,0 +1,33 @@
1
+ //#region src/physics/waves/core.ts
2
+ const waveK = (wavelength) => 2 * Math.PI / wavelength;
3
+ const waveOmega = (freq) => 2 * Math.PI * freq;
4
+ const speed = (w) => w.freq * w.wavelength;
5
+ const period = (freq) => freq ? 1 / freq : Infinity;
6
+ /** Displacement of one travelling wave at position x, time t. */
7
+ function waveY(w, x, t) {
8
+ return w.amp * Math.sin(waveK(w.wavelength) * x - waveOmega(w.freq) * t + (w.phase ?? 0));
9
+ }
10
+ /** Superposition: the sum of several waves at (x,t). */
11
+ function sumY(ws, x, t) {
12
+ return ws.reduce((s, w) => s + waveY(w, x, t), 0);
13
+ }
14
+ /** Standing wave on a string of length L, harmonic n: 2A·sin(kx)·cos(ωt). */
15
+ function standingY(amp, L, n, freq, x, t) {
16
+ const k = n * Math.PI / L;
17
+ return 2 * amp * Math.sin(k * x) * Math.cos(waveOmega(freq) * t);
18
+ }
19
+ /** The harmonic wavelength for a string fixed at both ends: λ = 2L/n. */
20
+ const harmonicWavelength = (L, n) => 2 * L / n;
21
+ /** Node positions (displacement always 0) for harmonic n on [0, L]: x = mL/n. */
22
+ function nodes(L, n) {
23
+ return Array.from({ length: n + 1 }, (_, m) => m * L / n);
24
+ }
25
+ /** Antinode positions (max swing) for harmonic n on [0, L]: x = (m+½)L/n. */
26
+ function antinodes(L, n) {
27
+ return Array.from({ length: n }, (_, m) => (m + .5) * L / n);
28
+ }
29
+ /** Beat frequency when two close tones overlap: |f₁ − f₂|. */
30
+ const beatFreq = (f1, f2) => Math.abs(f1 - f2);
31
+
32
+ //#endregion
33
+ export { antinodes, beatFreq, harmonicWavelength, nodes, period, speed, standingY, sumY, waveOmega, waveY };
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/physics/waves/doppler.d.ts
4
+ interface DopplerProps {
5
+ mach?: number;
6
+ title?: string;
7
+ prompt?: string;
8
+ objectives?: string[];
9
+ hints?: string[];
10
+ controlId?: string;
11
+ height?: number;
12
+ }
13
+ declare function DopplerLab({
14
+ mach,
15
+ title,
16
+ prompt,
17
+ objectives,
18
+ hints: hintList,
19
+ controlId,
20
+ height
21
+ }: DopplerProps): ReactNode;
22
+ //#endregion
23
+ export { DopplerLab, DopplerProps };