@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
package/dist/core/easing.mjs
CHANGED
|
@@ -12,7 +12,7 @@ const easeInOut = (t) => t < .5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2;
|
|
|
12
12
|
const rushInto = (t) => 2 * smooth(t / 2);
|
|
13
13
|
/** Decelerate to rest (manim `rush_from`). */
|
|
14
14
|
const rushFrom = (t) => 2 * smooth(t / 2 + .5) - 1;
|
|
15
|
-
/** Go to 1 then back to 0 (manim `there_and_back`)
|
|
15
|
+
/** Go to 1 then back to 0 (manim `there_and_back`), great for pulses. */
|
|
16
16
|
const thereAndBack = (t) => smooth(t < .5 ? 2 * t : 2 * (1 - t));
|
|
17
17
|
/** Overshoot then settle. */
|
|
18
18
|
const elastic = (t) => {
|
|
@@ -49,7 +49,7 @@ function cubicBezier(x1, y1, x2, y2) {
|
|
|
49
49
|
function squish(fn, a = .2, b = .8) {
|
|
50
50
|
return (t) => t < a ? 0 : t > b ? 1 : fn((t - a) / (b - a));
|
|
51
51
|
}
|
|
52
|
-
/** Built-in registry
|
|
52
|
+
/** Built-in registry, extend with `registerEasing` (see ./registry). */
|
|
53
53
|
const EASINGS = {
|
|
54
54
|
linear,
|
|
55
55
|
smooth,
|
package/dist/core/numeric.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/core/numeric.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* numeric
|
|
3
|
+
* numeric, small numerical-calculus helpers, used when an exact symbolic result
|
|
4
4
|
* isn't available (e.g. a function the differentiator doesn't handle) or when a
|
|
5
5
|
* widget just needs a number. Pure, dependency-free.
|
|
6
6
|
*/
|
|
@@ -17,7 +17,7 @@ declare function sampleFunction(fn: RealFn, range: [number, number], samples?: n
|
|
|
17
17
|
/** Riemann sum of `fn` over `[a, b]` with `n` subintervals. A teaching estimate. */
|
|
18
18
|
declare function riemannSum(fn: RealFn, range: [number, number], n: number, mode?: 'left' | 'right' | 'mid'): number;
|
|
19
19
|
/**
|
|
20
|
-
* Composite Simpson's rule
|
|
20
|
+
* Composite Simpson's rule, a high-accuracy definite-integral estimate (error
|
|
21
21
|
* O(h⁴), vs O(h) for a Riemann sum). Used as the "reference" a Riemann sum
|
|
22
22
|
* converges toward. `n` is forced even. Not exact, but accurate to ~machine
|
|
23
23
|
* precision for smooth integrands at n≈1000.
|
|
@@ -26,7 +26,7 @@ declare function integrate(fn: RealFn, range: [number, number], n?: number): num
|
|
|
26
26
|
/**
|
|
27
27
|
* Estimate a one-sided limit of `fn` as x → c from `side` (+1 right, −1 left) by
|
|
28
28
|
* sampling a shrinking sequence of offsets. Returns the closest-in value and
|
|
29
|
-
* whether the sequence is *converging* (consecutive samples agree)
|
|
29
|
+
* whether the sequence is *converging* (consecutive samples agree), so callers
|
|
30
30
|
* can honestly report "estimated limit" + confidence rather than a hard claim.
|
|
31
31
|
*/
|
|
32
32
|
declare function estimateOneSidedLimit(fn: RealFn, c: number, side: 1 | -1): {
|
package/dist/core/numeric.mjs
CHANGED
|
@@ -32,7 +32,7 @@ function riemannSum(fn, range, n, mode = "mid") {
|
|
|
32
32
|
return sum * dx;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Composite Simpson's rule
|
|
35
|
+
* Composite Simpson's rule, a high-accuracy definite-integral estimate (error
|
|
36
36
|
* O(h⁴), vs O(h) for a Riemann sum). Used as the "reference" a Riemann sum
|
|
37
37
|
* converges toward. `n` is forced even. Not exact, but accurate to ~machine
|
|
38
38
|
* precision for smooth integrands at n≈1000.
|
|
@@ -48,7 +48,7 @@ function integrate(fn, range, n = 1e3) {
|
|
|
48
48
|
/**
|
|
49
49
|
* Estimate a one-sided limit of `fn` as x → c from `side` (+1 right, −1 left) by
|
|
50
50
|
* sampling a shrinking sequence of offsets. Returns the closest-in value and
|
|
51
|
-
* whether the sequence is *converging* (consecutive samples agree)
|
|
51
|
+
* whether the sequence is *converging* (consecutive samples agree), so callers
|
|
52
52
|
* can honestly report "estimated limit" + confidence rather than a hard claim.
|
|
53
53
|
*/
|
|
54
54
|
function estimateOneSidedLimit(fn, c, side) {
|
package/dist/core/reactive.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/core/reactive.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Tiny reactive value
|
|
3
|
+
* Tiny reactive value, the `ValueTracker` / signal at the heart of
|
|
4
4
|
* interactivity. A slider/drag updates a `value()`; anything derived from it
|
|
5
5
|
* recomputes; React components bound via `useValue` repaint. Framework-light
|
|
6
6
|
* (no external dep); the React glue is one hook.
|
package/dist/core/reactive.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { useEffect, useReducer, useRef } from "react";
|
|
|
2
2
|
|
|
3
3
|
//#region src/core/reactive.ts
|
|
4
4
|
/**
|
|
5
|
-
* Tiny reactive value
|
|
5
|
+
* Tiny reactive value, the `ValueTracker` / signal at the heart of
|
|
6
6
|
* interactivity. A slider/drag updates a `value()`; anything derived from it
|
|
7
7
|
* recomputes; React components bound via `useValue` repaint. Framework-light
|
|
8
8
|
* (no external dep); the React glue is one hook.
|
package/dist/core/rng.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/core/rng.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Seeded PRNG
|
|
3
|
+
* Seeded PRNG, deterministic randomness so a simulation is REPLAYABLE (same
|
|
4
4
|
* seed → same run; an agent can pin a seed, a lesson reproduces exactly, SSR /
|
|
5
5
|
* Remotion stays stable). mulberry32: tiny, fast, good enough for teaching. This
|
|
6
6
|
* is the canonical home (generic numerics live in core, per the shared-math rule);
|
|
@@ -15,7 +15,7 @@ declare function randInt(rng: Rng, lo: number, hi: number): number;
|
|
|
15
15
|
declare function shuffle<T>(arr: readonly T[], rng: Rng): T[];
|
|
16
16
|
/** Sample `k` distinct items (without replacement). */
|
|
17
17
|
declare function sample<T>(arr: readonly T[], k: number, rng: Rng): T[];
|
|
18
|
-
/** A normal (Gaussian) variate via Box–Muller
|
|
18
|
+
/** A normal (Gaussian) variate via Box–Muller, for sampling-distribution sims. */
|
|
19
19
|
declare function gaussian(rng: Rng, mu?: number, sigma?: number): number;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { Rng, gaussian, mulberry32, randInt, sample, shuffle };
|
package/dist/core/rng.mjs
CHANGED
|
@@ -27,7 +27,7 @@ function shuffle(arr, rng) {
|
|
|
27
27
|
function sample(arr, k, rng) {
|
|
28
28
|
return shuffle(arr, rng).slice(0, Math.max(0, Math.min(k, arr.length)));
|
|
29
29
|
}
|
|
30
|
-
/** A normal (Gaussian) variate via Box–Muller
|
|
30
|
+
/** A normal (Gaussian) variate via Box–Muller, for sampling-distribution sims. */
|
|
31
31
|
function gaussian(rng, mu = 0, sigma = 1) {
|
|
32
32
|
let u = 0, v = 0;
|
|
33
33
|
while (u === 0) u = rng();
|
package/dist/core/tex.mjs
CHANGED
|
@@ -6,11 +6,11 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
|
|
7
7
|
//#region src/core/tex.tsx
|
|
8
8
|
/**
|
|
9
|
-
* Tex
|
|
9
|
+
* Tex, render a LaTeX string with KaTeX AT RENDER TIME, so the markup is
|
|
10
10
|
* identical on the server and client: SSR/static exports show real maths (not raw
|
|
11
11
|
* `\cdot`/`\dfrac`), there's no raw-then-hydrate flash, and hydration matches.
|
|
12
12
|
*
|
|
13
|
-
* `katex` is a static import kept in this OWN module
|
|
13
|
+
* `katex` is a static import kept in this OWN module, stage/labs `neverBundle`
|
|
14
14
|
* leave it external, so only `<Tex>` importers pull it (the consumer resolves the
|
|
15
15
|
* optional peer; non-Tex consumers never bundle it). If `renderToString` throws on
|
|
16
16
|
* a malformed string we fall back to the raw LaTeX in a `<code>`. Pair with
|
package/dist/core/timeline.d.mts
CHANGED
|
@@ -27,7 +27,7 @@ interface Keyframe {
|
|
|
27
27
|
/**
|
|
28
28
|
* Pure multi-stage interpolation: build a `(t in [0,1]) => number` from
|
|
29
29
|
* keyframes. The manim-style way to express richer programmatic animation
|
|
30
|
-
* without a scheduler
|
|
30
|
+
* without a scheduler, drive `t` from `useTween`/`useFrameLoop`.
|
|
31
31
|
*/
|
|
32
32
|
declare function keyframes(frames: Keyframe[]): (t: number) => number;
|
|
33
33
|
//#endregion
|
package/dist/core/timeline.mjs
CHANGED
|
@@ -52,7 +52,7 @@ function useTween(opts) {
|
|
|
52
52
|
/**
|
|
53
53
|
* Pure multi-stage interpolation: build a `(t in [0,1]) => number` from
|
|
54
54
|
* keyframes. The manim-style way to express richer programmatic animation
|
|
55
|
-
* without a scheduler
|
|
55
|
+
* without a scheduler, drive `t` from `useTween`/`useFrameLoop`.
|
|
56
56
|
*/
|
|
57
57
|
function keyframes(frames) {
|
|
58
58
|
const ks = [...frames].sort((a, b) => a.at - b.at);
|
package/dist/core/util.mjs
CHANGED
|
@@ -13,6 +13,16 @@ function num(v, fallback) {
|
|
|
13
13
|
}
|
|
14
14
|
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
15
15
|
const lerp = (a, b, t) => a + (b - a) * t;
|
|
16
|
+
/** Round to `dp` decimal places (default 2), as a number. The shared rounding
|
|
17
|
+
* the part-whole bar labs (percent / fraction / ratio) all need for readouts. */
|
|
18
|
+
const round = (n, dp = 2) => Math.round(n * 10 ** dp) / 10 ** dp;
|
|
19
|
+
/** Greatest common divisor (Euclid), 0→1 so a ratio/fraction can always reduce. */
|
|
20
|
+
const gcd = (a, b) => {
|
|
21
|
+
a = Math.abs(a);
|
|
22
|
+
b = Math.abs(b);
|
|
23
|
+
while (b) [a, b] = [b, a % b];
|
|
24
|
+
return a || 1;
|
|
25
|
+
};
|
|
16
26
|
const DEG = Math.PI / 180;
|
|
17
27
|
/** Degrees → radians. */
|
|
18
28
|
const toRad = (deg) => deg * DEG;
|
|
@@ -28,4 +38,4 @@ function remap(x, inMin, inMax, outMin, outMax, doClamp = false) {
|
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
//#endregion
|
|
31
|
-
export { approxEq, clamp, cn, lerp, num, remap, toDeg, toRad };
|
|
41
|
+
export { approxEq, clamp, cn, gcd, lerp, num, remap, round, toDeg, toRad };
|
|
@@ -5,33 +5,25 @@ import { CheckButton, Chip, StatusPill, Stepper } from "../../kit/controls.mjs";
|
|
|
5
5
|
import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
|
|
6
6
|
import { HintLadder, RevealSolution, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
|
|
7
7
|
import { factorial, multinomial } from "../core/combinatorics.mjs";
|
|
8
|
+
import { CATEGORICAL } from "../../kit/palette.mjs";
|
|
8
9
|
import { useMemo, useState } from "react";
|
|
9
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
11
|
import { useControlSurface } from "@classytic/stage";
|
|
11
12
|
|
|
12
13
|
//#region src/discrete/arrangements/preset.tsx
|
|
13
14
|
/**
|
|
14
|
-
* ArrangementsLab
|
|
15
|
+
* ArrangementsLab, arranging things in a row when some are IDENTICAL (the multiset
|
|
15
16
|
* permutation the slots/selection labs don't cover). The classic MISSISSIPPI, or a
|
|
16
17
|
* row of coloured beads. The derivation, made concrete: if all n were distinct
|
|
17
18
|
* there'd be n! orders; but swapping two identical letters gives the SAME word, so
|
|
18
|
-
* each real arrangement is counted (count of that letter)! times
|
|
19
|
+
* each real arrangement is counted (count of that letter)! times, divide it out:
|
|
19
20
|
*
|
|
20
21
|
* n! / (n₁! · n₂! · …) (the multinomial coefficient)
|
|
21
22
|
*
|
|
22
23
|
* You watch two identical tiles swap into the same row (the overcount), then the
|
|
23
24
|
* formula falls out. Predict-then-check. Kernel = factorial / multinomial.
|
|
24
25
|
*/
|
|
25
|
-
const PALETTE =
|
|
26
|
-
"#1c7ed6",
|
|
27
|
-
"#e8590c",
|
|
28
|
-
"#2f9e44",
|
|
29
|
-
"#9c36b5",
|
|
30
|
-
"#e03131",
|
|
31
|
-
"#0ca678",
|
|
32
|
-
"#f59f00",
|
|
33
|
-
"#1098ad"
|
|
34
|
-
];
|
|
26
|
+
const PALETTE = CATEGORICAL;
|
|
35
27
|
function fromWord(w) {
|
|
36
28
|
const order = [], m = /* @__PURE__ */ new Map();
|
|
37
29
|
for (const ch of w.toUpperCase()) {
|
|
@@ -111,7 +103,7 @@ function ArrangementsLab({ word, items, title = "Arrange with repeats", prompt,
|
|
|
111
103
|
children: [
|
|
112
104
|
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("p", {
|
|
113
105
|
className: "lab-field-label",
|
|
114
|
-
children: [n, " items in a row
|
|
106
|
+
children: [n, " items in a row, identical ones share a colour"]
|
|
115
107
|
}), /* @__PURE__ */ jsx("div", {
|
|
116
108
|
style: {
|
|
117
109
|
display: "flex",
|
|
@@ -148,7 +140,7 @@ function ArrangementsLab({ word, items, title = "Arrange with repeats", prompt,
|
|
|
148
140
|
style: { color: swapGroup.color },
|
|
149
141
|
children: swapGroup.label
|
|
150
142
|
}),
|
|
151
|
-
"'s
|
|
143
|
+
"'s ⇄, it's the ",
|
|
152
144
|
/* @__PURE__ */ jsx("b", { children: "same row" }),
|
|
153
145
|
". So every arrangement is counted ",
|
|
154
146
|
swapGroup.count,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Chip, Slider } from "../../kit/controls.mjs";
|
|
4
4
|
import { Callout, ControlBar, Field, LabFrame } from "../../kit/frame.mjs";
|
|
5
|
-
import { HintLadder, RevealSolution, useHints } from "../../kit/pedagogy.mjs";
|
|
5
|
+
import { ChallengeCard, HintLadder, RevealSolution, useChallenge, useCheckpoint, useHints } from "../../kit/pedagogy.mjs";
|
|
6
6
|
import { bayes } from "../core/probability.mjs";
|
|
7
7
|
import { ProportionModel } from "../../kit/proportion.mjs";
|
|
8
8
|
import { FrequencyTree } from "../../kit/freq-tree.mjs";
|
|
@@ -14,8 +14,8 @@ import { SamplerCore } from "@classytic/stage/sim";
|
|
|
14
14
|
|
|
15
15
|
//#region src/discrete/bayes/preset.tsx
|
|
16
16
|
/**
|
|
17
|
-
* BayesLab
|
|
18
|
-
* THEORY (default): a 4-step walkthrough
|
|
17
|
+
* BayesLab, base-rate neglect, taught Brilliant-style: ONE idea at a time, big.
|
|
18
|
+
* THEORY (default): a 4-step walkthrough, (1) the rare population, (2) the test
|
|
19
19
|
* catches most sick people, (3) but also flags many healthy ones, (4) so a
|
|
20
20
|
* positive is usually a false alarm. Each step reveals one more layer of a large
|
|
21
21
|
* area model; the frequency tree + answer land on the last step.
|
|
@@ -28,11 +28,10 @@ const FALSEPOS = "var(--stage-warn, #e8a020)";
|
|
|
28
28
|
const MUTED = "var(--stage-muted)";
|
|
29
29
|
const pct = (x) => `${(x * 100).toFixed(x < .01 ? 2 : 1)}%`;
|
|
30
30
|
const r0 = (x) => Math.round(x);
|
|
31
|
-
function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, population = 1e3, conditionLabels = ["disease", "healthy"], testLabels = ["test +", "test −"], predict = false, title = "Bayes
|
|
31
|
+
function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, population = 1e3, conditionLabels = ["disease", "healthy"], testLabels = ["test +", "test −"], predict = false, title = "Bayes: the base-rate trap", prompt, objectives, hints: hintList, controlId }) {
|
|
32
32
|
const [p, setP] = useState(prior);
|
|
33
33
|
const [s, setS] = useState(sensitivity);
|
|
34
34
|
const [f, setF] = useState(falsePositive);
|
|
35
|
-
const [guess, setGuess] = useState(.5);
|
|
36
35
|
const [revealed, setRevealed] = useState(!predict);
|
|
37
36
|
const [mode, setMode] = useState("theory");
|
|
38
37
|
const [perStep, setPerStep] = useState(50);
|
|
@@ -43,6 +42,33 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
43
42
|
const posterior = bayes(s, p, f);
|
|
44
43
|
const [has, not] = conditionLabels, [pos] = testLabels;
|
|
45
44
|
const posShort = pos.replace("test ", "");
|
|
45
|
+
const predictQ = [{
|
|
46
|
+
id: "bayes-posterior",
|
|
47
|
+
prompt: `Of everyone who tests ${posShort}, roughly what fraction TRULY have the ${has}?`,
|
|
48
|
+
choices: [
|
|
49
|
+
{
|
|
50
|
+
value: "most",
|
|
51
|
+
label: "most of them"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
value: "about-half",
|
|
55
|
+
label: "about half"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
value: "small",
|
|
59
|
+
label: "only a small fraction"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
answer: "small",
|
|
63
|
+
explain: `Base-rate neglect: the ${has} is rare (prior ${pct(p)}), so even an accurate test produces far more false alarms than true positives, the posterior stays small.`
|
|
64
|
+
}];
|
|
65
|
+
const ch = useChallenge(predictQ);
|
|
66
|
+
if (predict && ch.allCorrect && !revealed) setRevealed(true);
|
|
67
|
+
useCheckpoint({
|
|
68
|
+
solved: ch.allCorrect,
|
|
69
|
+
activity: "bayes:predict",
|
|
70
|
+
hintsUsed: hints.count
|
|
71
|
+
});
|
|
46
72
|
const N = population;
|
|
47
73
|
const tp = N * p * s, fn = N * p * (1 - s), fp = N * (1 - p) * f, tn = N * (1 - p) * (1 - f);
|
|
48
74
|
const sampling = mode === "sample";
|
|
@@ -96,7 +122,7 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
96
122
|
useControlSurface(controlId, {
|
|
97
123
|
prevalence: {
|
|
98
124
|
type: "number",
|
|
99
|
-
label: "prior P(A)
|
|
125
|
+
label: "prior P(A): prevalence",
|
|
100
126
|
min: .001,
|
|
101
127
|
max: .5,
|
|
102
128
|
step: .001,
|
|
@@ -105,7 +131,7 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
105
131
|
},
|
|
106
132
|
sensitivity: {
|
|
107
133
|
type: "number",
|
|
108
|
-
label: "P(B|A)
|
|
134
|
+
label: "P(B|A): true-positive rate",
|
|
109
135
|
min: .5,
|
|
110
136
|
max: 1,
|
|
111
137
|
step: .01,
|
|
@@ -114,7 +140,7 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
114
140
|
},
|
|
115
141
|
falsePositive: {
|
|
116
142
|
type: "number",
|
|
117
|
-
label: "P(B|¬A)
|
|
143
|
+
label: "P(B|¬A): false-positive rate",
|
|
118
144
|
min: 0,
|
|
119
145
|
max: .5,
|
|
120
146
|
step: .01,
|
|
@@ -160,9 +186,9 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
160
186
|
count: dHea
|
|
161
187
|
}];
|
|
162
188
|
const captions = [
|
|
163
|
-
`Out of ${r0(N).toLocaleString()} people, only ${r0(tp + fn)} actually have the ${has}
|
|
189
|
+
`Out of ${r0(N).toLocaleString()} people, only ${r0(tp + fn)} actually have the ${has}, it's rare (${pct(p)}).`,
|
|
164
190
|
`The test is sensitive: of those ${r0(tp + fn)} sick people it catches ${r0(tp)} (and misses ${r0(fn)}).`,
|
|
165
|
-
`But the same test also flags ${r0(fp)} of the ${r0(fp + tn)} healthy people
|
|
191
|
+
`But the same test also flags ${r0(fp)} of the ${r0(fp + tn)} healthy people, false alarms.`,
|
|
166
192
|
`So ${r0(tp + fp)} test ${posShort}, yet only ${r0(tp)} are truly sick → a positive means just ${pct(posterior)}.`
|
|
167
193
|
];
|
|
168
194
|
const figure = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
@@ -257,29 +283,11 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
257
283
|
]
|
|
258
284
|
})
|
|
259
285
|
]
|
|
260
|
-
}) : /* @__PURE__ */
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
", what's the chance you actually have it?"
|
|
266
|
-
]
|
|
267
|
-
}), /* @__PURE__ */ jsxs(ControlBar, { children: [/* @__PURE__ */ jsx(Field, {
|
|
268
|
-
label: "your guess",
|
|
269
|
-
value: pct(guess),
|
|
270
|
-
children: /* @__PURE__ */ jsx(Slider, {
|
|
271
|
-
value: guess,
|
|
272
|
-
min: 0,
|
|
273
|
-
max: 1,
|
|
274
|
-
step: .01,
|
|
275
|
-
onChange: setGuess,
|
|
276
|
-
ariaLabel: "your guess"
|
|
277
|
-
})
|
|
278
|
-
}), /* @__PURE__ */ jsx(Chip, {
|
|
279
|
-
selected: false,
|
|
280
|
-
onClick: () => setRevealed(true),
|
|
281
|
-
children: "reveal"
|
|
282
|
-
})] })] })] }) : void 0,
|
|
286
|
+
}) : /* @__PURE__ */ jsx(ChallengeCard, {
|
|
287
|
+
questions: predictQ,
|
|
288
|
+
state: ch,
|
|
289
|
+
title: "Predict first"
|
|
290
|
+
})] }) : void 0,
|
|
283
291
|
controls: /* @__PURE__ */ jsxs(ControlBar, { children: [
|
|
284
292
|
/* @__PURE__ */ jsx(Field, {
|
|
285
293
|
label: "mode",
|
|
@@ -382,7 +390,7 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
382
390
|
posShort,
|
|
383
391
|
") = ",
|
|
384
392
|
pct(posterior),
|
|
385
|
-
"
|
|
393
|
+
", far below the test's accuracy, because the prior is only ",
|
|
386
394
|
pct(p),
|
|
387
395
|
"."
|
|
388
396
|
] }),
|
|
@@ -395,7 +403,7 @@ function BayesLab({ prior = .01, sensitivity = .9, falsePositive = .09, populati
|
|
|
395
403
|
});
|
|
396
404
|
}
|
|
397
405
|
/** The answer as a picture: of everyone who tests +, what red share truly has it.
|
|
398
|
-
* A bar of JUST the positive region (true-positive red | false-positive orange)
|
|
406
|
+
* A bar of JUST the positive region (true-positive red | false-positive orange) ,
|
|
399
407
|
* the posterior IS the red fraction, legible at any prior (unlike the 1%-wide
|
|
400
408
|
* column the area model degenerates to). minWidth keeps the red sliver visible. */
|
|
401
409
|
function PositiveBar({ tp, fp, pos, has }) {
|
|
@@ -11,9 +11,9 @@ import { useControlSurface } from "@classytic/stage";
|
|
|
11
11
|
|
|
12
12
|
//#region src/discrete/binomial/preset.tsx
|
|
13
13
|
/**
|
|
14
|
-
* BinomialDistributionLab
|
|
14
|
+
* BinomialDistributionLab, the bridge from counting to the bell. P(X=k successes
|
|
15
15
|
* in n trials) = C(n,k)·pᵏ·(1−p)ⁿ⁻ᵏ, drawn as bars you can interrogate: click a bar
|
|
16
|
-
* and the formula DERIVES itself
|
|
16
|
+
* and the formula DERIVES itself, k successes happen C(n,k) ways (the Pascal /
|
|
17
17
|
* counting number), each way has probability pᵏ for the successes times (1−p)ⁿ⁻ᵏ for
|
|
18
18
|
* the failures. Slide p to watch it skew and (at ½) turn symmetric; slide n and flip
|
|
19
19
|
* on the normal overlay to watch the binomial become the Galton-board bell. Mean np
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/discrete/combination-studio/figure.tsx
|
|
6
|
+
const SKIN = "#e8b98c";
|
|
7
|
+
/** A friendly stick-ish person who wears the chosen garments. */
|
|
8
|
+
function CharacterFigure({ parts, size = 64, dim = false }) {
|
|
9
|
+
const { top = "#9aa3b2", bottom = "#5b6472", hat, hold } = parts;
|
|
10
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
11
|
+
width: size,
|
|
12
|
+
height: size,
|
|
13
|
+
viewBox: "0 0 64 64",
|
|
14
|
+
style: {
|
|
15
|
+
display: "block",
|
|
16
|
+
opacity: dim ? .28 : 1,
|
|
17
|
+
transition: "opacity .2s"
|
|
18
|
+
},
|
|
19
|
+
"aria-hidden": true,
|
|
20
|
+
children: [
|
|
21
|
+
/* @__PURE__ */ jsx("rect", {
|
|
22
|
+
x: "26",
|
|
23
|
+
y: "40",
|
|
24
|
+
width: "5",
|
|
25
|
+
height: "16",
|
|
26
|
+
rx: "2.5",
|
|
27
|
+
fill: bottom
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ jsx("rect", {
|
|
30
|
+
x: "33",
|
|
31
|
+
y: "40",
|
|
32
|
+
width: "5",
|
|
33
|
+
height: "16",
|
|
34
|
+
rx: "2.5",
|
|
35
|
+
fill: bottom
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ jsx("rect", {
|
|
38
|
+
x: "22",
|
|
39
|
+
y: "24",
|
|
40
|
+
width: "20",
|
|
41
|
+
height: "20",
|
|
42
|
+
rx: "6",
|
|
43
|
+
fill: top
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ jsx("rect", {
|
|
46
|
+
x: "17",
|
|
47
|
+
y: "26",
|
|
48
|
+
width: "5",
|
|
49
|
+
height: "14",
|
|
50
|
+
rx: "2.5",
|
|
51
|
+
fill: top
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ jsx("rect", {
|
|
54
|
+
x: "42",
|
|
55
|
+
y: "26",
|
|
56
|
+
width: "5",
|
|
57
|
+
height: "14",
|
|
58
|
+
rx: "2.5",
|
|
59
|
+
fill: top
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ jsx("circle", {
|
|
62
|
+
cx: "32",
|
|
63
|
+
cy: "16",
|
|
64
|
+
r: "9",
|
|
65
|
+
fill: SKIN
|
|
66
|
+
}),
|
|
67
|
+
hat && /* @__PURE__ */ jsx("path", {
|
|
68
|
+
d: "M20 13 Q32 -1 44 13 Z",
|
|
69
|
+
fill: hat
|
|
70
|
+
}),
|
|
71
|
+
hat && /* @__PURE__ */ jsx("rect", {
|
|
72
|
+
x: "18",
|
|
73
|
+
y: "12",
|
|
74
|
+
width: "28",
|
|
75
|
+
height: "3.4",
|
|
76
|
+
rx: "1.7",
|
|
77
|
+
fill: hat
|
|
78
|
+
}),
|
|
79
|
+
hold && /* @__PURE__ */ jsx("text", {
|
|
80
|
+
x: "47",
|
|
81
|
+
y: "44",
|
|
82
|
+
fontSize: "13",
|
|
83
|
+
textAnchor: "middle",
|
|
84
|
+
children: hold
|
|
85
|
+
})
|
|
86
|
+
]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** A stacked outcome card: one emoji (or colour swatch) per category. */
|
|
90
|
+
function ComboCard({ cells, size = 60, dim = false }) {
|
|
91
|
+
return /* @__PURE__ */ jsx("div", {
|
|
92
|
+
style: {
|
|
93
|
+
display: "flex",
|
|
94
|
+
flexDirection: "column",
|
|
95
|
+
alignItems: "center",
|
|
96
|
+
gap: 2,
|
|
97
|
+
opacity: dim ? .3 : 1,
|
|
98
|
+
transition: "opacity .2s",
|
|
99
|
+
width: size
|
|
100
|
+
},
|
|
101
|
+
"aria-hidden": true,
|
|
102
|
+
children: cells.map((c, i) => c.emoji ? /* @__PURE__ */ jsx("span", {
|
|
103
|
+
style: {
|
|
104
|
+
fontSize: size * .42,
|
|
105
|
+
lineHeight: 1
|
|
106
|
+
},
|
|
107
|
+
children: c.emoji
|
|
108
|
+
}, i) : /* @__PURE__ */ jsx("span", { style: {
|
|
109
|
+
width: size * .6,
|
|
110
|
+
height: size * .26,
|
|
111
|
+
borderRadius: 5,
|
|
112
|
+
background: c.color ?? "#9aa3b2"
|
|
113
|
+
} }, i))
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/** A pickable option in a rack: the swatch/emoji + its label, selected ring. */
|
|
117
|
+
function OptionSwatch({ emoji, color, label, selected, onClick }) {
|
|
118
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
119
|
+
type: "button",
|
|
120
|
+
onClick,
|
|
121
|
+
"aria-pressed": selected,
|
|
122
|
+
"aria-label": label,
|
|
123
|
+
style: {
|
|
124
|
+
display: "inline-flex",
|
|
125
|
+
flexDirection: "column",
|
|
126
|
+
alignItems: "center",
|
|
127
|
+
gap: 3,
|
|
128
|
+
cursor: "pointer",
|
|
129
|
+
padding: "6px 8px",
|
|
130
|
+
borderRadius: 10,
|
|
131
|
+
background: "transparent",
|
|
132
|
+
border: `2px solid ${selected ? "var(--stage-accent)" : "var(--stage-grid)"}`,
|
|
133
|
+
boxShadow: selected ? "0 0 0 3px color-mix(in oklab, var(--stage-accent) 22%, transparent)" : "none",
|
|
134
|
+
transition: "border-color .15s, box-shadow .15s"
|
|
135
|
+
},
|
|
136
|
+
children: [emoji ? /* @__PURE__ */ jsx("span", {
|
|
137
|
+
style: {
|
|
138
|
+
fontSize: 24,
|
|
139
|
+
lineHeight: 1
|
|
140
|
+
},
|
|
141
|
+
children: emoji
|
|
142
|
+
}) : /* @__PURE__ */ jsx("span", { style: {
|
|
143
|
+
width: 28,
|
|
144
|
+
height: 18,
|
|
145
|
+
borderRadius: 5,
|
|
146
|
+
background: color ?? "#9aa3b2"
|
|
147
|
+
} }), /* @__PURE__ */ jsx("span", {
|
|
148
|
+
style: {
|
|
149
|
+
fontSize: 11,
|
|
150
|
+
color: "var(--stage-muted)",
|
|
151
|
+
fontWeight: 600
|
|
152
|
+
},
|
|
153
|
+
children: label
|
|
154
|
+
})]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
export { CharacterFigure, ComboCard, OptionSwatch };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CharSlot } from "./figure.mjs";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/discrete/combination-studio/preset.d.ts
|
|
5
|
+
interface ComboOption {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
emoji?: string;
|
|
9
|
+
color?: string;
|
|
10
|
+
}
|
|
11
|
+
interface ComboCategory {
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
slot?: CharSlot;
|
|
15
|
+
options: ComboOption[];
|
|
16
|
+
}
|
|
17
|
+
interface CombinationStudioProps {
|
|
18
|
+
/** The thing being built, e.g. "outfit", "sundae" (used in the headline + question). */
|
|
19
|
+
scenario?: string;
|
|
20
|
+
categories?: ComboCategory[];
|
|
21
|
+
/** 'character' assembles a person; 'card' stacks the chosen emoji (non-clothing). */
|
|
22
|
+
figure?: 'character' | 'card';
|
|
23
|
+
/** How many categories are in play at the start (rest revealed via + variable). */
|
|
24
|
+
startActive?: number;
|
|
25
|
+
/** Cap outcomes drawn on the wall. */
|
|
26
|
+
maxWall?: number;
|
|
27
|
+
title?: string;
|
|
28
|
+
prompt?: string;
|
|
29
|
+
objectives?: string[];
|
|
30
|
+
hints?: string[];
|
|
31
|
+
}
|
|
32
|
+
declare function CombinationStudioLab({
|
|
33
|
+
scenario,
|
|
34
|
+
categories,
|
|
35
|
+
figure,
|
|
36
|
+
startActive,
|
|
37
|
+
maxWall,
|
|
38
|
+
title,
|
|
39
|
+
prompt,
|
|
40
|
+
objectives,
|
|
41
|
+
hints: hintList
|
|
42
|
+
}?: CombinationStudioProps): ReactNode;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { CombinationStudioLab, CombinationStudioProps, ComboCategory, ComboOption };
|