/* ===== ArbitrajZ — Sparkline (the hero) + brand mark ===== */
const { useState, useRef, useEffect, useMemo } = React;
/* The radar mark, reused from the ArbitrajZ favicon. `live` adds a slow sweep. */
function RadarMark({ size = 30, live = false, glow = false }) {
const uid = useMemo(() => "rm" + Math.random().toString(36).slice(2, 7), []);
return (
);
}
/*
Sparkline — funding-rate path with a visible ZERO baseline.
Above the baseline = short earns; a crossing below = a negative-funding event.
Stable series read as a calm flat line; volatile ones visibly stab below zero.
*/
function Sparkline({ series, width = 224, height = 60, stable }) {
const uid = useMemo(() => "sp" + Math.random().toString(36).slice(2, 7), []);
const padY = 9;
const stroke = stable ? "#2EE6A6" : "#F5B544";
const geom = useMemo(() => {
const max = Math.max(...series, 0);
const min = Math.min(...series, 0);
const span = max - min || 1;
const x = (i) => (i / (series.length - 1)) * (width - 2) + 1;
const y = (v) => padY + (1 - (v - min) / span) * (height - padY * 2);
const zeroY = y(0);
const pts = series.map((v, i) => [x(i), y(v), v]);
const line = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
const area = `M${pts[0][0].toFixed(1)} ${zeroY.toFixed(1)} ` +
pts.map((p) => "L" + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ") +
` L${pts[pts.length - 1][0].toFixed(1)} ${zeroY.toFixed(1)} Z`;
const negs = pts.filter((p) => p[2] < 0);
return { pts, line, area, zeroY, negs, last: pts[pts.length - 1] };
}, [series, width, height]);
const [hover, setHover] = useState(null);
return (
);
}
window.RadarMark = RadarMark;
window.Sparkline = Sparkline;
/* Colorful candlestick mark — same rounded-tile chrome as the radar, but a
green/red OHLC chart for a more "chart-forward" brand read. */
function ChartMark({ size = 32 }) {
const uid = useMemo(() => "cm" + Math.random().toString(36).slice(2, 7), []);
const G = "#2EE6A6", R = "#FF5C6C";
return (
);
}
window.ChartMark = ChartMark;