@classytic/stage 0.2.0 → 0.4.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/LICENSE +1 -1
- package/README.md +5 -1
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/assets/index.mjs +0 -1
- package/dist/atomic/aufbau.d.mts +144 -0
- package/dist/atomic/aufbau.mjs +384 -0
- package/dist/atomic/elements.d.mts +67 -0
- package/dist/atomic/elements.mjs +785 -0
- package/dist/atomic/emission.d.mts +112 -0
- package/dist/atomic/emission.mjs +179 -0
- package/dist/atomic/index.d.mts +8 -0
- package/dist/atomic/index.mjs +9 -0
- package/dist/atomic/periodic.d.mts +82 -0
- package/dist/atomic/periodic.mjs +231 -0
- package/dist/atomic/properties.d.mts +100 -0
- package/dist/atomic/properties.mjs +574 -0
- package/dist/atomic/shells.d.mts +137 -0
- package/dist/atomic/shells.mjs +170 -0
- package/dist/atomic/trends.d.mts +148 -0
- package/dist/atomic/trends.mjs +225 -0
- package/dist/builder/Palette.mjs +50 -89
- package/dist/builder/SceneBuilder.mjs +15 -73
- package/dist/chem/chromatography.d.mts +66 -0
- package/dist/chem/chromatography.mjs +63 -0
- package/dist/chem/complex.d.mts +114 -0
- package/dist/chem/complex.mjs +234 -0
- package/dist/chem/cycle.d.mts +75 -0
- package/dist/chem/cycle.mjs +145 -0
- package/dist/chem/equation.d.mts +86 -0
- package/dist/chem/equation.mjs +168 -0
- package/dist/chem/formula.d.mts +90 -0
- package/dist/chem/formula.mjs +201 -0
- package/dist/chem/functional-groups.d.mts +31 -0
- package/dist/chem/functional-groups.mjs +187 -0
- package/dist/chem/hazard.d.mts +94 -0
- package/dist/chem/hazard.mjs +329 -0
- package/dist/chem/index.d.mts +34 -33
- package/dist/chem/index.mjs +34 -28
- package/dist/chem/ionic.d.mts +98 -0
- package/dist/chem/ionic.mjs +156 -0
- package/dist/chem/layout.d.mts +46 -0
- package/dist/chem/layout.mjs +342 -0
- package/dist/chem/lewis.d.mts +79 -0
- package/dist/chem/lewis.mjs +163 -0
- package/dist/chem/molecular-orbital.d.mts +114 -0
- package/dist/chem/molecular-orbital.mjs +201 -0
- package/dist/chem/molecule.d.mts +154 -0
- package/dist/chem/molecule.mjs +282 -0
- package/dist/chem/nmr.d.mts +153 -0
- package/dist/chem/nmr.mjs +165 -0
- package/dist/chem/polymer.d.mts +65 -0
- package/dist/chem/polymer.mjs +179 -0
- package/dist/chem/redox.d.mts +138 -0
- package/dist/chem/redox.mjs +328 -0
- package/dist/chem/relations.d.mts +183 -0
- package/dist/chem/relations.mjs +299 -0
- package/dist/chem/skeleton.d.mts +51 -0
- package/dist/chem/skeleton.mjs +186 -0
- package/dist/chem/solution.d.mts +116 -0
- package/dist/chem/solution.mjs +186 -0
- package/dist/chem/species.d.mts +47 -0
- package/dist/chem/species.mjs +128 -0
- package/dist/chem/stereo.d.mts +108 -0
- package/dist/chem/stereo.mjs +286 -0
- package/dist/chem/stoichiometry.d.mts +95 -0
- package/dist/chem/stoichiometry.mjs +145 -0
- package/dist/chem/synthesis.d.mts +113 -0
- package/dist/chem/synthesis.mjs +281 -0
- package/dist/chem/vsepr.d.mts +80 -0
- package/dist/chem/vsepr.mjs +247 -0
- package/dist/circuit/ac.d.mts +163 -0
- package/dist/circuit/ac.mjs +452 -0
- package/dist/circuit/dc.d.mts +92 -0
- package/dist/circuit/dc.mjs +333 -0
- package/dist/circuit/index.d.mts +5 -92
- package/dist/circuit/index.mjs +5 -332
- package/dist/circuit/network.d.mts +99 -0
- package/dist/circuit/network.mjs +440 -0
- package/dist/circuit/topology.d.mts +102 -0
- package/dist/circuit/topology.mjs +143 -0
- package/dist/colour/absorption.d.mts +79 -0
- package/dist/colour/absorption.mjs +137 -0
- package/dist/colour/index.d.mts +6 -0
- package/dist/colour/index.mjs +7 -0
- package/dist/colour/name.d.mts +14 -0
- package/dist/colour/name.mjs +76 -0
- package/dist/colour/observer.d.mts +31 -0
- package/dist/colour/observer.mjs +46 -0
- package/dist/colour/spectrum.d.mts +61 -0
- package/dist/colour/spectrum.mjs +108 -0
- package/dist/colour/srgb.d.mts +49 -0
- package/dist/colour/srgb.mjs +108 -0
- package/dist/core/constants.d.mts +138 -0
- package/dist/core/constants.mjs +139 -0
- package/dist/core/index.d.mts +4 -1
- package/dist/core/index.mjs +4 -1
- package/dist/core/math.d.mts +26 -0
- package/dist/core/math.mjs +37 -0
- package/dist/core/vec3.d.mts +94 -0
- package/dist/core/vec3.mjs +123 -0
- package/dist/core/worked.d.mts +35 -0
- package/dist/core/worked.mjs +44 -0
- package/dist/electro/cell.d.mts +102 -0
- package/dist/electro/cell.mjs +170 -0
- package/dist/electro/conductivity.d.mts +157 -0
- package/dist/electro/conductivity.mjs +156 -0
- package/dist/electro/couples.d.mts +114 -0
- package/dist/electro/couples.mjs +334 -0
- package/dist/electro/electrolysis.d.mts +96 -0
- package/dist/electro/electrolysis.mjs +274 -0
- package/dist/electro/faraday.d.mts +150 -0
- package/dist/electro/faraday.mjs +118 -0
- package/dist/electro/index.d.mts +6 -0
- package/dist/electro/index.mjs +7 -0
- package/dist/finance/accounting/adjustments.d.mts +17 -0
- package/dist/finance/accounting/adjustments.mjs +202 -0
- package/dist/finance/accounting/analysis.d.mts +8 -0
- package/dist/finance/accounting/analysis.mjs +205 -0
- package/dist/finance/accounting/clubs.d.mts +21 -0
- package/dist/finance/accounting/clubs.mjs +217 -0
- package/dist/finance/accounting/company-statements.d.mts +7 -0
- package/dist/finance/accounting/company-statements.mjs +150 -0
- package/dist/finance/accounting/harness.d.mts +7 -0
- package/dist/finance/accounting/harness.mjs +45 -0
- package/dist/finance/accounting/index.d.mts +18 -0
- package/dist/finance/accounting/index.mjs +18 -0
- package/dist/finance/accounting/journalize.d.mts +16 -0
- package/dist/finance/accounting/journalize.mjs +128 -0
- package/dist/finance/accounting/manufacturing.d.mts +8 -0
- package/dist/finance/accounting/manufacturing.mjs +236 -0
- package/dist/finance/accounting/partnership.d.mts +7 -0
- package/dist/finance/accounting/partnership.mjs +152 -0
- package/dist/finance/accounting/period-case.d.mts +6 -0
- package/dist/finance/accounting/period-case.mjs +71 -0
- package/dist/finance/accounting/post.d.mts +9 -0
- package/dist/finance/accounting/post.mjs +84 -0
- package/dist/finance/accounting/precision.d.mts +9 -0
- package/dist/finance/accounting/precision.mjs +15 -0
- package/dist/finance/accounting/rules.d.mts +21 -0
- package/dist/finance/accounting/rules.mjs +37 -0
- package/dist/finance/accounting/solve.d.mts +28 -0
- package/dist/finance/accounting/solve.mjs +92 -0
- package/dist/finance/accounting/statements.d.mts +7 -0
- package/dist/finance/accounting/statements.mjs +142 -0
- package/dist/finance/accounting/types.d.mts +649 -0
- package/dist/finance/accounting/validate.d.mts +7 -0
- package/dist/finance/accounting/validate.mjs +67 -0
- package/dist/finance/accounting/verification.d.mts +24 -0
- package/dist/finance/accounting/verification.mjs +386 -0
- package/dist/finance/bizsim.d.mts +75 -0
- package/dist/finance/bizsim.mjs +296 -0
- package/dist/finance/index.d.mts +95 -0
- package/dist/finance/index.mjs +145 -0
- package/dist/finance/investment-math.d.mts +7 -0
- package/dist/finance/investment-math.mjs +18 -0
- package/dist/finance/management-accounting/budgeting.d.mts +7 -0
- package/dist/finance/management-accounting/budgeting.mjs +189 -0
- package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
- package/dist/finance/management-accounting/cash-budget.mjs +154 -0
- package/dist/finance/management-accounting/costing.d.mts +8 -0
- package/dist/finance/management-accounting/costing.mjs +175 -0
- package/dist/finance/management-accounting/decisions.d.mts +8 -0
- package/dist/finance/management-accounting/decisions.mjs +164 -0
- package/dist/finance/management-accounting/index.d.mts +13 -0
- package/dist/finance/management-accounting/index.mjs +13 -0
- package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
- package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
- package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
- package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
- package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
- package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
- package/dist/finance/management-accounting/management-case.d.mts +8 -0
- package/dist/finance/management-accounting/management-case.mjs +91 -0
- package/dist/finance/management-accounting/master-budget.d.mts +7 -0
- package/dist/finance/management-accounting/master-budget.mjs +137 -0
- package/dist/finance/management-accounting/production-costing.d.mts +8 -0
- package/dist/finance/management-accounting/production-costing.mjs +214 -0
- package/dist/finance/management-accounting/types.d.mts +644 -0
- package/dist/finance/management-accounting/variances.d.mts +7 -0
- package/dist/finance/management-accounting/variances.mjs +150 -0
- package/dist/index.d.mts +9 -8
- package/dist/index.mjs +5 -5
- package/dist/interaction/MovableDot.mjs +19 -0
- package/dist/interaction/useDraggable.mjs +24 -4
- package/dist/math/analysis.d.mts +61 -0
- package/dist/math/analysis.mjs +187 -0
- package/dist/math/answer-check.d.mts +50 -0
- package/dist/math/answer-check.mjs +106 -0
- package/dist/math/calculus.d.mts +17 -1
- package/dist/math/calculus.mjs +365 -2
- package/dist/math/complex.d.mts +93 -0
- package/dist/math/complex.mjs +239 -0
- package/dist/math/expr.d.mts +23 -0
- package/dist/math/expr.mjs +36 -0
- package/dist/math/index.d.mts +9 -23
- package/dist/math/index.mjs +9 -38
- package/dist/math/latex.mjs +10 -1
- package/dist/math/parse.mjs +1 -1
- package/dist/math/poly.d.mts +55 -0
- package/dist/math/poly.mjs +273 -0
- package/dist/math/rearrange.d.mts +14 -0
- package/dist/math/rearrange.mjs +125 -0
- package/dist/math/solve.d.mts +21 -0
- package/dist/math/solve.mjs +75 -0
- package/dist/networking/addressing.d.mts +26 -0
- package/dist/networking/addressing.mjs +33 -0
- package/dist/networking/cloud/access.d.mts +36 -0
- package/dist/networking/cloud/access.mjs +95 -0
- package/dist/networking/cloud/containers.d.mts +43 -0
- package/dist/networking/cloud/containers.mjs +54 -0
- package/dist/networking/cloud/edge.d.mts +17 -0
- package/dist/networking/cloud/edge.mjs +31 -0
- package/dist/networking/cloud/failure-domains.d.mts +19 -0
- package/dist/networking/cloud/failure-domains.mjs +22 -0
- package/dist/networking/cloud/geo-routing.d.mts +22 -0
- package/dist/networking/cloud/geo-routing.mjs +64 -0
- package/dist/networking/cloud/index.d.mts +18 -0
- package/dist/networking/cloud/index.mjs +19 -0
- package/dist/networking/cloud/inference-reliability.d.mts +30 -0
- package/dist/networking/cloud/inference-reliability.mjs +76 -0
- package/dist/networking/cloud/inference.d.mts +118 -0
- package/dist/networking/cloud/inference.mjs +179 -0
- package/dist/networking/cloud/infrastructure.d.mts +45 -0
- package/dist/networking/cloud/infrastructure.mjs +96 -0
- package/dist/networking/cloud/observability.d.mts +24 -0
- package/dist/networking/cloud/observability.mjs +34 -0
- package/dist/networking/cloud/orchestration.d.mts +32 -0
- package/dist/networking/cloud/orchestration.mjs +38 -0
- package/dist/networking/cloud/recovery.d.mts +21 -0
- package/dist/networking/cloud/recovery.mjs +27 -0
- package/dist/networking/cloud/releases.d.mts +42 -0
- package/dist/networking/cloud/releases.mjs +135 -0
- package/dist/networking/cloud/scaling.d.mts +25 -0
- package/dist/networking/cloud/scaling.mjs +65 -0
- package/dist/networking/cloud/secrets.d.mts +39 -0
- package/dist/networking/cloud/secrets.mjs +68 -0
- package/dist/networking/cloud/server-deployment.d.mts +29 -0
- package/dist/networking/cloud/server-deployment.mjs +72 -0
- package/dist/networking/cloud/storage.d.mts +16 -0
- package/dist/networking/cloud/storage.mjs +58 -0
- package/dist/networking/cloud/vpc.d.mts +18 -0
- package/dist/networking/cloud/vpc.mjs +100 -0
- package/dist/networking/delivery.d.mts +34 -0
- package/dist/networking/delivery.mjs +52 -0
- package/dist/networking/index.d.mts +47 -0
- package/dist/networking/index.mjs +47 -0
- package/dist/networking/ipv6.d.mts +28 -0
- package/dist/networking/ipv6.mjs +17 -0
- package/dist/networking/journeys.d.mts +83 -0
- package/dist/networking/journeys.mjs +161 -0
- package/dist/networking/models/airtime.d.mts +87 -0
- package/dist/networking/models/airtime.mjs +130 -0
- package/dist/networking/models/cellular.d.mts +157 -0
- package/dist/networking/models/cellular.mjs +252 -0
- package/dist/networking/models/encapsulation.d.mts +98 -0
- package/dist/networking/models/encapsulation.mjs +132 -0
- package/dist/networking/models/handover.d.mts +116 -0
- package/dist/networking/models/handover.mjs +209 -0
- package/dist/networking/models/handshake.d.mts +90 -0
- package/dist/networking/models/handshake.mjs +122 -0
- package/dist/networking/models/index.d.mts +14 -0
- package/dist/networking/models/index.mjs +15 -0
- package/dist/networking/models/media.d.mts +82 -0
- package/dist/networking/models/media.mjs +188 -0
- package/dist/networking/models/satellite.d.mts +86 -0
- package/dist/networking/models/satellite.mjs +121 -0
- package/dist/networking/models/spectrum.d.mts +83 -0
- package/dist/networking/models/spectrum.mjs +235 -0
- package/dist/networking/models/switch.d.mts +80 -0
- package/dist/networking/models/switch.mjs +155 -0
- package/dist/networking/models/vlan.d.mts +62 -0
- package/dist/networking/models/vlan.mjs +100 -0
- package/dist/networking/models/vpn.d.mts +66 -0
- package/dist/networking/models/vpn.mjs +125 -0
- package/dist/networking/models/wifi-privacy.d.mts +82 -0
- package/dist/networking/models/wifi-privacy.mjs +130 -0
- package/dist/networking/models/wifi.d.mts +240 -0
- package/dist/networking/models/wifi.mjs +562 -0
- package/dist/networking/nat-traversal.d.mts +24 -0
- package/dist/networking/nat-traversal.mjs +38 -0
- package/dist/networking/protocols.d.mts +17 -0
- package/dist/networking/protocols.mjs +57 -0
- package/dist/networking/queue.d.mts +12 -0
- package/dist/networking/queue.mjs +18 -0
- package/dist/networking/route-learning.d.mts +23 -0
- package/dist/networking/route-learning.mjs +43 -0
- package/dist/networking/routing.d.mts +11 -0
- package/dist/networking/routing.mjs +25 -0
- package/dist/networking/signals.d.mts +26 -0
- package/dist/networking/signals.mjs +35 -0
- package/dist/networking/subnet.d.mts +49 -0
- package/dist/networking/subnet.mjs +89 -0
- package/dist/networking/tcp-reliability.d.mts +24 -0
- package/dist/networking/tcp-reliability.mjs +38 -0
- package/dist/networking/topology/contract.d.mts +123 -0
- package/dist/networking/topology/index.d.mts +4 -0
- package/dist/networking/topology/index.mjs +4 -0
- package/dist/networking/topology/presets.d.mts +7 -0
- package/dist/networking/topology/presets.mjs +302 -0
- package/dist/networking/topology/simulation.d.mts +8 -0
- package/dist/networking/topology/simulation.mjs +179 -0
- package/dist/networking/wireless.d.mts +11 -0
- package/dist/networking/wireless.mjs +17 -0
- package/dist/optics/imaging.d.mts +218 -0
- package/dist/optics/imaging.mjs +276 -0
- package/dist/optics/index.d.mts +7 -0
- package/dist/optics/index.mjs +8 -0
- package/dist/optics/laws.d.mts +70 -0
- package/dist/optics/laws.mjs +195 -0
- package/dist/optics/prism.d.mts +148 -0
- package/dist/optics/prism.mjs +197 -0
- package/dist/optics/refraction.d.mts +201 -0
- package/dist/optics/refraction.mjs +270 -0
- package/dist/optics/wave-optics.d.mts +171 -0
- package/dist/optics/wave-optics.mjs +259 -0
- package/dist/physics/ac/index.d.mts +183 -0
- package/dist/physics/ac/index.mjs +203 -0
- package/dist/physics/dynamics/forces.d.mts +98 -0
- package/dist/physics/dynamics/forces.mjs +153 -0
- package/dist/physics/dynamics/friction.d.mts +76 -0
- package/dist/physics/dynamics/friction.mjs +119 -0
- package/dist/physics/dynamics/system.d.mts +68 -0
- package/dist/physics/dynamics/system.mjs +125 -0
- package/dist/physics/electrostatics/index.d.mts +169 -0
- package/dist/physics/electrostatics/index.mjs +249 -0
- package/dist/physics/energy/centre-of-mass.d.mts +115 -0
- package/dist/physics/energy/centre-of-mass.mjs +180 -0
- package/dist/physics/energy/conservation.d.mts +81 -0
- package/dist/physics/energy/conservation.mjs +129 -0
- package/dist/physics/energy/power.d.mts +90 -0
- package/dist/physics/energy/power.mjs +167 -0
- package/dist/physics/energy/spring.d.mts +73 -0
- package/dist/physics/energy/spring.mjs +129 -0
- package/dist/physics/energy/store.d.mts +63 -0
- package/dist/physics/energy/store.mjs +108 -0
- package/dist/physics/energy/theorem.d.mts +65 -0
- package/dist/physics/energy/theorem.mjs +113 -0
- package/dist/physics/energy/work.d.mts +114 -0
- package/dist/physics/energy/work.mjs +219 -0
- package/dist/physics/gravitation/body.d.mts +85 -0
- package/dist/physics/gravitation/body.mjs +168 -0
- package/dist/physics/gravitation/kepler.d.mts +127 -0
- package/dist/physics/gravitation/kepler.mjs +216 -0
- package/dist/physics/gravitation/law.d.mts +117 -0
- package/dist/physics/gravitation/law.mjs +175 -0
- package/dist/physics/gravitation/orbit.d.mts +119 -0
- package/dist/physics/gravitation/orbit.mjs +202 -0
- package/dist/physics/gravitation/potential.d.mts +114 -0
- package/dist/physics/gravitation/potential.mjs +202 -0
- package/dist/physics/gravitation/variation.d.mts +97 -0
- package/dist/physics/gravitation/variation.mjs +175 -0
- package/dist/physics/index.d.mts +35 -0
- package/dist/physics/index.mjs +36 -0
- package/dist/physics/integral-sweep.d.mts +63 -0
- package/dist/physics/integral-sweep.mjs +126 -0
- package/dist/physics/kinematics/equations.d.mts +47 -0
- package/dist/physics/kinematics/equations.mjs +126 -0
- package/dist/physics/kinematics/free-fall.d.mts +53 -0
- package/dist/physics/kinematics/free-fall.mjs +71 -0
- package/dist/physics/kinematics/given.d.mts +16 -0
- package/dist/physics/kinematics/given.mjs +55 -0
- package/dist/physics/kinematics/roots.d.mts +41 -0
- package/dist/physics/kinematics/roots.mjs +72 -0
- package/dist/physics/kinematics/solve.d.mts +52 -0
- package/dist/physics/kinematics/solve.mjs +172 -0
- package/dist/physics/magnetism/biot-savart.d.mts +161 -0
- package/dist/physics/magnetism/biot-savart.mjs +353 -0
- package/dist/physics/magnetism/flux.d.mts +94 -0
- package/dist/physics/magnetism/flux.mjs +313 -0
- package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
- package/dist/physics/magnetism/geomagnetism.mjs +184 -0
- package/dist/physics/magnetism/index.d.mts +12 -0
- package/dist/physics/magnetism/index.mjs +74 -0
- package/dist/physics/magnetism/lorentz.d.mts +28 -0
- package/dist/physics/magnetism/lorentz.mjs +88 -0
- package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
- package/dist/physics/magnetism/magnetic-force.mjs +169 -0
- package/dist/physics/momentum/collide.d.mts +77 -0
- package/dist/physics/momentum/collide.mjs +115 -0
- package/dist/physics/momentum/impulse.d.mts +89 -0
- package/dist/physics/momentum/impulse.mjs +159 -0
- package/dist/physics/momentum/planar.d.mts +60 -0
- package/dist/physics/momentum/planar.mjs +110 -0
- package/dist/physics/projectile.d.mts +107 -0
- package/dist/physics/projectile.mjs +185 -0
- package/dist/physics/rotation/angular.d.mts +85 -0
- package/dist/physics/rotation/angular.mjs +130 -0
- package/dist/physics/rotation/circular.d.mts +79 -0
- package/dist/physics/rotation/circular.mjs +131 -0
- package/dist/physics/rotation/inertia.d.mts +164 -0
- package/dist/physics/rotation/inertia.mjs +332 -0
- package/dist/physics/rotation/torque.d.mts +65 -0
- package/dist/physics/rotation/torque.mjs +134 -0
- package/dist/physics/vectors.d.mts +64 -0
- package/dist/physics/vectors.mjs +114 -0
- package/dist/primitives/Dot.d.mts +2 -15
- package/dist/primitives/Dot.mjs +6 -4
- package/dist/primitives/Grid.d.mts +33 -17
- package/dist/primitives/Grid.mjs +89 -17
- package/dist/primitives/Label.d.mts +1 -14
- package/dist/primitives/Label.mjs +3 -2
- package/dist/primitives/Lines.d.mts +4 -32
- package/dist/primitives/Lines.mjs +10 -8
- package/dist/primitives/Shapes.d.mts +5 -43
- package/dist/primitives/Shapes.mjs +12 -10
- package/dist/primitives/index.d.mts +2 -2
- package/dist/primitives/index.mjs +2 -2
- package/dist/primitives/props.mjs +31 -0
- package/dist/quantity/index.d.mts +119 -0
- package/dist/quantity/index.mjs +417 -0
- package/dist/relation/derive.d.mts +74 -0
- package/dist/relation/derive.mjs +73 -0
- package/dist/relation/index.d.mts +56 -0
- package/dist/relation/index.mjs +234 -0
- package/dist/scene/Scene.d.mts +6 -1
- package/dist/scene/Scene.mjs +15 -40
- package/dist/scene/evaluators.mjs +1 -1
- package/dist/sim/thermal.mjs +45 -20
- package/dist/thermo/calorimetry.d.mts +207 -0
- package/dist/thermo/calorimetry.mjs +345 -0
- package/dist/thermo/cycles.d.mts +142 -0
- package/dist/thermo/cycles.mjs +256 -0
- package/dist/thermo/entropy.d.mts +87 -0
- package/dist/thermo/entropy.mjs +140 -0
- package/dist/thermo/expansion.d.mts +130 -0
- package/dist/thermo/expansion.mjs +178 -0
- package/dist/thermo/gas.d.mts +197 -0
- package/dist/thermo/gas.mjs +279 -0
- package/dist/thermo/heat-transfer.d.mts +164 -0
- package/dist/thermo/heat-transfer.mjs +217 -0
- package/dist/thermo/index.d.mts +9 -82
- package/dist/thermo/index.mjs +9 -132
- package/dist/thermo/processes.d.mts +95 -0
- package/dist/thermo/processes.mjs +154 -0
- package/dist/thermo/temperature.d.mts +174 -0
- package/dist/thermo/temperature.mjs +236 -0
- package/dist/view/Stage.mjs +4 -11
- package/dist/waves/damping.d.mts +224 -0
- package/dist/waves/damping.mjs +317 -0
- package/dist/waves/doppler.d.mts +72 -0
- package/dist/waves/doppler.mjs +125 -0
- package/dist/waves/index.d.mts +10 -0
- package/dist/waves/index.mjs +10 -0
- package/dist/waves/pendulum.d.mts +130 -0
- package/dist/waves/pendulum.mjs +211 -0
- package/dist/waves/pitch.d.mts +125 -0
- package/dist/waves/pitch.mjs +158 -0
- package/dist/waves/shm.d.mts +170 -0
- package/dist/waves/shm.mjs +279 -0
- package/dist/waves/springs.d.mts +103 -0
- package/dist/waves/springs.mjs +176 -0
- package/dist/waves/superposition.d.mts +124 -0
- package/dist/waves/superposition.mjs +196 -0
- package/dist/waves/wave.d.mts +154 -0
- package/dist/waves/wave.mjs +178 -0
- package/package.json +103 -23
- package/styles.css +125 -8
- package/dist/assets/kit/index.mjs +0 -4
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { fromMinor, toMinor } from "../accounting/precision.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/finance/management-accounting/variances.ts
|
|
4
|
+
const DEFAULT_POLICY = { decimalPlaces: 2 };
|
|
5
|
+
function analyzeCostVariances(facts, policy = DEFAULT_POLICY) {
|
|
6
|
+
const diagnostics = [];
|
|
7
|
+
if ([
|
|
8
|
+
facts.actualOutputUnits,
|
|
9
|
+
facts.material.standardQuantityPerUnit,
|
|
10
|
+
facts.material.standardPricePerUnit,
|
|
11
|
+
facts.material.actualQuantity,
|
|
12
|
+
facts.material.actualPricePerUnit,
|
|
13
|
+
facts.labour.standardHoursPerUnit,
|
|
14
|
+
facts.labour.standardRatePerHour,
|
|
15
|
+
facts.labour.actualHours,
|
|
16
|
+
facts.labour.actualRatePerHour,
|
|
17
|
+
facts.variableOverhead.standardRatePerHour,
|
|
18
|
+
facts.variableOverhead.actualRatePerHour,
|
|
19
|
+
facts.fixedOverhead.budgeted,
|
|
20
|
+
facts.fixedOverhead.actual
|
|
21
|
+
].some((value) => !Number.isFinite(value) || value < 0)) diagnostics.push({
|
|
22
|
+
code: "invalid-input",
|
|
23
|
+
severity: "error",
|
|
24
|
+
message: "Variance inputs must be finite and non-negative."
|
|
25
|
+
});
|
|
26
|
+
if (!Number.isFinite(facts.fixedOverhead.normalCapacityHours) || facts.fixedOverhead.normalCapacityHours <= 0) diagnostics.push({
|
|
27
|
+
code: "invalid-input",
|
|
28
|
+
severity: "error",
|
|
29
|
+
message: "Normal capacity hours must be finite and positive."
|
|
30
|
+
});
|
|
31
|
+
if (diagnostics.length > 0) return emptyResult(diagnostics);
|
|
32
|
+
const standardQuantity = facts.actualOutputUnits * facts.material.standardQuantityPerUnit;
|
|
33
|
+
const standardHours = facts.actualOutputUnits * facts.labour.standardHoursPerUnit;
|
|
34
|
+
const variance = (amount) => {
|
|
35
|
+
const rounded = money(amount, policy);
|
|
36
|
+
return {
|
|
37
|
+
amount: Math.abs(rounded),
|
|
38
|
+
outcome: rounded > 0 ? "favorable" : rounded < 0 ? "adverse" : "none"
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const signed = (item) => item.outcome === "favorable" ? item.amount : item.outcome === "adverse" ? -item.amount : 0;
|
|
42
|
+
const combine = (...items) => variance(items.reduce((sum, item) => sum + signed(item), 0));
|
|
43
|
+
const materialPrice = variance(facts.material.actualQuantity * (facts.material.standardPricePerUnit - facts.material.actualPricePerUnit));
|
|
44
|
+
const materialUsage = variance(facts.material.standardPricePerUnit * (standardQuantity - facts.material.actualQuantity));
|
|
45
|
+
const labourRate = variance(facts.labour.actualHours * (facts.labour.standardRatePerHour - facts.labour.actualRatePerHour));
|
|
46
|
+
const labourEfficiency = variance(facts.labour.standardRatePerHour * (standardHours - facts.labour.actualHours));
|
|
47
|
+
const variableExpenditure = variance(facts.labour.actualHours * (facts.variableOverhead.standardRatePerHour - facts.variableOverhead.actualRatePerHour));
|
|
48
|
+
const variableEfficiency = variance(facts.variableOverhead.standardRatePerHour * (standardHours - facts.labour.actualHours));
|
|
49
|
+
const fixedExpenditure = variance(facts.fixedOverhead.budgeted - facts.fixedOverhead.actual);
|
|
50
|
+
const fixedVolume = variance(standardHours * (facts.fixedOverhead.budgeted / facts.fixedOverhead.normalCapacityHours) - facts.fixedOverhead.budgeted);
|
|
51
|
+
const materialTotal = combine(materialPrice, materialUsage);
|
|
52
|
+
const labourTotal = combine(labourRate, labourEfficiency);
|
|
53
|
+
const variableTotal = combine(variableExpenditure, variableEfficiency);
|
|
54
|
+
const fixedTotal = combine(fixedExpenditure, fixedVolume);
|
|
55
|
+
const totalCostVariance = combine(materialTotal, labourTotal, variableTotal, fixedTotal);
|
|
56
|
+
const trace = [
|
|
57
|
+
{
|
|
58
|
+
id: "variance:material-price",
|
|
59
|
+
kind: "derive",
|
|
60
|
+
rule: "Material price variance = actual quantity × (standard price − actual price). Positive is favorable.",
|
|
61
|
+
working: `${facts.material.actualQuantity} × (${facts.material.standardPricePerUnit} − ${facts.material.actualPricePerUnit})`,
|
|
62
|
+
result: signed(materialPrice)
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "variance:material-usage",
|
|
66
|
+
kind: "derive",
|
|
67
|
+
rule: "Material usage variance = standard price × (standard quantity for output − actual quantity). Positive is favorable.",
|
|
68
|
+
working: `${facts.material.standardPricePerUnit} × (${standardQuantity} − ${facts.material.actualQuantity})`,
|
|
69
|
+
result: signed(materialUsage)
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "variance:labour-rate",
|
|
73
|
+
kind: "derive",
|
|
74
|
+
rule: "Labour rate variance = actual hours × (standard rate − actual rate). Positive is favorable.",
|
|
75
|
+
working: `${facts.labour.actualHours} × (${facts.labour.standardRatePerHour} − ${facts.labour.actualRatePerHour})`,
|
|
76
|
+
result: signed(labourRate)
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "variance:labour-efficiency",
|
|
80
|
+
kind: "derive",
|
|
81
|
+
rule: "Labour efficiency variance = standard rate × (standard hours for output − actual hours). Positive is favorable.",
|
|
82
|
+
working: `${facts.labour.standardRatePerHour} × (${standardHours} − ${facts.labour.actualHours})`,
|
|
83
|
+
result: signed(labourEfficiency)
|
|
84
|
+
}
|
|
85
|
+
];
|
|
86
|
+
return {
|
|
87
|
+
completed: true,
|
|
88
|
+
standardQuantity,
|
|
89
|
+
standardHours,
|
|
90
|
+
material: {
|
|
91
|
+
price: materialPrice,
|
|
92
|
+
usage: materialUsage,
|
|
93
|
+
total: materialTotal
|
|
94
|
+
},
|
|
95
|
+
labour: {
|
|
96
|
+
rate: labourRate,
|
|
97
|
+
efficiency: labourEfficiency,
|
|
98
|
+
total: labourTotal
|
|
99
|
+
},
|
|
100
|
+
variableOverhead: {
|
|
101
|
+
expenditure: variableExpenditure,
|
|
102
|
+
efficiency: variableEfficiency,
|
|
103
|
+
total: variableTotal
|
|
104
|
+
},
|
|
105
|
+
fixedOverhead: {
|
|
106
|
+
expenditure: fixedExpenditure,
|
|
107
|
+
volume: fixedVolume,
|
|
108
|
+
total: fixedTotal
|
|
109
|
+
},
|
|
110
|
+
totalCostVariance,
|
|
111
|
+
diagnostics,
|
|
112
|
+
trace
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const money = (value, policy) => fromMinor(toMinor(value, policy), policy);
|
|
116
|
+
const zero = {
|
|
117
|
+
amount: 0,
|
|
118
|
+
outcome: "none"
|
|
119
|
+
};
|
|
120
|
+
const emptyResult = (diagnostics) => ({
|
|
121
|
+
completed: false,
|
|
122
|
+
standardQuantity: 0,
|
|
123
|
+
standardHours: 0,
|
|
124
|
+
material: {
|
|
125
|
+
price: zero,
|
|
126
|
+
usage: zero,
|
|
127
|
+
total: zero
|
|
128
|
+
},
|
|
129
|
+
labour: {
|
|
130
|
+
rate: zero,
|
|
131
|
+
efficiency: zero,
|
|
132
|
+
total: zero
|
|
133
|
+
},
|
|
134
|
+
variableOverhead: {
|
|
135
|
+
expenditure: zero,
|
|
136
|
+
efficiency: zero,
|
|
137
|
+
total: zero
|
|
138
|
+
},
|
|
139
|
+
fixedOverhead: {
|
|
140
|
+
expenditure: zero,
|
|
141
|
+
volume: zero,
|
|
142
|
+
total: zero
|
|
143
|
+
},
|
|
144
|
+
totalCostVariance: zero,
|
|
145
|
+
diagnostics,
|
|
146
|
+
trace: []
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
//#endregion
|
|
150
|
+
export { analyzeCostVariances };
|
package/dist/index.d.mts
CHANGED
|
@@ -12,9 +12,16 @@ import { IconName, ToolIcon } from "./builder/icons.mjs";
|
|
|
12
12
|
import { AUTHORING_TOOLS, CIRCLE, DELETE, GEOMETRY_TOOLS, INTERSECT, LINE, MEASURE, MIDPOINT, NOTE, POINT, SCALAR, SEGMENT, SELECT, Tool, ToolCtx } from "./builder/tools.mjs";
|
|
13
13
|
import { SceneBuilder, SceneBuilderProps } from "./builder/SceneBuilder.mjs";
|
|
14
14
|
import { Palette, PaletteProps } from "./builder/Palette.mjs";
|
|
15
|
+
import { BinOp, Node, compileNode, evaluate, freeVars } from "./math/ast.mjs";
|
|
16
|
+
import { parse as parse$1 } from "./math/parse.mjs";
|
|
17
|
+
import { definiteIntegral, differentiate, integrate, simplify } from "./math/calculus.mjs";
|
|
18
|
+
import { CompiledFn, compile } from "./math/compile.mjs";
|
|
19
|
+
import { toLatex as toLatex$1 } from "./math/latex.mjs";
|
|
20
|
+
import { CompiledExpr, ExprError, ExprResult, compileExpr } from "./math/expr.mjs";
|
|
15
21
|
import { CoordsContext, DragOverlayContext, StageRefContext, useCoords, useDragOverlay, useStageRef } from "./core/context.mjs";
|
|
16
22
|
import { ClockProvider, ClockProviderProps, FrameDriver, FrameInfo, useFrameLoop } from "./core/clock.mjs";
|
|
17
23
|
import { Learner, LearnerProvider, LearnerResult, PriorAttempts, useLearner } from "./core/learner.mjs";
|
|
24
|
+
import { approxEq, clamp, clamp01, gcd, remap, round, snapTo, toDeg, toRad } from "./core/math.mjs";
|
|
18
25
|
import { RichSpan, Script, parseRichText } from "./core/richText.mjs";
|
|
19
26
|
import { StepProgress, StepProgressProvider, StepScope, StepSpec, StepState, useStepProgress } from "./steps/index.mjs";
|
|
20
27
|
import { Stage, StageProps } from "./view/Stage.mjs";
|
|
@@ -26,7 +33,7 @@ import { Line, LineProps, Ray, Segment, SegmentProps, Vector, VectorProps } from
|
|
|
26
33
|
import { Circle, CircleProps, Ellipse, EllipseProps, Path, PathProps, Polygon, PolygonProps, Polyline, PolylineProps } from "./primitives/Shapes.mjs";
|
|
27
34
|
import { Label, LabelProps } from "./primitives/Label.mjs";
|
|
28
35
|
import { Tex, TexProps } from "./primitives/Tex.mjs";
|
|
29
|
-
import { Axes, AxesProps, Grid, GridProps, niceStep } from "./primitives/Grid.mjs";
|
|
36
|
+
import { Axes, AxesProps, ClearZone, Grid, GridProps, clearOfLabel, niceStep } from "./primitives/Grid.mjs";
|
|
30
37
|
import { OfXProps, OfYProps, ParametricProps, Plot } from "./primitives/Plot.mjs";
|
|
31
38
|
import { CanvasLayer, CanvasLayerProps } from "./primitives/CanvasLayer.mjs";
|
|
32
39
|
import { useScreenToMath } from "./interaction/useScreenToMath.mjs";
|
|
@@ -40,12 +47,6 @@ import { CURRENT_SCHEMA_VERSION, emptyDoc, migrate, parse, serialize } from "./s
|
|
|
40
47
|
import { InstanceState, SceneStore } from "./scene/store.mjs";
|
|
41
48
|
import { Scene, SceneProps } from "./scene/Scene.mjs";
|
|
42
49
|
import { RenderOpts, renderElements } from "./scene/render.mjs";
|
|
43
|
-
import { BinOp, Node, compileNode, evaluate, freeVars } from "./math/ast.mjs";
|
|
44
|
-
import { parse as parse$1 } from "./math/parse.mjs";
|
|
45
|
-
import { differentiate, simplify } from "./math/calculus.mjs";
|
|
46
|
-
import { CompiledFn, compile } from "./math/compile.mjs";
|
|
47
|
-
import { toLatex as toLatex$1 } from "./math/latex.mjs";
|
|
48
|
-
import { CompiledExpr, ExprError, ExprResult, compileExpr } from "./math/index.mjs";
|
|
49
50
|
import { BinOp as BinOp$1, LNode, evalBool, freeVars as freeVars$1 } from "./logic/ast.mjs";
|
|
50
51
|
import { parseLogic } from "./logic/parse.mjs";
|
|
51
52
|
import { Classification, TruthRow, TruthTable, classify, equivalent, toCNF, toDNF, truthTable } from "./logic/table.mjs";
|
|
@@ -53,4 +54,4 @@ import { toLatex } from "./logic/latex.mjs";
|
|
|
53
54
|
import { Cube, Minimization, cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImplicants } from "./logic/minimize.mjs";
|
|
54
55
|
import { CompiledLogic, LogicResult, compileLogic } from "./logic/index.mjs";
|
|
55
56
|
import { AssetResolveArgs, AssetSpec, assetMeta, getAsset, listAssets, registerAsset } from "./scene/assets.mjs";
|
|
56
|
-
export { type A11yProps, AUTHORING_TOOLS, type AriaSliderProps, type AssetGeometry, type AssetResolveArgs, type AssetSpec, Axes, type AxesProps, type BinOp, type Binding, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, type CanvasLayerProps, Circle, type CircleProps, type CircleVal, type Classification, ClockProvider, type ClockProviderProps, type Command, type CommandResult, type CompiledExpr, type CompiledFn, type CompiledLogic, type Constrain, type ControlMap, type ControlPick, type ControlSpec, type ControlSurface, type CoordinateSystem, CoordsContext, type CoordsOptions, type Cube, DELETE, type DerivedDef, type DerivedElement, type DerivedKind, type DispatchOpts, Dot, type DotProps, DragOverlayContext, type DraggableHandlers, EVALUATORS, Editor, type ElementBase, type ElementStyle, Ellipse, type EllipseProps, type EvalCtx, type ExprError, type ExprResult, type FrameDriver, type FrameInfo, type FreeElement, type FreeNote, type FreePoint, type FreeScalar, GEOMETRY_TOOLS, type GlyphBox, Grid, type GridProps, HangerHook, type HangerHookProps, type HitCandidate, INTERSECT, type IconName, type Id, type InstanceState, LINE, type LNode, type LabMeta, Label, type LabelProps, type Learner, LearnerProvider, type LearnerResult, Line, type LineProps, type BinOp$1 as LogicBinOp, type LogicResult, MEASURE, MIDPOINT, type Matrix, type Minimization, MovableDot, type MovableDotProps, type MutatePatch, NOTE, type Node, type NumOrRef, OP_REFS, type OfXProps, type OfYProps, type Op, POINT, Palette, type PaletteProps, type ParametricProps, Path, type PathProps, Plot, Point, Polygon, type PolygonProps, Polyline, type PolylineProps, type PressSpringOpts, type PriorAttempts, Ray, type Ref, type RenderOpts, type Resolved, type RichSpan, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, type SceneBuilderProps, type SceneDoc, type SceneElement, type SceneMeta, type SceneProps, SceneStore, type Vec2 as SceneVec2, type Script, Segment, type SegmentProps, type ShapeLineVal, type Size, Stage, StageAssetDefs, type StageProps, StageRefContext, type StepProgress, StepProgressProvider, StepScope, type StepSpec, type StepState, type StyleProps, Tex, type TexProps, type Tool, type ToolCtx, ToolIcon, type TruthRow, type TruthTable, type UseDraggable, type UseDraggableArgs, type Val, type Vec2, Vector, type VectorProps, type ViewBox, WeightGlyph, XBlockGlyph, applyCommand, assetMeta, classify, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, getAsset, getControlSurface, hitTest, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, renderElements, resolve, serialize, simplify, toCNF, toDNF, toLatex$1 as toLatex, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
|
|
57
|
+
export { type A11yProps, AUTHORING_TOOLS, type AriaSliderProps, type AssetGeometry, type AssetResolveArgs, type AssetSpec, Axes, type AxesProps, type BinOp, type Binding, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, type CanvasLayerProps, Circle, type CircleProps, type CircleVal, type Classification, type ClearZone, ClockProvider, type ClockProviderProps, type Command, type CommandResult, type CompiledExpr, type CompiledFn, type CompiledLogic, type Constrain, type ControlMap, type ControlPick, type ControlSpec, type ControlSurface, type CoordinateSystem, CoordsContext, type CoordsOptions, type Cube, DELETE, type DerivedDef, type DerivedElement, type DerivedKind, type DispatchOpts, Dot, type DotProps, DragOverlayContext, type DraggableHandlers, EVALUATORS, Editor, type ElementBase, type ElementStyle, Ellipse, type EllipseProps, type EvalCtx, type ExprError, type ExprResult, type FrameDriver, type FrameInfo, type FreeElement, type FreeNote, type FreePoint, type FreeScalar, GEOMETRY_TOOLS, type GlyphBox, Grid, type GridProps, HangerHook, type HangerHookProps, type HitCandidate, INTERSECT, type IconName, type Id, type InstanceState, LINE, type LNode, type LabMeta, Label, type LabelProps, type Learner, LearnerProvider, type LearnerResult, Line, type LineProps, type BinOp$1 as LogicBinOp, type LogicResult, MEASURE, MIDPOINT, type Matrix, type Minimization, MovableDot, type MovableDotProps, type MutatePatch, NOTE, type Node, type NumOrRef, OP_REFS, type OfXProps, type OfYProps, type Op, POINT, Palette, type PaletteProps, type ParametricProps, Path, type PathProps, Plot, Point, Polygon, type PolygonProps, Polyline, type PolylineProps, type PressSpringOpts, type PriorAttempts, Ray, type Ref, type RenderOpts, type Resolved, type RichSpan, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, type SceneBuilderProps, type SceneDoc, type SceneElement, type SceneMeta, type SceneProps, SceneStore, type Vec2 as SceneVec2, type Script, Segment, type SegmentProps, type ShapeLineVal, type Size, Stage, StageAssetDefs, type StageProps, StageRefContext, type StepProgress, StepProgressProvider, StepScope, type StepSpec, type StepState, type StyleProps, Tex, type TexProps, type Tool, type ToolCtx, ToolIcon, type TruthRow, type TruthTable, type UseDraggable, type UseDraggableArgs, type Val, type Vec2, Vector, type VectorProps, type ViewBox, WeightGlyph, XBlockGlyph, applyCommand, approxEq, assetMeta, clamp, clamp01, classify, clearOfLabel, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, definiteIntegral, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, gcd, getAsset, getControlSurface, hitTest, integrate, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, remap, renderElements, resolve, round, serialize, simplify, snapTo, toCNF, toDNF, toDeg, toLatex$1 as toLatex, toRad, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
|
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { CoordsContext, DragOverlayContext, StageRefContext, useCoords, useDragO
|
|
|
5
5
|
import { ClockProvider, useFrameLoop } from "./core/clock.mjs";
|
|
6
6
|
import { getControlSurface, listControlSurfaces, onControlChange, useControlSurface } from "./core/control.mjs";
|
|
7
7
|
import { LearnerProvider, useLearner } from "./core/learner.mjs";
|
|
8
|
+
import { approxEq, clamp, clamp01, gcd, remap, round, snapTo, toDeg, toRad } from "./core/math.mjs";
|
|
8
9
|
import { StepProgressProvider, StepScope, useStepProgress } from "./steps/index.mjs";
|
|
9
10
|
import { useElementSize } from "./view/useElementSize.mjs";
|
|
10
11
|
import { Stage } from "./view/Stage.mjs";
|
|
@@ -14,7 +15,7 @@ import { Line, Ray, Segment, Vector } from "./primitives/Lines.mjs";
|
|
|
14
15
|
import { Circle, Ellipse, Path, Polygon, Polyline } from "./primitives/Shapes.mjs";
|
|
15
16
|
import { Label } from "./primitives/Label.mjs";
|
|
16
17
|
import { Tex } from "./primitives/Tex.mjs";
|
|
17
|
-
import { Axes, Grid, niceStep } from "./primitives/Grid.mjs";
|
|
18
|
+
import { Axes, Grid, clearOfLabel, niceStep } from "./primitives/Grid.mjs";
|
|
18
19
|
import { Plot } from "./primitives/Plot.mjs";
|
|
19
20
|
import { CanvasLayer } from "./primitives/CanvasLayer.mjs";
|
|
20
21
|
import { useScreenToMath } from "./interaction/useScreenToMath.mjs";
|
|
@@ -27,10 +28,10 @@ import { OP_REFS, isRef, parentIds } from "./scene/schema.mjs";
|
|
|
27
28
|
import { assetMeta, getAsset, listAssets, registerAsset } from "./scene/assets.mjs";
|
|
28
29
|
import { compileNode, evaluate, freeVars } from "./math/ast.mjs";
|
|
29
30
|
import { parse as parse$1 } from "./math/parse.mjs";
|
|
30
|
-
import { differentiate, simplify } from "./math/calculus.mjs";
|
|
31
|
+
import { definiteIntegral, differentiate, integrate, simplify } from "./math/calculus.mjs";
|
|
31
32
|
import { compile } from "./math/compile.mjs";
|
|
32
33
|
import { toLatex as toLatex$1 } from "./math/latex.mjs";
|
|
33
|
-
import { compileExpr } from "./math/
|
|
34
|
+
import { compileExpr } from "./math/expr.mjs";
|
|
34
35
|
import { EVALUATORS } from "./scene/evaluators.mjs";
|
|
35
36
|
import { resolve } from "./scene/resolve.mjs";
|
|
36
37
|
import { applyCommand, collectRemoved, inverse } from "./scene/commands.mjs";
|
|
@@ -46,7 +47,6 @@ import { AUTHORING_TOOLS, CIRCLE, DELETE, GEOMETRY_TOOLS, INTERSECT, LINE, MEASU
|
|
|
46
47
|
import { SceneBuilder } from "./builder/SceneBuilder.mjs";
|
|
47
48
|
import { StageAssetDefs } from "./assets/kit/svg-defs.mjs";
|
|
48
49
|
import { BucketGlyph, HangerHook, WeightGlyph, XBlockGlyph } from "./assets/kit/glyphs.mjs";
|
|
49
|
-
import "./assets/kit/index.mjs";
|
|
50
50
|
import { evalBool, freeVars as freeVars$1 } from "./logic/ast.mjs";
|
|
51
51
|
import { parseLogic } from "./logic/parse.mjs";
|
|
52
52
|
import { classify, equivalent, toCNF, toDNF, truthTable } from "./logic/table.mjs";
|
|
@@ -54,4 +54,4 @@ import { toLatex } from "./logic/latex.mjs";
|
|
|
54
54
|
import { cubeCovers, cubeOfSelection, cubeTerm, minimalCover, minimize, primeImplicants } from "./logic/minimize.mjs";
|
|
55
55
|
import { compileLogic } from "./logic/index.mjs";
|
|
56
56
|
|
|
57
|
-
export { AUTHORING_TOOLS, Axes, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, Circle, ClockProvider, CoordsContext, DELETE, Dot, DragOverlayContext, EVALUATORS, Editor, Ellipse, GEOMETRY_TOOLS, Grid, HangerHook, INTERSECT, LINE, Label, LearnerProvider, Line, MEASURE, MIDPOINT, MovableDot, NOTE, OP_REFS, POINT, Palette, Path, Plot, Point, Polygon, Polyline, Ray, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, SceneStore, Segment, Stage, StageAssetDefs, StageRefContext, StepProgressProvider, StepScope, Tex, ToolIcon, Vector, WeightGlyph, XBlockGlyph, applyCommand, assetMeta, classify, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, getAsset, getControlSurface, hitTest, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, renderElements, resolve, serialize, simplify, toCNF, toDNF, toLatex$1 as toLatex, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
|
|
57
|
+
export { AUTHORING_TOOLS, Axes, BucketGlyph, CIRCLE, CURRENT_SCHEMA_VERSION, CanvasLayer, Circle, ClockProvider, CoordsContext, DELETE, Dot, DragOverlayContext, EVALUATORS, Editor, Ellipse, GEOMETRY_TOOLS, Grid, HangerHook, INTERSECT, LINE, Label, LearnerProvider, Line, MEASURE, MIDPOINT, MovableDot, NOTE, OP_REFS, POINT, Palette, Path, Plot, Point, Polygon, Polyline, Ray, SCALAR, SEGMENT, SELECT, Scene, SceneBuilder, SceneStore, Segment, Stage, StageAssetDefs, StageRefContext, StepProgressProvider, StepScope, Tex, ToolIcon, Vector, WeightGlyph, XBlockGlyph, applyCommand, approxEq, assetMeta, clamp, clamp01, classify, clearOfLabel, collectRemoved, compile, compileExpr, compileLogic, compileNode, controlsFromScene, createCoords, cubeCovers, cubeOfSelection, cubeTerm, definiteIntegral, differentiate, emptyDoc, equivalent, evalBool, evaluate, fmt, freeVars, gcd, getAsset, getControlSurface, hitTest, integrate, inverse, isAssetGeom, isCircleVal, isDerived, isFree, isLineVal, isRef, isVec2, listAssets, listControlSurfaces, freeVars$1 as logicFreeVars, toLatex as logicToLatex, mat, migrate, minimalCover, minimize, niceStep, numOf, onControlChange, parentIds, parse, parse$1 as parseExpr, parseLogic, parseRichText, primeImplicants, registerAsset, remap, renderElements, resolve, round, serialize, simplify, snapTo, toCNF, toDNF, toDeg, toLatex$1 as toLatex, toRad, truthTable, useControlSurface, useCoords, useDragOverlay, useDraggable, useEditor, useElementSize, useFrameLoop, useImpulse, useInView, useLearner, usePressSpring, useScreenToMath, useStageRef, useStepProgress, vec };
|
|
@@ -56,6 +56,7 @@ function MovableDot({ value, onMove, constrain, color = ACCENT, r = 7, ariaLabel
|
|
|
56
56
|
...step !== void 0 ? { step } : {}
|
|
57
57
|
});
|
|
58
58
|
const [hovered, setHovered] = useState(false);
|
|
59
|
+
const [interacted, setInteracted] = useState(false);
|
|
59
60
|
const press = usePressSpring(dragging, {
|
|
60
61
|
to: 1,
|
|
61
62
|
stiffness: 360,
|
|
@@ -87,6 +88,14 @@ function MovableDot({ value, onMove, constrain, color = ACCENT, r = 7, ariaLabel
|
|
|
87
88
|
...handlers,
|
|
88
89
|
...ariaProps,
|
|
89
90
|
"aria-label": ariaLabel,
|
|
91
|
+
onPointerDown: (e) => {
|
|
92
|
+
setInteracted(true);
|
|
93
|
+
handlers.onPointerDown(e);
|
|
94
|
+
},
|
|
95
|
+
onKeyDown: (e) => {
|
|
96
|
+
setInteracted(true);
|
|
97
|
+
handlers.onKeyDown(e);
|
|
98
|
+
},
|
|
90
99
|
onPointerEnter: () => setHovered(true),
|
|
91
100
|
onPointerLeave: () => setHovered(false),
|
|
92
101
|
style: {
|
|
@@ -100,6 +109,16 @@ function MovableDot({ value, onMove, constrain, color = ACCENT, r = 7, ariaLabel
|
|
|
100
109
|
r: Math.max(r + 14, 12),
|
|
101
110
|
fill: "transparent"
|
|
102
111
|
}),
|
|
112
|
+
!interacted && !dragging && /* @__PURE__ */ jsx("circle", {
|
|
113
|
+
className: "stage-nudge",
|
|
114
|
+
cx: px,
|
|
115
|
+
cy: py,
|
|
116
|
+
r: r + 5,
|
|
117
|
+
fill: "none",
|
|
118
|
+
stroke: color,
|
|
119
|
+
strokeWidth: 1.5,
|
|
120
|
+
style: { pointerEvents: "none" }
|
|
121
|
+
}),
|
|
103
122
|
dragging ? /* @__PURE__ */ jsx("circle", {
|
|
104
123
|
cx: px,
|
|
105
124
|
cy: py,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useScreenToMath } from "./useScreenToMath.mjs";
|
|
4
|
-
import { useCallback, useRef, useState } from "react";
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
5
|
|
|
6
6
|
//#region src/interaction/useDraggable.ts
|
|
7
7
|
function constrained(p, start, constrain) {
|
|
@@ -20,6 +20,20 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
|
|
|
20
20
|
const toMath = useScreenToMath();
|
|
21
21
|
const [dragging, setDragging] = useState(false);
|
|
22
22
|
const startRef = useRef(value);
|
|
23
|
+
const onMoveRef = useRef(onMove);
|
|
24
|
+
onMoveRef.current = onMove;
|
|
25
|
+
const pendingRef = useRef(null);
|
|
26
|
+
const rafRef = useRef(0);
|
|
27
|
+
const flushMove = useCallback(() => {
|
|
28
|
+
rafRef.current = 0;
|
|
29
|
+
const p = pendingRef.current;
|
|
30
|
+
if (!p) return;
|
|
31
|
+
pendingRef.current = null;
|
|
32
|
+
onMoveRef.current(p, "move");
|
|
33
|
+
}, []);
|
|
34
|
+
useEffect(() => () => {
|
|
35
|
+
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
36
|
+
}, []);
|
|
23
37
|
const onPointerDown = useCallback((e) => {
|
|
24
38
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
25
39
|
startRef.current = value;
|
|
@@ -30,19 +44,25 @@ function useDraggable({ value, onMove, constrain, step = .5, range }) {
|
|
|
30
44
|
if (!dragging) return;
|
|
31
45
|
const m = toMath(e);
|
|
32
46
|
if (!m) return;
|
|
33
|
-
|
|
47
|
+
pendingRef.current = constrained({
|
|
34
48
|
x: m[0],
|
|
35
49
|
y: m[1]
|
|
36
|
-
}, startRef.current, constrain)
|
|
50
|
+
}, startRef.current, constrain);
|
|
51
|
+
if (!rafRef.current) rafRef.current = requestAnimationFrame(flushMove);
|
|
37
52
|
}, [
|
|
38
53
|
dragging,
|
|
39
54
|
toMath,
|
|
40
55
|
constrain,
|
|
41
|
-
|
|
56
|
+
flushMove
|
|
42
57
|
]);
|
|
43
58
|
const onPointerUp = useCallback((e) => {
|
|
44
59
|
if (!dragging) return;
|
|
45
60
|
setDragging(false);
|
|
61
|
+
if (rafRef.current) {
|
|
62
|
+
cancelAnimationFrame(rafRef.current);
|
|
63
|
+
rafRef.current = 0;
|
|
64
|
+
}
|
|
65
|
+
pendingRef.current = null;
|
|
46
66
|
const m = toMath(e);
|
|
47
67
|
onMove(m ? constrained({
|
|
48
68
|
x: m[0],
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Node } from "./ast.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/math/analysis.d.ts
|
|
4
|
+
type Fn1 = (x: number) => number;
|
|
5
|
+
/** A straight line y = m·x + c, with the point it was taken at and an evaluator. */
|
|
6
|
+
interface Line {
|
|
7
|
+
m: number;
|
|
8
|
+
c: number;
|
|
9
|
+
at: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
f: Fn1;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Real roots of f on [a,b]. Two passes so it doesn't miss the roots students do:
|
|
17
|
+
* 1. sign-change brackets refined by BISECTION (odd-multiplicity / crossings);
|
|
18
|
+
* 2. local minima of |f| polished by NEWTON, accepted only if |f| really drops
|
|
19
|
+
* to ~0 — this recovers TANGENT / double roots (e.g. x² at 0) that never
|
|
20
|
+
* change sign. False minima (a parabola that never reaches 0) are rejected
|
|
21
|
+
* by the accept tolerance, so no phantom roots.
|
|
22
|
+
*/
|
|
23
|
+
declare function roots(f: Fn1, a: number, b: number, opts?: {
|
|
24
|
+
steps?: number;
|
|
25
|
+
tol?: number;
|
|
26
|
+
}): number[];
|
|
27
|
+
/** Points where f and g meet on [a,b]. */
|
|
28
|
+
declare function intersections(f: Fn1, g: Fn1, a: number, b: number, opts?: {
|
|
29
|
+
steps?: number;
|
|
30
|
+
tol?: number;
|
|
31
|
+
}): {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
}[];
|
|
35
|
+
/** Exact tangent line to `ast` at x = x0 (params baked in via `scope`). */
|
|
36
|
+
declare function tangentAt(ast: Node, x0: number, varName?: string, params?: Record<string, number>): Line | null;
|
|
37
|
+
/** Normal line to `ast` at x = x0 (⟂ the tangent). Null if the tangent is horizontal. */
|
|
38
|
+
declare function normalAt(ast: Node, x0: number, varName?: string, params?: Record<string, number>): Line | null;
|
|
39
|
+
/**
|
|
40
|
+
* Composite-Simpson definite integral ∫_a^b f dx, on a NUMERIC function.
|
|
41
|
+
*
|
|
42
|
+
* Error O(h⁴) against O(h) for a Riemann sum, so at n≈1000 it is accurate to near machine
|
|
43
|
+
* precision for a smooth integrand and serves as the reference value a Riemann sum converges
|
|
44
|
+
* toward. `n` is forced even, as the rule requires. Not adaptive: a singularity inside [a, b] is
|
|
45
|
+
* not detected, which is why the callers in this file (`areaBetween`) split at the crossings first.
|
|
46
|
+
*
|
|
47
|
+
* Named `quadrature` because `calculus.ts` beside it exports `integrate`, which integrates an AST
|
|
48
|
+
* SYMBOLICALLY: different argument type, different return type, different meaning. (`simpson`
|
|
49
|
+
* would become a lie the moment the rule changed.) The single implementation, after two copies of
|
|
50
|
+
* it were found in labs; see `KERNEL-CONTRACT.md` §7.
|
|
51
|
+
*/
|
|
52
|
+
declare function quadrature(f: Fn1, a: number, b: number, n?: number): number;
|
|
53
|
+
/**
|
|
54
|
+
* Geometric area between f and g over [a,b]. SPLITS at every crossing so the
|
|
55
|
+
* pieces where g > f don't cancel the pieces where f > g (which a single
|
|
56
|
+
* |∫(f−g)| would). Sums |∫| over each sub-interval — the area an exam actually
|
|
57
|
+
* wants.
|
|
58
|
+
*/
|
|
59
|
+
declare function areaBetween(f: Fn1, g: Fn1, a: number, b: number, n?: number): number;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Fn1, Line, areaBetween, intersections, normalAt, quadrature, roots, tangentAt };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { evaluate } from "./ast.mjs";
|
|
2
|
+
import { differentiate } from "./calculus.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/math/analysis.ts
|
|
5
|
+
/**
|
|
6
|
+
* analysis, the NUMERIC layer over this package's symbolic engine: the half of calculus that needs
|
|
7
|
+
* a number rather than an expression. `calculus.ts` differentiates and integrates an AST exactly;
|
|
8
|
+
* this file finds roots, intersections, tangents, normals and areas, which in general have no
|
|
9
|
+
* closed form at all.
|
|
10
|
+
*
|
|
11
|
+
* Everything works on a compiled scalar `Fn1 = (x) => number` (params already baked into the
|
|
12
|
+
* closure) plus, for exact tangents, the parsed `Node` AST. Pure: no React, no pixels.
|
|
13
|
+
*
|
|
14
|
+
* Methods, and why each is safe:
|
|
15
|
+
* • roots, bisection on sign changes PLUS Newton at local minima of |f|, so tangent (even
|
|
16
|
+
* multiplicity) roots are found and poles are rejected. See the docblock on `roots`.
|
|
17
|
+
* • tangents/normals, EXACT: the AST is differentiated symbolically, then evaluated. No
|
|
18
|
+
* finite-difference error in the gradient a lesson shows.
|
|
19
|
+
* • quadrature, composite Simpson, error O(h⁴).
|
|
20
|
+
*
|
|
21
|
+
* Units: none. These are pure numbers on a pure function.
|
|
22
|
+
*/
|
|
23
|
+
function pushUnique(out, x, tol) {
|
|
24
|
+
if (!out.some((p) => Math.abs(p - x) <= tol)) out.push(x);
|
|
25
|
+
}
|
|
26
|
+
/** Newton's method from x0 using a central-difference derivative (we only hold
|
|
27
|
+
* the numeric f, not its AST). Returns the polished root, or null on a flat
|
|
28
|
+
* derivative / divergence. Used to recover tangent (even-multiplicity) roots a
|
|
29
|
+
* sign-change scan can't see. */
|
|
30
|
+
function newton(f, x0, tol) {
|
|
31
|
+
let x = x0;
|
|
32
|
+
for (let k = 0; k < 40; k++) {
|
|
33
|
+
const fx = f(x);
|
|
34
|
+
if (!Number.isFinite(fx)) return null;
|
|
35
|
+
if (Math.abs(fx) <= tol) return x;
|
|
36
|
+
const h = Math.max(1e-7, Math.abs(x) * 1e-7);
|
|
37
|
+
const d = (f(x + h) - f(x - h)) / (2 * h);
|
|
38
|
+
if (!Number.isFinite(d) || Math.abs(d) < 1e-13) return null;
|
|
39
|
+
const nx = x - fx / d;
|
|
40
|
+
if (!Number.isFinite(nx)) return null;
|
|
41
|
+
if (Math.abs(nx - x) <= tol) return nx;
|
|
42
|
+
x = nx;
|
|
43
|
+
}
|
|
44
|
+
return Math.abs(f(x)) <= tol ? x : null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Real roots of f on [a,b]. Two passes so it doesn't miss the roots students do:
|
|
48
|
+
* 1. sign-change brackets refined by BISECTION (odd-multiplicity / crossings);
|
|
49
|
+
* 2. local minima of |f| polished by NEWTON, accepted only if |f| really drops
|
|
50
|
+
* to ~0 — this recovers TANGENT / double roots (e.g. x² at 0) that never
|
|
51
|
+
* change sign. False minima (a parabola that never reaches 0) are rejected
|
|
52
|
+
* by the accept tolerance, so no phantom roots.
|
|
53
|
+
*/
|
|
54
|
+
function roots(f, a, b, opts = {}) {
|
|
55
|
+
const steps = opts.steps ?? 1e3;
|
|
56
|
+
const tol = opts.tol ?? 1e-9;
|
|
57
|
+
const grid = (b - a) / steps;
|
|
58
|
+
const out = [];
|
|
59
|
+
const xs = [], fs = [];
|
|
60
|
+
for (let i = 0; i <= steps; i++) {
|
|
61
|
+
const x = a + grid * i;
|
|
62
|
+
xs.push(x);
|
|
63
|
+
fs.push(f(x));
|
|
64
|
+
}
|
|
65
|
+
let maxAbs = 0;
|
|
66
|
+
for (const v of fs) if (Number.isFinite(v)) maxAbs = Math.max(maxAbs, Math.abs(v));
|
|
67
|
+
const acceptTol = 1e-7 * (1 + maxAbs);
|
|
68
|
+
for (let i = 1; i <= steps; i++) {
|
|
69
|
+
const fPrev = fs[i - 1], fx = fs[i];
|
|
70
|
+
if (!Number.isFinite(fPrev) || !Number.isFinite(fx)) continue;
|
|
71
|
+
if (fPrev === 0) {
|
|
72
|
+
pushUnique(out, xs[i - 1], grid);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (fPrev * fx < 0) {
|
|
76
|
+
let lo = xs[i - 1], hi = xs[i], flo = fPrev;
|
|
77
|
+
for (let k = 0; k < 80 && hi - lo > tol; k++) {
|
|
78
|
+
const mid = (lo + hi) / 2;
|
|
79
|
+
const fm = f(mid);
|
|
80
|
+
if (!Number.isFinite(fm)) break;
|
|
81
|
+
if (flo * fm <= 0) hi = mid;
|
|
82
|
+
else {
|
|
83
|
+
lo = mid;
|
|
84
|
+
flo = fm;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const mid = (lo + hi) / 2;
|
|
88
|
+
if (Math.abs(f(mid)) <= acceptTol) pushUnique(out, mid, grid);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (let i = 1; i < steps; i++) {
|
|
92
|
+
const p = fs[i - 1], c = fs[i], q = fs[i + 1];
|
|
93
|
+
if (!Number.isFinite(p) || !Number.isFinite(c) || !Number.isFinite(q)) continue;
|
|
94
|
+
if (Math.abs(c) <= Math.abs(p) && Math.abs(c) <= Math.abs(q) && Math.abs(c) < .05 * (1 + maxAbs)) {
|
|
95
|
+
const r = newton(f, xs[i], tol);
|
|
96
|
+
if (r != null && r >= a - grid && r <= b + grid && Math.abs(f(r)) <= acceptTol) pushUnique(out, r, grid);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
out.sort((u, v) => u - v);
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/** Points where f and g meet on [a,b]. */
|
|
103
|
+
function intersections(f, g, a, b, opts) {
|
|
104
|
+
return roots((x) => f(x) - g(x), a, b, opts).map((x) => ({
|
|
105
|
+
x,
|
|
106
|
+
y: f(x)
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
/** Exact tangent line to `ast` at x = x0 (params baked in via `scope`). */
|
|
110
|
+
function tangentAt(ast, x0, varName = "x", params = {}) {
|
|
111
|
+
const d = differentiate(ast, varName);
|
|
112
|
+
if (!d) return null;
|
|
113
|
+
const m = evaluate(d, {
|
|
114
|
+
...params,
|
|
115
|
+
[varName]: x0
|
|
116
|
+
});
|
|
117
|
+
const y0 = evaluate(ast, {
|
|
118
|
+
...params,
|
|
119
|
+
[varName]: x0
|
|
120
|
+
});
|
|
121
|
+
if (!Number.isFinite(m) || !Number.isFinite(y0)) return null;
|
|
122
|
+
const c = y0 - m * x0;
|
|
123
|
+
return {
|
|
124
|
+
m,
|
|
125
|
+
c,
|
|
126
|
+
at: {
|
|
127
|
+
x: x0,
|
|
128
|
+
y: y0
|
|
129
|
+
},
|
|
130
|
+
f: (x) => m * x + c
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** Normal line to `ast` at x = x0 (⟂ the tangent). Null if the tangent is horizontal. */
|
|
134
|
+
function normalAt(ast, x0, varName = "x", params = {}) {
|
|
135
|
+
const t = tangentAt(ast, x0, varName, params);
|
|
136
|
+
if (!t || t.m === 0) return null;
|
|
137
|
+
const m = -1 / t.m;
|
|
138
|
+
const c = t.at.y - m * t.at.x;
|
|
139
|
+
return {
|
|
140
|
+
m,
|
|
141
|
+
c,
|
|
142
|
+
at: t.at,
|
|
143
|
+
f: (x) => m * x + c
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Composite-Simpson definite integral ∫_a^b f dx, on a NUMERIC function.
|
|
148
|
+
*
|
|
149
|
+
* Error O(h⁴) against O(h) for a Riemann sum, so at n≈1000 it is accurate to near machine
|
|
150
|
+
* precision for a smooth integrand and serves as the reference value a Riemann sum converges
|
|
151
|
+
* toward. `n` is forced even, as the rule requires. Not adaptive: a singularity inside [a, b] is
|
|
152
|
+
* not detected, which is why the callers in this file (`areaBetween`) split at the crossings first.
|
|
153
|
+
*
|
|
154
|
+
* Named `quadrature` because `calculus.ts` beside it exports `integrate`, which integrates an AST
|
|
155
|
+
* SYMBOLICALLY: different argument type, different return type, different meaning. (`simpson`
|
|
156
|
+
* would become a lie the moment the rule changed.) The single implementation, after two copies of
|
|
157
|
+
* it were found in labs; see `KERNEL-CONTRACT.md` §7.
|
|
158
|
+
*/
|
|
159
|
+
function quadrature(f, a, b, n = 1e3) {
|
|
160
|
+
if (a === b) return 0;
|
|
161
|
+
const m = Math.max(2, Math.ceil(n / 2) * 2);
|
|
162
|
+
const h = (b - a) / m;
|
|
163
|
+
let sum = f(a) + f(b);
|
|
164
|
+
for (let i = 1; i < m; i++) sum += (i % 2 === 1 ? 4 : 2) * f(a + i * h);
|
|
165
|
+
return sum * h / 3;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Geometric area between f and g over [a,b]. SPLITS at every crossing so the
|
|
169
|
+
* pieces where g > f don't cancel the pieces where f > g (which a single
|
|
170
|
+
* |∫(f−g)| would). Sums |∫| over each sub-interval — the area an exam actually
|
|
171
|
+
* wants.
|
|
172
|
+
*/
|
|
173
|
+
function areaBetween(f, g, a, b, n = 1e3) {
|
|
174
|
+
const d = (x) => f(x) - g(x);
|
|
175
|
+
const cuts = [
|
|
176
|
+
a,
|
|
177
|
+
...roots(d, a, b).filter((x) => x > a + 1e-9 && x < b - 1e-9).sort((u, v) => u - v),
|
|
178
|
+
b
|
|
179
|
+
];
|
|
180
|
+
const per = Math.max(20, Math.round(n / Math.max(1, cuts.length - 1)));
|
|
181
|
+
let area = 0;
|
|
182
|
+
for (let i = 0; i < cuts.length - 1; i++) area += Math.abs(quadrature(d, cuts[i], cuts[i + 1], per));
|
|
183
|
+
return area;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
export { areaBetween, intersections, normalAt, quadrature, roots, tangentAt };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/math/answer-check.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* answer-check, the "is the student right?" layer, built on the expr engine beside it. Two modes,
|
|
4
|
+
* the ones exams need:
|
|
5
|
+
*
|
|
6
|
+
* • NUMBER — value within tolerance, parsed so `pi/2` and `2*sqrt(5)` count.
|
|
7
|
+
* • EXPRESSION — any algebraically EQUIVALENT form accepted, checked BOTH symbolically
|
|
8
|
+
* (simplify(student − answer) → 0) AND numerically by sampling, so
|
|
9
|
+
* `(x+1)(x+2)` ≡ `x^2+3x+2`.
|
|
10
|
+
*
|
|
11
|
+
* Both passes run because neither is sufficient alone: the simplifier cannot collapse every
|
|
12
|
+
* equivalent pair, and sampling alone would accept two expressions that happen to agree on the
|
|
13
|
+
* sample points. Symbolic first, numeric as the fallback, and a minimum count of agreeing FINITE
|
|
14
|
+
* samples so a pair that is undefined everywhere in the window cannot pass by default.
|
|
15
|
+
*
|
|
16
|
+
* Tolerances are relative, not absolute: a 1% window on a quantity of order 10⁵ is not the same
|
|
17
|
+
* marking scheme as a 1% window on 0.3, and only one of those is what an exam means.
|
|
18
|
+
*
|
|
19
|
+
* Pure: no React, no pixels.
|
|
20
|
+
*/
|
|
21
|
+
/** Evaluate a numeric answer string (`3.14`, `pi/2`, `2*sqrt(5)`) → number (NaN if invalid). */
|
|
22
|
+
declare function parseValue(raw: string): number;
|
|
23
|
+
declare function normalizeMathInput(raw: string): string;
|
|
24
|
+
/** Numeric match with a relative-ish tolerance (default ~1% of scale). */
|
|
25
|
+
declare function checkNumber(student: number, value: number, tol?: number): boolean;
|
|
26
|
+
interface ExprCheckOpts {
|
|
27
|
+
/** Variables to sample (defaults to the union of both sides' free vars). */
|
|
28
|
+
vars?: string[];
|
|
29
|
+
/** Sampling domain for the numeric pass. */
|
|
30
|
+
domain?: [number, number];
|
|
31
|
+
tol?: number;
|
|
32
|
+
samples?: number;
|
|
33
|
+
}
|
|
34
|
+
/** True if `student` is algebraically equivalent to `answer` (symbolic OR numeric). */
|
|
35
|
+
declare function checkExpression(student: string, answer: string, opts?: ExprCheckOpts): boolean;
|
|
36
|
+
type AnswerSpec = {
|
|
37
|
+
kind: 'number';
|
|
38
|
+
value: number;
|
|
39
|
+
tol?: number;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'expression';
|
|
42
|
+
value: string;
|
|
43
|
+
vars?: string[];
|
|
44
|
+
domain?: [number, number];
|
|
45
|
+
tol?: number;
|
|
46
|
+
};
|
|
47
|
+
/** Check a raw student string against an authored answer spec. */
|
|
48
|
+
declare function checkAnswer(spec: AnswerSpec, raw: string): boolean;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { AnswerSpec, ExprCheckOpts, checkAnswer, checkExpression, checkNumber, normalizeMathInput, parseValue };
|