@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
|
@@ -12,17 +12,17 @@ import { useControlSurface, useLearner } from "@classytic/stage";
|
|
|
12
12
|
|
|
13
13
|
//#region src/discrete/truth-table/preset.tsx
|
|
14
14
|
/**
|
|
15
|
-
* TruthTableEngine
|
|
15
|
+
* TruthTableEngine, the GENERAL authorable truth-table tool. A creator declares
|
|
16
16
|
* any propositional formula (¬ ∧ ∨ ⊕ → ↔, unicode or ASCII) and a mode; the lab
|
|
17
17
|
* derives EVERYTHING from the stage logic kernel (parse → truth table → classify
|
|
18
|
-
* → equivalence). No per-problem widget
|
|
18
|
+
* → equivalence). No per-problem widget, one tool covers all of propositional
|
|
19
19
|
* logic, from "fill the implication table" to "are these two equivalent?".
|
|
20
20
|
*
|
|
21
21
|
* Modes:
|
|
22
|
-
* • show
|
|
22
|
+
* • show , full reference table with sub-expression columns built up
|
|
23
23
|
* textbook-style (vars → ¬p → q∧r → … → the whole formula).
|
|
24
|
-
* • fill
|
|
25
|
-
* • classify
|
|
24
|
+
* • fill , learner toggles each output cell, then Check (graded per cell).
|
|
25
|
+
* • classify, learner judges tautology / contradiction / contingency.
|
|
26
26
|
* Pass `compare` to put a second formula beside the first + an equivalence verdict
|
|
27
27
|
* (De Morgan, contrapositive, p→q ≡ ¬p∨q …). Agent-drivable via `controlId`.
|
|
28
28
|
*/
|
|
@@ -31,6 +31,8 @@ const CLASSES = [
|
|
|
31
31
|
"contradiction",
|
|
32
32
|
"contingency"
|
|
33
33
|
];
|
|
34
|
+
/** 2^n rows: past this a truth table is impractical to render and unsafe for 32-bit shifts. */
|
|
35
|
+
const MAX_VARS = 12;
|
|
34
36
|
/** Sub-expressions in build-up (post-order) order, deduped, vars/consts excluded;
|
|
35
37
|
* the root formula is last. */
|
|
36
38
|
function subformulas(n) {
|
|
@@ -83,8 +85,9 @@ function TruthTableLab({ formula, compare, mode: mode0 = "fill", breakdown = tru
|
|
|
83
85
|
cmp
|
|
84
86
|
]);
|
|
85
87
|
const envs = useMemo(() => {
|
|
88
|
+
if (vars.length > MAX_VARS) return [];
|
|
86
89
|
const rows = [];
|
|
87
|
-
for (let m = 0; m <
|
|
90
|
+
for (let m = 0; m < 2 ** vars.length; m++) {
|
|
88
91
|
const env = {};
|
|
89
92
|
vars.forEach((v, i) => {
|
|
90
93
|
env[v] = (m & 1 << vars.length - 1 - i) !== 0;
|
|
@@ -201,6 +204,26 @@ function TruthTableLab({ formula, compare, mode: mode0 = "fill", breakdown = tru
|
|
|
201
204
|
]
|
|
202
205
|
})
|
|
203
206
|
});
|
|
207
|
+
if (vars.length > MAX_VARS) return /* @__PURE__ */ jsx(LabFrame, {
|
|
208
|
+
title,
|
|
209
|
+
children: /* @__PURE__ */ jsxs("p", {
|
|
210
|
+
className: "lab-misconception",
|
|
211
|
+
role: "status",
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ jsx("span", {
|
|
214
|
+
"aria-hidden": true,
|
|
215
|
+
children: "⚠"
|
|
216
|
+
}),
|
|
217
|
+
" This truth table has ",
|
|
218
|
+
vars.length,
|
|
219
|
+
" variables (",
|
|
220
|
+
2 ** vars.length,
|
|
221
|
+
" rows). Keep it to ",
|
|
222
|
+
MAX_VARS,
|
|
223
|
+
" or fewer."
|
|
224
|
+
]
|
|
225
|
+
})
|
|
226
|
+
});
|
|
204
227
|
const th = {
|
|
205
228
|
padding: "6px 12px",
|
|
206
229
|
fontWeight: 700,
|
|
@@ -381,7 +404,7 @@ function TruthTableLab({ formula, compare, mode: mode0 = "fill", breakdown = tru
|
|
|
381
404
|
className: "lab-bar",
|
|
382
405
|
children: /* @__PURE__ */ jsx(StatusPill, {
|
|
383
406
|
ok: equiv,
|
|
384
|
-
children: equiv ? "Equivalent
|
|
407
|
+
children: equiv ? "Equivalent ✓, identical columns" : "NOT equivalent, columns differ"
|
|
385
408
|
})
|
|
386
409
|
})
|
|
387
410
|
] });
|
|
@@ -419,7 +442,7 @@ function TruthTableLab({ formula, compare, mode: mode0 = "fill", breakdown = tru
|
|
|
419
442
|
}),
|
|
420
443
|
checked && /* @__PURE__ */ jsx(StatusPill, {
|
|
421
444
|
ok: guess === cls,
|
|
422
|
-
children: guess === cls ? `✓ ${cls}` : `Not quite
|
|
445
|
+
children: guess === cls ? `✓ ${cls}` : `Not quite, it’s a ${cls}`
|
|
423
446
|
})
|
|
424
447
|
] }),
|
|
425
448
|
!compare && mode === "fill" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(CheckButton, {
|
|
@@ -428,7 +451,7 @@ function TruthTableLab({ formula, compare, mode: mode0 = "fill", breakdown = tru
|
|
|
428
451
|
children: "Check"
|
|
429
452
|
}), checked && /* @__PURE__ */ jsx(StatusPill, {
|
|
430
453
|
ok: allFilledCorrect,
|
|
431
|
-
children: allFilledCorrect ? "All correct ✓" : "Some cells are off
|
|
454
|
+
children: allFilledCorrect ? "All correct ✓" : "Some cells are off, fix the red ones"
|
|
432
455
|
})] })
|
|
433
456
|
] }),
|
|
434
457
|
footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [!compare && mode !== "show" && /* @__PURE__ */ jsx(RevealSolution, {
|
|
@@ -10,14 +10,14 @@ import { compileLogic, useControlSurface, useLearner } from "@classytic/stage";
|
|
|
10
10
|
|
|
11
11
|
//#region src/discrete/venn/preset.tsx
|
|
12
12
|
/**
|
|
13
|
-
* VennSetBoard
|
|
13
|
+
* VennSetBoard, the GENERAL sets + inclusion–exclusion tool (2 or 3 sets). The
|
|
14
14
|
* creator declares set MEMBERS; the lab places each element in its true region,
|
|
15
15
|
* shows live region counts, and (explore) the inclusion–exclusion breakdown
|
|
16
|
-
* |A∪B| = |A| + |B| − |A∩B
|
|
16
|
+
* |A∪B| = |A| + |B| − |A∩B|, the "overcount, then correct" spine made visible.
|
|
17
17
|
*
|
|
18
18
|
* The trinity made literal: a SET expression is a PROPOSITIONAL formula over
|
|
19
19
|
* membership (∩↔∧, ∪↔∨, ᶜ↔¬), so "shade the region for A ∩ ¬B" runs on the SAME
|
|
20
|
-
* `compileLogic` kernel as the truth-table lab
|
|
20
|
+
* `compileLogic` kernel as the truth-table lab, one source of truth.
|
|
21
21
|
*
|
|
22
22
|
* Self-contained SVG (a fixed diagram, not a coordinate plot), so no Stage coords
|
|
23
23
|
* needed; counts/IE come from `@classytic/labs/discrete/core`.
|
|
@@ -27,77 +27,77 @@ const GEO2 = {
|
|
|
27
27
|
0,
|
|
28
28
|
0,
|
|
29
29
|
340,
|
|
30
|
-
|
|
30
|
+
224
|
|
31
31
|
],
|
|
32
32
|
circles: [{
|
|
33
33
|
cx: 132,
|
|
34
|
-
cy:
|
|
35
|
-
r:
|
|
34
|
+
cy: 118,
|
|
35
|
+
r: 82
|
|
36
36
|
}, {
|
|
37
37
|
cx: 208,
|
|
38
|
-
cy:
|
|
39
|
-
r:
|
|
38
|
+
cy: 118,
|
|
39
|
+
r: 82
|
|
40
40
|
}],
|
|
41
41
|
centroids: {
|
|
42
|
-
"10": [
|
|
43
|
-
"01": [
|
|
44
|
-
"11": [170,
|
|
45
|
-
"00": [
|
|
42
|
+
"10": [80, 118],
|
|
43
|
+
"01": [260, 118],
|
|
44
|
+
"11": [170, 118],
|
|
45
|
+
"00": [40, 30]
|
|
46
46
|
},
|
|
47
47
|
labels: [{
|
|
48
|
-
x:
|
|
49
|
-
y:
|
|
48
|
+
x: 104,
|
|
49
|
+
y: 26
|
|
50
50
|
}, {
|
|
51
|
-
x:
|
|
52
|
-
y:
|
|
51
|
+
x: 236,
|
|
52
|
+
y: 26
|
|
53
53
|
}]
|
|
54
54
|
};
|
|
55
55
|
const GEO3 = {
|
|
56
56
|
vb: [
|
|
57
57
|
0,
|
|
58
58
|
0,
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
360,
|
|
60
|
+
306
|
|
61
61
|
],
|
|
62
62
|
circles: [
|
|
63
63
|
{
|
|
64
|
-
cx:
|
|
65
|
-
cy:
|
|
66
|
-
r:
|
|
64
|
+
cx: 140,
|
|
65
|
+
cy: 116,
|
|
66
|
+
r: 78
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
|
-
cx:
|
|
70
|
-
cy:
|
|
71
|
-
r:
|
|
69
|
+
cx: 220,
|
|
70
|
+
cy: 116,
|
|
71
|
+
r: 78
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
cx:
|
|
75
|
-
cy:
|
|
76
|
-
r:
|
|
74
|
+
cx: 180,
|
|
75
|
+
cy: 186,
|
|
76
|
+
r: 78
|
|
77
77
|
}
|
|
78
78
|
],
|
|
79
79
|
centroids: {
|
|
80
|
-
"100": [
|
|
81
|
-
"010": [
|
|
82
|
-
"001": [
|
|
83
|
-
"110": [
|
|
84
|
-
"101": [
|
|
85
|
-
"011": [
|
|
86
|
-
"111": [
|
|
87
|
-
"000": [
|
|
80
|
+
"100": [104, 96],
|
|
81
|
+
"010": [256, 96],
|
|
82
|
+
"001": [180, 232],
|
|
83
|
+
"110": [180, 84],
|
|
84
|
+
"101": [132, 162],
|
|
85
|
+
"011": [228, 162],
|
|
86
|
+
"111": [180, 140],
|
|
87
|
+
"000": [44, 30]
|
|
88
88
|
},
|
|
89
89
|
labels: [
|
|
90
90
|
{
|
|
91
|
-
x:
|
|
92
|
-
y:
|
|
91
|
+
x: 104,
|
|
92
|
+
y: 30
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
|
-
x:
|
|
96
|
-
y:
|
|
95
|
+
x: 256,
|
|
96
|
+
y: 30
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
|
-
x:
|
|
100
|
-
y:
|
|
99
|
+
x: 180,
|
|
100
|
+
y: 296
|
|
101
101
|
}
|
|
102
102
|
]
|
|
103
103
|
};
|
|
@@ -274,6 +274,23 @@ function VennSetBoardLab({ sets, mode: mode0 = "explore", target, title = "Sets
|
|
|
274
274
|
invoke: reset
|
|
275
275
|
}
|
|
276
276
|
});
|
|
277
|
+
if (n < 2 || n > 3) return /* @__PURE__ */ jsx(LabFrame, {
|
|
278
|
+
title,
|
|
279
|
+
prompt,
|
|
280
|
+
children: /* @__PURE__ */ jsxs("p", {
|
|
281
|
+
className: "lab-misconception",
|
|
282
|
+
role: "status",
|
|
283
|
+
children: [
|
|
284
|
+
/* @__PURE__ */ jsx("span", {
|
|
285
|
+
"aria-hidden": true,
|
|
286
|
+
children: "⚠"
|
|
287
|
+
}),
|
|
288
|
+
" The Venn lab supports 2 or 3 sets; you gave ",
|
|
289
|
+
n,
|
|
290
|
+
". Reduce the number of sets."
|
|
291
|
+
]
|
|
292
|
+
})
|
|
293
|
+
});
|
|
277
294
|
const [vx, vy, vw, vh] = geo.vb;
|
|
278
295
|
const showShade = mode === "shade";
|
|
279
296
|
const figure = /* @__PURE__ */ jsx("div", {
|
|
@@ -307,10 +324,10 @@ function VennSetBoardLab({ sets, mode: mode0 = "explore", target, title = "Sets
|
|
|
307
324
|
cy: c.cy,
|
|
308
325
|
r: c.r,
|
|
309
326
|
fill: PALETTE[i],
|
|
310
|
-
fillOpacity: .
|
|
311
|
-
stroke:
|
|
312
|
-
strokeOpacity: .
|
|
313
|
-
strokeWidth:
|
|
327
|
+
fillOpacity: .09,
|
|
328
|
+
stroke: PALETTE[i],
|
|
329
|
+
strokeOpacity: .7,
|
|
330
|
+
strokeWidth: 2
|
|
314
331
|
}, i)),
|
|
315
332
|
geo.labels.map((l, i) => /* @__PURE__ */ jsx("text", {
|
|
316
333
|
x: l.x,
|
|
@@ -319,20 +336,26 @@ function VennSetBoardLab({ sets, mode: mode0 = "explore", target, title = "Sets
|
|
|
319
336
|
fontSize: 15,
|
|
320
337
|
fontWeight: 800,
|
|
321
338
|
textAnchor: "middle",
|
|
339
|
+
style: {
|
|
340
|
+
paintOrder: "stroke",
|
|
341
|
+
stroke: "var(--stage-bg)",
|
|
342
|
+
strokeWidth: 4,
|
|
343
|
+
strokeLinejoin: "round"
|
|
344
|
+
},
|
|
322
345
|
children: names[i]
|
|
323
346
|
}, i)),
|
|
324
347
|
mode === "explore" && regions.filter((r) => r.count > 0 && r.sig !== "0".repeat(n)).map((r) => /* @__PURE__ */ jsx("text", {
|
|
325
348
|
x: r.centroid[0],
|
|
326
349
|
y: r.centroid[1],
|
|
327
350
|
fill: "var(--stage-fg)",
|
|
328
|
-
fontSize:
|
|
351
|
+
fontSize: 16,
|
|
329
352
|
fontWeight: 700,
|
|
330
353
|
textAnchor: "middle",
|
|
331
354
|
dominantBaseline: "central",
|
|
332
355
|
style: {
|
|
333
356
|
paintOrder: "stroke",
|
|
334
357
|
stroke: "var(--stage-bg)",
|
|
335
|
-
strokeWidth: 4,
|
|
358
|
+
strokeWidth: 4.5,
|
|
336
359
|
strokeLinejoin: "round"
|
|
337
360
|
},
|
|
338
361
|
children: r.count
|
|
@@ -441,7 +464,7 @@ function VennSetBoardLab({ sets, mode: mode0 = "explore", target, title = "Sets
|
|
|
441
464
|
}),
|
|
442
465
|
checked && /* @__PURE__ */ jsx(StatusPill, {
|
|
443
466
|
ok: correct,
|
|
444
|
-
children: correct ? "✓ Exactly right" : "Not quite
|
|
467
|
+
children: correct ? "✓ Exactly right" : "Not quite, adjust the regions"
|
|
445
468
|
})
|
|
446
469
|
] }) : void 0,
|
|
447
470
|
footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [mode === "shade" && /* @__PURE__ */ jsx(RevealSolution, {
|
|
@@ -10,15 +10,15 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
|
|
11
11
|
//#region src/geography/cycle-lab/preset.tsx
|
|
12
12
|
/**
|
|
13
|
-
* CycleLab
|
|
13
|
+
* CycleLab, ONE authorable lab for every cycle (water, rock, carbon, nitrogen,
|
|
14
14
|
* food chains…). The creator/agent declares the model (nodes + process-labelled
|
|
15
15
|
* edges) and a challenge; the shared CycleDiagram renders it. Not a bespoke
|
|
16
|
-
* WaterCycle/RockCycle widget
|
|
16
|
+
* WaterCycle/RockCycle widget, the cycle is data.
|
|
17
17
|
*
|
|
18
|
-
* • challenge='trace'
|
|
18
|
+
* • challenge='trace', click a stage; its outgoing arrows + the processes that
|
|
19
19
|
* drive them light up. The branched rock/carbon cycles reveal that you don't
|
|
20
|
-
* have to go all the way around
|
|
21
|
-
* • challenge='label-process'
|
|
20
|
+
* have to go all the way around, any rock can melt or re-weather.
|
|
21
|
+
* • challenge='label-process', the process names are stripped off the arrows
|
|
22
22
|
* into a tray; match each one to the transition it drives. That IS the IGCSE
|
|
23
23
|
* skill, and it's unambiguous (clean rings like the water cycle).
|
|
24
24
|
*
|
|
@@ -81,7 +81,7 @@ function TraceCycle({ nodes, edges, size, title, prompt, objectives, activity })
|
|
|
81
81
|
size,
|
|
82
82
|
activeId: active,
|
|
83
83
|
onNodeClick: click,
|
|
84
|
-
ariaLabel: `${title}
|
|
84
|
+
ariaLabel: `${title}: a cycle diagram with ${nodes.length} stages (${nodes.map((nd) => nd.label).join(", ")}) connected by labelled process arrows. Activate a stage to trace its outgoing transitions and the processes that drive them.`
|
|
85
85
|
})
|
|
86
86
|
}), /* @__PURE__ */ jsx(LiveRegion, { children: active ? `${labelOf(active)} leads to ${out.map((e) => `${labelOf(e.to)} by ${e.label}`).join(", ") || "nothing further"}.` : "" })] });
|
|
87
87
|
const footer = /* @__PURE__ */ jsxs("div", {
|
|
@@ -101,7 +101,7 @@ function TraceCycle({ nodes, edges, size, title, prompt, objectives, activity })
|
|
|
101
101
|
/* @__PURE__ */ jsxs("span", {
|
|
102
102
|
style: { color: "var(--stage-muted)" },
|
|
103
103
|
children: [
|
|
104
|
-
"
|
|
104
|
+
" , ",
|
|
105
105
|
e.label,
|
|
106
106
|
"→ "
|
|
107
107
|
]
|
|
@@ -126,7 +126,7 @@ function TraceCycle({ nodes, edges, size, title, prompt, objectives, activity })
|
|
|
126
126
|
});
|
|
127
127
|
return /* @__PURE__ */ jsx(LabFrame, {
|
|
128
128
|
title,
|
|
129
|
-
prompt: prompt ?? "Click each stage to trace where it goes
|
|
129
|
+
prompt: prompt ?? "Click each stage to trace where it goes, and which process drives the change.",
|
|
130
130
|
objectives,
|
|
131
131
|
footer,
|
|
132
132
|
children: figure
|
|
@@ -171,9 +171,16 @@ function LabelProcess({ nodes, edges, size, title, prompt, objectives, hash: h,
|
|
|
171
171
|
const fill = ok ? "var(--stage-good)" : bad ? "var(--stage-danger)" : "var(--stage-muted)";
|
|
172
172
|
return /* @__PURE__ */ jsxs("g", {
|
|
173
173
|
onClick: () => onSlot(key),
|
|
174
|
+
onKeyDown: (e) => {
|
|
175
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
176
|
+
e.preventDefault();
|
|
177
|
+
onSlot(key);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
174
180
|
style: { cursor: "pointer" },
|
|
175
181
|
role: "button",
|
|
176
|
-
|
|
182
|
+
tabIndex: 0,
|
|
183
|
+
"aria-label": val ? `${val}, ${ok ? "correctly matched, activate to take it back" : "incorrect, activate to clear"}` : sel ? `Empty process slot, activate to place ${sel} here` : "Empty process slot, pick a process first, then activate to place it here",
|
|
177
184
|
children: [/* @__PURE__ */ jsx("rect", {
|
|
178
185
|
x: Math.round(mid.x - w / 2),
|
|
179
186
|
y: mid.y - 10,
|
|
@@ -207,7 +214,7 @@ function LabelProcess({ nodes, edges, size, title, prompt, objectives, hash: h,
|
|
|
207
214
|
edges,
|
|
208
215
|
size,
|
|
209
216
|
edgeSlot,
|
|
210
|
-
ariaLabel: `${title}
|
|
217
|
+
ariaLabel: `${title}: a cycle diagram with ${nodes.length} stages (${nodes.map((nd) => nd.label).join(", ")}) and ${labelEdges.length} arrows whose process labels have been removed. Pick a process from the tray, then activate the arrow slot it drives to match it.`
|
|
211
218
|
})
|
|
212
219
|
}), /* @__PURE__ */ jsx(LiveRegion, { children: solved ? "All processes matched correctly." : `${solvedCount} of ${labelEdges.length} processes matched.` })] });
|
|
213
220
|
const controls = /* @__PURE__ */ jsx(ControlBar, { children: /* @__PURE__ */ jsx(Field, {
|
|
@@ -5,11 +5,11 @@ interface CycleSpec {
|
|
|
5
5
|
nodes: CycleNode[];
|
|
6
6
|
edges: CycleEdge[];
|
|
7
7
|
}
|
|
8
|
-
/** Water cycle
|
|
8
|
+
/** Water cycle, a clean 5-stage ring; each edge is one distinct process. */
|
|
9
9
|
declare const WATER_CYCLE: CycleSpec;
|
|
10
|
-
/** Rock cycle
|
|
10
|
+
/** Rock cycle, a ring PLUS shortcuts: any rock can skip ahead (heat, re-weather). */
|
|
11
11
|
declare const ROCK_CYCLE: CycleSpec;
|
|
12
|
-
/** Carbon cycle
|
|
12
|
+
/** Carbon cycle, branched (CO₂ in/out by several routes); ties to photo/respiration. */
|
|
13
13
|
declare const CARBON_CYCLE: CycleSpec;
|
|
14
14
|
declare const CYCLE_PRESETS: {
|
|
15
15
|
readonly water: CycleSpec;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/geography/cycles.ts
|
|
2
|
-
/** Water cycle
|
|
2
|
+
/** Water cycle, a clean 5-stage ring; each edge is one distinct process. */
|
|
3
3
|
const WATER_CYCLE = {
|
|
4
4
|
nodes: [
|
|
5
5
|
{
|
|
@@ -56,7 +56,7 @@ const WATER_CYCLE = {
|
|
|
56
56
|
}
|
|
57
57
|
]
|
|
58
58
|
};
|
|
59
|
-
/** Rock cycle
|
|
59
|
+
/** Rock cycle, a ring PLUS shortcuts: any rock can skip ahead (heat, re-weather). */
|
|
60
60
|
const ROCK_CYCLE = {
|
|
61
61
|
nodes: [
|
|
62
62
|
{
|
|
@@ -123,7 +123,7 @@ const ROCK_CYCLE = {
|
|
|
123
123
|
}
|
|
124
124
|
]
|
|
125
125
|
};
|
|
126
|
-
/** Carbon cycle
|
|
126
|
+
/** Carbon cycle, branched (CO₂ in/out by several routes); ties to photo/respiration. */
|
|
127
127
|
const CARBON_CYCLE = {
|
|
128
128
|
nodes: [
|
|
129
129
|
{
|
|
@@ -55,6 +55,7 @@ interface GeometryBoardProps {
|
|
|
55
55
|
scene?: GeoElement[];
|
|
56
56
|
view?: View;
|
|
57
57
|
title?: string;
|
|
58
|
+
prompt?: string;
|
|
58
59
|
subtitle?: string;
|
|
59
60
|
height?: number;
|
|
60
61
|
}
|
|
@@ -65,6 +66,7 @@ declare function GeometryBoard({
|
|
|
65
66
|
scene,
|
|
66
67
|
view,
|
|
67
68
|
title,
|
|
69
|
+
prompt,
|
|
68
70
|
height
|
|
69
71
|
}: GeometryBoardProps): ReactNode;
|
|
70
72
|
//#endregion
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { LabFrame } from "../../kit/frame.mjs";
|
|
3
4
|
import { useEffect, useMemo, useState } from "react";
|
|
4
|
-
import { jsx
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
import { Scene } from "@classytic/stage";
|
|
6
7
|
|
|
7
8
|
//#region src/geometry/board/preset.tsx
|
|
8
9
|
/**
|
|
9
|
-
* GeometryBoard
|
|
10
|
+
* GeometryBoard, a declarative interactive-geometry engine, now on the
|
|
10
11
|
* @classytic/stage scene model. A creator describes a CONSTRUCTION as a list of
|
|
11
12
|
* `GeoElement`s; we convert it to a portable SceneDoc and let stage's resolver
|
|
12
13
|
* do the dependency math (circle/line intersection, midpoints) + dragging +
|
|
13
|
-
* a11y. The canvas geometry math is gone
|
|
14
|
+
* a11y. The canvas geometry math is gone, stage already owns it.
|
|
14
15
|
*
|
|
15
16
|
* <GeometryBoard scene={[
|
|
16
17
|
* { type:'point', id:'A', x:3, y:0, draggable:true },
|
|
@@ -118,29 +119,24 @@ function geoSceneToDoc(scene, view) {
|
|
|
118
119
|
bindings: []
|
|
119
120
|
};
|
|
120
121
|
}
|
|
121
|
-
function GeometryBoard({ scene = [], view = DEFAULT_VIEW, title, height = 360 }) {
|
|
122
|
+
function GeometryBoard({ scene = [], view = DEFAULT_VIEW, title = "Geometry construction", prompt = "Drag the points to explore the construction.", height = 360 }) {
|
|
122
123
|
const initial = useMemo(() => geoSceneToDoc(scene, view), [scene, view]);
|
|
123
124
|
const [doc, setDoc] = useState(initial);
|
|
124
125
|
useEffect(() => {
|
|
125
126
|
setDoc(initial);
|
|
126
127
|
}, [initial]);
|
|
127
|
-
return /* @__PURE__ */
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
fontWeight: 600,
|
|
132
|
-
marginBottom: 6
|
|
133
|
-
},
|
|
134
|
-
children: title
|
|
135
|
-
}), /* @__PURE__ */ jsx(Scene, {
|
|
128
|
+
return /* @__PURE__ */ jsx(LabFrame, {
|
|
129
|
+
title,
|
|
130
|
+
prompt,
|
|
131
|
+
children: /* @__PURE__ */ jsx(Scene, {
|
|
136
132
|
doc,
|
|
137
133
|
onChange: setDoc,
|
|
138
134
|
interactive: true,
|
|
139
135
|
showGrid: true,
|
|
140
136
|
showAxes: true,
|
|
141
137
|
height,
|
|
142
|
-
ariaLabel: title
|
|
143
|
-
})
|
|
138
|
+
ariaLabel: title
|
|
139
|
+
})
|
|
144
140
|
});
|
|
145
141
|
}
|
|
146
142
|
|
|
@@ -7,7 +7,7 @@ import { Axes, Dot, Grid, Stage, ToolIcon, isCircleVal, isLineVal, isVec2, rende
|
|
|
7
7
|
|
|
8
8
|
//#region src/geometry/builder.tsx
|
|
9
9
|
/**
|
|
10
|
-
* GeometryBuilder
|
|
10
|
+
* GeometryBuilder, a visual, click-to-build editor for a `GeometryBoard` scene.
|
|
11
11
|
*
|
|
12
12
|
* Pick a tool, click the board: drop points, connect them into segments/lines,
|
|
13
13
|
* draw circles (centre → through-point), mark the intersection of two
|
|
@@ -16,7 +16,7 @@ import { Axes, Dot, Grid, Stage, ToolIcon, isCircleVal, isLineVal, isVec2, rende
|
|
|
16
16
|
*
|
|
17
17
|
* Now on the @classytic/stage engine: the construction is converted to a SceneDoc
|
|
18
18
|
* and rendered with stage's resolver + `renderElements` (SVG, accessible, real
|
|
19
|
-
* draggable points)
|
|
19
|
+
* draggable points), the canvas geometry math is gone. `GeometryBoard` is the
|
|
20
20
|
* read-only render of this editor's output.
|
|
21
21
|
*/
|
|
22
22
|
const TOOLS = [
|
|
@@ -303,7 +303,7 @@ function GeometryBuilder({ scene = [], onChange, title = "Build a construction",
|
|
|
303
303
|
view: VIEW,
|
|
304
304
|
height,
|
|
305
305
|
onPointerMath: onBuild,
|
|
306
|
-
ariaLabel: `Geometry construction editor
|
|
306
|
+
ariaLabel: `Geometry construction editor, ${tool} tool`,
|
|
307
307
|
className: "cursor-crosshair",
|
|
308
308
|
children: [
|
|
309
309
|
/* @__PURE__ */ jsx(Grid, {}),
|
|
@@ -11,11 +11,11 @@ import { useInView } from "@classytic/stage";
|
|
|
11
11
|
|
|
12
12
|
//#region src/ict/number-systems/base-odometer.tsx
|
|
13
13
|
/**
|
|
14
|
-
* BaseOdometer
|
|
14
|
+
* BaseOdometer, the same quantity, ticking in every base at once.
|
|
15
15
|
*
|
|
16
16
|
* Stacked odometer rows (one per base) all driven by ONE shared integer:
|
|
17
|
-
* increment it and binary/octal/decimal/hex roll in lockstep
|
|
18
|
-
* rolls fastest (the rightmost-bit frequency cascade), hex barely moves
|
|
17
|
+
* increment it and binary/octal/decimal/hex roll in lockstep, the binary row
|
|
18
|
+
* rolls fastest (the rightmost-bit frequency cascade), hex barely moves, so
|
|
19
19
|
* "base is a costume, not a different number" is something you watch, not read.
|
|
20
20
|
* A race toggle auto-counts via the frame loop so the cascade plays as motion.
|
|
21
21
|
* Composes the shared WheelRow (DRY: the wheel + carry animation live in one place).
|
|
@@ -31,7 +31,7 @@ function BaseOdometerLab({ bases = [
|
|
|
31
31
|
8,
|
|
32
32
|
10,
|
|
33
33
|
16
|
|
34
|
-
], width = "auto", start = 0, max = 255, race = false, speed = 2, highlightBase, target, title = "Base odometer", prompt = "One quantity, every base at once
|
|
34
|
+
], width = "auto", start = 0, max = 255, race = false, speed = 2, highlightBase, target, title = "Base odometer", prompt = "One quantity, every base at once: +1 and watch them all roll.", objectives }) {
|
|
35
35
|
const [value, setValue] = useState(Math.max(0, Math.min(max, Math.floor(start))));
|
|
36
36
|
const [racing, setRacing] = useState(race);
|
|
37
37
|
const acc = useRef(0);
|
|
@@ -7,7 +7,7 @@ interface BitGrouperProps {
|
|
|
7
7
|
/** Group sizes offered as chips (4 = hex, 3 = octal). */
|
|
8
8
|
groupings?: number[];
|
|
9
9
|
start?: number;
|
|
10
|
-
/** Pose "build this value"
|
|
10
|
+
/** Pose "build this value", reports via the learner seam when matched. */
|
|
11
11
|
target?: {
|
|
12
12
|
value: number;
|
|
13
13
|
base: 16 | 8 | 2;
|
|
@@ -9,10 +9,10 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
|
|
10
10
|
//#region src/ict/number-systems/bit-grouper.tsx
|
|
11
11
|
/**
|
|
12
|
-
* BitGrouper
|
|
12
|
+
* BitGrouper, slice a byte into nibbles and read the hex.
|
|
13
13
|
*
|
|
14
14
|
* A strip of tappable bits that auto-slices into groups of k FROM THE RIGHT
|
|
15
|
-
* (4 for hex, 3 for octal), translating each group to a hex/octal digit live
|
|
15
|
+
* (4 for hex, 3 for octal), translating each group to a hex/octal digit live ,
|
|
16
16
|
* the "group the bits" trick made physical. Flip between hex and octal to watch
|
|
17
17
|
* the SAME bits re-slice and the leftmost group pad with zeros; in octal the top
|
|
18
18
|
* group of a byte never exceeds 3 (greyed), which is exactly why hex won.
|
|
@@ -42,7 +42,7 @@ function sliceFromRight(value, width, k) {
|
|
|
42
42
|
}
|
|
43
43
|
return groups;
|
|
44
44
|
}
|
|
45
|
-
function BitGrouperLab({ width = 8, groupSize = 4, groupings = [4, 3], start = 0, target, showColor = false, title = "Bit grouper", prompt = "Tap the bits. Group from the right
|
|
45
|
+
function BitGrouperLab({ width = 8, groupSize = 4, groupings = [4, 3], start = 0, target, showColor = false, title = "Bit grouper", prompt = "Tap the bits. Group from the right: 4 per hex digit, 3 per octal digit.", objectives }) {
|
|
46
46
|
const cap = (1 << width) - 1;
|
|
47
47
|
const [value, setValue] = useState(Math.max(0, Math.min(cap, Math.floor(start))));
|
|
48
48
|
const [k, setK] = useState(groupSize);
|
|
@@ -135,7 +135,7 @@ function BitGrouperLab({ width = 8, groupSize = 4, groupings = [4, 3], start = 0
|
|
|
135
135
|
children: [
|
|
136
136
|
"the greyed top octal group is only ",
|
|
137
137
|
width % k,
|
|
138
|
-
" bits
|
|
138
|
+
" bits, it never passes ",
|
|
139
139
|
(1 << width % k) - 1,
|
|
140
140
|
", so octal wastes the top of a byte (why hex won)"
|
|
141
141
|
]
|
|
@@ -5,7 +5,7 @@ interface PlaceValueDialProps {
|
|
|
5
5
|
base?: number;
|
|
6
6
|
width?: number;
|
|
7
7
|
start?: number;
|
|
8
|
-
/** Pose "spin the dials to N"
|
|
8
|
+
/** Pose "spin the dials to N", reports via the learner seam when matched. */
|
|
9
9
|
target?: number;
|
|
10
10
|
/** Base chips the learner can switch between (re-bases the same value). */
|
|
11
11
|
bases?: number[];
|
|
@@ -10,13 +10,13 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
|
|
11
11
|
//#region src/ict/number-systems/place-value-dial.tsx
|
|
12
12
|
/**
|
|
13
|
-
* PlaceValueDial
|
|
13
|
+
* PlaceValueDial, count in any base and watch the carry ripple.
|
|
14
14
|
*
|
|
15
15
|
* A row of odometer wheels in base-N. +1 ticks the ones wheel; when it passes
|
|
16
|
-
* N−1 it snaps to 0 and KICKS the next wheel up
|
|
16
|
+
* N−1 it snaps to 0 and KICKS the next wheel up, the carry ripples left while
|
|
17
17
|
* the power-of-N place values light up and sum to the live value. Re-base the
|
|
18
18
|
* SAME count with the base chips to see "10 in any base means you ticked over
|
|
19
|
-
* the base exactly once". In base-2 the wheels become ON/OFF cells
|
|
19
|
+
* the base exactly once". In base-2 the wheels become ON/OFF cells, the
|
|
20
20
|
* "lightbulbs worth 1-2-4-8-16" picture. (Anti-pattern guard: weights stay on
|
|
21
21
|
* screen, the carry is shown not hidden, and it works in both directions.)
|
|
22
22
|
*/
|
|
@@ -12,7 +12,7 @@ interface DigitWheelProps {
|
|
|
12
12
|
digit: number;
|
|
13
13
|
/** 0 (settled) → 1 (just changed); slides the digit stack while it decays. */
|
|
14
14
|
roll?: number;
|
|
15
|
-
/** +1 counted up, −1 counted down
|
|
15
|
+
/** +1 counted up, −1 counted down, direction the wheel rolls. */
|
|
16
16
|
dir?: number;
|
|
17
17
|
/** Non-zero digits read as "active" (accent); a zero is muted. */
|
|
18
18
|
active?: boolean;
|
|
@@ -32,7 +32,7 @@ declare function DigitWheel({
|
|
|
32
32
|
onTap,
|
|
33
33
|
ariaLabel
|
|
34
34
|
}: DigitWheelProps): ReactNode;
|
|
35
|
-
/** A binary ON/OFF cell
|
|
35
|
+
/** A binary ON/OFF cell, the "lightbulb worth 2^n" picture for base-2 mode. */
|
|
36
36
|
declare function BitCell({
|
|
37
37
|
on,
|
|
38
38
|
onTap,
|
|
@@ -56,7 +56,7 @@ interface WheelRowProps {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* A row of odometer wheels (or bit cells) for `value` in `base`, with the
|
|
59
|
-
* carry-ripple roll animation OWNED here
|
|
59
|
+
* carry-ripple roll animation OWNED here, the single reusable place-value
|
|
60
60
|
* primitive both PlaceValueDial and BaseOdometer compose, so the animation +
|
|
61
61
|
* weight rendering live in exactly one spot.
|
|
62
62
|
*/
|