Spaces:
Running
Running
deploy(hf): sync szl-holdings/a11oy@main derived COPY set
Browse filesReusable Dockerfile-COPY-derived deploy from szl-holdings/a11oy main.
Files: 930 Pruned: 0
Derived from Dockerfile COPY sources (NO hand-maintained allowlist).
Signed-off-by: SZL Holdings <noreply@szlholdings.ai>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
static/3d/surfaces/counter-uas.js
CHANGED
|
@@ -40,9 +40,21 @@ const EP = {
|
|
| 40 |
cued: "/api/a11oy/v1/counter-uas/cued-tracks",
|
| 41 |
airpicture: "/api/a11oy/v1/counter-uas/air-picture",
|
| 42 |
gates: "/api/a11oy/v1/counter-uas/gates",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
dronesDb: "/static/3d/surfaces/data/drones_db.json",
|
| 44 |
};
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
// Globe radius (world units) + altitude scale (alt_m -> world units above surface).
|
| 47 |
const R = 3.0;
|
| 48 |
const ALT_SCALE = 1.0 / 18000; // ~18 km ceiling maps to ~+1 globe radius of lift
|
|
@@ -64,7 +76,7 @@ let _disposables = [];
|
|
| 64 |
// Live caches (honest: empty until a real fetch lands).
|
| 65 |
let _state = {
|
| 66 |
evaluate: null, telemetry: null, cued: null, airpicture: null, gates: null, db: null,
|
| 67 |
-
meta: {}, dbCount: 0,
|
| 68 |
};
|
| 69 |
|
| 70 |
// ── geo helpers ────────────────────────────────────────────────────────────
|
|
@@ -221,6 +233,7 @@ let _dsseLock = null; // DSSE signature lock animation node
|
|
| 221 |
let _fingerprintCallout = null;
|
| 222 |
let _restrictedZones = null; // restricted-airspace SDF volumes
|
| 223 |
let _ridPanel = null, _gatesPanel = null, _verdictPanel = null, _posturePanel = null, _fpPanel = null;
|
|
|
|
| 224 |
let _beamPhase = 0, _lockPhase = 0;
|
| 225 |
|
| 226 |
function rebuildTracks() {
|
|
@@ -377,6 +390,10 @@ function buildOverlay() {
|
|
| 377 |
_verdictPanel = card("Λ-Gate Verdict · senses-and-evidences");
|
| 378 |
_overlay.appendChild(_verdictPanel);
|
| 379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
// D15: DSSE signature panel (real ECDSA-P256)
|
| 381 |
_fpPanel = null;
|
| 382 |
_ridPanel = card("Remote-ID / RID Validator");
|
|
@@ -424,6 +441,52 @@ function renderVerdict() {
|
|
| 424 |
}
|
| 425 |
}
|
| 426 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 427 |
function renderRid() {
|
| 428 |
clearCard(_ridPanel);
|
| 429 |
const tele = _state.telemetry, cued = _state.cued;
|
|
@@ -517,13 +580,13 @@ function mount(ctx) {
|
|
| 517 |
|
| 518 |
// floating honesty billboard
|
| 519 |
try {
|
| 520 |
-
const bb = ctx.label.billboard(THREE, "
|
| 521 |
_group.add(bb);
|
| 522 |
_track(() => { if (bb.material.map) bb.material.map.dispose(); bb.material.dispose(); });
|
| 523 |
} catch (_) {}
|
| 524 |
|
| 525 |
const badge = buildOverlay();
|
| 526 |
-
renderPosture(); renderVerdict(); renderRid(); renderGates(); renderFingerprint();
|
| 527 |
|
| 528 |
// per-frame animation (rotate the estate slowly + run demo updaters). The shell's
|
| 529 |
// Stage has no offFrame(), so we self-guard: once unmounted, _group is null and the
|
|
@@ -561,6 +624,10 @@ function mount(ctx) {
|
|
| 561 |
_handles.push(ctx.live.poll(EP.gates, 30000, (json) => {
|
| 562 |
_state.gates = json; renderGates();
|
| 563 |
}));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
// 53-fingerprint DB (static vendored; fetched once)
|
| 565 |
fetch(EP.dronesDb, { headers: { accept: "application/json" } })
|
| 566 |
.then((r) => r.ok ? r.json() : null)
|
|
@@ -581,7 +648,8 @@ function unmount() {
|
|
| 581 |
try { if (_group && _stage) _stage.scene.remove(_group); } catch (_) {}
|
| 582 |
_overlay = _show = null; _group = null; _globe = null; _trackGroup = null;
|
| 583 |
_verdictBeam = null; _dsseLock = null; _stage = null; THREE = null; _ctx = null;
|
| 584 |
-
|
|
|
|
| 585 |
}
|
| 586 |
|
| 587 |
-
export default { id: ID, title: TITLE, endpoints: [EP.evaluate, EP.telemetry, EP.cued, EP.airpicture, EP.gates], mount, unmount };
|
|
|
|
| 40 |
cued: "/api/a11oy/v1/counter-uas/cued-tracks",
|
| 41 |
airpicture: "/api/a11oy/v1/counter-uas/air-picture",
|
| 42 |
gates: "/api/a11oy/v1/counter-uas/gates",
|
| 43 |
+
// Governed in-request MODELED compute: evaluates the C-UAS formula stack + the
|
| 44 |
+
// Λ-ROE advisory gate (Conjecture 1, gray never green; effector SIMULATED). This
|
| 45 |
+
// is the surface's honest runtime-default label source (szl_cuas_formulas.py).
|
| 46 |
+
compute: "/api/a11oy/v1/counter-uas/compute",
|
| 47 |
dronesDb: "/static/3d/surfaces/data/drones_db.json",
|
| 48 |
};
|
| 49 |
|
| 50 |
+
// Honest surface state. The headline label is READ VERBATIM from the live compute
|
| 51 |
+
// endpoint and defaults to MODELED (the governed compute is a deterministic model of
|
| 52 |
+
// the C-UAS formulas — no live sensor/effector on the demo floor). Λ-ROE is Conjecture
|
| 53 |
+
// 1 and renders GRAY, never green. Never fabricated; never upgraded past what the
|
| 54 |
+
// endpoint declares.
|
| 55 |
+
const S = { label: null, compute: null, roe: null };
|
| 56 |
+
const LAMBDA_GRAY = 0x9aa7b0; // Λ = Conjecture 1 → GRAY (never green). Doctrine v11.
|
| 57 |
+
|
| 58 |
// Globe radius (world units) + altitude scale (alt_m -> world units above surface).
|
| 59 |
const R = 3.0;
|
| 60 |
const ALT_SCALE = 1.0 / 18000; // ~18 km ceiling maps to ~+1 globe radius of lift
|
|
|
|
| 76 |
// Live caches (honest: empty until a real fetch lands).
|
| 77 |
let _state = {
|
| 78 |
evaluate: null, telemetry: null, cued: null, airpicture: null, gates: null, db: null,
|
| 79 |
+
compute: null, meta: {}, dbCount: 0,
|
| 80 |
};
|
| 81 |
|
| 82 |
// ── geo helpers ────────────────────────────────────────────────────────────
|
|
|
|
| 233 |
let _fingerprintCallout = null;
|
| 234 |
let _restrictedZones = null; // restricted-airspace SDF volumes
|
| 235 |
let _ridPanel = null, _gatesPanel = null, _verdictPanel = null, _posturePanel = null, _fpPanel = null;
|
| 236 |
+
let _computePanel = null; // governed MODELED compute + Λ-ROE advisory gate (gray)
|
| 237 |
let _beamPhase = 0, _lockPhase = 0;
|
| 238 |
|
| 239 |
function rebuildTracks() {
|
|
|
|
| 390 |
_verdictPanel = card("Λ-Gate Verdict · senses-and-evidences");
|
| 391 |
_overlay.appendChild(_verdictPanel);
|
| 392 |
|
| 393 |
+
// Governed MODELED compute + Λ-ROE advisory gate (Conjecture 1, gray never green).
|
| 394 |
+
_computePanel = card("Governed compute · Λ-ROE (Conjecture 1)");
|
| 395 |
+
_overlay.appendChild(_computePanel);
|
| 396 |
+
|
| 397 |
// D15: DSSE signature panel (real ECDSA-P256)
|
| 398 |
_fpPanel = null;
|
| 399 |
_ridPanel = card("Remote-ID / RID Validator");
|
|
|
|
| 441 |
}
|
| 442 |
}
|
| 443 |
|
| 444 |
+
// Governed MODELED compute + Λ-ROE advisory gate. The headline label is read VERBATIM
|
| 445 |
+
// from the endpoint (defaults MODELED). Λ-ROE is Conjecture 1 — its chip is ALWAYS the
|
| 446 |
+
// gray Conjecture token, NEVER green; the effector is SIMULATED, human-on-loop. We honor
|
| 447 |
+
// the endpoint's explicit render contract (render_green must be false).
|
| 448 |
+
function renderCompute() {
|
| 449 |
+
if (!_computePanel) return;
|
| 450 |
+
clearCard(_computePanel);
|
| 451 |
+
const j = _state.compute;
|
| 452 |
+
// Runtime-default honesty label, read verbatim from the live compute endpoint. This
|
| 453 |
+
// is the census single-source-of-truth (a11oy_frontier_page._derive_label): the
|
| 454 |
+
// headline label is `(endpoint.label || "MODELED")`, never upgraded past what the
|
| 455 |
+
// endpoint declares. Λ-ROE stays Conjecture 1 (gray) regardless.
|
| 456 |
+
const jl = j && j.label;
|
| 457 |
+
S.label = (jl || "MODELED").toUpperCase();
|
| 458 |
+
if (!j || j.degraded || j.ok === false) {
|
| 459 |
+
_computePanel.appendChild(row("compute", j && j.degraded ? "DEGRADED" : "—", S.label));
|
| 460 |
+
// Λ-ROE remains Conjecture 1 (gray) even when the compute is unavailable.
|
| 461 |
+
_computePanel.appendChild(row("Λ-ROE", "Conjecture 1 · advisory", "MODELED"));
|
| 462 |
+
return;
|
| 463 |
+
}
|
| 464 |
+
const roe = j.lambda_roe_gate || {};
|
| 465 |
+
S.roe = roe;
|
| 466 |
+
_computePanel.appendChild(row("data", String(j.data_label || "MODELED"), S.label));
|
| 467 |
+
const eng = (j.results && j.results.engageability) || {};
|
| 468 |
+
if (eng.feasible != null) {
|
| 469 |
+
_computePanel.appendChild(row("engageability", eng.feasible ? "feasible" : "infeasible",
|
| 470 |
+
eng.effector === "SIMULATED" ? "SIMULATED" : "MODELED"));
|
| 471 |
+
}
|
| 472 |
+
const cons = (j.results && j.results.consensus) || {};
|
| 473 |
+
if (cons.lambda2 != null) _computePanel.appendChild(row("consensus λ₂", String(cons.lambda2)));
|
| 474 |
+
// Λ-ROE gate row — ALWAYS the gray Conjecture chip, NEVER green. Doctrine v11.
|
| 475 |
+
const posture = roe.posture || "advisory";
|
| 476 |
+
const roeRow = row("Λ-ROE", String(posture), "MODELED");
|
| 477 |
+
// Force the Λ posture pill gray (Conjecture 1) regardless of sub-gate pass state.
|
| 478 |
+
const pill = document.createElement("span");
|
| 479 |
+
pill.textContent = "Conjecture 1 · gray";
|
| 480 |
+
pill.style.cssText = "margin-left:6px;padding:1px 6px;border-radius:6px;font:10px ui-monospace,monospace;" +
|
| 481 |
+
"color:#0d1117;background:#9aa7b0;"; // gray (#9aa7b0) — NEVER green
|
| 482 |
+
roeRow.appendChild(pill);
|
| 483 |
+
_computePanel.appendChild(roeRow);
|
| 484 |
+
_computePanel.appendChild(row("authorization", String(roe.authorization || "advisory") +
|
| 485 |
+
" · " + String(roe.control_mode || "human_on_loop")));
|
| 486 |
+
_computePanel.appendChild(row("effector", String(roe.effector || "SIMULATED"), "SIMULATED"));
|
| 487 |
+
_computePanel.appendChild(row("autonomous engage", roe.autonomous_engage ? "YES" : "NO — never"));
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
function renderRid() {
|
| 491 |
clearCard(_ridPanel);
|
| 492 |
const tele = _state.telemetry, cued = _state.cued;
|
|
|
|
| 580 |
|
| 581 |
// floating honesty billboard
|
| 582 |
try {
|
| 583 |
+
const bb = ctx.label.billboard(THREE, "MODELED", { text: "senses · evidences · NOT defeats · Λ-ROE Conjecture 1", scale: 0.42, position: [0, R + 2.0, 0] });
|
| 584 |
_group.add(bb);
|
| 585 |
_track(() => { if (bb.material.map) bb.material.map.dispose(); bb.material.dispose(); });
|
| 586 |
} catch (_) {}
|
| 587 |
|
| 588 |
const badge = buildOverlay();
|
| 589 |
+
renderPosture(); renderVerdict(); renderCompute(); renderRid(); renderGates(); renderFingerprint();
|
| 590 |
|
| 591 |
// per-frame animation (rotate the estate slowly + run demo updaters). The shell's
|
| 592 |
// Stage has no offFrame(), so we self-guard: once unmounted, _group is null and the
|
|
|
|
| 624 |
_handles.push(ctx.live.poll(EP.gates, 30000, (json) => {
|
| 625 |
_state.gates = json; renderGates();
|
| 626 |
}));
|
| 627 |
+
// Governed MODELED compute + Λ-ROE advisory gate (Conjecture 1, gray never green).
|
| 628 |
+
_handles.push(ctx.live.poll(EP.compute, 8000, (json) => {
|
| 629 |
+
_state.compute = json; renderCompute();
|
| 630 |
+
}));
|
| 631 |
// 53-fingerprint DB (static vendored; fetched once)
|
| 632 |
fetch(EP.dronesDb, { headers: { accept: "application/json" } })
|
| 633 |
.then((r) => r.ok ? r.json() : null)
|
|
|
|
| 648 |
try { if (_group && _stage) _stage.scene.remove(_group); } catch (_) {}
|
| 649 |
_overlay = _show = null; _group = null; _globe = null; _trackGroup = null;
|
| 650 |
_verdictBeam = null; _dsseLock = null; _stage = null; THREE = null; _ctx = null;
|
| 651 |
+
_computePanel = null; S.label = null; S.compute = null; S.roe = null;
|
| 652 |
+
_state = { evaluate: null, telemetry: null, cued: null, airpicture: null, gates: null, db: null, compute: null, meta: {}, dbCount: 0 };
|
| 653 |
}
|
| 654 |
|
| 655 |
+
export default { id: ID, title: TITLE, endpoints: [EP.evaluate, EP.telemetry, EP.cued, EP.airpicture, EP.gates, EP.compute], mount, unmount };
|
static/3d/surfaces/fabric.js
CHANGED
|
@@ -33,6 +33,18 @@ import { createShowcase } from "./_showcase.js";
|
|
| 33 |
const ID = "fabric";
|
| 34 |
const TITLE = "Compute Fabric";
|
| 35 |
const ENDPOINT = "/api/a11oy/v1/compute-pool-hardened";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
// Doctrine palette (matches the shell CSS vars).
|
| 38 |
const C = {
|
|
@@ -48,7 +60,7 @@ const C = {
|
|
| 48 |
};
|
| 49 |
|
| 50 |
let _ctx = null, _stage = null, _THREE = null;
|
| 51 |
-
let _handle = null, _overlay = null, _panel = null, _detailChip = null, _show = null;
|
| 52 |
let _root = null; // group holding the whole mesh (rotates slowly)
|
| 53 |
let _nodeMeshes = []; // [{ data, group, core, ring, glow, orbit[], labelSprite, basePos }]
|
| 54 |
let _edges = []; // [{ line, a, b, hot }]
|
|
@@ -137,9 +149,10 @@ function _buildOverlay() {
|
|
| 137 |
// The counts rows fold into the (collapsed) body so the 3D node mesh stays the star.
|
| 138 |
_show = createShowcase(_ctx, {
|
| 139 |
id: ID, title: TITLE, accent: "#5b8dee", badge,
|
| 140 |
-
legend: ["LIVE", "MEASURED", "STRUCTURAL-ONLY"],
|
| 141 |
description: "reachable = REAL TCP probe this sweep · sovereign = owned-hardware " +
|
| 142 |
-
"property, never inferred ·
|
|
|
|
| 143 |
plain: { html: _plainHtml },
|
| 144 |
});
|
| 145 |
|
|
@@ -159,6 +172,8 @@ function _buildOverlay() {
|
|
| 159 |
card.appendChild(_row("sovereign GPU live", "v_sov"));
|
| 160 |
card.appendChild(_row("secondary lung", "v_chaski"));
|
| 161 |
card.appendChild(_row("reach probe", "v_label"));
|
|
|
|
|
|
|
| 162 |
ov.appendChild(card);
|
| 163 |
|
| 164 |
_show.body.appendChild(ov);
|
|
@@ -547,6 +562,31 @@ function _updateHud(json, meta) {
|
|
| 547 |
}
|
| 548 |
}
|
| 549 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 550 |
// ----------------------------------------------------------------------------
|
| 551 |
// Degraded / missing handling
|
| 552 |
// ----------------------------------------------------------------------------
|
|
@@ -693,11 +733,16 @@ function mount(ctx) {
|
|
| 693 |
}
|
| 694 |
}, { badge: built.badge, onState: (meta) => { if (meta.state !== "live" && meta.state !== "degraded") _showDegraded(meta); } });
|
| 695 |
|
|
|
|
|
|
|
|
|
|
| 696 |
return { id: ID, started: true };
|
| 697 |
}
|
| 698 |
|
| 699 |
function unmount() {
|
| 700 |
try { if (_handle) _handle.stop(); } catch (_) {}
|
|
|
|
|
|
|
| 701 |
try {
|
| 702 |
if (_domEl) {
|
| 703 |
if (_onClick) _domEl.removeEventListener("click", _onClick);
|
|
@@ -716,4 +761,4 @@ function unmount() {
|
|
| 716 |
_ctx = null; _stage = null; _THREE = null; _lastJson = null; _selected = null;
|
| 717 |
}
|
| 718 |
|
| 719 |
-
export default { id: ID, title: TITLE, endpoints: [ENDPOINT], mount, unmount };
|
|
|
|
| 33 |
const ID = "fabric";
|
| 34 |
const TITLE = "Compute Fabric";
|
| 35 |
const ENDPOINT = "/api/a11oy/v1/compute-pool-hardened";
|
| 36 |
+
// MODELED compute-fabric topology/throughput model (szl_fabric_surface.py). Evaluates
|
| 37 |
+
// the classical scalability laws (Amdahl/Gustafson/USL/Little) over the HORIZONTAL
|
| 38 |
+
// fabric. Node COUNT is live when the pool is reachable; the THROUGHPUT is MODELED
|
| 39 |
+
// (never a metered read) and carries cited inputs + provenance. This is the surface's
|
| 40 |
+
// honest runtime-default census label source.
|
| 41 |
+
const TOPOLOGY_EP = "/api/a11oy/v1/fabric/topology";
|
| 42 |
+
|
| 43 |
+
// Honest surface state. The headline label is READ VERBATIM from the topology endpoint
|
| 44 |
+
// and defaults to MODELED (the topology/throughput is a MODELED scalability model of the
|
| 45 |
+
// fabric — the reach counts remain MEASURED, labelled separately). Never fabricated;
|
| 46 |
+
// never upgraded past what the endpoint declares.
|
| 47 |
+
const S = { label: null, topo: null };
|
| 48 |
|
| 49 |
// Doctrine palette (matches the shell CSS vars).
|
| 50 |
const C = {
|
|
|
|
| 60 |
};
|
| 61 |
|
| 62 |
let _ctx = null, _stage = null, _THREE = null;
|
| 63 |
+
let _handle = null, _topoHandle = null, _overlay = null, _panel = null, _detailChip = null, _show = null;
|
| 64 |
let _root = null; // group holding the whole mesh (rotates slowly)
|
| 65 |
let _nodeMeshes = []; // [{ data, group, core, ring, glow, orbit[], labelSprite, basePos }]
|
| 66 |
let _edges = []; // [{ line, a, b, hot }]
|
|
|
|
| 149 |
// The counts rows fold into the (collapsed) body so the 3D node mesh stays the star.
|
| 150 |
_show = createShowcase(_ctx, {
|
| 151 |
id: ID, title: TITLE, accent: "#5b8dee", badge,
|
| 152 |
+
legend: ["LIVE", "MEASURED", "MODELED", "STRUCTURAL-ONLY"],
|
| 153 |
description: "reachable = REAL TCP probe this sweep · sovereign = owned-hardware " +
|
| 154 |
+
"property, never inferred · throughput is a MODELED scalability model (Amdahl/" +
|
| 155 |
+
"Gustafson/USL/Little, cited) · the node mesh is STRUCTURAL-ONLY (no measured NVLink bytes).",
|
| 156 |
plain: { html: _plainHtml },
|
| 157 |
});
|
| 158 |
|
|
|
|
| 172 |
card.appendChild(_row("sovereign GPU live", "v_sov"));
|
| 173 |
card.appendChild(_row("secondary lung", "v_chaski"));
|
| 174 |
card.appendChild(_row("reach probe", "v_label"));
|
| 175 |
+
card.appendChild(_row("governed throughput", "v_tput"));
|
| 176 |
+
card.appendChild(_row("topology model", "v_topo"));
|
| 177 |
ov.appendChild(card);
|
| 178 |
|
| 179 |
_show.body.appendChild(ov);
|
|
|
|
| 562 |
}
|
| 563 |
}
|
| 564 |
|
| 565 |
+
// ----------------------------------------------------------------------------
|
| 566 |
+
// MODELED topology / throughput handler. Sets the surface's runtime-default honesty
|
| 567 |
+
// label VERBATIM from the endpoint (defaults MODELED — the census single-source-of-
|
| 568 |
+
// truth, a11oy_frontier_page._derive_label). The throughput is MODELED, NOT a metered
|
| 569 |
+
// read; the reach counts stay MEASURED (labelled separately). HORIZONTAL scale only —
|
| 570 |
+
// no fused/pooled VRAM claim.
|
| 571 |
+
// ----------------------------------------------------------------------------
|
| 572 |
+
function _onTopology(j) {
|
| 573 |
+
S.topo = j;
|
| 574 |
+
// Runtime-default census label, read verbatim (never upgraded past what it declares).
|
| 575 |
+
const jl = j && j.label;
|
| 576 |
+
S.label = (jl || "MODELED").toUpperCase();
|
| 577 |
+
const tput = j && j.throughput;
|
| 578 |
+
if (_hud.v_tput) {
|
| 579 |
+
_hud.v_tput.textContent = (tput && tput.governed_jobs_per_s != null)
|
| 580 |
+
? (tput.governed_jobs_per_s + " jobs/s") : "—";
|
| 581 |
+
_hud.v_tput.style.color = C.para; // MODELED figure — neutral, never a MEASURED green
|
| 582 |
+
}
|
| 583 |
+
if (_hud.v_topo) {
|
| 584 |
+
const n = j && j.topology && j.topology.nodes_total;
|
| 585 |
+
_hud.v_topo.textContent = (n != null ? (n + " nodes · ") : "") + S.label;
|
| 586 |
+
_hud.v_topo.style.color = C.para;
|
| 587 |
+
}
|
| 588 |
+
}
|
| 589 |
+
|
| 590 |
// ----------------------------------------------------------------------------
|
| 591 |
// Degraded / missing handling
|
| 592 |
// ----------------------------------------------------------------------------
|
|
|
|
| 733 |
}
|
| 734 |
}, { badge: built.badge, onState: (meta) => { if (meta.state !== "live" && meta.state !== "degraded") _showDegraded(meta); } });
|
| 735 |
|
| 736 |
+
// MODELED topology/throughput poll (sets the honest runtime-default census label).
|
| 737 |
+
_topoHandle = ctx.live.poll(TOPOLOGY_EP, 9000, (json) => { _onTopology(json); });
|
| 738 |
+
|
| 739 |
return { id: ID, started: true };
|
| 740 |
}
|
| 741 |
|
| 742 |
function unmount() {
|
| 743 |
try { if (_handle) _handle.stop(); } catch (_) {}
|
| 744 |
+
try { if (_topoHandle) _topoHandle.stop(); } catch (_) {}
|
| 745 |
+
_topoHandle = null; S.label = null; S.topo = null;
|
| 746 |
try {
|
| 747 |
if (_domEl) {
|
| 748 |
if (_onClick) _domEl.removeEventListener("click", _onClick);
|
|
|
|
| 761 |
_ctx = null; _stage = null; _THREE = null; _lastJson = null; _selected = null;
|
| 762 |
}
|
| 763 |
|
| 764 |
+
export default { id: ID, title: TITLE, endpoints: [ENDPOINT, TOPOLOGY_EP], mount, unmount };
|