Commit graph

50 commits

Author SHA1 Message Date
Doxa Maps
c1a2f36983 Wall of People Groups: comments state what was measured without naming who measured it
Five comment lines in the Wall's sources named a fleet agent as the measurer. They now keep the
measurement and drop the name. Comments only; no behaviour changes.
2026-10-01 00:17:18 +00:00
Doxa Maps
7f2dec8600 Wall of People Groups: the Bless poster takes the house poster style, full width, with nothing clipped
The poster now reads like the UPG 100 List posters (poster-render's approved template):
- warm paper, hairline rules instead of black boxes and sidebars, Georgia for the title and the scripture;
- the sans for names and labels, tracked capitals for the small labels, and the purple ink for every
  scripture reference;
- a quiet boxed centrepiece in the journey.
The screen canvas draws the same paper and ink, so the wall still shows what prints.

Layout:
- The header, the chart, the grid and the footer share ONE full content width and ONE inner padding, so
  text edges and rules line up. The subtitle, the blessing's intro lines and the closing line no longer
  wrap inside an 80% column.
- The grid's spare height is shared equally above and below it (it pooled as one gap above the footer),
  and a gap now separates the chart from the first row.

Fixed, measured on the print in en and ar at every size (0 clipped text blocks, was 12-15):
- the Old/New Testament rail labels overran their rows;
- the longest verse cell overran its row (the chart's verse size now fits its longest cell);
- the title's descenders were clipped;
- two real names were cut by the line clamp (0 of the live 2,107 now): a name's lines are counted by
  whole words, and a long name may take four lines at the floor size.
2026-09-30 22:32:56 +00:00
Doxa Maps
332aa002f8 Wall of People Groups: the Bless poster takes its sheets, glue bands and marks from PanelSheets, byte for byte
blessPoster.js now plans its 5 x 8 ft sheets, finished size, screen layout, glue band, trim line and sheet
tags through library panelSheets.js instead of its own copy. The print HTML, the screen layout and the plan
are unchanged: hashed for 3 presets and the default in all 11 locales (44 cases), before and after, all
identical; a 0.001 in change to the glue label moves all 44.

check:panel-sheets (gates:pre, headless) pins both geometries (60x96 stacked, 66x66 side by side, one
sheet; glue and bleed):
- the sheets tile the finished poster;
- glue slices tile it, and bleed slices repeat exactly the join;
- a bleed join prints a guide, not a solid band, and a screen preview always shows the red band;
- the Bless 5x8ft takes its bands and marks from the module.
It is two-sided: 4 planted defects are caught, and the Bless arm fails on the old private copy.
2026-09-30 22:03:40 +00:00
Doxa Maps
db1e6c978f Wall of People Groups: the wall pans and zooms with the pointer, 1:1
d3-zoom on a canvas reports its transform in the canvas's own CSS px, but the renderer applied it inside
the "meet" fit (a leftover from the SVG, whose viewBox made it world units). Every pan therefore moved
the wall by only the fit scale: a 200 px mouse drag panned 34 px at 1440, a 120 x 200 px finger drag
14 x 23 px on a phone, and a wheel zoom drifted about 90 px off the pointer. The transform now applies
after the fit, in Bless and Social mode alike.

Also: a trackpad pinch (ctrl-wheel) zooms the wall instead of falling through to a browser page zoom,
with a capped step; and a fling can no longer leave an empty table (the wall always covers the centre
of the view). check:wall-pan (gates:pre) runs the real WallCanvas methods with d3's transform
arithmetic and catches the old formulas.
2026-09-30 21:29:56 +00:00
Doxa Maps
7d5d7a62d8 Print on phones: the shared Print bar is labelled in the reader's language from the wall and the poster prints too 2026-09-30 08:04:52 +00:00
Doxa Maps
f544ca6334 Print on phones, everywhere: the map's poster dialog, research-map, the gospel tree, the planner and the wall
Every other caller of the in-place print moves onto the phone path the poster wall already uses:
printImageBlob (the map's poster/download dialog and research-map) prints the page itself on a phone,
and the gospel tree, the prayer-walk planner and the wall of people groups call printDocument. A caller
without its own progress dialog gets a shared Print bar when the tap has expired, labelled through the
caller's own translator. Desktop keeps the in-place frame unchanged. Source only; the bundles are rebuilt
when it lands.
2026-09-30 07:34:19 +00:00
Doxa Maps
f50b641b28 The Wall's and the template's proofs become guards: four two-sided headless checks, in the plugins' own scripts/
Until now these ran from _qa-cycle, so they proved a landing once and guarded nothing after it. Each now lives with its plugin, locates the repo from its own path, and fails on its known-bad:
- wall-of-people-groups/scripts/check-wall-wysiwyg.mjs: the screen poster and the print are one layout on every preset (sheets, 2,107 card rects to 0.002 in, name size and wrap, reference size, chrome blocks). Planted: a card moved 0.01 in, a name a point larger, the footer missing on screen. About 0.6 s.
- wall-of-people-groups/scripts/check-wall-print-watch.mjs: the HD print counts its photos while they load, counts the ones that could not load, finishes at load or the 10-minute ceiling, and ends when its frame is gone. Planted copies of printWatch.js now go to the OS temp folder, never into the tree. About 0.3 s.
- wall-of-people-groups/scripts/check-wall-no-bg-photos.mjs + fixtures/pray-list-sample.json: the real store (through Vite) never requests a photo on its own, a group with no photo URL gets none, and one with a URL keeps it. Planted: the old background test, added through the store's $onAction. The store from before L12 (d9e9aa448) fails both arms: 12 photo requests in 3.5 s and 3 groups on the 404 placeholder. The fixture is a trimmed sample of the live list: 200 rows (120 with has_photo, 77 without, 3 synthetic with no image_url), only the fields the check reads, 66 KB. About 10 s.
- template-bundle/scripts/check-template-i18n.mjs: profile B renders from template.json in en, ar and zh, one sentence in each language's own order with both <code> islands, and no raw key. Planted: the English catalogue served as Arabic. About 4 s.

All four are headless: no browser seat.
2026-09-29 13:14:46 +00:00
Doxa Maps
488d34836a Wall of People Groups: the level-of-detail hook reports the zoom it actually draws at
rega's L12 photo probe read host.__wallLod().cardPx as 0 after 46 wheel ticks: the field was set once when the cards were first laid out and never again, since the canvas renderer replaced the LOD component that used to update it. The canvas now records one card's on-screen width at every frame it draws (stats.cardPx, both the grid and the poster), and the hook returns that. The container's header comment no longer claims Font Awesome is loaded: the canvas draws its own icons, and d3 is pinned and kept off window.d3 (src/wallD3.js).
2026-09-29 12:35:22 +00:00
Doxa Maps
c2473d0e41 exp's maps keep the reason and drop the speaker: no comment quotes or cites the Driver
21 lines in seven of exp's bundles (upg-neighbor 4, prayer-walk-planner 8, doxa-simple-map 2, pplr-data-maps 2, wall-of-people-groups 1, doxa-vision-card 1, all-people-groups 3): each keeps its engineering reason, its dates and its measurements; the speaker and the quotes go (a quote becomes a plain statement of the defect). Comments only. Five bundles rebuild byte-identical; doxa-simple-map and pplr-data-maps change only in their Vue scoped-style ids, which hash the SFC source.
2026-09-29 08:56:44 +00:00
Doxa Maps
7e309d1777 Wall of People Groups: the poster print counts its photos while they load, and says how many could not load
The HD poster prints on its frame's 'load', which waits for every photo: up to 2,107 photos, 132 MB, which can take minutes on a slow connection, and a photo that fails prints as a grey box without a word. The print button now reads "Preparing the poster: n of 2,107 photos" while the frame loads, and if any photo could not load, a toast says how many print as grey boxes. The counting is src/printWatch.js (it never decides when to print; the frame's own 'load' does). It finishes at 'load', at the frame's 10-minute ceiling, or at once if the frame is gone (closed), so the busy button never outlives its frame. The busy state's fallback moves from 120 s to that ceiling, because the frame is now kept until it has loaded (printInPlace, exp-shepherd/print-floor).

Headless, fake timers and a fake frame (_qa-cycle/exp-shepherd/check-wall-print-watch.mjs): progress climbs as photos load; 3 photos with no pixels are counted as failed; a load that never ends finishes once at the ceiling and not before; a frame removed at 60 s ends the watch within a tick; 4 planted defects (failures not counted, no ceiling, no progress, a removed frame holding the watch) each caught.
2026-09-29 08:56:44 +00:00
Doxa Maps
32e3a20ae4 Wall of People Groups: the store no longer downloads every photo in the background, and the dead source picker and old card are gone
Measured on the live list (2026-09-29): after loading, the store tested every photo by loading it, three at a time with a second between batches: 932 photos, 132 MB by their Content-Length (the 77 IMB photos alone are 115 MB), for as long as the page stayed open, whether or not anyone zoomed in. All 939 photo URLs answered 200, and the canvas already loads only the photos in view and draws its grey box for any that fail, so the test is removed. A headless run of the real store with a counting Image stub: 12 photo requests in the first 3.5 s before, 0 after.

A group with no photo URL now gets none, instead of the stock "no image" photo, which answers 404. Today every group has a URL (a regional photo when it has none of its own), so nothing changes on screen.

The source picker only showed with two sources or more, and there has been one since the WordPress API and the CSV were dropped. It goes, with the two loaders, the CSV parser, their CSS, and the card component nothing imports. The bundle is 9.6 kB smaller (2.5 kB gzip).
2026-09-29 07:22:57 +00:00
Doxa Maps
7160126831 Wall of People Groups: the verse file's comments name the brief and the chosen footer, not a person 2026-09-29 05:17:38 +00:00
Doxa Maps
042803ab3a Wall of People Groups: photos are kept as small copies, text is measured a little at a time, and off-screen sheets skip rendering
Measured on the live list: 77 photos are 1024 x 1024 (4 MB each decoded) and drawImage downscaled each of them on every frame it was visible. A loaded photo is now kept at 320 px on its long side (createImageBitmap with resize, or one drawImage into a small canvas where that is missing), and the original is released; the print frame loads the originals itself. Below text zoom no card is measured (the photo box uses an estimate), and at text zoom at most 150 new cards are measured per frame. The overlay's sheets use content-visibility:auto. The host hook reports the counts (photos loaded, thumbnails, fallbacks, cards measured) for the performance probes.
2026-09-29 05:17:38 +00:00
Doxa Maps
daf8a335ea Wall of People Groups: the poster comes in 3 by 4 ft (the default), 2 by 3 ft and 5 by 8 ft, and every size keeps its scripture readable
The brief's three sizes. At 3 x 4 and 2 x 3 ft a verse under each of ~2,100 cards would print at 3 pt and 2 pt, so those sizes use the strip layout: cards of name and photo, and one blessing verse per row on a strip under it at 9 pt (33 and 34 verses). 5 x 8 ft keeps a verse under every card at 6 pt. The footer's height now comes from its text (the whole passages), with the journey never below 6 pt; the screen shows the strips as it shows the rest of the poster.
2026-09-29 05:17:38 +00:00
Doxa Maps
9e82ac8dd1 Wall of People Groups: the poster's footer quotes the whole passages, Numbers 6:22-27 and the journey's seven, and the chart cites the passages its verses come from
The priestly blessing is Numbers 6:22-27 in full: the Lord's word to Moses and Aaron in small type, the three blessing lines large, and the promise that closes it. Each station of the journey quotes the passage the brief lists: Genesis 12:1-4, Genesis 15:5-6, Galatians 3:13-14, 1 Peter 2:4-8 (the cornerstone, at the centre), Galatians 3:5-7 and 28-29, 1 Peter 2:9-10, Luke 19:9-10. The chart's New Testament verses name their passages (Matthew 21:21, from 21:18-22; Matthew 8:26, from 8:23-27). All WEB, verbatim, checked by script against ebible.org.
2026-09-29 05:17:38 +00:00
Doxa Maps
cc5d592b02 Wall of People Groups: on a phone every control is on screen
rega measured the header at 390 px: one row, so the title wrapped to five lines and the poster-size select (x=393) and the Bless/Social toggle (x=553) ran off the edge, unreachable. On a phone the title takes one short line and the controls wrap onto rows.
2026-09-29 03:38:57 +00:00
Doxa Maps
807c78cc64 Every Experimental map carries its own hosted ?, where its controls already are
Map controls: prayer-walk-planner (under fullscreen), gospel-internet (the map and the language
tree, the board's default view), country-posters (the country map, its entry profile) and
all-people-groups get the library HelpButton with hosted. Own bars, where there is no control
column: the Wall (after the Bless/Social toggle), the PPLR hub (the end of its view bar) and the
vision card (its top corner, at the end of the reading direction so Arabic mirrors it) use
useHostedHelp. The vision card's label is the library's own "About this map" in each of the
eleven locales, copied into vision.json rather than translated again. UPG Neighbor is left as it
is: its bar already has an About button that opens the full explainer.

Each "?" stays hidden until a host marks its pane, so nothing changes until the app answers.
2026-09-29 02:35:35 +00:00
Doxa Maps
994ef3391d Wall of People Groups: the poster footer's station names print in the reader's language 2026-09-29 01:28:30 +00:00
Doxa Maps
0be63de7ac Wall of People Groups: changing the language keeps the Social board where you were 2026-09-29 00:39:55 +00:00
Doxa Maps
03b5078d4e Wall of People Groups: the poster's title and chart never flash at print size before the wall's zoom applies 2026-09-29 00:39:55 +00:00
Doxa Maps
9d3040867f Wall of People Groups: Share works in Social mode, the loading screen stays inside the wall, and the orientation switch shows only where it does something
Share opens the phone's share sheet for the group's prayer page, or copies the link and says Copied!. The loading overlay was position:fixed and covered an embedding page; it now sits inside the wall like the offline notice. Landscape / portrait arranges the Social board only: in Bless mode the wall is the poster.
2026-09-29 00:39:55 +00:00
Doxa Maps
2473ce5d01 Wall of People Groups: the poster's sheets lie on a grey table, and names are as black on screen as on paper 2026-09-29 00:39:55 +00:00
Doxa Maps
fab6cb695f Wall of People Groups: the last three long names fit their cards
A name is measured wider (0.72 em a bold character) and a wrapped name gets the lines it needs, up to three, on the poster and on the wall alike.
2026-09-29 00:39:55 +00:00
Doxa Maps
0c9772784d Wall of People Groups: in Bless mode the wall is the poster, what you see is what prints
The screen shows the printed sheets themselves, stacked as they print (three 60 × 36 in pages for 5 × 8 ft, glue bands and all). Every card sits where it prints, sized by the same cardText() the print uses; the title, the prayer-themes chart and the footer are the print's own HTML in an overlay that follows the zoom and lets every click through to the wall.
2026-09-29 00:39:55 +00:00
Doxa Maps
a331f1f20e Wall of People Groups: nothing on the poster is cut off, and the size list reads the same in Arabic
The chart's rotated labels are sized from their own text and wrap; its theme headers fit their row. A long group name shrinks to fit (never below 6 pt) or takes two lines, and the photo gives way so the card's content never outgrows the card. The verse reference prints at 6 pt. The size labels are isolated left to right, so an RTL page no longer reorders '5 × 8 ft · 3×'.
2026-09-29 00:39:55 +00:00
Doxa Maps
12b913a711 Wall of People Groups: the poster's prayer-themes chart and closing line print in the reader's language 2026-09-28 23:01:29 +00:00
Doxa Maps
00dabc0a9e Wall of People Groups: the poster's footer tells the calling to bless the nations, from Abraham to the church, with Christ the cornerstone at its centre
Every scripture, name and reference, on the printed sheet and on the canvas, is set in its own direction, so an English verse on a right-to-left page keeps its full stop at the end.
2026-09-28 22:44:20 +00:00
Doxa Maps
e7356fa1b9 Wall of People Groups: the poster prints its chart labels and closing line in English until their translations land, and the sea's New Testament verse is the storm stilled (Matthew 8:26)
The chart's theme names, its row labels and the closing line print in English (the blessPoster defaults) until studio's round B carries the theme keys; the title, the DOXA line and the glue label are already translated. lang and dir still follow the page, so right-to-left locales lay the chart out right to left.
2026-09-28 20:51:53 +00:00
Doxa Maps
4b299bad8f Wall of People Groups: the poster tells the story, a prayer-themes chart of treasure, mountain and sea above the people groups and the priestly blessing and the priesthood of believers beneath them 2026-09-28 20:51:32 +00:00
Doxa Maps
317f33c15e Wall of People Groups: a 3 by 3 foot poster size 2026-09-28 20:51:32 +00:00
Doxa Maps
bee12baea0 Wall of People Groups: focus returns to the wall when a dialog closes, and the map pin hint stays off the wall 2026-09-28 20:51:32 +00:00
Doxa Maps
ef7325990a Wall of People Groups: names open the group's prayer page, and the prayer and comment dialogs close on Escape and keep focus inside 2026-09-28 20:51:32 +00:00
Doxa Maps
84c745c44e Wall of People Groups: one canvas instead of 36,000 SVG nodes, drawing only the cards in view, photos loaded as you zoom in 2026-09-28 20:51:32 +00:00
Doxa Maps
b0d336d0d6 Wall of People Groups: the poster is 5 by 8 feet by default, three stacked sheets glued on 6-inch borders, and other sizes fit their own grid 2026-09-28 20:51:32 +00:00
Doxa Maps
43992ccac3 Wall of People Groups: the share notice and the drawing-library error in the reader's language 2026-09-28 20:51:32 +00:00
Doxa Maps
3f3494eac9 Wall of People Groups: in Bless mode, Print poster prints all the people groups as one 8 by 5 foot poster on three overlapping sheets 2026-09-28 20:51:32 +00:00
Doxa Maps
f4c3767784 Wall of People Groups: Bless mode by default, a blessing verse under every people group, and Social mode one click away 2026-09-28 20:51:31 +00:00
Doxa Maps
fcad0dc1a0 Wall of People Groups: comment times and the unnamed-group fallback in the reader's language 2026-09-28 18:52:57 +00:00
Doxa Maps
786a834610 Map errors in every language, and print buttons that show they are busy (UPG Neighbor, All People Groups, Prayer Walk Planner, Wall) 2026-09-28 18:34:16 +00:00
Doxa Maps
5ab4af2e44 Five plugins were silently monolingual, because the bootstrap was copied sixteen times
Goal (c), and it turned into a goal (d) fix. Every profile element is
defineCustomElement(ProfileLoader, { configureApp }), and the configureApp has four
steps. The fourth, app.provide('appI18n', i18n), is the one that gets dropped.

ProfileLoader injects that instance (ProfileLoader.vue:176) to drive its locale from
profile-config. Without the provide the watcher holds null and the drive NEVER RUNS --
while setRuntimeLocale() on the next line still fires, so tStatic strings DO follow the
host. The element renders a convincing MIXTURE of the reader's language and English, and
nothing throws, because the t() shim falls back to its key. It reads as "a few strings
not translated yet".

SHIPPING THAT TODAY: country-posters, key-cities, gospel-resources, cities-internet and
my-upg-100-list. regions-plugin censused all 19 entry files independently and found the
same five and no sixth. The measurement is regions-dashboard's, from when they hit it:
a Spanish catalogue present, es set, and every t() string still English.

All sixteen entries now call library/elements/defineMapElement.js, so the five are fixed
by construction rather than by five separate edits. Behaviour is otherwise identical --
same options, same element names, same per-plugin extras. wall-of-people-groups needed
the helper to hand its pinia back, because it takes a store off its own instance and a
helper that hid pinia would have given it a second one: two stores and a silent state
split.

★ AND THE CENSUS THAT RECOMMENDED THIS SAW FOUR OF SIXTEEN. My detector hashed function
BODIES; eleven sites are not `function buildXElement()` at all, they are
`const El = defineCustomElement(...)`. I wrote "every number here is a lower bound" in
the census as a caveat and it was the headline within the hour -- a 4x undercount of the
item it recommended. So this gate greps for the SHAPE, not for a known list: a check
written around the four that matched would have passed the twelve that did not.

check-element-bootstrap has two arms. No entry may build a profile element by hand, and
the helper itself must provide appI18n -- PLANTED as a negative case, so the regression
cannot return by editing library instead of a plugin. It also fails if it finds fewer
than ten entries, because a detection that stops matching reports the same green as a
tree with no problems.

THE PLANT CAUGHT TWO BUGS IN THIS GATE BEFORE IT CAUGHT ANYTHING ELSE. The predicate
matched the helper's DOCSTRING, so it would have passed a helper that only mentions the
provide in prose -- comments are stripped now, because a check that reads comments is
reading the author's intentions rather than the program. And the plant itself used /m
instead of /gm, so it deleted the documentation and left the code, then reported that it
could not detect an absence that was not there.
2026-09-28 17:40:34 +00:00
Doxa Maps
91fac156ee Wall of People Groups: no debug logging in the shipped bundle
40 console.log calls (fetch progress, grid sizes, sample rows, API stats) ran on every
load; public-hygiene flagged them. Warnings and errors are kept.
2026-09-28 02:53:46 +00:00
Doxa Maps
ca6979e49f Wall of People Groups opens where the photos are, with rows as far apart as columns
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
The wall opened at the whole-wall view, where a card is 11-15 CSS px, under wallLod's 48 px photo
threshold, so every card showed its empty image slot: the README picture read as a blank grid (the
Driver: "zoomed too far out... hard to see the people groups"). It now opens at the top-left corner,
where the store puts the biggest clusters, with cards ~96 px wide. Checked headless with lodPlan on
the component's own geometry (2,107 groups, 53x40): desktop 1440x820 k=7.5, 77 photos; 1280x720
k=8.6, 60; phone 390x700 k=20 (max), 15 photos, all 'hd' and far under the 300 cap, so the memory
win holds. Reset Zoom still shows the whole wall. Rows were 3 units apart against 8 between columns
and left a 200-unit empty band at the bottom of the 4ft x 3ft canvas; 8 fills it exactly.

Built with BUNDLE=wall-of-people-groups only, then the tree; check:sri PASS.
2026-09-27 05:30:05 +00:00
Doxa Maps
06209dc45e One pinned-UMD loader for PPLR and the Wall: library/utils/loadPinnedUmd.js
pplr-data-maps and the Wall each carried the same ~40-line d3 loader (pinned, SRI, and a trap that keeps
the UMD from writing into a host page's own window.d3). It is now one library helper, fed from the
CDN registry. check:pinned-umd (headless, gates:post): the tag carries the pinned integrity, a host's d3
gains no keys, and a failed load rejects leaving the host's d3 in place. Both bundles build.
2026-09-26 07:24:25 +00:00
Doxa Maps
e3d25ff6db The people-group list is a universal prop: the same maps can show any project's list
Every map showed DOXA's people groups, and only those. The same maps must serve other projects'
lists: Project 7000 (unreached), 4700 (frontier), 700 (frontier of 500,000 or more), 2000 (DOXA).
The list is now chosen the way the engine is:
  profile-config `list` > ?list= > window.MAP_LIST > 'doxa' (exactly today's behaviour)
with ids or project aliases ('700', 'project-7000').

- library/lists/lists.json: each list is a FILTER over the IMB / peoplegroups.org dataset already
  in the repo (Lostness Priority, Population, Engagement Status), never a hand-kept roster.
- library/scripts/people-groups/build-lists.mjs (`bun run lists`): writes each list's DOXA members
  to data/people-groups/lists/<id>.json, joined the way the Vision Card funnel joins, so the
  counts agree with it: unreached 7,341 (2,082 DOXA), frontier 4,754 (1,745), frontier-500k 737
  (71), unengaged 2,982 (1,929).
- library/lists/peopleGroupList.js: resolvePeopleGroupList and applyPeopleGroupList(rows, cfg).
  The default list returns the same array, unfetched. A list whose membership cannot load shows no
  groups (fails closed) rather than DOXA's whole list under another list's name.
- Tier A, every production map: DataSourceManager applies it (and the maps that build one pass
  their profileConfig), and so does every direct people-group fetch: people-groups-grid, the
  Big Picture header, research-dashboard (data, CSV export; the DOXA-wide /statistics baselines
  are skipped under another list), Regions (list, dashboards, their table), UPG-100 (4 fetches +
  the poster wall), Gospel's roster, and the Experimental upg-neighbor and Wall. The composites
  thread `list` to their children like `provider`.

Gates: check:universal-props gains a `list` column (LIST-FETCH, LIST-DSM, LIST-KEYS; its
self-test now plants 9 bypasses) and passes across 18 bundles, with all-people-groups allowed:
it draws the IMB dataset, so its list is Tier B. New check:list-prop-unit (Node, 17 cases, in
gates:post); poisoning the ladder order or deleting a membership file fails it. Documented in
documentation/reference-universal-props.md section 5.

Headless: all 14 touched bundles build; check:composites-mount 20/20 and check:composite-interop
17 links pass on this tree; no-orphan-gates, script-flags, quoted-scripts, doc-scripts pass. Not
rendered in a browser.
2026-09-26 05:16:02 +00:00
Doxa Maps
cd72dbad7d Wall of People Groups: loading d3 no longer writes into the host page's own d3
The Wall's pinned-d3 loader had the flaw rega found in PPLR's: d3's UMD build
writes its exports INTO an existing window.d3, so restoring the host's object
afterwards was too late. Ours had already been written into it. Same fix as
pplr-data-maps (60faff1a): while our script executes (document.currentScript
is our element), window.d3 is a slot of ours; any other code always sees the
host's own. A non-configurable `var d3` global is emptied for the load instead.

Headless, the real d3@7.9.0 (sha384 matches the pinned SRI) in a vm realm:
  before  host owns window.d3: keys 2 -> 579, version -> 7.9.0
  after   host owns window.d3: keys 2 -> 2, version host-7.0.0; the Wall gets its own d3 7.9.0
  after   no host d3: window.d3 absent afterwards, as before
rega re-ran PPLR's identical loader in a browser in all three variants, including a real
non-configurable `var d3`: PASS.
2026-09-26 05:10:25 +00:00
Doxa Maps
9844f72eaf Wall of People Groups: nothing leaks onto the host page (no Font Awesome, no window.d3)
The critic fact-check (CRITIC-9) found the Wall injecting Font Awesome 6.5.1 into the HOST
page's <head> (global .fa-* rules that can restyle a partner's own icons) and loading d3@7 (a
floating range, no SRI) as window.d3, overwriting a host's own d3.
  - The card's heart / comment / share icons are now plain SVG paths in the card itself, not
    Font Awesome <i> tags in three foreignObject/xhtml divs per card (~6,300 on the wall: lighter
    too). The dialog hearts are inline SVG; the source-picker info icons are a text glyph. No
    Font Awesome stylesheet is injected anywhere.
  - src/wallD3.js loads d3@7.9.0 exactly, with integrity + crossorigin, keeps it in the module
    (wallD3()) and puts the host's window.d3 back (or leaves none).
  - The heart used `self.$store`; `self` is the browser's window, so a prayer made in this
    session never lit it. It now reads this.$store.
Headless proof: a stubbed-DOM test of the d3 loader, 6/6 (the host's d3 restored, none leaked,
exact version + integrity + crossorigin, a failure rejects). The bundle builds and contains 0 Font
Awesome references.
needs eyes: the Wall: hearts, comments and share icons render on the cards; a card whose group has
prayers shows a red heart; a host page with its own d3 or Font Awesome is unaffected.

(cherry picked from commit 28575d6013)
2026-09-26 03:34:31 +00:00
Doxa Maps
7b1e64eaba Wall of People Groups: level of detail like a map, and an HD poster print path
The wall gave all ~2,100 card photos their full href at once, so every photo was fetched and
decoded even with the whole 4000x3000 wall on screen and each photo a few pixels wide. Now:
  - photo URLs are parked in data-hd; zoomed out (a card under 48 px on screen) the wall shows
    only the light image slots, with no photos loaded;
  - zoomed in, updateLod() (rAF-throttled on every zoom/pan) gives HD photos only to the cards in
    view plus one card of margin, and REMOVES them from cards that leave the view; a 300-image
    cap keeps any view light;
  - "Print HD poster" loads every photo, waits for them, prints, then returns to level of detail;
    it replaces the old "coming later" alert (new key wall.printPoster, all 11 locales).
The geometry is a pure module (src/wallLod.js), so it is tested without a browser.
MEASURED, headless: the real 2,107-card layout at 1280x800. Sampled photos are ~200x250 (23 real
image URLs from the live API): ~0.22 MB each decoded, ~45 KB compressed. Loading all of them, as
before, is ~466 MB decoded + ~94 MB downloaded. With LOD: zoom 1-4x = 0 photos; 6x = 150 (~33 MB);
8x = 80 (~18 MB); 12x = 63 (~14 MB). lodPlan matches a brute-force visibility oracle at every zoom.
Photos are the part of the 1.4 GB that can be measured without a browser; the rest (DOM,
rasterisation) needs a browser heap snapshot: needs eyes.
needs eyes: Wall of People Groups: DevTools memory before/after; zoomed out = no photos, zoom in =
photos appear only where you look; "Print HD poster" prints every photo.

(cherry picked from commit ef9646f8f5)
2026-09-26 03:34:30 +00:00
Doxa Maps
85019a1543 Wall of People Groups: the wall and its dialogs speak the reader's language
The universal-props matrix flagged the Wall as a locale BYPASS: no t() anywhere. A new wall area
(library/i18n/locales/<lc>/wall.json, all 11 locales, 39 keys) now carries the header, orientation
and zoom controls, the loading and offline notice, each card's prayer count and "View prayers", and
both dialogs (Prayer Tools, People Group Chats), with aria-labels on the close buttons, which had none.
The components use the globally injected $t (createAppI18n, globalInjection). The prayer count uses
vue-i18n's plural choice in English and a neutral "label: n" form elsewhere, so no language needs
plural rules. Status values from the API are data and stay as they come.
Headless proof: vue-i18n against the real catalogs, 8/8 (en 0/1/4 plural, ar neutral form, ar title,
de label form); check:i18n-parity PASS; the bundle builds. Library catalog change: studio lands it.
needs eyes: Wall of People Groups with ?lang=ar: the header, a card's prayer line, and both dialogs.

(cherry picked from commit 7c1c60975e)
2026-09-26 03:34:29 +00:00
doxa-maps-88655c70
e31738762c Wall of People Groups: say so when the live API cannot be reached, and stop a render error
With pray.doxa.life unreachable (offline, or a local dev server whose 127.0.0.1 origin the API
refuses by CORS) the wall sat at "0 Groups Loaded" with nothing explaining why, and logged
"Cannot read properties of undefined (reading 'length')". That error was not the fetch at all:
SourceSelector's template read `sources`, which does not exist (its computed is
availableSources), so it threw on every render, online as well.
  - SourceSelector: availableSources.
  - PeopleGroupsWall: when nothing loaded and the store holds an error, an in-wall notice says
    what failed and offers Try again (inside the wall, never position:fixed over a host page).
  - The store logs the network failure as a warning: it is an expected state now shown on screen.
Measured with every pray.doxa.life request aborted: the TypeError is gone, the notice renders,
and the only console line left is the browser's own "Failed to load resource". Unblocking and
pressing Try again loads 2107 groups. Live (unblocked): 2107 groups, 0 console errors.
2026-09-25 19:20:48 +00:00
doxa-maps-88655c70
7fec74260f Wall of People Groups: every Doxa people group on one zoomable prayer wall joins Experimental
The Instagram-style prayer wall (2,107 DX people groups as photo cards on a d3
canvas, with a pray dialog and comments) existed only as a no-build SPA whose
components were template strings compiled in the browser. It is now a bundle:
the components are SFCs in src/components, and the root is the app's own
container without the router. The API developer panel does not ship. Pinia comes
from the package. The canvas is found by ref, not document id, which cannot see
into a shadow root. Font Awesome is registered on the document too, because
@font-face does not load from a shadow root.

Data is the live pray.doxa.life list. The uupg.doxa.life endpoint no longer
answers, so that source and every photo URL built on it are gone. The card and
both dialogs show the API's image_url instead; before this, every dialog read
"No image". The 2.6 MB CSV fallback duplicated the live API and does not ship.
Missing photos draw inline, not from via.placeholder.com. Prayers and comments
stay in localStorage under a wall-pg: prefix, and the "Print (Coming Soon)"
button, which only alerted, is gone.

Measured on a served built tree: the leaf page, a script embed on another
origin, the Research Gallery tab and a 390 px phone each load all 2,107 groups
with photos and Font Awesome, 0 page errors, 0 failed requests. Zooming in and
tapping a card's heart opens the prayer dialog with the group, its status and
its photo.
2026-09-25 10:34:39 +00:00