From 61ee4e57524b3b804343a68bf4fac15f0ff90af5 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Mon, 28 Sep 2026 02:43:35 +0000 Subject: [PATCH] Update from source 1bbfeae07 --- README.md | 2 + documentation/DEPLOY.md | 94 +++++++++++++++++++ documentation/THIRD-PARTY.md | 14 ++- internal/check-optional-t-equivalence.mjs | 4 + .../gospel-internet.instances.json | 18 ++-- .../gospel-internet/src/components/GiGrid.vue | 4 +- .../regions-dashboard/src/useRegionsI18n.js | 11 ++- public/dx-maps/doxa-maps-spa/manifest.json | 22 +++-- .../gospel-internet/board/board/index.html | 4 +- .../dx-maps/gospel-internet/board/index.html | 2 +- .../board/india-china/index.html | 4 +- .../board/language-tree/index.html | 4 +- .../board/platforms/index.html | 4 +- .../board/project-700/index.html | 4 +- .../gospel-internet/board/zero/index.html | 4 +- .../gospel-internet/gospel-internet.js | 38 ++++---- public/dx-maps/manifest.json | 22 +++-- 17 files changed, 194 insertions(+), 61 deletions(-) create mode 100644 documentation/DEPLOY.md diff --git a/README.md b/README.md index 074a40bf..8d7b392c 100644 --- a/README.md +++ b/README.md @@ -711,6 +711,8 @@ provider*" page in front of everything, open only to the groups you allow. Recip Working from your own laptop alongside the team (zero config, everything local by default): [documentation/HOWTO-join-the-table.md](./documentation/HOWTO-join-the-table.md). When your agent runs on a server instead: [documentation/CLOUD-DEVELOPMENT-ENVIRONMENT.md](./documentation/CLOUD-DEVELOPMENT-ENVIRONMENT.md). +All four ways dx-maps ships (laptop, shared cloud dev server, public embeds, a folder in your own site): +[documentation/DEPLOY.md](./documentation/DEPLOY.md). --- diff --git a/documentation/DEPLOY.md b/documentation/DEPLOY.md new file mode 100644 index 00000000..9b5f1368 --- /dev/null +++ b/documentation/DEPLOY.md @@ -0,0 +1,94 @@ +# Deploying dx-maps — the 4 ways it ships + +dx-maps is one repo that runs in four places. Two are for **building** maps (your laptop, a shared +cloud dev server); two are for **showing** them (public embeds, a folder inside your own site). The +building ones run the live source with hot reload; the showing ones serve the **built** folder, +`dx-maps/`, which is checked for private files before it is published. + +| # | Where | For | What you run | What you get | +|---|---|---|---|---| +| 1 | **Your laptop** | building, alone or with a team | `bun run dev` | the Plugin Studio at http://localhost:5173 | +| 2 | **A shared cloud dev server** | a team, or an agent on a server | the Docker image in `deployment/cloud/` | the Plugin Studio at `https:///`, behind your team's sign-in | +| 3 | **Public embeds** | other sites showing a map | the built `dx-maps/` folder on `/cdn` or any static host | `https:///…/dx-maps///index.html` and `…//.js` | +| 4 | **Inside your own site** | one site hosting every map | copy `dx-maps/` into the site's `public/` | the maps at `https:////…` | + +--- + +## 1. Your laptop — `bun run dev` + +```bash +git clone --depth 1 https://git.nuxtbase.app/doxa-open/doxa-maps.git +cd doxa-maps +bun install --frozen-lockfile +bun run dev # → http://localhost:5173/ is the Plugin Studio +``` + +Zero config: no `.env` is needed. Everything is local by default — hot reload of your own edits, a local +PocketBase at `/api/pb`, and Rudder's voice engine once it is set up (Go 1.22+, then +`bash backend/rudder-engine/setup-runtime.sh`). Every setting, with its default, +is in [`.env.example`](../.env.example); an empty value means the default. + +- Follow what teammates land on a shared branch: set `DX_SYNC_REMOTE` (a remote name or a repo URL). +- Use the team's shared PocketBase instead of a local one: set `DX_PB_URL`. + +Details: [HOWTO-join-the-table.md](./HOWTO-join-the-table.md). + +## 2. A shared cloud dev server — Docker or Coolify, with `/data` + +One running copy of the Plugin Studio that follows a branch and hot-reloads every push, for a whole team +or for an agent that lives on a server. Nobody edits files on it: changes arrive by pushing. + +```bash +docker build -t dx-maps-dev deployment/cloud +docker run -d -p 5173:5173 -v dx-maps-data:/data \ + -e REPO_URL=https:////.git -e BRANCH=main dx-maps-dev +``` + +Or paste `deployment/cloud/Dockerfile` into a container host (Coolify's "Dockerfile" build pack) and give +it a domain. + +- **Give it a persistent `/data` volume.** It holds the team PocketBase (dev and prod) and the last + published build. Without one, every restart or redeploy starts empty. +- **Put the sign-in in front** before it is reachable from the internet: the `OIDC_*` settings. Only the + groups you allow get in. +- About **2.5 GB of memory and 2 vCPUs**. + +It also serves the **team PocketBase** at `/pb/` and, after an admin triggers a build, the **public +embed folder** at `/cdn/` (way 3). + +Details: [deployment/cloud/README.md](../deployment/cloud/README.md) and +[CLOUD-DEVELOPMENT-ENVIRONMENT.md](./CLOUD-DEVELOPMENT-ENVIRONMENT.md). + +## 3. Public embeds — `/cdn` or any static host + +The built folder, `dx-maps/`, is what other sites embed. Every link inside it is relative, so it works +from any address. + +- **From the cloud dev server:** an admin runs a build (`POST /admin/build`; about 2 minutes). It builds + the current commit, removes private files, refuses to publish if any remain, then swaps + `/cdn/dx-maps/` over atomically. `/cdn/` is public (no sign-in) and sends + `Access-Control-Allow-Origin: *`, so both iframes and JS embeds work on other sites. +- **On any static host:** build locally with `BUILD_ALLOW=1 bun run build` and upload `public/dx-maps/`. + For JS embeds on other sites, the host must send `Access-Control-Allow-Origin: *`. + +Every page loads its script with an integrity hash, so a tampered or stale script is refused by the +browser. The Plugin Studio's "copy embed" gives you the iframe and the script snippet for each map. + +Details, per host (Cloudflare Pages, jsDelivr, any web server) and per embed style: +[README — What the build makes](../README.md#what-the-build-makes--3-outputs) and +[README-SECTION-3-cli-commands.md](./README-SECTION-3-cli-commands.md). + +## 4. Inside your own site — the folder in `public/` + +Copy the built `dx-maps/` folder into your site's `public/` (renaming it is fine) and your site becomes +the host: no second server and no cross-site setup, because the maps and the page share one origin. + +**Live example:** the DX-life branch +[`research-gallery`](https://your-git-host.example/doxa-maps.git-cdn/src/branch/research-gallery) +drops the folder into DX-life's `public/` and fills `/research` with the Research Gallery. Run it with +`bun install && bun run dev`, then open `/research/`. + +--- + +**Which one?** Building maps: **1**, plus **2** if several people or agents work together. Showing maps +on other sites: **3**. Showing them on a site you already run: **4**. diff --git a/documentation/THIRD-PARTY.md b/documentation/THIRD-PARTY.md index 2d535bd3..a8888c22 100644 --- a/documentation/THIRD-PARTY.md +++ b/documentation/THIRD-PARTY.md @@ -14,7 +14,7 @@ served folder". The licence travels with the asset; the explanation travels with | `vendor/tabulator/tabulator.min.js` + `.min.css` | olifolkerd/tabulator v6.3.1 | MIT | **No** — the `.js` had only `(c) Oliver Folkerd 2025`; the `.css` had nothing | closed: upstream `LICENSE` now vendored beside it | | `boundaries/gb-IND-ADM1*.geojson` (4 files) | geoBoundaries gbOpen, boundaryID `IND-ADM1-1811400` | **CC BY 2.5 IN**, licenceSource `github.com/datameet/maps`, year 2011 — fetched verbatim from the geoBoundaries API | **Yes** — `boundaries/ATTRIBUTION` now ships beside the data, plus the existing `.meta.json` sidecar | none (closed 2026-09-28) | | `boundaries/gb-CHN-ADM1.geojson` | geoBoundaries gbOpen, boundaryID `CHN-ADM1-43563684` | **Public Domain**, licenceSource `commons.wikimedia.org`, year 2019 | recorded in `boundaries/ATTRIBUTION` | none — upstream records no attribution duty | -| `boundaries/world-adm0*.geojson` (2 files, 162 countries) | **geoBoundaries gbOpen, assembled per country** — corrected: its features carry geoBoundaries' own `iso3`/`shapeGroup`/`shapeName` properties, and the plugin's `data/adm0/PROVENANCE.json` names the source and endpoint. NOT Natural Earth, as this register first guessed | **MIXED — up to 162 different upstream licences.** gbOpen passes each country's own licence through | the principle is stated in `boundaries/ATTRIBUTION`; the per-country licences are **not** | **OPEN** — that PROVENANCE.json's `licences` table is EMPTY, so which of the 162 are CC BY is unestablished. Closing it means one API query per country. upg100-plugin's data; routed to them | +| `boundaries/world-adm0*.geojson` (2 files, 162 countries) | geoBoundaries gbOpen, assembled per country (its features carry geoBoundaries' own `iso3`/`shapeGroup`/`shapeName`; corrected — this register first guessed Natural Earth) | **MIXED, and ESTABLISHED per country as of 2026-09-28**: 162 upstream licences. **32** duty-free (28 Public Domain + 4 CC0) · **65** attribution-only · **65 SHARE-ALIKE CLASS** (58 ODbL 1.0 + 7 explicit ShareAlike: AGO GAB GEO GIN MMR NER TUR) | **Yes** — the per-country table (licence + licenseSource + boundaryID + boundarySource, fetched verbatim from the geoBoundaries API, 162 of 162, 0 failures) ships at `plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json`. `boundaries/ATTRIBUTION` references it by path rather than copying it | **OPEN, legal — not a measurement**: whether a redistributed boundary file is a "Derivative Database" under ODbL is unanswered, and half the duty-bearing countries turn on it. With the agent's data-licensing item | | `people-groups/*` (3 files, 8 MB) | peoplegroups.org | **not established** | no terms ship | **OPEN, judgment** — redistribution terms unknown | | `pplr/*` (6 files, 16 MB) | **PPLR ArcGIS Online org** `services2.arcgis.com/S4ydGgujXcif36k3`, aggregating IMB (peoplegroups.org), Joshua Project, the ROP registry, and carrying WCD (World Christian Database) IDs. Built from a local 78 MB extract not present in this repo — evidence from exp-shepherd | **UNRESOLVED.** `aCountry` and `aIMBPeople` publish no `copyrightText`, description or licence (queried `f=json`) | nothing ships | **OPEN, judgment** — redistribution not established. WCD is a proprietary Brill database, so even the IDs need a check | | `tables/*` (304 files, 36 MB) | derived by `library/scripts/research/fetch-*.mjs` from several upstream APIs | **varies, not established per table** | nothing ships; there is no source or licence doc in `tables/` | **OPEN, judgment** — the largest gap by volume | @@ -34,8 +34,16 @@ served folder". The licence travels with the asset; the explanation travels with ## What is NOT closed, and why it is not mine to close -Four rows above are marked OPEN. Two are simply unverified and someone should look -(`world-adm0` provenance, the `pplr` upstream). Two need a decision rather than a fetch: +★ ONE FACT IN THIS FILE IS ALSO ASSERTED ELSEWHERE, AND THAT IS WHERE IT WILL DRIFT. The world-adm0 +licence counts appear both here and in `plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json`. +**That file is the authority; if the two disagree, it wins.** They have already drifted once: this +register said the licence table was EMPTY on the very commit where it held all 162, because the two +landings crossed and neither author could see the other's tree. A register that still reads +"unestablished" after the work is done is settled-by-omission in reverse — the absence of an update +reads as the absence of the work. + +Three rows above are marked OPEN. One is simply unverified and someone should look +(the `pplr` upstream). Two need a decision rather than a fetch: **people-groups** and the 304 **tables** carry data whose redistribution terms are not established, and 36 MB of derived tables is the largest exposure by volume. Attaching a licence I have not confirmed would be worse than the present gap, so those go to the agent. diff --git a/internal/check-optional-t-equivalence.mjs b/internal/check-optional-t-equivalence.mjs index 976e73e2..d9d8eb26 100644 --- a/internal/check-optional-t-equivalence.mjs +++ b/internal/check-optional-t-equivalence.mjs @@ -146,6 +146,10 @@ const SITES = [ // the catalogue default, its duplicate EN map is deleted, and section 9 keeps the ruling's PRECONDITION // true rather than measured once. // First site on the {t, te, locale} form: it needs locale for toLocaleString. + // ⚠ null, NOT a fallback. This row came back as 'fallback: (full) =>' in a merge, because the branch it + // merged from predates 0ded1a4e — the commit that carried out the embed-contract ruling here and deleted + // the inline EN map. Taking a SITES array wholesale from another branch re-asserts ITS view of every + // file in it, including the ones you changed; the gate caught it, which is the only reason it is right. ['plugin-designs/all-people-groups/all-people-groups.vue', 'useOptionalI18n', null], // wave 3c — my-upg-100-list (owner: upg100-plugin). No namespace, since callers pass full keys. // ⚠ THE THIRD COLUMN IS null, NOT 'humanizeKey(k)', and that is a DEPARTURE from 4c05e589, which diff --git a/plugin-designs/gospel-internet/gospel-internet.instances.json b/plugin-designs/gospel-internet/gospel-internet.instances.json index ca843b01..31f784c5 100644 --- a/plugin-designs/gospel-internet/gospel-internet.instances.json +++ b/plugin-designs/gospel-internet/gospel-internet.instances.json @@ -6,7 +6,8 @@ "title": "Gospel x Internet — the board", "props": { "profile": "board", - "urlState": "query" + "urlState": "query", + "pinHint": false } }, { @@ -15,7 +16,8 @@ "props": { "profile": "board", "view": "zero", - "urlState": "query" + "urlState": "query", + "pinHint": false } }, { @@ -25,7 +27,8 @@ "profile": "board", "view": "province", "panel": "map", - "urlState": "query" + "urlState": "query", + "pinHint": false } }, { @@ -34,7 +37,8 @@ "props": { "profile": "board", "panel": "tree", - "urlState": "query" + "urlState": "query", + "pinHint": false } }, { @@ -43,7 +47,8 @@ "props": { "profile": "board", "view": "platforms", - "urlState": "query" + "urlState": "query", + "pinHint": false } }, { @@ -52,7 +57,8 @@ "props": { "profile": "board", "list": "700", - "urlState": "query" + "urlState": "query", + "pinHint": false } } ] diff --git a/plugin-designs/gospel-internet/src/components/GiGrid.vue b/plugin-designs/gospel-internet/src/components/GiGrid.vue index 63e5ea4c..030c8ac2 100644 --- a/plugin-designs/gospel-internet/src/components/GiGrid.vue +++ b/plugin-designs/gospel-internet/src/components/GiGrid.vue @@ -152,6 +152,7 @@ useShadowStyles( '.gig-sticky{position:sticky;inset-inline-start:0;z-index:1;background:inherit;font-weight:600}' + '.gig-chk{width:34px;justify-content:center}' + '.gig-chk input{width:15px;height:15px;margin:0;cursor:pointer;accent-color:#3b463d}' + + '.gig-hit{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;cursor:pointer}' + '.gig-dot{width:10px;height:10px;border-radius:50%;box-sizing:border-box;border:1.5px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.2);flex:none;margin-inline-end:6px}' + '.gig-sw{width:10px;height:10px;border-radius:2px;flex:none;margin-inline-end:6px;opacity:.85}' + '.gig-td a{color:#4f6b52}' + @@ -197,7 +198,8 @@ useShadowStyles( @click="board.openGroup(r.slug)" @keydown="onRowKey($event, r)" @mouseenter="bus.setHover(r.slug)" @mouseleave="bus.setHover(null)">
- + +
diff --git a/plugin-designs/regions-dashboard/src/useRegionsI18n.js b/plugin-designs/regions-dashboard/src/useRegionsI18n.js index ac86ad26..ca3bcc8d 100644 --- a/plugin-designs/regions-dashboard/src/useRegionsI18n.js +++ b/plugin-designs/regions-dashboard/src/useRegionsI18n.js @@ -11,9 +11,14 @@ * is the point. * * FALLS BACK TO THE KEY. A missing string renders the English sentence rather than 'regions.Foo'. - * That matters here: our repo ships 11 locales and DX-life translates 8, so it/ro/zh have no - * regions.json at all and resolve through this fallback (library/i18n README: a missing area file - * is fine, fallbackLocale 'en' handles it). + * ✗ THE REASON GIVEN HERE IS NOW STALE, corrected 2026-09-27. It read: "our repo ships 11 locales and + * DX-life translates 8, so it/ro/zh have no regions.json at all and resolve through this fallback." + * MEASURED: all ELEVEN locales now carry a regions.json, it/ro/zh included. The fallback is still + * right and still load-bearing — a key absent from a catalogue renders its English sentence, which is + * exactly what a reader should see — but it is no longer three whole languages leaning on it. + * COVERAGE, measured the same day: 61 of the 61 keys this plugin actually calls are present in all 11 + * locales. The 62nd that a raw source scan reports is t('Region') appearing only inside two COMMENTS, + * which say themselves that DX-life never needed the key (they have no all-regions state). * * PLACEMENT: plugin-local on purpose. It is four lines shaped entirely by how THESE pages were * written, and the repo's rule is to default to the plugin folder and promote to library/ only diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index 1c6c6a9f..1d6a8b63 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -604,7 +604,7 @@ "bundle": "gospel-internet", "scriptUrl": "./gospel-internet/gospel-internet.js", "output": "dx-maps/gospel-internet/gospel-internet.js", - "integrity": "sha384-rJnN+qmCkokPGSCgbIMnEE/Dj/l8KQi9hEI9bl0aWxpuxtsDQMkZ35tBccFbwVLX", + "integrity": "sha384-oGueXgVn05BKMDaSbY61Gdl/coGTTPu/uMM/BWcYMWCi5Vyr+6N3dk59AKpuDw7i", "elements": [ "gospel-internet-board" ], @@ -623,7 +623,7 @@ "scriptUrl": "./gospel-internet/gospel-internet.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" }, "instances": [ { @@ -632,7 +632,8 @@ "apiBaseUrl": "", "props": { "profile": "board", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/board/index.html", @@ -647,7 +648,8 @@ "props": { "profile": "board", "view": "zero", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/zero/index.html", @@ -663,7 +665,8 @@ "profile": "board", "view": "province", "panel": "map", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/india-china/index.html", @@ -678,7 +681,8 @@ "props": { "profile": "board", "panel": "tree", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/language-tree/index.html", @@ -693,7 +697,8 @@ "props": { "profile": "board", "view": "platforms", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/platforms/index.html", @@ -708,7 +713,8 @@ "props": { "profile": "board", "list": "700", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/project-700/index.html", diff --git a/public/dx-maps/gospel-internet/board/board/index.html b/public/dx-maps/gospel-internet/board/board/index.html index 219f8fb6..85e289a1 100644 --- a/public/dx-maps/gospel-internet/board/board/index.html +++ b/public/dx-maps/gospel-internet/board/board/index.html @@ -36,7 +36,7 @@ - + - + - + - + - + - + - + \n\n" + "script": "\n\n\n\n" }, "instances": [ { @@ -632,7 +632,8 @@ "apiBaseUrl": "", "props": { "profile": "board", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/board/index.html", @@ -647,7 +648,8 @@ "props": { "profile": "board", "view": "zero", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/zero/index.html", @@ -663,7 +665,8 @@ "profile": "board", "view": "province", "panel": "map", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/india-china/index.html", @@ -678,7 +681,8 @@ "props": { "profile": "board", "panel": "tree", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/language-tree/index.html", @@ -693,7 +697,8 @@ "props": { "profile": "board", "view": "platforms", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/platforms/index.html", @@ -708,7 +713,8 @@ "props": { "profile": "board", "list": "700", - "urlState": "query" + "urlState": "query", + "pinHint": false }, "element": "gospel-internet-board", "iframeUrl": "./gospel-internet/board/project-700/index.html",