The Deaf Gap tab was missing more than half the Deaf gap
Two tables behind the brief's resources view were describing a different dataset from
the map beside them.
"Where Nothing Was Found" still listed 3,457 groups. The map draws 2,901. Its builder
already used the current tier; it simply had not been re-run since audio Scripture and
Bible video started lifting groups out of tier 0. A mobiliser exporting that tab would
have worked through 556 groups who now have a resource. Regenerated, and it matches the
map exactly.
"The Deaf Gap" was worse, and structurally so. It came from the curated 2,106-record
set and reported 73 sign languages, 120 people groups, 19.35M people. The map draws
150 sign languages, 234 groups, 84.2M people. The tab named for the Deaf gap was
missing more than half of it. Rebuilt from the pins - the same index the map draws, so
the two cannot disagree - and it now measures 150 languages, 234 groups, 84,159,050
people, of which 136 languages / 183 groups / 55,199,840 people have nothing found.
Kept deliberately: the bridge rule, verbatim, because it is the most important sentence
in the table - a sign language is bridged ONLY by another sign language, and text or
audio in a spoken language does not reach a Deaf community. That is also why the
related-variety reasoning added for spoken macrolanguages must never be applied to
these rows. Private-use codes are counted rather than hidden: 40 of these languages
carry qaa-qtz codes that no resource pool indexes, so "nothing found" for them is a
statement about the join as much as about the world, and each such row says so.
MY FIRST VERSION OF THIS SHIPPED AN EMPTY TABLE AND MY PROBE PASSED IT. DataTable
renders a { meta, columns, rows } document and the rebuild omitted `columns`, so the
tab drew its header, its "234 rows" caption and five pages of pagination over a
completely empty body. The probe had asserted the caption - a number the page prints
about itself, which is not evidence it drew anything. It now counts rendered rows AND
cells, and is proven against the defect: with `columns` removed it reports 50 row
shells and 0 cells and FAILS; restored, it passes. The row count alone would still have
missed it.
Verified: both tabs' captions match offline counts from the same index (2,901 and 234),
both render real cells, no page errors. Screenshot read.
This commit is contained in:
parent
455c872c82
commit
78e9f3cc2f
10 changed files with 7908 additions and 3336 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -44,7 +44,7 @@
|
|||
},
|
||||
{
|
||||
"name": "deaf-gap",
|
||||
"rows": 120
|
||||
"rows": 234
|
||||
},
|
||||
{
|
||||
"name": "open-doors",
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
},
|
||||
{
|
||||
"name": "gospel-gaps",
|
||||
"rows": 3457
|
||||
"rows": 2901
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ const TABS = [
|
|||
// carries a URL you can click.
|
||||
{ id: 'links', label: 'Every Resource + Link', file: 'gospel-resource-links' },
|
||||
// The other half of the same question. Every other table here lists what EXISTS; this
|
||||
// one lists the 3,457 groups with nothing found, which is the list a mobiliser can
|
||||
// one lists the groups with nothing found, which is the list a mobiliser can
|
||||
// actually export and work through. It is NOT the "Gaps & Opportunities" table below:
|
||||
// that one is one row per group across the curated 2,106-record set and structurally
|
||||
// cannot see these groups.
|
||||
|
|
@ -47,7 +47,10 @@ const TABS = [
|
|||
// The actionable shortlist: 28 places where a co-located language ALREADY
|
||||
// carries a resource the group's own language lacks.
|
||||
{ id: 'bridges', label: 'City Bridges', file: 'city-bridge-opportunities' },
|
||||
// The largest structurally-invisible bloc: 73 sign languages, 17.5M with nothing.
|
||||
// The largest structurally-invisible bloc. Rebuilt from the pins: it used to be derived
|
||||
// from the curated 2,106-record set and showed 73 sign languages / 120 groups / 19.35M,
|
||||
// while the map drew 150 / 234 / 84.2M — the Deaf tab was missing more than half of the
|
||||
// thing it is named for. Counts live in the table's own meta now, not in this comment.
|
||||
{ id: 'deaf', label: 'The Deaf Gap', file: 'deaf-gap' },
|
||||
{ id: 'resources', label: 'Resources by People Group', file: 'people-group-resources' },
|
||||
// Ranked languages per country joined to resources — the bridge-language view.
|
||||
|
|
|
|||
117
plugin-designs/gospel-resources/scripts/build-deaf-gap-table.mjs
Normal file
117
plugin-designs/gospel-resources/scripts/build-deaf-gap-table.mjs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* build-deaf-gap-table.mjs — the Deaf gap, rebuilt from the PINS.
|
||||
*
|
||||
* WHY IT IS BEING REBUILT. The table this replaces was derived from the curated
|
||||
* 2,106-record set and reported 73 sign languages, 120 people groups and 19.35M people.
|
||||
* The map draws 150 sign languages across 234 groups and 84.2M people. Two surfaces of one
|
||||
* dataset describing different universes, and the smaller one was the "Deaf Gap" tab — the
|
||||
* table a reader would export to decide where Deaf work is needed. It was missing more than
|
||||
* half of it.
|
||||
*
|
||||
* MEASURED NOW: 150 sign languages · 234 groups · 84.2M people, of which 136 languages /
|
||||
* 183 groups / 55.2M people have nothing found in any pool checked.
|
||||
*
|
||||
* THE BRIDGE RULE IS KEPT VERBATIM because it is the most important sentence here: a sign
|
||||
* language is bridged ONLY by another sign language. Text and audio in a spoken language do
|
||||
* not reach a Deaf community, so the "related variety" reasoning that applies to spoken
|
||||
* macrolanguages must never be applied to these rows.
|
||||
*
|
||||
* PRIVATE-USE CODES ARE COUNTED, NOT HIDDEN. 40 of these languages carry qaa-qtz codes,
|
||||
* which are private use in ISO 639-3 and are indexed by no resource pool on earth. A group
|
||||
* on such a code cannot be matched to a resource even if one exists, so "nothing found" for
|
||||
* them is a statement about the JOIN as much as about the world, and the row says so.
|
||||
*/
|
||||
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||
const REPO = resolve(HERE, '../../..')
|
||||
const PINS = resolve(REPO, 'data/tables/people-group-pins.json')
|
||||
const BY_COUNTRY = resolve(REPO, 'data/tables/gospel-by-country.json')
|
||||
const OUT = resolve(REPO, 'data/tables/deaf-gap.json')
|
||||
|
||||
const pins = JSON.parse(readFileSync(PINS, 'utf8'))
|
||||
const { codes, pins: rows } = pins
|
||||
|
||||
let countryName = {}
|
||||
try {
|
||||
const c = JSON.parse(readFileSync(BY_COUNTRY, 'utf8'))
|
||||
for (const r of c.rows || []) if (r.iso3) countryName[r.iso3] = r.country || r.iso3
|
||||
} catch { countryName = {} }
|
||||
|
||||
const isPrivate = (c) => !!c && c.length === 3 && c >= 'qaa' && c <= 'qtz'
|
||||
const out = []
|
||||
const langs = new Set()
|
||||
const nothingLangs = new Set()
|
||||
let people = 0, nothingGroups = 0, nothingPeople = 0, privateCodes = new Set()
|
||||
|
||||
for (const [name, , , iso3, code, pop] of rows) {
|
||||
const v = codes[code]
|
||||
if (!(v && v.sg === 1)) continue
|
||||
langs.add(code)
|
||||
people += pop || 0
|
||||
if (isPrivate(code)) privateCodes.add(code)
|
||||
const hasFilm = !!v.f
|
||||
const hasAny = !!(v.s || v.f || v.au || v.bv || (v.d && v.d.length))
|
||||
if (!hasAny) { nothingLangs.add(code); nothingGroups++; nothingPeople += pop || 0 }
|
||||
out.push({
|
||||
people_group: name,
|
||||
sign_language: v.l || '',
|
||||
iso639_3: code || '',
|
||||
countries: countryName[iso3] || iso3 || '',
|
||||
population: pop || 0,
|
||||
// A Deaf group is reached by SIGNED Scripture. Text is recorded because a Deaf reader
|
||||
// may use it, but it is never what makes the row "reached".
|
||||
signed_film: hasFilm ? v.f : '',
|
||||
has_signed_film: hasFilm,
|
||||
has_any_resource: hasAny,
|
||||
code_unmatchable: isPrivate(code),
|
||||
status: hasAny ? 'a resource exists in this sign language' : 'nothing found in the pools checked',
|
||||
note: isPrivate(code)
|
||||
? 'This code is PRIVATE USE in ISO 639-3 (qaa-qtz). No resource pool indexes it, so a resource could exist and still never join to this row.'
|
||||
: '',
|
||||
})
|
||||
}
|
||||
out.sort((a, b) => Number(a.has_any_resource) - Number(b.has_any_resource) || b.population - a.population)
|
||||
|
||||
const fmt = (n) => n.toLocaleString('en-US')
|
||||
// DataTable renders a { meta, columns, rows } document and `columns` IS the Tabulator
|
||||
// definition — omit it and the table draws its header, its row count and its pagination
|
||||
// over an empty body, which looks like a data problem and is not one.
|
||||
const columns = [
|
||||
{ title: 'People Group', field: 'people_group', type: 'string' },
|
||||
{ title: 'Sign language', field: 'sign_language', type: 'string' },
|
||||
{ title: 'ISO 639-3', field: 'iso639_3', type: 'string' },
|
||||
{ title: 'Countries', field: 'countries', type: 'string' },
|
||||
{ title: 'Population', field: 'population', type: 'number' },
|
||||
{ title: 'Signed film', field: 'has_signed_film', type: 'boolean' },
|
||||
{ title: 'Signed film link', field: 'signed_film', type: 'url' },
|
||||
{ title: 'Has anything', field: 'has_any_resource', type: 'boolean' },
|
||||
{ title: 'Code unlookupable', field: 'code_unmatchable', type: 'boolean' },
|
||||
{ title: 'Status', field: 'status', type: 'string' },
|
||||
{ title: 'Note', field: 'note', type: 'string' },
|
||||
]
|
||||
|
||||
mkdirSync(dirname(OUT), { recursive: true })
|
||||
writeFileSync(OUT, `${JSON.stringify({
|
||||
columns,
|
||||
meta: {
|
||||
title: 'The Deaf Gap',
|
||||
grain: 'one row per Deaf people group',
|
||||
generated: new Date().toISOString().slice(0, 10),
|
||||
measured: `${langs.size} sign languages · ${out.length} people groups · ${fmt(people)} people. ` +
|
||||
`${nothingLangs.size} languages / ${nothingGroups} groups / ${fmt(nothingPeople)} people with NOTHING found.`,
|
||||
bridge_rule: 'A sign language is bridged ONLY by another sign language. Text and audio in a spoken language do not reach a Deaf community.',
|
||||
compounding_problem: `${privateCodes.size} of these languages carry PRIVATE-USE (qaa-qtz) codes outside ISO 639-3. No resource pool indexes a private-use code, so those groups cannot be matched to a resource even if one exists.`,
|
||||
what_is_unchecked: 'Deaf Bible Society and DOOR International, both key-gated. The open catalogues are exhausted: the JESUS Film lists 14 sign-language entries across 13 ISO codes and every one is already here, and Faith Comes By Hearing carries none.',
|
||||
source: 'data/tables/people-group-pins.json — the same index the map draws, so the two cannot disagree.',
|
||||
},
|
||||
rows: out,
|
||||
}, null, 1)}\n`)
|
||||
|
||||
console.log(`deaf-gap: ${out.length} groups · ${langs.size} sign languages · ${fmt(people)} people`)
|
||||
console.log(` nothing found: ${nothingLangs.size} languages / ${nothingGroups} groups / ${fmt(nothingPeople)} people`)
|
||||
console.log(` private-use codes: ${privateCodes.size}`)
|
||||
console.log(`wrote ${OUT}`)
|
||||
3702
public/assets/tables/deaf-gap.json
vendored
3702
public/assets/tables/deaf-gap.json
vendored
File diff suppressed because it is too large
Load diff
2
public/assets/tables/gospel-gaps.json
vendored
2
public/assets/tables/gospel-gaps.json
vendored
File diff suppressed because one or more lines are too long
4
public/assets/tables/index.json
vendored
4
public/assets/tables/index.json
vendored
|
|
@ -44,7 +44,7 @@
|
|||
},
|
||||
{
|
||||
"name": "deaf-gap",
|
||||
"rows": 120
|
||||
"rows": 234
|
||||
},
|
||||
{
|
||||
"name": "open-doors",
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
},
|
||||
{
|
||||
"name": "gospel-gaps",
|
||||
"rows": 3457
|
||||
"rows": 2901
|
||||
}
|
||||
]
|
||||
}
|
||||
3702
public/doxa-maps/assets/tables/deaf-gap.json
generated
3702
public/doxa-maps/assets/tables/deaf-gap.json
generated
File diff suppressed because it is too large
Load diff
2
public/doxa-maps/assets/tables/gospel-gaps.json
generated
2
public/doxa-maps/assets/tables/gospel-gaps.json
generated
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue