// Pure upload-progress formatting (no DOM), extracted from static/upload.js. /** Human-readable transfer speed, e.g. "2.4 MB/s" or "740 KB/s". */ export function formatSpeed(bytesPerSec: number): string { return bytesPerSec > 1024 * 1024 ? (bytesPerSec / (1024 * 1024)).toFixed(1) + ' MB/s' : (bytesPerSec / 1024).toFixed(0) + ' KB/s'; } /** * Human-readable ETA, e.g. "45s" or "2m 5s". * * One rounding, applied once, before the split into minutes and seconds. The * previous spelling rounded twice, `ceil(sec / 60)` for the minutes and * `ceil(sec % 60)` for the remainder, so 125 seconds read as "3m 5s": the * minutes had already absorbed the remainder and then it was added again. * Rounding first also keeps the remainder under 60, which floor-then-ceil * would not: 119.5 seconds would have printed "1m 60s". */ export function formatEta(remainingSec: number): string { const whole = Math.ceil(remainingSec); return whole < 60 ? whole + 's' : Math.floor(whole / 60) + 'm ' + (whole % 60) + 's'; }