@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,181 @@
|
|
|
1
|
+
import { FRICTION } from "../core/integrator.js";
|
|
2
|
+
import { forceVectorAt } from "./probes.js";
|
|
3
|
+
function arrow(ctx, x, y, dx, dy, head = 4) {
|
|
4
|
+
const len = Math.hypot(dx, dy);
|
|
5
|
+
if (len < 0.001)
|
|
6
|
+
return;
|
|
7
|
+
ctx.beginPath();
|
|
8
|
+
ctx.moveTo(x, y);
|
|
9
|
+
ctx.lineTo(x + dx, y + dy);
|
|
10
|
+
const a = Math.atan2(dy, dx);
|
|
11
|
+
ctx.lineTo(x + dx - head * Math.cos(a - 0.4), y + dy - head * Math.sin(a - 0.4));
|
|
12
|
+
ctx.moveTo(x + dx, y + dy);
|
|
13
|
+
ctx.lineTo(x + dx - head * Math.cos(a + 0.4), y + dy - head * Math.sin(a + 0.4));
|
|
14
|
+
ctx.stroke();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve relationship agents to drawable edges via a position lookup. Agents whose endpoints have
|
|
18
|
+
* no position are dropped (you can only draw what you can place). Pure.
|
|
19
|
+
*/
|
|
20
|
+
export function topologyEdges(agents, posOf) {
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const a of agents) {
|
|
23
|
+
const from = posOf(a.from);
|
|
24
|
+
const to = posOf(a.to);
|
|
25
|
+
if (!from || !to)
|
|
26
|
+
continue;
|
|
27
|
+
out.push({ from, to, type: a.type, strength: a.strength, memory: a.memory, active: a.active });
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
/** Draw the coupling graph: thicker = stronger, brighter = more memory, accent = active this tick. */
|
|
32
|
+
export function drawTopology(ctx, agents, posOf, opts = {}) {
|
|
33
|
+
const color = opts.color ?? '77,163,255';
|
|
34
|
+
const activeColor = opts.activeColor ?? '45,212,191';
|
|
35
|
+
const maxWidth = opts.maxWidth ?? 4;
|
|
36
|
+
ctx.save();
|
|
37
|
+
for (const e of topologyEdges(agents, posOf)) {
|
|
38
|
+
const alpha = 0.18 + 0.62 * e.memory;
|
|
39
|
+
ctx.strokeStyle = `rgba(${e.active ? activeColor : color},${alpha.toFixed(3)})`;
|
|
40
|
+
ctx.lineWidth = 0.5 + maxWidth * e.strength;
|
|
41
|
+
ctx.beginPath();
|
|
42
|
+
ctx.moveTo(e.from.x, e.from.y);
|
|
43
|
+
ctx.lineTo(e.to.x, e.to.y);
|
|
44
|
+
ctx.stroke();
|
|
45
|
+
}
|
|
46
|
+
ctx.restore();
|
|
47
|
+
}
|
|
48
|
+
const fmt = (v) => (typeof v === 'number' ? (Number.isInteger(v) ? String(v) : v.toFixed(3)) : v);
|
|
49
|
+
/** Flatten a snapshot to ordered label/value rows (counts first, then metrics). Pure. */
|
|
50
|
+
export function inspectorRows(snap) {
|
|
51
|
+
const rows = [];
|
|
52
|
+
const add = (label, v) => {
|
|
53
|
+
if (v !== undefined)
|
|
54
|
+
rows.push({ label, value: fmt(v) });
|
|
55
|
+
};
|
|
56
|
+
add('bodies', snap.bodies);
|
|
57
|
+
add('particles', snap.particles);
|
|
58
|
+
add('agents', snap.agents);
|
|
59
|
+
add('relationships', snap.relationships);
|
|
60
|
+
add('contracts', snap.contracts);
|
|
61
|
+
if (snap.metrics)
|
|
62
|
+
for (const k of Object.keys(snap.metrics))
|
|
63
|
+
rows.push({ label: k, value: fmt(snap.metrics[k]) });
|
|
64
|
+
return rows;
|
|
65
|
+
}
|
|
66
|
+
/** Draw the inspector as a compact monospace panel (top-left by default). */
|
|
67
|
+
export function drawInspector(ctx, snap, opts = {}) {
|
|
68
|
+
const rows = inspectorRows(snap);
|
|
69
|
+
const x = opts.x ?? 12;
|
|
70
|
+
const y = opts.y ?? 12;
|
|
71
|
+
const w = opts.width ?? 180;
|
|
72
|
+
const lh = 16;
|
|
73
|
+
const h = rows.length * lh + 10;
|
|
74
|
+
ctx.save();
|
|
75
|
+
ctx.font = '11px ui-monospace, monospace';
|
|
76
|
+
ctx.fillStyle = 'rgba(11,11,16,0.78)';
|
|
77
|
+
ctx.fillRect(x, y, w, h);
|
|
78
|
+
rows.forEach((r, i) => {
|
|
79
|
+
const yy = y + 8 + i * lh + 8;
|
|
80
|
+
ctx.fillStyle = 'rgba(255,255,255,0.45)';
|
|
81
|
+
ctx.fillText(r.label, x + 8, yy);
|
|
82
|
+
ctx.fillStyle = '#4da3ff';
|
|
83
|
+
ctx.textAlign = 'right';
|
|
84
|
+
ctx.fillText(r.value, x + w - 8, yy);
|
|
85
|
+
ctx.textAlign = 'left';
|
|
86
|
+
});
|
|
87
|
+
ctx.restore();
|
|
88
|
+
}
|
|
89
|
+
/** Rank causal contributions by magnitude (desc) with each one's fraction of the total. Pure. */
|
|
90
|
+
export function causalityBars(contribs) {
|
|
91
|
+
const mags = contribs.map((c) => ({ token: c.token, magnitude: Math.hypot(c.dvx, c.dvy) }));
|
|
92
|
+
const total = mags.reduce((s, m) => s + m.magnitude, 0) || 1;
|
|
93
|
+
return mags
|
|
94
|
+
.map((m) => ({ token: m.token, magnitude: m.magnitude, fraction: m.magnitude / total }))
|
|
95
|
+
.sort((a, b) => b.magnitude - a.magnitude);
|
|
96
|
+
}
|
|
97
|
+
/** Draw causality at a point: a vector per contributing force from the origin, plus a ranked bar list. */
|
|
98
|
+
export function drawCausality(ctx, contribs, origin, opts = {}) {
|
|
99
|
+
const scale = opts.scale ?? 8;
|
|
100
|
+
ctx.save();
|
|
101
|
+
// vectors from the probe origin
|
|
102
|
+
ctx.strokeStyle = 'rgba(240,136,62,0.85)';
|
|
103
|
+
ctx.lineWidth = 1.5;
|
|
104
|
+
for (const c of contribs)
|
|
105
|
+
arrow(ctx, origin.x, origin.y, c.dvx * scale, c.dvy * scale, 5);
|
|
106
|
+
// ranked bars
|
|
107
|
+
const bars = causalityBars(contribs);
|
|
108
|
+
const bx = opts.x ?? origin.x + 14;
|
|
109
|
+
const by = opts.y ?? origin.y + 14;
|
|
110
|
+
const bw = opts.width ?? 120;
|
|
111
|
+
ctx.font = '10px ui-monospace, monospace';
|
|
112
|
+
bars.forEach((b, i) => {
|
|
113
|
+
const yy = by + i * 14;
|
|
114
|
+
ctx.fillStyle = 'rgba(255,255,255,0.1)';
|
|
115
|
+
ctx.fillRect(bx, yy, bw, 8);
|
|
116
|
+
ctx.fillStyle = '#f0883e';
|
|
117
|
+
ctx.fillRect(bx, yy, bw * b.fraction, 8);
|
|
118
|
+
ctx.fillStyle = 'rgba(255,255,255,0.7)';
|
|
119
|
+
ctx.fillText(b.token, bx + bw + 6, yy + 8);
|
|
120
|
+
});
|
|
121
|
+
ctx.restore();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* A deterministic forward "ghost" trajectory: integrate one probe under the class-A body forces,
|
|
125
|
+
* summing each (force, body) Δv per step and damping by friction — the same shape the real
|
|
126
|
+
* integrator uses, kept dependency-light. Pure and repeatable: same inputs → same path. This is the
|
|
127
|
+
* *prediction* overlay's data (an expected future path), not the live sim.
|
|
128
|
+
*/
|
|
129
|
+
export function ghostTrajectory(forces, tokens, bodies, start, opts = {}) {
|
|
130
|
+
const steps = opts.steps ?? 60;
|
|
131
|
+
const friction = opts.friction ?? FRICTION;
|
|
132
|
+
const scale = opts.forceScale ?? 1;
|
|
133
|
+
const charge = opts.charge ?? 0;
|
|
134
|
+
let x = start.x;
|
|
135
|
+
let y = start.y;
|
|
136
|
+
let vx = start.vx;
|
|
137
|
+
let vy = start.vy;
|
|
138
|
+
const path = [{ x, y }];
|
|
139
|
+
for (let i = 0; i < steps; i++) {
|
|
140
|
+
let ax = 0;
|
|
141
|
+
let ay = 0;
|
|
142
|
+
const probe = { vx, vy, charge, m: 1, heat: 0 };
|
|
143
|
+
for (const t of tokens) {
|
|
144
|
+
const f = forces[t];
|
|
145
|
+
if (!f)
|
|
146
|
+
continue;
|
|
147
|
+
for (const b of bodies) {
|
|
148
|
+
const v = forceVectorAt(f, b, x, y, probe);
|
|
149
|
+
ax += v.x;
|
|
150
|
+
ay += v.y;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
vx = (vx + ax * scale) * friction;
|
|
154
|
+
vy = (vy + ay * scale) * friction;
|
|
155
|
+
x += vx;
|
|
156
|
+
y += vy;
|
|
157
|
+
path.push({ x, y });
|
|
158
|
+
}
|
|
159
|
+
return path;
|
|
160
|
+
}
|
|
161
|
+
/** Draw a ghost trajectory as a dashed path that fades toward the predicted future. */
|
|
162
|
+
export function drawPrediction(ctx, points, opts = {}) {
|
|
163
|
+
if (points.length < 2)
|
|
164
|
+
return;
|
|
165
|
+
const color = opts.color ?? '255,255,255';
|
|
166
|
+
ctx.save();
|
|
167
|
+
ctx.setLineDash([3, 4]);
|
|
168
|
+
ctx.lineWidth = 1.5;
|
|
169
|
+
for (let i = 1; i < points.length; i++) {
|
|
170
|
+
const a = points[i - 1];
|
|
171
|
+
const b = points[i];
|
|
172
|
+
const alpha = 0.6 * (1 - i / points.length);
|
|
173
|
+
ctx.strokeStyle = `rgba(${color},${alpha.toFixed(3)})`;
|
|
174
|
+
ctx.beginPath();
|
|
175
|
+
ctx.moveTo(a.x, a.y);
|
|
176
|
+
ctx.lineTo(b.x, b.y);
|
|
177
|
+
ctx.stroke();
|
|
178
|
+
}
|
|
179
|
+
ctx.restore();
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=modes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.js","sourceRoot":"","sources":["../../src/diagnostics/modes.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,aAAa,EAA2B,MAAM,aAAa,CAAC;AAKrE,SAAS,KAAK,CAAC,GAAQ,EAAE,CAAS,EAAE,CAAS,EAAE,EAAU,EAAE,EAAU,EAAE,IAAI,GAAG,CAAC;IAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/B,IAAI,GAAG,GAAG,KAAK;QAAE,OAAO;IACxB,GAAG,CAAC,SAAS,EAAE,CAAC;IAChB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjB,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACjF,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACjF,GAAG,CAAC,MAAM,EAAE,CAAC;AACf,CAAC;AAkBD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoC,EAAE,KAAiB;IACnF,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,SAAS;QAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,YAAY,CAC1B,GAAQ,EACR,MAAoC,EACpC,KAAiB,EACjB,OAAoE,EAAE;IAEtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;IACpC,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;QACrC,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QAChF,GAAG,CAAC,SAAS,GAAG,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC5C,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3B,GAAG,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IACD,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC;AAkBD,MAAM,GAAG,GAAG,CAAC,CAAkB,EAAU,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3H,yFAAyF;AACzF,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,IAAI,GAAmB,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,CAAqB,EAAE,EAAE;QACnD,IAAI,CAAC,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC;IACF,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACzC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC;IACnH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,GAAQ,EAAE,IAAuB,EAAE,OAAmD,EAAE;IACpH,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC;IAChC,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC1C,GAAG,CAAC,SAAS,GAAG,qBAAqB,CAAC;IACtC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC9B,GAAG,CAAC,SAAS,GAAG,wBAAwB,CAAC;QACzC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;QAC1B,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;QACxB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC;AAWD,iGAAiG;AACjG,MAAM,UAAU,aAAa,CAAC,QAAuC;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,GAAG,KAAK,EAAE,CAAC,CAAC;SACvF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,aAAa,CAC3B,GAAQ,EACR,QAAuC,EACvC,MAAU,EACV,OAAmE,EAAE;IAErE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAC9B,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,gCAAgC;IAChC,GAAG,CAAC,WAAW,GAAG,uBAAuB,CAAC;IAC1C,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1F,cAAc;IACd,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;IAC7B,GAAG,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC1C,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;QACvB,GAAG,CAAC,SAAS,GAAG,uBAAuB,CAAC;QACxC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;QAC1B,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzC,GAAG,CAAC,SAAS,GAAG,uBAAuB,CAAC;QACxC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC;AAcD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAqB,EACrB,MAAyB,EACzB,MAAuB,EACvB,KAAuD,EACvD,OAAqB,EAAE;IAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAChB,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAChB,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IAClB,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IAClB,MAAM,IAAI,GAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC3C,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBACV,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YACZ,CAAC;QACH,CAAC;QACD,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;QAClC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;QAClC,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,IAAI,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,cAAc,CAAC,GAAQ,EAAE,MAAqB,EAAE,OAA2B,EAAE;IAC3F,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC;IAC1C,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxB,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;QACzB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QACrB,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5C,GAAG,CAAC,WAAW,GAAG,QAAQ,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACvD,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,GAAG,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IACD,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Potential & scalar-field diagnostics (visualization-methods-taxonomy §6). The scalar potential a
|
|
3
|
+
* body radiates (`Φ = -s / sqrt(d² + ε²)`), and a generic grid sampler that turns any scalar field
|
|
4
|
+
* into a value grid for contour / potential / heatmap rendering. Pure; reads no live state.
|
|
5
|
+
*/
|
|
6
|
+
import type { Body } from '../core/types.ts';
|
|
7
|
+
/**
|
|
8
|
+
* The scalar potential of a body at a world point. `gravity` is an attractive well (Φ < 0, deeper
|
|
9
|
+
* toward the mass); `charge` is signed by polarity. `s` defaults to the body's `M`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function potentialAt(b: Body, x: number, y: number, kind?: 'gravity' | 'charge'): number;
|
|
12
|
+
/** The summed potential of many bodies at a point. */
|
|
13
|
+
export declare function netPotentialAt(bodies: readonly Body[], x: number, y: number, kind?: 'gravity' | 'charge'): number;
|
|
14
|
+
export interface ScalarGridData {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
/** cell size in px. */
|
|
18
|
+
resolution: number;
|
|
19
|
+
cols: number;
|
|
20
|
+
rows: number;
|
|
21
|
+
values: Float32Array;
|
|
22
|
+
min: number;
|
|
23
|
+
max: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sample any scalar field `f(x, y)` onto a grid — the data a contour/potential layer renders from
|
|
27
|
+
* (e.g. marching squares over `values`). Pure.
|
|
28
|
+
*/
|
|
29
|
+
export declare function sampleScalarGrid(f: (x: number, y: number) => number, width: number, height: number, resolution?: number): ScalarGridData;
|
|
30
|
+
//# sourceMappingURL=potential.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"potential.d.ts","sourceRoot":"","sources":["../../src/diagnostics/potential.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAI7C;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,GAAG,QAAoB,GAAG,MAAM,CAOzG;AAED,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,GAAG,QAAoB,GAAG,MAAM,CAI5H;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,EACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,SAAK,GACd,cAAc,CAehB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const EPS = 6; // softening, matches the engine's Plummer-style core
|
|
2
|
+
/**
|
|
3
|
+
* The scalar potential of a body at a world point. `gravity` is an attractive well (Φ < 0, deeper
|
|
4
|
+
* toward the mass); `charge` is signed by polarity. `s` defaults to the body's `M`.
|
|
5
|
+
*/
|
|
6
|
+
export function potentialAt(b, x, y, kind = 'gravity') {
|
|
7
|
+
const dx = x - b.cx;
|
|
8
|
+
const dy = y - b.cy;
|
|
9
|
+
const d = Math.sqrt(dx * dx + dy * dy + EPS * EPS);
|
|
10
|
+
const s = b.M || b.strength || 1;
|
|
11
|
+
const sign = kind === 'charge' ? (b.spin < 0 ? -1 : 1) : -1; // gravity always attractive
|
|
12
|
+
return (sign * s) / d;
|
|
13
|
+
}
|
|
14
|
+
/** The summed potential of many bodies at a point. */
|
|
15
|
+
export function netPotentialAt(bodies, x, y, kind = 'gravity') {
|
|
16
|
+
let phi = 0;
|
|
17
|
+
for (const b of bodies)
|
|
18
|
+
phi += potentialAt(b, x, y, kind);
|
|
19
|
+
return phi;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sample any scalar field `f(x, y)` onto a grid — the data a contour/potential layer renders from
|
|
23
|
+
* (e.g. marching squares over `values`). Pure.
|
|
24
|
+
*/
|
|
25
|
+
export function sampleScalarGrid(f, width, height, resolution = 16) {
|
|
26
|
+
const cols = Math.max(1, Math.ceil(width / resolution));
|
|
27
|
+
const rows = Math.max(1, Math.ceil(height / resolution));
|
|
28
|
+
const values = new Float32Array(cols * rows);
|
|
29
|
+
let min = Infinity;
|
|
30
|
+
let max = -Infinity;
|
|
31
|
+
for (let r = 0; r < rows; r++) {
|
|
32
|
+
for (let c = 0; c < cols; c++) {
|
|
33
|
+
const v = f(c * resolution, r * resolution);
|
|
34
|
+
values[r * cols + c] = v;
|
|
35
|
+
if (v < min)
|
|
36
|
+
min = v;
|
|
37
|
+
if (v > max)
|
|
38
|
+
max = v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { width, height, resolution, cols, rows, values, min: min === Infinity ? 0 : min, max: max === -Infinity ? 0 : max };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=potential.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"potential.js","sourceRoot":"","sources":["../../src/diagnostics/potential.ts"],"names":[],"mappings":"AAOA,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,qDAAqD;AAEpE;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,CAAO,EAAE,CAAS,EAAE,CAAS,EAAE,OAA6B,SAAS;IAC/F,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;IACpB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B;IACzF,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,cAAc,CAAC,MAAuB,EAAE,CAAS,EAAE,CAAS,EAAE,OAA6B,SAAS;IAClH,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,GAAG,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,CAAmC,EACnC,KAAa,EACb,MAAc,EACd,UAAU,GAAG,EAAE;IAEf,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,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC;YAC5C,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,GAAG;gBAAE,GAAG,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,GAAG,GAAG;gBAAE,GAAG,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAC9H,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probe diagnostics (visualization-methods-taxonomy §3/§4, §11). Probes are instruments fired into
|
|
3
|
+
* the field to read it: a force's *vector* at a point (Δv on a probe — `field magnitude != force
|
|
4
|
+
* magnitude`), and the per-token *causality* breakdown of why motion happened. Works for body→
|
|
5
|
+
* particle (class-A) forces; class-B/C/D forces need neighbours/grids the conformance runner wires.
|
|
6
|
+
*/
|
|
7
|
+
import type { Body, Force, ForceRegistry, Vec2 } from '../core/types.ts';
|
|
8
|
+
/** An instrument particle. */
|
|
9
|
+
export interface Probe {
|
|
10
|
+
vx: number;
|
|
11
|
+
vy: number;
|
|
12
|
+
charge: number;
|
|
13
|
+
m: number;
|
|
14
|
+
heat: number;
|
|
15
|
+
}
|
|
16
|
+
/** The standard probe set (viz-taxonomy §4). */
|
|
17
|
+
export declare const PROBE_PRESETS: Readonly<Record<string, Probe>>;
|
|
18
|
+
/**
|
|
19
|
+
* The force vector a class-A force exerts on a probe at (x, y): the Δv from a single `apply()`. A
|
|
20
|
+
* still or neutral probe correctly reads zero for velocity- or charge-dependent forces (magnetism,
|
|
21
|
+
* charge) — that's the point of probes.
|
|
22
|
+
*/
|
|
23
|
+
export declare function forceVectorAt(force: Force, b: Body, x: number, y: number, probe?: Probe): Vec2;
|
|
24
|
+
export interface CausalContribution {
|
|
25
|
+
token: string;
|
|
26
|
+
dvx: number;
|
|
27
|
+
dvy: number;
|
|
28
|
+
}
|
|
29
|
+
/** Decompose the motion at (x, y) into per-token contributions — the causality overlay's data. */
|
|
30
|
+
export declare function causalityAt(registry: ForceRegistry, tokens: readonly string[], b: Body, x: number, y: number, probe?: Probe): CausalContribution[];
|
|
31
|
+
//# sourceMappingURL=probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/diagnostics/probes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAiB,KAAK,EAAE,aAAa,EAAa,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEnG,8BAA8B;AAC9B,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gDAAgD;AAChD,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAQzD,CAAC;AAgBF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,KAA8B,GAAG,IAAI,CAkBtH;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CACzB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,CAAC,EAAE,IAAI,EACP,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,GAAE,KAA8B,GACpC,kBAAkB,EAAE,CAStB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** The standard probe set (viz-taxonomy §4). */
|
|
2
|
+
export const PROBE_PRESETS = {
|
|
3
|
+
neutral: { vx: 0, vy: 0, charge: 0, m: 1, heat: 0 },
|
|
4
|
+
positive: { vx: 1, vy: 0, charge: 1, m: 1, heat: 0 },
|
|
5
|
+
negative: { vx: 1, vy: 0, charge: -1, m: 1, heat: 0 },
|
|
6
|
+
still: { vx: 0, vy: 0, charge: 1, m: 1, heat: 0 },
|
|
7
|
+
fast: { vx: 6, vy: 0, charge: 1, m: 1, heat: 0 },
|
|
8
|
+
hot: { vx: 0, vy: 0, charge: 0, m: 1, heat: 1 },
|
|
9
|
+
massive: { vx: 0, vy: 0, charge: 0, m: 6, heat: 0 },
|
|
10
|
+
};
|
|
11
|
+
function probeEnv(b, x, y) {
|
|
12
|
+
const dx = b.cx - x;
|
|
13
|
+
const dy = b.cy - y;
|
|
14
|
+
return {
|
|
15
|
+
dx,
|
|
16
|
+
dy,
|
|
17
|
+
dist: Math.max(Math.hypot(dx, dy), 1),
|
|
18
|
+
form: {},
|
|
19
|
+
c: 12,
|
|
20
|
+
G: 1,
|
|
21
|
+
t: 0,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The force vector a class-A force exerts on a probe at (x, y): the Δv from a single `apply()`. A
|
|
26
|
+
* still or neutral probe correctly reads zero for velocity- or charge-dependent forces (magnetism,
|
|
27
|
+
* charge) — that's the point of probes.
|
|
28
|
+
*/
|
|
29
|
+
export function forceVectorAt(force, b, x, y, probe = PROBE_PRESETS.neutral) {
|
|
30
|
+
const p = {
|
|
31
|
+
x,
|
|
32
|
+
y,
|
|
33
|
+
vx: probe.vx,
|
|
34
|
+
vy: probe.vy,
|
|
35
|
+
charge: probe.charge,
|
|
36
|
+
m: probe.m,
|
|
37
|
+
heat: probe.heat,
|
|
38
|
+
size: 1,
|
|
39
|
+
cap: null,
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
force.apply(b, p, probeEnv(b, x, y));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { x: 0, y: 0 };
|
|
46
|
+
}
|
|
47
|
+
return { x: p.vx - probe.vx, y: p.vy - probe.vy };
|
|
48
|
+
}
|
|
49
|
+
/** Decompose the motion at (x, y) into per-token contributions — the causality overlay's data. */
|
|
50
|
+
export function causalityAt(registry, tokens, b, x, y, probe = PROBE_PRESETS.neutral) {
|
|
51
|
+
const out = [];
|
|
52
|
+
for (const t of tokens) {
|
|
53
|
+
const f = registry[t];
|
|
54
|
+
if (!f)
|
|
55
|
+
continue;
|
|
56
|
+
const v = forceVectorAt(f, b, x, y, probe);
|
|
57
|
+
out.push({ token: t, dvx: v.x, dvy: v.y });
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.js","sourceRoot":"","sources":["../../src/diagnostics/probes.ts"],"names":[],"mappings":"AAiBA,gDAAgD;AAChD,MAAM,CAAC,MAAM,aAAa,GAAoC;IAC5D,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACnD,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACpD,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACrD,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IACjD,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IAChD,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IAC/C,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;CACpD,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAO,EAAE,CAAS,EAAE,CAAS;IAC7C,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpB,OAAO;QACL,EAAE;QACF,EAAE;QACF,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,EAAE,EAAe;QACrB,CAAC,EAAE,EAAE;QACL,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;KACa,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,CAAO,EAAE,CAAS,EAAE,CAAS,EAAE,QAAe,aAAa,CAAC,OAAQ;IAC9G,MAAM,CAAC,GAAG;QACR,CAAC;QACD,CAAC;QACD,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,CAAC,EAAE,KAAK,CAAC,CAAC;QACV,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,CAAC;QACP,GAAG,EAAE,IAAI;KACa,CAAC;IACzB,IAAI,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC;AACpD,CAAC;AAQD,kGAAkG;AAClG,MAAM,UAAU,WAAW,CACzB,QAAuB,EACvB,MAAyB,EACzB,CAAO,EACP,CAAS,EACT,CAAS,EACT,QAAe,aAAa,CAAC,OAAQ;IAErC,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostic overlay rendering (visualization-methods-taxonomy §3, §6, §7, §11). Draws the pure
|
|
3
|
+
* diagnostic data (force vectors, contours, potential, energy) onto a Canvas 2D context. The
|
|
4
|
+
* marching-squares contour extraction is pure and testable; the `draw*` helpers are thin context
|
|
5
|
+
* calls. These reveal state — they read, never mutate physics.
|
|
6
|
+
*/
|
|
7
|
+
import type { Body, Particle, Force } from '../core/types.ts';
|
|
8
|
+
import type { ScalarGridData } from './potential.ts';
|
|
9
|
+
import { sampleScalarGrid } from './potential.ts';
|
|
10
|
+
import { type Probe } from './probes.ts';
|
|
11
|
+
import type { EnergyReport } from './energy.ts';
|
|
12
|
+
export interface Segment {
|
|
13
|
+
x1: number;
|
|
14
|
+
y1: number;
|
|
15
|
+
x2: number;
|
|
16
|
+
y2: number;
|
|
17
|
+
}
|
|
18
|
+
/** All isoline segments for a set of levels (evenly spaced if `levels` is a count). Pure. */
|
|
19
|
+
export declare function contourSegments(grid: ScalarGridData, levels?: number[] | number): Segment[];
|
|
20
|
+
type Ctx = CanvasRenderingContext2D;
|
|
21
|
+
/** Draw contour isolines of a scalar grid. */
|
|
22
|
+
export declare function drawContours(ctx: Ctx, grid: ScalarGridData, opts?: {
|
|
23
|
+
levels?: number;
|
|
24
|
+
color?: string;
|
|
25
|
+
}): void;
|
|
26
|
+
/** Draw a body's potential field as soft shaded wells (normalized grid → alpha). */
|
|
27
|
+
export declare function drawPotential(ctx: Ctx, grid: ScalarGridData, opts?: {
|
|
28
|
+
color?: string;
|
|
29
|
+
}): void;
|
|
30
|
+
/** Draw a force's vector field by probing it on a grid (viz §3 — uses a probe, §4). */
|
|
31
|
+
export declare function drawForceVectors(ctx: Ctx, force: Force, body: Body, W: number, H: number, opts?: {
|
|
32
|
+
spacing?: number;
|
|
33
|
+
probe?: Probe;
|
|
34
|
+
scale?: number;
|
|
35
|
+
color?: string;
|
|
36
|
+
}): void;
|
|
37
|
+
/** Draw per-particle velocity vectors. */
|
|
38
|
+
export declare function drawVelocityVectors(ctx: Ctx, particles: readonly Particle[], opts?: {
|
|
39
|
+
scale?: number;
|
|
40
|
+
color?: string;
|
|
41
|
+
}): void;
|
|
42
|
+
/** Draw a compact kinetic/thermal/total energy bar. */
|
|
43
|
+
export declare function drawEnergyBar(ctx: Ctx, report: EnergyReport, opts?: {
|
|
44
|
+
x?: number;
|
|
45
|
+
y?: number;
|
|
46
|
+
w?: number;
|
|
47
|
+
}): void;
|
|
48
|
+
export { sampleScalarGrid };
|
|
49
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/diagnostics/render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAiB,KAAK,KAAK,EAAiB,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAgCD,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,GAAE,MAAM,EAAE,GAAG,MAAU,GAAG,OAAO,EAAE,CAM9F;AAED,KAAK,GAAG,GAAG,wBAAwB,CAAC;AAepC,8CAA8C;AAC9C,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAWjH;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAWjG;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,EACV,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7E,IAAI,CAaN;AAED,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,QAAQ,EAAE,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAOjI;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAqBrH;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { sampleScalarGrid } from "./potential.js";
|
|
2
|
+
import { forceVectorAt, PROBE_PRESETS } from "./probes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Marching-squares isolines for one level over a scalar grid → line segments in pixel space. Pure.
|
|
5
|
+
* (Saddle cells are split into two segments by edge order — good enough for diagnostic contours.)
|
|
6
|
+
*/
|
|
7
|
+
function levelSegments(grid, level) {
|
|
8
|
+
const { cols, rows, resolution: res, values } = grid;
|
|
9
|
+
const at = (c, r) => values[r * cols + c] ?? 0;
|
|
10
|
+
const segs = [];
|
|
11
|
+
for (let r = 0; r < rows - 1; r++) {
|
|
12
|
+
for (let c = 0; c < cols - 1; c++) {
|
|
13
|
+
const tl = at(c, r);
|
|
14
|
+
const tr = at(c + 1, r);
|
|
15
|
+
const bl = at(c, r + 1);
|
|
16
|
+
const br = at(c + 1, r + 1);
|
|
17
|
+
const pts = [];
|
|
18
|
+
const cross = (a, b) => (level - a) / (b - a);
|
|
19
|
+
if (tl < level !== tr < level)
|
|
20
|
+
pts.push({ x: (c + cross(tl, tr)) * res, y: r * res }); // top
|
|
21
|
+
if (tr < level !== br < level)
|
|
22
|
+
pts.push({ x: (c + 1) * res, y: (r + cross(tr, br)) * res }); // right
|
|
23
|
+
if (bl < level !== br < level)
|
|
24
|
+
pts.push({ x: (c + cross(bl, br)) * res, y: (r + 1) * res }); // bottom
|
|
25
|
+
if (tl < level !== bl < level)
|
|
26
|
+
pts.push({ x: c * res, y: (r + cross(tl, bl)) * res }); // left
|
|
27
|
+
if (pts.length === 2)
|
|
28
|
+
segs.push({ x1: pts[0].x, y1: pts[0].y, x2: pts[1].x, y2: pts[1].y });
|
|
29
|
+
else if (pts.length === 4) {
|
|
30
|
+
segs.push({ x1: pts[0].x, y1: pts[0].y, x2: pts[1].x, y2: pts[1].y });
|
|
31
|
+
segs.push({ x1: pts[2].x, y1: pts[2].y, x2: pts[3].x, y2: pts[3].y });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return segs;
|
|
36
|
+
}
|
|
37
|
+
/** All isoline segments for a set of levels (evenly spaced if `levels` is a count). Pure. */
|
|
38
|
+
export function contourSegments(grid, levels = 8) {
|
|
39
|
+
const list = typeof levels === 'number'
|
|
40
|
+
? Array.from({ length: levels }, (_, i) => grid.min + ((i + 1) / (levels + 1)) * (grid.max - grid.min))
|
|
41
|
+
: levels;
|
|
42
|
+
return list.flatMap((l) => levelSegments(grid, l));
|
|
43
|
+
}
|
|
44
|
+
function arrow(ctx, x, y, dx, dy, head = 4) {
|
|
45
|
+
const len = Math.hypot(dx, dy);
|
|
46
|
+
if (len < 0.001)
|
|
47
|
+
return;
|
|
48
|
+
ctx.beginPath();
|
|
49
|
+
ctx.moveTo(x, y);
|
|
50
|
+
ctx.lineTo(x + dx, y + dy);
|
|
51
|
+
const a = Math.atan2(dy, dx);
|
|
52
|
+
ctx.lineTo(x + dx - head * Math.cos(a - 0.4), y + dy - head * Math.sin(a - 0.4));
|
|
53
|
+
ctx.moveTo(x + dx, y + dy);
|
|
54
|
+
ctx.lineTo(x + dx - head * Math.cos(a + 0.4), y + dy - head * Math.sin(a + 0.4));
|
|
55
|
+
ctx.stroke();
|
|
56
|
+
}
|
|
57
|
+
/** Draw contour isolines of a scalar grid. */
|
|
58
|
+
export function drawContours(ctx, grid, opts = {}) {
|
|
59
|
+
ctx.save();
|
|
60
|
+
ctx.strokeStyle = opts.color ?? 'rgba(77,163,255,0.5)';
|
|
61
|
+
ctx.lineWidth = 1;
|
|
62
|
+
for (const s of contourSegments(grid, opts.levels ?? 8)) {
|
|
63
|
+
ctx.beginPath();
|
|
64
|
+
ctx.moveTo(s.x1, s.y1);
|
|
65
|
+
ctx.lineTo(s.x2, s.y2);
|
|
66
|
+
ctx.stroke();
|
|
67
|
+
}
|
|
68
|
+
ctx.restore();
|
|
69
|
+
}
|
|
70
|
+
/** Draw a body's potential field as soft shaded wells (normalized grid → alpha). */
|
|
71
|
+
export function drawPotential(ctx, grid, opts = {}) {
|
|
72
|
+
const span = grid.max - grid.min || 1;
|
|
73
|
+
ctx.save();
|
|
74
|
+
for (let r = 0; r < grid.rows; r++) {
|
|
75
|
+
for (let c = 0; c < grid.cols; c++) {
|
|
76
|
+
const n = ((grid.values[r * grid.cols + c] ?? 0) - grid.min) / span;
|
|
77
|
+
ctx.fillStyle = (opts.color ?? 'rgba(77,163,255,A)').replace('A', (n * 0.5).toFixed(3));
|
|
78
|
+
ctx.fillRect(c * grid.resolution, r * grid.resolution, grid.resolution, grid.resolution);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
ctx.restore();
|
|
82
|
+
}
|
|
83
|
+
/** Draw a force's vector field by probing it on a grid (viz §3 — uses a probe, §4). */
|
|
84
|
+
export function drawForceVectors(ctx, force, body, W, H, opts = {}) {
|
|
85
|
+
const spacing = opts.spacing ?? 36;
|
|
86
|
+
const scale = opts.scale ?? 6;
|
|
87
|
+
ctx.save();
|
|
88
|
+
ctx.strokeStyle = opts.color ?? 'rgba(45,212,191,0.7)';
|
|
89
|
+
ctx.lineWidth = 1;
|
|
90
|
+
for (let y = spacing / 2; y < H; y += spacing) {
|
|
91
|
+
for (let x = spacing / 2; x < W; x += spacing) {
|
|
92
|
+
const v = forceVectorAt(force, body, x, y, opts.probe ?? PROBE_PRESETS.neutral);
|
|
93
|
+
arrow(ctx, x, y, v.x * scale, v.y * scale);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
ctx.restore();
|
|
97
|
+
}
|
|
98
|
+
/** Draw per-particle velocity vectors. */
|
|
99
|
+
export function drawVelocityVectors(ctx, particles, opts = {}) {
|
|
100
|
+
const scale = opts.scale ?? 3;
|
|
101
|
+
ctx.save();
|
|
102
|
+
ctx.strokeStyle = opts.color ?? 'rgba(255,255,255,0.5)';
|
|
103
|
+
ctx.lineWidth = 1;
|
|
104
|
+
for (const p of particles)
|
|
105
|
+
arrow(ctx, p.x, p.y, p.vx * scale, p.vy * scale);
|
|
106
|
+
ctx.restore();
|
|
107
|
+
}
|
|
108
|
+
/** Draw a compact kinetic/thermal/total energy bar. */
|
|
109
|
+
export function drawEnergyBar(ctx, report, opts = {}) {
|
|
110
|
+
const x = opts.x ?? 12;
|
|
111
|
+
const y = opts.y ?? 12;
|
|
112
|
+
const w = opts.w ?? 160;
|
|
113
|
+
const total = report.total || 1;
|
|
114
|
+
const rows = [
|
|
115
|
+
['K', report.kinetic / total, '#4da3ff'],
|
|
116
|
+
['T', report.thermal / total, '#f0883e'],
|
|
117
|
+
];
|
|
118
|
+
ctx.save();
|
|
119
|
+
ctx.font = '11px ui-monospace, monospace';
|
|
120
|
+
rows.forEach(([label, frac, color], i) => {
|
|
121
|
+
const yy = y + i * 16;
|
|
122
|
+
ctx.fillStyle = 'rgba(255,255,255,0.4)';
|
|
123
|
+
ctx.fillText(label, x, yy + 9);
|
|
124
|
+
ctx.fillStyle = 'rgba(255,255,255,0.1)';
|
|
125
|
+
ctx.fillRect(x + 16, yy, w, 10);
|
|
126
|
+
ctx.fillStyle = color;
|
|
127
|
+
ctx.fillRect(x + 16, yy, w * Math.min(1, frac), 10);
|
|
128
|
+
});
|
|
129
|
+
ctx.restore();
|
|
130
|
+
}
|
|
131
|
+
export { sampleScalarGrid };
|
|
132
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/diagnostics/render.ts"],"names":[],"mappings":"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"}
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field export serializers (visualization-methods-taxonomy §15). Turn a field into a portable
|
|
3
|
+
* artifact: an SVG of vector segments (field lines, contours, relationship overlays), or a PNG data
|
|
4
|
+
* URL of the canvas. Both are DOM-global-free — `segmentsToSvg` is pure, and `canvasToPng` calls the
|
|
5
|
+
* passed canvas's own `toDataURL`. The download helpers (which need `document`) live in
|
|
6
|
+
* `@fundamental-engine/platform` (`downloadUrl` / `downloadText` / `downloadCanvasPng`).
|
|
7
|
+
*/
|
|
8
|
+
import type { Segment } from './diagnostics/render.ts';
|
|
9
|
+
export interface SvgOptions {
|
|
10
|
+
stroke?: string;
|
|
11
|
+
strokeWidth?: number;
|
|
12
|
+
background?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Serialize line segments to a standalone SVG document. Pure — no DOM. */
|
|
15
|
+
export declare function segmentsToSvg(segments: readonly Segment[], width: number, height: number, opts?: SvgOptions): string;
|
|
16
|
+
/** A PNG data URL of a canvas (the rasterized field) — the canvas's own `toDataURL`, no globals. */
|
|
17
|
+
export declare function canvasToPng(canvas: HTMLCanvasElement): string;
|
|
18
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAIvD,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,UAAe,GAAG,MAAM,CAWxH;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAE7D"}
|
package/dist/export.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const round = (n) => Math.round(n * 100) / 100;
|
|
2
|
+
/** Serialize line segments to a standalone SVG document. Pure — no DOM. */
|
|
3
|
+
export function segmentsToSvg(segments, width, height, opts = {}) {
|
|
4
|
+
const bg = opts.background ? `<rect width="${width}" height="${height}" fill="${opts.background}"/>` : '';
|
|
5
|
+
const lines = segments
|
|
6
|
+
.map((s) => `<line x1="${round(s.x1)}" y1="${round(s.y1)}" x2="${round(s.x2)}" y2="${round(s.y2)}"/>`)
|
|
7
|
+
.join('');
|
|
8
|
+
return (`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">` +
|
|
9
|
+
bg +
|
|
10
|
+
`<g stroke="${opts.stroke ?? '#4da3ff'}" stroke-width="${opts.strokeWidth ?? 1}" fill="none">${lines}</g>` +
|
|
11
|
+
`</svg>`);
|
|
12
|
+
}
|
|
13
|
+
/** A PNG data URL of a canvas (the rasterized field) — the canvas's own `toDataURL`, no globals. */
|
|
14
|
+
export function canvasToPng(canvas) {
|
|
15
|
+
return canvas.toDataURL('image/png');
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AASA,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAQ/D,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,QAA4B,EAAE,KAAa,EAAE,MAAc,EAAE,OAAmB,EAAE;IAC9G,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,KAAK,aAAa,MAAM,WAAW,IAAI,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,MAAM,KAAK,GAAG,QAAQ;SACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;SACrG,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,CACL,kDAAkD,KAAK,aAAa,MAAM,kBAAkB,KAAK,IAAI,MAAM,IAAI;QAC/G,EAAE;QACF,cAAc,IAAI,CAAC,MAAM,IAAI,SAAS,mBAAmB,IAAI,CAAC,WAAW,IAAI,CAAC,iBAAiB,KAAK,MAAM;QAC1G,QAAQ,CACT,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,MAAyB;IACnD,OAAO,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC"}
|