// Generated, do not edit. sha256:08b414b8e046583bdfdf9c3302134a9e220a7c451265f464b9ed56dca2d3d460 import { getPref, setPref } from '../data/preferences.js'; import { CONFIG, targetHash } from '../../shared/config.js'; import { esc } from './escape.js'; const producers = []; let cache = []; let cacheKey = ''; const PREF_SCOPE = 'attention'; const PREF_ACT = 'activated'; const PREF_SEEN = 'seen'; const PREF_DAY = 'day'; const activated = new Map(); const seen = new Set(); let loaded = false; let dayN = 0; const stateKey = a => `${a.id}|${a.severity || 'attention'}`; function todayStr() { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; } async function ensureLoaded() { if (loaded) return; loaded = true; try { const act = await getPref(PREF_SCOPE, PREF_ACT, {}); if (act && typeof act === 'object' && !Array.isArray(act)) { for (const [id, s] of Object.entries(act)) activated.set(String(id), Number(s) || 0); } } catch { } try { const s = await getPref(PREF_SCOPE, PREF_SEEN, []); if (Array.isArray(s)) for (const k of s) seen.add(String(k)); } catch { } let day = { date: '', n: 0 }; try { const d = await getPref(PREF_SCOPE, PREF_DAY, null); if (d && typeof d === 'object') day = d; } catch { } const today = todayStr(); if (day.date !== today) { day = { date: today, n: (Number(day.n) || 0) + 1 }; saveDay(day); } dayN = Number(day.n) || 1; } async function saveDay(day) { try { await setPref(PREF_SCOPE, PREF_DAY, day); } catch { } } async function saveActivated() { try { await setPref(PREF_SCOPE, PREF_ACT, Object.fromEntries(activated)); } catch { } } async function saveSeen() { try { await setPref(PREF_SCOPE, PREF_SEEN, [...seen]); } catch { } } function fadeFor(a) { const k = stateKey(a); if (!activated.has(k)) return 'hidden'; const age = dayN - activated.get(k); if (age >= CONFIG.ATTENTION.HIDE_AFTER_DAYS) return 'hidden'; if (age >= CONFIG.ATTENTION.FADE_AFTER_DAYS || seen.has(k)) return 'dim'; return 'full'; } function currentRouteKey() { const h = (typeof location !== 'undefined' ? location.hash : '') || ''; return h.replace(/^#\/?/, '') || 'home'; } function opDezePlek(a, here) { const hereHead = here.split('/')[0]; if (!a.tab) return a.route === here || a.route === hereHead; const plek = `${a.route}/${a.tab}`; return here === plek || here.startsWith(`${plek}/`); } export function registerAttention(producer) { if (typeof producer === 'function') producers.push(producer); return () => { const i = producers.indexOf(producer); if (i >= 0) producers.splice(i, 1); }; } export async function refreshAttention() { const collected = []; for (const p of producers) { try { const items = await p(); if (Array.isArray(items)) collected.push(...items.filter(Boolean)); } catch { } } const norm = collected.map(a => ({ id: String(a.id), severity: a.severity || 'attention', route: a.route ?? null, tab: a.tab ?? null, hash: a.hash || (a.route ? targetHash({ route: a.route }) : null), label: a.label || '', count: Number.isFinite(a.count) ? a.count : null, })).sort((x, y) => (x.route || '').localeCompare(y.route || '') || x.id.localeCompare(y.id)); cache = norm; await ensureLoaded(); const here = currentRouteKey(); const liveKeys = new Set(norm.map(stateKey)); let activatedChanged = false, seenChanged = false; for (const a of norm) { const k = stateKey(a); if (activated.has(k)) { if (a.route !== null && opDezePlek(a, here) && !seen.has(k)) { seen.add(k); seenChanged = true; } continue; } if (a.route === null || !opDezePlek(a, here)) { activated.set(k, dayN); activatedChanged = true; } } for (const k of [...activated.keys()]) { if (!liveKeys.has(k)) { activated.delete(k); activatedChanged = true; } } for (const k of [...seen]) { if (!liveKeys.has(k)) { seen.delete(k); seenChanged = true; } } if (activatedChanged) saveActivated(); if (seenChanged) saveSeen(); const actKey = norm.filter(a => activated.has(stateKey(a))).map(a => `${stateKey(a)}:${fadeFor(a)}`).sort().join(','); const key = JSON.stringify(norm) + '|' + actKey; const changed = key !== cacheKey; cacheKey = key; if (changed && typeof document !== 'undefined' && typeof document.dispatchEvent === 'function') { document.dispatchEvent(new CustomEvent('attention-changed')); } return cache; } export function attentionItems() { return cache; } export function generalAttention() { return cache.filter(a => a.route === null).map(a => ({ ...a, fade: fadeFor(a) })).filter(a => a.fade !== 'hidden'); } export function attentionForRoute(route) { return cache.filter(a => a.route === route) .map(a => ({ ...a, fade: fadeFor(a) })).filter(a => a.fade !== 'hidden'); } export function hasAttentionForRoute(route) { return attentionForRoute(route).length > 0; } export function attentionHasProblem(items) { return (items || []).some(a => a.severity === 'problem'); } export function attentionDimmed(items) { return !!(items && items.length) && items.every(a => a.fade === 'dim'); } export function attentionDotHtml(items) { if (!items || !items.length) return ''; const hint = items.map(a => a.label).filter(Boolean).join(' \u00b7 '); const dim = attentionDimmed(items); const stuk = attentionHasProblem(items); return ` `; }