@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.
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/biology/enzyme-rate/preset.mjs +5 -5
- package/dist/biology/genetic-cross/core.d.mts +7 -7
- package/dist/biology/genetic-cross/core.mjs +4 -4
- package/dist/biology/genetic-cross/grid.mjs +132 -123
- package/dist/biology/genetic-cross/preset.mjs +4 -4
- package/dist/biology/genetic-cross/sex-linked.mjs +7 -7
- package/dist/biology/photosynthesis-factors/preset.mjs +8 -8
- package/dist/biology/respiration/preset.mjs +4 -4
- package/dist/biology/sequence/central-dogma.mjs +5 -5
- package/dist/biology/sequence/core.d.mts +6 -6
- package/dist/biology/sequence/core.mjs +1 -1
- package/dist/biology/sequence/preset.mjs +6 -6
- package/dist/blocks/authoring.mjs +5 -5
- package/dist/blocks/biology.d.mts +2 -2
- package/dist/blocks/biology.mjs +5 -5
- package/dist/blocks/chem.d.mts +2 -2
- package/dist/blocks/chem.mjs +13 -13
- package/dist/blocks/circuits.d.mts +293 -4
- package/dist/blocks/circuits.mjs +874 -9
- package/dist/blocks/discrete.d.mts +30 -2
- package/dist/blocks/discrete.mjs +74 -4
- package/dist/blocks/economics.mjs +1 -1
- package/dist/blocks/geography.mjs +1 -1
- package/dist/blocks/geometry.mjs +3 -3
- package/dist/blocks/ict.d.mts +90 -1
- package/dist/blocks/ict.mjs +217 -7
- package/dist/blocks/index.d.mts +3064 -657
- package/dist/blocks/index.mjs +9 -9
- package/dist/blocks/lab-block.mjs +5 -5
- package/dist/blocks/lab-config.d.mts +1 -1
- package/dist/blocks/lab-config.mjs +4 -4
- package/dist/blocks/lab-gallery.d.mts +1 -1
- package/dist/blocks/lab-gallery.mjs +2 -2
- package/dist/blocks/language.d.mts +6 -6
- package/dist/blocks/language.mjs +12 -12
- package/dist/blocks/lesson.mjs +4 -4
- package/dist/blocks/math.d.mts +577 -11
- package/dist/blocks/math.mjs +1648 -14
- package/dist/blocks/ml.d.mts +45 -1
- package/dist/blocks/ml.mjs +80 -6
- package/dist/blocks/physics.d.mts +9 -4
- package/dist/blocks/physics.mjs +75 -28
- package/dist/blocks/statistics.mjs +1 -1
- package/dist/build/CircuitEditor.d.mts +14 -0
- package/dist/build/CircuitEditor.mjs +787 -0
- package/dist/build/CircuitPlayer.d.mts +19 -0
- package/dist/build/CircuitPlayer.mjs +53 -0
- package/dist/build/CircuitScene.d.mts +61 -0
- package/dist/build/CircuitScene.mjs +383 -0
- package/dist/build/contract.d.mts +116 -0
- package/dist/build/editor-ops.d.mts +65 -0
- package/dist/build/editor-ops.mjs +306 -0
- package/dist/build/editor-ui.mjs +121 -0
- package/dist/build/flow.d.mts +14 -0
- package/dist/build/flow.mjs +119 -0
- package/dist/build/index.d.mts +10 -0
- package/dist/build/index.mjs +10 -0
- package/dist/build/parts/ammeter.d.mts +1 -0
- package/dist/build/parts/ammeter.mjs +32 -0
- package/dist/build/parts/bulb.d.mts +1 -0
- package/dist/build/parts/bulb.mjs +50 -0
- package/dist/build/parts/capacitor.d.mts +1 -0
- package/dist/build/parts/capacitor.mjs +26 -0
- package/dist/build/parts/cell.d.mts +1 -0
- package/dist/build/parts/cell.mjs +40 -0
- package/dist/build/parts/diode.d.mts +1 -0
- package/dist/build/parts/diode.mjs +33 -0
- package/dist/build/parts/index.d.mts +5 -0
- package/dist/build/parts/index.mjs +43 -0
- package/dist/build/parts/mosfet.d.mts +1 -0
- package/dist/build/parts/mosfet.mjs +95 -0
- package/dist/build/parts/node.d.mts +1 -0
- package/dist/build/parts/node.mjs +32 -0
- package/dist/build/parts/resistor.d.mts +1 -0
- package/dist/build/parts/resistor.mjs +49 -0
- package/dist/build/parts/shared.mjs +42 -0
- package/dist/build/parts/switch.d.mts +1 -0
- package/dist/build/parts/switch.mjs +34 -0
- package/dist/build/parts.d.mts +1 -0
- package/dist/build/registry.d.mts +9 -0
- package/dist/build/registry.mjs +15 -0
- package/dist/build/solve.d.mts +8 -0
- package/dist/build/solve.mjs +0 -0
- package/dist/catalog/registry.d.mts +2 -2
- package/dist/catalog/templates.d.mts +1 -1
- package/dist/catalog/templates.mjs +6 -6
- package/dist/chem/battery.mjs +1 -1
- package/dist/chem/bohr-atom.mjs +4 -4
- package/dist/chem/diffusion/preset.mjs +4 -4
- package/dist/chem/electrochem/preset.mjs +5 -5
- package/dist/chem/equilibrium/preset.d.mts +1 -1
- package/dist/chem/equilibrium/preset.mjs +6 -6
- package/dist/chem/gas-box/preset.mjs +6 -6
- package/dist/chem/kinetics/preset.mjs +6 -6
- package/dist/chem/periodic-trends/preset.mjs +7 -7
- package/dist/chem/reaction-lab.mjs +3 -3
- package/dist/chem/reaction-profile.mjs +4 -4
- package/dist/chem/solution/dilution.mjs +6 -6
- package/dist/chem/solution/field.d.mts +2 -2
- package/dist/chem/solution/field.mjs +2 -2
- package/dist/chem/solution/solution-box.mjs +7 -7
- package/dist/chem/stoichiometry/preset.mjs +5 -5
- package/dist/chem/titration/preset.mjs +5 -5
- package/dist/circuits/ac-dc/asset.mjs +1 -1
- package/dist/circuits/ac-dc/preset.mjs +2 -2
- package/dist/circuits/brownout/index.d.mts +1 -0
- package/dist/circuits/brownout/preset.d.mts +22 -0
- package/dist/circuits/brownout/preset.mjs +399 -0
- package/dist/circuits/capacitor-leak/preset.mjs +13 -8
- package/dist/circuits/circuit/asset.mjs +71 -14
- package/dist/circuits/circuit/preset.mjs +23 -5
- package/dist/circuits/circuit-builder.mjs +60 -132
- package/dist/circuits/circuit-lab.mjs +60 -40
- package/dist/circuits/cmos-gate/index.d.mts +1 -0
- package/dist/circuits/cmos-gate/preset.d.mts +75 -0
- package/dist/circuits/cmos-gate/preset.mjs +1491 -0
- package/dist/circuits/diode/index.d.mts +1 -0
- package/dist/circuits/diode/preset.d.mts +25 -0
- package/dist/circuits/diode/preset.mjs +266 -0
- package/dist/circuits/index.d.mts +7 -1
- package/dist/circuits/index.mjs +7 -1
- package/dist/circuits/rc-charging/index.d.mts +1 -0
- package/dist/circuits/rc-charging/preset.d.mts +27 -0
- package/dist/circuits/rc-charging/preset.mjs +329 -0
- package/dist/circuits/semiconductor/index.d.mts +1 -0
- package/dist/circuits/semiconductor/preset.d.mts +102 -0
- package/dist/circuits/semiconductor/preset.mjs +1855 -0
- package/dist/circuits/transistor/index.d.mts +1 -0
- package/dist/circuits/transistor/preset.d.mts +27 -0
- package/dist/circuits/transistor/preset.mjs +329 -0
- package/dist/commerce/accounting/core.d.mts +1 -1
- package/dist/commerce/accounting/equation-balance.mjs +5 -5
- package/dist/commerce/accounting/journal-poster.mjs +8 -8
- package/dist/commerce/accounting/statement-sorter.mjs +4 -4
- package/dist/commerce/economics/core.d.mts +2 -2
- package/dist/commerce/economics/core.mjs +1 -1
- package/dist/commerce/economics/demand-shift-vs-move.mjs +6 -6
- package/dist/commerce/economics/elasticity-revenue.mjs +6 -6
- package/dist/commerce/economics/market-equilibrium.mjs +5 -5
- package/dist/core/easing.d.mts +3 -3
- package/dist/core/easing.mjs +2 -2
- package/dist/core/numeric.d.mts +3 -3
- package/dist/core/numeric.mjs +2 -2
- package/dist/core/reactive.d.mts +1 -1
- package/dist/core/reactive.mjs +1 -1
- package/dist/core/rng.d.mts +2 -2
- package/dist/core/rng.mjs +1 -1
- package/dist/core/tex.mjs +2 -2
- package/dist/core/timeline.d.mts +1 -1
- package/dist/core/timeline.mjs +1 -1
- package/dist/core/util.mjs +11 -1
- package/dist/discrete/arrangements/preset.mjs +6 -14
- package/dist/discrete/bayes/preset.mjs +43 -35
- package/dist/discrete/binomial/preset.mjs +2 -2
- package/dist/discrete/combination-studio/figure.d.mts +6 -0
- package/dist/discrete/combination-studio/figure.mjs +159 -0
- package/dist/discrete/combination-studio/index.d.mts +2 -0
- package/dist/discrete/combination-studio/preset.d.mts +44 -0
- package/dist/discrete/combination-studio/preset.mjs +440 -0
- package/dist/discrete/core/combinatorics.d.mts +23 -3
- package/dist/discrete/core/combinatorics.mjs +38 -3
- package/dist/discrete/core/pigeonhole.d.mts +1 -1
- package/dist/discrete/core/pigeonhole.mjs +1 -1
- package/dist/discrete/core/probability.d.mts +3 -3
- package/dist/discrete/core/probability.mjs +3 -3
- package/dist/discrete/core/sets.d.mts +1 -1
- package/dist/discrete/counting-slots/preset.mjs +8 -8
- package/dist/discrete/counting-tree/preset.mjs +65 -8
- package/dist/discrete/expected-value/preset.mjs +13 -13
- package/dist/discrete/hypergeometric/preset.mjs +48 -15
- package/dist/discrete/index.d.mts +4 -2
- package/dist/discrete/index.mjs +4 -2
- package/dist/discrete/karnaugh/preset.mjs +26 -20
- package/dist/discrete/lln/preset.mjs +44 -3
- package/dist/discrete/logic-circuit/preset.mjs +2 -2
- package/dist/discrete/monte-carlo/preset.d.mts +1 -1
- package/dist/discrete/monte-carlo/preset.mjs +14 -14
- package/dist/discrete/monty-hall/preset.mjs +6 -6
- package/dist/discrete/outcome-builder/preset.mjs +3 -3
- package/dist/discrete/pascal/preset.mjs +37 -7
- package/dist/discrete/rules.d.mts +20 -0
- package/dist/discrete/rules.mjs +264 -0
- package/dist/discrete/sample-space/preset.mjs +4 -4
- package/dist/discrete/selection/preset.mjs +7 -13
- package/dist/discrete/truth-table/preset.mjs +32 -9
- package/dist/discrete/venn/preset.mjs +71 -48
- package/dist/geography/cycle-lab/preset.mjs +17 -10
- package/dist/geography/cycles.d.mts +3 -3
- package/dist/geography/cycles.mjs +3 -3
- package/dist/geometry/board/preset.d.mts +2 -0
- package/dist/geometry/board/preset.mjs +11 -15
- package/dist/geometry/builder.mjs +3 -3
- package/dist/ict/number-systems/base-odometer.mjs +4 -4
- package/dist/ict/number-systems/bit-grouper.d.mts +1 -1
- package/dist/ict/number-systems/bit-grouper.mjs +4 -4
- package/dist/ict/number-systems/place-value-dial.d.mts +1 -1
- package/dist/ict/number-systems/place-value-dial.mjs +3 -3
- package/dist/ict/number-systems/wheel.d.mts +3 -3
- package/dist/ict/number-systems/wheel.mjs +4 -4
- package/dist/kit/annotate.mjs +3 -3
- package/dist/kit/answer-check.d.mts +2 -2
- package/dist/kit/answer-check.mjs +34 -6
- package/dist/kit/ask.d.mts +19 -0
- package/dist/kit/ask.mjs +46 -0
- package/dist/kit/bar-strip.mjs +53 -0
- package/dist/kit/calc.d.mts +33 -0
- package/dist/kit/calc.mjs +27 -0
- package/dist/kit/carrier-engine.mjs +147 -0
- package/dist/kit/clue-scene.d.mts +86 -0
- package/dist/kit/clue-scene.mjs +424 -0
- package/dist/kit/cluster.d.mts +30 -0
- package/dist/kit/cluster.mjs +81 -0
- package/dist/kit/controls.mjs +11 -5
- package/dist/kit/coords.d.mts +88 -0
- package/dist/kit/coords.mjs +192 -0
- package/dist/kit/data-scene.d.mts +27 -0
- package/dist/kit/data-scene.mjs +199 -0
- package/dist/kit/diagram.mjs +111 -50
- package/dist/kit/electronics.mjs +552 -60
- package/dist/kit/expr-analysis.d.mts +18 -6
- package/dist/kit/expr-analysis.mjs +82 -28
- package/dist/kit/frame.d.mts +3 -3
- package/dist/kit/frame.mjs +25 -6
- package/dist/kit/gameshow.mjs +2 -2
- package/dist/kit/index.d.mts +14 -2
- package/dist/kit/index.mjs +13 -1
- package/dist/kit/logic-gates.mjs +246 -47
- package/dist/kit/palette.mjs +26 -0
- package/dist/kit/pedagogy.d.mts +4 -4
- package/dist/kit/pedagogy.mjs +21 -17
- package/dist/kit/play.d.mts +1 -1
- package/dist/kit/play.mjs +3 -3
- package/dist/kit/predict.d.mts +55 -0
- package/dist/kit/predict.mjs +146 -0
- package/dist/kit/receipt.d.mts +29 -0
- package/dist/kit/receipt.mjs +94 -0
- package/dist/kit/rich.mjs +2 -2
- package/dist/kit/rule.d.mts +59 -0
- package/dist/kit/rule.mjs +215 -0
- package/dist/kit/scale.mjs +1 -1
- package/dist/kit/scene-library.d.mts +22 -0
- package/dist/kit/scene-library.mjs +311 -0
- package/dist/kit/scene-studio.d.mts +14 -0
- package/dist/kit/scene-studio.mjs +338 -0
- package/dist/kit/scenes.d.mts +31 -0
- package/dist/kit/scenes.mjs +569 -0
- package/dist/kit/slot-fill.d.mts +61 -0
- package/dist/kit/slot-fill.mjs +207 -0
- package/dist/kit/solve.d.mts +21 -0
- package/dist/kit/solve.mjs +75 -0
- package/dist/kit/space.mjs +5 -5
- package/dist/kit/steps.mjs +2 -2
- package/dist/kit/vessel.d.mts +69 -0
- package/dist/kit/vessel.mjs +191 -0
- package/dist/language/agreement/preset.mjs +2 -2
- package/dist/language/article-lens/preset.d.mts +1 -1
- package/dist/language/article-lens/preset.mjs +8 -8
- package/dist/language/deck.d.mts +3 -3
- package/dist/language/deck.mjs +1 -1
- package/dist/language/preposition-scene/preset.d.mts +2 -2
- package/dist/language/preposition-scene/preset.mjs +5 -5
- package/dist/language/sentence-builder/preset.mjs +5 -5
- package/dist/language/transform/preset.d.mts +2 -2
- package/dist/language/transform/preset.mjs +5 -5
- package/dist/language/ui.d.mts +3 -3
- package/dist/language/ui.mjs +4 -4
- package/dist/language/word-match/preset.mjs +3 -3
- package/dist/logic/LogicBuildLab.d.mts +22 -0
- package/dist/logic/LogicBuildLab.mjs +170 -0
- package/dist/logic/LogicEditScene.d.mts +31 -0
- package/dist/logic/LogicEditScene.mjs +276 -0
- package/dist/logic/LogicEditor.d.mts +14 -0
- package/dist/logic/LogicEditor.mjs +413 -0
- package/dist/logic/LogicScene.d.mts +32 -0
- package/dist/logic/LogicScene.mjs +277 -0
- package/dist/logic/contract.d.mts +72 -0
- package/dist/logic/display.d.mts +24 -0
- package/dist/logic/display.mjs +127 -0
- package/dist/logic/edit-ops.d.mts +44 -0
- package/dist/logic/edit-ops.mjs +177 -0
- package/dist/logic/evaluate.d.mts +11 -0
- package/dist/logic/evaluate.mjs +93 -0
- package/dist/logic/gates.d.mts +10 -0
- package/dist/logic/gates.mjs +73 -0
- package/dist/logic/index.d.mts +14 -0
- package/dist/logic/index.mjs +13 -0
- package/dist/logic/lab.d.mts +32 -0
- package/dist/logic/lab.mjs +160 -0
- package/dist/logic/presets.d.mts +12 -0
- package/dist/logic/presets.mjs +241 -0
- package/dist/logic/registry.d.mts +9 -0
- package/dist/logic/registry.mjs +15 -0
- package/dist/math/area-model/preset.mjs +70 -44
- package/dist/math/balance-algebra/preset.mjs +14 -5
- package/dist/math/broken-tree/index.d.mts +1 -0
- package/dist/math/broken-tree/preset.d.mts +26 -0
- package/dist/math/broken-tree/preset.mjs +435 -0
- package/dist/math/circle/index.d.mts +1 -0
- package/dist/math/circle/preset.d.mts +44 -0
- package/dist/math/circle/preset.mjs +198 -0
- package/dist/math/complex/core.d.mts +93 -0
- package/dist/math/complex/core.mjs +239 -0
- package/dist/math/complex/index.d.mts +3 -0
- package/dist/math/complex/preset.d.mts +31 -0
- package/dist/math/complex/preset.mjs +377 -0
- package/dist/math/complex/rules.d.mts +6 -0
- package/dist/math/complex/rules.mjs +121 -0
- package/dist/math/conic/index.d.mts +1 -0
- package/dist/math/conic/preset.d.mts +30 -0
- package/dist/math/conic/preset.mjs +334 -0
- package/dist/math/derivation.mjs +5 -5
- package/dist/math/derivative-explorer/preset.mjs +5 -5
- package/dist/math/domain-range/index.d.mts +1 -0
- package/dist/math/domain-range/preset.d.mts +33 -0
- package/dist/math/domain-range/preset.mjs +313 -0
- package/dist/math/fraction-bar/index.d.mts +1 -0
- package/dist/math/fraction-bar/preset.d.mts +27 -0
- package/dist/math/fraction-bar/preset.mjs +197 -0
- package/dist/math/function-machine/preset.mjs +2 -2
- package/dist/math/gradient-descent.mjs +6 -6
- package/dist/math/grapher/preset.d.mts +1 -1
- package/dist/math/grapher/preset.mjs +4 -4
- package/dist/math/harmonic-form/preset.mjs +6 -6
- package/dist/math/index.d.mts +27 -2
- package/dist/math/index.mjs +27 -2
- package/dist/math/integral-explorer/preset.mjs +2 -2
- package/dist/math/interactive/preset.mjs +3 -3
- package/dist/math/limit-explorer/preset.mjs +4 -4
- package/dist/math/linear-model/index.d.mts +1 -0
- package/dist/math/linear-model/preset.d.mts +53 -0
- package/dist/math/linear-model/preset.mjs +164 -0
- package/dist/math/linear-system/preset.mjs +4 -4
- package/dist/math/mystery-bucket/preset.mjs +6 -6
- package/dist/math/number-line/preset.mjs +3 -2
- package/dist/math/parabola/preset.mjs +4 -3
- package/dist/math/pattern/preset.mjs +7 -13
- package/dist/math/percent-bar/index.d.mts +1 -0
- package/dist/math/percent-bar/preset.d.mts +37 -0
- package/dist/math/percent-bar/preset.mjs +275 -0
- package/dist/math/poly/core.d.mts +50 -0
- package/dist/math/poly/core.mjs +268 -0
- package/dist/math/poly/index.d.mts +3 -0
- package/dist/math/poly/preset.d.mts +23 -0
- package/dist/math/poly/preset.mjs +141 -0
- package/dist/math/poly/steps.d.mts +10 -0
- package/dist/math/poly/steps.mjs +99 -0
- package/dist/math/rate-machine/index.d.mts +1 -0
- package/dist/math/rate-machine/preset.d.mts +35 -0
- package/dist/math/rate-machine/preset.mjs +281 -0
- package/dist/math/ratio-share/index.d.mts +1 -0
- package/dist/math/ratio-share/preset.d.mts +24 -0
- package/dist/math/ratio-share/preset.mjs +204 -0
- package/dist/math/receipt/index.d.mts +1 -0
- package/dist/math/receipt/preset.d.mts +22 -0
- package/dist/math/receipt/preset.mjs +137 -0
- package/dist/math/sequence-predict/index.d.mts +1 -0
- package/dist/math/sequence-predict/preset.d.mts +34 -0
- package/dist/math/sequence-predict/preset.mjs +130 -0
- package/dist/math/straight-line/index.d.mts +1 -0
- package/dist/math/straight-line/preset.d.mts +37 -0
- package/dist/math/straight-line/preset.mjs +374 -0
- package/dist/math/system-solve/index.d.mts +1 -0
- package/dist/math/system-solve/preset.d.mts +21 -0
- package/dist/math/system-solve/preset.mjs +227 -0
- package/dist/math/transform/index.d.mts +1 -0
- package/dist/math/transform/preset.d.mts +41 -0
- package/dist/math/transform/preset.mjs +343 -0
- package/dist/math/triangle-trig/preset.mjs +12 -9
- package/dist/math/trig/core.d.mts +37 -0
- package/dist/math/trig/core.mjs +150 -0
- package/dist/math/trig/diagrams.d.mts +1 -0
- package/dist/math/trig/diagrams.mjs +321 -0
- package/dist/math/trig/index.d.mts +3 -0
- package/dist/math/trig/preset.d.mts +25 -0
- package/dist/math/trig/preset.mjs +260 -0
- package/dist/math/trig/rules.d.mts +6 -0
- package/dist/math/trig/rules.mjs +159 -0
- package/dist/math/trig-explorer.mjs +4 -4
- package/dist/ml/boundary/preset.mjs +8 -3
- package/dist/ml/classifier/preset.mjs +31 -6
- package/dist/ml/kmeans/preset.mjs +4 -4
- package/dist/ml/knn/preset.mjs +47 -12
- package/dist/ml/regression/preset.mjs +36 -7
- package/dist/physics/atwood/preset.mjs +4 -4
- package/dist/physics/bullet-walls/preset.d.mts +1 -1
- package/dist/physics/bullet-walls/preset.mjs +7 -7
- package/dist/physics/carnot/preset.mjs +6 -6
- package/dist/physics/circular-motion/preset.mjs +36 -5
- package/dist/physics/collision-track/preset.mjs +35 -5
- package/dist/physics/efficiency/preset.d.mts +2 -2
- package/dist/physics/efficiency/preset.mjs +5 -5
- package/dist/physics/electric-field/preset.mjs +32 -23
- package/dist/physics/electric-flux/index.d.mts +1 -0
- package/dist/physics/electric-flux/preset.d.mts +29 -0
- package/dist/physics/electric-flux/preset.mjs +264 -0
- package/dist/physics/energy-skate/preset.mjs +5 -5
- package/dist/physics/entropy/preset.mjs +7 -7
- package/dist/physics/expansion/preset.mjs +13 -13
- package/dist/physics/exponential/asset.mjs +1 -1
- package/dist/physics/exponential/preset.mjs +4 -4
- package/dist/physics/gas-process/preset.mjs +3 -3
- package/dist/physics/gauss-law/index.d.mts +1 -0
- package/dist/physics/gauss-law/preset.d.mts +20 -0
- package/dist/physics/gauss-law/preset.mjs +286 -0
- package/dist/physics/gravitation/preset.mjs +7 -7
- package/dist/physics/gravity-drop.mjs +4 -4
- package/dist/physics/heat-transfer/preset.d.mts +1 -1
- package/dist/physics/heat-transfer/preset.mjs +10 -10
- package/dist/physics/impulse/preset.mjs +5 -5
- package/dist/physics/index.d.mts +4 -1
- package/dist/physics/index.mjs +4 -1
- package/dist/physics/kepler/preset.mjs +4 -4
- package/dist/physics/lever/preset.mjs +3 -3
- package/dist/physics/lorentz/preset.mjs +11 -11
- package/dist/physics/magnetism/preset.mjs +3 -3
- package/dist/physics/optics/preset.mjs +2 -2
- package/dist/physics/orbit-lab.mjs +5 -5
- package/dist/physics/projectile-lab.mjs +4 -4
- package/dist/physics/rain-relative/preset.mjs +5 -5
- package/dist/physics/ramp-forces/preset.mjs +5 -5
- package/dist/physics/river-boat.mjs +6 -6
- package/dist/physics/shm/preset.mjs +9 -9
- package/dist/physics/stopping-distance/preset.mjs +3 -3
- package/dist/physics/temperature-scales/preset.mjs +105 -116
- package/dist/physics/terminal-velocity/preset.mjs +5 -5
- package/dist/physics/thermal/preset.mjs +5 -5
- package/dist/physics/vector-board/preset.mjs +7 -6
- package/dist/physics/vector-scene.mjs +2 -2
- package/dist/physics/vector-types/preset.mjs +37 -3
- package/dist/physics/water-density/preset.mjs +12 -12
- package/dist/physics/waves/doppler.mjs +2 -2
- package/dist/physics/waves/preset.mjs +4 -4
- package/dist/physics/waves/ripple.mjs +6 -6
- package/dist/physics/waves/string.mjs +5 -5
- package/dist/physics/work-energy/preset.mjs +4 -4
- package/dist/physics/work-potential/index.d.mts +1 -0
- package/dist/physics/work-potential/preset.d.mts +20 -0
- package/dist/physics/work-potential/preset.mjs +276 -0
- package/dist/schemas/index.d.mts +6 -6
- package/dist/schemas/index.mjs +3 -3
- package/dist/statistics/center-spread/preset.mjs +3 -3
- package/dist/statistics/core/descriptive.d.mts +2 -2
- package/dist/statistics/core/descriptive.mjs +2 -2
- package/dist/statistics/core/normal.d.mts +3 -3
- package/dist/statistics/core/normal.mjs +3 -3
- package/dist/statistics/core/sequences.d.mts +1 -1
- package/dist/statistics/galton/preset.mjs +2 -2
- package/dist/statistics/histogram/preset.mjs +6 -6
- package/dist/statistics/normal/preset.mjs +2 -2
- package/dist/statistics/sampling/preset.mjs +4 -4
- package/dist/statistics/sequence/preset.mjs +58 -15
- package/dist/statistics/z-table/preset.mjs +17 -4
- package/package.json +11 -3
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
12
|
+
* ThermalExpansionLab, heat a solid and it grows. Drag the temperature and watch:
|
|
13
13
|
*
|
|
14
|
-
* • LENGTH ΔL = α·L·ΔT (a rod stretches
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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)
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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'] }
|
|
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
|
|
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
|
|
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
|
|
21
|
-
* top and sinks
|
|
22
|
-
* • RADIATION
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"
|
|
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
|
|
564
|
+
"EM waves, needs ",
|
|
565
565
|
/* @__PURE__ */ jsx("strong", {
|
|
566
566
|
style: { color: "var(--stage-fg)" },
|
|
567
567
|
children: "no medium"
|