The HTML report was entirely JavaScript-driven — stats/sidebar/messages only
populated from an embedded JSON blob after load. Viewers that don't execute
scripts (or block network access for local files) showed a blank 0/0/0
skeleton even though the purge worked correctly. Now every stat, the channel
list, and every message are rendered directly into the HTML by Python; JS is
only a progressive enhancement for search. Avatar is downloaded and embedded
as a base64 data URI instead of a live CDN link, so it always renders. Also
parallelized archived-thread lookups, skip the rate-limit pause on channels
with nothing to delete, and post an immediate placeholder log message that
gets edited with the final results instead of the channel sitting silent.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>