@classytic/labs 0.1.0 → 0.2.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 (455) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/biology/enzyme-rate/preset.mjs +5 -5
  3. package/dist/biology/genetic-cross/core.d.mts +7 -7
  4. package/dist/biology/genetic-cross/core.mjs +4 -4
  5. package/dist/biology/genetic-cross/grid.mjs +132 -123
  6. package/dist/biology/genetic-cross/preset.mjs +4 -4
  7. package/dist/biology/genetic-cross/sex-linked.mjs +7 -7
  8. package/dist/biology/photosynthesis-factors/preset.mjs +8 -8
  9. package/dist/biology/respiration/preset.mjs +4 -4
  10. package/dist/biology/sequence/central-dogma.mjs +5 -5
  11. package/dist/biology/sequence/core.d.mts +6 -6
  12. package/dist/biology/sequence/core.mjs +1 -1
  13. package/dist/biology/sequence/preset.mjs +6 -6
  14. package/dist/blocks/authoring.mjs +5 -5
  15. package/dist/blocks/biology.d.mts +2 -2
  16. package/dist/blocks/biology.mjs +5 -5
  17. package/dist/blocks/chem.d.mts +2 -2
  18. package/dist/blocks/chem.mjs +13 -13
  19. package/dist/blocks/circuits.d.mts +293 -4
  20. package/dist/blocks/circuits.mjs +874 -9
  21. package/dist/blocks/discrete.d.mts +30 -2
  22. package/dist/blocks/discrete.mjs +74 -4
  23. package/dist/blocks/economics.mjs +1 -1
  24. package/dist/blocks/geography.mjs +1 -1
  25. package/dist/blocks/geometry.mjs +3 -3
  26. package/dist/blocks/ict.d.mts +90 -1
  27. package/dist/blocks/ict.mjs +217 -7
  28. package/dist/blocks/index.d.mts +3064 -657
  29. package/dist/blocks/index.mjs +9 -9
  30. package/dist/blocks/lab-block.mjs +5 -5
  31. package/dist/blocks/lab-config.d.mts +1 -1
  32. package/dist/blocks/lab-config.mjs +4 -4
  33. package/dist/blocks/lab-gallery.d.mts +1 -1
  34. package/dist/blocks/lab-gallery.mjs +2 -2
  35. package/dist/blocks/language.d.mts +6 -6
  36. package/dist/blocks/language.mjs +12 -12
  37. package/dist/blocks/lesson.mjs +4 -4
  38. package/dist/blocks/math.d.mts +577 -11
  39. package/dist/blocks/math.mjs +1648 -14
  40. package/dist/blocks/ml.d.mts +45 -1
  41. package/dist/blocks/ml.mjs +80 -6
  42. package/dist/blocks/physics.d.mts +9 -4
  43. package/dist/blocks/physics.mjs +75 -28
  44. package/dist/blocks/statistics.mjs +1 -1
  45. package/dist/build/CircuitEditor.d.mts +14 -0
  46. package/dist/build/CircuitEditor.mjs +787 -0
  47. package/dist/build/CircuitPlayer.d.mts +19 -0
  48. package/dist/build/CircuitPlayer.mjs +53 -0
  49. package/dist/build/CircuitScene.d.mts +61 -0
  50. package/dist/build/CircuitScene.mjs +383 -0
  51. package/dist/build/contract.d.mts +116 -0
  52. package/dist/build/editor-ops.d.mts +65 -0
  53. package/dist/build/editor-ops.mjs +306 -0
  54. package/dist/build/editor-ui.mjs +121 -0
  55. package/dist/build/flow.d.mts +14 -0
  56. package/dist/build/flow.mjs +119 -0
  57. package/dist/build/index.d.mts +10 -0
  58. package/dist/build/index.mjs +10 -0
  59. package/dist/build/parts/ammeter.d.mts +1 -0
  60. package/dist/build/parts/ammeter.mjs +32 -0
  61. package/dist/build/parts/bulb.d.mts +1 -0
  62. package/dist/build/parts/bulb.mjs +50 -0
  63. package/dist/build/parts/capacitor.d.mts +1 -0
  64. package/dist/build/parts/capacitor.mjs +26 -0
  65. package/dist/build/parts/cell.d.mts +1 -0
  66. package/dist/build/parts/cell.mjs +40 -0
  67. package/dist/build/parts/diode.d.mts +1 -0
  68. package/dist/build/parts/diode.mjs +33 -0
  69. package/dist/build/parts/index.d.mts +5 -0
  70. package/dist/build/parts/index.mjs +43 -0
  71. package/dist/build/parts/mosfet.d.mts +1 -0
  72. package/dist/build/parts/mosfet.mjs +95 -0
  73. package/dist/build/parts/node.d.mts +1 -0
  74. package/dist/build/parts/node.mjs +32 -0
  75. package/dist/build/parts/resistor.d.mts +1 -0
  76. package/dist/build/parts/resistor.mjs +49 -0
  77. package/dist/build/parts/shared.mjs +42 -0
  78. package/dist/build/parts/switch.d.mts +1 -0
  79. package/dist/build/parts/switch.mjs +34 -0
  80. package/dist/build/parts.d.mts +1 -0
  81. package/dist/build/registry.d.mts +9 -0
  82. package/dist/build/registry.mjs +15 -0
  83. package/dist/build/solve.d.mts +8 -0
  84. package/dist/build/solve.mjs +0 -0
  85. package/dist/catalog/registry.d.mts +2 -2
  86. package/dist/catalog/templates.d.mts +1 -1
  87. package/dist/catalog/templates.mjs +6 -6
  88. package/dist/chem/battery.mjs +1 -1
  89. package/dist/chem/bohr-atom.mjs +4 -4
  90. package/dist/chem/diffusion/preset.mjs +4 -4
  91. package/dist/chem/electrochem/preset.mjs +5 -5
  92. package/dist/chem/equilibrium/preset.d.mts +1 -1
  93. package/dist/chem/equilibrium/preset.mjs +6 -6
  94. package/dist/chem/gas-box/preset.mjs +6 -6
  95. package/dist/chem/kinetics/preset.mjs +6 -6
  96. package/dist/chem/periodic-trends/preset.mjs +7 -7
  97. package/dist/chem/reaction-lab.mjs +3 -3
  98. package/dist/chem/reaction-profile.mjs +4 -4
  99. package/dist/chem/solution/dilution.mjs +6 -6
  100. package/dist/chem/solution/field.d.mts +2 -2
  101. package/dist/chem/solution/field.mjs +2 -2
  102. package/dist/chem/solution/solution-box.mjs +7 -7
  103. package/dist/chem/stoichiometry/preset.mjs +5 -5
  104. package/dist/chem/titration/preset.mjs +5 -5
  105. package/dist/circuits/ac-dc/asset.mjs +1 -1
  106. package/dist/circuits/ac-dc/preset.mjs +2 -2
  107. package/dist/circuits/brownout/index.d.mts +1 -0
  108. package/dist/circuits/brownout/preset.d.mts +22 -0
  109. package/dist/circuits/brownout/preset.mjs +399 -0
  110. package/dist/circuits/capacitor-leak/preset.mjs +13 -8
  111. package/dist/circuits/circuit/asset.mjs +71 -14
  112. package/dist/circuits/circuit/preset.mjs +23 -5
  113. package/dist/circuits/circuit-builder.mjs +60 -132
  114. package/dist/circuits/circuit-lab.mjs +60 -40
  115. package/dist/circuits/cmos-gate/index.d.mts +1 -0
  116. package/dist/circuits/cmos-gate/preset.d.mts +75 -0
  117. package/dist/circuits/cmos-gate/preset.mjs +1491 -0
  118. package/dist/circuits/diode/index.d.mts +1 -0
  119. package/dist/circuits/diode/preset.d.mts +25 -0
  120. package/dist/circuits/diode/preset.mjs +266 -0
  121. package/dist/circuits/index.d.mts +7 -1
  122. package/dist/circuits/index.mjs +7 -1
  123. package/dist/circuits/rc-charging/index.d.mts +1 -0
  124. package/dist/circuits/rc-charging/preset.d.mts +27 -0
  125. package/dist/circuits/rc-charging/preset.mjs +329 -0
  126. package/dist/circuits/semiconductor/index.d.mts +1 -0
  127. package/dist/circuits/semiconductor/preset.d.mts +102 -0
  128. package/dist/circuits/semiconductor/preset.mjs +1855 -0
  129. package/dist/circuits/transistor/index.d.mts +1 -0
  130. package/dist/circuits/transistor/preset.d.mts +27 -0
  131. package/dist/circuits/transistor/preset.mjs +329 -0
  132. package/dist/commerce/accounting/core.d.mts +1 -1
  133. package/dist/commerce/accounting/equation-balance.mjs +5 -5
  134. package/dist/commerce/accounting/journal-poster.mjs +8 -8
  135. package/dist/commerce/accounting/statement-sorter.mjs +4 -4
  136. package/dist/commerce/economics/core.d.mts +2 -2
  137. package/dist/commerce/economics/core.mjs +1 -1
  138. package/dist/commerce/economics/demand-shift-vs-move.mjs +6 -6
  139. package/dist/commerce/economics/elasticity-revenue.mjs +6 -6
  140. package/dist/commerce/economics/market-equilibrium.mjs +5 -5
  141. package/dist/core/easing.d.mts +3 -3
  142. package/dist/core/easing.mjs +2 -2
  143. package/dist/core/numeric.d.mts +3 -3
  144. package/dist/core/numeric.mjs +2 -2
  145. package/dist/core/reactive.d.mts +1 -1
  146. package/dist/core/reactive.mjs +1 -1
  147. package/dist/core/rng.d.mts +2 -2
  148. package/dist/core/rng.mjs +1 -1
  149. package/dist/core/tex.mjs +2 -2
  150. package/dist/core/timeline.d.mts +1 -1
  151. package/dist/core/timeline.mjs +1 -1
  152. package/dist/core/util.mjs +11 -1
  153. package/dist/discrete/arrangements/preset.mjs +6 -14
  154. package/dist/discrete/bayes/preset.mjs +43 -35
  155. package/dist/discrete/binomial/preset.mjs +2 -2
  156. package/dist/discrete/combination-studio/figure.d.mts +6 -0
  157. package/dist/discrete/combination-studio/figure.mjs +159 -0
  158. package/dist/discrete/combination-studio/index.d.mts +2 -0
  159. package/dist/discrete/combination-studio/preset.d.mts +44 -0
  160. package/dist/discrete/combination-studio/preset.mjs +440 -0
  161. package/dist/discrete/core/combinatorics.d.mts +23 -3
  162. package/dist/discrete/core/combinatorics.mjs +38 -3
  163. package/dist/discrete/core/pigeonhole.d.mts +1 -1
  164. package/dist/discrete/core/pigeonhole.mjs +1 -1
  165. package/dist/discrete/core/probability.d.mts +3 -3
  166. package/dist/discrete/core/probability.mjs +3 -3
  167. package/dist/discrete/core/sets.d.mts +1 -1
  168. package/dist/discrete/counting-slots/preset.mjs +8 -8
  169. package/dist/discrete/counting-tree/preset.mjs +65 -8
  170. package/dist/discrete/expected-value/preset.mjs +13 -13
  171. package/dist/discrete/hypergeometric/preset.mjs +48 -15
  172. package/dist/discrete/index.d.mts +4 -2
  173. package/dist/discrete/index.mjs +4 -2
  174. package/dist/discrete/karnaugh/preset.mjs +26 -20
  175. package/dist/discrete/lln/preset.mjs +44 -3
  176. package/dist/discrete/logic-circuit/preset.mjs +2 -2
  177. package/dist/discrete/monte-carlo/preset.d.mts +1 -1
  178. package/dist/discrete/monte-carlo/preset.mjs +14 -14
  179. package/dist/discrete/monty-hall/preset.mjs +6 -6
  180. package/dist/discrete/outcome-builder/preset.mjs +3 -3
  181. package/dist/discrete/pascal/preset.mjs +37 -7
  182. package/dist/discrete/rules.d.mts +20 -0
  183. package/dist/discrete/rules.mjs +264 -0
  184. package/dist/discrete/sample-space/preset.mjs +4 -4
  185. package/dist/discrete/selection/preset.mjs +7 -13
  186. package/dist/discrete/truth-table/preset.mjs +32 -9
  187. package/dist/discrete/venn/preset.mjs +71 -48
  188. package/dist/geography/cycle-lab/preset.mjs +17 -10
  189. package/dist/geography/cycles.d.mts +3 -3
  190. package/dist/geography/cycles.mjs +3 -3
  191. package/dist/geometry/board/preset.d.mts +2 -0
  192. package/dist/geometry/board/preset.mjs +11 -15
  193. package/dist/geometry/builder.mjs +3 -3
  194. package/dist/ict/number-systems/base-odometer.mjs +4 -4
  195. package/dist/ict/number-systems/bit-grouper.d.mts +1 -1
  196. package/dist/ict/number-systems/bit-grouper.mjs +4 -4
  197. package/dist/ict/number-systems/place-value-dial.d.mts +1 -1
  198. package/dist/ict/number-systems/place-value-dial.mjs +3 -3
  199. package/dist/ict/number-systems/wheel.d.mts +3 -3
  200. package/dist/ict/number-systems/wheel.mjs +4 -4
  201. package/dist/kit/annotate.mjs +3 -3
  202. package/dist/kit/answer-check.d.mts +2 -2
  203. package/dist/kit/answer-check.mjs +34 -6
  204. package/dist/kit/ask.d.mts +19 -0
  205. package/dist/kit/ask.mjs +46 -0
  206. package/dist/kit/bar-strip.mjs +53 -0
  207. package/dist/kit/calc.d.mts +33 -0
  208. package/dist/kit/calc.mjs +27 -0
  209. package/dist/kit/carrier-engine.mjs +147 -0
  210. package/dist/kit/clue-scene.d.mts +86 -0
  211. package/dist/kit/clue-scene.mjs +424 -0
  212. package/dist/kit/cluster.d.mts +30 -0
  213. package/dist/kit/cluster.mjs +81 -0
  214. package/dist/kit/controls.mjs +11 -5
  215. package/dist/kit/coords.d.mts +88 -0
  216. package/dist/kit/coords.mjs +192 -0
  217. package/dist/kit/data-scene.d.mts +27 -0
  218. package/dist/kit/data-scene.mjs +199 -0
  219. package/dist/kit/diagram.mjs +111 -50
  220. package/dist/kit/electronics.mjs +552 -60
  221. package/dist/kit/expr-analysis.d.mts +18 -6
  222. package/dist/kit/expr-analysis.mjs +82 -28
  223. package/dist/kit/frame.d.mts +3 -3
  224. package/dist/kit/frame.mjs +25 -6
  225. package/dist/kit/gameshow.mjs +2 -2
  226. package/dist/kit/index.d.mts +14 -2
  227. package/dist/kit/index.mjs +13 -1
  228. package/dist/kit/logic-gates.mjs +246 -47
  229. package/dist/kit/palette.mjs +26 -0
  230. package/dist/kit/pedagogy.d.mts +4 -4
  231. package/dist/kit/pedagogy.mjs +21 -17
  232. package/dist/kit/play.d.mts +1 -1
  233. package/dist/kit/play.mjs +3 -3
  234. package/dist/kit/predict.d.mts +55 -0
  235. package/dist/kit/predict.mjs +146 -0
  236. package/dist/kit/receipt.d.mts +29 -0
  237. package/dist/kit/receipt.mjs +94 -0
  238. package/dist/kit/rich.mjs +2 -2
  239. package/dist/kit/rule.d.mts +59 -0
  240. package/dist/kit/rule.mjs +215 -0
  241. package/dist/kit/scale.mjs +1 -1
  242. package/dist/kit/scene-library.d.mts +22 -0
  243. package/dist/kit/scene-library.mjs +311 -0
  244. package/dist/kit/scene-studio.d.mts +14 -0
  245. package/dist/kit/scene-studio.mjs +338 -0
  246. package/dist/kit/scenes.d.mts +31 -0
  247. package/dist/kit/scenes.mjs +569 -0
  248. package/dist/kit/slot-fill.d.mts +61 -0
  249. package/dist/kit/slot-fill.mjs +207 -0
  250. package/dist/kit/solve.d.mts +21 -0
  251. package/dist/kit/solve.mjs +75 -0
  252. package/dist/kit/space.mjs +5 -5
  253. package/dist/kit/steps.mjs +2 -2
  254. package/dist/kit/vessel.d.mts +69 -0
  255. package/dist/kit/vessel.mjs +191 -0
  256. package/dist/language/agreement/preset.mjs +2 -2
  257. package/dist/language/article-lens/preset.d.mts +1 -1
  258. package/dist/language/article-lens/preset.mjs +8 -8
  259. package/dist/language/deck.d.mts +3 -3
  260. package/dist/language/deck.mjs +1 -1
  261. package/dist/language/preposition-scene/preset.d.mts +2 -2
  262. package/dist/language/preposition-scene/preset.mjs +5 -5
  263. package/dist/language/sentence-builder/preset.mjs +5 -5
  264. package/dist/language/transform/preset.d.mts +2 -2
  265. package/dist/language/transform/preset.mjs +5 -5
  266. package/dist/language/ui.d.mts +3 -3
  267. package/dist/language/ui.mjs +4 -4
  268. package/dist/language/word-match/preset.mjs +3 -3
  269. package/dist/logic/LogicBuildLab.d.mts +22 -0
  270. package/dist/logic/LogicBuildLab.mjs +170 -0
  271. package/dist/logic/LogicEditScene.d.mts +31 -0
  272. package/dist/logic/LogicEditScene.mjs +276 -0
  273. package/dist/logic/LogicEditor.d.mts +14 -0
  274. package/dist/logic/LogicEditor.mjs +413 -0
  275. package/dist/logic/LogicScene.d.mts +32 -0
  276. package/dist/logic/LogicScene.mjs +277 -0
  277. package/dist/logic/contract.d.mts +72 -0
  278. package/dist/logic/display.d.mts +24 -0
  279. package/dist/logic/display.mjs +127 -0
  280. package/dist/logic/edit-ops.d.mts +44 -0
  281. package/dist/logic/edit-ops.mjs +177 -0
  282. package/dist/logic/evaluate.d.mts +11 -0
  283. package/dist/logic/evaluate.mjs +93 -0
  284. package/dist/logic/gates.d.mts +10 -0
  285. package/dist/logic/gates.mjs +73 -0
  286. package/dist/logic/index.d.mts +14 -0
  287. package/dist/logic/index.mjs +13 -0
  288. package/dist/logic/lab.d.mts +32 -0
  289. package/dist/logic/lab.mjs +160 -0
  290. package/dist/logic/presets.d.mts +12 -0
  291. package/dist/logic/presets.mjs +241 -0
  292. package/dist/logic/registry.d.mts +9 -0
  293. package/dist/logic/registry.mjs +15 -0
  294. package/dist/math/area-model/preset.mjs +70 -44
  295. package/dist/math/balance-algebra/preset.mjs +14 -5
  296. package/dist/math/broken-tree/index.d.mts +1 -0
  297. package/dist/math/broken-tree/preset.d.mts +26 -0
  298. package/dist/math/broken-tree/preset.mjs +435 -0
  299. package/dist/math/circle/index.d.mts +1 -0
  300. package/dist/math/circle/preset.d.mts +44 -0
  301. package/dist/math/circle/preset.mjs +198 -0
  302. package/dist/math/complex/core.d.mts +93 -0
  303. package/dist/math/complex/core.mjs +239 -0
  304. package/dist/math/complex/index.d.mts +3 -0
  305. package/dist/math/complex/preset.d.mts +31 -0
  306. package/dist/math/complex/preset.mjs +377 -0
  307. package/dist/math/complex/rules.d.mts +6 -0
  308. package/dist/math/complex/rules.mjs +121 -0
  309. package/dist/math/conic/index.d.mts +1 -0
  310. package/dist/math/conic/preset.d.mts +30 -0
  311. package/dist/math/conic/preset.mjs +334 -0
  312. package/dist/math/derivation.mjs +5 -5
  313. package/dist/math/derivative-explorer/preset.mjs +5 -5
  314. package/dist/math/domain-range/index.d.mts +1 -0
  315. package/dist/math/domain-range/preset.d.mts +33 -0
  316. package/dist/math/domain-range/preset.mjs +313 -0
  317. package/dist/math/fraction-bar/index.d.mts +1 -0
  318. package/dist/math/fraction-bar/preset.d.mts +27 -0
  319. package/dist/math/fraction-bar/preset.mjs +197 -0
  320. package/dist/math/function-machine/preset.mjs +2 -2
  321. package/dist/math/gradient-descent.mjs +6 -6
  322. package/dist/math/grapher/preset.d.mts +1 -1
  323. package/dist/math/grapher/preset.mjs +4 -4
  324. package/dist/math/harmonic-form/preset.mjs +6 -6
  325. package/dist/math/index.d.mts +27 -2
  326. package/dist/math/index.mjs +27 -2
  327. package/dist/math/integral-explorer/preset.mjs +2 -2
  328. package/dist/math/interactive/preset.mjs +3 -3
  329. package/dist/math/limit-explorer/preset.mjs +4 -4
  330. package/dist/math/linear-model/index.d.mts +1 -0
  331. package/dist/math/linear-model/preset.d.mts +53 -0
  332. package/dist/math/linear-model/preset.mjs +164 -0
  333. package/dist/math/linear-system/preset.mjs +4 -4
  334. package/dist/math/mystery-bucket/preset.mjs +6 -6
  335. package/dist/math/number-line/preset.mjs +3 -2
  336. package/dist/math/parabola/preset.mjs +4 -3
  337. package/dist/math/pattern/preset.mjs +7 -13
  338. package/dist/math/percent-bar/index.d.mts +1 -0
  339. package/dist/math/percent-bar/preset.d.mts +37 -0
  340. package/dist/math/percent-bar/preset.mjs +275 -0
  341. package/dist/math/poly/core.d.mts +50 -0
  342. package/dist/math/poly/core.mjs +268 -0
  343. package/dist/math/poly/index.d.mts +3 -0
  344. package/dist/math/poly/preset.d.mts +23 -0
  345. package/dist/math/poly/preset.mjs +141 -0
  346. package/dist/math/poly/steps.d.mts +10 -0
  347. package/dist/math/poly/steps.mjs +99 -0
  348. package/dist/math/rate-machine/index.d.mts +1 -0
  349. package/dist/math/rate-machine/preset.d.mts +35 -0
  350. package/dist/math/rate-machine/preset.mjs +281 -0
  351. package/dist/math/ratio-share/index.d.mts +1 -0
  352. package/dist/math/ratio-share/preset.d.mts +24 -0
  353. package/dist/math/ratio-share/preset.mjs +204 -0
  354. package/dist/math/receipt/index.d.mts +1 -0
  355. package/dist/math/receipt/preset.d.mts +22 -0
  356. package/dist/math/receipt/preset.mjs +137 -0
  357. package/dist/math/sequence-predict/index.d.mts +1 -0
  358. package/dist/math/sequence-predict/preset.d.mts +34 -0
  359. package/dist/math/sequence-predict/preset.mjs +130 -0
  360. package/dist/math/straight-line/index.d.mts +1 -0
  361. package/dist/math/straight-line/preset.d.mts +37 -0
  362. package/dist/math/straight-line/preset.mjs +374 -0
  363. package/dist/math/system-solve/index.d.mts +1 -0
  364. package/dist/math/system-solve/preset.d.mts +21 -0
  365. package/dist/math/system-solve/preset.mjs +227 -0
  366. package/dist/math/transform/index.d.mts +1 -0
  367. package/dist/math/transform/preset.d.mts +41 -0
  368. package/dist/math/transform/preset.mjs +343 -0
  369. package/dist/math/triangle-trig/preset.mjs +12 -9
  370. package/dist/math/trig/core.d.mts +37 -0
  371. package/dist/math/trig/core.mjs +150 -0
  372. package/dist/math/trig/diagrams.d.mts +1 -0
  373. package/dist/math/trig/diagrams.mjs +321 -0
  374. package/dist/math/trig/index.d.mts +3 -0
  375. package/dist/math/trig/preset.d.mts +25 -0
  376. package/dist/math/trig/preset.mjs +260 -0
  377. package/dist/math/trig/rules.d.mts +6 -0
  378. package/dist/math/trig/rules.mjs +159 -0
  379. package/dist/math/trig-explorer.mjs +4 -4
  380. package/dist/ml/boundary/preset.mjs +8 -3
  381. package/dist/ml/classifier/preset.mjs +31 -6
  382. package/dist/ml/kmeans/preset.mjs +4 -4
  383. package/dist/ml/knn/preset.mjs +47 -12
  384. package/dist/ml/regression/preset.mjs +36 -7
  385. package/dist/physics/atwood/preset.mjs +4 -4
  386. package/dist/physics/bullet-walls/preset.d.mts +1 -1
  387. package/dist/physics/bullet-walls/preset.mjs +7 -7
  388. package/dist/physics/carnot/preset.mjs +6 -6
  389. package/dist/physics/circular-motion/preset.mjs +36 -5
  390. package/dist/physics/collision-track/preset.mjs +35 -5
  391. package/dist/physics/efficiency/preset.d.mts +2 -2
  392. package/dist/physics/efficiency/preset.mjs +5 -5
  393. package/dist/physics/electric-field/preset.mjs +32 -23
  394. package/dist/physics/electric-flux/index.d.mts +1 -0
  395. package/dist/physics/electric-flux/preset.d.mts +29 -0
  396. package/dist/physics/electric-flux/preset.mjs +264 -0
  397. package/dist/physics/energy-skate/preset.mjs +5 -5
  398. package/dist/physics/entropy/preset.mjs +7 -7
  399. package/dist/physics/expansion/preset.mjs +13 -13
  400. package/dist/physics/exponential/asset.mjs +1 -1
  401. package/dist/physics/exponential/preset.mjs +4 -4
  402. package/dist/physics/gas-process/preset.mjs +3 -3
  403. package/dist/physics/gauss-law/index.d.mts +1 -0
  404. package/dist/physics/gauss-law/preset.d.mts +20 -0
  405. package/dist/physics/gauss-law/preset.mjs +286 -0
  406. package/dist/physics/gravitation/preset.mjs +7 -7
  407. package/dist/physics/gravity-drop.mjs +4 -4
  408. package/dist/physics/heat-transfer/preset.d.mts +1 -1
  409. package/dist/physics/heat-transfer/preset.mjs +10 -10
  410. package/dist/physics/impulse/preset.mjs +5 -5
  411. package/dist/physics/index.d.mts +4 -1
  412. package/dist/physics/index.mjs +4 -1
  413. package/dist/physics/kepler/preset.mjs +4 -4
  414. package/dist/physics/lever/preset.mjs +3 -3
  415. package/dist/physics/lorentz/preset.mjs +11 -11
  416. package/dist/physics/magnetism/preset.mjs +3 -3
  417. package/dist/physics/optics/preset.mjs +2 -2
  418. package/dist/physics/orbit-lab.mjs +5 -5
  419. package/dist/physics/projectile-lab.mjs +4 -4
  420. package/dist/physics/rain-relative/preset.mjs +5 -5
  421. package/dist/physics/ramp-forces/preset.mjs +5 -5
  422. package/dist/physics/river-boat.mjs +6 -6
  423. package/dist/physics/shm/preset.mjs +9 -9
  424. package/dist/physics/stopping-distance/preset.mjs +3 -3
  425. package/dist/physics/temperature-scales/preset.mjs +105 -116
  426. package/dist/physics/terminal-velocity/preset.mjs +5 -5
  427. package/dist/physics/thermal/preset.mjs +5 -5
  428. package/dist/physics/vector-board/preset.mjs +7 -6
  429. package/dist/physics/vector-scene.mjs +2 -2
  430. package/dist/physics/vector-types/preset.mjs +37 -3
  431. package/dist/physics/water-density/preset.mjs +12 -12
  432. package/dist/physics/waves/doppler.mjs +2 -2
  433. package/dist/physics/waves/preset.mjs +4 -4
  434. package/dist/physics/waves/ripple.mjs +6 -6
  435. package/dist/physics/waves/string.mjs +5 -5
  436. package/dist/physics/work-energy/preset.mjs +4 -4
  437. package/dist/physics/work-potential/index.d.mts +1 -0
  438. package/dist/physics/work-potential/preset.d.mts +20 -0
  439. package/dist/physics/work-potential/preset.mjs +276 -0
  440. package/dist/schemas/index.d.mts +6 -6
  441. package/dist/schemas/index.mjs +3 -3
  442. package/dist/statistics/center-spread/preset.mjs +3 -3
  443. package/dist/statistics/core/descriptive.d.mts +2 -2
  444. package/dist/statistics/core/descriptive.mjs +2 -2
  445. package/dist/statistics/core/normal.d.mts +3 -3
  446. package/dist/statistics/core/normal.mjs +3 -3
  447. package/dist/statistics/core/sequences.d.mts +1 -1
  448. package/dist/statistics/galton/preset.mjs +2 -2
  449. package/dist/statistics/histogram/preset.mjs +6 -6
  450. package/dist/statistics/normal/preset.mjs +2 -2
  451. package/dist/statistics/sampling/preset.mjs +4 -4
  452. package/dist/statistics/sequence/preset.mjs +58 -15
  453. package/dist/statistics/z-table/preset.mjs +17 -4
  454. package/package.json +11 -3
  455. package/styles.css +4 -1
@@ -9,16 +9,16 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
 
10
10
  //#region src/physics/entropy/preset.tsx
11
11
  /**
12
- * EntropyLab — why heat only flows one way, and why a gas always spreads out.
12
+ * EntropyLab, why heat only flows one way, and why a gas always spreads out.
13
13
  * Entropy is the bookkeeping behind the second law: in any real (spontaneous)
14
14
  * process the TOTAL entropy of the universe increases.
15
15
  *
16
- * • HEAT FLOW — move a chunk of heat Q from a hot body (Th) to a cold one (Tc).
16
+ * • HEAT FLOW, move a chunk of heat Q from a hot body (Th) to a cold one (Tc).
17
17
  * The hot body loses ΔS = −Q/Th; the cold body gains ΔS = +Q/Tc. Because
18
- * Tc < Th, the gain outweighs the loss, so ΔS_total = Q(1/Tc − 1/Th) > 0 —
18
+ * Tc < Th, the gain outweighs the loss, so ΔS_total = Q(1/Tc − 1/Th) > 0 ,
19
19
  * hot→cold is spontaneous. Running it backwards would DECREASE total entropy,
20
20
  * which never happens by itself. (Equal temperatures ⇒ ΔS_total = 0, reversible.)
21
- * • FREE EXPANSION — let a gas spread into a vacuum. No heat, no work, but the gas
21
+ * • FREE EXPANSION, let a gas spread into a vacuum. No heat, no work, but the gas
22
22
  * can never un-mix: ΔS = nR·ln(Vf/Vi) > 0. Spreading out is simply overwhelmingly
23
23
  * more likely than staying bunched up (more microstates).
24
24
  *
@@ -26,7 +26,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
26
26
  */
27
27
  const R = 8.314462618;
28
28
  const W = 640, H = 340;
29
- function EntropyLab({ mode: mode0 = "heat", title = "Entropy & the second law — the one-way arrow", prompt = "Real processes always increase the total entropy of the universe. See why heat flows hot→cold and why a gas spreads out — and never reverses on its own.", objectives = [
29
+ function EntropyLab({ mode: mode0 = "heat", title = "Entropy & the second law: the one-way arrow", prompt = "Real processes always increase the total entropy of the universe. See why heat flows hot→cold and why a gas spreads out, and never reverses on its own.", objectives = [
30
30
  "Compute entropy change as ΔS = Q/T for heat moved at temperature T",
31
31
  "See ΔS_total > 0 for spontaneous heat flow (and = 0 only when Th = Tc)",
32
32
  "Explain free expansion: ΔS = nR·ln(Vf/Vi) > 0, gas never un-mixes"
@@ -223,7 +223,7 @@ function EntropyLab({ mode: mode0 = "heat", title = "Entropy & the second law
223
223
  style: { color: "var(--stage-fg)" },
224
224
  children: "more"
225
225
  }),
226
- " entropy than the hot body loses (same Q, smaller T). So heat flows hot→cold by itself; the reverse would lower total entropy — forbidden by the 2nd law."
226
+ " entropy than the hot body loses (same Q, smaller T). So heat flows hot→cold by itself; the reverse would lower total entropy, forbidden by the 2nd law."
227
227
  ]
228
228
  })]
229
229
  })] });
@@ -317,7 +317,7 @@ function EntropyLab({ mode: mode0 = "heat", title = "Entropy & the second law
317
317
  }), /* @__PURE__ */ jsxs("span", {
318
318
  style: { color: "var(--stage-muted)" },
319
319
  children: [
320
- "No heat, no work — yet entropy still rises, because the gas now has far more ways to arrange itself. Fully open (Vf = 2Vi) gives ",
320
+ "No heat, no work, yet entropy still rises, because the gas now has far more ways to arrange itself. Fully open (Vf = 2Vi) gives ",
321
321
  /* @__PURE__ */ jsx("strong", {
322
322
  style: { color: "var(--stage-fg)" },
323
323
  children: "nR·ln 2 ≈ 5.76 J/K"
@@ -9,18 +9,18 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
 
10
10
  //#region src/physics/expansion/preset.tsx
11
11
  /**
12
- * ThermalExpansionLab — heat a solid and it grows. Drag the temperature and watch:
12
+ * ThermalExpansionLab, heat a solid and it grows. Drag the temperature and watch:
13
13
  *
14
- * • LENGTH ΔL = α·L·ΔT (a rod stretches — why rails and bridges leave gaps)
14
+ * • LENGTH ΔL = α·L·ΔT (a rod stretches, why rails and bridges leave gaps)
15
15
  * • AREA ΔA = 2α·A·ΔT (a plate grows in both directions)
16
16
  * • VOLUME ΔV = 3α·V·ΔT (a ball swells in all three)
17
- * • BIMETALLIC STRIP — two metals with different α bonded back-to-back: the one
17
+ * • BIMETALLIC STRIP, two metals with different α bonded back-to-back: the one
18
18
  * that expands more (brass) ends up on the OUTSIDE of the curve, so the strip
19
- * bends. Heat it enough and it closes a contact — that's a thermostat.
19
+ * bends. Heat it enough and it closes a contact, that's a thermostat.
20
20
  *
21
21
  * Real expansion is tiny (α ~ 10⁻⁵ /°C), so the drawing is MAGNIFIED for visibility
22
22
  * (the on-screen note says by how much) while the readout shows the TRUE ΔL/ΔA/ΔV.
23
- * Interactive — recomputes as you drag, no simulation loop. Pure SVG, themed.
23
+ * Interactive, recomputes as you drag, no simulation loop. Pure SVG, themed.
24
24
  */
25
25
  const W = 720, H = 360;
26
26
  const MAG = 120;
@@ -46,9 +46,9 @@ const METALS = {
46
46
  label: "Invar"
47
47
  }
48
48
  };
49
- function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansion — heat it, it grows", prompt = "Solids expand when heated as their atoms jiggle further apart. Drag the temperature: length, area and volume each grow — and two bonded metals bend.", objectives = [
49
+ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansion: heat it, it grows", prompt = "Solids expand when heated as their atoms jiggle further apart. Drag the temperature: length, area and volume each grow, and two bonded metals bend.", objectives = [
50
50
  "Use ΔL = αLΔT, and that area grows by 2α and volume by 3α",
51
- "See expansion is tiny but real — why rails, bridges and pipes need gaps",
51
+ "See expansion is tiny but real, why rails, bridges and pipes need gaps",
52
52
  "Explain a bimetallic strip / thermostat: unequal α → it bends"
53
53
  ], controlConfig } = {}) {
54
54
  const [mode, setMode] = useState(mode0);
@@ -161,7 +161,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
161
161
  style: { color: "var(--stage-fg)" },
162
162
  children: [dLmm.toFixed(2), " mm"]
163
163
  }),
164
- " — tiny, but a 100 m bridge would grow ",
164
+ ", tiny, but a 100 m bridge would grow ",
165
165
  (dLmm * 100).toFixed(0),
166
166
  " mm, so it needs expansion joints."
167
167
  ] }));
@@ -220,7 +220,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
220
220
  children: [
221
221
  "drawing ×",
222
222
  MAG,
223
- " — grows in BOTH directions (2α)"
223
+ ", grows in BOTH directions (2α)"
224
224
  ]
225
225
  })
226
226
  ]
@@ -354,7 +354,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
354
354
  children: [
355
355
  "drawing ×",
356
356
  MAG,
357
- " — grows in ALL three directions (3α)"
357
+ ", grows in ALL three directions (3α)"
358
358
  ]
359
359
  })
360
360
  ]
@@ -463,7 +463,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
463
463
  x: 488,
464
464
  y: 80,
465
465
  fill: "var(--stage-fg)",
466
- children: "brass (α high) — outside"
466
+ children: "brass (α high), outside"
467
467
  }),
468
468
  /* @__PURE__ */ jsx("rect", {
469
469
  x: 470,
@@ -476,7 +476,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
476
476
  x: 488,
477
477
  y: 100,
478
478
  fill: "var(--stage-fg)",
479
- children: "steel (α low) — inside"
479
+ children: "steel (α low), inside"
480
480
  })
481
481
  ]
482
482
  })
@@ -491,7 +491,7 @@ function ThermalExpansionLab({ mode: mode0 = "length", title = "Thermal expansio
491
491
  style: { color: "var(--stage-fg)" },
492
492
  children: "longer, outer"
493
493
  }),
494
- " edge of the curve — the strip bends toward the steel. Drag the temperature up until it closes the contact: that's how a ",
494
+ " edge of the curve, the strip bends toward the steel. Drag the temperature up until it closes the contact: that's how a ",
495
495
  /* @__PURE__ */ jsx("strong", {
496
496
  style: { color: "var(--stage-fg)" },
497
497
  children: "thermostat"
@@ -203,7 +203,7 @@ function chart(P, m, decay, maxV, sy, _sx, frame, curve, tx0, tx1, ty, halfLife,
203
203
  fontSize: 11,
204
204
  fill: "var(--stage-muted)",
205
205
  children: [
206
- decay ? `half-life ≈ ${halfLife.toFixed(1)} s — each one halves what's left` : `cooling toward room temp · τ ≈ ${m.tau.toFixed(1)} s`,
206
+ decay ? `half-life ≈ ${halfLife.toFixed(1)} s, each one halves what's left` : `cooling toward room temp · τ ≈ ${m.tau.toFixed(1)} s`,
207
207
  " · t = ",
208
208
  m.tSec.toFixed(1),
209
209
  " s"
@@ -10,9 +10,9 @@ import { Scene, registerAsset } from "@classytic/stage";
10
10
 
11
11
  //#region src/physics/exponential/preset.tsx
12
12
  /**
13
- * DecayCoolingLab — exponential relaxation made tangible, the standard data-driven
13
+ * DecayCoolingLab, exponential relaxation made tangible, the standard data-driven
14
14
  * way: one SceneDoc + one `rate` sim, two skins via the rate-process asset. Same
15
- * law (dy/dt = (target−y)/τ) tells two stories — radioactive atoms decaying to 0,
15
+ * law (dy/dt = (target−y)/τ) tells two stories, radioactive atoms decaying to 0,
16
16
  * and a hot drink cooling to room temperature. Press Play; it stops once relaxed.
17
17
  */
18
18
  registerAsset("rate-process", RATE_PROCESS_ASSET);
@@ -53,9 +53,9 @@ const EXPONENTIAL_CHALLENGE = [{
53
53
  }
54
54
  ],
55
55
  answer: "start",
56
- explain: "The rate tracks the gap to the surroundings — biggest at the start, easing to zero as it nears room temperature."
56
+ explain: "The rate tracks the gap to the surroundings, biggest at the start, easing to zero as it nears room temperature."
57
57
  }];
58
- function DecayCoolingLab({ mode: mode0 = "decay", title = "Exponential change — decay & cooling", prompt = "Same law, two stories: atoms decay and a hot drink cools — each relaxes toward a baseline at a rate set by τ. Press Play.", objectives = [
58
+ function DecayCoolingLab({ mode: mode0 = "decay", title = "Exponential change: decay & cooling", prompt = "Same law, two stories: atoms decay and a hot drink cools, each relaxes toward a baseline at a rate set by τ. Press Play.", objectives = [
59
59
  "See exponential relaxation toward a baseline",
60
60
  "Read a half-life (decay halves every t½)",
61
61
  "Recognise the SAME curve behind decay and cooling"
@@ -10,7 +10,7 @@ import { R, gammaDiatomic, gammaMonatomic, runProcess } from "@classytic/stage/t
10
10
 
11
11
  //#region src/physics/gas-process/preset.tsx
12
12
  /**
13
- * GasProcessLab — the four ideal-gas processes on a P–V diagram, with the first law
13
+ * GasProcessLab, the four ideal-gas processes on a P–V diagram, with the first law
14
14
  * kept honest. Pick a process, push/pull the gas, and watch:
15
15
  * • a piston cylinder (gas particles spread as V grows, colour tracks T),
16
16
  * • the P–V curve with the WORK shaded as the area under it (∫P dV),
@@ -46,7 +46,7 @@ const KINDS = [
46
46
  const kPa = (p) => (p / 1e3).toFixed(0);
47
47
  const L = (v) => (v * 1e3).toFixed(1);
48
48
  const J = (x) => (x >= 0 ? "+" : "−") + Math.abs(x).toFixed(0);
49
- function GasProcessLab({ kind: kind0 = "isothermal", title = "Gas processes — work is the area under P–V", prompt = "Expand or compress an ideal gas four different ways. The shaded area under the P–V curve is the work; the first law ΔU = Q − W balances the books.", objectives = [
49
+ function GasProcessLab({ kind: kind0 = "isothermal", title = "Gas processes: work is the area under P–V", prompt = "Expand or compress an ideal gas four different ways. The shaded area under the P–V curve is the work; the first law ΔU = Q − W balances the books.", objectives = [
50
50
  "Read work as the area under the P–V curve (∫P dV)",
51
51
  "Compare isothermal, adiabatic, isobaric and isochoric paths",
52
52
  "Apply the first law ΔU = Q − W and see when Q, W or ΔU is zero"
@@ -308,7 +308,7 @@ function GasProcessLab({ kind: kind0 = "isothermal", title = "Gas processes —
308
308
  ". PV = const."
309
309
  ] }),
310
310
  kind === "adiabatic" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
311
- "No heat in (Q = 0), so the work comes straight out of internal energy — the gas ",
311
+ "No heat in (Q = 0), so the work comes straight out of internal energy, the gas ",
312
312
  /* @__PURE__ */ jsx("strong", {
313
313
  style: { color: "var(--stage-fg)" },
314
314
  children: "cools as it expands"
@@ -0,0 +1 @@
1
+ import { GaussLab, GaussProps } from "./preset.mjs";
@@ -0,0 +1,20 @@
1
+ import { LabAskSpec } from "../../kit/ask.mjs";
2
+ import { ReactNode } from "react";
3
+
4
+ //#region src/physics/gauss-law/preset.d.ts
5
+ interface GaussProps {
6
+ title?: string;
7
+ prompt?: string;
8
+ ask?: LabAskSpec;
9
+ height?: number;
10
+ activity?: string;
11
+ }
12
+ declare function GaussLab({
13
+ title,
14
+ prompt,
15
+ ask,
16
+ height,
17
+ activity
18
+ }?: GaussProps): ReactNode;
19
+ //#endregion
20
+ export { GaussLab, GaussProps };
@@ -0,0 +1,286 @@
1
+ 'use client';
2
+
3
+ import { Chip } from "../../kit/controls.mjs";
4
+ import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
5
+ import { LabAsk } from "../../kit/ask.mjs";
6
+ import { useMemo, useState } from "react";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
+ import { MovableDot, Stage, useCoords } from "@classytic/stage";
9
+ import { fieldAt, fieldLines } from "@classytic/stage/field";
10
+
11
+ //#region src/physics/gauss-law/preset.tsx
12
+ /**
13
+ * GaussLab, Gauss's law as a thing you can see: the net number of field lines
14
+ * crossing OUT of a closed surface depends only on the charge it ENCLOSES, not on
15
+ * the surface's size or shape, and not at all on charges outside it.
16
+ *
17
+ * A Gaussian loop (drag its centre, drag the rim to resize) sits in the field of
18
+ * two charges. Around the loop, short markers show which way the field crosses it:
19
+ * GREEN points out (flux leaving), RED points in (flux entering).
20
+ * • enclose a + charge: every marker points out. Resize the loop: still all out,
21
+ * the net is unchanged, that is the whole point of Gauss's law.
22
+ * • a charge OUTSIDE: every line that enters one side leaves the other, so the
23
+ * greens and reds cancel and the net flux is zero.
24
+ * The readout gives the enclosed charge Q and the net flux Φ = Q/ε₀.
25
+ *
26
+ * Built on the shared stage `field` kernel (same one that draws electric-field
27
+ * and magnetism). Authorable via props + an optional checked question.
28
+ */
29
+ const VIEW = {
30
+ xMin: -6.5,
31
+ xMax: 6.5,
32
+ yMin: -4.1,
33
+ yMax: 4.1
34
+ };
35
+ const POS = "var(--stage-danger, #e03131)";
36
+ const NEG = "var(--stage-accent, #3b82f6)";
37
+ const OUT = "var(--stage-good)";
38
+ const IN = "var(--stage-danger, #e03131)";
39
+ const M = 20;
40
+ /** The charge glyphs (coloured disc + ± symbol), drawn ON TOP so the handles never hide them. */
41
+ function ChargeGlyphs({ charges }) {
42
+ const c = useCoords();
43
+ return /* @__PURE__ */ jsx("g", {
44
+ style: { pointerEvents: "none" },
45
+ children: charges.map((ch, i) => {
46
+ const [x, y] = c.toPx(ch.at.x, ch.at.y);
47
+ return /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("circle", {
48
+ cx: x,
49
+ cy: y,
50
+ r: 14,
51
+ fill: ch.q > 0 ? POS : NEG,
52
+ stroke: "var(--stage-bg)",
53
+ strokeWidth: 2
54
+ }), /* @__PURE__ */ jsx("text", {
55
+ x,
56
+ y: y + 5,
57
+ textAnchor: "middle",
58
+ fontSize: 18,
59
+ fontWeight: 800,
60
+ fill: "white",
61
+ children: ch.q > 0 ? "+" : "−"
62
+ })] }, i);
63
+ })
64
+ });
65
+ }
66
+ function GaussFigure({ sources, lines, center, radius }) {
67
+ const c = useCoords();
68
+ const P = (v) => c.toPx(v.x, v.y);
69
+ const [cx, cy] = P(center);
70
+ const rPx = Math.abs(c.toPx(center.x + radius, center.y)[0] - cx);
71
+ const markers = [];
72
+ for (let i = 0; i < M; i++) {
73
+ const ang = 2 * Math.PI * i / M;
74
+ const nhat = {
75
+ x: Math.cos(ang),
76
+ y: Math.sin(ang)
77
+ };
78
+ const p = {
79
+ x: center.x + radius * nhat.x,
80
+ y: center.y + radius * nhat.y
81
+ };
82
+ const E = fieldAt(sources, p);
83
+ const out = E.x * nhat.x + E.y * nhat.y > 0;
84
+ const L = .32;
85
+ const tip = out ? {
86
+ x: p.x + nhat.x * L,
87
+ y: p.y + nhat.y * L
88
+ } : {
89
+ x: p.x - nhat.x * L,
90
+ y: p.y - nhat.y * L
91
+ };
92
+ const [px, py] = P(p), [tx, ty] = P(tip);
93
+ markers.push(/* @__PURE__ */ jsx("line", {
94
+ x1: px,
95
+ y1: py,
96
+ x2: tx,
97
+ y2: ty,
98
+ stroke: out ? OUT : IN,
99
+ strokeWidth: 2.6,
100
+ strokeLinecap: "round"
101
+ }, `m${i}`));
102
+ }
103
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
104
+ lines.map((ln, i) => /* @__PURE__ */ jsx("polyline", {
105
+ points: ln.points.map((pt) => P(pt).join(",")).join(" "),
106
+ fill: "none",
107
+ stroke: "color-mix(in oklab, var(--stage-accent) 28%, transparent)",
108
+ strokeWidth: 1.3,
109
+ strokeLinejoin: "round"
110
+ }, `l${i}`)),
111
+ /* @__PURE__ */ jsx("circle", {
112
+ cx,
113
+ cy,
114
+ r: rPx,
115
+ fill: "color-mix(in oklab, var(--stage-good) 8%, transparent)",
116
+ stroke: "var(--stage-good)",
117
+ strokeWidth: 2,
118
+ strokeDasharray: "7 5"
119
+ }),
120
+ markers
121
+ ] });
122
+ }
123
+ function GaussLab({ title = "Gauss’s law: flux depends only on the charge inside", prompt = "Drag the loop and resize it. Green markers are field leaving, red are field entering. The net depends only on the charge enclosed, not the loop’s size.", ask, height = 420, activity = "gauss-law" } = {}) {
124
+ const [chA, setChA] = useState({
125
+ x: -1.3,
126
+ y: 0
127
+ });
128
+ const [chB, setChB] = useState({
129
+ x: 4.8,
130
+ y: 0
131
+ });
132
+ const [qa, setQa] = useState(1);
133
+ const [qb, setQb] = useState(1);
134
+ const [center, setCenter] = useState({
135
+ x: .4,
136
+ y: 0
137
+ });
138
+ const [rim, setRim] = useState({
139
+ x: 2.6,
140
+ y: 0
141
+ });
142
+ const radius = Math.max(.6, Math.hypot(rim.x - center.x, rim.y - center.y));
143
+ const charges = useMemo(() => [{
144
+ at: chA,
145
+ q: qa
146
+ }, {
147
+ at: chB,
148
+ q: qb
149
+ }], [
150
+ chA,
151
+ chB,
152
+ qa,
153
+ qb
154
+ ]);
155
+ const sources = useMemo(() => charges.map((ch) => ({
156
+ kind: "point",
157
+ at: ch.at,
158
+ q: ch.q
159
+ })), [charges]);
160
+ const lines = useMemo(() => fieldLines(sources, {
161
+ perSource: 12,
162
+ step: .07,
163
+ maxSteps: 600,
164
+ bounds: VIEW,
165
+ seed: .4
166
+ }), [sources]);
167
+ const enclosed = charges.filter((ch) => Math.hypot(ch.at.x - center.x, ch.at.y - center.y) < radius);
168
+ const Qenc = enclosed.reduce((s, ch) => s + ch.q, 0);
169
+ const verdict = Qenc > 0 ? "net flux OUT" : Qenc < 0 ? "net flux IN" : "net flux ZERO";
170
+ const figure = /* @__PURE__ */ jsxs(Stage, {
171
+ view: VIEW,
172
+ height,
173
+ ariaLabel: `Gaussian loop enclosing charge ${Qenc}`,
174
+ children: [
175
+ /* @__PURE__ */ jsx(GaussFigure, {
176
+ sources,
177
+ lines,
178
+ center,
179
+ radius
180
+ }),
181
+ /* @__PURE__ */ jsx(MovableDot, {
182
+ value: chA,
183
+ onMove: setChA,
184
+ color: qa > 0 ? POS : NEG,
185
+ ariaLabel: "charge A",
186
+ r: 8
187
+ }),
188
+ /* @__PURE__ */ jsx(MovableDot, {
189
+ value: chB,
190
+ onMove: setChB,
191
+ color: qb > 0 ? POS : NEG,
192
+ ariaLabel: "charge B",
193
+ r: 8
194
+ }),
195
+ /* @__PURE__ */ jsx(MovableDot, {
196
+ value: center,
197
+ onMove: (p) => {
198
+ const d = {
199
+ x: rim.x - center.x,
200
+ y: rim.y - center.y
201
+ };
202
+ setCenter(p);
203
+ setRim({
204
+ x: p.x + d.x,
205
+ y: p.y + d.y
206
+ });
207
+ },
208
+ color: "var(--stage-good)",
209
+ ariaLabel: "loop centre, drag to move it",
210
+ r: 7
211
+ }),
212
+ /* @__PURE__ */ jsx(MovableDot, {
213
+ value: rim,
214
+ onMove: setRim,
215
+ color: "var(--stage-good)",
216
+ ariaLabel: "loop edge, drag to resize",
217
+ r: 6
218
+ }),
219
+ /* @__PURE__ */ jsx(ChargeGlyphs, { charges })
220
+ ]
221
+ });
222
+ return /* @__PURE__ */ jsx(LabFrame, {
223
+ title,
224
+ prompt,
225
+ controls: /* @__PURE__ */ jsxs(ControlBar, { children: [/* @__PURE__ */ jsx(Field, {
226
+ label: "charge A",
227
+ children: /* @__PURE__ */ jsxs("span", {
228
+ className: "lab-field-row",
229
+ children: [/* @__PURE__ */ jsx(Chip, {
230
+ selected: qa > 0,
231
+ onClick: () => setQa(1),
232
+ children: "+"
233
+ }), /* @__PURE__ */ jsx(Chip, {
234
+ selected: qa < 0,
235
+ onClick: () => setQa(-1),
236
+ children: "−"
237
+ })]
238
+ })
239
+ }), /* @__PURE__ */ jsx(Field, {
240
+ label: "charge B",
241
+ children: /* @__PURE__ */ jsxs("span", {
242
+ className: "lab-field-row",
243
+ children: [/* @__PURE__ */ jsx(Chip, {
244
+ selected: qb > 0,
245
+ onClick: () => setQb(1),
246
+ children: "+"
247
+ }), /* @__PURE__ */ jsx(Chip, {
248
+ selected: qb < 0,
249
+ onClick: () => setQb(-1),
250
+ children: "−"
251
+ })]
252
+ })
253
+ })] }),
254
+ aside: /* @__PURE__ */ jsx(Callout, {
255
+ tone: "result",
256
+ children: /* @__PURE__ */ jsxs("div", {
257
+ style: {
258
+ display: "grid",
259
+ gap: 6,
260
+ fontVariantNumeric: "tabular-nums",
261
+ fontSize: 13
262
+ },
263
+ children: [
264
+ /* @__PURE__ */ jsxs("span", { children: ["charges enclosed: ", /* @__PURE__ */ jsx("strong", { children: enclosed.length })] }),
265
+ /* @__PURE__ */ jsxs("span", { children: ["enclosed charge Q = ", /* @__PURE__ */ jsxs("strong", { children: [Qenc > 0 ? "+" : "", Qenc] })] }),
266
+ /* @__PURE__ */ jsxs("span", { children: ["Φ = Q/ε₀ → ", /* @__PURE__ */ jsx("strong", {
267
+ style: { color: Qenc > 0 ? OUT : Qenc < 0 ? IN : "var(--stage-muted)" },
268
+ children: verdict
269
+ })] }),
270
+ /* @__PURE__ */ jsx("span", {
271
+ style: { color: "var(--stage-muted)" },
272
+ children: "resize the loop: same charge inside, same flux. A charge outside adds zero."
273
+ })
274
+ ]
275
+ })
276
+ }),
277
+ footer: ask ? /* @__PURE__ */ jsx(LabAsk, {
278
+ ask,
279
+ activity
280
+ }) : void 0,
281
+ children: figure
282
+ });
283
+ }
284
+
285
+ //#endregion
286
+ export { GaussLab };
@@ -11,19 +11,19 @@ import { Circle, Dot, Label, MovableDot, Polyline, Segment, Stage, Vector } from
11
11
 
12
12
  //#region src/physics/gravitation/preset.tsx
13
13
  /**
14
- * GravitationLab — "Inverse-square", how gravity fades with distance.
14
+ * GravitationLab, "Inverse-square", how gravity fades with distance.
15
15
  *
16
16
  * Newton's law of universal gravitation: F = G·M·m / r². Drag the satellite and
17
- * the pull on it tracks 1/r² — DOUBLE the distance and the force drops to a
17
+ * the pull on it tracks 1/r², DOUBLE the distance and the force drops to a
18
18
  * QUARTER (not a half), the defining surprise of an inverse-square law. The same
19
19
  * rule is why weight shrinks with altitude (g = GM/r²). A live F-vs-r curve marks
20
20
  * where you are on the steep 1/r² fall-off.
21
21
  *
22
- * Interactive (drag the satellite) — no timed loop. Tokenized SVG.
22
+ * Interactive (drag the satellite), no timed loop. Tokenized SVG.
23
23
  */
24
24
  const GRAVITATION_CHALLENGE = [{
25
25
  id: "double-r",
26
- prompt: "Double the distance between two masses — the gravitational force becomes…",
26
+ prompt: "Double the distance between two masses, the gravitational force becomes…",
27
27
  choices: [
28
28
  {
29
29
  value: "quarter",
@@ -62,7 +62,7 @@ const GRAVITATION_CHALLENGE = [{
62
62
  }];
63
63
  const R_MIN = 2.4, R_MAX = 9;
64
64
  const K_BASE = 60;
65
- function GravitationLab({ planetMass = 5, satMass = 1, title = "Inverse-square gravity — double the distance, quarter the pull", prompt = "Newton’s law: F = G·M·m / r². Drag the satellite in and out — the pull follows 1/r², so moving twice as far drops the force to a quarter, not a half. It’s the same law that thins your weight with altitude (g = GM/r²).", objectives, controlConfig }) {
65
+ function GravitationLab({ planetMass = 5, satMass = 1, title = "Inverse-square gravity: double the distance, quarter the pull", prompt = "Newton’s law: F = G·M·m / r². Drag the satellite in and out, the pull follows 1/r², so moving twice as far drops the force to a quarter, not a half. It’s the same law that thins your weight with altitude (g = GM/r²).", objectives, controlConfig }) {
66
66
  const [M, setM] = useState(planetMass);
67
67
  const [m, setm] = useState(satMass);
68
68
  const [sat, setSat] = useState({
@@ -179,7 +179,7 @@ function GravitationLab({ planetMass = 5, satMass = 1, title = "Inverse-square g
179
179
  value: sat,
180
180
  onMove,
181
181
  color: "var(--stage-accent)",
182
- ariaLabel: "satellite — drag to change distance"
182
+ ariaLabel: "satellite, drag to change distance"
183
183
  })
184
184
  ]
185
185
  })
@@ -303,7 +303,7 @@ function GravitationLab({ planetMass = 5, satMass = 1, title = "Inverse-square g
303
303
  opacity: .75,
304
304
  margin: 0
305
305
  },
306
- children: "The curve falls as 1/r² — steeply near the planet, then a long faint tail. Same maths gives orbital speed v = √(GM/r) and ties straight into the Kepler lab."
306
+ children: "The curve falls as 1/r², steeply near the planet, then a long faint tail. Same maths gives orbital speed v = √(GM/r) and ties straight into the Kepler lab."
307
307
  }),
308
308
  /* @__PURE__ */ jsx(LiveRegion, { children: `Distance ${r.toFixed(1)}, pull ${F.toFixed(1)}. Doubling the distance quarters the force.` })
309
309
  ]
@@ -8,7 +8,7 @@ import { Label, Segment, Stage, fmt, useCoords, useFrameLoop, useInView } from "
8
8
 
9
9
  //#region src/physics/gravity-drop.tsx
10
10
  /**
11
- * GravityDrop — drop identical balls on three worlds; stronger gravity wins.
11
+ * GravityDrop, drop identical balls on three worlds; stronger gravity wins.
12
12
  * On the @classytic/stage engine (SVG): three lanes in a fixed coordinate box,
13
13
  * the balls fall on the engine clock, landing times appear as they hit.
14
14
  */
@@ -18,7 +18,7 @@ const num = (v, fb) => {
18
18
  };
19
19
  /**
20
20
  * A falling ball: a shaded sphere (tone fill + top-left specular) with a motion
21
- * trail whose length scales with speed — so the eye reads Jupiter's ball as
21
+ * trail whose length scales with speed, so the eye reads Jupiter's ball as
22
22
  * genuinely faster than the Moon's. Drawn in pixels (project the math centre
23
23
  * first); the trail and highlight are constant-quality regardless of zoom.
24
24
  */
@@ -172,9 +172,9 @@ function GravityDrop(props) {
172
172
  })] });
173
173
  return /* @__PURE__ */ jsx(LabFrame, {
174
174
  title: "Gravity Drop",
175
- prompt: `Drop identical balls from ${fallH} m on three worlds — stronger gravity wins.`,
175
+ prompt: `Drop identical balls from ${fallH} m on three worlds, stronger gravity wins.`,
176
176
  aside: /* @__PURE__ */ jsxs(Callout, { children: [
177
- "Same mass, same height — only ",
177
+ "Same mass, same height, only ",
178
178
  /* @__PURE__ */ jsx("strong", { children: "g" }),
179
179
  " differs."
180
180
  ] }),
@@ -10,7 +10,7 @@ interface HeatTransferProps {
10
10
  objectives?: string[];
11
11
  /**
12
12
  * Creator policy. To author a SINGLE-mechanism lesson (e.g. conduction only),
13
- * set `mode: 'conduction'` and `controlConfig: { hide: ['mechanism'] }` — the
13
+ * set `mode: 'conduction'` and `controlConfig: { hide: ['mechanism'] }`, the
14
14
  * switcher vanishes and the lab is focused on that one idea. Any knob (material,
15
15
  * rod length, body temperature, …) can likewise be hidden or locked.
16
16
  */
@@ -11,15 +11,15 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
 
12
12
  //#region src/physics/heat-transfer/preset.tsx
13
13
  /**
14
- * HeatTransferLab — the three ways heat travels, side by side, each with its real
14
+ * HeatTransferLab, the three ways heat travels, side by side, each with its real
15
15
  * rate law and an iconic animation:
16
16
  *
17
- * • CONDUCTION — through a solid, atom to atom. A rod between a hot and a cold
17
+ * • CONDUCTION, through a solid, atom to atom. A rod between a hot and a cold
18
18
  * end settles into a linear temperature gradient; energy packets march down it
19
19
  * at a speed set by Fourier's law Q̇ = k·A·ΔT/L (copper races, wood crawls).
20
- * • CONVECTION — bulk flow in a fluid. Heated fluid expands, rises, cools at the
21
- * top and sinks — a rolling convection current. Rate Q̇ = h·A·ΔT.
22
- * • RADIATION — electromagnetic waves, no medium needed. A hot body glows and
20
+ * • CONVECTION, bulk flow in a fluid. Heated fluid expands, rises, cools at the
21
+ * top and sinks, a rolling convection current. Rate Q̇ = h·A·ΔT.
22
+ * • RADIATION, electromagnetic waves, no medium needed. A hot body glows and
23
23
  * throws photons outward; the power obeys Stefan–Boltzmann P = εσA(T⁴ − T₀⁴),
24
24
  * so doubling the absolute temperature multiplies the radiated power by 16.
25
25
  *
@@ -47,10 +47,10 @@ const MATERIALS = {
47
47
  }
48
48
  };
49
49
  const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
50
- function HeatTransferLab({ mode: mode0 = "conduction", title = "Heat transfer — conduction, convection & radiation", prompt = "The three ways heat moves: through solids (conduction), by bulk fluid flow (convection), and as radiation across empty space.", objectives = [
50
+ function HeatTransferLab({ mode: mode0 = "conduction", title = "Heat transfer: conduction, convection & radiation", prompt = "The three ways heat moves: through solids (conduction), by bulk fluid flow (convection), and as radiation across empty space.", objectives = [
51
51
  "Tell conduction, convection and radiation apart by their mechanism",
52
52
  "See conduction depends on the material: Q̇ = k·A·ΔT/L (copper ≫ wood)",
53
- "See radiation obeys T⁴ — double the temperature, 16× the power"
53
+ "See radiation obeys T⁴, double the temperature, 16× the power"
54
54
  ], controlConfig } = {}) {
55
55
  const [mode, setMode] = useState(mode0);
56
56
  const [material, setMaterial] = useState("copper");
@@ -244,7 +244,7 @@ function HeatTransferLab({ mode: mode0 = "conduction", title = "Heat transfer
244
244
  }),
245
245
  " has k = ",
246
246
  k,
247
- " W/m·K — metals conduct ~1000× better than wood."
247
+ " W/m·K, metals conduct ~1000× better than wood."
248
248
  ]
249
249
  })]
250
250
  })] });
@@ -403,7 +403,7 @@ function HeatTransferLab({ mode: mode0 = "conduction", title = "Heat transfer
403
403
  style: { color: "var(--stage-fg)" },
404
404
  children: "sinks"
405
405
  }),
406
- " — a rolling current that carries heat with the moving matter. (No solid needed; impossible in a vacuum.)"
406
+ ", a rolling current that carries heat with the moving matter. (No solid needed; impossible in a vacuum.)"
407
407
  ]
408
408
  })]
409
409
  })] });
@@ -561,7 +561,7 @@ function HeatTransferLab({ mode: mode0 = "conduction", title = "Heat transfer
561
561
  }), /* @__PURE__ */ jsxs("span", {
562
562
  style: { color: "var(--stage-muted)" },
563
563
  children: [
564
- "EM waves — needs ",
564
+ "EM waves, needs ",
565
565
  /* @__PURE__ */ jsx("strong", {
566
566
  style: { color: "var(--stage-fg)" },
567
567
  children: "no medium"