A minimal Cloudflare Worker that serves a small suite of browser tools.
-
Markdown Preview (
/markdown)- GitHub-flavored Markdown via
marked. - MathJax for inline
$...$and block$$...$$. - Sanitized output with
DOMPurify. - Dual-pane editor/preview, theme toggle with persistence.
- Tabs with rename/new/delete stored in
localStorage. - Syntax highlighting via Highlight.js (full build) with language alias normalization and dark/light theme swapping.
- Copy rendered HTML to clipboard.
- GitHub-flavored Markdown via
-
Euler Preview (
/euler)- Preview Project Euler forum posts (BBCode + TeX).
- Supported tags include
[b] [i] [s] [sup] [sub] [url] [img] [quote] [collapse] [list] [*] [hide] [r] [g] [h1] [h2] [center] [right]. - Code blocks:
[code]...[/code]or[code=lang]...[/code]with options*to disable highlight and?to force auto-detect (e.g.[code=js],[code=py*],[code=?]). - MathJax for
$...$and$$...$$. - Tabs with rename/new/delete stored in
localStorage. - Syntax highlighting via Highlight.js with language alias normalization and dark/light theme swapping.
-
Pastebin (
/pastebin)- Create and share text snippets.
- Visibility options:
public(listed) orunlisted(hidden from lists, accessible by link). - Auth via Google OAuth; stores users, sessions, and pastes in Cloudflare D1.
- Not signed in or not allowed: pastes are saved in your browser’s localStorage (local mode). Local pastes are only visible in that browser/device; you can open them via
#local=<id>in the URL. - Public listing at
/pastebinshows recent public pastes; your pastes appear after sign-in. - Direct links like
/pastebin/p/abcd1234open a read-only view.
-
LLM Cost Calculator (
/llm-cost)- Paste token usage dumps (supports cached and reasoning tokens) and see per-run totals.
- Enter pricing per token, per 1K, or per 1M for input, cached input, output, and reasoning tokens.
- Save multiple model pricing profiles locally (seeded with popular models; update the placeholders to match current rates).
-
Actuary Calculator (
/actuary)- Enter ages with gender suffixes (e.g.
63m 75f) and an optional horizon in years or an absolute year. - Uses the XKCD
actuary.pySocial Security actuarial tables to compute the years until 5/50/95% odds that someone (or everyone) dies. - Shows probability of a death within the requested window plus per-person probabilities for the horizon.
- Enter ages with gender suffixes (e.g.
-
TIFF Viewer (
/tiff-viewer)- Load TIFFs from file or base64 (data URL or raw) and decode locally using bundled
UTIF.js(no external CDN dependency). - Toggle channels on/off and assign per-channel colors; supports planar and interleaved layouts with automatic channel count detection.
- Zoom controls (in/out buttons, slider, Fit width) with default fit-to-width scaling; viewer scrolls when the image exceeds the viewport.
- Load TIFFs from file or base64 (data URL or raw) and decode locally using bundled
-
YouTube Transcript (
/yt-transcript)- Fetch transcripts for public videos with optional translation by language code when available.
- View normalized segments alongside the full transcript text, toggle timestamps, and copy the result.
- Persist last-used URL/language and theme preference locally.
All tools include a Home button in the header to return to /.
/— Tools index page with tiles./markdown— Markdown Preview./euler— Euler Preview (Project Euler forum flavor)./pastebin— Pastebin UI (create, list, login)./pastebin/p/:id— View a specific paste (public or unlisted)./llm-cost— LLM Cost Calculator./actuary— Actuary Calculator./tiff-viewer— Multi-channel TIFF viewer (local UTIF decode, channel mixing, zoom)./yt-transcript— YouTube Transcript fetcher.- API routes:
/api/pastebin/*,/api/auth/*, OAuth/auth/google/*,/api/yt-transcript.
src/index.ts— Worker entry; routes and serves static assets frompublicvia theASSETSbinding. Falls back to bundled reads in tests/dev.public/index.html— Index page.public/markdown.html— Markdown Preview page (Marked + DOMPurify + MathJax, tabs, Highlight.js with theme swap, copy button).public/euler.html— Euler Preview page (BBCode → HTML, MathJax, tabs, Highlight.js with theme swap).public/pastebin.html— Pastebin UI.public/llm-cost.html— LLM Cost Calculator UI (usage parsing, pricing library in localStorage).public/actuary.html— Actuary Calculator UI (Social Security actuarial tables ported fromactuary.py).public/tiff-viewer.html— TIFF viewer UI with channel toggles/colors, fit-to-width zoom, and localUTIF.jsloader.public/vendor/utif.js— Bundled TIFF decoder used by the viewer; served locally for offline/CSP-friendly usage.public/yt-transcript.html— YouTube transcript viewer UI with segment list and API integration.wrangler.jsonc— Wrangler config with assets binding enabled.migrations/0001_pastebin.sql— D1 tables for users, sessions, pastes.test/index.spec.ts— Basic unit/integration tests.
- Dev server:
npm run devthen openhttp://localhost:8787/. - Tests:
npm test - Deploy:
npm run deploy
If you change static HTML in public/, no Worker code changes are required.
- Create a D1 database and bind it:
- In
wrangler.jsonc, setd1_databases[0].database_idto your D1 id (or use an env binding). - Run migrations:
wrangler d1 migrations apply web_tools_db(or your database name).
- In
- Configure Google OAuth:
- Create OAuth 2.0 Client (Web) in Google Cloud Console.
- Authorized redirect URI:
https://YOUR_DOMAIN/auth/google/callback - Set vars/secrets:
wrangler secret put GOOGLE_CLIENT_SECRETwrangler kv:namespacenot required.- In
wrangler.jsoncvars, setGOOGLE_CLIENT_IDandOAUTH_REDIRECT_URL. - Optional:
SESSION_COOKIE_NAME(defaults towt_session).
- Dev: ensure your dev URL’s redirect matches (use
--local-protocol=httpsor a tunnel if needed).
Security notes:
- Sessions use random tokens stored in D1 and set as HttpOnly, Secure, SameSite=Lax cookies.
- Only
publicpastes appear in listings;unlistedrequire the direct link. - When not signed in or not allowed, pastes are saved to
localStorageonly and cannot be shared across devices. View a local paste by opening/pastebin#local=<id>on the same browser.
- MathJax inline delimiters are restricted to
$...$to avoid conflicts with literal parentheses in text and links; display math supports$$...$$and\[...\]. - Output HTML is sanitized before insertion. Be cautious if you change the sanitization step.
MIT — see LICENSE.md.