// Evidence tooltip — appears on hover over a node or edge, anchored to cursor. window.EvidenceTip = function EvidenceTip({ payload }) { if (!payload) return null; const { node, edge, status, reasons, pos } = payload; const W = 320; let left = pos.x + 16; let top = pos.y + 14; if (typeof window !== "undefined") { if (left + W > window.innerWidth - 12) left = pos.x - W - 16; if (top + 220 > window.innerHeight - 12) top = pos.y - 220; if (top < 12) top = 12; } return (
{node && ( <>
{node.name} {status}
{node.description}
{reasons && reasons.length > 0 && ( <> {reasons.slice(0, 2).map((r, i) => { const ev = (r.evidence && r.evidence[0]) || null; return (
{r.label}
{r.fix &&
{r.fix}
} {ev && ev.quote &&
“{ev.quote}”
} {ev && (
{prettyUrl(ev.url)} T{ev.tier || r.tier || 1}
)}
); })} )} {(!reasons || reasons.length === 0) && (
type · {node.type} T{node.tier}
)} )} {edge && ( <>
{displayName(edge.from)} {displayName(edge.to)} {edge.relation}
{edge.fix &&
{edge.fix}
} {edge.evidence && edge.evidence[0] && ( <>
“{edge.evidence[0].quote}”
{prettyUrl(edge.evidence[0].url)} T{edge.tier}
)} )}
); }; function displayName(c) { const n = (window.FORGE_NODES || []).find(x => x.canonical === c); return n ? n.name : c; } function prettyUrl(url) { if (!url) return ""; if (url.startsWith("mempalace://")) return "mempalace · rick"; try { const u = new URL(url); return u.hostname.replace(/^www\./, "") + u.pathname; } catch { return url; } }