@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/kit/logic-gates.mjs
CHANGED
|
@@ -33,16 +33,36 @@ function gatePorts(type, x, y, s) {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
+
/** Where a small TYPE label (AND/OR/…) sits INSIDE the gate body: resolved per shape so it lands
|
|
37
|
+
* on the visual centroid (the D-body of AND, the right-shifted bulge of OR/XOR, the triangle of
|
|
38
|
+
* NOT) instead of overlapping an edge. */
|
|
39
|
+
function gateLabelPos(type, x, y, s) {
|
|
40
|
+
const base = baseOf(type);
|
|
41
|
+
const cy = y + s / 2;
|
|
42
|
+
if (base === "OR" || base === "XOR") return {
|
|
43
|
+
x: x + .46 * s,
|
|
44
|
+
y: cy
|
|
45
|
+
};
|
|
46
|
+
if (base === "NOT") return {
|
|
47
|
+
x: x + .3 * s,
|
|
48
|
+
y: cy
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
x: x + .38 * s,
|
|
52
|
+
y: cy
|
|
53
|
+
};
|
|
54
|
+
}
|
|
36
55
|
/** A logic gate glyph. `live` = its OUTPUT is high. */
|
|
37
56
|
function GateGlyph({ x, y, size: s, type, live, label }) {
|
|
38
57
|
const base = baseOf(type);
|
|
39
|
-
const stroke = METAL;
|
|
58
|
+
const stroke = live ? LIVE : METAL;
|
|
59
|
+
const fill = live ? "color-mix(in oklab, var(--stage-live) 14%, var(--stage-bg))" : BG;
|
|
40
60
|
const ports = gatePorts(type, x, y, s);
|
|
41
61
|
const cy = y + s / 2;
|
|
42
62
|
let body;
|
|
43
63
|
if (base === "AND") body = /* @__PURE__ */ jsx("path", {
|
|
44
64
|
d: `M${x},${y} H${x + .36 * s} A${.5 * s},${.5 * s} 0 0 1 ${x + .36 * s},${y + s} H${x} Z`,
|
|
45
|
-
fill
|
|
65
|
+
fill,
|
|
46
66
|
stroke,
|
|
47
67
|
strokeWidth: 2,
|
|
48
68
|
strokeLinejoin: "round"
|
|
@@ -51,26 +71,19 @@ function GateGlyph({ x, y, size: s, type, live, label }) {
|
|
|
51
71
|
const ox = base === "XOR" ? x + .08 * s : x;
|
|
52
72
|
body = /* @__PURE__ */ jsx("path", {
|
|
53
73
|
d: `M${ox},${y} C${ox + .22 * s},${y + .16 * s} ${ox + .22 * s},${y + .84 * s} ${ox},${y + s} C${ox + .45 * s},${y + s} ${ox + .72 * s},${y + .82 * s} ${x + .86 * s},${cy} C${ox + .72 * s},${y + .18 * s} ${ox + .45 * s},${y} ${ox},${y} Z`,
|
|
54
|
-
fill
|
|
74
|
+
fill,
|
|
55
75
|
stroke,
|
|
56
76
|
strokeWidth: 2,
|
|
57
77
|
strokeLinejoin: "round"
|
|
58
78
|
});
|
|
59
79
|
} else body = /* @__PURE__ */ jsx("path", {
|
|
60
80
|
d: `M${x + .06 * s},${y} L${x + .7 * s},${cy} L${x + .06 * s},${y + s} Z`,
|
|
61
|
-
fill
|
|
81
|
+
fill,
|
|
62
82
|
stroke,
|
|
63
83
|
strokeWidth: 2,
|
|
64
84
|
strokeLinejoin: "round"
|
|
65
85
|
});
|
|
66
86
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
67
|
-
live && /* @__PURE__ */ jsx("circle", {
|
|
68
|
-
cx: x + .46 * s,
|
|
69
|
-
cy,
|
|
70
|
-
r: s * .62,
|
|
71
|
-
fill: LIVE,
|
|
72
|
-
opacity: .12
|
|
73
|
-
}),
|
|
74
87
|
base === "XOR" && /* @__PURE__ */ jsx("path", {
|
|
75
88
|
d: `M${x - .02 * s},${y} C${x + .2 * s},${y + .16 * s} ${x + .2 * s},${y + .84 * s} ${x - .02 * s},${y + s}`,
|
|
76
89
|
fill: "none",
|
|
@@ -103,57 +116,45 @@ function GateGlyph({ x, y, size: s, type, live, label }) {
|
|
|
103
116
|
strokeWidth: 1.4,
|
|
104
117
|
strokeLinecap: "round"
|
|
105
118
|
}),
|
|
106
|
-
label &&
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
label && (() => {
|
|
120
|
+
const lp = gateLabelPos(type, x, y, s);
|
|
121
|
+
return /* @__PURE__ */ jsx("text", {
|
|
122
|
+
x: lp.x,
|
|
123
|
+
y: lp.y,
|
|
124
|
+
fill: FG,
|
|
125
|
+
fontSize: Math.max(7, s * .17),
|
|
126
|
+
fontWeight: 700,
|
|
127
|
+
textAnchor: "middle",
|
|
128
|
+
dominantBaseline: "central",
|
|
129
|
+
style: { pointerEvents: "none" },
|
|
130
|
+
children: label
|
|
131
|
+
});
|
|
132
|
+
})()
|
|
117
133
|
] });
|
|
118
134
|
}
|
|
119
|
-
/** An output LED
|
|
135
|
+
/** An output LED: a clean filled disc (lit = `color`, idle = a faint outlined disc). No glow. */
|
|
120
136
|
function Lamp({ cx, cy, r, on, color = LIVE, label }) {
|
|
121
|
-
const lit = color;
|
|
122
137
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
123
|
-
on && /* @__PURE__ */ jsx("circle", {
|
|
124
|
-
cx,
|
|
125
|
-
cy,
|
|
126
|
-
r: r * 2.1,
|
|
127
|
-
fill: lit,
|
|
128
|
-
opacity: .18
|
|
129
|
-
}),
|
|
130
|
-
on && /* @__PURE__ */ jsx("circle", {
|
|
131
|
-
cx,
|
|
132
|
-
cy,
|
|
133
|
-
r: r * 1.45,
|
|
134
|
-
fill: lit,
|
|
135
|
-
opacity: .28
|
|
136
|
-
}),
|
|
137
138
|
/* @__PURE__ */ jsx("circle", {
|
|
138
139
|
cx,
|
|
139
140
|
cy,
|
|
140
141
|
r,
|
|
141
|
-
fill: on ?
|
|
142
|
-
stroke: on ?
|
|
142
|
+
fill: on ? color : "color-mix(in oklab, var(--stage-metal) 14%, var(--stage-bg))",
|
|
143
|
+
stroke: on ? color : METAL,
|
|
143
144
|
strokeWidth: 1.5
|
|
144
145
|
}),
|
|
145
146
|
/* @__PURE__ */ jsx("circle", {
|
|
146
|
-
cx: cx - r * .
|
|
147
|
-
cy: cy - r * .
|
|
148
|
-
r: r * .
|
|
147
|
+
cx: cx - r * .28,
|
|
148
|
+
cy: cy - r * .3,
|
|
149
|
+
r: r * .28,
|
|
149
150
|
fill: SHEEN,
|
|
150
|
-
opacity: on ? .
|
|
151
|
+
opacity: on ? .5 : .2
|
|
151
152
|
}),
|
|
152
153
|
label && /* @__PURE__ */ jsx("text", {
|
|
153
154
|
x: cx,
|
|
154
|
-
y: cy + r +
|
|
155
|
+
y: cy + r + 5,
|
|
155
156
|
fill: FG,
|
|
156
|
-
fontSize: Math.max(8, r * .
|
|
157
|
+
fontSize: Math.max(8, r * .85),
|
|
157
158
|
fontWeight: 700,
|
|
158
159
|
textAnchor: "middle",
|
|
159
160
|
dominantBaseline: "hanging",
|
|
@@ -162,6 +163,204 @@ function Lamp({ cx, cy, r, on, color = LIVE, label }) {
|
|
|
162
163
|
})
|
|
163
164
|
] });
|
|
164
165
|
}
|
|
166
|
+
/** Which of segments a–g are lit for each hex digit 0–F (decoder truth, for a 7-seg display). */
|
|
167
|
+
const SEG_MAP = [
|
|
168
|
+
[
|
|
169
|
+
1,
|
|
170
|
+
1,
|
|
171
|
+
1,
|
|
172
|
+
1,
|
|
173
|
+
1,
|
|
174
|
+
1,
|
|
175
|
+
0
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
0,
|
|
179
|
+
1,
|
|
180
|
+
1,
|
|
181
|
+
0,
|
|
182
|
+
0,
|
|
183
|
+
0,
|
|
184
|
+
0
|
|
185
|
+
],
|
|
186
|
+
[
|
|
187
|
+
1,
|
|
188
|
+
1,
|
|
189
|
+
0,
|
|
190
|
+
1,
|
|
191
|
+
1,
|
|
192
|
+
0,
|
|
193
|
+
1
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
1,
|
|
197
|
+
1,
|
|
198
|
+
1,
|
|
199
|
+
1,
|
|
200
|
+
0,
|
|
201
|
+
0,
|
|
202
|
+
1
|
|
203
|
+
],
|
|
204
|
+
[
|
|
205
|
+
0,
|
|
206
|
+
1,
|
|
207
|
+
1,
|
|
208
|
+
0,
|
|
209
|
+
0,
|
|
210
|
+
1,
|
|
211
|
+
1
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
1,
|
|
215
|
+
0,
|
|
216
|
+
1,
|
|
217
|
+
1,
|
|
218
|
+
0,
|
|
219
|
+
1,
|
|
220
|
+
1
|
|
221
|
+
],
|
|
222
|
+
[
|
|
223
|
+
1,
|
|
224
|
+
0,
|
|
225
|
+
1,
|
|
226
|
+
1,
|
|
227
|
+
1,
|
|
228
|
+
1,
|
|
229
|
+
1
|
|
230
|
+
],
|
|
231
|
+
[
|
|
232
|
+
1,
|
|
233
|
+
1,
|
|
234
|
+
1,
|
|
235
|
+
0,
|
|
236
|
+
0,
|
|
237
|
+
0,
|
|
238
|
+
0
|
|
239
|
+
],
|
|
240
|
+
[
|
|
241
|
+
1,
|
|
242
|
+
1,
|
|
243
|
+
1,
|
|
244
|
+
1,
|
|
245
|
+
1,
|
|
246
|
+
1,
|
|
247
|
+
1
|
|
248
|
+
],
|
|
249
|
+
[
|
|
250
|
+
1,
|
|
251
|
+
1,
|
|
252
|
+
1,
|
|
253
|
+
1,
|
|
254
|
+
0,
|
|
255
|
+
1,
|
|
256
|
+
1
|
|
257
|
+
],
|
|
258
|
+
[
|
|
259
|
+
1,
|
|
260
|
+
1,
|
|
261
|
+
1,
|
|
262
|
+
0,
|
|
263
|
+
1,
|
|
264
|
+
1,
|
|
265
|
+
1
|
|
266
|
+
],
|
|
267
|
+
[
|
|
268
|
+
0,
|
|
269
|
+
0,
|
|
270
|
+
1,
|
|
271
|
+
1,
|
|
272
|
+
1,
|
|
273
|
+
1,
|
|
274
|
+
1
|
|
275
|
+
],
|
|
276
|
+
[
|
|
277
|
+
1,
|
|
278
|
+
0,
|
|
279
|
+
0,
|
|
280
|
+
1,
|
|
281
|
+
1,
|
|
282
|
+
1,
|
|
283
|
+
0
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
0,
|
|
287
|
+
1,
|
|
288
|
+
1,
|
|
289
|
+
1,
|
|
290
|
+
1,
|
|
291
|
+
0,
|
|
292
|
+
1
|
|
293
|
+
],
|
|
294
|
+
[
|
|
295
|
+
1,
|
|
296
|
+
0,
|
|
297
|
+
0,
|
|
298
|
+
1,
|
|
299
|
+
1,
|
|
300
|
+
1,
|
|
301
|
+
1
|
|
302
|
+
],
|
|
303
|
+
[
|
|
304
|
+
1,
|
|
305
|
+
0,
|
|
306
|
+
0,
|
|
307
|
+
0,
|
|
308
|
+
1,
|
|
309
|
+
1,
|
|
310
|
+
1
|
|
311
|
+
]
|
|
312
|
+
].map((r) => r.map(Boolean));
|
|
313
|
+
function digitSegments(value) {
|
|
314
|
+
return SEG_MAP[(value % 16 + 16) % 16];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* A seven-segment display digit. Drive it with a `value` (0–15 → 0–F) or explicit `segs`
|
|
318
|
+
* (a..g booleans). Lit segments glow in the display colour; dark segments are a faint ghost,
|
|
319
|
+
* so you read it like a real LED display. This is the output for binary/decoder/DLD labs.
|
|
320
|
+
*/
|
|
321
|
+
function SevenSegment({ x, y, w = 46, h = 80, value, segs, color = "var(--stage-warn)" }) {
|
|
322
|
+
const on = segs ?? (value !== void 0 ? digitSegments(value) : [
|
|
323
|
+
false,
|
|
324
|
+
false,
|
|
325
|
+
false,
|
|
326
|
+
false,
|
|
327
|
+
false,
|
|
328
|
+
false,
|
|
329
|
+
false
|
|
330
|
+
]);
|
|
331
|
+
const t = Math.min(w, h) * .13;
|
|
332
|
+
const off = "color-mix(in oklab, var(--stage-metal) 16%, transparent)";
|
|
333
|
+
const seg = (key, lit, x1, y1, x2, y2) => /* @__PURE__ */ jsx("line", {
|
|
334
|
+
x1,
|
|
335
|
+
y1,
|
|
336
|
+
x2,
|
|
337
|
+
y2,
|
|
338
|
+
stroke: lit ? color : off,
|
|
339
|
+
strokeWidth: t,
|
|
340
|
+
strokeLinecap: "round",
|
|
341
|
+
opacity: lit ? 1 : .55
|
|
342
|
+
}, key);
|
|
343
|
+
const midY = y + h / 2;
|
|
344
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
345
|
+
/* @__PURE__ */ jsx("rect", {
|
|
346
|
+
x: x - t,
|
|
347
|
+
y: y - t,
|
|
348
|
+
width: w + 2 * t,
|
|
349
|
+
height: h + 2 * t,
|
|
350
|
+
rx: 6,
|
|
351
|
+
fill: "color-mix(in oklab, var(--stage-bg) 80%, var(--stage-metal))",
|
|
352
|
+
stroke: "var(--stage-grid)",
|
|
353
|
+
strokeWidth: 1
|
|
354
|
+
}),
|
|
355
|
+
seg("a", on[0], x + t, y, x + w - t, y),
|
|
356
|
+
seg("b", on[1], x + w, y + t, x + w, midY - t * .5),
|
|
357
|
+
seg("c", on[2], x + w, midY + t * .5, x + w, y + h - t),
|
|
358
|
+
seg("d", on[3], x + t, y + h, x + w - t, y + h),
|
|
359
|
+
seg("e", on[4], x, midY + t * .5, x, y + h - t),
|
|
360
|
+
seg("f", on[5], x, y + t, x, midY - t * .5),
|
|
361
|
+
seg("g", on[6], x + t, midY, x + w - t, midY)
|
|
362
|
+
] });
|
|
363
|
+
}
|
|
165
364
|
/** An input switch (toggle). Render inside a `<g onClick>` in the lab for taps. */
|
|
166
365
|
function ToggleSwitch({ x, y, w, h, on, label }) {
|
|
167
366
|
const r = h / 2;
|
|
@@ -207,4 +406,4 @@ function ToggleSwitch({ x, y, w, h, on, label }) {
|
|
|
207
406
|
}
|
|
208
407
|
|
|
209
408
|
//#endregion
|
|
210
|
-
export { GateGlyph, Lamp, ToggleSwitch, gatePorts };
|
|
409
|
+
export { GateGlyph, Lamp, SevenSegment, ToggleSwitch, gatePorts };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/kit/palette.ts
|
|
2
|
+
/**
|
|
3
|
+
* Categorical colour palette, theme-aware. The eight hues live as CSS custom
|
|
4
|
+
* properties (`--stage-cat-1`..`--stage-cat-8`) in @classytic/stage's styles.css,
|
|
5
|
+
* with tuned LIGHT (:root) and DARK (.dark) values, so a series/group colour
|
|
6
|
+
* adapts to the theme instead of being a fixed hex that only reads on one
|
|
7
|
+
* background. Labs import these instead of hardcoding their own hex arrays.
|
|
8
|
+
*
|
|
9
|
+
* • SVG / CSS labs → CATEGORICAL (var(--stage-cat-N) strings)
|
|
10
|
+
* • canvas labs that read tokens via getComputedStyle().getPropertyValue()
|
|
11
|
+
* → CATEGORICAL_TOKENS (the bare custom-property names)
|
|
12
|
+
*
|
|
13
|
+
* cat-1/2/3 align with --stage-accent / --stage-accent-2 / --stage-good.
|
|
14
|
+
*/
|
|
15
|
+
const N = 8;
|
|
16
|
+
/** `var(--stage-cat-N)` strings — drop straight into SVG fill/stroke or CSS. */
|
|
17
|
+
const CATEGORICAL = Array.from({ length: N }, (_, i) => `var(--stage-cat-${i + 1})`);
|
|
18
|
+
/** Bare custom-property names — for canvas labs that resolve via getPropertyValue. */
|
|
19
|
+
const CATEGORICAL_TOKENS = Array.from({ length: N }, (_, i) => `--stage-cat-${i + 1}`);
|
|
20
|
+
/** The i-th categorical colour (var string), wrapping. */
|
|
21
|
+
const catColor = (i) => CATEGORICAL[(i % N + N) % N];
|
|
22
|
+
/** The i-th categorical token name (for canvas getPropertyValue), wrapping. */
|
|
23
|
+
const catToken = (i) => CATEGORICAL_TOKENS[(i % N + N) % N];
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { CATEGORICAL, catColor, catToken };
|
package/dist/kit/pedagogy.d.mts
CHANGED
|
@@ -36,7 +36,7 @@ interface Hints {
|
|
|
36
36
|
reveal: () => void;
|
|
37
37
|
reset: () => void;
|
|
38
38
|
}
|
|
39
|
-
/** Progressive hint state
|
|
39
|
+
/** Progressive hint state, reveal one at a time. */
|
|
40
40
|
declare function useHints(hints?: string[]): Hints;
|
|
41
41
|
/** Learner-visible goal banner ("You'll be able to …"). */
|
|
42
42
|
declare function Objectives({
|
|
@@ -44,7 +44,7 @@ declare function Objectives({
|
|
|
44
44
|
}: {
|
|
45
45
|
items?: string[];
|
|
46
46
|
}): ReactNode;
|
|
47
|
-
/** The hint ladder
|
|
47
|
+
/** The hint ladder, revealed hints + a "need a hint?" button while more remain. */
|
|
48
48
|
declare function HintLadder({
|
|
49
49
|
hints
|
|
50
50
|
}: {
|
|
@@ -104,14 +104,14 @@ interface RevealSolutionProps {
|
|
|
104
104
|
solution: ReactNode;
|
|
105
105
|
/** Gate the button (e.g. only after a wrong attempt). Default: always shown. */
|
|
106
106
|
available?: boolean;
|
|
107
|
-
/** Fired ONCE when the learner reveals
|
|
107
|
+
/** Fired ONCE when the learner reveals, let the lab dock the score (peek ≠ solve). */
|
|
108
108
|
onReveal?: () => void;
|
|
109
109
|
buttonLabel?: string;
|
|
110
110
|
/** The warning shown with the solution. */
|
|
111
111
|
note?: string;
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
-
* The shared "Show answer" escape hatch
|
|
114
|
+
* The shared "Show answer" escape hatch, so no lab is a dead-end "wrong/right".
|
|
115
115
|
* Manages its own shown/hidden; `key` it (e.g. per step/event) to reset between
|
|
116
116
|
* questions. Revealing is a deliberate peek: it warns and reports via `onReveal`.
|
|
117
117
|
*/
|
package/dist/kit/pedagogy.mjs
CHANGED
|
@@ -6,23 +6,23 @@ import { useLearner } from "@classytic/stage";
|
|
|
6
6
|
|
|
7
7
|
//#region src/kit/pedagogy.tsx
|
|
8
8
|
/**
|
|
9
|
-
* Pedagogy/assessment kit
|
|
9
|
+
* Pedagogy/assessment kit, the formative-feedback layer every lab shares.
|
|
10
10
|
*
|
|
11
11
|
* `LabMeta` (objectives, hints, misconceptions, successCriteria) was authored
|
|
12
12
|
* but never rendered. This turns it into the Brilliant-style loop:
|
|
13
|
-
* • `useCheckpoint
|
|
13
|
+
* • `useCheckpoint`, the ONE assessment seam: report once on first solve,
|
|
14
14
|
* with a hint penalty folded into the score. Kills the per-lab
|
|
15
15
|
* `if (x === answer) report(...)` + done-ref boilerplate.
|
|
16
|
-
* • `useHints` + `<HintLadder
|
|
16
|
+
* • `useHints` + `<HintLadder>`, progressive reveal; each hint taken docks
|
|
17
17
|
* the score (pass `hints.count` to useCheckpoint).
|
|
18
|
-
* • `<Objectives
|
|
19
|
-
* • `<Feedback
|
|
18
|
+
* • `<Objectives>`, the learner-visible goal banner.
|
|
19
|
+
* • `<Feedback>`, unifies success / try-again / misconception note (the
|
|
20
20
|
* misconception is a boolean the lab computes from resolved state).
|
|
21
|
-
* • `<RevealSolution
|
|
21
|
+
* • `<RevealSolution>`, the shared "Show answer" escape hatch every lab gets:
|
|
22
22
|
* a button → a warned solution panel, firing `onReveal` once so the lab can
|
|
23
23
|
* dock the score (peeking ≠ solving). No more dead-end "wrong/right".
|
|
24
24
|
*
|
|
25
|
-
* Domain glue over stage's learner seam
|
|
25
|
+
* Domain glue over stage's learner seam, stays in labs so stage is a pure
|
|
26
26
|
* engine; imports only `useLearner` from @classytic/stage.
|
|
27
27
|
*/
|
|
28
28
|
/** Report completion once, the first time `solved` becomes true. */
|
|
@@ -69,7 +69,7 @@ function useCheckpoint({ solved, activity, score, hintsUsed = 0, hintPenalty = .
|
|
|
69
69
|
reported
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
-
/** Progressive hint state
|
|
72
|
+
/** Progressive hint state, reveal one at a time. */
|
|
73
73
|
function useHints(hints = []) {
|
|
74
74
|
const [n, setN] = useState(0);
|
|
75
75
|
return {
|
|
@@ -91,7 +91,7 @@ function Objectives({ items }) {
|
|
|
91
91
|
}), /* @__PURE__ */ jsx("ul", { children: items.map((o, i) => /* @__PURE__ */ jsx("li", { children: o }, i)) })]
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
/** The hint ladder
|
|
94
|
+
/** The hint ladder, revealed hints + a "need a hint?" button while more remain. */
|
|
95
95
|
function HintLadder({ hints }) {
|
|
96
96
|
if (hints.revealed.length === 0 && !hints.hasMore) return null;
|
|
97
97
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -147,16 +147,20 @@ function ChallengeCard({ questions, state, title = "Predict first" }) {
|
|
|
147
147
|
state.total
|
|
148
148
|
]
|
|
149
149
|
})]
|
|
150
|
-
}), questions.map((q) => {
|
|
150
|
+
}), questions.map((q, i) => {
|
|
151
151
|
const picked = state.picks[q.id];
|
|
152
152
|
const answered = picked != null;
|
|
153
153
|
const correct = picked === q.answer;
|
|
154
154
|
return /* @__PURE__ */ jsxs("div", {
|
|
155
155
|
className: "lab-challenge-q",
|
|
156
156
|
children: [
|
|
157
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ jsxs("span", {
|
|
158
158
|
className: "lab-challenge-prompt",
|
|
159
|
-
children:
|
|
159
|
+
children: [questions.length > 1 && /* @__PURE__ */ jsx("span", {
|
|
160
|
+
className: "lab-challenge-num",
|
|
161
|
+
"aria-hidden": true,
|
|
162
|
+
children: i + 1
|
|
163
|
+
}), /* @__PURE__ */ jsx("span", { children: q.prompt })]
|
|
160
164
|
}),
|
|
161
165
|
/* @__PURE__ */ jsx("div", {
|
|
162
166
|
className: "lab-choices",
|
|
@@ -185,7 +189,7 @@ function ChallengeCard({ questions, state, title = "Predict first" }) {
|
|
|
185
189
|
className: "lab-pill",
|
|
186
190
|
"data-state": "no",
|
|
187
191
|
role: "status",
|
|
188
|
-
children: "Not yet
|
|
192
|
+
children: "Not yet, try again"
|
|
189
193
|
}))
|
|
190
194
|
]
|
|
191
195
|
}, q.id);
|
|
@@ -244,7 +248,7 @@ function AskBox({ prompt, placeholder = "your answer", check, activity }) {
|
|
|
244
248
|
className: "lab-pill",
|
|
245
249
|
"data-state": "no",
|
|
246
250
|
role: "status",
|
|
247
|
-
children: "Not yet
|
|
251
|
+
children: "Not yet, try again"
|
|
248
252
|
})
|
|
249
253
|
]
|
|
250
254
|
}),
|
|
@@ -263,7 +267,7 @@ function AskBox({ prompt, placeholder = "your answer", check, activity }) {
|
|
|
263
267
|
});
|
|
264
268
|
}
|
|
265
269
|
/** Unified success / misconception / try-again feedback. */
|
|
266
|
-
function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet
|
|
270
|
+
function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet, keep going" }) {
|
|
267
271
|
if (ok) return /* @__PURE__ */ jsxs("span", {
|
|
268
272
|
className: "lab-pill",
|
|
269
273
|
"data-state": "ok",
|
|
@@ -288,11 +292,11 @@ function Feedback({ ok, misconception, okText = "Correct", tryText = "Not yet
|
|
|
288
292
|
});
|
|
289
293
|
}
|
|
290
294
|
/**
|
|
291
|
-
* The shared "Show answer" escape hatch
|
|
295
|
+
* The shared "Show answer" escape hatch, so no lab is a dead-end "wrong/right".
|
|
292
296
|
* Manages its own shown/hidden; `key` it (e.g. per step/event) to reset between
|
|
293
297
|
* questions. Revealing is a deliberate peek: it warns and reports via `onReveal`.
|
|
294
298
|
*/
|
|
295
|
-
function RevealSolution({ solution, available = true, onReveal, buttonLabel = "Show answer", note = "Peeking
|
|
299
|
+
function RevealSolution({ solution, available = true, onReveal, buttonLabel = "Show answer", note = "Peeking, this one won’t count as solved on your own." }) {
|
|
296
300
|
const [shown, setShown] = useState(false);
|
|
297
301
|
if (shown) return /* @__PURE__ */ jsxs("div", {
|
|
298
302
|
className: "lab-solution",
|
package/dist/kit/play.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ interface PlayGate {
|
|
|
6
6
|
inView: boolean;
|
|
7
7
|
playing: boolean;
|
|
8
8
|
setPlaying: (p: boolean) => void;
|
|
9
|
-
/** playing && inView
|
|
9
|
+
/** playing && inView, pass to useFrameLoop's `running`. */
|
|
10
10
|
running: boolean;
|
|
11
11
|
}
|
|
12
12
|
declare function usePlayGate(autoPlay?: boolean): PlayGate;
|
package/dist/kit/play.mjs
CHANGED
|
@@ -8,9 +8,9 @@ import { useInView } from "@classytic/stage";
|
|
|
8
8
|
/**
|
|
9
9
|
* Play-gate for hand-driven sim labs (those running their own useFrameLoop rather
|
|
10
10
|
* than going through <Scene>, which already has this). It does two things:
|
|
11
|
-
* • off-screen pause
|
|
11
|
+
* • off-screen pause, the loop only runs while the figure is visible, so a page
|
|
12
12
|
* of labs doesn't pin the CPU;
|
|
13
|
-
* • press-to-start
|
|
13
|
+
* • press-to-start, an ambient animation shouldn't auto-run; show a ▶ Play
|
|
14
14
|
* overlay until the learner starts it.
|
|
15
15
|
*
|
|
16
16
|
* Usage:
|
|
@@ -19,7 +19,7 @@ import { useInView } from "@classytic/stage";
|
|
|
19
19
|
* … <PlayWrap gate={gate}>{figureSvg}</PlayWrap>
|
|
20
20
|
*
|
|
21
21
|
* For a USER-TRIGGERED lab (a Run/Drop button already decides when to animate),
|
|
22
|
-
* skip the overlay
|
|
22
|
+
* skip the overlay, just gate the existing condition on visibility with `useInView`.
|
|
23
23
|
*/
|
|
24
24
|
function usePlayGate(autoPlay = false) {
|
|
25
25
|
const { ref, inView } = useInView();
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { GuessTone } from "./vessel.mjs";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
import { Vec2 } from "@classytic/stage";
|
|
4
|
+
|
|
5
|
+
//#region src/kit/predict.d.ts
|
|
6
|
+
interface PredictPlotProps {
|
|
7
|
+
/** Given data points, already plotted (the pattern to extend). */
|
|
8
|
+
data: Vec2[];
|
|
9
|
+
/** The controlled ghost point the learner drags. */
|
|
10
|
+
guess: Vec2;
|
|
11
|
+
onGuess: (p: Vec2, phase: 'move' | 'commit') => void;
|
|
12
|
+
/** Colour the ghost by correctness (parent decides). */
|
|
13
|
+
tone?: GuessTone;
|
|
14
|
+
/** First-quadrant window; axes sit at the corner. */
|
|
15
|
+
xMax: number;
|
|
16
|
+
yMax: number;
|
|
17
|
+
xStep?: number;
|
|
18
|
+
yStep?: number;
|
|
19
|
+
xLabel?: string;
|
|
20
|
+
yLabel?: string;
|
|
21
|
+
height?: number;
|
|
22
|
+
/** Lock the ghost to its x (vertical drag only). Default true , predict the y. */
|
|
23
|
+
lockX?: boolean;
|
|
24
|
+
/** Snap the ghost to the grid on drag. Default true. */
|
|
25
|
+
snap?: boolean;
|
|
26
|
+
/** Draw the underlying rule line y = slope·x + intercept (e.g. once solved). */
|
|
27
|
+
rule?: {
|
|
28
|
+
slope: number;
|
|
29
|
+
intercept: number;
|
|
30
|
+
} | null;
|
|
31
|
+
/** Faint guide column at x = guess.x so the learner sees which input they're on. */
|
|
32
|
+
showColumn?: boolean;
|
|
33
|
+
/** Readout the guess coordinate as a label by the ghost. */
|
|
34
|
+
readout?: boolean;
|
|
35
|
+
}
|
|
36
|
+
declare function PredictPlot({
|
|
37
|
+
data,
|
|
38
|
+
guess,
|
|
39
|
+
onGuess,
|
|
40
|
+
tone,
|
|
41
|
+
xMax,
|
|
42
|
+
yMax,
|
|
43
|
+
xStep,
|
|
44
|
+
yStep,
|
|
45
|
+
xLabel,
|
|
46
|
+
yLabel,
|
|
47
|
+
height,
|
|
48
|
+
lockX,
|
|
49
|
+
snap,
|
|
50
|
+
rule,
|
|
51
|
+
showColumn,
|
|
52
|
+
readout
|
|
53
|
+
}: PredictPlotProps): ReactNode;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { PredictPlot, PredictPlotProps };
|