@fundamental-engine/core 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 +21 -0
- package/README.md +128 -0
- package/dist/agents/element-agent.d.ts +38 -0
- package/dist/agents/element-agent.d.ts.map +1 -0
- package/dist/agents/element-agent.js +70 -0
- package/dist/agents/element-agent.js.map +1 -0
- package/dist/agents/event-agent.d.ts +47 -0
- package/dist/agents/event-agent.d.ts.map +1 -0
- package/dist/agents/event-agent.js +82 -0
- package/dist/agents/event-agent.js.map +1 -0
- package/dist/agents/index.d.ts +17 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +57 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/region-agents.d.ts +40 -0
- package/dist/agents/region-agents.d.ts.map +1 -0
- package/dist/agents/region-agents.js +22 -0
- package/dist/agents/region-agents.js.map +1 -0
- package/dist/agents/relationship.d.ts +55 -0
- package/dist/agents/relationship.d.ts.map +1 -0
- package/dist/agents/relationship.js +40 -0
- package/dist/agents/relationship.js.map +1 -0
- package/dist/agents/user-agent.d.ts +57 -0
- package/dist/agents/user-agent.d.ts.map +1 -0
- package/dist/agents/user-agent.js +45 -0
- package/dist/agents/user-agent.js.map +1 -0
- package/dist/config/forces.config.d.ts +101 -0
- package/dist/config/forces.config.d.ts.map +1 -0
- package/dist/config/forces.config.js +239 -0
- package/dist/config/forces.config.js.map +1 -0
- package/dist/config/manual.d.ts +134 -0
- package/dist/config/manual.d.ts.map +1 -0
- package/dist/config/manual.js +604 -0
- package/dist/config/manual.js.map +1 -0
- package/dist/config/palettes.d.ts +18 -0
- package/dist/config/palettes.d.ts.map +1 -0
- package/dist/config/palettes.js +34 -0
- package/dist/config/palettes.js.map +1 -0
- package/dist/config/presets.d.ts +48 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +87 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/config/tokens.d.ts +3 -0
- package/dist/config/tokens.d.ts.map +1 -0
- package/dist/config/tokens.js +16 -0
- package/dist/config/tokens.js.map +1 -0
- package/dist/conformance/expectations.d.ts +40 -0
- package/dist/conformance/expectations.d.ts.map +1 -0
- package/dist/conformance/expectations.js +347 -0
- package/dist/conformance/expectations.js.map +1 -0
- package/dist/conformance/experiments.d.ts +17 -0
- package/dist/conformance/experiments.d.ts.map +1 -0
- package/dist/conformance/experiments.js +875 -0
- package/dist/conformance/experiments.js.map +1 -0
- package/dist/conformance/run.d.ts +18 -0
- package/dist/conformance/run.d.ts.map +1 -0
- package/dist/conformance/run.js +240 -0
- package/dist/conformance/run.js.map +1 -0
- package/dist/conformance/types.d.ts +100 -0
- package/dist/conformance/types.d.ts.map +1 -0
- package/dist/conformance/types.js +2 -0
- package/dist/conformance/types.js.map +1 -0
- package/dist/contracts/guards.d.ts +51 -0
- package/dist/contracts/guards.d.ts.map +1 -0
- package/dist/contracts/guards.js +100 -0
- package/dist/contracts/guards.js.map +1 -0
- package/dist/contracts/index.d.ts +18 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +107 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/passport.d.ts +88 -0
- package/dist/contracts/passport.d.ts.map +1 -0
- package/dist/contracts/passport.js +135 -0
- package/dist/contracts/passport.js.map +1 -0
- package/dist/contracts/types.d.ts +120 -0
- package/dist/contracts/types.d.ts.map +1 -0
- package/dist/contracts/types.js +24 -0
- package/dist/contracts/types.js.map +1 -0
- package/dist/core/accretion.d.ts +50 -0
- package/dist/core/accretion.d.ts.map +1 -0
- package/dist/core/accretion.js +98 -0
- package/dist/core/accretion.js.map +1 -0
- package/dist/core/agents.d.ts +31 -0
- package/dist/core/agents.d.ts.map +1 -0
- package/dist/core/agents.js +51 -0
- package/dist/core/agents.js.map +1 -0
- package/dist/core/attention.d.ts +72 -0
- package/dist/core/attention.d.ts.map +1 -0
- package/dist/core/attention.js +122 -0
- package/dist/core/attention.js.map +1 -0
- package/dist/core/causality.d.ts +38 -0
- package/dist/core/causality.d.ts.map +1 -0
- package/dist/core/causality.js +64 -0
- package/dist/core/causality.js.map +1 -0
- package/dist/core/conditions.d.ts +10 -0
- package/dist/core/conditions.d.ts.map +1 -0
- package/dist/core/conditions.js +22 -0
- package/dist/core/conditions.js.map +1 -0
- package/dist/core/currents.d.ts +53 -0
- package/dist/core/currents.d.ts.map +1 -0
- package/dist/core/currents.js +65 -0
- package/dist/core/currents.js.map +1 -0
- package/dist/core/dock.d.ts +35 -0
- package/dist/core/dock.d.ts.map +1 -0
- package/dist/core/dock.js +39 -0
- package/dist/core/dock.js.map +1 -0
- package/dist/core/events.d.ts +23 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +34 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/feedback-sink.d.ts +32 -0
- package/dist/core/feedback-sink.d.ts.map +1 -0
- package/dist/core/feedback-sink.js +53 -0
- package/dist/core/feedback-sink.js.map +1 -0
- package/dist/core/feedback.d.ts +11 -0
- package/dist/core/feedback.d.ts.map +1 -0
- package/dist/core/feedback.js +16 -0
- package/dist/core/feedback.js.map +1 -0
- package/dist/core/field-store.d.ts +26 -0
- package/dist/core/field-store.d.ts.map +1 -0
- package/dist/core/field-store.js +54 -0
- package/dist/core/field-store.js.map +1 -0
- package/dist/core/field.d.ts +18 -0
- package/dist/core/field.d.ts.map +1 -0
- package/dist/core/field.js +1943 -0
- package/dist/core/field.js.map +1 -0
- package/dist/core/fieldline-seeds.d.ts +25 -0
- package/dist/core/fieldline-seeds.d.ts.map +1 -0
- package/dist/core/fieldline-seeds.js +32 -0
- package/dist/core/fieldline-seeds.js.map +1 -0
- package/dist/core/fieldlines.d.ts +75 -0
- package/dist/core/fieldlines.d.ts.map +1 -0
- package/dist/core/fieldlines.js +111 -0
- package/dist/core/fieldlines.js.map +1 -0
- package/dist/core/flow.d.ts +38 -0
- package/dist/core/flow.d.ts.map +1 -0
- package/dist/core/flow.js +27 -0
- package/dist/core/flow.js.map +1 -0
- package/dist/core/formations.d.ts +11 -0
- package/dist/core/formations.d.ts.map +1 -0
- package/dist/core/formations.js +22 -0
- package/dist/core/formations.js.map +1 -0
- package/dist/core/geometry.d.ts +67 -0
- package/dist/core/geometry.d.ts.map +1 -0
- package/dist/core/geometry.js +68 -0
- package/dist/core/geometry.js.map +1 -0
- package/dist/core/heatmap.d.ts +22 -0
- package/dist/core/heatmap.d.ts.map +1 -0
- package/dist/core/heatmap.js +55 -0
- package/dist/core/heatmap.js.map +1 -0
- package/dist/core/host.d.ts +46 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/core/host.js +11 -0
- package/dist/core/host.js.map +1 -0
- package/dist/core/integrator.d.ts +24 -0
- package/dist/core/integrator.d.ts.map +1 -0
- package/dist/core/integrator.js +375 -0
- package/dist/core/integrator.js.map +1 -0
- package/dist/core/math.d.ts +37 -0
- package/dist/core/math.d.ts.map +1 -0
- package/dist/core/math.js +77 -0
- package/dist/core/math.js.map +1 -0
- package/dist/core/reactions.d.ts +32 -0
- package/dist/core/reactions.d.ts.map +1 -0
- package/dist/core/reactions.js +45 -0
- package/dist/core/reactions.js.map +1 -0
- package/dist/core/registry.d.ts +13 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +20 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/render-backend.d.ts +46 -0
- package/dist/core/render-backend.d.ts.map +1 -0
- package/dist/core/render-backend.js +75 -0
- package/dist/core/render-backend.js.map +1 -0
- package/dist/core/render-modes.d.ts +42 -0
- package/dist/core/render-modes.d.ts.map +1 -0
- package/dist/core/render-modes.js +141 -0
- package/dist/core/render-modes.js.map +1 -0
- package/dist/core/reservoir.d.ts +43 -0
- package/dist/core/reservoir.d.ts.map +1 -0
- package/dist/core/reservoir.js +207 -0
- package/dist/core/reservoir.js.map +1 -0
- package/dist/core/scalar-grid.d.ts +51 -0
- package/dist/core/scalar-grid.d.ts.map +1 -0
- package/dist/core/scalar-grid.js +146 -0
- package/dist/core/scalar-grid.js.map +1 -0
- package/dist/core/scanner.d.ts +59 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +260 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/shadow.d.ts +69 -0
- package/dist/core/shadow.d.ts.map +1 -0
- package/dist/core/shadow.js +84 -0
- package/dist/core/shadow.js.map +1 -0
- package/dist/core/spatial-hash.d.ts +30 -0
- package/dist/core/spatial-hash.d.ts.map +1 -0
- package/dist/core/spatial-hash.js +64 -0
- package/dist/core/spatial-hash.js.map +1 -0
- package/dist/core/streamlines.d.ts +29 -0
- package/dist/core/streamlines.d.ts.map +1 -0
- package/dist/core/streamlines.js +70 -0
- package/dist/core/streamlines.js.map +1 -0
- package/dist/core/surface.d.ts +19 -0
- package/dist/core/surface.d.ts.map +1 -0
- package/dist/core/surface.js +21 -0
- package/dist/core/surface.js.map +1 -0
- package/dist/core/temporal.d.ts +110 -0
- package/dist/core/temporal.d.ts.map +1 -0
- package/dist/core/temporal.js +139 -0
- package/dist/core/temporal.js.map +1 -0
- package/dist/core/thermo.d.ts +48 -0
- package/dist/core/thermo.d.ts.map +1 -0
- package/dist/core/thermo.js +48 -0
- package/dist/core/thermo.js.map +1 -0
- package/dist/core/types.d.ts +610 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/weights.d.ts +111 -0
- package/dist/core/weights.d.ts.map +1 -0
- package/dist/core/weights.js +128 -0
- package/dist/core/weights.js.map +1 -0
- package/dist/diagnostics/energy.d.ts +21 -0
- package/dist/diagnostics/energy.d.ts.map +1 -0
- package/dist/diagnostics/energy.js +27 -0
- package/dist/diagnostics/energy.js.map +1 -0
- package/dist/diagnostics/fields.d.ts +23 -0
- package/dist/diagnostics/fields.d.ts.map +1 -0
- package/dist/diagnostics/fields.js +30 -0
- package/dist/diagnostics/fields.js.map +1 -0
- package/dist/diagnostics/index.d.ts +46 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +23 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/diagnostics/modes.d.ts +108 -0
- package/dist/diagnostics/modes.d.ts.map +1 -0
- package/dist/diagnostics/modes.js +181 -0
- package/dist/diagnostics/modes.js.map +1 -0
- package/dist/diagnostics/potential.d.ts +30 -0
- package/dist/diagnostics/potential.d.ts.map +1 -0
- package/dist/diagnostics/potential.js +43 -0
- package/dist/diagnostics/potential.js.map +1 -0
- package/dist/diagnostics/probes.d.ts +31 -0
- package/dist/diagnostics/probes.d.ts.map +1 -0
- package/dist/diagnostics/probes.js +61 -0
- package/dist/diagnostics/probes.js.map +1 -0
- package/dist/diagnostics/render.d.ts +49 -0
- package/dist/diagnostics/render.d.ts.map +1 -0
- package/dist/diagnostics/render.js +132 -0
- package/dist/diagnostics/render.js.map +1 -0
- package/dist/export.d.ts +18 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +17 -0
- package/dist/export.js.map +1 -0
- package/dist/forces/extended.d.ts +121 -0
- package/dist/forces/extended.d.ts.map +1 -0
- package/dist/forces/extended.js +674 -0
- package/dist/forces/extended.js.map +1 -0
- package/dist/forces/index.d.ts +33 -0
- package/dist/forces/index.d.ts.map +1 -0
- package/dist/forces/index.js +237 -0
- package/dist/forces/index.js.map +1 -0
- package/dist/forces/natural.d.ts +106 -0
- package/dist/forces/natural.d.ts.map +1 -0
- package/dist/forces/natural.js +385 -0
- package/dist/forces/natural.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect/budget.d.ts +17 -0
- package/dist/inspect/budget.d.ts.map +1 -0
- package/dist/inspect/budget.js +19 -0
- package/dist/inspect/budget.js.map +1 -0
- package/dist/inspect/index.d.ts +10 -0
- package/dist/inspect/index.d.ts.map +1 -0
- package/dist/inspect/index.js +10 -0
- package/dist/inspect/index.js.map +1 -0
- package/dist/inspect/report.d.ts +17 -0
- package/dist/inspect/report.d.ts.map +1 -0
- package/dist/inspect/report.js +44 -0
- package/dist/inspect/report.js.map +1 -0
- package/dist/inspect/snapshot.d.ts +21 -0
- package/dist/inspect/snapshot.d.ts.map +1 -0
- package/dist/inspect/snapshot.js +30 -0
- package/dist/inspect/snapshot.js.map +1 -0
- package/dist/recipes/catalog.d.ts +51 -0
- package/dist/recipes/catalog.d.ts.map +1 -0
- package/dist/recipes/catalog.js +1496 -0
- package/dist/recipes/catalog.js.map +1 -0
- package/dist/recipes/charge.d.ts +18 -0
- package/dist/recipes/charge.d.ts.map +1 -0
- package/dist/recipes/charge.js +27 -0
- package/dist/recipes/charge.js.map +1 -0
- package/dist/recipes/compile.d.ts +93 -0
- package/dist/recipes/compile.d.ts.map +1 -0
- package/dist/recipes/compile.js +113 -0
- package/dist/recipes/compile.js.map +1 -0
- package/dist/recipes/explain.d.ts +8 -0
- package/dist/recipes/explain.d.ts.map +1 -0
- package/dist/recipes/explain.js +46 -0
- package/dist/recipes/explain.js.map +1 -0
- package/dist/recipes/gallery.d.ts +6 -0
- package/dist/recipes/gallery.d.ts.map +1 -0
- package/dist/recipes/gallery.js +6 -0
- package/dist/recipes/gallery.js.map +1 -0
- package/dist/recipes/gravity.d.ts +16 -0
- package/dist/recipes/gravity.d.ts.map +1 -0
- package/dist/recipes/gravity.js +27 -0
- package/dist/recipes/gravity.js.map +1 -0
- package/dist/recipes/index.d.ts +18 -0
- package/dist/recipes/index.d.ts.map +1 -0
- package/dist/recipes/index.js +36 -0
- package/dist/recipes/index.js.map +1 -0
- package/dist/recipes/intent.d.ts +44 -0
- package/dist/recipes/intent.d.ts.map +1 -0
- package/dist/recipes/intent.js +46 -0
- package/dist/recipes/intent.js.map +1 -0
- package/dist/recipes/schema.d.ts +103 -0
- package/dist/recipes/schema.d.ts.map +1 -0
- package/dist/recipes/schema.js +123 -0
- package/dist/recipes/schema.js.map +1 -0
- package/dist/recipes/wayfinding.d.ts +39 -0
- package/dist/recipes/wayfinding.d.ts.map +1 -0
- package/dist/recipes/wayfinding.js +77 -0
- package/dist/recipes/wayfinding.js.map +1 -0
- package/dist/semantic/index.d.ts +13 -0
- package/dist/semantic/index.d.ts.map +1 -0
- package/dist/semantic/index.js +31 -0
- package/dist/semantic/index.js.map +1 -0
- package/dist/semantic/layers.d.ts +24 -0
- package/dist/semantic/layers.d.ts.map +1 -0
- package/dist/semantic/layers.js +27 -0
- package/dist/semantic/layers.js.map +1 -0
- package/dist/semantic/materials.d.ts +20 -0
- package/dist/semantic/materials.d.ts.map +1 -0
- package/dist/semantic/materials.js +17 -0
- package/dist/semantic/materials.js.map +1 -0
- package/dist/semantic/states.d.ts +11 -0
- package/dist/semantic/states.d.ts.map +1 -0
- package/dist/semantic/states.js +26 -0
- package/dist/semantic/states.js.map +1 -0
- package/dist/visual/channels.d.ts +71 -0
- package/dist/visual/channels.d.ts.map +1 -0
- package/dist/visual/channels.js +70 -0
- package/dist/visual/channels.js.map +1 -0
- package/dist/visual/index.d.ts +39 -0
- package/dist/visual/index.d.ts.map +1 -0
- package/dist/visual/index.js +30 -0
- package/dist/visual/index.js.map +1 -0
- package/dist/visual/lint.d.ts +41 -0
- package/dist/visual/lint.d.ts.map +1 -0
- package/dist/visual/lint.js +58 -0
- package/dist/visual/lint.js.map +1 -0
- package/dist/visual/mapping.d.ts +13 -0
- package/dist/visual/mapping.d.ts.map +1 -0
- package/dist/visual/mapping.js +43 -0
- package/dist/visual/mapping.js.map +1 -0
- package/dist/visual/semantic-text.d.ts +28 -0
- package/dist/visual/semantic-text.d.ts.map +1 -0
- package/dist/visual/semantic-text.js +36 -0
- package/dist/visual/semantic-text.js.map +1 -0
- package/dist/visual/tokens.d.ts +23 -0
- package/dist/visual/tokens.d.ts.map +1 -0
- package/dist/visual/tokens.js +54 -0
- package/dist/visual/tokens.js.map +1 -0
- package/dist/visual/visualization.d.ts +31 -0
- package/dist/visual/visualization.d.ts.map +1 -0
- package/dist/visual/visualization.js +47 -0
- package/dist/visual/visualization.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weight primitives — the page-weight → body-strength contract made one definition.
|
|
3
|
+
*
|
|
4
|
+
* Every page in the example family computes the same two numbers by hand:
|
|
5
|
+
*
|
|
6
|
+
* 1. **A weight** — a positive magnitude (citations, market cap, message count) log-normalized
|
|
7
|
+
* against the set's max into `0..1`: `ln(x+1) / ln(max+1)`. The log is the family's standard
|
|
8
|
+
* "consensus" shape — heavy-tailed data (one work with 6,046 citations next to one with 12)
|
|
9
|
+
* compresses into a legible range while zero stays exactly zero and the max reads exactly one.
|
|
10
|
+
* 2. **A strength** — that weight mapped onto the engine's attract-body range for the
|
|
11
|
+
* `data-strength` attribute: `0.4 + w · 1.6`, i.e. `w ∈ 0..1 → strength ∈ 0.4..2.0`. The floor
|
|
12
|
+
* keeps even the lightest body *present* in the field (strength 0 would make it inert); the
|
|
13
|
+
* ceiling is the range the example family's attract bodies were tuned in.
|
|
14
|
+
*
|
|
15
|
+
* That pair IS the contract between page weights and engine body strengths, and it was hand-rolled
|
|
16
|
+
* at ~38 call sites — drift-prone magic numbers. These primitives are the extraction (the same
|
|
17
|
+
* ratchet as `temporal.ts`, the sibling module): pure, deterministic maps — zero DOM, zero state.
|
|
18
|
+
* Degenerate inputs (NaN, ±Infinity, negative magnitudes, `max ≤ 0`) never produce NaN — each
|
|
19
|
+
* function documents its safe value.
|
|
20
|
+
*
|
|
21
|
+
* Equivalences for callers replacing the hand-rolls (the wave-2 spec):
|
|
22
|
+
*
|
|
23
|
+
* - `logNormalize(x, max)` `===` `Math.log(x + 1) / Math.log(max + 1)` for finite `x ≥ 0` and
|
|
24
|
+
* finite `max > 0` with `x ≤ max` — bit-for-bit, no epsilon (same expression, then clamped).
|
|
25
|
+
* The evidence page's `Math.max(...counts, 1)` guard on the max is subsumed by the `max ≤ 0 → 0`
|
|
26
|
+
* rule for integer counts: all-zero counts produce all-zero weights either way.
|
|
27
|
+
* - `el.dataset.strength = (0.4 + w * 1.6).toFixed(2)` becomes
|
|
28
|
+
* `el.dataset.strength = weightToStrength(w).toFixed(2)` — the function returns the number;
|
|
29
|
+
* the two-decimal formatting stays at the attribute write.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* The `data-strength` floor: `weightToStrength(0)` — the lightest body's strength. A zero-weight
|
|
33
|
+
* body still participates in the field; it is light, not absent.
|
|
34
|
+
*/
|
|
35
|
+
export declare const WEIGHT_STRENGTH_BASE = 0.4;
|
|
36
|
+
/**
|
|
37
|
+
* The `data-strength` span: `weightToStrength(1) − weightToStrength(0)`. Base + span = `2.0`,
|
|
38
|
+
* the heaviest attract strength the example family uses.
|
|
39
|
+
*/
|
|
40
|
+
export declare const WEIGHT_STRENGTH_SPAN = 1.6;
|
|
41
|
+
/**
|
|
42
|
+
* Log-normalize a positive magnitude against the set's max:
|
|
43
|
+
*
|
|
44
|
+
* weight = clamp01( ln(value + 1) / ln(max + 1) )
|
|
45
|
+
*
|
|
46
|
+
* The family's standard "consensus" shape — heavy tails compress (a 500× citation gap reads as a
|
|
47
|
+
* legible weight gap, not a 500× one), zero stays exactly `0`, and `value === max` reads exactly
|
|
48
|
+
* `1`. Monotonically non-decreasing in `value` for a fixed `max > 0`.
|
|
49
|
+
*
|
|
50
|
+
* For finite `value ≥ 0` and finite `max > 0` with `value ≤ max` this is bit-for-bit
|
|
51
|
+
* `Math.log(value + 1) / Math.log(max + 1)` — the exact expression the example pages hand-roll.
|
|
52
|
+
*
|
|
53
|
+
* Degenerate inputs: `max ≤ 0` (or non-finite) returns `0` for every value — no max, no scale;
|
|
54
|
+
* a negative, NaN, or `-Infinity` value reads as `0`; a value above the max (`+Infinity`
|
|
55
|
+
* included) clamps to `1` — live updates can briefly outrun a stale max; re-normalize via
|
|
56
|
+
* {@link logNormalizeAll}.
|
|
57
|
+
*/
|
|
58
|
+
export declare function logNormalize(value: number, max: number): number;
|
|
59
|
+
/**
|
|
60
|
+
* {@link logNormalize} over a whole set in one pass: weights are index-aligned with `values`,
|
|
61
|
+
* each normalized against the set's own max (negative/NaN entries read as `0`, exactly as in
|
|
62
|
+
* `logNormalize`). The max is returned too — live pages keep it and re-normalize incoming
|
|
63
|
+
* single values against it between full passes.
|
|
64
|
+
*
|
|
65
|
+
* An empty set, or one with no positive finite value, returns `{ weights: [0, …], max: 0 }`
|
|
66
|
+
* (all-zero counts produce all-zero weights — the same result as the pages'
|
|
67
|
+
* `Math.max(...counts, 1)` guard). Otherwise the largest entry's weight is exactly `1`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function logNormalizeAll(values: readonly number[]): {
|
|
70
|
+
weights: number[];
|
|
71
|
+
max: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The page-weight → engine-strength contract:
|
|
75
|
+
*
|
|
76
|
+
* strength = WEIGHT_STRENGTH_BASE + w · WEIGHT_STRENGTH_SPAN (= 0.4 + w · 1.6)
|
|
77
|
+
*
|
|
78
|
+
* so `w ∈ 0..1 → strength ∈ 0.4..2.0` — the attract-body range every example uses for
|
|
79
|
+
* `data-strength`. The constants are exported so the mapping has ONE definition; the endpoints
|
|
80
|
+
* are exact: `weightToStrength(0) === 0.4`, `weightToStrength(1) === 2.0`. Monotonically
|
|
81
|
+
* increasing in `w`.
|
|
82
|
+
*
|
|
83
|
+
* Returns the number; callers `.toFixed(2)` at the attribute write
|
|
84
|
+
* (`el.dataset.strength = weightToStrength(w).toFixed(2)`).
|
|
85
|
+
*
|
|
86
|
+
* Degenerate inputs: `w` outside `0..1` clamps to the endpoints (±Infinity included); NaN reads
|
|
87
|
+
* as `0` — an unknown weight is a light body, not a NaN attribute.
|
|
88
|
+
*/
|
|
89
|
+
export declare function weightToStrength(w: number): number;
|
|
90
|
+
/**
|
|
91
|
+
* Min–max log normalization — the family's *contrast-stretched* weight shape:
|
|
92
|
+
*
|
|
93
|
+
* ```txt
|
|
94
|
+
* w = (ln(value + 1) − ln(min + 1)) / (ln(max + 1) − ln(min + 1))
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* Where {@link logNormalize} anchors zero at zero (absolute consensus — a 10-citation paper
|
|
98
|
+
* stays light next to a 10,000-citation one), `logNormalizeBetween` stretches the SET's own
|
|
99
|
+
* range to 0..1 — the lightest member reads 0, the heaviest 1 — which is what the dense
|
|
100
|
+
* mosaics/front pages use so every tier is visually distinct (market caps, pageviews,
|
|
101
|
+
* listens, reply tempo). Bit-identical to the pages' hand-rolled
|
|
102
|
+
* `(Math.log(v + 1) − lmin) / (lmax − lmin)` for finite inputs in range.
|
|
103
|
+
*
|
|
104
|
+
* Degenerate set (max ≤ min — all values equal): returns `opts.equal`, default `1` (the
|
|
105
|
+
* market/newsroom convention: an undifferentiated set reads heavy, not absent). Pass
|
|
106
|
+
* `{ equal: 0 }` for the inverse convention. Out-of-range values clamp to 0..1; NaN reads 0.
|
|
107
|
+
*/
|
|
108
|
+
export declare function logNormalizeBetween(value: number, min: number, max: number, opts?: {
|
|
109
|
+
equal?: number;
|
|
110
|
+
}): number;
|
|
111
|
+
//# sourceMappingURL=weights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../../src/core/weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAIxC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,MAAM,CAMR"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weight primitives — the page-weight → body-strength contract made one definition.
|
|
3
|
+
*
|
|
4
|
+
* Every page in the example family computes the same two numbers by hand:
|
|
5
|
+
*
|
|
6
|
+
* 1. **A weight** — a positive magnitude (citations, market cap, message count) log-normalized
|
|
7
|
+
* against the set's max into `0..1`: `ln(x+1) / ln(max+1)`. The log is the family's standard
|
|
8
|
+
* "consensus" shape — heavy-tailed data (one work with 6,046 citations next to one with 12)
|
|
9
|
+
* compresses into a legible range while zero stays exactly zero and the max reads exactly one.
|
|
10
|
+
* 2. **A strength** — that weight mapped onto the engine's attract-body range for the
|
|
11
|
+
* `data-strength` attribute: `0.4 + w · 1.6`, i.e. `w ∈ 0..1 → strength ∈ 0.4..2.0`. The floor
|
|
12
|
+
* keeps even the lightest body *present* in the field (strength 0 would make it inert); the
|
|
13
|
+
* ceiling is the range the example family's attract bodies were tuned in.
|
|
14
|
+
*
|
|
15
|
+
* That pair IS the contract between page weights and engine body strengths, and it was hand-rolled
|
|
16
|
+
* at ~38 call sites — drift-prone magic numbers. These primitives are the extraction (the same
|
|
17
|
+
* ratchet as `temporal.ts`, the sibling module): pure, deterministic maps — zero DOM, zero state.
|
|
18
|
+
* Degenerate inputs (NaN, ±Infinity, negative magnitudes, `max ≤ 0`) never produce NaN — each
|
|
19
|
+
* function documents its safe value.
|
|
20
|
+
*
|
|
21
|
+
* Equivalences for callers replacing the hand-rolls (the wave-2 spec):
|
|
22
|
+
*
|
|
23
|
+
* - `logNormalize(x, max)` `===` `Math.log(x + 1) / Math.log(max + 1)` for finite `x ≥ 0` and
|
|
24
|
+
* finite `max > 0` with `x ≤ max` — bit-for-bit, no epsilon (same expression, then clamped).
|
|
25
|
+
* The evidence page's `Math.max(...counts, 1)` guard on the max is subsumed by the `max ≤ 0 → 0`
|
|
26
|
+
* rule for integer counts: all-zero counts produce all-zero weights either way.
|
|
27
|
+
* - `el.dataset.strength = (0.4 + w * 1.6).toFixed(2)` becomes
|
|
28
|
+
* `el.dataset.strength = weightToStrength(w).toFixed(2)` — the function returns the number;
|
|
29
|
+
* the two-decimal formatting stays at the attribute write.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* The `data-strength` floor: `weightToStrength(0)` — the lightest body's strength. A zero-weight
|
|
33
|
+
* body still participates in the field; it is light, not absent.
|
|
34
|
+
*/
|
|
35
|
+
export const WEIGHT_STRENGTH_BASE = 0.4;
|
|
36
|
+
/**
|
|
37
|
+
* The `data-strength` span: `weightToStrength(1) − weightToStrength(0)`. Base + span = `2.0`,
|
|
38
|
+
* the heaviest attract strength the example family uses.
|
|
39
|
+
*/
|
|
40
|
+
export const WEIGHT_STRENGTH_SPAN = 1.6;
|
|
41
|
+
const clamp01 = (n) => (n < 0 ? 0 : n > 1 ? 1 : n);
|
|
42
|
+
/**
|
|
43
|
+
* Log-normalize a positive magnitude against the set's max:
|
|
44
|
+
*
|
|
45
|
+
* weight = clamp01( ln(value + 1) / ln(max + 1) )
|
|
46
|
+
*
|
|
47
|
+
* The family's standard "consensus" shape — heavy tails compress (a 500× citation gap reads as a
|
|
48
|
+
* legible weight gap, not a 500× one), zero stays exactly `0`, and `value === max` reads exactly
|
|
49
|
+
* `1`. Monotonically non-decreasing in `value` for a fixed `max > 0`.
|
|
50
|
+
*
|
|
51
|
+
* For finite `value ≥ 0` and finite `max > 0` with `value ≤ max` this is bit-for-bit
|
|
52
|
+
* `Math.log(value + 1) / Math.log(max + 1)` — the exact expression the example pages hand-roll.
|
|
53
|
+
*
|
|
54
|
+
* Degenerate inputs: `max ≤ 0` (or non-finite) returns `0` for every value — no max, no scale;
|
|
55
|
+
* a negative, NaN, or `-Infinity` value reads as `0`; a value above the max (`+Infinity`
|
|
56
|
+
* included) clamps to `1` — live updates can briefly outrun a stale max; re-normalize via
|
|
57
|
+
* {@link logNormalizeAll}.
|
|
58
|
+
*/
|
|
59
|
+
export function logNormalize(value, max) {
|
|
60
|
+
if (!Number.isFinite(max) || max <= 0)
|
|
61
|
+
return 0;
|
|
62
|
+
const v = value > 0 ? value : 0; // NaN/negatives/−Infinity read as 0; +Infinity clamps below
|
|
63
|
+
return clamp01(Math.log(v + 1) / Math.log(max + 1));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* {@link logNormalize} over a whole set in one pass: weights are index-aligned with `values`,
|
|
67
|
+
* each normalized against the set's own max (negative/NaN entries read as `0`, exactly as in
|
|
68
|
+
* `logNormalize`). The max is returned too — live pages keep it and re-normalize incoming
|
|
69
|
+
* single values against it between full passes.
|
|
70
|
+
*
|
|
71
|
+
* An empty set, or one with no positive finite value, returns `{ weights: [0, …], max: 0 }`
|
|
72
|
+
* (all-zero counts produce all-zero weights — the same result as the pages'
|
|
73
|
+
* `Math.max(...counts, 1)` guard). Otherwise the largest entry's weight is exactly `1`.
|
|
74
|
+
*/
|
|
75
|
+
export function logNormalizeAll(values) {
|
|
76
|
+
let max = 0;
|
|
77
|
+
for (const v of values)
|
|
78
|
+
if (Number.isFinite(v) && v > max)
|
|
79
|
+
max = v;
|
|
80
|
+
return { weights: values.map((v) => logNormalize(v, max)), max };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The page-weight → engine-strength contract:
|
|
84
|
+
*
|
|
85
|
+
* strength = WEIGHT_STRENGTH_BASE + w · WEIGHT_STRENGTH_SPAN (= 0.4 + w · 1.6)
|
|
86
|
+
*
|
|
87
|
+
* so `w ∈ 0..1 → strength ∈ 0.4..2.0` — the attract-body range every example uses for
|
|
88
|
+
* `data-strength`. The constants are exported so the mapping has ONE definition; the endpoints
|
|
89
|
+
* are exact: `weightToStrength(0) === 0.4`, `weightToStrength(1) === 2.0`. Monotonically
|
|
90
|
+
* increasing in `w`.
|
|
91
|
+
*
|
|
92
|
+
* Returns the number; callers `.toFixed(2)` at the attribute write
|
|
93
|
+
* (`el.dataset.strength = weightToStrength(w).toFixed(2)`).
|
|
94
|
+
*
|
|
95
|
+
* Degenerate inputs: `w` outside `0..1` clamps to the endpoints (±Infinity included); NaN reads
|
|
96
|
+
* as `0` — an unknown weight is a light body, not a NaN attribute.
|
|
97
|
+
*/
|
|
98
|
+
export function weightToStrength(w) {
|
|
99
|
+
return WEIGHT_STRENGTH_BASE + clamp01(Number.isNaN(w) ? 0 : w) * WEIGHT_STRENGTH_SPAN;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Min–max log normalization — the family's *contrast-stretched* weight shape:
|
|
103
|
+
*
|
|
104
|
+
* ```txt
|
|
105
|
+
* w = (ln(value + 1) − ln(min + 1)) / (ln(max + 1) − ln(min + 1))
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* Where {@link logNormalize} anchors zero at zero (absolute consensus — a 10-citation paper
|
|
109
|
+
* stays light next to a 10,000-citation one), `logNormalizeBetween` stretches the SET's own
|
|
110
|
+
* range to 0..1 — the lightest member reads 0, the heaviest 1 — which is what the dense
|
|
111
|
+
* mosaics/front pages use so every tier is visually distinct (market caps, pageviews,
|
|
112
|
+
* listens, reply tempo). Bit-identical to the pages' hand-rolled
|
|
113
|
+
* `(Math.log(v + 1) − lmin) / (lmax − lmin)` for finite inputs in range.
|
|
114
|
+
*
|
|
115
|
+
* Degenerate set (max ≤ min — all values equal): returns `opts.equal`, default `1` (the
|
|
116
|
+
* market/newsroom convention: an undifferentiated set reads heavy, not absent). Pass
|
|
117
|
+
* `{ equal: 0 }` for the inverse convention. Out-of-range values clamp to 0..1; NaN reads 0.
|
|
118
|
+
*/
|
|
119
|
+
export function logNormalizeBetween(value, min, max, opts) {
|
|
120
|
+
if (!Number.isFinite(value) || Number.isNaN(value))
|
|
121
|
+
return 0;
|
|
122
|
+
const lmin = Math.log(Math.max(0, min) + 1);
|
|
123
|
+
const lmax = Math.log(Math.max(0, max) + 1);
|
|
124
|
+
if (!(lmax > lmin))
|
|
125
|
+
return opts?.equal ?? 1;
|
|
126
|
+
return clamp01((Math.log(Math.max(0, value) + 1) - lmin) / (lmax - lmin));
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=weights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weights.js","sourceRoot":"","sources":["../../src/core/weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,GAAW;IACrD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,4DAA4D;IAC7F,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG;YAAE,GAAG,GAAG,CAAC,CAAC;IACnE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,OAAO,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC;AACxF,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,GAAW,EACX,GAAW,EACX,IAAyB;IAEzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Energy diagnostics (visualization-methods-taxonomy §7). Pure accounting over a particle set —
|
|
3
|
+
* kinetic, thermal, and total energy, plus per-step drift. The data behind the "energy view": it
|
|
4
|
+
* reads state, never mutates it (the energy view must not affect integration).
|
|
5
|
+
*/
|
|
6
|
+
import type { Particle } from '../core/types.ts';
|
|
7
|
+
/** Kinetic energy Σ ½·m·|v|² — the full 3D speed (vz is 0 in a flat field, z-axis.md). */
|
|
8
|
+
export declare function kineticEnergy(particles: readonly Particle[]): number;
|
|
9
|
+
/** Thermal energy proxy Σ heat (agitation held as per-particle heat ∈ [0,1]). */
|
|
10
|
+
export declare function thermalEnergy(particles: readonly Particle[]): number;
|
|
11
|
+
export interface EnergyReport {
|
|
12
|
+
kinetic: number;
|
|
13
|
+
thermal: number;
|
|
14
|
+
total: number;
|
|
15
|
+
count: number;
|
|
16
|
+
}
|
|
17
|
+
/** A full energy snapshot for the dashboard. */
|
|
18
|
+
export declare function energyReport(particles: readonly Particle[]): EnergyReport;
|
|
19
|
+
/** Fractional energy drift between two snapshots — for stability/conservation checks. */
|
|
20
|
+
export declare function energyDrift(before: number, after: number): number;
|
|
21
|
+
//# sourceMappingURL=energy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"energy.d.ts","sourceRoot":"","sources":["../../src/diagnostics/energy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAKpE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAIpE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,YAAY,CAIzE;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Kinetic energy Σ ½·m·|v|² — the full 3D speed (vz is 0 in a flat field, z-axis.md). */
|
|
2
|
+
export function kineticEnergy(particles) {
|
|
3
|
+
let k = 0;
|
|
4
|
+
for (const p of particles)
|
|
5
|
+
k += 0.5 * (p.m || 1) * (p.vx * p.vx + p.vy * p.vy + (p.vz ?? 0) * (p.vz ?? 0));
|
|
6
|
+
return k;
|
|
7
|
+
}
|
|
8
|
+
/** Thermal energy proxy Σ heat (agitation held as per-particle heat ∈ [0,1]). */
|
|
9
|
+
export function thermalEnergy(particles) {
|
|
10
|
+
let t = 0;
|
|
11
|
+
for (const p of particles)
|
|
12
|
+
t += p.heat;
|
|
13
|
+
return t;
|
|
14
|
+
}
|
|
15
|
+
/** A full energy snapshot for the dashboard. */
|
|
16
|
+
export function energyReport(particles) {
|
|
17
|
+
const kinetic = kineticEnergy(particles);
|
|
18
|
+
const thermal = thermalEnergy(particles);
|
|
19
|
+
return { kinetic, thermal, total: kinetic + thermal, count: particles.length };
|
|
20
|
+
}
|
|
21
|
+
/** Fractional energy drift between two snapshots — for stability/conservation checks. */
|
|
22
|
+
export function energyDrift(before, after) {
|
|
23
|
+
if (before === 0)
|
|
24
|
+
return after === 0 ? 0 : Infinity;
|
|
25
|
+
return Math.abs(after - before) / Math.abs(before);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=energy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"energy.js","sourceRoot":"","sources":["../../src/diagnostics/energy.ts"],"names":[],"mappings":"AAOA,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,SAA8B;IAC1D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,CAAC,IAAI,SAAS;QACvB,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,SAA8B;IAC1D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IACvC,OAAO,CAAC,CAAC;AACX,CAAC;AASD,gDAAgD;AAChD,MAAM,UAAU,YAAY,CAAC,SAA8B;IACzD,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AACjF,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,KAAa;IACvD,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heatmap-variant samplers (visualization-methods-taxonomy §5). The engine ships the density
|
|
3
|
+
* heatmap; these are the per-particle samplers + a pure grid accumulator for the other documented
|
|
4
|
+
* variants (heat, velocity). A heatmap is a scalar buffer — pick what each particle deposits.
|
|
5
|
+
*/
|
|
6
|
+
import type { Particle } from '../core/types.ts';
|
|
7
|
+
export type HeatmapKind = 'density' | 'heat' | 'velocity';
|
|
8
|
+
/** What each particle deposits, per heatmap kind. */
|
|
9
|
+
export declare const HEATMAP_SAMPLERS: Readonly<Record<HeatmapKind, (p: Particle) => number>>;
|
|
10
|
+
export interface HeatmapGrid {
|
|
11
|
+
cols: number;
|
|
12
|
+
rows: number;
|
|
13
|
+
resolution: number;
|
|
14
|
+
values: Float32Array;
|
|
15
|
+
/** running peak, for [0,1] normalization. */
|
|
16
|
+
peak: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Accumulate a per-particle scalar (chosen by `kind`) onto a coarse grid — a heatmap variant. Each
|
|
20
|
+
* particle deposits into its cell; `peak` normalizes the render. Pure.
|
|
21
|
+
*/
|
|
22
|
+
export declare function accumulateHeatmap(particles: readonly Particle[], kind: HeatmapKind, width: number, height: number, resolution?: number): HeatmapGrid;
|
|
23
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/diagnostics/fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1D,qDAAqD;AACrD,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,MAAM,CAAC,CAInF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,SAAI,GACb,WAAW,CAgBb"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** What each particle deposits, per heatmap kind. */
|
|
2
|
+
export const HEATMAP_SAMPLERS = {
|
|
3
|
+
density: () => 1,
|
|
4
|
+
heat: (p) => p.heat,
|
|
5
|
+
velocity: (p) => Math.hypot(p.vx, p.vy),
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Accumulate a per-particle scalar (chosen by `kind`) onto a coarse grid — a heatmap variant. Each
|
|
9
|
+
* particle deposits into its cell; `peak` normalizes the render. Pure.
|
|
10
|
+
*/
|
|
11
|
+
export function accumulateHeatmap(particles, kind, width, height, resolution = 8) {
|
|
12
|
+
const cols = Math.max(1, Math.ceil(width / resolution));
|
|
13
|
+
const rows = Math.max(1, Math.ceil(height / resolution));
|
|
14
|
+
const values = new Float32Array(cols * rows);
|
|
15
|
+
const sample = HEATMAP_SAMPLERS[kind];
|
|
16
|
+
let peak = 0;
|
|
17
|
+
for (const p of particles) {
|
|
18
|
+
if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height)
|
|
19
|
+
continue;
|
|
20
|
+
const c = Math.min(cols - 1, Math.floor(p.x / resolution));
|
|
21
|
+
const r = Math.min(rows - 1, Math.floor(p.y / resolution));
|
|
22
|
+
const i = r * cols + c;
|
|
23
|
+
const v = (values[i] ?? 0) + sample(p);
|
|
24
|
+
values[i] = v;
|
|
25
|
+
if (v > peak)
|
|
26
|
+
peak = v;
|
|
27
|
+
}
|
|
28
|
+
return { cols, rows, resolution, values, peak };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/diagnostics/fields.ts"],"names":[],"mappings":"AASA,qDAAqD;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAA2D;IACtF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;CACxC,CAAC;AAWF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAA8B,EAC9B,IAAiB,EACjB,KAAa,EACb,MAAc,EACd,UAAU,GAAG,CAAC;IAEd,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM;YAAE,SAAS;QAClE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostics (visualization-methods-taxonomy §3–§7, §11). The data behind the diagnostic overlays —
|
|
3
|
+
* energy accounting, scalar potential + grid sampling, probe force-vectors + causality, heatmap-variant
|
|
4
|
+
* samplers — plus `render.ts`, which draws them onto a Canvas 2D context (C1). Nothing mutates physics.
|
|
5
|
+
*/
|
|
6
|
+
export * from './energy.ts';
|
|
7
|
+
export * from './potential.ts';
|
|
8
|
+
export * from './probes.ts';
|
|
9
|
+
export * from './fields.ts';
|
|
10
|
+
export * from './render.ts';
|
|
11
|
+
export * from './modes.ts';
|
|
12
|
+
/** The diagnostics this module provides (inspectable list; canvas drawing is the UI frontier). */
|
|
13
|
+
export declare const DIAGNOSTICS: readonly [{
|
|
14
|
+
readonly name: "energy";
|
|
15
|
+
readonly provides: "kinetic / thermal / total energy + drift";
|
|
16
|
+
readonly reads: "particles";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "potential";
|
|
19
|
+
readonly provides: "scalar potential Φ + grid sampling for contours";
|
|
20
|
+
readonly reads: "bodies";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "force-vectors";
|
|
23
|
+
readonly provides: "a force’s Δv on a probe at a point";
|
|
24
|
+
readonly reads: "force + probe";
|
|
25
|
+
}, {
|
|
26
|
+
readonly name: "causality";
|
|
27
|
+
readonly provides: "per-token contribution to motion (ranked bars + vectors)";
|
|
28
|
+
readonly reads: "registry + tokens";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "heatmap-variants";
|
|
31
|
+
readonly provides: "density / heat / velocity scalar grids";
|
|
32
|
+
readonly reads: "particles";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "topology";
|
|
35
|
+
readonly provides: "relationship-agent coupling edges (strength / memory)";
|
|
36
|
+
readonly reads: "relationship agents + positions";
|
|
37
|
+
}, {
|
|
38
|
+
readonly name: "inspector";
|
|
39
|
+
readonly provides: "body / agent / metric / contract HUD rows";
|
|
40
|
+
readonly reads: "system snapshot";
|
|
41
|
+
}, {
|
|
42
|
+
readonly name: "prediction";
|
|
43
|
+
readonly provides: "deterministic forward ghost trajectory";
|
|
44
|
+
readonly reads: "forces + bodies + probe";
|
|
45
|
+
}];
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAE3B,kGAAkG;AAClG,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASd,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostics (visualization-methods-taxonomy §3–§7, §11). The data behind the diagnostic overlays —
|
|
3
|
+
* energy accounting, scalar potential + grid sampling, probe force-vectors + causality, heatmap-variant
|
|
4
|
+
* samplers — plus `render.ts`, which draws them onto a Canvas 2D context (C1). Nothing mutates physics.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./energy.js";
|
|
7
|
+
export * from "./potential.js";
|
|
8
|
+
export * from "./probes.js";
|
|
9
|
+
export * from "./fields.js";
|
|
10
|
+
export * from "./render.js";
|
|
11
|
+
export * from "./modes.js";
|
|
12
|
+
/** The diagnostics this module provides (inspectable list; canvas drawing is the UI frontier). */
|
|
13
|
+
export const DIAGNOSTICS = [
|
|
14
|
+
{ name: 'energy', provides: 'kinetic / thermal / total energy + drift', reads: 'particles' },
|
|
15
|
+
{ name: 'potential', provides: 'scalar potential Φ + grid sampling for contours', reads: 'bodies' },
|
|
16
|
+
{ name: 'force-vectors', provides: 'a force’s Δv on a probe at a point', reads: 'force + probe' },
|
|
17
|
+
{ name: 'causality', provides: 'per-token contribution to motion (ranked bars + vectors)', reads: 'registry + tokens' },
|
|
18
|
+
{ name: 'heatmap-variants', provides: 'density / heat / velocity scalar grids', reads: 'particles' },
|
|
19
|
+
{ name: 'topology', provides: 'relationship-agent coupling edges (strength / memory)', reads: 'relationship agents + positions' },
|
|
20
|
+
{ name: 'inspector', provides: 'body / agent / metric / contract HUD rows', reads: 'system snapshot' },
|
|
21
|
+
{ name: 'prediction', provides: 'deterministic forward ghost trajectory', reads: 'forces + bodies + probe' },
|
|
22
|
+
];
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAE3B,kGAAkG;AAClG,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,0CAA0C,EAAE,KAAK,EAAE,WAAW,EAAE;IAC5F,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,iDAAiD,EAAE,KAAK,EAAE,QAAQ,EAAE;IACnG,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,oCAAoC,EAAE,KAAK,EAAE,eAAe,EAAE;IACjG,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,0DAA0D,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACvH,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,wCAAwC,EAAE,KAAK,EAAE,WAAW,EAAE;IACpG,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,uDAAuD,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACjI,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,2CAA2C,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACtG,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,wCAAwC,EAAE,KAAK,EAAE,yBAAyB,EAAE;CACpG,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four debug/graph render modes (visualization-methods-taxonomy "Render Modes Catalog" —
|
|
3
|
+
* previously `planned`): topology, inspector, causality, prediction. Each is a pure data/geometry
|
|
4
|
+
* function (testable, no canvas) plus a thin `draw*` helper. Like the C1 overlays these *reveal*
|
|
5
|
+
* state — they read bodies/agents/forces and never mutate physics.
|
|
6
|
+
*
|
|
7
|
+
* topology relationship-agent coupling graph (strength → width, memory → glow)
|
|
8
|
+
* inspector a debug HUD of body/agent/metric/contract counts
|
|
9
|
+
* causality per-force contribution to motion at a point (reuses causalityAt)
|
|
10
|
+
* prediction a deterministic forward "ghost" trajectory of a probe under the body forces
|
|
11
|
+
*/
|
|
12
|
+
import type { Body, ForceRegistry } from '../core/types.ts';
|
|
13
|
+
import type { RelationshipAgent } from '../agents/relationship.ts';
|
|
14
|
+
import { type CausalContribution } from './probes.ts';
|
|
15
|
+
type Ctx = CanvasRenderingContext2D;
|
|
16
|
+
type Pt = {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
/** A relationship resolved to two endpoint positions, ready to draw. */
|
|
21
|
+
export interface TopologyEdge {
|
|
22
|
+
from: Pt;
|
|
23
|
+
to: Pt;
|
|
24
|
+
type: string;
|
|
25
|
+
/** active coupling strength ∈ [0,1] → line width. */
|
|
26
|
+
strength: number;
|
|
27
|
+
/** accumulated familiarity ∈ [0,1] → persistence glow. */
|
|
28
|
+
memory: number;
|
|
29
|
+
active: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Position lookup for a body id (returns undefined for unplaced bodies). */
|
|
32
|
+
export type PositionOf = (bodyId: string) => Pt | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve relationship agents to drawable edges via a position lookup. Agents whose endpoints have
|
|
35
|
+
* no position are dropped (you can only draw what you can place). Pure.
|
|
36
|
+
*/
|
|
37
|
+
export declare function topologyEdges(agents: readonly RelationshipAgent[], posOf: PositionOf): TopologyEdge[];
|
|
38
|
+
/** Draw the coupling graph: thicker = stronger, brighter = more memory, accent = active this tick. */
|
|
39
|
+
export declare function drawTopology(ctx: Ctx, agents: readonly RelationshipAgent[], posOf: PositionOf, opts?: {
|
|
40
|
+
color?: string;
|
|
41
|
+
activeColor?: string;
|
|
42
|
+
maxWidth?: number;
|
|
43
|
+
}): void;
|
|
44
|
+
/** A snapshot of system counts/metrics for the inspector HUD. */
|
|
45
|
+
export interface InspectorSnapshot {
|
|
46
|
+
bodies?: number;
|
|
47
|
+
particles?: number;
|
|
48
|
+
agents?: number;
|
|
49
|
+
relationships?: number;
|
|
50
|
+
contracts?: number;
|
|
51
|
+
metrics?: Record<string, number | string>;
|
|
52
|
+
}
|
|
53
|
+
export interface InspectorRow {
|
|
54
|
+
label: string;
|
|
55
|
+
value: string;
|
|
56
|
+
}
|
|
57
|
+
/** Flatten a snapshot to ordered label/value rows (counts first, then metrics). Pure. */
|
|
58
|
+
export declare function inspectorRows(snap: InspectorSnapshot): InspectorRow[];
|
|
59
|
+
/** Draw the inspector as a compact monospace panel (top-left by default). */
|
|
60
|
+
export declare function drawInspector(ctx: Ctx, snap: InspectorSnapshot, opts?: {
|
|
61
|
+
x?: number;
|
|
62
|
+
y?: number;
|
|
63
|
+
width?: number;
|
|
64
|
+
}): void;
|
|
65
|
+
/** A per-token causal contribution ranked by magnitude, with its share of the total. */
|
|
66
|
+
export interface CausalBar {
|
|
67
|
+
token: string;
|
|
68
|
+
magnitude: number;
|
|
69
|
+
/** share of total |contribution| ∈ [0,1]. */
|
|
70
|
+
fraction: number;
|
|
71
|
+
}
|
|
72
|
+
/** Rank causal contributions by magnitude (desc) with each one's fraction of the total. Pure. */
|
|
73
|
+
export declare function causalityBars(contribs: readonly CausalContribution[]): CausalBar[];
|
|
74
|
+
/** Draw causality at a point: a vector per contributing force from the origin, plus a ranked bar list. */
|
|
75
|
+
export declare function drawCausality(ctx: Ctx, contribs: readonly CausalContribution[], origin: Pt, opts?: {
|
|
76
|
+
scale?: number;
|
|
77
|
+
x?: number;
|
|
78
|
+
y?: number;
|
|
79
|
+
width?: number;
|
|
80
|
+
}): void;
|
|
81
|
+
export interface GhostOptions {
|
|
82
|
+
/** number of forward steps to simulate (default 60). */
|
|
83
|
+
steps?: number;
|
|
84
|
+
/** velocity damping per step (default = the integrator's FRICTION). */
|
|
85
|
+
friction?: number;
|
|
86
|
+
/** scale applied to summed force Δv per step (default 1). */
|
|
87
|
+
forceScale?: number;
|
|
88
|
+
/** the ghost probe's charge (for charge/magnetism forces; default 0). */
|
|
89
|
+
charge?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A deterministic forward "ghost" trajectory: integrate one probe under the class-A body forces,
|
|
93
|
+
* summing each (force, body) Δv per step and damping by friction — the same shape the real
|
|
94
|
+
* integrator uses, kept dependency-light. Pure and repeatable: same inputs → same path. This is the
|
|
95
|
+
* *prediction* overlay's data (an expected future path), not the live sim.
|
|
96
|
+
*/
|
|
97
|
+
export declare function ghostTrajectory(forces: ForceRegistry, tokens: readonly string[], bodies: readonly Body[], start: {
|
|
98
|
+
x: number;
|
|
99
|
+
y: number;
|
|
100
|
+
vx: number;
|
|
101
|
+
vy: number;
|
|
102
|
+
}, opts?: GhostOptions): Pt[];
|
|
103
|
+
/** Draw a ghost trajectory as a dashed path that fades toward the predicted future. */
|
|
104
|
+
export declare function drawPrediction(ctx: Ctx, points: readonly Pt[], opts?: {
|
|
105
|
+
color?: string;
|
|
106
|
+
}): void;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=modes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../src/diagnostics/modes.ts"],"names":[],"mappings":"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"}
|