Its toast has always read "Tap a coloured dot — someone still needs prayer". Tapping one showed Scripture, film, audio, video, stories, tracts and training, and no way to pray. doxa.life publishes a page per people group and sibling plugins in this repo already link to it; this map simply never did. 1,723 groups now carry a "Pray for <group>" action with the number already praying beside it. THIS IS THE ONE JOIN HERE THAT IS NOT BY LANGUAGE, and it needed justifying rather than assuming. Every other source keys on ISO 639-3 because a translation serves everyone who speaks the language; prayer does not work that way — you pray for a people, in a place. So this keys on (group name, country), which is a NAME join, the thing this map refuses everywhere else because names collide. Allowed only because the key was tested first: on the API side (name, country) is perfectly unique — 2,107 entries, 2,107 distinct keys, 0 collisions — and on the pin side 12,379 pins give 12,369 distinct keys. The ambiguous ones are DROPPED, not guessed. One entry was lost that way, and 383 more have no pin here at all. pray.doxa.life is the fourth host in this bundle that answers 200 with identical bytes for any URL: /abai-sungai and /zzz-not-a-real-group are both 3,903 bytes. Rendered it does discriminate — a real slug titles the page "Abai Sungai - App" with 1,863 characters, a bogus one titles it "Doxa.Life" with zero — but existence comes from the API listing, which is the publisher's own statement and costs one request rather than 1,723 renders. The lookup is COMPUTED, not baked into groupAt. groupAt runs the instant a pin is clicked, so a value read there is whatever had arrived by then and never updates when the lazy fetch lands — the same shape as the link-verification state that used to hang off openPin's country branch. Verified with a negative control: a group in the index renders an anchor whose href matches the expected slug URL exactly, and German, which is not in it, renders nothing. My probe reported FAIL twice against correct code by waiting a guessed 900ms; it now waits for the data. Screenshot read — the Lati, 2,900 people with nothing found in any pool, can now be prayed for. |
||
|---|---|---|
| .. | ||
| external-bundles | ||
| legacy/upg-neighbor | ||
| people-groups | ||
| posters | ||
| tables | ||
| vendor | ||
| README.md | ||
data/ — the bundler's source-of-truth data
The law: data lives here; public/ is generated. Every folder in data/ is copied into the
served web-root by the build (internal/generate-tree.mjs), exactly like the per-profile data in
plugin-designs/*/data/. You should be able to rm -rf public/ and get it all back with bun run build.
| Folder | Served at | What it is |
|---|---|---|
people-groups/ |
/assets/people-groups/ |
People-group datasets (CSV/JSON) the maps read at runtime |
vendor/ |
/assets/vendor/ |
Third-party runtime assets (e.g. table libraries) |
posters/ |
/assets/posters/ |
Rendered poster webp set (heavy pipeline output; poster walls fetch these) |
tables/ |
/assets/tables/ |
The MERGED served table set (its index.json is the merge; per-profile plugin-designs/*/data/tables are build-time sources) |
external-bundles/ |
not served | Prebuilt map IIFEs vendored from sibling projects (not built here); only the optional layouts/ shell mounted them, so the build no longer copies them into public/ |
Don't edit anything under public/ by hand — change it here (or in plugin-designs/*/data/,
layouts/*/assets/) and rebuild.