#!/usr/bin/env python3 """Build a self-contained HTML artifact for sandboxed Gallery viewers.""" from __future__ import annotations import base64 import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SITE = ROOT / "prototype" / "site" DEFAULT_OUTPUT = ROOT / "prototype" / "gallery" / "aetherbound-guild-prototype.html" def data_uri(path: Path) -> str: mime = "image/webp" if path.suffix == ".webp" else "application/octet-stream" encoded = base64.b64encode(path.read_bytes()).decode("ascii") return f"data:{mime};base64,{encoded}" def main() -> None: index = (SITE / "index.html").read_text(encoding="utf-8") styles = (SITE / "styles.css").read_text(encoding="utf-8") app = (SITE / "app.js").read_text(encoding="utf-8") catalog = json.loads((SITE / "data" / "catalog.json").read_text(encoding="utf-8")) asset_paths = sorted((SITE / "assets" / "web").glob("*.webp")) asset_paths.append(SITE / "favicon.webp") for path in asset_paths: relative = path.relative_to(SITE).as_posix() uri = data_uri(path) index = index.replace(relative, uri) app = app.replace(relative, uri) catalog_json = json.dumps(catalog, ensure_ascii=False, separators=(",", ":")) catalog_json = catalog_json.replace("<", "\\u003c") app = app.replace("', f"", ) index = index.replace( '', f'\n' f"", ) if 'href="styles.css"' in index or 'src="app.js"' in index: raise RuntimeError("external stylesheet or script remains in bundle") if "assets/web/" in index: raise RuntimeError("external prototype asset remains in bundle") DEFAULT_OUTPUT.parent.mkdir(parents=True, exist_ok=True) DEFAULT_OUTPUT.write_text(index, encoding="utf-8") print(f"ABG_GALLERY_BUNDLE_OK bytes={DEFAULT_OUTPUT.stat().st_size} output={DEFAULT_OUTPUT}") if __name__ == "__main__": main()