drop-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev b2e053fd98cb
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 80ddb8c5df822e290afdd3c7
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
src/lib/format.ts
// Sizes, speeds and times in plain words.

/** Sizes like "50.3 MB", with a no-break space so the number and unit stay on one line. */
export function bytes(n: number): string {
  if (n < 1000) return `${n}\u00a0B`;
  const units = ["KB", "MB", "GB", "TB"];
  let v = n / 1000;
  let i = 0;
  while (v >= 1000 && i < units.length - 1) { v /= 1000; i++; }
  return `${v >= 100 ? Math.round(v) : v >= 10 ? v.toFixed(1).replace(/\.0$/, "") : v.toFixed(2).replace(/\.?0+$/, "")}\u00a0${units[i]}`;
}

export function speed(bytesPerSecond: number): string {
  return `${bytes(Math.max(0, Math.round(bytesPerSecond)))}/s`;
}

export function timeLeft(seconds: number): string {
  if (!Number.isFinite(seconds) || seconds < 0) return "";
  if (seconds < 10) return "a few seconds left";
  if (seconds < 60) return `about ${Math.round(seconds / 5) * 5} seconds left`;
  const min = Math.round(seconds / 60);
  if (min < 60) return `about ${min} min left`;
  const h = Math.floor(min / 60);
  const m = min % 60;
  return `about ${h} h ${m ? `${m} min ` : ""}left`;
}

export function files(n: number): string {
  return `${n} ${n === 1 ? "file" : "files"}`;
}

/** Speed from a running byte count, smoothed over the last few seconds. */
export class Rate {
  private last: { t: number; n: number } | null = null;
  private value = 0;

  /** Feed the total so far; returns bytes per second. */
  push(total: number, now = performance.now()): number {
    if (!this.last) { this.last = { t: now, n: total }; return this.value; }
    const dt = (now - this.last.t) / 1000;
    if (dt < 0.4) return this.value;
    const instant = Math.max(0, total - this.last.n) / dt;
    this.value = this.value ? this.value * 0.6 + instant * 0.4 : instant;
    this.last = { t: now, n: total };
    return this.value;
  }

  reset() { this.last = null; this.value = 0; }
}

Change history

Point OpenApps links to openapps.free
b2e053fd98 · 17 hours ago
Bind agent address in policy
ca424dd814 · 19 hours ago
Retry release capture
ae07f1a3fd · 19 hours ago
Use OpenApps service URLs and add contribution strip
0452ce136f · 19 hours ago
Bounded source sync
ca1bc00aa4 · 1 day ago
Bounded source sync
d4982911a0 · 1 day ago
Bounded source sync
18c97fe4ca · 1 day ago