No description
  • JavaScript 40%
  • Python 39.3%
  • CSS 20.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-17 20:31:01 -04:00
deploy Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00
dist/chris Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00
work Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00
.gitignore Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00
LICENSE Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00
README.md Initial commit (hometown and identity data removed) 2026-07-17 20:31:01 -04:00

Maine Delegate Candidate Browser (Unofficial)

A single-file, searchable browser for the 3,662 delegate candidate statements in the Maine Democratic Party's 2026 special U.S. Senate nominating process. Built to help voters prepare for the July 18 and 19 county delegate meetings and the July 25 Nominating Convention in Bangor.

This is an unofficial volunteer project. It is not affiliated with or endorsed by the Maine Democratic Party. The official guides are at mainedems.org/senate-race.

What it adds over the official guide

  • Full-text search with word-start matching. Searching "ICE" will not match "justice". Quoted phrases match exactly.
  • Candidate preference labels. Statements that name a declared Senate candidate are tagged as Supports, Leans, or Mentions. The labels are filterable per candidate, allow selecting multiple candidates at once, and show counts that update with the other active filters.
  • Evidence on demand. Every label can be clicked to show the sentence or sentences it was derived from.
  • A county filter, plus preset issue-theme searches.
  • Ordering designed to reduce name bias. The default sort shuffles within each county, a fully shuffled sort is available, and a hide-names mode allows blind reading of statements.
  • A personal list. Pick delegates card by card or add all current matches, view the names grouped by county, print a paper checklist, or download a CSV. The list is saved in the browser via localStorage.

How the preference labels were made

  1. Each statement was scanned for mentions of the 12 declared candidates using hand-tuned patterns. These account for common misspellings ("Nirav Shaw", "Sheena Bellows") and exclude false positives such as Jesse Jackson, Libby Mitchell, and a delegate's own surname.
  2. Each mention was classified by rule patterns. Explicit commitments are labeled Supports. Hedged, past, or lower-ranked preferences are labeled Leans. Everything else is labeled Mentions. The results were reviewed with AI assistance and corrected by hand, with about 30 manual corrections. The full rule set and override list are in work/tag2.py.
  3. The evidence sentences behind every label are stored and displayed in the app.

The labels are a research aid and should not be treated as ground truth. A mention is not an endorsement; some are critical or biographical. Statements were written at different times, and some predate the final candidate field. Graham Platner, the withdrawn nominee, is deliberately not offered as a filter.

Repository layout

Path Purpose
deploy/index.html The entire site. Self-contained; deploy this one file.
dist/chris/ Generated files for the companion deployment (see below)
work/cards.json Snapshot of the delegate statements (July 17, 2026), reduced to name, county, statement, and id
work/app.js Application JavaScript, inlined into the HTML at build time
work/style.css Styles, inlined into the HTML at build time
work/tag2.py Mention detection and stance classification
work/tags_final.json Generated stance tags with evidence excerpts
work/build_data.py Compacts statements and tags into the embedded dataset
work/assemble.py Build script that produces deploy/index.html

Rebuilding

Requires Python 3 only. No Node or other build tooling.

cd work
python3 tag2.py        # regenerate stance tags from cards.json
python3 build_data.py  # compact statements and tags into data.min.json
python3 assemble.py    # write ../deploy/index.html and ../dist/chris/

To pick up newly submitted statements, replace work/cards.json with a fresh snapshot (reduced to the same four fields) and rerun the three scripts. Review new or changed stance tags before publishing.

Companion deployment

A second copy of this tool runs at verm.me/delegate-browser.html (repo). It uses the same app code but loads its data from a separate JSON file instead of embedding it. The build script generates both files for it: dist/chris/index.html and dist/chris/cards_enhanced.json. Its data URL and repo links are set in config constants at the top of work/assemble.py. After a rebuild here, those two generated files are copied into that repo and republished, so the two deployments stay in sync.

Deploying

The site is the single file deploy/index.html. Upload the deploy folder to any static host, such as Cloudflare Pages direct upload, Netlify, or GitHub Pages. There is no server component and no external request at runtime.

Visitor lists are stored in localStorage, which is tied to the domain. Keep the URL stable once shared.

Data and provenance

  • Delegate statements were published by the Maine Democratic Party in its Full Delegate Candidate Guide. The snapshot in this repository was taken July 17, 2026. The statements belong to the delegate candidates who wrote them. They are included for civic, informational use and are not covered by this repository's MIT license.
  • Delegate hometowns and the self-reported identity fields that appear in the official guide are intentionally excluded from this repository, its data files, and the app, in response to public concern about that information being published. Only name, county, and statement are carried. Statements are shown verbatim, so anything a delegate chose to say about themselves remains in their own words.
  • Candidate names and page links come from the Maine Dems Senate Candidate Guide.
  • Stance tags and evidence excerpts were generated by this project as described above. Treat them as annotations, not statements of fact.

If you are a delegate candidate and believe your statement is mislabeled, please open an issue. The evidence excerpt for every label is visible in the app.

License

Code is licensed under MIT. The embedded data is excluded, as described above.