Merge main into go-int/work
# Conflicts: # public/dx-maps/doxa-maps-spa/manifest.json # public/dx-maps/gospel-internet/board/board/index.html # public/dx-maps/gospel-internet/board/index.html # public/dx-maps/gospel-internet/board/india-china/index.html # public/dx-maps/gospel-internet/board/language-tree/index.html # public/dx-maps/gospel-internet/board/platforms/index.html # public/dx-maps/gospel-internet/board/project-700/index.html # public/dx-maps/gospel-internet/board/zero/index.html # public/dx-maps/gospel-internet/gospel-internet.js # public/dx-maps/manifest.json
This commit is contained in:
commit
879bb3a8fe
65 changed files with 2333 additions and 526 deletions
61
data/boundaries/ATTRIBUTION
Normal file
61
data/boundaries/ATTRIBUTION
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
BOUNDARY DATA — SOURCES AND ATTRIBUTION
|
||||
=======================================
|
||||
|
||||
The .geojson files in this folder are third-party boundary data. Every value below is taken
|
||||
VERBATIM from the upstream metadata (the geoBoundaries API, https://www.geoboundaries.org/api/current/gbOpen/<ISO3>/<LEVEL>/).
|
||||
Nothing here is our own wording about a licence.
|
||||
|
||||
gb-IND-ADM1-full.geojson, gb-IND-ADM1-full-web.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org)
|
||||
boundaryID IND-ADM1-1811400
|
||||
licence Creative Commons Attribution 2.5 India (CC BY 2.5 IN)
|
||||
licenceSource github.com/datameet/maps
|
||||
year 2011
|
||||
ATTRIBUTION IS REQUIRED for this file: it is Creative Commons Attribution, so a work that
|
||||
redistributes or displays it must credit the source above.
|
||||
|
||||
gb-IND-ADM1.geojson, gb-IND-ADM1-web.geojson
|
||||
The same India ADM1 boundary as above, curated to the UPG-100 list's partition.
|
||||
Same source, same boundaryID, same licence, same attribution duty.
|
||||
|
||||
gb-CHN-ADM1.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org)
|
||||
boundaryID CHN-ADM1-43563684
|
||||
licence Public Domain
|
||||
licenceSource commons.wikimedia.org/wiki/File
|
||||
year 2019
|
||||
No attribution duty: upstream records this boundary as Public Domain.
|
||||
|
||||
world-adm0.geojson, world-adm0-web.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org), assembled per country
|
||||
features 162 countries
|
||||
licence MIXED — and now ESTABLISHED per country, not merely acknowledged.
|
||||
THE PER-COUNTRY TABLE IS THE AUTHORITY, and it lives in ONE place on purpose:
|
||||
plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json
|
||||
It records boundaryLicense, licenseSource and boundaryID for all 162, each value taken
|
||||
verbatim from https://www.geoboundaries.org/api/current/gbOpen/<ISO3>/<LEVEL>/ (162 queries,
|
||||
0 failures, one spot-check re-verified against the live API). This file deliberately does NOT
|
||||
copy that table: one table in two places drifts.
|
||||
|
||||
130 OF THE 162 CARRY A DUTY. Only 32 are duty-free (28 Public Domain, 4 CC0). By class:
|
||||
|
||||
ATTRIBUTION-ONLY (credit the source)
|
||||
44 CC BY 4.0 13 CC BY 3.0 IGO 4 CC BY 2.5 2 CC BY 3.0
|
||||
2 Open Government Licence v3
|
||||
|
||||
SHARE-ALIKE CLASS — A STRONGER DUTY: a derivative may have to be licensed alike, which is
|
||||
the class that actually constrains giving this repository away.
|
||||
58 Open Data Commons ODbL 1.0
|
||||
7 Creative Commons ShareAlike 2.0 / 3.0 — AGO GAB GEO GIN MMR NER TUR
|
||||
|
||||
ODbL IS LISTED IN THAT CLASS DELIBERATELY. Alongside attribution it requires a Derivative
|
||||
Database to be offered under ODbL and carries a keep-open provision, so by volume the
|
||||
share-alike question covers 65 of 162 countries, not 7. This repository has already acted on
|
||||
that reading once: library/scripts/posters/data/README.md records that Natural Earth's 1:10m
|
||||
ROADS were requested and deliberately NOT shipped because of an ODbL obligation.
|
||||
WHETHER 'licensed alike' binds a giveaway of this repository is a legal question, not a
|
||||
measurement, and it is open. It is recorded here so nobody has to rediscover it.
|
||||
|
||||
duty-free: 28 Public Domain, 4 CC0.
|
||||
|
||||
See documentation/THIRD-PARTY.md for the whole shipped tree.
|
||||
|
|
@ -162,13 +162,18 @@ The only other thing here is `DX_PB_PORT`, which you set only if the log says po
|
|||
|
||||
## One more thing to set
|
||||
|
||||
The maps need a Mapbox token. It is the one credential you have to ask the team for:
|
||||
Copy `.env.example` to `.env.local`. **Every line in it is optional** — empty means the default, which is
|
||||
the all-local setup described above. You can start with none of them filled in.
|
||||
|
||||
The one you will probably want is a Mapbox token, which is the single credential you have to ask the team
|
||||
for:
|
||||
|
||||
```
|
||||
VITE_MAPBOX_TOKEN=<ask the team>
|
||||
```
|
||||
|
||||
That, plus `DX_SYNC_REMOTE=origin` if you want it, is the whole of `.env.local`.
|
||||
Leave it empty and the Mapbox-backed maps will not draw; you can also work with the keyless MapLibre
|
||||
provider instead.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@ served folder". The licence travels with the asset; the explanation travels with
|
|||
| Fonts: bebas-neue, figtree, noto-serif-devanagari, oswald, poppins | Google Fonts / foundry repos | OFL-1.1 | **Yes** — each `LICENSE` is the family's own upstream OFL, verbatim, with its real copyright line | none (closed 2026-09-28) |
|
||||
| `vendor/vue/vue.global.prod.js` | vuejs/core | MIT | **Partly** — the minified banner carries `(c) 2018-present Yuxi (Evan) You` and `@license MIT`, but NOT the permission notice MIT asks to include | closed: upstream `LICENSE` now vendored beside it |
|
||||
| `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-*.geojson` (4 files) | geoBoundaries gbOpen (www.geoboundaries.org) | CC BY — the India ADM1 file records **CC BY 2.5 IN**, sourced from DataMeet/Election Commission of India | **Partly** — provenance sits in ONE sidecar, `gb-IND-ADM1-full.meta.json` (source, boundaryID, licence, fetch URL, processing). The other boundary files have none, and no human-readable attribution ships | **OPEN** — CC BY requires attribution to accompany the work |
|
||||
| `boundaries/world-adm0*.geojson` | not verified — probably Natural Earth | Natural Earth is public domain | n/a if Natural Earth | **OPEN** — provenance unconfirmed for this file |
|
||||
| `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 |
|
||||
| `people-groups/*` (3 files, 8 MB) | peoplegroups.org | **not established** | no terms ship | **OPEN, judgment** — redistribution terms unknown |
|
||||
| `pplr/*` (6 files, 16 MB) | not resolved from `plugin-designs/pplr-data-maps/scripts/build-data.mjs` | **not established** | nothing ships | **OPEN, judgment** — owner should name the upstream |
|
||||
| `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 |
|
||||
| `images/worldmap.svg` | recorded in `images/PROVENANCE` | see that file | the PROVENANCE file ships and explains why no licence file sits beside it | none claimed; reasoning recorded rather than assumed |
|
||||
| `previews/*` (378 files) | our own poster previews | ours | n/a | none |
|
||||
|
|
@ -25,6 +26,7 @@ served folder". The licence travels with the asset; the explanation travels with
|
|||
|
||||
| Vendored file | Upstream URL | sha256 |
|
||||
|---|---|---|
|
||||
| `data/boundaries/ATTRIBUTION` | geoBoundaries API, per boundary (values verbatim) | see the file |
|
||||
| `data/vendor/tabulator/LICENSE` | `https://raw.githubusercontent.com/olifolkerd/tabulator/master/LICENSE` | `191a2ee554684e1064c897b432f0e1bc6dfa714ca045d3f6ea2cf692cbd398b7` |
|
||||
| `data/vendor/vue/LICENSE` | `https://raw.githubusercontent.com/vuejs/core/main/LICENSE` | `49190d1f742dd61e47fe816df4963e5186a2a62100d9122f9883a60ea32973ac` |
|
||||
| `data/fonts/bebas-neue/LICENSE` | `https://raw.githubusercontent.com/google/fonts/main/ofl/bebasneue/OFL.txt` | see `documentation/vendored-fonts.md` |
|
||||
|
|
|
|||
|
|
@ -1551,6 +1551,10 @@ function main() {
|
|||
// COMPLETE India ADM1 (36 units, geoBoundaries gbOpen, CC BY 2.5 IN; source + licence in its meta),
|
||||
// for maps that colour every state. The curated file above is UPG-100's 34-unit partition.
|
||||
[resolve(__dirname, '..', 'data', 'boundaries', 'gb-IND-ADM1-full.geojson'), 'gb-IND-ADM1-full.geojson'],
|
||||
// ★ AND THE ATTRIBUTION, because this pair list is what decides whether it TRAVELS. The India
|
||||
// ADM1 boundary is Creative Commons Attribution, so the credit has to reach the recipient with
|
||||
// the data; a file left in data/boundaries would never ship. Same trap as vendor/*/LICENSE.
|
||||
[resolve(__dirname, '..', 'data', 'boundaries', 'ATTRIBUTION'), 'ATTRIBUTION'],
|
||||
[resolve(__dirname, '..', 'data', 'boundaries', 'gb-IND-ADM1-full.meta.json'), 'gb-IND-ADM1-full.meta.json'],
|
||||
// WEB copies (library/scripts/boundaries/build-web-boundaries.mjs): every feature and island kept, about
|
||||
// a fifth of the bytes. The interactive maps fetch these; posters, print and build-time point-in-polygon
|
||||
|
|
@ -1618,6 +1622,11 @@ function main() {
|
|||
'boundaries/gb-CHN-ADM1.geojson',
|
||||
'boundaries/gb-IND-ADM1-full.geojson', // all 36 states (Cities with Internet's NFHS layer)
|
||||
'boundaries/gb-IND-ADM1-full.meta.json', // its source and licence, served beside it
|
||||
// ★ SECOND STAGE. The pair list above only gathers into the build POOL; THIS list decides what
|
||||
// reaches the tree. I added ATTRIBUTION to the pair list, ran the build, and it still did not ship
|
||||
// — a two-stage pipeline needs the entry in both. The India ADM1 boundary is Creative Commons
|
||||
// Attribution, so the credit must travel with the data.
|
||||
'boundaries/ATTRIBUTION',
|
||||
'boundaries/world-adm0-web.geojson', // the web copies the interactive maps fetch
|
||||
'boundaries/gb-IND-ADM1-web.geojson',
|
||||
'boundaries/gb-IND-ADM1-full-web.geojson',
|
||||
|
|
|
|||
80
internal/generate-wagf-region-names.mjs
Normal file
80
internal/generate-wagf-region-names.mjs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* generate-wagf-region-names.mjs — the WAGF region names, in the reader's language, from vendored CLDR.
|
||||
*
|
||||
* ★ THE DEFECT (rega KA3, 3d64bcad, ?lang=ar). Big Picture's region chart labels its bars with the
|
||||
* prayer API's ENGLISH region names — "Africa", "Asia", "Latin America & Caribbean" — on an Arabic page.
|
||||
* They are not chrome and no catalogue held them: they are DATA labels, so every i18n gate was green
|
||||
* while the chart read English to every reader. The regions are a closed set of seven
|
||||
* (library/colors/wagf-region.js WAGF_REGIONS), which is what makes cataloguing them possible at all.
|
||||
*
|
||||
* ★ WHY GENERATED AND NOT HAND-AUTHORED. Ten locales x seven names is seventy strings I cannot write.
|
||||
* Five of the seven ARE standard UN M49 macro-regions, so CLDR already names them in every locale we
|
||||
* ship, and Node's own ICU is the same data library/utils/countryName.js already trusts for countries.
|
||||
* Generating is what keeps a translation out of my hands: the strings are copied from CLDR, committed,
|
||||
* and reviewable, and re-running this reproduces them byte for byte.
|
||||
*
|
||||
* africa -> 002 · asia -> 142 · europe -> 150 · latin_america_&_caribbean -> 419 · oceania -> 009
|
||||
*
|
||||
* ★ TWO REGIONS ARE DELIBERATELY NOT WRITTEN, because CLDR has no code that means them:
|
||||
* · middle_east — M49 145 is "Western Asia", a different set (it includes the Caucasus and excludes
|
||||
* Egypt). Naming it "Western Asia" in ten locales would silently redraw the region.
|
||||
* · north_america_&_non-spanish_caribbean — M49 021 is "Northern America", which excludes the
|
||||
* Caribbean this bucket exists to include.
|
||||
* Both stay English until the Driver rules on a translation source. An English label a reader can
|
||||
* still match to the map beats a localized label that names the wrong territory.
|
||||
*
|
||||
* ★ AND ONE SCOPE NOTE ON 419: CLDR's long name is "Latin America" while our label says
|
||||
* "Latin America & Caribbean". The ENGLISH entry keeps our wording (it is the authored, authoritative
|
||||
* one); the other ten take CLDR's, which omits the Caribbean from the NAME while the bucket still holds
|
||||
* it. Recorded here rather than silently accepted — the alternative was English in ten locales.
|
||||
*
|
||||
* node internal/generate-wagf-region-names.mjs # write
|
||||
* node internal/generate-wagf-region-names.mjs --check # verify the catalogue matches CLDR (CI)
|
||||
*/
|
||||
import { readFileSync, writeFileSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const CHECK = process.argv.includes('--check')
|
||||
const M49 = { africa: '002', asia: '142', europe: '150', 'latin_america_&_caribbean': '419', oceania: '009' }
|
||||
const HELD = ['middle_east', 'north_america_&_non-spanish_caribbean']
|
||||
const LOCALES = ['ar', 'de', 'en', 'es', 'fr', 'hi', 'it', 'pt', 'ro', 'ru', 'zh']
|
||||
// The English entries stay as the product authored them (see the 419 note above); every other locale
|
||||
// is CLDR's. Read from the one file that already owns the region set, so a seventh region added there
|
||||
// shows up here as a missing name rather than as a silent English label.
|
||||
const { WAGF_REGIONS } = await import(join(ROOT, 'library/colors/wagf-region.js'))
|
||||
|
||||
const names = (lc) => {
|
||||
const dn = new Intl.DisplayNames([lc], { type: 'region' })
|
||||
const out = {}
|
||||
for (const [slug, code] of Object.entries(M49)) out[slug] = lc === 'en' ? WAGF_REGIONS[slug] : dn.of(code)
|
||||
return out
|
||||
}
|
||||
let wrote = 0
|
||||
const drift = []
|
||||
for (const lc of LOCALES) {
|
||||
const p = join(ROOT, 'library/i18n/locales', lc, 'dashboard.json')
|
||||
const cat = JSON.parse(readFileSync(p, 'utf8'))
|
||||
const want = names(lc)
|
||||
if (CHECK) {
|
||||
const have = cat.wagfRegion || {}
|
||||
for (const [k, v] of Object.entries(want)) if (have[k] !== v) drift.push(`${lc}.wagfRegion.${k}: catalogue ${JSON.stringify(have[k])} vs CLDR ${JSON.stringify(v)}`)
|
||||
continue
|
||||
}
|
||||
cat.wagfRegion = want
|
||||
writeFileSync(p, JSON.stringify(cat, null, 2) + '\n')
|
||||
wrote++
|
||||
}
|
||||
const unaccounted = Object.keys(WAGF_REGIONS).filter((s) => !M49[s] && !HELD.includes(s))
|
||||
if (unaccounted.length) {
|
||||
console.error(`WAGF-REGION-NAMES: FAIL — ${unaccounted.length} region(s) in WAGF_REGIONS have neither a CLDR code nor a recorded reason: ${unaccounted.join(', ')}`)
|
||||
process.exit(1)
|
||||
}
|
||||
if (CHECK) {
|
||||
if (drift.length) { console.error(`WAGF-REGION-NAMES: FAIL — ${drift.length} catalogue entry(ies) no longer match CLDR:\n ${drift.join('\n ')}`); process.exit(1) }
|
||||
console.log(`WAGF-REGION-NAMES: PASS — ${Object.keys(M49).length} name(s) x ${LOCALES.length} locale(s) match vendored CLDR; ${HELD.length} held in English on purpose (${HELD.join(', ')}).`)
|
||||
} else {
|
||||
console.log(`WAGF-REGION-NAMES: wrote ${Object.keys(M49).length} name(s) into ${wrote} locale catalogue(s); ${HELD.length} held in English (${HELD.join(', ')}).`)
|
||||
}
|
||||
|
|
@ -45,3 +45,43 @@ export function openPrintFrame(bodyHtml, { autoprint = false } = {}) {
|
|||
|
||||
return frame.contentWindow
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a rendered poster IMAGE, at its real paper size, through the same in-place frame.
|
||||
*
|
||||
* ★ THE DRIVER'S RULE (2026-09-28): an "Export poster" button opens the PRINT DIALOG with a preview.
|
||||
* It never hands over a file. Simple Research was rendering a PNG and calling a download helper, so
|
||||
* the reader got doxa-prayer-poster.png in their downloads folder and no preview, no paper size, and
|
||||
* no way to print it without opening it somewhere else first. The dialog IS the preview: the sheet the
|
||||
* browser shows is the poster, at the size the spec asked for.
|
||||
*
|
||||
* @page carries the spec's own inches so the preview is not letter-shaped by default — a 8.5x11
|
||||
* poster previewed on A4 is a different document from the one that was rendered. margin:0 because the
|
||||
* renderer already composed the margins into the image; a second set would scale the poster down.
|
||||
*
|
||||
* The object URL is revoked on afterprint AND on the frame's 60s reclaim, since afterprint does not
|
||||
* fire in every engine when the dialog is dismissed. Revoking early would blank the preview, so the
|
||||
* image element is kept alive by the frame itself rather than by a timer here.
|
||||
*
|
||||
* Returns true when the dialog was opened, false when the host blocked the frame — the caller decides
|
||||
* what to do about it, because a silent no-op is exactly the failure this replaced.
|
||||
*/
|
||||
export function printImageBlob(blob, { widthIn = 8.5, heightIn = 11, title = '', alt = '' } = {}) {
|
||||
if (!blob || typeof URL === 'undefined' || !URL.createObjectURL) return false
|
||||
const url = URL.createObjectURL(blob)
|
||||
const esc = (v) => String(v).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]))
|
||||
// The image is sized by the PAGE, not by its pixels: object-fit keeps a poster rendered at any DPI
|
||||
// on its own sheet without cropping. The <img> also gates the print — openPrintFrame's bootstrap
|
||||
// waits for load, which is what keeps the first page from printing blank.
|
||||
const html = `<!doctype html><html><head><meta charset="utf-8"><title>${esc(title)}</title>`
|
||||
+ `<style>@page{size:${widthIn}in ${heightIn}in;margin:0}`
|
||||
+ 'html,body{margin:0;padding:0;background:#fff}'
|
||||
+ 'img{display:block;width:100%;height:100%;object-fit:contain}</style></head>'
|
||||
+ `<body><img src="${url}" alt="${esc(alt || title)}"></body></html>`
|
||||
const win = openPrintFrame(html, { autoprint: true })
|
||||
if (!win) { URL.revokeObjectURL(url); return false }
|
||||
const revoke = () => { try { URL.revokeObjectURL(url) } catch { /* already gone */ } }
|
||||
try { win.addEventListener('afterprint', () => setTimeout(revoke, 0)) } catch { /* cross-doc guard */ }
|
||||
setTimeout(revoke, 60000)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -482,7 +482,6 @@ export function useMapClustering(options = {}) {
|
|||
}
|
||||
|
||||
_attachClusterClickHandler(map);
|
||||
console.log(`[${mapId}] Clustering: mapbox-native applied (${features.length} features)`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -566,10 +565,6 @@ export function useMapClustering(options = {}) {
|
|||
_setLayerVisibility(map, CLUSTER_LINES_LAYER, true);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[${mapId}] Clustering: ${algorithm} applied — ` +
|
||||
`${lines.length} lines across ${stats?.totalGroups ?? 0} groups`
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "المحدَّدة أولاً",
|
||||
"selected_first_hint": "رفع الشعوب المحدَّدة إلى الأعلى مع الإبقاء على ترتيب الأعمدة",
|
||||
"n_shown": "{n} معروض",
|
||||
"other": "أخرى"
|
||||
"other": "أخرى",
|
||||
"wagfRegion": {
|
||||
"africa": "أفريقيا",
|
||||
"asia": "آسيا",
|
||||
"europe": "أوروبا",
|
||||
"latin_america_&_caribbean": "أمريكا اللاتينية",
|
||||
"oceania": "أوقيانوسيا"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Ausgewählte zuerst",
|
||||
"selected_first_hint": "Die ausgewählten Volksgruppen nach oben holen, die Spaltensortierung bleibt erhalten",
|
||||
"n_shown": "{n} angezeigt",
|
||||
"other": "Andere"
|
||||
"other": "Andere",
|
||||
"wagfRegion": {
|
||||
"africa": "Afrika",
|
||||
"asia": "Asien",
|
||||
"europe": "Europa",
|
||||
"latin_america_&_caribbean": "Lateinamerika",
|
||||
"oceania": "Ozeanien"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Selected first",
|
||||
"selected_first_hint": "Float the selected people groups to the top, keeping your column sort",
|
||||
"n_shown": "{n} shown",
|
||||
"other": "Other"
|
||||
"other": "Other",
|
||||
"wagfRegion": {
|
||||
"africa": "Africa",
|
||||
"asia": "Asia",
|
||||
"europe": "Europe",
|
||||
"latin_america_&_caribbean": "Latin America & Caribbean",
|
||||
"oceania": "Oceania"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Los seleccionados primero",
|
||||
"selected_first_hint": "Llevar arriba los grupos de personas seleccionados, manteniendo el orden de las columnas",
|
||||
"n_shown": "{n} mostrados",
|
||||
"other": "Otros"
|
||||
"other": "Otros",
|
||||
"wagfRegion": {
|
||||
"africa": "África",
|
||||
"asia": "Asia",
|
||||
"europe": "Europa",
|
||||
"latin_america_&_caribbean": "Latinoamérica",
|
||||
"oceania": "Oceanía"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "La sélection en premier",
|
||||
"selected_first_hint": "Faire remonter les groupes de personnes sélectionnés, en conservant le tri des colonnes",
|
||||
"n_shown": "{n} affichés",
|
||||
"other": "Autres"
|
||||
"other": "Autres",
|
||||
"wagfRegion": {
|
||||
"africa": "Afrique",
|
||||
"asia": "Asie",
|
||||
"europe": "Europe",
|
||||
"latin_america_&_caribbean": "Amérique latine",
|
||||
"oceania": "Océanie"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "चयनित पहले",
|
||||
"selected_first_hint": "चयनित जनसमूहों को ऊपर लाएँ, आपका कॉलम क्रम बनाए रखते हुए",
|
||||
"n_shown": "{n} दिखाए गए",
|
||||
"other": "अन्य"
|
||||
"other": "अन्य",
|
||||
"wagfRegion": {
|
||||
"africa": "अफ़्रीका",
|
||||
"asia": "एशिया",
|
||||
"europe": "यूरोप",
|
||||
"latin_america_&_caribbean": "लैटिन अमेरिका",
|
||||
"oceania": "ओशिआनिया"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Prima i selezionati",
|
||||
"selected_first_hint": "Porta in alto i gruppi di persone selezionati, mantenendo l’ordinamento delle colonne",
|
||||
"n_shown": "{n} mostrati",
|
||||
"other": "Altri"
|
||||
"other": "Altri",
|
||||
"wagfRegion": {
|
||||
"africa": "Africa",
|
||||
"asia": "Asia",
|
||||
"europe": "Europa",
|
||||
"latin_america_&_caribbean": "America Latina",
|
||||
"oceania": "Oceania"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Os selecionados primeiro",
|
||||
"selected_first_hint": "Trazer para cima os grupos de pessoas selecionados, mantendo a ordenação das colunas",
|
||||
"n_shown": "{n} apresentados",
|
||||
"other": "Outros"
|
||||
"other": "Outros",
|
||||
"wagfRegion": {
|
||||
"africa": "África",
|
||||
"asia": "Ásia",
|
||||
"europe": "Europa",
|
||||
"latin_america_&_caribbean": "América Latina",
|
||||
"oceania": "Oceania"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Cele selectate primele",
|
||||
"selected_first_hint": "Ridică grupurile de oameni selectate în partea de sus, păstrând sortarea coloanelor",
|
||||
"n_shown": "{n} afișate",
|
||||
"other": "Altele"
|
||||
"other": "Altele",
|
||||
"wagfRegion": {
|
||||
"africa": "Africa",
|
||||
"asia": "Asia",
|
||||
"europe": "Europa",
|
||||
"latin_america_&_caribbean": "America Latină",
|
||||
"oceania": "Oceania"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "Выбранные сначала",
|
||||
"selected_first_hint": "Поднять выбранные народы наверх, сохранив сортировку столбцов",
|
||||
"n_shown": "{n} показано",
|
||||
"other": "Другое"
|
||||
"other": "Другое",
|
||||
"wagfRegion": {
|
||||
"africa": "Африка",
|
||||
"asia": "Азия",
|
||||
"europe": "Европа",
|
||||
"latin_america_&_caribbean": "Латинская Америка",
|
||||
"oceania": "Океания"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,12 @@
|
|||
"selected_first": "所选优先",
|
||||
"selected_first_hint": "将所选民族置顶,同时保留您的列排序",
|
||||
"n_shown": "显示 {n} 个",
|
||||
"other": "其他"
|
||||
"other": "其他",
|
||||
"wagfRegion": {
|
||||
"africa": "非洲",
|
||||
"asia": "亚洲",
|
||||
"europe": "欧洲",
|
||||
"latin_america_&_caribbean": "拉丁美洲",
|
||||
"oceania": "大洋洲"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import countries from '../data/countries.json'
|
|||
|
||||
const ALPHA2 = table.map
|
||||
const ENGLISH = new Map(countries.map((c) => [c.value, c.label]))
|
||||
const BY_ENGLISH = new Map(countries.map((c) => [String(c.label).trim().toLowerCase(), c.value]))
|
||||
|
||||
/** The alpha-2 for an alpha-3 code, or undefined. Exported because callers building URLs and flag
|
||||
* assets need the same lookup, and a second copy of it would drift. */
|
||||
|
|
@ -49,6 +50,24 @@ export function alpha2Of(iso3) {
|
|||
return iso3 ? ALPHA2[String(iso3).toUpperCase()] : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* The alpha-3 for a canonical ENGLISH country name, or undefined.
|
||||
*
|
||||
* ★ FOR LABELS THAT ARRIVE IN ENGLISH WITH NO CODE ATTACHED — the case the header's ✓ names. Big
|
||||
* Picture's top-countries chart aggregates on the prayer API's English country LABEL, so by the time a
|
||||
* bar is drawn the alpha-3 is gone and only "India" is in hand. Reversing our own countries.json is
|
||||
* exact where it matches and silent where it does not, which is the only safe shape here: an unmatched
|
||||
* name keeps rendering as itself rather than becoming a code or a blank.
|
||||
*
|
||||
* Built from the SAME table englishName() reads, so the two can never disagree about which name is
|
||||
* canonical. Names are compared case-insensitively and trimmed; nothing else is normalized, because a
|
||||
* looser match is how "Congo" would quietly become the wrong country.
|
||||
*/
|
||||
export function iso3ForEnglishName(name) {
|
||||
if (!name) return undefined
|
||||
return BY_ENGLISH.get(String(name).trim().toLowerCase())
|
||||
}
|
||||
|
||||
/** The canonical English name, or undefined. */
|
||||
export function englishName(iso3) {
|
||||
return iso3 ? ENGLISH.get(String(iso3).toUpperCase()) : undefined
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@
|
|||
"check:embedder-keys": "node plugin-designs/regions-dashboard/scripts/check-embedder-keys.mjs",
|
||||
"check:english-leaks": "node internal/check-gospel-english-leaks.mjs",
|
||||
"check:experimental-shelf": "node internal/check-experimental-shelf.mjs",
|
||||
"check:export-one-click": "node plugin-designs/doxa-research-map/scripts/check-export-one-click.mjs",
|
||||
"check:export-one-click:maplibre": "node plugin-designs/doxa-research-map/scripts/check-export-one-click.mjs --provider maplibre",
|
||||
"check:export-poster-prints": "node plugin-designs/doxa-research-map/scripts/check-export-poster-prints.mjs",
|
||||
"check:export-poster-prints:maplibre": "node plugin-designs/doxa-research-map/scripts/check-export-poster-prints.mjs --provider maplibre",
|
||||
"check:facet-cascade": "node internal/check-facet-cascade.mjs",
|
||||
"check:facet-cascade:offline": "node internal/check-facet-cascade.mjs --offline",
|
||||
"check:facet-cascade:self-test": "node internal/check-facet-cascade.mjs --self-test",
|
||||
|
|
@ -332,8 +332,8 @@
|
|||
"check:embedder-keys": "regions-mfe forwards page-scoped config to its nested panes by an explicit key list (INHERITED_PAGE_KEYS). Asserts the documented embedder keys travel (dataSource, tokenUrl among them) AND that profile and instanceId do NOT: the host's would overwrite each pane's own and collapse both tabs into one view.",
|
||||
"check:english-leaks": "A translated key must not render in English. rega's method: a string is a LEAK when the catalogue has a DIFFERENT value for the locale and the page still shows the English one - a render/wiring fault, not a missing translation. Third-party attributions, data names, placeholder-only strings and the prose this bundle deliberately keeps in English are all excluded, the last by simply not being in the catalogue. Scoped to the LEAF on purpose: six keys were reported leaking in the gallery and the leaf is clean in ar/zh/ru/hi - the gallery builds its iframe src with no lang parameter, so the embed never learns the locale. Embedder defect, not a bundle one.",
|
||||
"check:experimental-shelf": "Every Experimental-folder bundle, leaf + Gallery tab, mapbox + maplibre: mounts with content, 0 errors / failed requests, maps load and DRAW their own data. Self-tests on a deliberately broken bundle first. Run through internal/browser-slot.sh.",
|
||||
"check:export-one-click": "the Simple Research 'Export poster' button gives a FILE on ONE click (no menu, no dialog, no second step): leaf AND Research Gallery, en AND ar; the file is a real print PNG (US Letter @200 DPI); 0 page errors. Run inside the shared browser slot. Exit 2 = SKIP, 75 = NOT MEASURED.",
|
||||
"check:export-one-click:maplibre": "the same four one-click exports on the keyless MapLibre engine (OpenFreeMap tiles): the hidden print map must be built with the engine that drew the screen, and the footer must credit the tiles actually printed.",
|
||||
"check:export-poster-prints": "the Simple Research 'Export poster' button opens the PRINT DIALOG on the poster in ONE click and downloads NOTHING (the Driver's rule, 2026-09-28): leaf AND Research Gallery, en AND ar; the printing document is the 1700x2200 poster on an 8.5in x 11in sheet; no download arrives; 0 page errors. window.print is stubbed, so this measures everything up to the dialog. Replaces check:export-one-click, which asserted the download this rule forbids. Run inside the shared browser slot. Exit 2 = SKIP, 75 = NOT MEASURED.",
|
||||
"check:export-poster-prints:maplibre": "the same four one-click prints on the keyless MapLibre engine (OpenFreeMap tiles): the hidden print map must be built with the engine that drew the screen, and the footer must credit the tiles actually printed.",
|
||||
"check:facet-cascade": "a child facet selection must not outlive its parent: clearing a parent facet must cascade-clear its descendants on EVERY clear path. Asserts on RESULT COUNTS, not DOM — an orphaned child silently ANDs the map to empty. run check:facet-cascade:self-test for the NEGATIVE test (reverts the cascade and requires this gate to FAIL).",
|
||||
"check:facet-changes-map": "a facet selection must CHANGE THE DOTS — and the dots must SAY what they mean. Asserts (1) the rd-bubbles feature set changes by count AND identity, (2) every surviving dot satisfies the selected level, (3) while a prayer filter is active circle-color is a DATA-DRIVEN EXPRESSION reading peoplePraying, not a flat literal. Assertion 3 is the one that matters: the prayer filter ALREADY narrowed 2107->689 correctly while the Driver reported it broken, because every dot painted the same orange. Browser gate (needs `bun run dev` on 5173, or BASE_URL/PROBE_PATH at a served tree), so NOT in build:unlocked. run the `check:facet-changes-map:self-test` script for the NEGATIVE test.",
|
||||
"check:facet-changes-map:built": "the SAME gate against the BUILT tree instead of the dev server. Measured 2026-09-24: the dev default is 1 PASS / 3 FAIL in four runs on a busy box (88 unbundled module requests vs the built leaf's 3), while the built tree passes deterministically. Use this when you need a trustworthy answer; use the dev default when checking uncommitted source.",
|
||||
|
|
|
|||
|
|
@ -1299,16 +1299,17 @@ watch(() => mapStore.selectedRegion, (key) => {
|
|||
// required getMap, so it mounted invisible; and the old loader called useMapPoster({ sourceMap, … })
|
||||
// with an OBJECT where the shared composable takes a FUNCTION, so a render would have thrown anyway.
|
||||
// Now the button does the export itself, through the SHARED poster path (useMapPoster → render →
|
||||
// download), with a sensible print default: the current view on US Letter portrait at 200 DPI, the
|
||||
// legend title and rows, and a source/date footer. No dialog, no second step.
|
||||
// print), with a sensible print default: the current view on US Letter portrait at 200 DPI, the
|
||||
// legend title and rows, and a source/date footer. One click, one dialog, the poster in the preview.
|
||||
const posterBusy = ref(false)
|
||||
async function openPoster() {
|
||||
if (posterBusy.value) return
|
||||
posterBusy.value = true
|
||||
try {
|
||||
const [{ useMapPoster }, { defaultPosterSpec }] = await Promise.all([
|
||||
const [{ useMapPoster }, { defaultPosterSpec }, { printImageBlob }] = await Promise.all([
|
||||
import('@map/composables/poster/useMapPoster.js'),
|
||||
import('@map/constants/posterDefaults.js'),
|
||||
import('@map/composables/printInPlace.js'),
|
||||
])
|
||||
const exporter = useMapPoster(() => map.value)
|
||||
const spec = defaultPosterSpec({ widthIn: 8.5, heightIn: 11, dpi: 200, orientation: 'portrait' })
|
||||
|
|
@ -1333,19 +1334,31 @@ async function openPoster() {
|
|||
spec.slots.footer = { ...spec.slots.footer, left: 'pray.doxa.life', right: new Date().toISOString().slice(0, 10),
|
||||
attribution: onMaplibre ? '© OpenFreeMap © OpenMapTiles © OpenStreetMap' : '© Mapbox © OpenStreetMap' }
|
||||
const blob = await exporter.render(spec, 'png')
|
||||
// File name from the view's id, not its title: an Arabic or Chinese title has no ASCII letters
|
||||
// to keep, and every reader's file would otherwise be the same "doxa-map-poster.png".
|
||||
const slug = String(activeTab.value?.id || '').replace(/[^a-z0-9]+/gi, '-').replace(/^-+|-+$/g, '').toLowerCase()
|
||||
_downloadBlob(blob, 'doxa-' + (slug || 'map') + '-poster.png')
|
||||
// ★ THE DIALOG, NOT A DOWNLOAD (the Driver, 2026-09-28: an export-poster button must open the
|
||||
// print dialog with a poster preview, never hand over a file). This used to call _downloadBlob,
|
||||
// so the reader got a PNG in their downloads folder with no preview, no paper size and no way to
|
||||
// print it without opening it somewhere else first. printImageBlob puts the rendered poster on a
|
||||
// sheet of exactly the spec's size and raises the dialog over the map — the preview IS the poster.
|
||||
// The same in-place frame the Driver's earlier ruling settled on: no pop-up, no blocker, and it
|
||||
// works when an agent triggers it without a user gesture.
|
||||
const printed = printImageBlob(blob, {
|
||||
widthIn: spec.widthIn ?? 8.5,
|
||||
heightIn: spec.heightIn ?? 11,
|
||||
title,
|
||||
alt: title,
|
||||
})
|
||||
// An unopenable frame (sandboxed or detached host) is reported, not silently swallowed: a button
|
||||
// that looks like it worked and did nothing is the defect this whole path has already had once.
|
||||
if (!printed) console.error('[research-map] poster print: the host blocked the print frame')
|
||||
} catch (err) {
|
||||
console.error('[research-map] poster export failed:', err)
|
||||
} finally {
|
||||
posterBusy.value = false
|
||||
}
|
||||
}
|
||||
// The toolbar's export label: the drawer's translated 'Export poster…' WITHOUT the ellipsis — an
|
||||
// ellipsis promises a dialog, and this button hands over the file directly.
|
||||
const exportPosterLabel = computed(() => String(t('controls.export_poster') || 'Export poster').replace(/\s*…\s*$/, ''))
|
||||
// The toolbar's export label, WITH its ellipsis. The ellipsis was stripped while this button handed
|
||||
// over a file directly; it now opens the print dialog, which is exactly what an ellipsis promises.
|
||||
const exportPosterLabel = computed(() => String(t('controls.export_poster') || 'Export poster…'))
|
||||
|
||||
// ─── Export menu router (SemanticTreeLegend @export) ─────────────────────────
|
||||
// EXPERIMENTAL — dormant behind the shared kill-switch (SHOW_EXPORT_BUTTON).
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-export-one-click.mjs — the Simple Research "Export poster" button gives you a FILE on ONE
|
||||
* click, with no menu, dialog or second step, in its own leaf AND inside the Research Gallery, in
|
||||
* en AND ar.
|
||||
*
|
||||
* WHY (card BUILD-SIMPLE-RESEARCH-EXPORT-ZERO-CLICK; the Driver: "there's an export button on the
|
||||
* simple dashboard ... get it working"). Measured 2026-09-25 before the fix: one click produced
|
||||
* NOTHING — no dialog, no file within 60s, no error — in both hosts. A silent dead button reads as
|
||||
* "the export is slow" to a reader, never as "it is broken", so no other gate could see it.
|
||||
*
|
||||
* WHAT IT ASSERTS, per host × language:
|
||||
* 1. exactly ONE click on the ALWAYS-VISIBLE export button in the map toolbar (button.export-poster-btn).
|
||||
* The drawer's "Export poster…" does not count: the drawer is CLOSED by default (translated off
|
||||
* screen), so it costs an extra click to reach — measured 2026-09-25, and in Arabic the button
|
||||
* could not be clicked at all. The toolbar button must be on screen with no preparation;
|
||||
* 2. a download arrives within 120s, WITHOUT any further click;
|
||||
* 3. the file is a real PNG (signature) of the print size (US Letter at 200 DPI = 1700x2200);
|
||||
* 4. 0 page errors.
|
||||
*
|
||||
* Runs through internal/browser-slot.sh like every browser gate. Starts its own servers on
|
||||
* OS-assigned ports and proves the server is THIS checkout's tree before measuring.
|
||||
* --provider maplibre runs the same four on the keyless engine.
|
||||
* EXPORT_SAVE_DIR=<dir> keeps each downloaded poster (<host>-<lang>-<file>) so a person can look at it.
|
||||
* Exit: 0 pass · 1 fail · 2 SKIP (no built tree / no playwright) · 75 NOT MEASURED (server identity)
|
||||
*/
|
||||
import { createServer } from 'node:http'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..')
|
||||
// The tree's name comes from the build config, never a literal: the doxa-maps -> dx-maps rename
|
||||
// turned the literal into a silent SKIP (exit 2) that measured nothing.
|
||||
const { TREE_NAME } = await import(resolve(ROOT, 'internal/_tree-name.mjs'))
|
||||
if (!existsSync(resolve(ROOT, `public/${TREE_NAME}/research-map-plus-grid/research-map-plus-grid.js`))) {
|
||||
console.log('SKIP check-export-one-click: no built research-map-plus-grid'); process.exit(2)
|
||||
}
|
||||
let chromium
|
||||
try { ({ chromium } = await import('playwright')) } catch { console.log('SKIP check-export-one-click: playwright not installed'); process.exit(2) }
|
||||
|
||||
const freePort = () => new Promise(ok => { const s = createServer().listen(0, '127.0.0.1', () => { const p = s.address().port; s.close(() => ok(p)) }) })
|
||||
const PROVIDER = process.argv.includes('--provider') ? process.argv[process.argv.indexOf('--provider') + 1] : '' // maplibre = the keyless engine
|
||||
const TP = await freePort(), HP = await freePort()
|
||||
const TREE = `http://127.0.0.1:${TP}/${TREE_NAME}`
|
||||
let lang = 'en'
|
||||
const srv = spawn(process.execPath, ['internal/serve-strict.mjs', '--port', String(TP)], { cwd: ROOT, stdio: 'ignore' })
|
||||
const host = createServer((_, r) => { r.writeHead(200, { 'content-type': 'text/html' }); r.end(`<!doctype html><html lang="${lang}"><body style="margin:0"><script src="${TREE}/doxa-maps-spa/doxa-maps-spa.js"></script><doxa-maps-spa tab="research-map-plus-grid"${PROVIDER ? ` provider="${PROVIDER}"` : ''} style="height:900px"></doxa-maps-spa></body></html>`) }).listen(HP, 'localhost')
|
||||
const cleanup = () => { try { srv.kill() } catch {} try { host.close() } catch {} }
|
||||
await new Promise(r => setTimeout(r, 800))
|
||||
|
||||
// Server identity by CONTENT: the served manifest must be this checkout's.
|
||||
{
|
||||
const disk = readFileSync(resolve(ROOT, `public/${TREE_NAME}/manifest.json`), 'utf8')
|
||||
let served = ''
|
||||
for (let i = 0; i < 20 && !served; i++) {
|
||||
try { const r = await fetch(`${TREE}/manifest.json`); if (r.ok) served = await r.text() } catch { /* not up yet */ }
|
||||
if (!served) await new Promise(r => setTimeout(r, 300))
|
||||
}
|
||||
if (served !== disk) { console.log(`NOT MEASURED: :${TP} is not serving this checkout's tree. Re-run.`); cleanup(); process.exit(75) }
|
||||
}
|
||||
|
||||
const b = await chromium.launch({ args: ['--use-angle=swiftshader', '--enable-unsafe-swiftshader'] })
|
||||
const fails = []
|
||||
try {
|
||||
for (lang of ['en', 'ar']) for (const where of ['leaf', 'gallery']) {
|
||||
const url = where === 'leaf' ? `${TREE}/research-map-plus-grid/research-map-plus-grid/index.html?lang=${lang}${PROVIDER ? `&provider=${PROVIDER}` : ''}` : `http://localhost:${HP}/`
|
||||
const ctx = await b.newContext({ acceptDownloads: true, viewport: { width: 1400, height: 900 } })
|
||||
const p = await ctx.newPage(); const errs = []
|
||||
p.on('pageerror', e => errs.push(String(e).slice(0, 160)))
|
||||
// A failed export is CAUGHT and logged (console.error), never thrown: read the console, or a dead
|
||||
// button reports "no file" with no reason.
|
||||
const consoleErrs = []; p.on('console', m => { if (m.type() === 'error' || m.type() === 'warning') consoleErrs.push(m.text().slice(0, 200)) })
|
||||
const downloads = []; p.on('download', d => downloads.push(d))
|
||||
await p.goto(url); await p.waitForTimeout(12000)
|
||||
const btn = p.locator('button.export-poster-btn').first()
|
||||
const onScreen = await btn.evaluate(el => { const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0 && r.left >= 0 && r.top >= 0 && r.right <= innerWidth && r.bottom <= innerHeight }).catch(() => false)
|
||||
if (!onScreen) errs.push('the export button is not on screen without a prior click')
|
||||
const label = ((await btn.getAttribute('title', { timeout: 20000 }).catch(() => '')) || '').trim()
|
||||
let clicks = 0
|
||||
// ONE PHYSICAL CLICK at the button's centre, as a reader makes it. Not locator.click(): that
|
||||
// re-checks its hit target and RETRIES, and by the retry the button is already disabled (the
|
||||
// export is running), so it reported "timeout" on exports whose file then arrived — measured
|
||||
// 2026-09-25 in gallery-ar and leaf-en. What the click achieved is judged by the file below.
|
||||
try {
|
||||
const box = await btn.boundingBox({ timeout: 20000 })
|
||||
if (!box) throw new Error('the export button has no box')
|
||||
await p.mouse.click(box.x + box.width / 2, box.y + box.height / 2); clicks = 1
|
||||
} catch (e) { errs.push('could not click: ' + String(e.message || e).split('\n')[0]) }
|
||||
for (let i = 0; i < 120 && !downloads.length; i++) await p.waitForTimeout(1000)
|
||||
let file = null, info = ''
|
||||
if (downloads.length) {
|
||||
file = downloads[0].suggestedFilename()
|
||||
const path = await downloads[0].path()
|
||||
const buf = readFileSync(path)
|
||||
if (process.env.EXPORT_SAVE_DIR) writeFileSync(resolve(process.env.EXPORT_SAVE_DIR, `${where}-${lang}${PROVIDER ? '-' + PROVIDER : ''}-${file}`), buf) // to LOOK at the poster
|
||||
const png = buf.length > 24 && buf.slice(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))
|
||||
const w = png ? buf.readUInt32BE(16) : 0, h = png ? buf.readUInt32BE(20) : 0
|
||||
info = `${png ? 'PNG' : 'NOT-PNG'} ${w}x${h} ${Math.round(buf.length / 1024)}KB`
|
||||
if (!png || w < 1600 || h < 2100) errs.push(`file is not the expected print PNG (${info})`)
|
||||
}
|
||||
if (!file) {
|
||||
for (const c of consoleErrs.filter(c => /poster|useMapPoster/i.test(c)).slice(-2)) errs.push(c)
|
||||
// SLOW or DEAD? A button still busy at the deadline is a render still running; an idle one is an
|
||||
// export that ended without a file. The verdict is FAIL either way; the reason says which.
|
||||
const busy = await btn.evaluate(el => el.disabled || el.getAttribute('aria-busy') === 'true').catch(() => null)
|
||||
errs.push(busy ? 'still rendering at the deadline (button busy)' : 'the export ended with no file (button idle)')
|
||||
}
|
||||
const ok = clicks === 1 && !!file && !errs.length
|
||||
console.log(`${ok ? 'PASS' : 'FAIL'} [${where} ${lang}${PROVIDER ? ' ' + PROVIDER : ''}] "${label}" · 1 click → ${file ? `${file} (${info})` : 'NO FILE within 120s'}${errs.length ? ' · ' + [...new Set(errs)].slice(0, 3).join(' | ') : ' · 0 errors'}`)
|
||||
if (!ok) fails.push(`${where} ${lang}`)
|
||||
await ctx.close()
|
||||
}
|
||||
} finally { await b.close(); cleanup() }
|
||||
|
||||
if (fails.length) { console.log(`\ncheck-export-one-click: FAIL (${fails.join(', ')})`); process.exit(1) }
|
||||
console.log('\ncheck-export-one-click: PASS — one click on Export poster gives a print PNG, leaf and gallery, en and ar')
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-export-poster-prints.mjs — the Simple Research "Export poster" button opens the PRINT DIALOG
|
||||
* with the poster in it, on ONE click, in its own leaf AND inside the Research Gallery, in en AND ar.
|
||||
* It must NEVER hand over a file.
|
||||
*
|
||||
* ★ THE RULE CHANGED, AND THIS GATE ASSERTED THE OLD ONE (the Driver, 2026-09-28: "an export-poster
|
||||
* button must open the print dialog with a poster preview, never a direct download"). It was
|
||||
* check-export-one-click, and it passed while the button did exactly what the Driver has now ruled
|
||||
* against: render a PNG and drop it in the downloads folder. A gate that encodes a superseded ruling
|
||||
* is worse than no gate — it defends the defect. The earlier history is still why the click path is
|
||||
* measured so carefully: before 2026-09-25 one click produced NOTHING, no dialog, no file, no error.
|
||||
*
|
||||
* WHAT IT ASSERTS, per host × language:
|
||||
* 1. exactly ONE click on the ALWAYS-VISIBLE export button in the map toolbar
|
||||
* (button.export-poster-btn). The drawer's "Export poster…" does not count: the drawer is CLOSED
|
||||
* by default (translated off screen), so it costs an extra click to reach — measured 2026-09-25,
|
||||
* and in Arabic the button could not be clicked at all;
|
||||
* 2. within 120s and with no further click, some frame calls window.print();
|
||||
* 3. the printing document IS the poster: an <img> at the print size (US Letter at 200 DPI =
|
||||
* 1700x2200) on an @page sized 8.5in x 11in. A dialog over a blank or letter-defaulted sheet is
|
||||
* not a preview of what was rendered;
|
||||
* 4. NO download arrives. This is the half that encodes the new rule, and it is asserted for the
|
||||
* whole run rather than at a moment, because a download that lands late is still a download;
|
||||
* 5. 0 page errors.
|
||||
*
|
||||
* ★ window.print IS STUBBED, not called through. The native dialog is modal and would hang the run
|
||||
* forever, so the init script records the call and returns. That makes this a test of everything up to
|
||||
* the dialog — the frame, the sheet size and the image — and not of the browser's own chrome, which is
|
||||
* the correct boundary for a headless gate.
|
||||
*
|
||||
* Runs through internal/browser-slot.sh like every browser gate. Starts its own servers on
|
||||
* OS-assigned ports and proves the server is THIS checkout's tree before measuring.
|
||||
* --provider maplibre runs the same four on the keyless engine.
|
||||
* Exit: 0 pass · 1 fail · 2 SKIP (no built tree / no playwright) · 75 NOT MEASURED (server identity)
|
||||
*/
|
||||
import { createServer } from 'node:http'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { existsSync, readFileSync } from 'node:fs'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..')
|
||||
// The tree's name comes from the build config, never a literal: the doxa-maps -> dx-maps rename
|
||||
// turned the literal into a silent SKIP (exit 2) that measured nothing.
|
||||
const { TREE_NAME } = await import(resolve(ROOT, 'internal/_tree-name.mjs'))
|
||||
if (!existsSync(resolve(ROOT, `public/${TREE_NAME}/research-map-plus-grid/research-map-plus-grid.js`))) {
|
||||
console.log('SKIP check-export-poster-prints: no built research-map-plus-grid'); process.exit(2)
|
||||
}
|
||||
let chromium
|
||||
try { ({ chromium } = await import('playwright')) } catch { console.log('SKIP check-export-poster-prints: playwright not installed'); process.exit(2) }
|
||||
|
||||
const freePort = () => new Promise(ok => { const s = createServer().listen(0, '127.0.0.1', () => { const p = s.address().port; s.close(() => ok(p)) }) })
|
||||
const PROVIDER = process.argv.includes('--provider') ? process.argv[process.argv.indexOf('--provider') + 1] : '' // maplibre = the keyless engine
|
||||
const TP = await freePort(), HP = await freePort()
|
||||
const TREE = `http://127.0.0.1:${TP}/${TREE_NAME}`
|
||||
let lang = 'en'
|
||||
const srv = spawn(process.execPath, ['internal/serve-strict.mjs', '--port', String(TP)], { cwd: ROOT, stdio: 'ignore' })
|
||||
const host = createServer((_, r) => { r.writeHead(200, { 'content-type': 'text/html' }); r.end(`<!doctype html><html lang="${lang}"><body style="margin:0"><script src="${TREE}/doxa-maps-spa/doxa-maps-spa.js"></script><doxa-maps-spa tab="research-map-plus-grid"${PROVIDER ? ` provider="${PROVIDER}"` : ''} style="height:900px"></doxa-maps-spa></body></html>`) }).listen(HP, 'localhost')
|
||||
const cleanup = () => { try { srv.kill() } catch {} try { host.close() } catch {} }
|
||||
await new Promise(r => setTimeout(r, 800))
|
||||
|
||||
// Server identity by CONTENT: the served manifest must be this checkout's.
|
||||
{
|
||||
const disk = readFileSync(resolve(ROOT, `public/${TREE_NAME}/manifest.json`), 'utf8')
|
||||
let served = ''
|
||||
for (let i = 0; i < 20 && !served; i++) {
|
||||
try { const r = await fetch(`${TREE}/manifest.json`); if (r.ok) served = await r.text() } catch { /* not up yet */ }
|
||||
if (!served) await new Promise(r => setTimeout(r, 300))
|
||||
}
|
||||
if (served !== disk) { console.log(`NOT MEASURED: :${TP} is not serving this checkout's tree. Re-run.`); cleanup(); process.exit(75) }
|
||||
}
|
||||
|
||||
const b = await chromium.launch({ args: ['--use-angle=swiftshader', '--enable-unsafe-swiftshader'] })
|
||||
const fails = []
|
||||
try {
|
||||
for (lang of ['en', 'ar']) for (const where of ['leaf', 'gallery']) {
|
||||
const url = where === 'leaf' ? `${TREE}/research-map-plus-grid/research-map-plus-grid/index.html?lang=${lang}${PROVIDER ? `&provider=${PROVIDER}` : ''}` : `http://localhost:${HP}/`
|
||||
const ctx = await b.newContext({ acceptDownloads: true, viewport: { width: 1400, height: 900 } })
|
||||
// Every frame, because the poster prints from an iframe the app creates (printInPlace.js). The
|
||||
// override lives on the WINDOW, which survives the document.open()/write() that fills that frame.
|
||||
// acceptDownloads stays TRUE on purpose: a download must be observable to be failed on.
|
||||
await ctx.addInitScript(() => {
|
||||
window.__printed = []
|
||||
window.print = function () {
|
||||
const img = document.querySelector('img')
|
||||
const style = document.querySelector('style')
|
||||
window.__printed.push({
|
||||
imgW: img ? img.naturalWidth : 0,
|
||||
imgH: img ? img.naturalHeight : 0,
|
||||
page: style ? (String(style.textContent).match(/@page\{size:([^;}]+)/) || [])[1] || '' : '',
|
||||
})
|
||||
}
|
||||
})
|
||||
const p = await ctx.newPage(); const errs = []
|
||||
p.on('pageerror', e => errs.push(String(e).slice(0, 160)))
|
||||
// A failed export is CAUGHT and logged (console.error), never thrown: read the console, or a dead
|
||||
// button reports "no file" with no reason.
|
||||
const consoleErrs = []; p.on('console', m => { if (m.type() === 'error' || m.type() === 'warning') consoleErrs.push(m.text().slice(0, 200)) })
|
||||
const downloads = []; p.on('download', d => downloads.push(d))
|
||||
await p.goto(url); await p.waitForTimeout(12000)
|
||||
const btn = p.locator('button.export-poster-btn').first()
|
||||
const onScreen = await btn.evaluate(el => { const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0 && r.left >= 0 && r.top >= 0 && r.right <= innerWidth && r.bottom <= innerHeight }).catch(() => false)
|
||||
if (!onScreen) errs.push('the export button is not on screen without a prior click')
|
||||
const label = ((await btn.getAttribute('title', { timeout: 20000 }).catch(() => '')) || '').trim()
|
||||
let clicks = 0
|
||||
// ONE PHYSICAL CLICK at the button's centre, as a reader makes it. Not locator.click(): that
|
||||
// re-checks its hit target and RETRIES, and by the retry the button is already disabled (the
|
||||
// export is running), so it reported "timeout" on exports whose file then arrived — measured
|
||||
// 2026-09-25 in gallery-ar and leaf-en. What the click achieved is judged by the file below.
|
||||
try {
|
||||
const box = await btn.boundingBox({ timeout: 20000 })
|
||||
if (!box) throw new Error('the export button has no box')
|
||||
await p.mouse.click(box.x + box.width / 2, box.y + box.height / 2); clicks = 1
|
||||
} catch (e) { errs.push('could not click: ' + String(e.message || e).split('\n')[0]) }
|
||||
// Poll every frame: the print call happens in the iframe printInPlace creates, which is not
|
||||
// attached when the click is made. A frame that has gone away is skipped rather than failing the
|
||||
// poll — the app reclaims its print frame, and a reclaimed frame is a completed print, not an error.
|
||||
const readPrints = async () => {
|
||||
const out = []
|
||||
for (const f of p.frames()) {
|
||||
const got = await f.evaluate(() => window.__printed || []).catch(() => [])
|
||||
out.push(...got)
|
||||
}
|
||||
return out
|
||||
}
|
||||
let prints = []
|
||||
for (let i = 0; i < 120 && !prints.length; i++) { await p.waitForTimeout(1000); prints = await readPrints() }
|
||||
let info = ''
|
||||
if (prints.length) {
|
||||
const pr = prints[0]
|
||||
info = `${pr.imgW}x${pr.imgH} on @page ${pr.page || '(none)'}`
|
||||
// The poster, at the size it was rendered, on the sheet it was rendered for.
|
||||
if (pr.imgW < 1600 || pr.imgH < 2100) errs.push(`the printed document is not the poster (${info})`)
|
||||
if (!/8\.5in\s+11in/.test(pr.page || '')) errs.push(`the sheet is not the poster's page size (@page ${pr.page || 'missing'})`)
|
||||
} else {
|
||||
for (const c of consoleErrs.filter(c => /poster|print|useMapPoster/i.test(c)).slice(-2)) errs.push(c)
|
||||
// SLOW or DEAD? A button still busy at the deadline is a render still running; an idle one is an
|
||||
// export that ended without opening anything. The verdict is FAIL either way; the reason says which.
|
||||
const busy = await btn.evaluate(el => el.disabled || el.getAttribute('aria-busy') === 'true').catch(() => null)
|
||||
errs.push(busy ? 'still rendering at the deadline (button busy)' : 'the export ended with no print dialog (button idle)')
|
||||
}
|
||||
// ★ THE NEW RULE'S OTHER HALF. A button that opens the dialog AND saves a file still breaks it.
|
||||
if (downloads.length) errs.push(`the button downloaded a file (${downloads[0].suggestedFilename()}) instead of only printing`)
|
||||
const ok = clicks === 1 && prints.length === 1 && !downloads.length && !errs.length
|
||||
// Exactly one dialog: two print frames would mean the click was handled twice, which a reader sees
|
||||
// as a second dialog appearing behind the first.
|
||||
if (clicks === 1 && prints.length > 1) errs.push(`${prints.length} print dialogs opened on one click`)
|
||||
console.log(`${ok ? 'PASS' : 'FAIL'} [${where} ${lang}${PROVIDER ? ' ' + PROVIDER : ''}] "${label}" · 1 click → ${prints.length ? `print dialog (${info})` : 'NO PRINT DIALOG within 120s'}${errs.length ? ' · ' + [...new Set(errs)].slice(0, 3).join(' | ') : ' · 0 errors, 0 downloads'}`)
|
||||
if (!ok) fails.push(`${where} ${lang}`)
|
||||
await ctx.close()
|
||||
}
|
||||
} finally { await b.close(); cleanup() }
|
||||
|
||||
if (fails.length) { console.log(`\ncheck-export-poster-prints: FAIL (${fails.join(', ')})`); process.exit(1) }
|
||||
console.log('\ncheck-export-poster-prints: PASS — one click opens the print dialog on the poster and downloads nothing, leaf and gallery, en and ar')
|
||||
1192
plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json
vendored
1192
plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* region-dashboards.vue — Tab 2 ("Region Dashboards") of the regions-dashboard bundle.
|
||||
*
|
||||
* @description The dashboard half of the Driver's 2-tab Regions element: given a region (or a
|
||||
* @description The dashboard half of the 2-tab Regions element: given a region (or a
|
||||
* single country inside one), it summarises that selection — headline stats plus a comparison
|
||||
* of its countries — using the SAME live people-groups endpoint and the SAME rollup fields as
|
||||
* regions-list.vue (tab 1), so the two tabs can never disagree about a number.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* regions-mfe.vue — the regions-dashboard NESTED-ELEMENTS MFE (the 2-tab Regions element).
|
||||
*
|
||||
* @description The composite the Driver asked for: ONE element carrying the SELECT VIEW switcher
|
||||
* @description The composite: ONE element carrying the SELECT VIEW switcher
|
||||
* over two panes — tab 1 "Regions List" (regions-list) and tab 2 "Region Dashboards"
|
||||
* (region-dashboards). Clicking a region or a country on tab 1 swaps to tab 2 with that
|
||||
* selection already applied.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<script setup>
|
||||
import { religionFamilyLabel } from '@map/colors/religion.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
import { WAGF_REGIONS } from '@map/colors/wagf-region.js'
|
||||
import countryName, { iso3ForEnglishName } from '@map/utils/countryName.js'
|
||||
import { tStatic, getRuntimeLocale } from '@map/i18n/index.js'
|
||||
/**
|
||||
* ChartsRail — RDASH phase 5: cross-filtered charts rail. Religion donut + Region donut (doxa-region
|
||||
* palette) + Top-country bar, all re-aggregating on filterSet and brushable back into it (click a
|
||||
|
|
@ -98,9 +100,45 @@ const isActive = (facet, key) => bus.isFilterActive(facet, key)
|
|||
// Two projections, one function, and both follow the same rule: the key crosses, the label is read.
|
||||
// OTHER_KEY is the rollup sentinel aggregate() produces; it must stay English on the wire (this
|
||||
// component refuses to filter on it by testing `key === 'Other'`) and be localized for a reader.
|
||||
// ★ TWO MORE FACETS CARRY ENGLISH DATA LABELS, and rega read both on ?lang=ar (KA3, 3d64bcad).
|
||||
// They are not chrome: no catalogue held them, so every i18n gate passed while the chart spoke English.
|
||||
// · wagf_region — the prayer API's seven region names. A closed set, so they are CATALOGUED, five of
|
||||
// them from vendored CLDR (internal/generate-wagf-region-names.mjs); middle_east and
|
||||
// north_america_&_non-spanish_caribbean have no CLDR code that means them and stay English.
|
||||
// · country_code — the API's English country name. The alpha-3 is gone by aggregation time, so
|
||||
// library/utils/countryName.js reverses its own table and then asks CLDR, per the ✓ case in that
|
||||
// file's header: a label that arrives in English regardless of the reader.
|
||||
// English is left EXACTLY as authored: at locale 'en' both projections return the key untouched, which
|
||||
// also keeps the 42 countries whose CLDR name differs from ours (see countryName.js) reading as before.
|
||||
// The five keys are written out rather than assembled from the slug: a template-literal key is
|
||||
// invisible to check:i18n-keys-exist (it counts such expressions as dynamic and will not guess at
|
||||
// them), and these entries are generated, so the gate is the only thing standing between a regenerated
|
||||
// catalogue and a chart silently back in English. Written out, deleting one fails the build.
|
||||
const REGION_SLUG = new Map(Object.entries(WAGF_REGIONS).map(([slug, label]) => [label, slug]))
|
||||
const REGION_KEY = {
|
||||
africa: 'dashboard.wagfRegion.africa',
|
||||
asia: 'dashboard.wagfRegion.asia',
|
||||
europe: 'dashboard.wagfRegion.europe',
|
||||
'latin_america_&_caribbean': 'dashboard.wagfRegion.latin_america_&_caribbean',
|
||||
oceania: 'dashboard.wagfRegion.oceania',
|
||||
}
|
||||
const regionLabel = (key) => {
|
||||
const slug = REGION_SLUG.get(key)
|
||||
const k = slug && REGION_KEY[slug]
|
||||
return (k && tStatic(k)) || key
|
||||
}
|
||||
const countryLabel = (key) => {
|
||||
const lc = getRuntimeLocale()
|
||||
if (!lc || lc === 'en') return key
|
||||
const iso3 = iso3ForEnglishName(key)
|
||||
return iso3 ? countryName(iso3, lc) : key
|
||||
}
|
||||
const legendLabel = (facet, key) => {
|
||||
if (key === OTHER_KEY) return otherLabel()
|
||||
return facet === 'religion_family' ? religionFamilyLabel(key) : key
|
||||
if (facet === 'religion_family') return religionFamilyLabel(key)
|
||||
if (facet === 'wagf_region') return regionLabel(key)
|
||||
if (facet === 'country_code') return countryLabel(key)
|
||||
return key
|
||||
}
|
||||
// true when this chart's own facet has an active selection → drives the pop-out / dim-others state.
|
||||
const hasSelection = (facet) => filterSet[facet] != null // any selection, scalar or array
|
||||
|
|
@ -372,7 +410,11 @@ useShadowStyles(`
|
|||
<div class="rd-bars">
|
||||
<div v-for="b in chart.geometry" :key="b.key" class="rd-bar" :class="{ on: isActive(chart.facet, b.key) }"
|
||||
:data-facet="chart.facet" :data-key="b.key">
|
||||
<span class="rd-bl">{{ b.key }}</span>
|
||||
<!-- ★ THE BAR LABEL WAS THE ONE CHART SURFACE STILL PRINTING THE RAW KEY. The donut, its
|
||||
legend and both tooltips already read legendLabel(); the bar list did not, which is why
|
||||
the top-countries and region charts stayed English after the donut was fixed. Same
|
||||
projector, so the two charts cannot disagree about a name again. -->
|
||||
<span class="rd-bl">{{ legendLabel(chart.facet, b.key) }}</span>
|
||||
<span class="rd-bt"><span class="rd-bf" :style="{ width: (b.frac * 100) + '%', background: b.color }"></span></span>
|
||||
<span class="rd-bv">{{ b.value }}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -919,7 +919,13 @@ useShadowStyles(`
|
|||
<div class="rd-td chk"></div>
|
||||
<div v-for="(col, i) in COLUMNS" :key="'f-' + col.key" class="rd-td"
|
||||
:class="{ num: col.type === 'num' }" :style="colFlex(col)">
|
||||
<template v-if="i === 0">Σ {{ fmt(rowCount) }} groups</template>
|
||||
<!-- ★ "groups" WAS THE LAST ENGLISH WORD IN THIS TABLE (rega KA3, ?lang=ar): the footer read
|
||||
"Σ 2,107 groups" on an Arabic page. dashboard.groups already ships in all eleven locales
|
||||
(ar "مجموعة"), so this is a call site that never read its own catalogue -- no new
|
||||
string, no new key. Singular/plural is written the same way as the header count at
|
||||
L794 -- the two say the same thing about the same number and would otherwise disagree at
|
||||
one row. Σ and the numeral stay as they are: NUMERALS ARE HELD. -->
|
||||
<template v-if="i === 0">Σ {{ fmt(rowCount) }} {{ rowCount === 1 ? T('dashboard.group', 'group') : T('dashboard.groups', 'groups') }}</template>
|
||||
<template v-else-if="col.key === 'population'">{{ fmt(sumPop) }}</template>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1384,6 +1384,12 @@ function applyProjection() {
|
|||
// the engine by trial instead of by identity. The helper instance-tests instead (C2).
|
||||
setProjectionOn(m, projection.value)
|
||||
}
|
||||
// The pill's accessible name: the action, from the catalogue, in the reader's language. Both keys
|
||||
// ship in all eleven locales, so this never falls back to English.
|
||||
const projName = computed(() => (projection.value === 'globe'
|
||||
? T('mapui.disableGlobe', 'Disable globe')
|
||||
: T('mapui.enableGlobe', 'Enable globe')))
|
||||
|
||||
function toggleProjection() { projection.value = projection.value === 'globe' ? 'mercator' : 'globe'; applyProjection() }
|
||||
|
||||
// ── RDASH-ENHANCE: fly-to on selection. Any facet brush (tree node / chart slice / region / row)
|
||||
|
|
@ -1590,7 +1596,10 @@ useShadowStyles(`
|
|||
the media query meant phones passed at 34px while desktop stayed at 73.5x23, the same one-pixel
|
||||
failure, now invisible to a phone sweep. Measured again at 1440x900 by upg100 (2a2ea36e). One
|
||||
rule, every width, no query to be right about. */
|
||||
.rd-proj{ min-height:24px; display:inline-flex; align-items:center; }
|
||||
/* ★ AND min-WIDTH now that the word is gone. The 24 used to come for free from the text
|
||||
("🌐 Globe" measured 74px wide); a glyph-only pill is about 29px with its padding, which passes,
|
||||
but only by accident of the font. Stating both axes keeps 2.5.8 AA true if the glyph changes. */
|
||||
.rd-proj{ min-height:24px; min-width:24px; display:inline-flex; align-items:center; justify-content:center; }
|
||||
/* Zoom cluster. MapToolbar defaults to top:6px on the inline-end edge, which is exactly where
|
||||
the Globe/Flat pill already sits, so drop this instance below it. 34px clears the pill
|
||||
(top:8px + roughly 22px tall) with a small breathing gap.
|
||||
|
|
@ -1691,8 +1700,20 @@ useShadowStyles(`
|
|||
<ZoomInButton :map="map" :disabled="!canZoomIn" />
|
||||
<ZoomOutButton :map="map" :disabled="!canZoomOut" />
|
||||
</MapToolbar>
|
||||
<span class="rd-proj" role="button" tabindex="0" data-proj-toggle @click="toggleProjection">
|
||||
{{ projection === 'globe' ? '🌐 Globe' : '▭ Flat' }}
|
||||
<!-- ★ THE ICON IS THE LABEL, because the word could not be translated without inventing one.
|
||||
rega saw "🌐 Globe" in Arabic on ?lang=ar (KA3, 3d64bcad): hardcoded English chrome on a
|
||||
localized map. "Globe" has no catalogue entry and "Flat" has none in any of the eleven
|
||||
locales, so translating the visible text meant either authoring ten new strings for a
|
||||
two-state toggle or leaving nine locales reading English. The catalogue DOES already ship
|
||||
mapui.enableGlobe / mapui.disableGlobe in all eleven — as the ACTION, which is what a button
|
||||
should announce anyway — so the accessible name and the tooltip come from there and the
|
||||
visible pill carries the glyph alone. A reader now sees no English, and a screen reader hears
|
||||
the action in their own language rather than the state in someone else's.
|
||||
The label names what the click DOES, not where you are: in globe mode the button turns the
|
||||
globe off. -->
|
||||
<span class="rd-proj" role="button" tabindex="0" data-proj-toggle @click="toggleProjection"
|
||||
:title="projName" :aria-label="projName">
|
||||
<span aria-hidden="true">{{ projection === 'globe' ? '🌐' : '▭' }}</span>
|
||||
</span>
|
||||
<div class="rd-legend-map" data-map-legend :aria-label="T('aria.upgCountLegend', 'UPG count legend')">
|
||||
<!-- ★ COMPOSED FROM TWO EXISTING CATALOGUE ENTRIES, not from new wording. This legend title
|
||||
|
|
|
|||
61
public/dx-maps/assets/boundaries/ATTRIBUTION
Normal file
61
public/dx-maps/assets/boundaries/ATTRIBUTION
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
BOUNDARY DATA — SOURCES AND ATTRIBUTION
|
||||
=======================================
|
||||
|
||||
The .geojson files in this folder are third-party boundary data. Every value below is taken
|
||||
VERBATIM from the upstream metadata (the geoBoundaries API, https://www.geoboundaries.org/api/current/gbOpen/<ISO3>/<LEVEL>/).
|
||||
Nothing here is our own wording about a licence.
|
||||
|
||||
gb-IND-ADM1-full.geojson, gb-IND-ADM1-full-web.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org)
|
||||
boundaryID IND-ADM1-1811400
|
||||
licence Creative Commons Attribution 2.5 India (CC BY 2.5 IN)
|
||||
licenceSource github.com/datameet/maps
|
||||
year 2011
|
||||
ATTRIBUTION IS REQUIRED for this file: it is Creative Commons Attribution, so a work that
|
||||
redistributes or displays it must credit the source above.
|
||||
|
||||
gb-IND-ADM1.geojson, gb-IND-ADM1-web.geojson
|
||||
The same India ADM1 boundary as above, curated to the UPG-100 list's partition.
|
||||
Same source, same boundaryID, same licence, same attribution duty.
|
||||
|
||||
gb-CHN-ADM1.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org)
|
||||
boundaryID CHN-ADM1-43563684
|
||||
licence Public Domain
|
||||
licenceSource commons.wikimedia.org/wiki/File
|
||||
year 2019
|
||||
No attribution duty: upstream records this boundary as Public Domain.
|
||||
|
||||
world-adm0.geojson, world-adm0-web.geojson
|
||||
source geoBoundaries gbOpen (www.geoboundaries.org), assembled per country
|
||||
features 162 countries
|
||||
licence MIXED — and now ESTABLISHED per country, not merely acknowledged.
|
||||
THE PER-COUNTRY TABLE IS THE AUTHORITY, and it lives in ONE place on purpose:
|
||||
plugin-designs/my-upg-100-list/data/adm0/PROVENANCE.json
|
||||
It records boundaryLicense, licenseSource and boundaryID for all 162, each value taken
|
||||
verbatim from https://www.geoboundaries.org/api/current/gbOpen/<ISO3>/<LEVEL>/ (162 queries,
|
||||
0 failures, one spot-check re-verified against the live API). This file deliberately does NOT
|
||||
copy that table: one table in two places drifts.
|
||||
|
||||
130 OF THE 162 CARRY A DUTY. Only 32 are duty-free (28 Public Domain, 4 CC0). By class:
|
||||
|
||||
ATTRIBUTION-ONLY (credit the source)
|
||||
44 CC BY 4.0 13 CC BY 3.0 IGO 4 CC BY 2.5 2 CC BY 3.0
|
||||
2 Open Government Licence v3
|
||||
|
||||
SHARE-ALIKE CLASS — A STRONGER DUTY: a derivative may have to be licensed alike, which is
|
||||
the class that actually constrains giving this repository away.
|
||||
58 Open Data Commons ODbL 1.0
|
||||
7 Creative Commons ShareAlike 2.0 / 3.0 — AGO GAB GEO GIN MMR NER TUR
|
||||
|
||||
ODbL IS LISTED IN THAT CLASS DELIBERATELY. Alongside attribution it requires a Derivative
|
||||
Database to be offered under ODbL and carries a keep-open provision, so by volume the
|
||||
share-alike question covers 65 of 162 countries, not 7. This repository has already acted on
|
||||
that reading once: library/scripts/posters/data/README.md records that Natural Earth's 1:10m
|
||||
ROADS were requested and deliberately NOT shipped because of an ODbL obligation.
|
||||
WHETHER 'licensed alike' binds a giveaway of this repository is a legal question, not a
|
||||
measurement, and it is open. It is recorded here so nobody has to rediscover it.
|
||||
|
||||
duty-free: 28 Public Domain, 4 CC0.
|
||||
|
||||
See documentation/THIRD-PARTY.md for the whole shipped tree.
|
||||
|
|
@ -1,24 +1,93 @@
|
|||
Bebas Neue — SIL Open Font License, Version 1.1
|
||||
Designer: Ryoichi Tsunekawa (Dharma Type). Distributed via Google Fonts.
|
||||
Full text: https://openfontlicense.org/ (OFL-1.1)
|
||||
Copyright © 2010 by Dharma Type.
|
||||
|
||||
WHY THIS FILE IS IN THIS REPO
|
||||
DX-life's /regions pages set --font-family-heading to 'Bebas Neue'. Their own site does not
|
||||
ship the file either — @nuxt/fonts downloads it at build and self-hosts it, which is why their
|
||||
computed font-family reads "Bebas Neue", "Bebas Neue Fallback: ...". We cannot @font-face from
|
||||
their origin: their font file is served without CORS headers, so a cross-origin face silently
|
||||
fails and every heading fell back to a condensed system stack. That substitution was the ONLY
|
||||
remaining difference between our regions dashboard and theirs (7 computed properties, all of
|
||||
them this one font and its knock-on sizes).
|
||||
So the font is vendored here, from Google Fonts, under the OFL that permits redistribution —
|
||||
self-hosted, never a CDN, the same rule public/assets/vendor/tabulator/ follows.
|
||||
Subsets and unicode-ranges are Google's own (css2 API, v16), reproduced verbatim in the
|
||||
@font-face declared by library/composables/useDocumentFont.js.
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
NOTE ON THIS FILENAME — it is deliberately extensionless.
|
||||
check:public-hygiene refuses *.md / *.markdown / *.txt anywhere in the served tree ("no docs in a
|
||||
served folder", Driver rule 2026-09-16), and it is right to: prose does not belong in a public
|
||||
mirror. But the OFL requires this licence to accompany the font files wherever they are
|
||||
redistributed, and the font files DO ship — they are fetched by the @font-face at runtime. So the
|
||||
licence travels with them under the conventional extensionless name, which satisfies the rule
|
||||
without weakening it. Do not rename this to LICENSE.txt.
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
Figtree — SIL Open Font License, Version 1.1
|
||||
Designer: Erik D. Kennedy. Distributed via Google Fonts.
|
||||
Vendored as the free stand-in for Brandon Grotesque (commercial), by Driver decision
|
||||
2026-09-24. Chosen by MEASUREMENT, not by name: at 500/19.5312px Figtree renders
|
||||
'FULL PROFILE' at 126px against Brandon's 128px on live doxa.life — the closest of 19
|
||||
libre grotesques tested. See _probe-glyph-width.mjs.
|
||||
|
||||
Copyright 2022 The Figtree Project Authors (https://github.com/erikdkennedy/figtree)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
|
|
|||
|
|
@ -1,29 +1,93 @@
|
|||
Poppins — SIL Open Font License, Version 1.1
|
||||
Designers: Indian Type Foundry, Jonny Pinhorn. Distributed via Google Fonts.
|
||||
Full text: https://openfontlicense.org/ (OFL-1.1)
|
||||
Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins)
|
||||
|
||||
WHY THIS FILE IS IN THIS REPO
|
||||
Poppins is DX-life's --font-family-base: the body face of every line of text on the pages the
|
||||
regions plugin clones. Their own site self-hosts it via @nuxt/fonts; we could not use theirs, so
|
||||
it is vendored here from Google Fonts under the OFL, which permits redistribution.
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
WHY IT WAS NEEDED — and why no CSS check caught it.
|
||||
A computed-style diff of our region dashboard against live doxa.life reported 68 of 68 properties
|
||||
IDENTICAL while our body text was rendering in a system fallback, because BOTH sides merely NAME
|
||||
"Poppins" first in font-family and a first-family comparison therefore matched. The difference only
|
||||
became visible against a glyph-width oracle: the same string at the same size measured 334.58px
|
||||
here against 317px on their page — 5.5% wider, i.e. a different face.
|
||||
document.fonts.check() is NOT a usable oracle for this: it returned true for families never
|
||||
vendored (Oswald, Brandon Grotesque) and false for Bebas Neue on DX-life's own page.
|
||||
See _qa-cycle/02-builder-cycle/_probe-glyph-width.mjs.
|
||||
|
||||
WHAT IS HERE, AND WHY ONLY THIS
|
||||
Weights 400/500/600/700 only — the four the regions surface actually asks for (measured across
|
||||
their _globals, _cards, _buttons and _filters SCSS: medium x10, regular x4, bold x2, plus the
|
||||
600 in the prayer-coverage legend). Subsets latin + latin-ext only. 44 KB in total, with Google's
|
||||
own unicode-ranges reproduced in the @font-face so the subset split behaves as it does on their
|
||||
site. Extra weights and scripts are deliberately NOT vendored — bloat is a repo rule here.
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
FILENAME: extensionless on purpose. check:public-hygiene refuses *.txt in a served folder and is
|
||||
right to, while the OFL requires this licence to accompany redistributed font files. Do not
|
||||
rename this to LICENSE.txt.
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
|
|
|||
21
public/dx-maps/assets/vendor/tabulator/LICENSE
vendored
Normal file
21
public/dx-maps/assets/vendor/tabulator/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2026 Oli Folkerd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
21
public/dx-maps/assets/vendor/vue/LICENSE
vendored
Normal file
21
public/dx-maps/assets/vendor/vue/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018-present, Yuxi (Evan) You and Vue contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <bp-big-picture> custom element. -->
|
||||
<script src="../../big-picture.js" integrity="sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP" crossorigin="anonymous"></script>
|
||||
<script src="../../big-picture.js" integrity="sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <bp-big-picture> custom element. -->
|
||||
<script src="../../big-picture.js" integrity="sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP" crossorigin="anonymous"></script>
|
||||
<script src="../../big-picture.js" integrity="sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <bp-big-picture> custom element. -->
|
||||
<script src="../big-picture.js" integrity="sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP" crossorigin="anonymous"></script>
|
||||
<script src="../big-picture.js" integrity="sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr" crossorigin="anonymous"></script>
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr" crossorigin="anonymous"></script>
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
"bundle": "big-picture",
|
||||
"scriptUrl": "./big-picture/big-picture.js",
|
||||
"output": "dx-maps/big-picture/big-picture.js",
|
||||
"integrity": "sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP",
|
||||
"integrity": "sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O",
|
||||
"elements": [
|
||||
"bp-big-picture",
|
||||
"bp-research-header",
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
"scriptUrl": "./big-picture/big-picture.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./big-picture/big-picture/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./big-picture/big-picture.js\" integrity=\"sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP\" crossorigin=\"anonymous\"></script>\n<bp-big-picture profile-config='{\"profile\":\"big-picture\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bp-big-picture>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./big-picture/big-picture.js\" integrity=\"sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O\" crossorigin=\"anonymous\"></script>\n<bp-big-picture profile-config='{\"profile\":\"big-picture\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bp-big-picture>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"bundle": "country-posters",
|
||||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"output": "dx-maps/country-posters/country-posters.js",
|
||||
"integrity": "sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA",
|
||||
"integrity": "sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh",
|
||||
"elements": [
|
||||
"country-posters-map"
|
||||
],
|
||||
|
|
@ -187,7 +187,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -202,7 +202,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -217,7 +217,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -226,7 +226,7 @@
|
|||
"bundle": "dashboard-plus-grid",
|
||||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"output": "dx-maps/dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"integrity": "sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr",
|
||||
"integrity": "sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ",
|
||||
"elements": [
|
||||
"dashboard-plus-grid"
|
||||
],
|
||||
|
|
@ -248,7 +248,7 @@
|
|||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -371,7 +371,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk",
|
||||
"integrity": "sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -389,7 +389,7 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -604,7 +604,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a",
|
||||
"integrity": "sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -623,7 +623,7 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -632,8 +632,7 @@
|
|||
"apiBaseUrl": "",
|
||||
"props": {
|
||||
"profile": "board",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/board/index.html",
|
||||
|
|
@ -648,8 +647,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"view": "zero",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/zero/index.html",
|
||||
|
|
@ -665,8 +663,7 @@
|
|||
"profile": "board",
|
||||
"view": "province",
|
||||
"panel": "map",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/india-china/index.html",
|
||||
|
|
@ -681,8 +678,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"panel": "tree",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/language-tree/index.html",
|
||||
|
|
@ -697,8 +693,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"view": "platforms",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/platforms/index.html",
|
||||
|
|
@ -713,8 +708,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"list": "700",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/project-700/index.html",
|
||||
|
|
@ -1057,7 +1051,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR",
|
||||
"integrity": "sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1071,7 +1065,7 @@
|
|||
"profile": "region-dashboards",
|
||||
"stage": "experimental",
|
||||
"file": "region-dashboards.vue",
|
||||
"description": "The dashboard half of the Driver's 2-tab Regions element: given a region (or a",
|
||||
"description": "The dashboard half of the 2-tab Regions element: given a region (or a",
|
||||
"element": "regions-dashboard",
|
||||
"type": "single",
|
||||
"isMap": true,
|
||||
|
|
@ -1079,7 +1073,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1094,14 +1088,14 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"profile": "regions-mfe",
|
||||
"stage": "production",
|
||||
"file": "regions-mfe.vue",
|
||||
"description": "The composite the Driver asked for: ONE element carrying the SELECT VIEW switcher",
|
||||
"description": "The composite: ONE element carrying the SELECT VIEW switcher",
|
||||
"element": "regions-dashboard",
|
||||
"type": "nested-elements-mfe",
|
||||
"isMap": true,
|
||||
|
|
@ -1109,7 +1103,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1118,7 +1112,7 @@
|
|||
"bundle": "research-dashboard",
|
||||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"output": "dx-maps/research-dashboard/research-dashboard.js",
|
||||
"integrity": "sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1",
|
||||
"integrity": "sha384-FmogM7ZH4D9phv7a6r8Yux2r9NxFFcIrdSgSjqpIQGRdwIdEyxTv0dTEHwW1aUs8",
|
||||
"elements": [
|
||||
"research-dashboard-map"
|
||||
],
|
||||
|
|
@ -1136,7 +1130,7 @@
|
|||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-FmogM7ZH4D9phv7a6r8Yux2r9NxFFcIrdSgSjqpIQGRdwIdEyxTv0dTEHwW1aUs8\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
},
|
||||
"bundle": "research-dashboard"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../doxa-research-map.js" integrity="sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk" crossorigin="anonymous"></script>
|
||||
<script src="../doxa-research-map.js" integrity="sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk" crossorigin="anonymous"></script>
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"province","panel":"map","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"province","panel":"map","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","panel":"tree","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","panel":"tree","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"platforms","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"platforms","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","list":"700","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","list":"700","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"zero","urlState":"query","pinHint":false};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"board","view":"zero","urlState":"query"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -40,7 +40,7 @@
|
|||
"bundle": "big-picture",
|
||||
"scriptUrl": "./big-picture/big-picture.js",
|
||||
"output": "dx-maps/big-picture/big-picture.js",
|
||||
"integrity": "sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP",
|
||||
"integrity": "sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O",
|
||||
"elements": [
|
||||
"bp-big-picture",
|
||||
"bp-research-header",
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
"scriptUrl": "./big-picture/big-picture.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./big-picture/big-picture/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./big-picture/big-picture.js\" integrity=\"sha384-vq5/y8EkBMQyCQFvBmoWBZhBX73c4vln8KD5tuMyMdhzMDf25zyUTdUx4XRAEibP\" crossorigin=\"anonymous\"></script>\n<bp-big-picture profile-config='{\"profile\":\"big-picture\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bp-big-picture>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./big-picture/big-picture.js\" integrity=\"sha384-ok/EhX34F4Novw0CMxEoYa69SLQmXtc4QzI1zPW1KV9t5bKlnxsoMxSNO68ea29O\" crossorigin=\"anonymous\"></script>\n<bp-big-picture profile-config='{\"profile\":\"big-picture\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bp-big-picture>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"bundle": "country-posters",
|
||||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"output": "dx-maps/country-posters/country-posters.js",
|
||||
"integrity": "sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA",
|
||||
"integrity": "sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh",
|
||||
"elements": [
|
||||
"country-posters-map"
|
||||
],
|
||||
|
|
@ -187,7 +187,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -202,7 +202,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -217,7 +217,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-mkjfczD2UgdXg1PKUHLuf5fFMs3W7UjGtDKJ9KVTWnTJ0SoQk6LPWMy+ijlkOGsA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-OCkvmeiqULZJ8S6Qw2JNlbt1PlS8rfc7ME6CwAVJfv0NkWEGbdDm/bWrGpEqAOyh\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -226,7 +226,7 @@
|
|||
"bundle": "dashboard-plus-grid",
|
||||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"output": "dx-maps/dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"integrity": "sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr",
|
||||
"integrity": "sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ",
|
||||
"elements": [
|
||||
"dashboard-plus-grid"
|
||||
],
|
||||
|
|
@ -248,7 +248,7 @@
|
|||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-+CKECgEuJ5pKzR11N0RMEEAEvBKz+F1S3xbVub8k0RAF+tSEV8fW6W2CVCTdJ1lZ\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -371,7 +371,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk",
|
||||
"integrity": "sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -389,7 +389,7 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-tD9vkhv3FNeVuKgdRQnpH/Ut0Zxh/BNqPl2lf8rOidmgj3831MsDD96m+4zv7Pr4\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -604,7 +604,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a",
|
||||
"integrity": "sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -623,7 +623,7 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-ZQF3CkN2yU6wgCToYTuCukqTHLBieBtrymjLPCtnF0ccWItHxiQC1Gr5UrdSPS+a\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-d40eQO58ZZ9VbuAIYGirFAtLmuR3YiXj7olTWzzAKN8eqeH30b6bE6xSjQg6htI3\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -632,8 +632,7 @@
|
|||
"apiBaseUrl": "",
|
||||
"props": {
|
||||
"profile": "board",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/board/index.html",
|
||||
|
|
@ -648,8 +647,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"view": "zero",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/zero/index.html",
|
||||
|
|
@ -665,8 +663,7 @@
|
|||
"profile": "board",
|
||||
"view": "province",
|
||||
"panel": "map",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/india-china/index.html",
|
||||
|
|
@ -681,8 +678,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"panel": "tree",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/language-tree/index.html",
|
||||
|
|
@ -697,8 +693,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"view": "platforms",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/platforms/index.html",
|
||||
|
|
@ -713,8 +708,7 @@
|
|||
"props": {
|
||||
"profile": "board",
|
||||
"list": "700",
|
||||
"urlState": "query",
|
||||
"pinHint": false
|
||||
"urlState": "query"
|
||||
},
|
||||
"element": "gospel-internet-board",
|
||||
"iframeUrl": "./gospel-internet/board/project-700/index.html",
|
||||
|
|
@ -1057,7 +1051,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR",
|
||||
"integrity": "sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1071,7 +1065,7 @@
|
|||
"profile": "region-dashboards",
|
||||
"stage": "experimental",
|
||||
"file": "region-dashboards.vue",
|
||||
"description": "The dashboard half of the Driver's 2-tab Regions element: given a region (or a",
|
||||
"description": "The dashboard half of the 2-tab Regions element: given a region (or a",
|
||||
"element": "regions-dashboard",
|
||||
"type": "single",
|
||||
"isMap": true,
|
||||
|
|
@ -1079,7 +1073,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1094,14 +1088,14 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"profile": "regions-mfe",
|
||||
"stage": "production",
|
||||
"file": "regions-mfe.vue",
|
||||
"description": "The composite the Driver asked for: ONE element carrying the SELECT VIEW switcher",
|
||||
"description": "The composite: ONE element carrying the SELECT VIEW switcher",
|
||||
"element": "regions-dashboard",
|
||||
"type": "nested-elements-mfe",
|
||||
"isMap": true,
|
||||
|
|
@ -1109,7 +1103,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1118,7 +1112,7 @@
|
|||
"bundle": "research-dashboard",
|
||||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"output": "dx-maps/research-dashboard/research-dashboard.js",
|
||||
"integrity": "sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1",
|
||||
"integrity": "sha384-FmogM7ZH4D9phv7a6r8Yux2r9NxFFcIrdSgSjqpIQGRdwIdEyxTv0dTEHwW1aUs8",
|
||||
"elements": [
|
||||
"research-dashboard-map"
|
||||
],
|
||||
|
|
@ -1136,7 +1130,7 @@
|
|||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-FmogM7ZH4D9phv7a6r8Yux2r9NxFFcIrdSgSjqpIQGRdwIdEyxTv0dTEHwW1aUs8\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
},
|
||||
"bundle": "research-dashboard"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-BKvyqmem1gAeYIpv+N7hUWezGfuToUwRjtpyN38YCa1TqdM4rA1zty9cNm8kpzOR" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-xr+Cao4cF71XZpfQ0iZCQi6ULw2Thnrl0JXxtAwxzkAJRVYbArdWXA9Q8CBwLIPK" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <research-dashboard-map> custom element. -->
|
||||
<script src="../research-dashboard.js" integrity="sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1" crossorigin="anonymous"></script>
|
||||
<script src="../research-dashboard.js" integrity="sha384-FmogM7ZH4D9phv7a6r8Yux2r9NxFFcIrdSgSjqpIQGRdwIdEyxTv0dTEHwW1aUs8" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue