{clock} {today}
{#if host} 85 && 'warn']}>CPU {Math.round(host.cpuPct)}% 90 && 'warn']}>RAM {Math.round(memPct)}% {#if disk}= 85 && 'bad']}>Disk {Math.round(disk.pct)}%{/if} {servicesDown.length ? `${servicesDown.length} down` : 'all up'} {/if} {#if data.weight}{data.weight.kg} kg{/if}

Tasks {data.tasks.length} now · {data.openCount} open

    {#each data.tasks as t (t.id)}
  • {t.title} {#if t.priority >= 2}{'!'.repeat(t.priority)}{/if} {#if t.status === 'in_progress'}doing{/if} {#if t.dueDate}{dueLabel(t.dueDate)}{t.dueTime ? ` ${t.dueTime.slice(0, 5)}` : ''}{/if}
  • {:else}
  • Nothing due. Nice.
  • {/each}

Notifications {data.ntfy?.topics.join(' · ') ?? 'no collector yet'}{#if data.ntfy?.errors.length} · {data.ntfy.errors.join(', ')} unreachable{/if}

    {#each data.ntfy?.messages ?? [] as m (m.id)}
  • = 4 && 'hi']}>
    {m.topic}
    {#if m.click} {#if m.title}{m.title}{/if} {m.message} {:else}

    {#if m.title}{m.title}{/if} {m.message}

    {/if}
  • {:else}
  • No notifications in the last 3 days.
  • {/each}

Backups & timers 0 }} >{timerProblems.length ? `${timerProblems.length} need a look` : 'all fine'}

    {#each timers as t (t.unit)}
  • {t.label} {t.status === 'running' ? 'running' : t.last ? ago(t.last * 1000, now) : 'not since boot'} {t.next ? ago(t.next * 1000, now) : ''}
  • {/each}

Server {host ? `${host.hostname} · ${ago(host.at, now)}` : 'no snapshot yet'}{stale && host ? ' (stale)' : ''}

{#if host}
{@render meter('CPU', host.cpuPct, `${Math.round(host.cpuPct)}% · ${host.cpus} cores`)} {@render meter('RAM', memPct, `${bytes(host.mem.used)} / ${bytes(host.mem.total)}`)} {@render meter( 'Swap', swapPct, host.swap.total ? `${bytes(host.swap.used)} / ${bytes(host.swap.total)}` : 'none' )} {#each host.disks as d (d.mount)} {@render meter( `Disk ${d.mount}`, d.pct, `${bytes(d.free)} free of ${bytes(d.total)}` )} {/each}

load {host.load.join(' / ')} · up {duration(host.uptimeS)} · {containersUp}/{containers.length} containers

    {#each containers as c (c.name)}
  • {shortName(c.name)} {#if c.restarts}↻{c.restarts}{/if} {c.cpu ?? ''} {c.mem ?? ''}
  • {/each}
{:else}

The host collector hasn't written a snapshot yet.

{/if}

Services {(host?.services.length ?? 0) - servicesDown.length}/{host?.services.length ?? 0} up

    {#each host?.services ?? [] as s (s.name)}
  • {s.name}
  • {/each}

Trackers

    {#each trackers as t (t.href)}
  • {t.name}
  • {/each}
{#snippet meter(label: string, pct: number, detail: string)}
{label} = 90 ? 'bad' : pct >= 75 ? 'warn' : 'ok']} style:width="{Math.min(100, pct)}%" > {detail}
{/snippet} {#snippet linkForm(l: { id: number; title: string; url: string; section: string } | null)}
async ({ result, update }) => { await update({ reset: !l }); if (result.type === 'success') editId = null; }} > {#if l}{/if} {#if l}{/if}
{/snippet}