Name the language spoken around a group that has nothing

For 230 people groups the map said "nothing found" and stopped, when
that was not the whole truth: a language already spoken widely in
their country does have Scripture or the film. Kimr in Sudan has
nothing in Assangori; Sudanese Arabic, spoken by 65 groups around
them, has both. That is the difference between no way in and a way in
that is not their heart language.

WORDED SO IT CANNOT BE SKIMMED AS "THEY HAVE SCRIPTURE". The heading
says "Not their language", the body names whose language it is and how
widely it is spoken, the strength is quoted from the source, and the
last line says a second language is a way in and not a translation.
The chips above are untouched and still read "none found" five times,
and the tier is unchanged: 2,001 groups still have nothing of their
own, exactly as before.

Two exclusions, both measured rather than assumed. Fourteen of these
rows offer a DEAF people group a SPOKEN bridge — Gawri "has a film" is
no use to Deaf Pakistanis, the same error as offering them recorded
audio — so sign languages are out. Sixty-five carry the curated
strength "weak — may not be a real lingua franca"; a bridge the source
itself doubts is not an answer, so those are out too.

Placed below the whole chip row after a first pass split it, leaving
the Zume chip stranded under the panel.
This commit is contained in:
doxa-maps-88655c70 2026-09-24 23:20:30 +00:00
parent 1ca75ba838
commit d55285eafe
13 changed files with 101 additions and 37 deletions

File diff suppressed because one or more lines are too long

View file

@ -161,7 +161,8 @@ const pgLoading = ref(false)
const pgErr = ref(null)
const selectedGroup = ref(null) // set = the people-group detail is showing
const pinRows = shallowRef([]) // [name, lat, lng, iso3, code, population, tier]
const pinCodes = ref({}) // ISO 639-3 -> { l, s, f, a, o, ck, un }
const pinCodes = ref({})
const pinBridges = ref({}) // '<iso639-3>|<ISO3 country>' -> the in-country bridge, if any
const pinCount = ref(0)
// The legend quotes these, so they can never drift from what the layer is drawing.
@ -555,6 +556,7 @@ function groupAt(i) {
gospel_tract: c.gp || null,
scripture_earth: c.se || null,
gospel_audio: c.ga || null,
bridge: pinBridges.value[`${r[4]}|${r[3]}`] || null,
related: c.rel || null,
zume_url: c.z || '',
zume_approx: c.za || null,
@ -674,6 +676,7 @@ async function load() {
])
rows.value = data.countries || []
pinCodes.value = pinData.codes || {}
pinBridges.value = pinData.bridges || {}
pinRows.value = pinData.pins || []
pinCount.value = pinRows.value.length
return adm0
@ -1443,6 +1446,24 @@ useShadowStyles(
Discipleship training · not in Zume's 54
</span>
</div>
<!-- AN IN-COUNTRY BRIDGE, and only for a group with nothing of their own. Worded
so it cannot be skimmed as "they have Scripture": the heading says NOT their
language, the body names whose language it is, and the gap above is
untouched. A bridge is a way in, not a translation. -->
<div v-if="selectedGroup.bridge && !selectedGroup.scripture_url && !selectedGroup.film_url
&& !selectedGroup.audio && !selectedGroup.gospel_audio && !selectedGroup.scripture_earth"
class="gm-sign" style="border-left-color:#92b195">
<b>Not their language — but spoken around them.</b>
<br>Nothing was found in {{ selectedGroup.language || 'their language' }}. In this
country, <b>{{ selectedGroup.bridge.l }}</b> is spoken by
{{ selectedGroup.bridge.n }} people groups and does have
<template v-if="selectedGroup.bridge.s && selectedGroup.bridge.f">Scripture and the JESUS Film</template>
<template v-else-if="selectedGroup.bridge.s">Scripture</template>
<template v-else>the JESUS Film</template>.
<br><em>Bridge strength: {{ selectedGroup.bridge.st }}.</em> A second language is a
way in, not a translation — the gap in their own language is unchanged.
</div>
<p v-if="selectedGroup.scripture_title || selectedGroup.scripture_scope" class="gm-scope">
<b>{{ selectedGroup.scripture_title || 'Scripture' }}</b>
<template v-if="selectedGroup.scripture_scope"> — {{ selectedGroup.scripture_scope }}</template>

View file

@ -49,6 +49,7 @@ const MACRO = resolve(REPO, 'data/tables/iso-macrolanguages.json')
const GODTOOLS = resolve(REPO, 'data/tables/godtools-index.json')
const SCRIPTUREEARTH = resolve(REPO, 'data/tables/scriptureearth-index.json')
const GRN = resolve(REPO, 'data/tables/grn-index.json')
const GAPSOPP = resolve(REPO, 'data/tables/gaps-and-opportunities.json')
// Two entries with the same subject rendered as "Open Bible Stories Open Bible Stories"
// — two links a reader cannot tell apart. 40 languages are in that state, because a
@ -503,6 +504,46 @@ for (const [c, v] of Object.entries(codes)) {
v.un = grnDecided ? NOT_SCANNED : `${NOT_SCANNED}, grn (not yet swept)`
}
// ═══ AN IN-COUNTRY BRIDGE, FOR GROUPS WITH NOTHING OF THEIR OWN ══════════════════════
// The map could say "nothing found" and stop. For 212 of those groups that is not the whole
// truth: a language ALREADY SPOKEN WIDELY IN THEIR COUNTRY has Scripture or the film, which
// is the difference between "no way in" and "a way in that is not their heart language".
// Kimr in Sudan has nothing; Sudanese Arabic, spoken by 65 groups around them, has both.
//
// THIS IS NEVER A CLAIM THAT THEY HAVE SCRIPTURE, and the sheet must not let a reader
// skim it as one. A bridge is a second language: real enough to act on, never a substitute
// for a translation, and the reason the heart-language gap stays exactly as it was.
//
// TWO EXCLUSIONS, both measured:
// - SIGN LANGUAGES. 14 of these rows offer a Deaf people group a SPOKEN bridge. Gawri
// "has a film" is of no use to Deaf Pakistanis, and suggesting it would be the same
// error as offering them recorded audio.
// - WEAK BRIDGES. 65 rows carry the curated strength "weak — shared by few groups; may
// not be a real lingua franca". A bridge the source itself doubts is not an answer.
const bridges = {}
let bridgeRows = 0
try {
const go = JSON.parse(readFileSync(GAPSOPP, 'utf8'))
for (const r of go.rows || []) {
if (r.heart_has_any) continue
if (!(r.bridge_has_scripture || r.bridge_has_film)) continue
if (/^weak/.test(r.bridge_strength || '')) continue
const code = r.heart_iso639_3
const iso3 = r.iso3
if (!code || !iso3) continue
if (codes[code] && codes[code].sg === 1) continue
bridges[`${code}|${iso3}`] = {
l: r.bridge_language || '',
c: r.bridge_iso639_3 || '',
st: r.bridge_strength || '',
n: r.bridge_groups_in_country || 0,
s: !!r.bridge_has_scripture,
f: !!r.bridge_has_film,
}
bridgeRows++
}
} catch { /* the curated table is optional; without it the map simply says less */ }
// Drop anything verification proved dead. THIS MUST RUN AFTER EVERY SOURCE HAS ATTACHED:
// it used to sit before the audio merge, so 71 dead bible.is filesets were attached after
// the drop had already happened and shipped anyway, while the pass reported "dropped 0".
@ -598,6 +639,7 @@ for (const p of slim) {
}
const out = {
bridges,
_note: 'Generated by scripts/build-people-group-pins.mjs. pins=[name,lat,lng,iso3,code,pop,tier]; URLs live in codes[] by ISO 639-3. No URL is invented here.',
generated: new Date().toISOString().slice(0, 10),
counts: { pins: pins.length, joined, withUrl, liftedByD43, codes: Object.keys(codes).length, droppedNoCoord: noCoord },
@ -626,6 +668,7 @@ console.log(`arclight codes ${Object.keys(arc).length} (${arcOnly} new, ${upgr
console.log(`share urls ${Object.keys(share).length}`)
console.log(`fcbh codes ${audioCodes} (${audioNew} new codes)`)
console.log(`gospel tracts ${gospelCodes} (Cru/GodTools presentations; depth only, tier UNCHANGED)`)
console.log(`in-country bridge ${bridgeRows} (groups with NOTHING of their own; a widely-spoken language around them has something — never counted as theirs)`)
console.log(`gospel audio ${grnCodes} (${grnNew} new codes; GRN via 5fish — heard, not read; ${grnSignSkipped} sign language(s) skipped)`)
console.log(`scripture earth ${seCodes} (${seNew} new codes; SIL partners — Scripture in their own language)`)
console.log(`related variety ${relatedCodes} (nothing of their own; an ISO macrolanguage sibling has something — tier UNCHANGED)`)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -26,7 +26,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -26,7 +26,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -40,7 +40,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf" 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

@ -26,7 +26,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf" 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

@ -596,7 +596,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "doxa-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha",
"integrity": "sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf",
"elements": [
"gospel-resources-map"
],
@ -616,7 +616,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha\" 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-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf\" 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>"
}
},
{
@ -630,7 +630,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha\" 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-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf\" 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>"
}
},
{
@ -644,7 +644,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": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha\" 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": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf\" 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>"
}
},
{
@ -658,7 +658,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-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha\" 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-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf\" 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>"
}
},
{
@ -672,7 +672,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": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-5yvjn7r2q52JpjK/dNXfEXIEMZpaA5MmdNN3aXb7TlBkHGULcAYtFcBnHifcDjha\" 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": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-mn0BNaHqLb//PbOgP1nMiIBJAkJXdbEj3za8PBVpACn9CIBakKOvRFk1HlAeVAqf\" 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>"
}
}
]