import { AppBar, Box, Button, Chip, Divider, IconButton, Stack, Toolbar, Tooltip, Typography, } from "@mui/material"; import OpenInNewRoundedIcon from "@mui/icons-material/OpenInNewRounded"; import RefreshRoundedIcon from "@mui/icons-material/RefreshRounded"; import HubRoundedIcon from "@mui/icons-material/HubRounded"; import type { IRGraphMeta, ResolvedModel } from "../types"; import { GranularitySlider } from "./GranularitySlider"; interface Props { resolved: ResolvedModel | null; meta: IRGraphMeta | null; onReset: () => void; granularity: number; maxGranularity: number; visibleNodeCount: number; onGranularityChange: (v: number) => void; bytesTransferred: number; } function bytesPretty(n: number): string { if (n < 1024) return `${n} B`; if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`; return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`; } function formatParams(n: number): string { if (n === 0) return "0"; if (n < 1_000_000) return `${(n / 1_000).toFixed(1)}K`; if (n < 1_000_000_000) return `${(n / 1_000_000).toFixed(1)}M`; return `${(n / 1_000_000_000).toFixed(2)}B`; } /** Split `owner/name` into a 2-tuple. Falls back gracefully on malformed input. */ function splitRepo(repoId: string): { owner: string; name: string } { const i = repoId.indexOf("/"); if (i < 0) return { owner: "", name: repoId }; return { owner: repoId.slice(0, i), name: repoId.slice(i + 1) }; } const MONO_FONT = '"JetBrains Mono", "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace'; const verticalRule = ( ); export function Header({ resolved, meta, onReset, granularity, maxGranularity, visibleNodeCount, onGranularityChange, bytesTransferred, }: Props) { // Effective bandwidth savings: compare the *expected* full-file size to the // bytes we actually pulled over the wire (just header metadata thanks to // raw_data skipping + external-data detection). const totalSize = resolved?.sizeBytes ?? 0; const savings = totalSize > 0 && bytesTransferred > 0 && bytesTransferred < totalSize ? 1 - bytesTransferred / totalSize : 0; const savingsLabel = savings > 0.05 ? `${(savings * 100).toFixed(0)}% saved` : null; const { owner, name } = splitRepo(resolved?.repoId ?? ""); return ( {/* ──────────── Brand ──────────── */} HF Model Viewer architecture explorer {resolved && ( <> {verticalRule} {/* ──────────── Repo crumb ──────────── */} {owner && ( {owner} / )} {name} {meta?.modelType && ( )} {/* ──────────── Granularity (full-width second row on mobile) ──────────── */} {maxGranularity > 0 && ( )} {verticalRule} {/* ──────────── Stats + actions ──────────── */} {meta && ( )} {savingsLabel && ( )} )} {!resolved && } ); }