Merge main into bundler-2/work

This commit is contained in:
Doxa Maps 2026-09-26 07:24:21 +00:00
commit d1c14aa661
10 changed files with 205 additions and 40 deletions

View file

@ -40,8 +40,39 @@ if (!wanted.length) {
process.exit(2)
}
/**
* ⚠ A DYNAMIC FETCH RESOLVES TO A DIRECTORY, AND A DIRECTORY ALWAYS EXISTS.
* The province layer fetches `${assetsBase}/boundaries/${PROVINCE_FILE[iso3]}`, so the parse
* above captures the literal prefix "boundaries/" and stops at the interpolation. That path is
* a real directory of 4,096 bytes, so it passed — proving nothing about the two files the map
* actually asks for. A check that cannot fail is the thing this repo keeps rediscovering.
* So a directory is never accepted as an asset, and any literal asset FILENAME mentioned in the
* leaf is checked on its own. That covers the interpolated case without trying to evaluate it.
*/
const dirLike = wanted.filter((r) => r.endsWith('/'))
const named = [...new Set(
[...src.matchAll(/['"`]([A-Za-z0-9_\-]+\.(?:geojson|json))['"`]/g)].map((m) => m[1]),
)]
/* ⚠ AND THE EXPANSION MUST NOT CONSULT THE FILESYSTEM TO DECIDE WHAT TO EXPECT.
* The first version only added a name if the file already existed, so deleting one simply
* removed it from the list and the gate went green on nine assets instead of ten. Proven by
* unstaging gb-CHN-ADM1.geojson: PASS, exit 0. The expectation has to come from the SOURCE —
* the filenames the leaf names — so that a file the leaf asks for and the tree lacks is a
* failure rather than a shorter list. */
for (const prefix of dirLike) {
const ext = /boundaries\//.test(prefix) ? '.geojson' : '.json'
for (const file of named.filter((f) => f.endsWith(ext))) wanted.push(prefix + file)
}
const missing = []
for (const rel of wanted) {
if (rel.endsWith('/')) {
/* Counted, not silently skipped: if the expansion above found nothing for this prefix the
reader must know the interpolated fetch went unverified. */
const found = wanted.filter((w) => w !== rel && w.startsWith(rel))
if (!found.length) missing.push(`${rel} — a dynamic fetch this check could not resolve to a file`)
continue
}
const p = resolve(POOL, rel)
if (!existsSync(p)) { missing.push(`${rel} — not staged`); continue }
const bytes = statSync(p).size

View file

@ -964,12 +964,16 @@ function openCountry(iso) {
if (!iso || !byIso.value[iso]) return
selected.value = byIso.value[iso]
selectedGroup.value = null
selectedProvince.value = null
shown.value = PAGE
ensurePeopleGroups()
/* Opening India or China IS the intent signal. 1.6 MB of Indian geometry is not something to
spend on the 173 countries nobody is looking at. */
ensureProvinces(iso)
}
function openGroup(g) { selectedGroup.value = g }
function closeSheet() { selected.value = null; selectedGroup.value = null }
function closeSheet() { selected.value = null; selectedGroup.value = null; selectedProvince.value = null }
async function load() {
const [data, adm0, pinData, doxaData] = await Promise.all([
@ -1087,6 +1091,108 @@ function paint(map, adm0) {
map.on('mouseleave', 'gr-fill', () => { map.getCanvas().style.cursor = '' })
}
/**
* ═══ PROVINCES, FETCHED ONLY WHEN SOMEONE LOOKS ══════════════════════════════════════════
*
* India and China hold 47.9% of the roster (855 + 154 of 2,107) and a national fill cannot
* answer "where would a team go" for half the map. But India's ADM1 geometry is 1,628 KB —
* nearly the size of the whole world ADM0 file — on a leaf that already loads about 4 MB and
* is meant to be embedded on thousands of partner sites. Loading it for the 173 countries
* nobody is looking at would be a tax on every reader for the benefit of two.
*
* So it arrives on intent: opening India or China fetches that country's provinces once, and
* nothing else changes for anyone else. China is 54 KB, India 1,628 KB, and both are cached
* after the first open.
*
* COLOURED BY THE SAME LADDER as the country fill, because a reader who has just learned what
* the clay ramp means must not have to learn a second scale one zoom later.
*/
const provinceState = ref({}) // iso3 -> 'loading' | 'ready' | 'failed'
const provinceGeo = ref({}) // iso3 -> the loaded FeatureCollection, kept for recolouring
/* A province is coloured by the SAME rule as a country, mode included — a reader who has just
learned the clay ramp must not meet a second scale one zoom later. featureColor cannot be
reused directly because it looks a country up by iso3; this is the same two lines against a
province's own counts. */
const colourProvinces = (geo) => {
for (const f of geo.features) {
const n = mode.value === 'gap' ? f.properties.zero : f.properties.groups - f.properties.zero
const b = f.properties.groups > 0 ? bandFor(mode.value === 'gap' ? BANDS : COVER_BANDS, n) : null
f.properties.pcolor = b ? b.color : NO_DOXA_FILL
}
}
/* Mode changes after a province layer exists would otherwise leave it painted in the old
scale — the country beneath it would say one thing and the province another. */
const repaintProvinces = () => {
const map = mapRef.value
if (!map) return
for (const [iso3, geo] of Object.entries(provinceGeo.value)) {
colourProvinces(geo)
const src = map.getSource(`gr-prov-${iso3}`)
if (src) src.setData(geo)
}
}
const provinceRows = ref(null) // the measured table: province -> counts
const selectedProvince = ref(null)
async function ensureProvinceTable() {
if (provinceRows.value) return provinceRows.value
const r = await fetch(`${assetsBase.value}/tables/gospel-by-province.json`)
provinceRows.value = await r.json()
return provinceRows.value
}
const PROVINCE_FILE = { IND: 'gb-IND-ADM1.geojson', CHN: 'gb-CHN-ADM1.geojson' }
async function ensureProvinces(iso3) {
const map = mapRef.value
if (!map || !PROVINCE_FILE[iso3] || provinceState.value[iso3]) return
provinceState.value = { ...provinceState.value, [iso3]: 'loading' }
try {
const [geo, table] = await Promise.all([
fetch(`${assetsBase.value}/boundaries/${PROVINCE_FILE[iso3]}`).then((r) => r.json()),
ensureProvinceTable(),
])
/* The counts come from the measured table, never recomputed here — the point-in-polygon
that produced them belongs in the build, and a second implementation in the leaf is how
two surfaces come to disagree. */
const by = {}
for (const row of (table.rows || [])) if (row.iso3 === iso3) by[row.province] = row
for (const f of geo.features) {
const row = by[f.properties.shapeName]
f.properties.zero = row ? row.zero_access_groups : 0
f.properties.groups = row ? row.groups : 0
}
provinceGeo.value = { ...provinceGeo.value, [iso3]: geo }
colourProvinces(geo)
const src = `gr-prov-${iso3}`
if (!map.getSource(src)) {
map.addSource(src, { type: 'geojson', data: geo })
map.addLayer({
id: `${src}-fill`, type: 'fill', source: src,
paint: { 'fill-color': ['get', 'pcolor'], 'fill-opacity': ['case', ['>', ['get', 'groups'], 0], 0.82, 0] },
}, 'gr-line')
map.addLayer({
id: `${src}-line`, type: 'line', source: src,
paint: { 'line-color': 'rgba(255,255,255,0.75)', 'line-width': 0.7 },
}, 'gr-pins-halo')
map.on('click', `${src}-fill`, (e) => openProvince(iso3, e.features?.[0]?.properties?.shapeName))
map.on('mouseenter', `${src}-fill`, () => { map.getCanvas().style.cursor = 'pointer' })
map.on('mouseleave', `${src}-fill`, () => { map.getCanvas().style.cursor = '' })
}
provinceState.value = { ...provinceState.value, [iso3]: 'ready' }
} catch (_) {
/* A province view is an enrichment; losing it must never take the country view with it. */
provinceState.value = { ...provinceState.value, [iso3]: 'failed' }
}
}
function openProvince(iso3, name) {
const t = provinceRows.value
if (!t || !name) return
selectedProvince.value = (t.rows || []).find((r) => r.iso3 === iso3 && r.province === name) || null
}
function closeProvince() { selectedProvince.value = null }
function pinFC() {
const feats = new Array(pinRows.value.length)
const hnrFor = (code) => {
@ -1367,6 +1473,7 @@ function setMode(m) {
if (mode.value === m) return
mode.value = m
if (mapRef.value && adm0Ref.value) paint(mapRef.value, adm0Ref.value)
repaintProvinces()
}
/* ═══ NUMBER FORMAT IS HELD FOR THE DRIVER ════════════════════════════════════════════════
@ -1883,7 +1990,34 @@ useShadowStyles(
<div v-if="err" class="gm-err">{{ err }}</div>
<!-- Tap a country: bottom sheet on mobile, corner card on desktop. -->
<div v-if="selected || showGapList" class="gm-sheet">
<!-- ═══ A PROVINCE, WHEN ONE IS TAPPED ═══════════════════════════════════════════════
Sits above the country sheet because it is the narrower answer to the same question,
and a reader who tapped a province asked about the province. Closing it returns to the
country rather than to the world, so the drill-down is reversible one step at a time.
English prose in the caveat line, per the standing decision. -->
<div v-if="selectedProvince" class="gm-sheet">
<div class="gm-sh-head">
<button type="button" class="gm-back" @click="closeProvince">‹ {{ selectedProvince.country }}</button>
<button type="button" class="gm-back" @click="closeSheet">{{ t('gospel.sheet.close') }}</button>
</div>
<h3 class="gm-sh-title">{{ selectedProvince.province }}</h3>
<div class="gm-stat"><span>{{ t('gospel.stat.peopleGroups') }}</span><b>{{ fmt(selectedProvince.groups) }}</b></div>
<div class="gm-stat"><span>{{ t('gospel.stat.population') }}</span><b>{{ fmt(selectedProvince.people) }}</b></div>
<div class="gm-stat"><span>{{ t('gospel.legend.tier0') }}</span><b>{{ fmt(selectedProvince.zero_access_groups) }}</b></div>
<div class="gm-stat" v-if="selectedProvince.zero_access_people">
<span>{{ t('gospel.stat.peopleAffected') }}</span><b>{{ fmt(selectedProvince.zero_access_people) }}</b>
</div>
<p v-if="selectedProvince.zero_access_examples" class="gm-note" dir="ltr" style="margin:6px 0 0">
Largest with nothing: <b>{{ selectedProvince.zero_access_examples }}</b>
<template v-if="selectedProvince.ways_in"><br>Way in: {{ selectedProvince.ways_in }} — chosen for the country, not this province.</template>
</p>
<p class="gm-note" dir="ltr" style="margin:6px 0 0">
A group is placed in a province from its own coordinate, which marks where a people is
found rather than a settlement. Near a border that point can fall on the wrong side.
</p>
</div>
<div v-else-if="selected || showGapList" class="gm-sheet">
<!-- ITEM 0 — the ranked gap: the largest groups with nothing found anywhere. -->
<template v-if="showGapList && !selected">

View file

@ -578,7 +578,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW",
"integrity": "sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO",
"elements": [
"gospel-resources-map"
],
@ -598,7 +598,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -612,7 +612,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -626,7 +626,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -640,7 +640,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -654,7 +654,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -578,7 +578,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW",
"integrity": "sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO",
"elements": [
"gospel-resources-map"
],
@ -598,7 +598,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -612,7 +612,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -626,7 +626,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -640,7 +640,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -654,7 +654,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-vOIYJyGSOBMKagYZMXgaARieQnSXVp3kJnNO4BlgVakMHV8he27DFGNzhJitWKXW\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KrZmEWirbhkdmcLBpBqHFA4pEex92noEZz+dWl5fsinGQXdJ3BZDEHhY+irkzrEO\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]