feat(install): replace .zip downloads with copy-paste shell snippets

The "Install on your server" section of the home page now prints four
short shell snippets — copy-paste into a terminal, files land in CWD.
Each uses curl to fetch the relevant bootstrap files; nothing else to
install:

  1. Self-contained:    fetches the 5 current-stable tool HTMLs into CWD
                        plus a _template/ directory of level-1 stubs.
                        ~1.8 MB on disk; no runtime dependency on the
                        site after install.
  2. Track stable:      fetches 5 tiny level-2 stubs (~10 KB total)
                        that fetch zddc.varasys.io's stable channel
                        on every page load.
  3. Track beta:        same, for beta.
  4. Track alpha:       same, for alpha.

Each snippet card explains when/why to use that option directly inline.

Implementation:
  - build.sh now produces website/bootstrap/level1/<tool>.html and
    website/bootstrap/track-{alpha,beta,stable}/<tool>.html as
    standalone files (rather than packaging them into zips).
  - install.zip and track-{alpha,beta,stable}.zip are removed; the
    snippets curl the per-channel stubs directly.
  - Docs updated: README, ARCHITECTURE, CLAUDE, AGENTS, bootstrap/README,
    zddc/README, landing/build.sh comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-04-29 13:30:32 -05:00
parent 4d6e497510
commit 916e53d873
38 changed files with 1229 additions and 142 deletions

View file

@ -61,10 +61,11 @@ website/
<tool>_stable.html -> ... symlink to current stable (highest semver)
<tool>_alpha.html mutable; overwritten by --release alpha
<tool>_beta.html mutable; overwritten by --release beta
install.zip drop-in self-contained install (5 stable HTMLs + _template/ stubs)
track-stable.zip level-2 stubs that track the current-stable channel
track-alpha.zip level-2 stubs that track the alpha channel
track-beta.zip level-2 stubs that track the beta channel
bootstrap/
level1/<tool>.html same-origin level-1 stubs (4 tools, no landing)
track-stable/<tool>.html level-2 stubs that track the current-stable channel
track-alpha/<tool>.html level-2 stubs that track the alpha channel
track-beta/<tool>.html level-2 stubs that track the beta channel
bootstrap/
level1.html.tmpl per-project bootstrap template (relative ../<tool>.html)
@ -209,12 +210,14 @@ The on-page label of the freshened build is `<channel> · <today> · <stable-tag
Note: the build pipeline used is the one **at the tag**, not on `main`. That is intentional (pure reproducibility). If you have made build-system improvements since stable was cut and want the freshen to use them, cut a new stable first.
### Bootstrap zips
### Bootstrap stubs
`build.sh` regenerates three downloadable zips into `website/` on every invocation:
`build.sh` regenerates `website/bootstrap/` on every invocation:
- `install.zip` — 5 current-stable HTMLs at root + `_template/` directory containing 4 level-1 bootstrap stubs (per-project use). Skipped if any tool has no stable release yet.
- `track-{alpha,beta,stable}.zip` — 5 level-2 stubs each, hardcoded to fetch the named channel from `zddc.varasys.io/releases/`. Drop one over a deployment root to switch the whole site to that channel.
- `bootstrap/level1/<tool>.html` — 4 same-origin level-1 stubs (archive, transmittal, classifier, mdedit; landing has no level-1 stub since it only lives at deployment root).
- `bootstrap/track-{alpha,beta,stable}/<tool>.html` — 5 level-2 stubs per channel, hardcoded to fetch the named channel from `zddc.varasys.io/releases/`.
End users install via copy-paste shell snippets on the home page's "Install on your server" section — each snippet `curl`s the relevant stubs (or stable HTMLs, for the self-contained option) into the operator's deployment directory.
See `bootstrap/README.md` for the install / pin / audit story.
@ -308,4 +311,4 @@ path that fails loudly and visibly on the developer's terminal.
- Every folder exposes a `.archive` virtual directory backed by the same global index — the depth in the URL only matters so HTML produced for offline use can reach `.archive/` via `../.archive/` relative links and have the browser resolve them before the request hits the server. The flat listing emits two redirect entries per tracking number: `<tracking>.html` (highest base rev) and `<tracking>_<rev>.html` (each specific base rev). Both redirect to the first chronologically received copy of the named revision. Modifier files (`<tracking>_<rev>+C1.html` etc.) remain reachable via the resolver but are not surfaced in the listing — they're return traffic, not primary documents. ACL is the only filter: the listing endpoint is gated by the contextPath's `.zddc` chain, and each entry is then filtered against the ACL of its resolved file's directory; per-target denials return 404 rather than 403 to avoid leaking that the tracking number exists in another subtree
- ACL is enforced via cascading `.zddc` YAML files; authentication is delegated to the upstream proxy via the `X-Auth-Request-Email` header (configurable with `ZDDC_EMAIL_HEADER`)
- `.zddc` schema also supports a top-level `admins:` glob list, peer to `acl.allow`/`acl.deny`. Honored **only** at the root `.zddc` (subdir `admins` entries are ignored to prevent privilege escalation via subtree write access). Drives the built-in debug dashboard at `/.admin/` (sub-routes: `/whoami`, `/config`, `/logs`); non-admin requests get 404 so the page is invisible. See `zddc/README.md` § "Admin Debug Page".
- **Reserved entry prefixes** under `ZDDC_ROOT`: `.`-prefixed entries are excluded from listings AND 404 on direct fetch (only `.archive` and `.admin` are exempt) — for invisible side-state like dev-shell home dirs. `_`-prefixed entries are excluded from listings only — for operator scaffolding like install.zip's `_template/` that's still reachable by direct URL. Drop side-state under `_` if it should be linkable; under `.` if it should be unreachable.
- **Reserved entry prefixes** under `ZDDC_ROOT`: `.`-prefixed entries are excluded from listings AND 404 on direct fetch (only `.archive` and `.admin` are exempt) — for invisible side-state like dev-shell home dirs. `_`-prefixed entries are excluded from listings only — for operator scaffolding like the `_template/` directory created by the self-contained install snippet, still reachable by direct URL. Drop side-state under `_` if it should be linkable; under `.` if it should be unreachable.

View file

@ -43,8 +43,9 @@ website/
<tool>_stable.html -> ... # symlink to the highest-versioned stable
<tool>_alpha.html # mutable: overwritten on every --release alpha
<tool>_beta.html # mutable: overwritten on every --release beta
install.zip # current-stable HTMLs + project bootstrap stubs
track-{alpha,beta,stable}.zip # level-2 channel-tracking stubs
bootstrap/
level1/<tool>.html # same-origin stubs for project subdirectories
track-{alpha,beta,stable}/ # per-channel level-2 stubs (5 tools each)
```
There is no `website/dev/`. To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release.
@ -59,16 +60,16 @@ Each topic has exactly one authoritative home; everything else links to it.
| Topic | Single home | Linked from |
|---|---|---|
| What ZDDC is + tool channel links + dual-mode (local/server) overview + install bundles | `website/index.html` (hand-edited intro for `zddc.varasys.io/`) | repo `README.md`, `bootstrap/README.md` |
| What ZDDC is + tool channel links + dual-mode (local/server) overview + install snippets | `website/index.html` (hand-edited intro for `zddc.varasys.io/`) | repo `README.md`, `bootstrap/README.md` |
| File-naming convention spec (status codes, modifiers, folder format) | `website/reference.html` | repo `README.md`, in-tool help text |
| Versions + channel builds index of every tool | `website/releases/index.html` (regenerated by `build.sh`) | website intro nav, "Browse all versions" link |
| Customer-deployment install (install.zip, level-1/2 stubs, `?v=`, audit) | `bootstrap/README.md` | website intro, `zddc/README.md` |
| Customer-deployment install (copy-paste shell snippets, level-1/2 stubs, `?v=`, audit) | `bootstrap/README.md` | website intro, `zddc/README.md` |
| zddc-server operations: env vars, ACL syntax, `.archive` URLs, container vs binary | `zddc/README.md` | `AGENTS.md`, `bootstrap/README.md`, website intro |
| Build / release / channel commands | `AGENTS.md` | repo `README.md` ("see AGENTS.md") |
| Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` |
| Per-tool internal design quirks | `<tool>/README.md` | (linked from website intro tool cards) |
`website/index.html` is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The landing tool ships only via `website/releases/landing_v<X>.html` and `install.zip``install.zip` copies `landing_stable.html` to `<deployment-root>/index.html` for customer sites where the project picker UI is actually useful (it queries `zddc-server` for the project list). The public website at `zddc.varasys.io/` has nothing to pick, so its root URL is the introduction page.
`website/index.html` is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The landing tool ships only via `website/releases/landing_v<X>.html` — the self-contained install snippet copies `landing_stable.html` to `<deployment-root>/index.html` for customer sites where the project picker UI is actually useful (it queries `zddc-server` for the project list). The public website at `zddc.varasys.io/` has nothing to pick, so its root URL is the introduction page.
When updating documentation, prefer linking over duplicating. If you find yourself rewriting the file-naming convention in a tool's README, link to `reference.html` instead.
@ -86,7 +87,7 @@ Each tool's `build.sh`:
4. Writes the result to `dist/tool.html`
5. If `--release <channel-or-version>` was passed, calls `promote_release` to write the appropriate file under `website/releases/`
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence and then regenerates the bootstrap zips (`install.zip`, `track-{alpha,beta,stable}.zip`) so they always match what's in `releases/`.
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence and then regenerates `website/bootstrap/` (level-1 stubs and per-channel level-2 stubs) so they always match what's in `releases/`.
### Channels
@ -116,7 +117,7 @@ Customer deployments under `zddc-server` use a two-level bootstrap pattern that
`document.write()` chains across both levels; origin stays at the deployment domain throughout. CORS only matters at level 2 (cross-origin to `zddc.varasys.io`); level 1 is same-origin.
The stubs are generated from `bootstrap/level{1,2}.html.tmpl` by the root `build.sh` and packaged into `install.zip` and `track-<channel>.zip`.
The stubs are generated from `bootstrap/level{1,2}.html.tmpl` by the root `build.sh` and published as standalone files under `website/bootstrap/level1/` and `website/bootstrap/track-<channel>/`. The home page's "Install on your server" section prints copy-paste shell snippets that `curl` these into the operator's deployment directory.
### Build Script Requirements

View file

@ -18,7 +18,7 @@ This is a **monorepo of independent tools**, not one application:
- `archive/`, `transmittal/`, `classifier/`, `mdedit/`, `landing/` — five self-contained HTML tools, each compiled to a single inlined HTML file in its own `dist/`. Naming: the first four output `dist/tool.html`; **`landing/` outputs `dist/index.html`** (it's the project picker served at the root of `zddc-server`).
- `zddc/` — Go HTTP server (separate sub-project, podman/podman-compose; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list.
- `shared/``base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh`)
- `website/` — published artifacts: `index.html` (root URL), `releases/<tool>_v<X.Y.Z>.html` (immutable stable archives), `releases/<tool>_stable.html` (symlink to current stable), `releases/<tool>_{alpha,beta}.html` (mutable channel files), plus bootstrap zips (`install.zip`, `track-{alpha,beta,stable}.zip`). `--release` is the only path to publishing — there is no `website/dev/`.
- `website/` — published artifacts: `index.html` (root URL), `releases/<tool>_v<X.Y.Z>.html` (immutable stable archives), `releases/<tool>_stable.html` (symlink to current stable), `releases/<tool>_{alpha,beta}.html` (mutable channel files), and `bootstrap/{level1,track-stable,track-beta,track-alpha}/<tool>.html` (per-channel level-2 stubs + same-origin level-1 stubs that the home-page install snippets curl into the operator's deployment dir). `--release` is the only path to publishing `releases/`; `bootstrap/` is regenerated by every plain `sh build.sh`. There is no `website/dev/`.
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
## Most-used commands

View file

@ -6,7 +6,7 @@ ZDDC is an information management convention plus a small set of single-file HTM
The name "Zero Day Document Control" comes from the convention itself — adopt it on day zero of a project, with no setup time. The tools are *optional* interfaces around the structure; the structure works without them.
> **For end users**: <https://zddc.varasys.io/> introduces the project, links to all tool channels (stable / beta / alpha), and offers `install.zip` for self-hosted deployments.
> **For end users**: <https://zddc.varasys.io/> introduces the project, links to all tool channels (stable / beta / alpha), and prints copy-paste shell snippets to install on a self-hosted deployment.
## Tools

View file

@ -4,6 +4,20 @@ ZDDC tools (archive, transmittal, classifier, mdedit, landing) are single-file
HTML bundles. The bootstrap pattern lets you install once on a deployment and
update by editing a few lines, without re-uploading multi-megabyte HTML files.
End users install via a short copy-paste shell snippet from the home page's
"Install on your server" section. The snippet uses `curl` to fetch either
the current stable HTMLs (self-contained) or tiny level-2 stubs (channel
trackers) into the deployment directory. The published stubs live under
`https://zddc.varasys.io/bootstrap/`:
- `bootstrap/level1/<tool>.html` — same-origin level-1 stubs (4 tools, no
landing — landing only lives at deployment root).
- `bootstrap/track-{stable,beta,alpha}/<tool>.html` — per-channel level-2
stubs (5 tools each).
Both directories are produced by the project's top-level `build.sh` from
`bootstrap/level{1,2}.html.tmpl`.
## The two-level model
A typical `zddc-server` deployment looks like this:
@ -35,11 +49,11 @@ A typical `zddc-server` deployment looks like this:
- a level-2 bootstrap — fetches a specific channel or pinned version from
`https://zddc.varasys.io/releases/<tool>_<channel|v…>.html`.
The site administrator switches the whole site to a channel by replacing
the file at `<ZDDC_ROOT>/<tool>.html` with the matching level-2 stub from
`track-<channel>.zip`. A single project can override one tool by editing
just `<project-X>/<tool>.html` (replace the relative `upstream` URL with an
absolute zddc.varasys.io URL).
The site administrator switches the whole site to a channel by re-running
the `track-<channel>` install snippet from the home page — that overwrites
the root `<tool>.html` files with the matching level-2 stubs. A single
project can override one tool by editing just `<project-X>/<tool>.html`
(replace the relative `upstream` URL with an absolute zddc.varasys.io URL).
## Why two levels
@ -121,5 +135,6 @@ Level-1 fetches are same-origin so no CORS is involved.
`level1.html.tmpl` and `level2.html.tmpl` are the source of truth. The
project's top-level `build.sh` substitutes `{{TOOL}}`, `{{TOOL_TITLE}}`,
and `{{CHANNEL}}` to produce the per-tool stubs that ship in
`install.zip` and `track-<channel>.zip`.
`{{CHANNEL}}`, and `{{FAVICON}}` to produce the per-tool stubs published
under `website/bootstrap/level1/` and `website/bootstrap/track-<channel>/`,
which the install snippets curl from `https://zddc.varasys.io/bootstrap/`.

103
build.sh
View file

@ -2,7 +2,7 @@
set -eu
# Top-level build script — builds all ZDDC HTML tools, the zddc-server
# binaries, and the downloadable bundles (install.zip and track-*.zip).
# binaries, and the bootstrap stubs published under website/bootstrap/.
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
@ -42,19 +42,18 @@ else
echo " release path builds its own copy via Containerfile.)"
fi
# ─── Bootstrap zips ──────────────────────────────────────────────────────────
# Generated from bootstrap/level{1,2}.html.tmpl on every build so they are
# always in sync with the current bootstrap pattern.
# ─── Bootstrap stubs ─────────────────────────────────────────────────────────
# Generated from bootstrap/level{1,2}.html.tmpl on every build and published
# as standalone files under website/bootstrap/. The website's "Install on
# your server" section prints copy-pasteable shell snippets that curl these
# files into the operator's deployment directory.
#
# install.zip — drop into deployment root for self-contained install.
# Contains the 5 current-stable HTMLs at root plus a
# _template/ directory with 4 level-1 stubs that
# projects can use as their starting layout.
# track-<channel>.zip — drop the level-2 stubs over deployment root to make
# the whole site track <channel> from zddc.varasys.io.
#
# install.zip needs at least one stable release to exist under
# website/releases/; if none exist yet, that zip is skipped with a warning.
# bootstrap/level1/<tool>.html — same-origin stubs for
# <project>/<tool>.html (4 tools;
# landing only lives at root)
# bootstrap/track-<channel>/<tool>.html — level-2 stubs that fetch the
# named channel from upstream
# (5 tools × 3 channels = 15)
WEBSITE_DIR="$SCRIPT_DIR/website"
RELEASES_DIR="$WEBSITE_DIR/releases"
@ -84,61 +83,37 @@ render_stub() {
"$1" > "$5"
}
build_install_zip() {
# Verify a stable release exists for every tool before staging.
_missing=""
while IFS='|' read -r _tool _file _title; do
[ -e "$RELEASES_DIR/${_tool}_stable.html" ] || _missing="$_missing $_tool"
done <<EOF
$TOOL_TABLE
EOF
build_bootstrap_stubs() {
_stubs="$WEBSITE_DIR/bootstrap"
rm -rf "$_stubs"
mkdir -p "$_stubs/level1"
if [ -n "$_missing" ]; then
echo "Skipping install.zip — no stable release for:$_missing"
return 0
fi
_staging=$(mktemp -d)
# Level-1 stubs (same-origin, channel-agnostic). Drop into a project
# subdirectory so <project>/<tool>.html fetches ../<tool>.html.
# Landing has no level-1 stub — landing only lives at deployment root.
while IFS='|' read -r _tool _file _title; do
cp "$RELEASES_DIR/${_tool}_stable.html" "$_staging/$_file"
done <<EOF
$TOOL_TABLE
EOF
# _template/ holds level-1 bootstraps for the four interactive tools
# (landing only lives at deployment root; project directories do not
# have their own landing page).
mkdir -p "$_staging/_template"
while IFS='|' read -r _tool _file _title; do
render_stub "$BOOTSTRAP_DIR/level1.html.tmpl" "$_tool" "$_title" "" "$_staging/_template/$_file"
render_stub "$BOOTSTRAP_DIR/level1.html.tmpl" "$_tool" "$_title" "" \
"$_stubs/level1/$_file"
done <<EOF
archive|archive.html|Archive
transmittal|transmittal.html|Transmittal
classifier|classifier.html|Classifier
mdedit|mdedit.html|Markdown Editor
EOF
echo "Wrote $_stubs/level1/{archive,transmittal,classifier,mdedit}.html"
cp "$BOOTSTRAP_DIR/README.md" "$_staging/README.md"
rm -f "$WEBSITE_DIR/install.zip"
(cd "$_staging" && zip -qr "$WEBSITE_DIR/install.zip" .)
echo "Wrote $WEBSITE_DIR/install.zip"
rm -rf "$_staging"
}
build_track_zip() {
_channel="$1"
_staging=$(mktemp -d)
# Level-2 stubs, one set per channel. Each fetches its named channel
# from upstream on every page load.
for _channel in alpha beta stable; do
mkdir -p "$_stubs/track-$_channel"
while IFS='|' read -r _tool _file _title; do
render_stub "$BOOTSTRAP_DIR/level2.html.tmpl" "$_tool" "$_title" "$_channel" "$_staging/$_file"
render_stub "$BOOTSTRAP_DIR/level2.html.tmpl" "$_tool" "$_title" "$_channel" \
"$_stubs/track-$_channel/$_file"
done <<EOF
$TOOL_TABLE
EOF
rm -f "$WEBSITE_DIR/track-$_channel.zip"
(cd "$_staging" && zip -qr "$WEBSITE_DIR/track-$_channel.zip" .)
echo "Wrote $WEBSITE_DIR/track-$_channel.zip"
rm -rf "$_staging"
echo "Wrote $_stubs/track-$_channel/ (5 stubs)"
done
}
# Regenerate website/releases/index.html — a static directory listing of
@ -246,11 +221,8 @@ TAIL
}
echo ""
echo "=== Building install.zip, track-*.zip, releases/index.html ==="
build_install_zip
build_track_zip alpha
build_track_zip beta
build_track_zip stable
echo "=== Building bootstrap stubs and releases/index.html ==="
build_bootstrap_stubs
build_releases_index
echo ""
@ -260,8 +232,9 @@ echo "Server deployment package: zddc/dist/"
echo " Binaries: zddc-server-{linux,darwin,windows}-*"
echo " Web files: web/ (copy contents to ZDDC_ROOT)"
echo ""
echo "Bootstrap downloads: website/"
echo " install.zip — self-contained install for deployment root"
echo " track-alpha.zip — level-2 stubs that track the alpha channel"
echo " track-beta.zip — level-2 stubs that track the beta channel"
echo " track-stable.zip — level-2 stubs that track the stable channel"
echo "Bootstrap stubs: website/bootstrap/"
echo " level1/<tool>.html — same-origin stubs for project subdirs"
echo " track-{alpha,beta,stable}/ — level-2 stubs for each channel"
echo ""
echo "The home page's 'Install on your server' section prints copy-pasteable"
echo "shell snippets that curl these files into the operator's deployment dir."

View file

@ -72,10 +72,11 @@ if [ "$is_release" = "1" ]; then
promote_release "landing"
# NOTE: website/index.html is a hand-edited intro page for
# zddc.varasys.io, not the landing tool. The landing tool ships
# only via website/releases/ and install.zip — install.zip puts
# landing_stable.html at the customer deployment root, where the
# project picker UI is useful (it queries zddc-server for the
# project list). See AGENTS.md "Releasing — channels and layout".
# only via website/releases/ — the self-contained install snippet
# on the home page copies landing_stable.html to <deployment-root>/
# index.html, where the project picker UI is useful (it queries
# zddc-server for the project list). See AGENTS.md "Releasing —
# channels and layout".
else
update_alpha "landing"
fi

View file

@ -0,0 +1,74 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Archive…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-1 bootstrap. Fetches the tool from the deployment root (same
// origin) and document.write()s it in place. The target may be the real
// built tool HTML or a level-2 bootstrap that fetches from upstream.
//
// URL parameter ?v= selects a specific version or channel:
// ?v=0.0.4 (or v0.0.4) tries ../archive_v0.0.4.html locally
// ?v=alpha|beta|stable tries ../archive_<channel>.html locally
// (none) fetches ../archive.html (default)
//
// If the requested version is not staged locally, falls back to the
// root entry (../archive.html) — which, if it is a level-2 stub,
// forwards the param upstream to zddc.varasys.io. So ?v=0.0.4 works
// whether admins staged it locally OR a level-2 stub is at root.
//
// To pin this single tool to a fixed version permanently, replace the
// `fallback` constant below with an absolute URL like
// https://zddc.varasys.io/releases/archive_v0.0.4.html.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'archive';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '';
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const versioned = '../' + tool + suffixFor(v) + '.html';
const fallback = '../' + tool + '.html';
async function fetchHTML(url) {
const resp = await fetch(url, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
return resp.text();
}
try {
let html;
if (v && versioned !== fallback) {
try {
html = await fetchHTML(versioned);
} catch (_) {
// Versioned copy not staged locally — let the root entry forward
// the request (level-2 stub will see ?v= and fetch upstream).
html = await fetchHTML(fallback);
}
} else {
html = await fetchHTML(fallback);
}
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load Archive: ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,74 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Classifier…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-1 bootstrap. Fetches the tool from the deployment root (same
// origin) and document.write()s it in place. The target may be the real
// built tool HTML or a level-2 bootstrap that fetches from upstream.
//
// URL parameter ?v= selects a specific version or channel:
// ?v=0.0.4 (or v0.0.4) tries ../classifier_v0.0.4.html locally
// ?v=alpha|beta|stable tries ../classifier_<channel>.html locally
// (none) fetches ../classifier.html (default)
//
// If the requested version is not staged locally, falls back to the
// root entry (../classifier.html) — which, if it is a level-2 stub,
// forwards the param upstream to zddc.varasys.io. So ?v=0.0.4 works
// whether admins staged it locally OR a level-2 stub is at root.
//
// To pin this single tool to a fixed version permanently, replace the
// `fallback` constant below with an absolute URL like
// https://zddc.varasys.io/releases/classifier_v0.0.4.html.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'classifier';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '';
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const versioned = '../' + tool + suffixFor(v) + '.html';
const fallback = '../' + tool + '.html';
async function fetchHTML(url) {
const resp = await fetch(url, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
return resp.text();
}
try {
let html;
if (v && versioned !== fallback) {
try {
html = await fetchHTML(versioned);
} catch (_) {
// Versioned copy not staged locally — let the root entry forward
// the request (level-2 stub will see ?v= and fetch upstream).
html = await fetchHTML(fallback);
}
} else {
html = await fetchHTML(fallback);
}
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load Classifier: ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,74 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Markdown Editor…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-1 bootstrap. Fetches the tool from the deployment root (same
// origin) and document.write()s it in place. The target may be the real
// built tool HTML or a level-2 bootstrap that fetches from upstream.
//
// URL parameter ?v= selects a specific version or channel:
// ?v=0.0.4 (or v0.0.4) tries ../mdedit_v0.0.4.html locally
// ?v=alpha|beta|stable tries ../mdedit_<channel>.html locally
// (none) fetches ../mdedit.html (default)
//
// If the requested version is not staged locally, falls back to the
// root entry (../mdedit.html) — which, if it is a level-2 stub,
// forwards the param upstream to zddc.varasys.io. So ?v=0.0.4 works
// whether admins staged it locally OR a level-2 stub is at root.
//
// To pin this single tool to a fixed version permanently, replace the
// `fallback` constant below with an absolute URL like
// https://zddc.varasys.io/releases/mdedit_v0.0.4.html.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'mdedit';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '';
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const versioned = '../' + tool + suffixFor(v) + '.html';
const fallback = '../' + tool + '.html';
async function fetchHTML(url) {
const resp = await fetch(url, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
return resp.text();
}
try {
let html;
if (v && versioned !== fallback) {
try {
html = await fetchHTML(versioned);
} catch (_) {
// Versioned copy not staged locally — let the root entry forward
// the request (level-2 stub will see ?v= and fetch upstream).
html = await fetchHTML(fallback);
}
} else {
html = await fetchHTML(fallback);
}
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load Markdown Editor: ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,74 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Transmittal…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-1 bootstrap. Fetches the tool from the deployment root (same
// origin) and document.write()s it in place. The target may be the real
// built tool HTML or a level-2 bootstrap that fetches from upstream.
//
// URL parameter ?v= selects a specific version or channel:
// ?v=0.0.4 (or v0.0.4) tries ../transmittal_v0.0.4.html locally
// ?v=alpha|beta|stable tries ../transmittal_<channel>.html locally
// (none) fetches ../transmittal.html (default)
//
// If the requested version is not staged locally, falls back to the
// root entry (../transmittal.html) — which, if it is a level-2 stub,
// forwards the param upstream to zddc.varasys.io. So ?v=0.0.4 works
// whether admins staged it locally OR a level-2 stub is at root.
//
// To pin this single tool to a fixed version permanently, replace the
// `fallback` constant below with an absolute URL like
// https://zddc.varasys.io/releases/transmittal_v0.0.4.html.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'transmittal';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '';
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const versioned = '../' + tool + suffixFor(v) + '.html';
const fallback = '../' + tool + '.html';
async function fetchHTML(url) {
const resp = await fetch(url, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
return resp.text();
}
try {
let html;
if (v && versioned !== fallback) {
try {
html = await fetchHTML(versioned);
} catch (_) {
// Versioned copy not staged locally — let the root entry forward
// the request (level-2 stub will see ?v= and fetch upstream).
html = await fetchHTML(fallback);
}
} else {
html = await fetchHTML(fallback);
}
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load Transmittal: ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Archive…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches archive from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// alpha channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the alpha default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'archive';
const defaultChannel = 'alpha';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Classifier…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches classifier from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// alpha channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the alpha default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'classifier';
const defaultChannel = 'alpha';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading ZDDC…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches landing from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// alpha channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the alpha default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'landing';
const defaultChannel = 'alpha';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Markdown Editor…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches mdedit from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// alpha channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the alpha default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'mdedit';
const defaultChannel = 'alpha';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Transmittal…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches transmittal from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// alpha channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the alpha default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'transmittal';
const defaultChannel = 'alpha';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Archive…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches archive from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// beta channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the beta default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'archive';
const defaultChannel = 'beta';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Classifier…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches classifier from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// beta channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the beta default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'classifier';
const defaultChannel = 'beta';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading ZDDC…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches landing from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// beta channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the beta default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'landing';
const defaultChannel = 'beta';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Markdown Editor…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches mdedit from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// beta channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the beta default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'mdedit';
const defaultChannel = 'beta';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Transmittal…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches transmittal from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// beta channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the beta default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'transmittal';
const defaultChannel = 'beta';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Archive…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches archive from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// stable channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the stable default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'archive';
const defaultChannel = 'stable';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Classifier…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches classifier from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// stable channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the stable default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'classifier';
const defaultChannel = 'stable';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading ZDDC…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches landing from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// stable channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the stable default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'landing';
const defaultChannel = 'stable';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Markdown Editor…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches mdedit from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// stable channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the stable default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'mdedit';
const defaultChannel = 'stable';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Loading Transmittal…</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+CiAgPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMxZTNhNWYiLz4KICA8ZyBmaWxsPSIjZmZmIj4KICAgIDxyZWN0IHg9IjE0IiB5PSIxOCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iNDMsMjUgNTAsMjUgMjEsNDMgMTQsNDMiLz4KICAgIDxyZWN0IHg9IjE0IiB5PSI0MyIgd2lkdGg9IjM2IiBoZWlnaHQ9IjciLz4KICA8L2c+Cjwvc3ZnPgo=">
<style>html,body{margin:0;font:14px system-ui,sans-serif;color:#666;padding:1rem}</style>
</head>
<body>
Loading…
<script>
// Level-2 bootstrap. Fetches transmittal from zddc.varasys.io and
// document.write()s it in place. The default upstream is the
// stable channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the stable default
//
// Requires zddc.varasys.io to serve Access-Control-Allow-Origin: *.
(async function () {
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = 'transmittal';
const defaultChannel = 'stable';
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;
if (value in channels) return channels[value];
const ver = value.startsWith('v') ? value.slice(1) : value;
return '_v' + ver;
}
const upstream = 'https://zddc.varasys.io/releases/' + tool + suffixFor(v) + '.html';
try {
const resp = await fetch(upstream, { cache: 'no-cache', credentials: 'omit' });
if (!resp.ok) throw new Error(resp.status + ' ' + resp.statusText);
const html = await resp.text();
document.open();
document.write(html);
document.close();
} catch (err) {
document.body.textContent = 'Failed to load from ' + upstream + ': ' + err.message;
}
})();
</script>
</body>
</html>

View file

@ -21,9 +21,11 @@
.channel-row .channel-stable { border-color: var(--color-primary); color: var(--color-primary); font-weight: 600; }
.channel-row .channel-beta, .channel-row .channel-alpha { color: var(--color-text-muted); }
.install-grid { display: grid; grid-template-columns: 1fr; gap: var(--spacing-md); margin-top: var(--spacing-md); }
@media (min-width: 720px) { .install-grid { grid-template-columns: repeat(2, 1fr); } }
.install-card { padding: var(--spacing-md); border: 1px solid var(--color-border); border-radius: 8px; background: var(--color-bg-subtle); }
.install-card h3 { margin-top: 0; }
.install-card h3 { margin-top: 0; margin-bottom: 0.25rem; }
.install-card .when { color: var(--color-text-muted); font-size: 0.92em; margin: 0.1rem 0 0.6rem 0; }
.install-card pre { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 6px; padding: 0.6rem 0.8rem; overflow-x: auto; font-size: 0.82em; line-height: 1.45; margin: 0; }
.install-card pre code { font-family: "SF Mono", Menlo, Consolas, monospace; }
.mode-grid { display: grid; grid-template-columns: 1fr; gap: var(--spacing-md); margin-top: var(--spacing-md); }
@media (min-width: 720px) { .mode-grid { grid-template-columns: 1fr 1fr; } }
.mode-card { padding: var(--spacing-md); border: 1px solid var(--color-border); border-radius: 8px; }
@ -181,32 +183,53 @@
<section style="margin-top: var(--spacing-2xl);">
<h2>Install on your server</h2>
<p>For a self-contained deployment with no dependency on this site at runtime, download <a href="install.zip"><code class="inline">install.zip</code></a> and extract it into the document root of your file server. To make a deployment auto-track a published channel from this site, use one of the <code class="inline">track-*.zip</code> bundles instead — each contains five tiny bootstrap stubs that fetch the named channel on every page load.</p>
<p>Each option below is a short shell snippet. <code class="inline">cd</code> into your deployment directory, copy-paste one of the four blocks into your terminal, and the files land in CWD. All four use <code class="inline">curl</code>; nothing else to install.</p>
<div class="install-grid">
<div class="install-card">
<h3>Self-contained</h3>
<p>Bundled stable tools + sample project bootstrap directory. No external dependencies after install.</p>
<p><a href="install.zip">install.zip →</a></p>
<h3>Self-contained install</h3>
<p class="when"><strong>Use when:</strong> you want a deployment that does not depend on <code class="inline">zddc.varasys.io</code> after install. Downloads the five current-stable tool HTMLs (~1.8 MB total) plus a <code class="inline">_template/</code> directory with level-1 stubs to copy into project subdirectories. Re-run to update.</p>
<pre><code>set -eu
B=https://zddc.varasys.io
for t in archive transmittal classifier mdedit; do
curl -fsSL "$B/releases/${t}_stable.html" -o "${t}.html"
done
curl -fsSL "$B/releases/landing_stable.html" -o index.html
mkdir -p _template
for t in archive transmittal classifier mdedit; do
curl -fsSL "$B/bootstrap/level1/${t}.html" -o "_template/${t}.html"
done</code></pre>
</div>
<div class="install-card">
<h3>Track stable</h3>
<p>Five level-2 bootstrap stubs. Drop over the deployment root to auto-track latest stable.</p>
<p><a href="track-stable.zip">track-stable.zip →</a></p>
<h3>Track <span style="color: var(--color-primary);">stable</span> channel</h3>
<p class="when"><strong>Use when:</strong> you want auto-updates whenever stable advances. Installs five tiny stubs (~10 KB total) that fetch <code class="inline">zddc.varasys.io</code> on every page load — visitors need network access. Switch channels later by re-running with <code class="inline">track-beta</code> or <code class="inline">track-alpha</code>.</p>
<pre><code>set -eu
B=https://zddc.varasys.io/bootstrap/track-stable
for f in archive transmittal classifier mdedit index; do
curl -fsSL "$B/${f}.html" -o "${f}.html"
done</code></pre>
</div>
<div class="install-card">
<h3>Track beta</h3>
<p>Five level-2 bootstrap stubs that fetch the beta channel.</p>
<p><a href="track-beta.zip">track-beta.zip →</a></p>
<h3>Track beta channel</h3>
<p class="when"><strong>Use when:</strong> you want to soak the next release before it goes stable. Same shape as the stable tracker, fetching the <code class="inline">beta</code> channel. Beta is overwritten in place; expect occasional updates.</p>
<pre><code>set -eu
B=https://zddc.varasys.io/bootstrap/track-beta
for f in archive transmittal classifier mdedit index; do
curl -fsSL "$B/${f}.html" -o "${f}.html"
done</code></pre>
</div>
<div class="install-card">
<h3>Track alpha</h3>
<p>Five level-2 bootstrap stubs that fetch the alpha channel.</p>
<p><a href="track-alpha.zip">track-alpha.zip →</a></p>
<h3>Track alpha channel</h3>
<p class="when"><strong>Use when:</strong> you want bleeding-edge work. Alpha is rebuilt without notice, sometimes daily, and may break — fine for a personal sandbox or to verify a fix you're tracking, not for shared deployments.</p>
<pre><code>set -eu
B=https://zddc.varasys.io/bootstrap/track-alpha
for f in archive transmittal classifier mdedit index; do
curl -fsSL "$B/${f}.html" -o "${f}.html"
done</code></pre>
</div>
</div>
<p style="margin-top: var(--spacing-md);">See <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/bootstrap/README.md">bootstrap/README.md</a> for the install model, the per-project / per-tool override pattern, and the audit grep that lets you see what every project on a deployment is pointing at.</p>
<p style="margin-top: var(--spacing-md);">See <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/bootstrap/README.md">bootstrap/README.md</a> for the level-1 / level-2 model, the per-project / per-tool override pattern, and the audit grep that lets you see what every project on a deployment is pointing at.</p>
</section>
<section style="margin-top: var(--spacing-2xl);">

Binary file not shown.

View file

@ -2095,7 +2095,7 @@ td[data-field="trackingNumber"] {
<div class="header-left">
<div class="header-title-group">
<span class="app-header__title">ZDDC Archive</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 · c95f079</span></span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 18:29:14 · 4d6e497-dirty</span></span>
</div>
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;"></button>

View file

@ -1358,7 +1358,7 @@ body.help-open .app-header {
<div class="header-left">
<div class="header-title-group">
<span class="app-header__title">ZDDC Classifier</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 · c95f079</span></span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 18:29:14 · 4d6e497-dirty</span></span>
</div>
<button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button>
<button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory">Refresh</button>

View file

@ -57,9 +57,10 @@
<a class="alpha" href="archive_alpha.html">alpha</a>
</div>
<div class="rel-versions"><strong>Pin to version:</strong>
<a href="archive_v0.0.2.html">v0.0.2</a>
<a href="archive_v0.0.1.html">v0.0.1</a>
</div>
<div class="rel-meta">stable currently → archive_v0.0.1.html</div>
<div class="rel-meta">stable currently → archive_v0.0.2.html</div>
</section>
<section class="rel-tool">
<h2>Transmittal</h2>
@ -69,9 +70,10 @@
<a class="alpha" href="transmittal_alpha.html">alpha</a>
</div>
<div class="rel-versions"><strong>Pin to version:</strong>
<a href="transmittal_v0.0.2.html">v0.0.2</a>
<a href="transmittal_v0.0.1.html">v0.0.1</a>
</div>
<div class="rel-meta">stable currently → transmittal_v0.0.1.html</div>
<div class="rel-meta">stable currently → transmittal_v0.0.2.html</div>
</section>
<section class="rel-tool">
<h2>Classifier</h2>
@ -81,9 +83,10 @@
<a class="alpha" href="classifier_alpha.html">alpha</a>
</div>
<div class="rel-versions"><strong>Pin to version:</strong>
<a href="classifier_v0.0.2.html">v0.0.2</a>
<a href="classifier_v0.0.1.html">v0.0.1</a>
</div>
<div class="rel-meta">stable currently → classifier_v0.0.1.html</div>
<div class="rel-meta">stable currently → classifier_v0.0.2.html</div>
</section>
<section class="rel-tool">
<h2>Markdown Editor</h2>
@ -93,9 +96,10 @@
<a class="alpha" href="mdedit_alpha.html">alpha</a>
</div>
<div class="rel-versions"><strong>Pin to version:</strong>
<a href="mdedit_v0.0.2.html">v0.0.2</a>
<a href="mdedit_v0.0.1.html">v0.0.1</a>
</div>
<div class="rel-meta">stable currently → mdedit_v0.0.1.html</div>
<div class="rel-meta">stable currently → mdedit_v0.0.2.html</div>
</section>
<section class="rel-tool">
<h2>ZDDC</h2>
@ -105,9 +109,10 @@
<a class="alpha" href="landing_alpha.html">alpha</a>
</div>
<div class="rel-versions"><strong>Pin to version:</strong>
<a href="landing_v0.0.2.html">v0.0.2</a>
<a href="landing_v0.0.1.html">v0.0.1</a>
</div>
<div class="rel-meta">stable currently → landing_v0.0.1.html</div>
<div class="rel-meta">stable currently → landing_v0.0.2.html</div>
</section>
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">

View file

@ -884,7 +884,7 @@ body {
<header class="app-header">
<div class="header-left">
<span class="app-header__title">ZDDC Archive</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 · c95f079</span></span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 18:29:14 · 4d6e497-dirty</span></span>
</div>
<div class="header-right">
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)"></button>

View file

@ -1650,7 +1650,7 @@ body.help-open .app-header {
<div class="header-left">
<div class="header-title-group">
<span class="app-header__title">ZDDC Markdown</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 · c95f079</span></span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 18:29:14 · 4d6e497-dirty</span></span>
</div>
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
</div>

View file

@ -2192,7 +2192,7 @@ dialog.modal--narrow {
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
<div class="header-title-group">
<span class="app-header__title">ZDDC Transmittal</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 · c95f079</span></span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">alpha · 2026-04-29 18:29:14 · 4d6e497-dirty</span></span>
</div>
<div class="app-header__spacer"></div>
<div class="app-header__icons">

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -173,9 +173,10 @@ Two prefixes are filtered from listings under `ZDDC_ROOT`:
side-state (caches, dev-shell home dirs, snapshot staging) on the same volume
that's served, without exposing it.
- **`_`-prefixed** (e.g. `/_template/`) — excluded from listings only. Direct URL
access still works, so install.zip's `_template/` directory of bootstrap stubs
is reachable but doesn't clutter the project picker. Use this for operator-
managed scaffolding the user shouldn't browse to but might link to.
access still works, so the `_template/` directory of bootstrap stubs created
by the install snippet is reachable but doesn't clutter the project picker.
Use this for operator-managed scaffolding the user shouldn't browse to but
might link to.
## Admin Debug Page
@ -229,17 +230,27 @@ callers.
## Landing Page and Tool Install
The recommended install drops `install.zip` (downloaded from
`https://zddc.varasys.io/install.zip`) into `ZDDC_ROOT/`:
The recommended install is a short shell snippet copy-pasted from the
"Install on your server" section of `https://zddc.varasys.io/`. There
are four snippets, all of which `cd`-and-curl into `ZDDC_ROOT/`:
- **Self-contained** — fetches the five current-stable tool HTMLs and
populates a `_template/` directory of level-1 bootstrap stubs. No
runtime dependency on `zddc.varasys.io`. Re-run to update.
- **Track stable / beta / alpha** — fetches five tiny level-2 stubs
(~10 KB total) that fetch the named channel from `zddc.varasys.io`
on every page load.
After running one of the snippets, the deployment looks like:
```
ZDDC_ROOT/
index.html ← landing page (current stable)
archive.html ← archive browser
index.html ← landing page (current stable, or level-2 stub)
archive.html ← archive browser (likewise)
transmittal.html
classifier.html
mdedit.html
_template/ ← template directory of level-1 bootstrap stubs;
_template/ ← level-1 bootstrap stubs (self-contained snippet only);
rename a copy to <project-name>/ for each project
Project-001/
archive.html ← level-1 stub: fetches ../archive.html
@ -250,16 +261,10 @@ ZDDC_ROOT/
```
This is fully self-contained — no external dependencies. To make the
deployment auto-track a published channel from `zddc.varasys.io`, drop
`track-alpha.zip` / `track-beta.zip` / `track-stable.zip` (also at
`https://zddc.varasys.io/`) over `ZDDC_ROOT/`: those replace the root
`<tool>.html` files with level-2 bootstrap stubs that fetch the named
channel from `zddc.varasys.io` on each page load. See
The level-2 stubs require `zddc-server` to accept cross-origin requests
from `zddc.varasys.io`, controlled via `ZDDC_CORS_ORIGIN`. See
[`bootstrap/README.md`](../bootstrap/README.md) for the full install
guide, the `?v=…` URL parameter for per-request version selection, and
the `ZDDC_CORS_ORIGIN` env var that lets `zddc-server` accept
cross-origin calls from the level-2 source.
guide and the `?v=…` URL parameter for per-request version selection.
The landing page fetches `GET /` (with `Accept: application/json`) to retrieve the list
of top-level project directories the requesting user has access to. It renders checkboxes
@ -352,9 +357,9 @@ returns JSON directory listings in exactly the same format as Caddy's `file-serv
— no changes to `archive/js/source.js` are needed.
To use: install `archive.html` at `ZDDC_ROOT/archive.html` (or any subdirectory) — either
the actual built tool from `install.zip`, or a level-1/level-2 bootstrap stub that fetches
it. Then open it via the zddc-server URL; the app will auto-connect and scan the directory
tree.
the actual built tool fetched by the self-contained install snippet, or a
level-1/level-2 bootstrap stub that fetches it. Then open it via the zddc-server URL;
the app will auto-connect and scan the directory tree.
## Container image