@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
@@ -0,0 +1,399 @@
1
+ 'use client';
2
+
3
+ import { Chip, Slider } from "../../kit/controls.mjs";
4
+ import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
5
+ import { ChallengeCard, useChallenge, useCheckpoint } from "../../kit/pedagogy.mjs";
6
+ import { Tag, Wire } from "../../kit/electronics.mjs";
7
+ import { LabAsk } from "../../kit/ask.mjs";
8
+ import { useState } from "react";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ import { solveDC } from "@classytic/stage/circuit";
11
+
12
+ //#region src/circuits/brownout/preset.tsx
13
+ /**
14
+ * BrownoutLab — what a falling supply voltage does to digital logic. A CMOS gate only switches
15
+ * when its transistors can turn on, and that needs the supply rail VDD to stay above the
16
+ * threshold Vth. Drag the battery EMF down (a draining cell, a sagging rail) and the engine solves
17
+ * the gate's output: with a healthy supply it swings rail to rail (valid 1 / 0); as VDD falls
18
+ * toward Vth the swing collapses and the output can no longer follow the input, so it is no longer
19
+ * a valid 1 or 0. That is a brown-out: the chip is not broken, it is simply starved of voltage, and
20
+ * this is the bridge from EMF and
21
+ * the battery to whether a logic circuit works at all.
22
+ */
23
+ const K = .5;
24
+ const C_HEALTHY = "var(--stage-good)";
25
+ const C_MARGINAL = "var(--stage-warn, oklch(0.78 0.15 80))";
26
+ const C_DEAD = "var(--stage-danger)";
27
+ const W = 460, H = 250;
28
+ function BrownoutLab({ vth = 2, vmax = 6, title = "Brown-out: when the supply is too low to think", prompt = "Drag the battery EMF down. The CMOS gate only switches while the supply rail VDD stays above the transistor threshold. As VDD falls toward Vth the output, solved by the engine, loses its swing and can no longer follow the input: a brown-out, where the logic is no longer a valid 1 or 0.", ask, activity = "brownout" } = {}) {
29
+ const [vdd, setVdd] = useState(5);
30
+ const [A, setA] = useState(1);
31
+ const ch = useChallenge(BROWNOUT_Q);
32
+ useCheckpoint({
33
+ solved: ch.allCorrect,
34
+ activity: "brownout:predict"
35
+ });
36
+ const inv = (vddV, aV) => [
37
+ {
38
+ kind: "V",
39
+ n1: 1,
40
+ n2: 0,
41
+ value: vddV
42
+ },
43
+ {
44
+ kind: "V",
45
+ n1: 3,
46
+ n2: 0,
47
+ value: aV
48
+ },
49
+ {
50
+ kind: "M",
51
+ pmos: true,
52
+ n1: 2,
53
+ n2: 1,
54
+ n3: 3,
55
+ value: 0,
56
+ vth,
57
+ k: K
58
+ },
59
+ {
60
+ kind: "M",
61
+ n1: 2,
62
+ n2: 0,
63
+ n3: 3,
64
+ value: 0,
65
+ vth,
66
+ k: K
67
+ }
68
+ ];
69
+ const yAt = (aV) => solveDC(inv(vdd, aV)).nodeV[2] ?? 0;
70
+ const Yhigh = yAt(0);
71
+ const Ylow = yAt(vdd);
72
+ const Y = yAt(A ? vdd : 0);
73
+ const swing = Yhigh - Ylow;
74
+ const swingFrac = vdd > .05 ? swing / vdd : 0;
75
+ const SAFE = 1.5 * vth;
76
+ const collapsed = swingFrac <= .5;
77
+ const zone = collapsed ? "dead" : vdd < SAFE ? "marginal" : "healthy";
78
+ const zoneColor = zone === "healthy" ? C_HEALTHY : zone === "marginal" ? C_MARGINAL : C_DEAD;
79
+ const valid = !collapsed;
80
+ const level = collapsed ? "invalid" : Y > vdd / 2 ? "1" : "0";
81
+ const GX = 70, GTOP = 40, GBOT = 210, GW = 26;
82
+ const y = (v) => GBOT - Math.min(v, vmax) / vmax * (GBOT - GTOP);
83
+ const band = (lo, hi, color) => /* @__PURE__ */ jsx("rect", {
84
+ x: GX,
85
+ y: y(hi),
86
+ width: GW,
87
+ height: Math.max(0, y(lo) - y(hi)),
88
+ fill: color,
89
+ opacity: .32
90
+ });
91
+ const gx = 250, gy = 125;
92
+ const scene = /* @__PURE__ */ jsx("div", {
93
+ style: {
94
+ borderRadius: 12,
95
+ overflow: "hidden",
96
+ background: "var(--stage-bg)",
97
+ border: "1px solid var(--stage-grid)",
98
+ maxWidth: W,
99
+ margin: "0 auto"
100
+ },
101
+ children: /* @__PURE__ */ jsxs("svg", {
102
+ viewBox: `0 0 ${W} ${H}`,
103
+ width: "100%",
104
+ role: "img",
105
+ "aria-label": `Brown-out demo, supply ${vdd.toFixed(1)} volts, logic ${zone === "healthy" ? "valid" : zone === "marginal" ? "marginal" : "invalid"}`,
106
+ children: [
107
+ band(0, vth, C_DEAD),
108
+ band(vth, SAFE, C_MARGINAL),
109
+ band(SAFE, vmax, C_HEALTHY),
110
+ /* @__PURE__ */ jsx("rect", {
111
+ x: GX,
112
+ y: GTOP,
113
+ width: GW,
114
+ height: GBOT - GTOP,
115
+ fill: "none",
116
+ stroke: "var(--stage-grid)",
117
+ strokeWidth: 1,
118
+ rx: 4
119
+ }),
120
+ /* @__PURE__ */ jsx("line", {
121
+ x1: GX - 4,
122
+ y1: y(vth),
123
+ x2: 100,
124
+ y2: y(vth),
125
+ stroke: C_DEAD,
126
+ strokeWidth: 1,
127
+ strokeDasharray: "3 3"
128
+ }),
129
+ /* @__PURE__ */ jsx("line", {
130
+ x1: GX - 4,
131
+ y1: y(SAFE),
132
+ x2: 100,
133
+ y2: y(SAFE),
134
+ stroke: C_HEALTHY,
135
+ strokeWidth: 1,
136
+ strokeDasharray: "3 3"
137
+ }),
138
+ /* @__PURE__ */ jsx(Tag, {
139
+ x: 104,
140
+ y: y(vth) + 4,
141
+ text: `Vth ${vth}V`,
142
+ color: "var(--stage-muted)",
143
+ size: 10,
144
+ weight: 700,
145
+ anchor: "start"
146
+ }),
147
+ /* @__PURE__ */ jsx(Tag, {
148
+ x: 104,
149
+ y: y(SAFE) + 4,
150
+ text: "safe",
151
+ color: "var(--stage-muted)",
152
+ size: 10,
153
+ weight: 700,
154
+ anchor: "start"
155
+ }),
156
+ /* @__PURE__ */ jsx("rect", {
157
+ x: GX,
158
+ y: y(vdd),
159
+ width: GW,
160
+ height: GBOT - y(vdd),
161
+ fill: zoneColor,
162
+ opacity: .85
163
+ }),
164
+ /* @__PURE__ */ jsx("polygon", {
165
+ points: `${GX - 12},${y(vdd) - 6} ${GX - 12},${y(vdd) + 6} ${GX - 2},${y(vdd)}`,
166
+ fill: zoneColor
167
+ }),
168
+ /* @__PURE__ */ jsx(Tag, {
169
+ x: 83,
170
+ y: GTOP - 8,
171
+ text: "VDD",
172
+ color: "var(--stage-fg)",
173
+ size: 12,
174
+ weight: 800,
175
+ anchor: "middle"
176
+ }),
177
+ /* @__PURE__ */ jsx(Tag, {
178
+ x: 83,
179
+ y: 226,
180
+ text: `${vdd.toFixed(1)} V`,
181
+ color: zoneColor,
182
+ size: 13,
183
+ weight: 800,
184
+ anchor: "middle"
185
+ }),
186
+ /* @__PURE__ */ jsx(Wire, {
187
+ points: [
188
+ [96, y(vdd)],
189
+ [gx, y(vdd)],
190
+ [gx, gy - 34]
191
+ ],
192
+ live: vdd > .05
193
+ }),
194
+ /* @__PURE__ */ jsx("polygon", {
195
+ points: `${gx},${gy - 26} ${gx},151 290,${gy}`,
196
+ fill: "color-mix(in oklab, var(--stage-metal, gray) 18%, var(--stage-bg))",
197
+ stroke: "var(--stage-fg)",
198
+ strokeWidth: 1.5
199
+ }),
200
+ /* @__PURE__ */ jsx("circle", {
201
+ cx: 296,
202
+ cy: gy,
203
+ r: 5,
204
+ fill: "var(--stage-bg)",
205
+ stroke: "var(--stage-fg)",
206
+ strokeWidth: 1.5
207
+ }),
208
+ /* @__PURE__ */ jsx(Tag, {
209
+ x: 270,
210
+ y: 129,
211
+ text: "NOT",
212
+ color: "var(--stage-fg)",
213
+ size: 10,
214
+ weight: 700,
215
+ anchor: "middle"
216
+ }),
217
+ /* @__PURE__ */ jsx(Wire, {
218
+ points: [[gx - 36, gy], [gx, gy]],
219
+ live: !!A
220
+ }),
221
+ /* @__PURE__ */ jsx("circle", {
222
+ cx: gx - 40,
223
+ cy: gy,
224
+ r: 4.5,
225
+ fill: A ? C_HEALTHY : "var(--stage-muted)"
226
+ }),
227
+ /* @__PURE__ */ jsx(Tag, {
228
+ x: gx - 40,
229
+ y: gy - 10,
230
+ text: `A=${A}`,
231
+ color: "var(--stage-fg)",
232
+ size: 11,
233
+ weight: 700,
234
+ anchor: "middle"
235
+ }),
236
+ /* @__PURE__ */ jsx(Wire, {
237
+ points: [[301, gy], [346, gy]],
238
+ live: valid && level === "1"
239
+ }),
240
+ /* @__PURE__ */ jsx("circle", {
241
+ cx: 350,
242
+ cy: gy,
243
+ r: 5,
244
+ fill: level === "invalid" ? C_DEAD : level === "1" ? C_HEALTHY : "var(--stage-muted)"
245
+ }),
246
+ /* @__PURE__ */ jsx(Tag, {
247
+ x: 358,
248
+ y: gy - 8,
249
+ text: "Y",
250
+ color: "var(--stage-fg)",
251
+ size: 12,
252
+ weight: 700,
253
+ anchor: "start"
254
+ }),
255
+ /* @__PURE__ */ jsx(Tag, {
256
+ x: 358,
257
+ y: 137,
258
+ text: level === "invalid" ? "?" : level,
259
+ color: level === "invalid" ? C_DEAD : level === "1" ? C_HEALTHY : "var(--stage-fg)",
260
+ size: 14,
261
+ weight: 800,
262
+ anchor: "start"
263
+ }),
264
+ /* @__PURE__ */ jsx(Tag, {
265
+ x: 270,
266
+ y: H - 14,
267
+ text: `output = ${Y.toFixed(2)} V`,
268
+ color: "var(--stage-muted)",
269
+ size: 11,
270
+ weight: 700,
271
+ anchor: "middle"
272
+ })
273
+ ]
274
+ })
275
+ });
276
+ return /* @__PURE__ */ jsx(LabFrame, {
277
+ title,
278
+ prompt,
279
+ controls: /* @__PURE__ */ jsxs(ControlBar, { children: [/* @__PURE__ */ jsx(Field, {
280
+ label: `battery EMF = ${vdd.toFixed(1)} V`,
281
+ children: /* @__PURE__ */ jsx(Slider, {
282
+ min: 0,
283
+ max: vmax,
284
+ step: .1,
285
+ value: vdd,
286
+ onChange: setVdd,
287
+ ariaLabel: "battery EMF in volts"
288
+ })
289
+ }), /* @__PURE__ */ jsx(Field, {
290
+ label: "input A",
291
+ children: /* @__PURE__ */ jsxs("span", {
292
+ className: "lab-field-row",
293
+ children: [/* @__PURE__ */ jsx(Chip, {
294
+ selected: A === 0,
295
+ onClick: () => setA(0),
296
+ children: "0"
297
+ }), /* @__PURE__ */ jsx(Chip, {
298
+ selected: A === 1,
299
+ onClick: () => setA(1),
300
+ children: "1"
301
+ })]
302
+ })
303
+ })] }),
304
+ aside: /* @__PURE__ */ jsxs("div", {
305
+ style: {
306
+ display: "flex",
307
+ flexDirection: "column",
308
+ gap: 10
309
+ },
310
+ children: [
311
+ /* @__PURE__ */ jsx("div", {
312
+ className: "lab-pill",
313
+ "data-state": valid ? "ok" : "no",
314
+ role: "status",
315
+ style: { alignSelf: "flex-start" },
316
+ children: zone === "healthy" ? "✓ supply healthy: logic valid, good noise margin" : zone === "marginal" ? "⚠ low rail: logic still valid but the noise margin is thin" : "✗ supply below threshold: output invalid (no swing)"
317
+ }),
318
+ /* @__PURE__ */ jsx(Callout, {
319
+ tone: "result",
320
+ children: /* @__PURE__ */ jsxs("div", {
321
+ style: {
322
+ fontSize: 13,
323
+ lineHeight: 1.6
324
+ },
325
+ children: [
326
+ "supply VDD = ",
327
+ /* @__PURE__ */ jsxs("strong", { children: [vdd.toFixed(1), " V"] }),
328
+ " (threshold Vth = ",
329
+ vth,
330
+ " V)",
331
+ /* @__PURE__ */ jsx("br", {}),
332
+ "output swing = ",
333
+ /* @__PURE__ */ jsxs("strong", { children: [Math.max(0, swing).toFixed(2), " V"] }),
334
+ " (",
335
+ Math.round(Math.max(0, swingFrac) * 100),
336
+ "% of rail)",
337
+ /* @__PURE__ */ jsx("br", {}),
338
+ "this output = ",
339
+ Y.toFixed(2),
340
+ " V → ",
341
+ level === "invalid" ? /* @__PURE__ */ jsx("span", {
342
+ style: {
343
+ color: C_DEAD,
344
+ fontWeight: 700
345
+ },
346
+ children: "invalid (neither 1 nor 0)"
347
+ }) : /* @__PURE__ */ jsxs("span", {
348
+ style: { fontWeight: 700 },
349
+ children: ["logic ", level]
350
+ })
351
+ ]
352
+ })
353
+ }),
354
+ /* @__PURE__ */ jsx(Callout, {
355
+ tone: "info",
356
+ children: /* @__PURE__ */ jsx("div", {
357
+ style: {
358
+ fontSize: 12.5,
359
+ lineHeight: 1.5
360
+ },
361
+ children: "A transistor needs gate-to-source above Vth to conduct. Once the whole rail drops near Vth, neither the pull-up nor the pull-down can fully turn on, so the output can no longer be driven to a valid level and the swing collapses. Real systems brown out when a battery drains or a heavy load makes the supply sag (EMF minus the internal-resistance drop). The cure is a minimum supply voltage, not a faster chip."
362
+ })
363
+ })
364
+ ]
365
+ }),
366
+ footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ChallengeCard, {
367
+ questions: BROWNOUT_Q,
368
+ state: ch,
369
+ title: "Predict first"
370
+ }), ask ? /* @__PURE__ */ jsx(LabAsk, {
371
+ ask,
372
+ activity
373
+ }) : null] }),
374
+ children: scene
375
+ });
376
+ }
377
+ const BROWNOUT_Q = [{
378
+ id: "brownout-low",
379
+ prompt: "The battery drains until the supply VDD falls below the transistor threshold Vth. What happens to the gate output?",
380
+ choices: [
381
+ {
382
+ value: "a",
383
+ label: "it becomes invalid: neither a clean 1 nor 0"
384
+ },
385
+ {
386
+ value: "b",
387
+ label: "it stays a perfect 1 and 0, just slower"
388
+ },
389
+ {
390
+ value: "c",
391
+ label: "the gate burns out"
392
+ }
393
+ ],
394
+ answer: "a",
395
+ explain: "Below Vth neither transistor can fully turn on, so the output cannot reach the rails and the swing collapses (it stops following the input). Nothing is damaged: the chip is simply starved of voltage. That is a brown-out, and it is why every chip has a minimum supply voltage."
396
+ }];
397
+
398
+ //#endregion
399
+ export { BrownoutLab };
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { Chip, Slider } from "../../kit/controls.mjs";
4
4
  import { ControlBar, Field, LabFrame, LiveRegion } from "../../kit/frame.mjs";
5
- import { HintLadder, useHints } from "../../kit/pedagogy.mjs";
6
- import { useFrameTick, useReducedMotion } from "../../kit/anim.mjs";
5
+ import { HintLadder, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
7
6
  import { CapacitorGlyph, CellGlyph, ResistorGlyph } from "../../kit/electronics.mjs";
7
+ import { useFrameTick, useReducedMotion } from "../../kit/anim.mjs";
8
8
  import { useRef, useState } from "react";
9
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
10
  import { useInView } from "@classytic/stage";
@@ -12,19 +12,19 @@ import { RateCore } from "@classytic/stage/sim";
12
12
 
13
13
  //#region src/circuits/capacitor-leak/preset.tsx
14
14
  /**
15
- * CapacitorLeakLab — why a capacitor charges, holds, and (slowly) LEAKS.
15
+ * CapacitorLeakLab, why a capacitor charges, holds, and (slowly) LEAKS.
16
16
  *
17
17
  * A textbook RC loop: a cell charges a capacitor C through a resistor R. Flip
18
- * the switch to "leak" and the cell is disconnected — the capacitor discharges
18
+ * the switch to "leak" and the cell is disconnected, the capacitor discharges
19
19
  * through its own leakage resistance, the field between the plates thins, drips
20
- * fall off the lower plate, and Vc decays exponentially. One source of truth —
21
- * Vc(t), integrated by the shared `useFrameLoop` clock — drives the plate field,
20
+ * fall off the lower plate, and Vc decays exponentially. One source of truth ,
21
+ * Vc(t), integrated by the shared `useFrameLoop` clock, drives the plate field,
22
22
  * the drips, the live readout, and the Vc–t trace, so they can never disagree.
23
23
  *
24
24
  * Time-dependent physics lives in the COMPONENT (the pure scene resolver runs
25
25
  * once per resolve and can't integrate an ODE); the symbols are the tokenized
26
26
  * @classytic/stage electronics glyphs, so the schematic stays exam-standard and
27
- * rethemes with `--stage-*`. SVG only — honours prefers-reduced-motion.
27
+ * rethemes with `--stage-*`. SVG only, honours prefers-reduced-motion.
28
28
  */
29
29
  const W = 440, H = 250;
30
30
  const xL = 60, xR = 380, yT = 80, yB = 172;
@@ -36,7 +36,7 @@ const GRAPH = {
36
36
  h: 44
37
37
  };
38
38
  const clamp01 = (v) => Math.max(0, Math.min(1, v));
39
- function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startCharged = false, title = "Charging & leaking a capacitor", prompt = "Charge it up, then flip to “leak” — watch the field thin and Vc decay.", objectives, hints = [] }) {
39
+ function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startCharged = false, title = "Charging & leaking a capacitor", prompt = "Charge it up, then flip to “leak”, watch the field thin and Vc decay.", objectives, hints = [] }) {
40
40
  const [V, setV] = useState(emf);
41
41
  const [R, setR] = useState(rK);
42
42
  const [C, setC] = useState(capU);
@@ -67,6 +67,11 @@ function CapacitorLeakLab({ emf = 6, rK = 10, capU = 100, leakK = 200, startChar
67
67
  const charging = mode === "charge" && q < .995;
68
68
  const leaking = mode === "leak" && q > .01;
69
69
  const hint = useHints(hints);
70
+ useCheckpoint({
71
+ solved: mode === "leak" && q <= .05,
72
+ activity: `capacitor-leak:${title}`,
73
+ hintsUsed: hint.count
74
+ });
70
75
  const sampleArr = rate.current.samples;
71
76
  const trace = sampleArr.length > 1 ? sampleArr.map((s, i) => {
72
77
  const x = GRAPH.x + i / (sampleArr.length - 1) * GRAPH.w;
@@ -3,6 +3,7 @@
3
3
  import { num } from "../../core/util.mjs";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { StageAssetDefs, registerAsset, useCoords } from "@classytic/stage";
6
+ import { solveDC } from "@classytic/stage/circuit";
6
7
 
7
8
  //#region src/circuits/circuit/asset.tsx
8
9
  const TYPE = {
@@ -16,6 +17,72 @@ const XR = 3.2;
16
17
  const ROW_GAP = 1.5;
17
18
  const RETURN_DROP = 2.2;
18
19
  const numOr = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : typeof v === "boolean" ? v ? 1 : 0 : d;
20
+ /**
21
+ * Solve the branch-list network through the ONE circuit engine (@classytic/stage/circuit
22
+ * MNA): parallel branches between the left bus (node 1) and the ground return (node 0),
23
+ * each a series chain with its own internal nodes; closed switch = near-zero R, open
24
+ * branch = omitted. Returns the totals + per-branch current read back from node voltages.
25
+ */
26
+ function solveNetwork(raw, nBranch, emf, internalR) {
27
+ const elems = [];
28
+ let node = 2;
29
+ if (internalR > 1e-9) {
30
+ const bn = node++;
31
+ elems.push({
32
+ kind: "V",
33
+ n1: bn,
34
+ n2: 0,
35
+ value: emf,
36
+ id: "batt"
37
+ });
38
+ elems.push({
39
+ kind: "R",
40
+ n1: bn,
41
+ n2: 1,
42
+ value: internalR
43
+ });
44
+ } else elems.push({
45
+ kind: "V",
46
+ n1: 1,
47
+ n2: 0,
48
+ value: emf,
49
+ id: "batt"
50
+ });
51
+ const branchOf = (b) => raw.filter((r) => r.branch === b).sort((a, c) => a.pos - c.pos);
52
+ const first = [];
53
+ for (let b = 0; b < nBranch; b++) {
54
+ const chain = branchOf(b);
55
+ if (chain.length === 0 || chain.some((r) => r.type === "switch" && !r.closed)) {
56
+ first[b] = null;
57
+ continue;
58
+ }
59
+ let prev = 1;
60
+ let f = null;
61
+ chain.forEach((r, idx) => {
62
+ const nb = idx === chain.length - 1 ? 0 : node++;
63
+ const R = r.type === "switch" ? 1e-6 : Math.max(1e-9, r.ohms);
64
+ elems.push({
65
+ kind: "R",
66
+ n1: prev,
67
+ n2: nb,
68
+ value: R
69
+ });
70
+ if (!f) f = {
71
+ a: prev,
72
+ b: nb,
73
+ R
74
+ };
75
+ prev = nb;
76
+ });
77
+ first[b] = f;
78
+ }
79
+ const sol = solveDC(elems);
80
+ const V = sol.nodeV;
81
+ return {
82
+ Itotal: Math.abs(sol.current["batt"] ?? 0),
83
+ branchI: first.map((f) => f ? Math.abs(((V[f.a] ?? 0) - (V[f.b] ?? 0)) / f.R) : 0)
84
+ };
85
+ }
19
86
  function resolver({ params, bound }) {
20
87
  const nComp = Math.max(0, Math.round(num(params.nComp, 0)));
21
88
  const nBranch = Math.max(1, Math.round(num(params.nBranch, 1)));
@@ -40,16 +107,7 @@ function resolver({ params, bound }) {
40
107
  });
41
108
  }
42
109
  const branchOf = (b) => raw.filter((r) => r.branch === b).sort((a, c) => a.pos - c.pos);
43
- const branchR = [];
44
- for (let b = 0; b < nBranch; b++) {
45
- const comps = branchOf(b);
46
- branchR[b] = comps.some((r) => r.type === "switch" && !r.closed) ? Infinity : comps.reduce((s, r) => s + (r.type === "switch" ? 0 : r.ohms), 0);
47
- }
48
- const invSum = branchR.reduce((s, R) => s + (Number.isFinite(R) && R > 0 ? 1 / R : Number.isFinite(R) ? 1e9 : 0), 0);
49
- const Rpar = invSum > 0 ? 1 / invSum : Infinity;
50
- const Rtot = Number.isFinite(Rpar) ? Rpar + internalR : Infinity;
51
- const Itotal = Number.isFinite(Rtot) && Rtot > 1e-9 ? emf / Rtot : 0;
52
- const Vbranch = emf - Itotal * internalR;
110
+ const { Itotal, branchI } = solveNetwork(raw, nBranch, emf, internalR);
53
111
  const loopH = (nBranch - 1) * ROW_GAP + RETURN_DROP;
54
112
  const yTop = loopH / 2;
55
113
  const yReturn = -loopH / 2;
@@ -58,7 +116,7 @@ function resolver({ params, bound }) {
58
116
  for (let b = 0; b < nBranch; b++) {
59
117
  const yb = yTop - b * ROW_GAP;
60
118
  const chain = branchOf(b);
61
- const Ib = Number.isFinite(branchR[b]) && branchR[b] > 0 ? Vbranch / branchR[b] : Number.isFinite(branchR[b]) ? Itotal : 0;
119
+ const Ib = branchI[b] ?? 0;
62
120
  const m = chain.length;
63
121
  chain.forEach((r, idx) => {
64
122
  const x = m === 1 ? 0 : -2.1 + (XR - PADX - -2.1) * (idx / (m - 1));
@@ -115,7 +173,6 @@ function resolver({ params, bound }) {
115
173
  ];
116
174
  for (let b = 0; b < nBranch; b++) {
117
175
  const yb = yTop - b * ROW_GAP;
118
- const Ib = Number.isFinite(branchR[b]) && branchR[b] > 0 ? Vbranch / branchR[b] : 0;
119
176
  wires.push({
120
177
  pts: [{
121
178
  x: XL,
@@ -124,7 +181,7 @@ function resolver({ params, bound }) {
124
181
  x: XR,
125
182
  y: yb
126
183
  }],
127
- energized: Ib > 1e-6
184
+ energized: (branchI[b] ?? 0) > 1e-6
128
185
  });
129
186
  }
130
187
  const bulbs = comps.filter((c) => c.type === "bulb");
@@ -148,7 +205,7 @@ function resolver({ params, bound }) {
148
205
  wires,
149
206
  emf,
150
207
  Itotal,
151
- Rtot: Number.isFinite(Rtot) ? Rtot : -1,
208
+ Rtot: Itotal > 1e-12 ? emf / Itotal : -1,
152
209
  solved,
153
210
  flowDur,
154
211
  energized: railEnergized
@@ -10,7 +10,7 @@ import { Scene, controlsFromScene, isAssetGeom, registerAsset, resolve, useContr
10
10
 
11
11
  //#region src/circuits/circuit/preset.tsx
12
12
  /**
13
- * Circuit network — a SceneDoc FACTORY on @classytic/stage. A creator declares a
13
+ * Circuit network, a SceneDoc FACTORY on @classytic/stage. A creator declares a
14
14
  * battery + parallel BRANCHES (each a series chain of resistor/bulb/switch); the
15
15
  * learner closes switches and tunes the battery to hit a goal (light a bulb /
16
16
  * reach a target current / light them all). EMF + each switch are FREE scalars
@@ -134,7 +134,12 @@ function CircuitNetworkLab(props) {
134
134
  12,
135
135
  1
136
136
  ], controlId, height = 360, prompt = "Close the switch and power the circuit." } = props;
137
- const { editor, doc } = useEditor(useMemo(() => circuitDoc(props), [JSON.stringify(props)]));
137
+ const { editor, doc } = useEditor(useMemo(() => circuitDoc(props), [JSON.stringify({
138
+ emf: props.emf,
139
+ internalR: props.internalR,
140
+ branches: props.branches,
141
+ goal: props.goal
142
+ })]));
138
143
  const resolved = resolve(doc);
139
144
  const { switches } = useMemo(() => flatten(branches), [branches]);
140
145
  const geom = resolved.values.get("circuit");
@@ -176,6 +181,8 @@ function CircuitNetworkLab(props) {
176
181
  solved: meta.solved,
177
182
  activity: "circuit-network"
178
183
  });
184
+ const switchSummary = switches.length ? switches.map((s) => `${s.label} ${Number(resolved.values.get(s.id) ?? 0) >= .5 ? "closed" : "open"}`).join(", ") : "no switches";
185
+ const figureLabel = `Circuit diagram. ${meta.solved ? "Powered, goal reached" : "Not yet powered"}. Battery ${emf} volts. ${switchSummary}. ${prompt}`;
179
186
  const figure = /* @__PURE__ */ jsxs(Fragment$1, { children: [
180
187
  /* @__PURE__ */ jsx(LabStyles, {}),
181
188
  /* @__PURE__ */ jsx(Scene, {
@@ -184,15 +191,26 @@ function CircuitNetworkLab(props) {
184
191
  showGrid: false,
185
192
  showAxes: false,
186
193
  height,
187
- ariaLabel: prompt
194
+ ariaLabel: figureLabel
188
195
  }),
189
196
  /* @__PURE__ */ jsx(LiveRegion, { children: meta.solved ? "Circuit powered, goal reached." : `Current ${(meta.Itotal * 1e3).toFixed(0)} milliamps.` })
190
197
  ] });
191
198
  const controlsUi = /* @__PURE__ */ jsxs(ControlBar, { children: [switches.map((s) => {
192
199
  const closed = Number(resolved.values.get(s.id) ?? 0) >= .5;
200
+ const flip = () => toggle(s.id);
193
201
  return /* @__PURE__ */ jsxs(Chip, {
194
202
  selected: closed,
195
- onClick: () => toggle(s.id),
203
+ onClick: flip,
204
+ role: "button",
205
+ tabIndex: 0,
206
+ "aria-pressed": closed,
207
+ "aria-label": `toggle ${s.label} (currently ${closed ? "closed" : "open"})`,
208
+ onKeyDown: (e) => {
209
+ if (e.key === "Enter" || e.key === " ") {
210
+ e.preventDefault();
211
+ flip();
212
+ }
213
+ },
196
214
  children: [
197
215
  s.label,
198
216
  ": ",
@@ -208,7 +226,7 @@ function CircuitNetworkLab(props) {
208
226
  max: emfMax,
209
227
  step: emfStep,
210
228
  onChange: setEmf,
211
- ariaLabel: "battery voltage",
229
+ ariaLabel: `battery voltage, ${emf} volts`,
212
230
  style: { width: 120 }
213
231
  })
214
232
  })] });