export const humanFileSize = value => window.humanFileSize(value); export const bigNum = (function () { return function bigNum(v) { const n = Number(v) || 0; const abs = Math.abs(n); if (abs < 1000) return String(n); if (abs < 10000) return (n / 1000).toFixed(1).replace(/\.0$/, "") + "k"; if (abs < 1000000) return Math.round(n / 1000) + "k"; if (abs < 10000000) return (n / 1000000).toFixed(1).replace(/\.0$/, "") + "M"; return Math.round(n / 1000000) + "M"; }; })(); export const humanTime = (function () { return function humanTime(seconds) { if (!seconds) { return "never"; } if (seconds instanceof Date) seconds = Math.round((Date.now() - seconds) / 1000); if (typeof seconds == "string" || typeof seconds == "number") seconds = Math.round((Date.now() - new Date(seconds)) / 1000); var suffix = seconds < 0 ? "from now" : "ago"; // more than 2 days ago display Date. Spell the month out so the date // is unambiguous regardless of the reader's locale (9/6 vs 6/9). if (Math.abs(seconds) > 2 * 60 * 60 * 24) { const now = new Date(); now.setSeconds(now.getSeconds() - seconds); return ( "on " + now.toLocaleDateString(undefined, { day: "numeric", month: "short", year: "numeric", }) ); } seconds = Math.abs(seconds); var times = [ seconds / 60 / 60 / 24 / 365, // years seconds / 60 / 60 / 24 / 30, // months seconds / 60 / 60 / 24 / 7, // weeks seconds / 60 / 60 / 24, // days seconds / 60 / 60, // hours seconds / 60, // minutes seconds, // seconds ]; var names = ["year", "month", "week", "day", "hour", "minute", "second"]; for (var i = 0; i < names.length; i++) { var time = Math.floor(times[i]); var name = names[i]; if (time > 1) name += "s"; if (time >= 1) return time + " " + name + " " + suffix; } return "0 seconds " + suffix; }; })(); export const title = (function () { return function (str) { if (!str) return str; str = str.toLowerCase(); var words = str.split(" "); var capitalized = words.map(function (word) { return word.charAt(0).toUpperCase() + word.substring(1, word.length); }); return capitalized.join(" "); }; })(); export const statusLabel = (function () { var labels = { ready: "Ready", error: "Error", expired: "Expired", expiring: "Expiring", removed: "Removed", removing: "Removing", queue: "Queued", download: "Downloading", downloaded: "Downloaded", preparing: "Preparing", anonymizing: "Anonymizing", }; return function (status) { if (!status) return ""; if (labels[status]) return labels[status]; var s = String(status).replace(/[_-]+/g, " ").toLowerCase(); return s.charAt(0).toUpperCase() + s.slice(1); }; })(); export const statusMsg = (function () { // Known machine codes → sentences. Unknown snake_case codes are // converted to a sentence instead of leaking `branch_not_found`. var codes = { branch_not_found: "Branch not found on GitHub", repo_not_found: "Repository not found on GitHub", repository_not_found: "Repository not found on GitHub", repo_not_accessible: "Repository is not accessible with your token", pr_not_found: "Pull request not found on GitHub", gist_not_found: "Gist not found on GitHub", commit_not_found: "Commit not found on GitHub", repo_too_big: "Repository exceeds the size limit", quota_exceeded: "Storage quota exceeded", incomplete_record: "Incomplete record: missing identifier", }; return function (msg) { if (!msg) return msg; var m = msg.match(/^rate_limited:(\d+)$/); if (m) { var remaining = Math.max(0, Math.ceil((parseInt(m[1], 10) - Date.now()) / 1000)); if (remaining <= 0) return "Rate limited — resuming soon"; var min = Math.floor(remaining / 60); var sec = remaining % 60; return "Rate limited — retrying in " + (min > 0 ? min + "m " + sec + "s" : sec + "s"); } if (codes[msg]) return codes[msg]; if (/^[a-z0-9]+(_[a-z0-9]+)+$/.test(msg)) { var s = msg.replace(/_/g, " "); return s.charAt(0).toUpperCase() + s.slice(1); } return msg; }; })(); export const diff = (function (html) { const esc = (s) => s.replace(/&/g, "&").replace(//g, ">"); function flushFile(out, file) { if (!file) return; const headerName = file.newPath && file.newPath !== "/dev/null" ? file.newPath : file.oldPath || ""; const status = file.oldPath === "/dev/null" ? "added" : file.newPath === "/dev/null" ? "deleted" : file.oldPath && file.newPath && file.oldPath !== file.newPath ? "renamed" : "modified"; out.push('
| ' + (line.oldNo || "") + " | " + '' + (line.newNo || "") + " | " + '' + (line.kind === "add" ? "+" : line.kind === "remove" ? "-" : line.kind === "hunk" ? "@" : "") + " | " + '' + esc(line.text) + " | " + "