/** * Satirist desk — pipeline timestamps, latest signals, writer stats, fact-check dates. * Data: /data/satirist-serious-links.json (manifest + serious links) */ (function () { function esc(s) { const d = document.createElement('div'); d.textContent = s == null ? '' : String(s); return d.innerHTML; } function formatPipelineUtc(iso) { if (!iso) return null; const d = new Date(iso); if (Number.isNaN(d.getTime())) return null; const pad = (n) => String(n).padStart(2, '0'); return ( d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + ' ' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ' UTC' ); } function formatFactCheckDate(iso) { if (!iso) return null; const d = new Date(iso.length === 10 ? iso + 'T12:00:00Z' : iso); if (Number.isNaN(d.getTime())) return iso.replace(/-/g, '\u2011'); const pad = (n) => String(n).padStart(2, '0'); return d.getUTCFullYear() + '\u2011' + pad(d.getUTCMonth() + 1) + '\u2011' + pad(d.getUTCDate()); } function setText(id, text) { const el = document.getElementById(id); if (el && text) el.textContent = text; } function applyRefresh(iso) { const ts = formatPipelineUtc(iso); if (!ts) return; setText('satirist-pipeline-refresh', ts); setText('satirist-pipeline-refresh-band', ts); setText('leg-scrape-time', ts); const dt = document.getElementById('daemon-time'); if (dt) dt.textContent = ts; } function writerCountLine(meta) { if (!meta) return null; let line = meta.articles_approx + ' articles'; if (meta.stats) line += ' · ' + meta.stats; if (meta.latest_label) line += ' · latest: ' + meta.latest_label; return line; } function applyWriters(writers) { if (!writers) return; document.querySelectorAll('[data-writer-id]').forEach(function (el) { const id = el.getAttribute('data-writer-id'); const line = writerCountLine(writers[id]); const target = el.querySelector('.wc-count'); if (line && target) target.textContent = line; }); } function anchorFor(sig) { if (sig.anchor) return sig.anchor; return '#' + sig.article_id; } function applyLatestSignals(manifest, articleMap) { const list = document.getElementById('satirist-latest-list'); if (!list || !Array.isArray(manifest.latest_signals)) return; list.innerHTML = ''; manifest.latest_signals.forEach(function (sig) { const article = articleMap.get(sig.article_id); const writer = sig.writer_name || article?.writer_name || ''; const desk = sig.desk || ''; const headline = sig.headline || article?.satire_title || sig.article_id; const date = sig.date_display || ''; const href = anchorFor(sig); const li = document.createElement('li'); li.setAttribute('data-signal-id', sig.article_id); li.appendChild(document.createTextNode(desk + ' — ')); const link = document.createElement('a'); link.href = href; link.textContent = headline; link.style.color = 'inherit'; link.style.textDecoration = 'none'; link.style.borderBottom = '1px dotted var(--rule)'; li.appendChild(link); if (writer || date) { let suffix = ' ('; if (writer) suffix += writer; if (writer && date) suffix += ', '; if (date) suffix += date; suffix += ')'; li.appendChild(document.createTextNode(suffix)); } list.appendChild(li); }); } function applyQueue(manifest) { const ul = document.getElementById('satire-queue-list'); if (!ul || !Array.isArray(manifest.queue_targets)) return; ul.innerHTML = manifest.queue_targets.map(function (t) { return '
  • ' + esc(t) + '
  • '; }).join(''); } function applyFactCheckDates(articles) { if (!Array.isArray(articles)) return; const map = new Map(articles.map(function (a) { return [a.id, a]; })); document.querySelectorAll('[data-satirist-id]').forEach(function (el) { const id = el.getAttribute('data-satirist-id'); const article = map.get(id); if (!article || !article.fact_check_as_of) return; const asOf = formatFactCheckDate(article.fact_check_as_of); el.querySelectorAll('.fact-check-box .fc-label').forEach(function (label) { const raw = label.textContent.replace(/\s*\(as of [^)]+\)\s*$/i, '').trim(); label.textContent = raw + ' (as of ' + asOf + ')'; }); }); } function applyManifest(manifest) { if (!manifest) return; const articleMap = new Map((manifest.articles || []).map(function (a) { return [a.id, a]; })); applyWriters(manifest.writers); applyLatestSignals(manifest, articleMap); applyQueue(manifest); applyFactCheckDates(manifest.articles); if (manifest.pipeline_interval_hours) { const hero = document.querySelector('.hero-freshness'); if (hero) { hero.textContent = 'Updated from the GMIIE pipeline every ' + manifest.pipeline_interval_hours + ' hours — new satire when the signals move, not on a content schedule.'; } } } async function fetchJson(url, signal) { const r = await fetch(url, { signal }); return r.ok ? r.json() : null; } async function loadPipelineRefresh(signal) { try { const data = await fetchJson('/api/gmiie/live/digest?jurisdiction=US-FED', signal); const iso = data && (data.generated_at || data.markets_fetched_at); if (iso) { applyRefresh(iso); return; } } catch (_) { /* static fallback */ } try { const data = await fetchJson('/data/gmiie-daily-digest.json', signal); if (data) applyRefresh(data.generated_at || data.markets_fetched_at); } catch (_) { /* HTML fallback */ } } async function loadManifest(signal) { try { const data = await fetchJson('/api/satirist/manifest', signal); if (data?.articles?.length) return data; } catch (_) { /* worker API unavailable */ } return fetchJson('/data/satirist-serious-links.json', signal); } async function load() { const signal = typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function' ? AbortSignal.timeout(10000) : undefined; try { const manifest = await loadManifest(signal); applyManifest(manifest); } catch (_) { /* static HTML fallback */ } await loadPipelineRefresh(signal); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', load); } else { load(); } window.GMIIESatiristFreshness = { load, applyManifest, applyRefresh }; })();