#!/usr/bin/env python3 """Muse Tour de Force — HTML renderer. Takes the structured TourData dict produced by tour_de_force.py and renders a self-contained, shareable HTML file with an interactive D3 commit DAG, operation log, architecture diagram, and animated replay. Stand-alone usage ----------------- python tools/render_html.py artifacts/tour_de_force.json python tools/render_html.py artifacts/tour_de_force.json --out custom.html """ from __future__ import annotations import json import pathlib import sys import urllib.request # --------------------------------------------------------------------------- # D3.js fetcher # --------------------------------------------------------------------------- _D3_CDN = "https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js" _D3_FALLBACK = f'' def _fetch_d3() -> str: """Download D3.js v7 minified. Returns the source or a CDN script tag.""" try: with urllib.request.urlopen(_D3_CDN, timeout=15) as resp: src = resp.read().decode("utf-8") print(f" ↓ D3.js fetched ({len(src)//1024}KB)") return f"" except Exception as exc: print(f" ⚠ Could not fetch D3 ({exc}); using CDN link in HTML") return _D3_FALLBACK # --------------------------------------------------------------------------- # Architecture SVG # --------------------------------------------------------------------------- _ARCH_HTML = """\