@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
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { clamp } from "../../core/util.mjs";
|
|
4
|
+
import { Callout, LabFrame } from "../../kit/frame.mjs";
|
|
5
|
+
import { useCheckpoint } from "../../kit/pedagogy.mjs";
|
|
6
|
+
import { LabAsk } from "../../kit/ask.mjs";
|
|
7
|
+
import { CoordPlane, num } from "../../kit/coords.mjs";
|
|
8
|
+
import { useEffect, useRef, useState } from "react";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { Dot, Label, MovableDot, Plot, Segment, compileExpr } from "@classytic/stage";
|
|
11
|
+
|
|
12
|
+
//#region src/math/domain-range/preset.tsx
|
|
13
|
+
/**
|
|
14
|
+
* DomainRangeLab, domain & range as SHADOWS. The big idea students miss is that
|
|
15
|
+
* domain/range aren't formulas to memorise; they're what you SEE when you let the
|
|
16
|
+
* curve cast two shadows:
|
|
17
|
+
*
|
|
18
|
+
* • shine a light from ABOVE → the curve's shadow on the x-axis is the DOMAIN
|
|
19
|
+
* (every input the function actually accepts), and
|
|
20
|
+
* • shine a light from the SIDE → the shadow on the y-axis is the RANGE
|
|
21
|
+
* (every output it can produce).
|
|
22
|
+
*
|
|
23
|
+
* On top of that, a "feed the machine" game: drag the input probe along the
|
|
24
|
+
* x-axis, it turns GREEN when the machine accepts the input (in the domain) and
|
|
25
|
+
* RED "undefined" when it doesn't (a pole like 1/(x−2), a √ of a negative, or an
|
|
26
|
+
* author-set restriction). So the SAME lab teaches every domain TYPE just by
|
|
27
|
+
* changing the expression: x² (range ≥ 0), √x (x ≥ 0), 1/x (x ≠ 0), √(9−x²)
|
|
28
|
+
* (the semicircle: domain [−3,3], range [0,3]), or a restricted interval.
|
|
29
|
+
*
|
|
30
|
+
* Built on the shared CoordPlane + the stage expr engine; authorable via props
|
|
31
|
+
* (equation, an optional domain restriction, a checked question).
|
|
32
|
+
*/
|
|
33
|
+
const C_DOMAIN = "var(--stage-accent)";
|
|
34
|
+
const C_RANGE = "var(--stage-accent-2)";
|
|
35
|
+
const C_OK = "var(--stage-good)";
|
|
36
|
+
const C_BAD = "var(--stage-danger)";
|
|
37
|
+
const N = 1200;
|
|
38
|
+
/** Contiguous covered intervals of a sorted value set (split where the gap exceeds `gap`). */
|
|
39
|
+
function coveredIntervals(values, gap) {
|
|
40
|
+
const v = values.filter(Number.isFinite).sort((a, b) => a - b);
|
|
41
|
+
if (!v.length) return [];
|
|
42
|
+
const out = [];
|
|
43
|
+
let lo = v[0], prev = v[0];
|
|
44
|
+
for (let i = 1; i < v.length; i++) {
|
|
45
|
+
const x = v[i];
|
|
46
|
+
if (x - prev > gap) {
|
|
47
|
+
out.push([lo, prev]);
|
|
48
|
+
lo = x;
|
|
49
|
+
}
|
|
50
|
+
prev = x;
|
|
51
|
+
}
|
|
52
|
+
out.push([lo, prev]);
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
/** Sort + merge overlapping/adjacent intervals. */
|
|
56
|
+
function mergeIntervals(iv) {
|
|
57
|
+
const v = iv.filter((x) => x != null).sort((a, b) => a[0] - b[0]);
|
|
58
|
+
const out = [];
|
|
59
|
+
for (const [a, b] of v) {
|
|
60
|
+
const last = out[out.length - 1];
|
|
61
|
+
if (last && a <= last[1] + 1e-6) last[1] = Math.max(last[1], b);
|
|
62
|
+
else out.push([a, b]);
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
const fmtIntervals = (rs, eps) => rs.length ? rs.map(([a, b]) => b - a < eps ? `{${num(a)}}` : `[${num(a)}, ${num(b)}]`).join(" ∪ ") : ", ";
|
|
67
|
+
function DomainRangeLab({ equation = "sqrt(9 - x^2)", xRange = [-6, 6], yRange = "auto", restrict, probe, title = "Domain and range: the two shadows", prompt = "Drag the input probe: green = the machine accepts it (in the domain), red = undefined. The blue strip is every allowed input; the orange strip is every output.", ask, height = 400, activity = "domain-range" } = {}) {
|
|
68
|
+
const [x0, x1] = xRange;
|
|
69
|
+
const compiled = (() => {
|
|
70
|
+
const c = compileExpr(equation);
|
|
71
|
+
return c.error !== void 0 ? null : c;
|
|
72
|
+
})();
|
|
73
|
+
const inRestrict = (x) => !restrict || x >= restrict[0] - 1e-9 && x <= restrict[1] + 1e-9;
|
|
74
|
+
const f = (x) => compiled && inRestrict(x) ? compiled.fn({ x }) : NaN;
|
|
75
|
+
const dx = (x1 - x0) / N;
|
|
76
|
+
const pts = [];
|
|
77
|
+
for (let i = 0; i <= N; i++) {
|
|
78
|
+
const x = x0 + i * dx;
|
|
79
|
+
const y = f(x);
|
|
80
|
+
if (Number.isFinite(y)) pts.push([x, y]);
|
|
81
|
+
}
|
|
82
|
+
const [yMin, yMax] = (() => {
|
|
83
|
+
if (yRange !== "auto") return yRange;
|
|
84
|
+
if (!pts.length) return [-6, 6];
|
|
85
|
+
const s = pts.map((p) => p[1]).sort((a, b) => a - b);
|
|
86
|
+
const lo = Math.min(0, s[Math.floor(s.length * .02)] ?? -1);
|
|
87
|
+
const hi = Math.max(0, s[Math.floor(s.length * .98)] ?? 1);
|
|
88
|
+
const pad = Math.max(1, (hi - lo) * .12);
|
|
89
|
+
return [lo - pad, hi + pad];
|
|
90
|
+
})();
|
|
91
|
+
const yCap = Math.max(Math.abs(yMin), Math.abs(yMax)) * 3.5;
|
|
92
|
+
const domain = coveredIntervals(pts.filter(([, y]) => Math.abs(y) <= yCap).map(([x]) => x), dx * 2.5);
|
|
93
|
+
const range = mergeIntervals(domain.map(([a, b]) => {
|
|
94
|
+
let mn = Infinity, mx = -Infinity;
|
|
95
|
+
for (const [x, y] of pts) if (x >= a - 1e-9 && x <= b + 1e-9 && y >= yMin && y <= yMax) {
|
|
96
|
+
if (y < mn) mn = y;
|
|
97
|
+
if (y > mx) mx = y;
|
|
98
|
+
}
|
|
99
|
+
return Number.isFinite(mn) ? [mn, mx] : null;
|
|
100
|
+
}));
|
|
101
|
+
const [pxState, setPx] = useState(clamp(probe ?? (x0 + x1) / 2, x0, x1));
|
|
102
|
+
const pX = clamp(pxState, x0, x1);
|
|
103
|
+
const pY = f(pX);
|
|
104
|
+
const accepted = Number.isFinite(pY);
|
|
105
|
+
const visited = useRef({
|
|
106
|
+
min: pX,
|
|
107
|
+
max: pX
|
|
108
|
+
});
|
|
109
|
+
const [swept, setSwept] = useState(false);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const v = visited.current;
|
|
112
|
+
if (pX < v.min) v.min = pX;
|
|
113
|
+
if (pX > v.max) v.max = pX;
|
|
114
|
+
if (!swept && v.max - v.min >= (x1 - x0) * .6) setSwept(true);
|
|
115
|
+
}, [
|
|
116
|
+
pX,
|
|
117
|
+
swept,
|
|
118
|
+
x0,
|
|
119
|
+
x1
|
|
120
|
+
]);
|
|
121
|
+
useCheckpoint({
|
|
122
|
+
solved: swept,
|
|
123
|
+
activity
|
|
124
|
+
});
|
|
125
|
+
const figure = /* @__PURE__ */ jsxs(CoordPlane, {
|
|
126
|
+
view: {
|
|
127
|
+
xMin: x0,
|
|
128
|
+
xMax: x1,
|
|
129
|
+
yMin,
|
|
130
|
+
yMax
|
|
131
|
+
},
|
|
132
|
+
height,
|
|
133
|
+
preserveAspect: false,
|
|
134
|
+
ariaLabel: `Domain and range of ${equation}`,
|
|
135
|
+
children: [
|
|
136
|
+
compiled && /* @__PURE__ */ jsx(Plot.OfX, {
|
|
137
|
+
y: f,
|
|
138
|
+
color: "var(--stage-fg)",
|
|
139
|
+
weight: 2.5
|
|
140
|
+
}),
|
|
141
|
+
domain.map(([a, b], i) => /* @__PURE__ */ jsx(Segment, {
|
|
142
|
+
from: {
|
|
143
|
+
x: a,
|
|
144
|
+
y: 0
|
|
145
|
+
},
|
|
146
|
+
to: {
|
|
147
|
+
x: b,
|
|
148
|
+
y: 0
|
|
149
|
+
},
|
|
150
|
+
color: C_DOMAIN,
|
|
151
|
+
weight: 7
|
|
152
|
+
}, `d${i}`)),
|
|
153
|
+
domain.length > 0 && /* @__PURE__ */ jsx(Label, {
|
|
154
|
+
x: domain[0][0],
|
|
155
|
+
y: 0,
|
|
156
|
+
text: "domain",
|
|
157
|
+
color: C_DOMAIN,
|
|
158
|
+
size: 12,
|
|
159
|
+
dy: 18,
|
|
160
|
+
dx: 2,
|
|
161
|
+
anchor: "start"
|
|
162
|
+
}),
|
|
163
|
+
range.map(([a, b], i) => /* @__PURE__ */ jsx(Segment, {
|
|
164
|
+
from: {
|
|
165
|
+
x: 0,
|
|
166
|
+
y: a
|
|
167
|
+
},
|
|
168
|
+
to: {
|
|
169
|
+
x: 0,
|
|
170
|
+
y: b
|
|
171
|
+
},
|
|
172
|
+
color: C_RANGE,
|
|
173
|
+
weight: 7
|
|
174
|
+
}, `r${i}`)),
|
|
175
|
+
range.length > 0 && /* @__PURE__ */ jsx(Label, {
|
|
176
|
+
x: 0,
|
|
177
|
+
y: range[range.length - 1][1],
|
|
178
|
+
text: "range",
|
|
179
|
+
color: C_RANGE,
|
|
180
|
+
size: 12,
|
|
181
|
+
dx: 10,
|
|
182
|
+
anchor: "start"
|
|
183
|
+
}),
|
|
184
|
+
accepted ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
185
|
+
/* @__PURE__ */ jsx(Segment, {
|
|
186
|
+
from: {
|
|
187
|
+
x: pX,
|
|
188
|
+
y: 0
|
|
189
|
+
},
|
|
190
|
+
to: {
|
|
191
|
+
x: pX,
|
|
192
|
+
y: pY
|
|
193
|
+
},
|
|
194
|
+
color: C_OK,
|
|
195
|
+
weight: 1.5,
|
|
196
|
+
dashed: true
|
|
197
|
+
}),
|
|
198
|
+
/* @__PURE__ */ jsx(Segment, {
|
|
199
|
+
from: {
|
|
200
|
+
x: pX,
|
|
201
|
+
y: pY
|
|
202
|
+
},
|
|
203
|
+
to: {
|
|
204
|
+
x: 0,
|
|
205
|
+
y: pY
|
|
206
|
+
},
|
|
207
|
+
color: C_OK,
|
|
208
|
+
weight: 1.5,
|
|
209
|
+
dashed: true
|
|
210
|
+
}),
|
|
211
|
+
/* @__PURE__ */ jsx(Dot, {
|
|
212
|
+
x: pX,
|
|
213
|
+
y: pY,
|
|
214
|
+
r: 5,
|
|
215
|
+
color: C_OK
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx(Dot, {
|
|
218
|
+
x: 0,
|
|
219
|
+
y: pY,
|
|
220
|
+
r: 5,
|
|
221
|
+
color: C_RANGE
|
|
222
|
+
})
|
|
223
|
+
] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Segment, {
|
|
224
|
+
from: {
|
|
225
|
+
x: pX,
|
|
226
|
+
y: yMin
|
|
227
|
+
},
|
|
228
|
+
to: {
|
|
229
|
+
x: pX,
|
|
230
|
+
y: yMax
|
|
231
|
+
},
|
|
232
|
+
color: C_BAD,
|
|
233
|
+
weight: 1.5,
|
|
234
|
+
dashed: true
|
|
235
|
+
}), /* @__PURE__ */ jsx(Label, {
|
|
236
|
+
x: pX,
|
|
237
|
+
y: (yMin + yMax) / 2,
|
|
238
|
+
text: "undefined",
|
|
239
|
+
color: C_BAD,
|
|
240
|
+
size: 12,
|
|
241
|
+
dx: 8,
|
|
242
|
+
anchor: "start"
|
|
243
|
+
})] }),
|
|
244
|
+
/* @__PURE__ */ jsx(MovableDot, {
|
|
245
|
+
value: {
|
|
246
|
+
x: pX,
|
|
247
|
+
y: 0
|
|
248
|
+
},
|
|
249
|
+
onMove: (p) => setPx(clamp(p.x, x0, x1)),
|
|
250
|
+
constrain: "horizontal",
|
|
251
|
+
color: accepted ? C_OK : C_BAD,
|
|
252
|
+
ariaLabel: "input probe, drag along the x-axis"
|
|
253
|
+
})
|
|
254
|
+
]
|
|
255
|
+
});
|
|
256
|
+
return /* @__PURE__ */ jsx(LabFrame, {
|
|
257
|
+
title,
|
|
258
|
+
prompt,
|
|
259
|
+
aside: /* @__PURE__ */ jsxs("div", {
|
|
260
|
+
style: {
|
|
261
|
+
display: "flex",
|
|
262
|
+
flexDirection: "column",
|
|
263
|
+
gap: 10
|
|
264
|
+
},
|
|
265
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
266
|
+
className: "lab-pill",
|
|
267
|
+
"data-state": accepted ? "ok" : "no",
|
|
268
|
+
role: "status",
|
|
269
|
+
style: { alignSelf: "flex-start" },
|
|
270
|
+
children: accepted ? `✓ f(${num(pX)}) = ${num(pY)}, accepted` : `✗ x = ${num(pX)} is not in the domain`
|
|
271
|
+
}), /* @__PURE__ */ jsx(Callout, {
|
|
272
|
+
tone: "result",
|
|
273
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
274
|
+
style: {
|
|
275
|
+
display: "grid",
|
|
276
|
+
gap: 6,
|
|
277
|
+
fontVariantNumeric: "tabular-nums",
|
|
278
|
+
fontSize: 13
|
|
279
|
+
},
|
|
280
|
+
children: [
|
|
281
|
+
/* @__PURE__ */ jsxs("span", { children: ["f(x) = ", /* @__PURE__ */ jsx("strong", { children: equation })] }),
|
|
282
|
+
/* @__PURE__ */ jsxs("span", {
|
|
283
|
+
style: { color: C_DOMAIN },
|
|
284
|
+
children: ["domain: ", /* @__PURE__ */ jsx("strong", { children: fmtIntervals(domain, dx * 3) })]
|
|
285
|
+
}),
|
|
286
|
+
/* @__PURE__ */ jsxs("span", {
|
|
287
|
+
style: { color: C_RANGE },
|
|
288
|
+
children: ["range: ", /* @__PURE__ */ jsx("strong", { children: fmtIntervals(range, (yMax - yMin) * .05) })]
|
|
289
|
+
}),
|
|
290
|
+
restrict && /* @__PURE__ */ jsxs("span", {
|
|
291
|
+
style: { color: "var(--stage-muted)" },
|
|
292
|
+
children: [
|
|
293
|
+
"restricted to [",
|
|
294
|
+
num(restrict[0]),
|
|
295
|
+
", ",
|
|
296
|
+
num(restrict[1]),
|
|
297
|
+
"]"
|
|
298
|
+
]
|
|
299
|
+
})
|
|
300
|
+
]
|
|
301
|
+
})
|
|
302
|
+
})]
|
|
303
|
+
}),
|
|
304
|
+
footer: ask ? /* @__PURE__ */ jsx(LabAsk, {
|
|
305
|
+
ask,
|
|
306
|
+
activity
|
|
307
|
+
}) : void 0,
|
|
308
|
+
children: figure
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
//#endregion
|
|
313
|
+
export { DomainRangeLab };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { FractionBarLab, FractionBarProps } from "./preset.mjs";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/math/fraction-bar/preset.d.ts
|
|
4
|
+
interface FractionBarProps {
|
|
5
|
+
/** Number of equal parts the whole is cut into. Default 4. */
|
|
6
|
+
denom?: number;
|
|
7
|
+
/** Starting shaded parts. Default 0. */
|
|
8
|
+
num?: number;
|
|
9
|
+
/** Goal numerator; solved when that many parts are shaded. Omit to explore. */
|
|
10
|
+
target?: number;
|
|
11
|
+
/** If set, also show the fraction OF this quantity (k/n × whole). */
|
|
12
|
+
whole?: number;
|
|
13
|
+
unit?: string;
|
|
14
|
+
/** Second strip cut into this many parts, to show the equivalent fraction. */
|
|
15
|
+
compareDenom?: number;
|
|
16
|
+
/** Show the decimal + percent equivalents. Default true. */
|
|
17
|
+
showEquiv?: boolean;
|
|
18
|
+
/** Optional concrete twin (any level scene): the part-whole as a pie / jar / etc. */
|
|
19
|
+
scene?: string;
|
|
20
|
+
height?: number;
|
|
21
|
+
title?: string;
|
|
22
|
+
prompt?: string;
|
|
23
|
+
activity?: string;
|
|
24
|
+
}
|
|
25
|
+
declare function FractionBarLab(props?: FractionBarProps): ReactNode;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { FractionBarLab, FractionBarProps };
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { gcd, round } from "../../core/util.mjs";
|
|
4
|
+
import { StatusPill } from "../../kit/controls.mjs";
|
|
5
|
+
import { ControlBar, LabFrame } from "../../kit/frame.mjs";
|
|
6
|
+
import { useCheckpoint } from "../../kit/pedagogy.mjs";
|
|
7
|
+
import { getScene } from "../../kit/scenes.mjs";
|
|
8
|
+
import { BarStrip } from "../../kit/bar-strip.mjs";
|
|
9
|
+
import { useEffect, useState } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { MovableDot, Segment, Stage } from "@classytic/stage";
|
|
12
|
+
|
|
13
|
+
//#region src/math/fraction-bar/preset.tsx
|
|
14
|
+
/**
|
|
15
|
+
* FractionBarLab, the authorable PART-WHOLE / fraction manipulative: a strip is
|
|
16
|
+
* split into `denom` equal parts and the learner drags to shade `num` of them.
|
|
17
|
+
* The same shaded amount reads as a fraction, a decimal, a percent, and (when a
|
|
18
|
+
* `whole` is set) a concrete quantity, so k/n, 0.75, 75% and "15 of 20" are
|
|
19
|
+
* visibly ONE thing. An optional second strip at a different denominator makes
|
|
20
|
+
* EQUIVALENT fractions (¾ = 6⁄8) something you see by re-cutting the same length.
|
|
21
|
+
*
|
|
22
|
+
* One engine, many uses, all data: set denom, a target to shade, a whole+unit
|
|
23
|
+
* for "fraction of a quantity", or a compare denominator for equivalence. Built
|
|
24
|
+
* on the juiced <MovableDot> (snaps to the cell boundaries, live readout).
|
|
25
|
+
*/
|
|
26
|
+
function FractionBarLab(props = {}) {
|
|
27
|
+
const { denom = 4, target, whole, unit = "", compareDenom, showEquiv = true, scene, height = 240, title = "Fractions", prompt = target != null ? `Shade ${target}/${denom} of the strip.` : "Drag to shade the strip.", activity = "fraction-bar" } = props;
|
|
28
|
+
const n = Math.max(1, Math.round(denom));
|
|
29
|
+
const clampN = (k) => Math.max(0, Math.min(n, Math.round(k)));
|
|
30
|
+
const [num, setNum] = useState(clampN(props.num ?? 0));
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
setNum(clampN(props.num ?? 0));
|
|
33
|
+
}, [props.num, n]);
|
|
34
|
+
const solved = target != null && num === target;
|
|
35
|
+
const frac = num / n;
|
|
36
|
+
const g = gcd(num, n);
|
|
37
|
+
const simp = num > 0 && g > 1 ? `${num / g}/${n / g}` : null;
|
|
38
|
+
const fillColor = solved ? "var(--stage-good)" : "var(--stage-accent)";
|
|
39
|
+
useCheckpoint({
|
|
40
|
+
solved,
|
|
41
|
+
activity,
|
|
42
|
+
response: `${num}/${n}`
|
|
43
|
+
});
|
|
44
|
+
const hasCompare = compareDenom != null && compareDenom > 0;
|
|
45
|
+
const cmpShaded = hasCompare ? Math.round(frac * compareDenom) : 0;
|
|
46
|
+
const cmpExact = hasCompare ? Math.abs(frac * compareDenom - cmpShaded) < 1e-9 : false;
|
|
47
|
+
const Y_MAIN = hasCompare ? .75 : 0;
|
|
48
|
+
const Y_CMP = -.95;
|
|
49
|
+
const yMin = hasCompare ? -2.1 : -1.5;
|
|
50
|
+
const yMax = hasCompare ? 1.9 : 1.2;
|
|
51
|
+
const figure = /* @__PURE__ */ jsxs(Stage, {
|
|
52
|
+
view: {
|
|
53
|
+
xMin: -.55,
|
|
54
|
+
xMax: n + .55,
|
|
55
|
+
yMin,
|
|
56
|
+
yMax
|
|
57
|
+
},
|
|
58
|
+
height,
|
|
59
|
+
preserveAspect: false,
|
|
60
|
+
pad: 14,
|
|
61
|
+
ariaLabel: `Fraction strip showing ${num} of ${n} parts shaded`,
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsx(BarStrip, {
|
|
64
|
+
span: n,
|
|
65
|
+
cells: n,
|
|
66
|
+
shaded: num,
|
|
67
|
+
y: Y_MAIN,
|
|
68
|
+
color: fillColor
|
|
69
|
+
}),
|
|
70
|
+
target != null && !solved && /* @__PURE__ */ jsx(Segment, {
|
|
71
|
+
from: {
|
|
72
|
+
x: target,
|
|
73
|
+
y: Y_MAIN - .85
|
|
74
|
+
},
|
|
75
|
+
to: {
|
|
76
|
+
x: target,
|
|
77
|
+
y: Y_MAIN + .85
|
|
78
|
+
},
|
|
79
|
+
color: "var(--stage-good)",
|
|
80
|
+
weight: 1.75,
|
|
81
|
+
opacity: .6,
|
|
82
|
+
dashed: true
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ jsx(MovableDot, {
|
|
85
|
+
value: {
|
|
86
|
+
x: num,
|
|
87
|
+
y: Y_MAIN
|
|
88
|
+
},
|
|
89
|
+
onMove: (p) => setNum(clampN(p.x)),
|
|
90
|
+
constrain: "horizontal",
|
|
91
|
+
range: {
|
|
92
|
+
min: 0,
|
|
93
|
+
max: n
|
|
94
|
+
},
|
|
95
|
+
snap: 1,
|
|
96
|
+
step: 1,
|
|
97
|
+
readout: () => `${num}/${n}`,
|
|
98
|
+
color: fillColor,
|
|
99
|
+
r: 9,
|
|
100
|
+
ariaLabel: "fraction boundary"
|
|
101
|
+
}),
|
|
102
|
+
hasCompare && /* @__PURE__ */ jsx(BarStrip, {
|
|
103
|
+
span: n,
|
|
104
|
+
cells: compareDenom,
|
|
105
|
+
shaded: cmpShaded,
|
|
106
|
+
y: Y_CMP,
|
|
107
|
+
color: "var(--stage-accent)",
|
|
108
|
+
weight: 26
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
const controls = /* @__PURE__ */ jsxs(ControlBar, { children: [
|
|
113
|
+
/* @__PURE__ */ jsxs("span", {
|
|
114
|
+
style: {
|
|
115
|
+
fontWeight: 700,
|
|
116
|
+
fontSize: 17,
|
|
117
|
+
fontVariantNumeric: "tabular-nums"
|
|
118
|
+
},
|
|
119
|
+
children: [
|
|
120
|
+
num,
|
|
121
|
+
"/",
|
|
122
|
+
n
|
|
123
|
+
]
|
|
124
|
+
}),
|
|
125
|
+
hasCompare && cmpShaded > 0 && /* @__PURE__ */ jsxs("span", {
|
|
126
|
+
style: {
|
|
127
|
+
opacity: .85,
|
|
128
|
+
fontVariantNumeric: "tabular-nums"
|
|
129
|
+
},
|
|
130
|
+
children: [
|
|
131
|
+
"= ",
|
|
132
|
+
cmpShaded,
|
|
133
|
+
"/",
|
|
134
|
+
compareDenom,
|
|
135
|
+
cmpExact ? "" : " (≈)"
|
|
136
|
+
]
|
|
137
|
+
}),
|
|
138
|
+
simp && /* @__PURE__ */ jsxs("span", {
|
|
139
|
+
style: { opacity: .75 },
|
|
140
|
+
children: ["= ", simp]
|
|
141
|
+
}),
|
|
142
|
+
showEquiv && /* @__PURE__ */ jsxs("span", {
|
|
143
|
+
style: {
|
|
144
|
+
opacity: .75,
|
|
145
|
+
fontVariantNumeric: "tabular-nums"
|
|
146
|
+
},
|
|
147
|
+
children: [
|
|
148
|
+
"= ",
|
|
149
|
+
round(frac),
|
|
150
|
+
" = ",
|
|
151
|
+
round(frac * 100),
|
|
152
|
+
"%"
|
|
153
|
+
]
|
|
154
|
+
}),
|
|
155
|
+
whole != null && /* @__PURE__ */ jsxs("span", {
|
|
156
|
+
style: {
|
|
157
|
+
opacity: .85,
|
|
158
|
+
fontVariantNumeric: "tabular-nums"
|
|
159
|
+
},
|
|
160
|
+
children: [
|
|
161
|
+
"= ",
|
|
162
|
+
round(frac * whole),
|
|
163
|
+
unit ? ` ${unit}` : "",
|
|
164
|
+
" of ",
|
|
165
|
+
whole
|
|
166
|
+
]
|
|
167
|
+
}),
|
|
168
|
+
target != null && /* @__PURE__ */ jsx(StatusPill, {
|
|
169
|
+
ok: solved,
|
|
170
|
+
children: solved ? `✓ ${target}/${n}` : `shade ${target}/${n}`
|
|
171
|
+
})
|
|
172
|
+
] });
|
|
173
|
+
const twin = scene && scene !== "none" ? getScene(scene)?.render({
|
|
174
|
+
frac,
|
|
175
|
+
guessTone: solved ? "ok" : "idle",
|
|
176
|
+
color: fillColor,
|
|
177
|
+
label: `${num}/${n}`,
|
|
178
|
+
width: 132,
|
|
179
|
+
height: 170
|
|
180
|
+
}) : null;
|
|
181
|
+
return /* @__PURE__ */ jsx(LabFrame, {
|
|
182
|
+
title,
|
|
183
|
+
prompt,
|
|
184
|
+
controls,
|
|
185
|
+
aside: twin ? /* @__PURE__ */ jsx("div", {
|
|
186
|
+
style: {
|
|
187
|
+
display: "grid",
|
|
188
|
+
placeItems: "center"
|
|
189
|
+
},
|
|
190
|
+
children: twin
|
|
191
|
+
}) : void 0,
|
|
192
|
+
children: figure
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//#endregion
|
|
197
|
+
export { FractionBarLab };
|
|
@@ -9,7 +9,7 @@ import { Label, Polygon, Segment, Stage } from "@classytic/stage";
|
|
|
9
9
|
|
|
10
10
|
//#region src/math/function-machine/preset.tsx
|
|
11
11
|
/**
|
|
12
|
-
* Function machine
|
|
12
|
+
* Function machine, a "predict the rule" interactive (Brilliant-style), built
|
|
13
13
|
* on @classytic/stage: inputs → outputs with index-matched connectors, a rule
|
|
14
14
|
* chip, multiple-choice rules, and a Check that reports to the learner seam. A
|
|
15
15
|
* GENERAL tool: a creator passes any inputs/outputs/choices/answer.
|
|
@@ -165,7 +165,7 @@ function FunctionMachineLab({ prompt = "Which rule produces these outputs?", inp
|
|
|
165
165
|
}),
|
|
166
166
|
result === "wrong" && /* @__PURE__ */ jsx(StatusPill, {
|
|
167
167
|
ok: false,
|
|
168
|
-
children: "Not quite
|
|
168
|
+
children: "Not quite, try another rule"
|
|
169
169
|
})
|
|
170
170
|
] }),
|
|
171
171
|
footer: /* @__PURE__ */ jsx(LiveRegion, { children: result === "correct" ? "Correct." : result === "wrong" ? "Incorrect, try again." : "" }),
|
|
@@ -10,22 +10,22 @@ import { CanvasLayer, compileExpr, differentiate, evaluate, simplify, toLatex, u
|
|
|
10
10
|
|
|
11
11
|
//#region src/math/gradient-descent.tsx
|
|
12
12
|
/**
|
|
13
|
-
* GradientDescent
|
|
13
|
+
* GradientDescent, the calculus that powers machine learning, made visible.
|
|
14
14
|
*
|
|
15
15
|
* Plots a 2-variable "loss surface" f(x, y) as a heatmap, then walks downhill by
|
|
16
16
|
* the rule that trains every neural net: step opposite the gradient,
|
|
17
17
|
* (x, y) ← (x, y) − lr · ∇f, ∇f = [∂f/∂x, ∂f/∂y].
|
|
18
18
|
*
|
|
19
|
-
* The gradient is the engine's EXACT symbolic differentiator
|
|
20
|
-
* `differentiate(ast, 'x')` and `differentiate(ast, 'y')
|
|
19
|
+
* The gradient is the engine's EXACT symbolic differentiator ,
|
|
20
|
+
* `differentiate(ast, 'x')` and `differentiate(ast, 'y')`, proving the scalar
|
|
21
21
|
* expr engine already does multivariable partials (numerical fallback otherwise).
|
|
22
22
|
*
|
|
23
23
|
* This is a genuine HIGH-ELEMENT-COUNT figure (a per-pixel-cell heatmap), so it
|
|
24
24
|
* renders on the engine's `<CanvasLayer>` (zero-dep raw Canvas2D, HiDPI, shares
|
|
25
|
-
* the coordinate system + clock) instead of one SVG node per cell
|
|
25
|
+
* the coordinate system + clock) instead of one SVG node per cell, and instead
|
|
26
26
|
* of a heavy GPU dependency. Everything ELSE (controls, KaTeX, theming) is the
|
|
27
27
|
* same kit every other lab uses. Drag the start point, tune the rate, watch it
|
|
28
|
-
* converge
|
|
28
|
+
* converge, or diverge.
|
|
29
29
|
*/
|
|
30
30
|
const VIRIDIS = [
|
|
31
31
|
[
|
|
@@ -360,7 +360,7 @@ function GradientDescent({ equation = "x^2 + 2*y^2", range = [-3, 3], start = [2
|
|
|
360
360
|
children: [
|
|
361
361
|
"“",
|
|
362
362
|
equation,
|
|
363
|
-
"
|
|
363
|
+
"”, ",
|
|
364
364
|
model.error
|
|
365
365
|
]
|
|
366
366
|
})]
|
|
@@ -18,7 +18,7 @@ interface GrapherProps {
|
|
|
18
18
|
params?: GraphParam[];
|
|
19
19
|
xRange?: [number, number];
|
|
20
20
|
yRange?: [number, number] | 'auto';
|
|
21
|
-
/** `log` plots log₁₀(y) with decade ticks
|
|
21
|
+
/** `log` plots log₁₀(y) with decade ticks, for exponentials/rates. */
|
|
22
22
|
yScale?: 'linear' | 'log';
|
|
23
23
|
title?: string;
|
|
24
24
|
subtitle?: string;
|
|
@@ -8,11 +8,11 @@ import { Label, Plot, Segment, Stage, compileExpr } from "@classytic/stage";
|
|
|
8
8
|
|
|
9
9
|
//#region src/math/grapher/preset.tsx
|
|
10
10
|
/**
|
|
11
|
-
* Grapher
|
|
11
|
+
* Grapher, a creator-authored equation/function plotter on the @classytic/stage
|
|
12
12
|
* engine. A creator types one or more formulas in `x` (and named params), optionally
|
|
13
13
|
* exposes params as sliders, and gets a clean auto-scaled multi-curve plot.
|
|
14
14
|
*
|
|
15
|
-
* Framed, labelled axes (NOT through-origin) so it reads cleanly for ANY window
|
|
15
|
+
* Framed, labelled axes (NOT through-origin) so it reads cleanly for ANY window ,
|
|
16
16
|
* including off-origin ranges like x∈[250,400] where a 0-axis would sit off-screen.
|
|
17
17
|
* Supports a LOG y-scale: essential for exponentials (e.g. Arrhenius rate ∝ e^(−Eₐ/RT)),
|
|
18
18
|
* where a linear axis collapses the curve onto the baseline but a log axis makes it a
|
|
@@ -40,7 +40,7 @@ function niceTicks(min, max, target = 6) {
|
|
|
40
40
|
for (let v = Math.ceil(min / step) * step; v <= max + step * 1e-6; v += step) out.push(Math.abs(v) < step * 1e-6 ? 0 : v);
|
|
41
41
|
return out;
|
|
42
42
|
}
|
|
43
|
-
/** Integer (decade) ticks for a log axis
|
|
43
|
+
/** Integer (decade) ticks for a log axis, falls back to nice ticks for a sub-decade window. */
|
|
44
44
|
function decadeTicks(min, max) {
|
|
45
45
|
const lo = Math.ceil(min - 1e-9), hi = Math.floor(max + 1e-9);
|
|
46
46
|
const out = [];
|
|
@@ -297,7 +297,7 @@ function Grapher({ equations, params = [], xRange = [-6.5, 6.5], yRange = "auto"
|
|
|
297
297
|
children: errors.map((e, i) => /* @__PURE__ */ jsxs("div", { children: [
|
|
298
298
|
"“",
|
|
299
299
|
e.expr,
|
|
300
|
-
"
|
|
300
|
+
"”, ",
|
|
301
301
|
e.error
|
|
302
302
|
] }, i))
|
|
303
303
|
})] });
|
|
@@ -11,19 +11,19 @@ import { Axes, Dot, Grid, Label, Plot, Segment, Stage, Vector } from "@classytic
|
|
|
11
11
|
|
|
12
12
|
//#region src/math/harmonic-form/preset.tsx
|
|
13
13
|
/**
|
|
14
|
-
* HarmonicFormLab
|
|
14
|
+
* HarmonicFormLab, "two waves are secretly one": a cos x + b sin x = R cos(x + α).
|
|
15
15
|
*
|
|
16
16
|
* The whole insight is that adding a cosine and a sine of the SAME frequency gives
|
|
17
|
-
* a SINGLE shifted cosine
|
|
17
|
+
* a SINGLE shifted cosine, and you can SEE why with phasors. The cos term is a
|
|
18
18
|
* vector of length a along the axis; the sin term is a vector of length b at a
|
|
19
19
|
* right angle to it (sin lags cos by 90°). Add them tip-to-tail and the resultant
|
|
20
|
-
* has length R = √(a²+b²) at angle
|
|
20
|
+
* has length R = √(a²+b²) at angle α, exactly the amplitude and phase of the one
|
|
21
21
|
* combined wave. Drag a and b: the phasor triangle and the three waves update live,
|
|
22
22
|
* and the messy two-wave sum visibly collapses onto one clean R cos(x + α).
|
|
23
23
|
*
|
|
24
24
|
* This builds the INTUITION for the auxiliary-angle form (Edexcel "express in the
|
|
25
25
|
* form R cos(x+α)"). The exact R and α arithmetic is left to written working / a
|
|
26
|
-
* paired derivation
|
|
26
|
+
* paired derivation, the lab is the picture, not the algebra.
|
|
27
27
|
*
|
|
28
28
|
* Convention: a cos x + b sin x = R cos(x + α) ⇒ a = R cos α, b = −R sin α, so
|
|
29
29
|
* α = atan2(−b, a) and the resultant phasor is (a, −b). Tokenized SVG; accessible.
|
|
@@ -71,7 +71,7 @@ const HARMONIC_CHALLENGE = [{
|
|
|
71
71
|
}
|
|
72
72
|
],
|
|
73
73
|
answer: "up",
|
|
74
|
-
explain: "R = √(a² + b²) is the hypotenuse
|
|
74
|
+
explain: "R = √(a² + b²) is the hypotenuse, growing either coefficient lengthens it."
|
|
75
75
|
}];
|
|
76
76
|
/** LaTeX for "a cos x ± b sin x", tidy for ±1 / 0 coefficients. */
|
|
77
77
|
function lhsTex(a, b) {
|
|
@@ -369,7 +369,7 @@ function HarmonicFormLab({ a: a0 = 4, b: b0 = -3, title = "Express a cos x + b s
|
|
|
369
369
|
/* @__PURE__ */ jsx(Tex$1, { tex: "R=\\sqrt{a^2+b^2}" }),
|
|
370
370
|
" and it peaks at ",
|
|
371
371
|
/* @__PURE__ */ jsx(Tex$1, { tex: "x=-\\alpha" }),
|
|
372
|
-
"
|
|
372
|
+
", the phasor's length and angle."
|
|
373
373
|
]
|
|
374
374
|
}),
|
|
375
375
|
/* @__PURE__ */ jsx(ChallengeCard, {
|