mirror of
https://github.com/direct-img/gh.direct-img.link.git
synced 2026-10-29 09:04:51 +00:00
stars.mjs renders dist/<owner>/<repo>.svg for each repo in repos.txt: a cumulative star chart with labelled breakouts, spikes and first star, ending in an isometric star. The hourly workflow commits only when the star count or UTC day changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
2.1 KiB
JavaScript
25 lines
2.1 KiB
JavaScript
// Synthetic star histories → preview/sim-<name>.png, to stress-test scaling and spike detection
|
|
import { writeFileSync } from 'node:fs'
|
|
import { execFileSync } from 'node:child_process'
|
|
import { svg, markers } from '../stars.mjs'
|
|
const DAY = 864e5, now = Date.parse('2026-10-28T12:00:00Z')
|
|
let seed = 7; const rnd = () => (seed = seed * 16807 % 2147483647) / 2147483647
|
|
const pois = l => { if (l > 30) return Math.max(0, Math.round(l + Math.sqrt(l) * (rnd() + rnd() + rnd() - 1.5) * 2)); let k = 0, p = 1, L = Math.exp(-l); while ((p *= rnd()) > L) k++; return k }
|
|
const sim = (born, rate) => { const b = Date.parse(born), out = []; for (let d = 0; b + d * DAY < now; d++) for (let k = pois(rate(d, Math.floor((now - b) / DAY))); k--;) out.push(Math.min(now - 1, b + (d + rnd()) * DAY)); return { born: b, stars: out.sort((x, y) => x - y) } }
|
|
const bump = (d, at, h, w = 2) => d >= at ? h * Math.exp(-(d - at) / w) : 0
|
|
const S = {
|
|
'old-steady-hn': ['acme/old-steady', sim('2022-11-01T09:00:00Z', d => bump(d, 3, 120, 3) + 2 + d / 200 + bump(d, 500, 500, 2))],
|
|
'late-viral': ['acme/late-viral', sim('2024-09-10T09:00:00Z', (d, n) => .15 + bump(d, n - 5, 700, 1.5))],
|
|
'many-bumps': ['acme/many-bumps', sim('2025-04-01T09:00:00Z', d => 1.5 + [40, 95, 160, 210, 260, 330, 400, 470, 520].reduce((s, a, i) => s + bump(d, a, 20 + i * 8, 1), 0))],
|
|
'huge': ['acme/huge-framework', sim('2019-03-01T09:00:00Z', d => bump(d, 1, 3000, 4) + 40 + 30 * Math.sin(d / 180) + bump(d, 900, 4000, 3) + bump(d, 1700, 2500, 2))],
|
|
'step-change': ['acme/step-change', sim('2024-06-01T09:00:00Z', d => d < 400 ? 1 : 15)],
|
|
'one-star': ['acme/lonely', sim('2026-06-01T09:00:00Z', d => d == 30 ? 1 : 0)],
|
|
'zero': ['acme/nothing-yet', { born: Date.parse('2026-10-20T09:00:00Z'), stars: [] }],
|
|
}
|
|
for (const [k, [repo, d]] of Object.entries(S)) {
|
|
const f = `${import.meta.dirname}/.sim-${k}.svg`
|
|
writeFileSync(f, svg({ repo, ...d }, now))
|
|
execFileSync(`${import.meta.dirname}/render.sh`, [f, 'sim-' + k])
|
|
console.log(k.padEnd(14), String(d.stars.length).padStart(7), markers(d, now).map(m => `${m.title} (${m.sub})`).join(" | "))
|
|
}
|