const notificationCenter = (() => { const store = new Map(); const dom = {}; let initialized = false; let hiddenResponseSignature = ""; let hiddenResponseAt = 0; function _cacheDom() { dom.root = $("notification-center"); dom.bell = $("notification-bell"); dom.badge = $("notification-badge"); dom.dropdown = $("notification-dropdown"); dom.list = $("notification-list"); dom.subtitle = $("notification-subtitle"); dom.markAll = $("notification-mark-all"); dom.clearAll = $("notification-clear-all"); } function _ordered() { return Array.from(store.values()).sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0)); } function _counts() { const items = _ordered(); return { total: items.length, unread: items.filter(item => !item.read).length, }; } function _relativeTime(timestamp) { if (!timestamp) return "Just now"; const diff = Math.max(0, Math.floor(Date.now() / 1000) - timestamp); if (diff < 10) return "Just now"; if (diff < 60) return `${diff}s ago`; if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; return new Date(timestamp * 1000).toLocaleDateString(); } function _notificationIcon(item) { const kind = item.kind || item.source || "notification"; const icons = { update: "system_update", cron: "schedule_send", heartbeat: "favorite", agent_response: "chat", memory_compact: "auto_fix_high", memory_compacted: "auto_fix_high", }; return icons[kind] || "notifications"; } function _notificationTypeLabel(item) { const kind = item.kind || item.source || "notification"; const labels = { update: "Update", cron: "Cron", heartbeat: "Heartbeat", agent_response: "Agent response", memory_compact: "Memory", memory_compacted: "Memory", }; return labels[kind] || (kind.replace(/_/g, " ").replace(/\b\w/g, ch => ch.toUpperCase())); } function _upsert(notification) { if (!notification || !notification.id) return; store.set(notification.id, notification); } function _replaceAll(items) { store.clear(); (items || []).forEach(_upsert); } function _setOpen(open) { if (!dom.root) return; dom.root.classList.toggle("is-open", open); } function _renderEmpty(message) { if (!dom.list) return; dom.list.innerHTML = `