| import { type ClassValue, clsx } from "clsx"; |
| import { twMerge } from "tailwind-merge"; |
|
|
| export function cn(...inputs: ClassValue[]): string { |
| return twMerge(clsx(inputs)); |
| } |
|
|
| |
| export function confidenceColor( |
| conf: number, |
| prediction: "real" | "fake" | "uncertain" |
| ): string { |
| if (prediction === "uncertain") { |
| return "text-warn"; |
| } |
| if (prediction === "fake") { |
| if (conf >= 0.85) return "text-danger"; |
| if (conf >= 0.6) return "text-warn"; |
| return "text-ink-dim"; |
| } |
| if (conf >= 0.85) return "text-cyber"; |
| if (conf >= 0.6) return "text-warn"; |
| return "text-ink-dim"; |
| } |
|
|
| export function formatMs(ms: number): string { |
| if (ms < 1) return `${(ms * 1000).toFixed(0)} µs`; |
| if (ms < 1000) return `${ms.toFixed(0)} ms`; |
| return `${(ms / 1000).toFixed(2)} s`; |
| } |
|
|
| export function formatPercent(value: number, digits = 1): string { |
| return `${(value * 100).toFixed(digits)}%`; |
| } |
|
|
| export function formatParams(k?: number | null): string { |
| if (k == null) return "—"; |
| if (k >= 1_000_000) return `${(k / 1_000_000).toFixed(1)}B`; |
| if (k >= 1_000) return `${(k / 1_000).toFixed(0)}M`; |
| return `${k}K`; |
| } |
|
|
| export function classifyStatus(status: string): "live" | "fallback" | "error" | "loading" { |
| const s = status.toLowerCase(); |
| if (s === "live") return "live"; |
| if (s.startsWith("architecture_only_fallback")) return "fallback"; |
| if (s.startsWith("error")) return "error"; |
| return "loading"; |
| } |
|
|