diff --git a/documentation/reference-library-index.md b/documentation/reference-library-index.md index c23c9b26a..e7a5a11d6 100644 --- a/documentation/reference-library-index.md +++ b/documentation/reference-library-index.md @@ -202,6 +202,8 @@ and a change here can break other maps. `import … from '@map/utils/colocation.js'` - **countries-meta** — countries-meta.js — a PORT of DX-life's config/countries-meta.ts (326 lines), the rollup `import … from '@map/utils/countries-meta.js'` +- **countryName** — countryName.js — a country's name in the reader's language. + `import … from '@map/utils/countryName.js'` - **embedBase** — embedBase.js — Where THIS bundle's built tree is served from, resolved at runtime. `import … from '@map/utils/embedBase.js'` - **geoUtils** — geoUtils.js — Geographic / GeoJSON Utility Functions @@ -243,6 +245,8 @@ and a change here can break other maps. `import … from '@map/data/country-posters.json'` - **iso-numeric-to-alpha2** — "4":"AF","8":"AL","12":"DZ","24":"AO","32":"AR","36":"AU","40":"AT","50":"BD", `import … from '@map/data/iso-numeric-to-alpha2.json'` +- **iso3-to-alpha2** — "_meta": { + `import … from '@map/data/iso3-to-alpha2.json'` - **langFamilyByIso** — "aar": "Afro-Asiatic", `import … from '@map/data/langFamilyByIso.json'` - **langFamilyByLanguage** — {"Chamacoco":"Zamucoan","Ninam":"Yanomaman","Yagua":"Yaguan","Muinane":"Witotoan","Finnish":"Uralic","Hill Mar diff --git a/library/data/iso3-to-alpha2.json b/library/data/iso3-to-alpha2.json new file mode 100644 index 000000000..cd15ddee5 --- /dev/null +++ b/library/data/iso3-to-alpha2.json @@ -0,0 +1,256 @@ +{ + "_meta": { + "generated_by": "library/scripts/generate-iso3-to-alpha2.mjs (bun run gen:iso3-to-alpha2)", + "purpose": "alpha-3 -> alpha-2 so Intl.DisplayNames can produce a LOCALIZED country name. Drives no data fetch.", + "not_to_be_confused_with": "library/scripts/research/out/iso3-to-iso2.json — the 176-country research spine that DOES drive fetches", + "source": "CLDR cldr-core 48.2.2, vendored at library/vendor/cldr/codeMappings.json (Unicode-3.0)", + "countries": 242, + "exceptions": { + "KOS": "XK — Kosovo has no ISO 3166-1 assignment; XK is the user-assigned code CLDR itself uses in locale ids (sr_Cyrl_XK)." + } + }, + "map": { + "AFG": "AF", + "ALB": "AL", + "DZA": "DZ", + "ASM": "AS", + "AND": "AD", + "AGO": "AO", + "AIA": "AI", + "ATG": "AG", + "ARG": "AR", + "ARM": "AM", + "ABW": "AW", + "AUS": "AU", + "AUT": "AT", + "AZE": "AZ", + "BHR": "BH", + "BGD": "BD", + "BRB": "BB", + "BLR": "BY", + "BEL": "BE", + "BLZ": "BZ", + "BEN": "BJ", + "BMU": "BM", + "BTN": "BT", + "BOL": "BO", + "BES": "BQ", + "BIH": "BA", + "BWA": "BW", + "BRA": "BR", + "BRN": "BN", + "BGR": "BG", + "BFA": "BF", + "BDI": "BI", + "CPV": "CV", + "KHM": "KH", + "CMR": "CM", + "CAN": "CA", + "CYM": "KY", + "CAF": "CF", + "TCD": "TD", + "CHL": "CL", + "CHN": "CN", + "CXR": "CX", + "CCK": "CC", + "COL": "CO", + "COM": "KM", + "COK": "CK", + "CRI": "CR", + "CIV": "CI", + "HRV": "HR", + "CUB": "CU", + "CUW": "CW", + "CYP": "CY", + "DNK": "DK", + "DJI": "DJ", + "DMA": "DM", + "DOM": "DO", + "ECU": "EC", + "EGY": "EG", + "SLV": "SV", + "GNQ": "GQ", + "ERI": "ER", + "EST": "EE", + "SWZ": "SZ", + "ETH": "ET", + "FLK": "FK", + "FRO": "FO", + "FJI": "FJ", + "FIN": "FI", + "FRA": "FR", + "GUF": "GF", + "PYF": "PF", + "GAB": "GA", + "GEO": "GE", + "DEU": "DE", + "GHA": "GH", + "GIB": "GI", + "GRC": "GR", + "GRL": "GL", + "GRD": "GD", + "GLP": "GP", + "GUM": "GU", + "GTM": "GT", + "GGY": "GG", + "GIN": "GN", + "GNB": "GW", + "GUY": "GY", + "HTI": "HT", + "HND": "HN", + "HKG": "HK", + "HUN": "HU", + "ISL": "IS", + "IND": "IN", + "IDN": "ID", + "IRN": "IR", + "IRQ": "IQ", + "IRL": "IE", + "IMN": "IM", + "ISR": "IL", + "ITA": "IT", + "JAM": "JM", + "JPN": "JP", + "JEY": "JE", + "JOR": "JO", + "KAZ": "KZ", + "KEN": "KE", + "KIR": "KI", + "KOS": "XK", + "KWT": "KW", + "KGZ": "KG", + "LAO": "LA", + "LVA": "LV", + "LBN": "LB", + "LSO": "LS", + "LBR": "LR", + "LBY": "LY", + "LIE": "LI", + "LTU": "LT", + "LUX": "LU", + "MAC": "MO", + "MDG": "MG", + "MWI": "MW", + "MYS": "MY", + "MLI": "ML", + "MLT": "MT", + "MTQ": "MQ", + "MRT": "MR", + "MUS": "MU", + "MYT": "YT", + "MEX": "MX", + "MDA": "MD", + "MCO": "MC", + "MNG": "MN", + "MNE": "ME", + "MSR": "MS", + "MAR": "MA", + "MOZ": "MZ", + "MMR": "MM", + "NAM": "NA", + "NRU": "NR", + "NPL": "NP", + "NCL": "NC", + "NZL": "NZ", + "NIC": "NI", + "NER": "NE", + "NGA": "NG", + "NIU": "NU", + "NFK": "NF", + "PRK": "KP", + "MKD": "MK", + "NOR": "NO", + "OMN": "OM", + "PAK": "PK", + "PLW": "PW", + "PSE": "PS", + "PAN": "PA", + "PNG": "PG", + "PRY": "PY", + "PER": "PE", + "POL": "PL", + "PRT": "PT", + "PRI": "PR", + "QAT": "QA", + "REU": "RE", + "ROU": "RO", + "RWA": "RW", + "BLM": "BL", + "SHN": "SH", + "KNA": "KN", + "LCA": "LC", + "MAF": "MF", + "SPM": "PM", + "VCT": "VC", + "WSM": "WS", + "SMR": "SM", + "STP": "ST", + "SAU": "SA", + "SEN": "SN", + "SRB": "RS", + "SYC": "SC", + "SLE": "SL", + "SGP": "SG", + "SXM": "SX", + "SVK": "SK", + "SVN": "SI", + "SOM": "SO", + "ZAF": "ZA", + "KOR": "KR", + "SSD": "SS", + "ESP": "ES", + "LKA": "LK", + "SDN": "SD", + "SUR": "SR", + "SJM": "SJ", + "SWE": "SE", + "CHE": "CH", + "SYR": "SY", + "TWN": "TW", + "TJK": "TJ", + "TZA": "TZ", + "THA": "TH", + "BHS": "BS", + "VGB": "VG", + "CZE": "CZ", + "COD": "CD", + "FSM": "FM", + "GMB": "GM", + "MDV": "MV", + "MHL": "MH", + "NLD": "NL", + "MNP": "MP", + "PHL": "PH", + "PCN": "PN", + "COG": "CG", + "RUS": "RU", + "SLB": "SB", + "TCA": "TC", + "ARE": "AE", + "GBR": "GB", + "USA": "US", + "VIR": "VI", + "TLS": "TL", + "TGO": "TG", + "TKL": "TK", + "TON": "TO", + "TTO": "TT", + "TUN": "TN", + "TUR": "TR", + "TKM": "TM", + "TUV": "TV", + "UGA": "UG", + "UKR": "UA", + "URY": "UY", + "UZB": "UZ", + "VUT": "VU", + "VAT": "VA", + "VEN": "VE", + "VNM": "VN", + "WLF": "WF", + "ESH": "EH", + "YEM": "YE", + "ZMB": "ZM", + "ZWE": "ZW" + } +} diff --git a/library/scripts/generate-iso3-to-alpha2.mjs b/library/scripts/generate-iso3-to-alpha2.mjs new file mode 100644 index 000000000..48e334830 --- /dev/null +++ b/library/scripts/generate-iso3-to-alpha2.mjs @@ -0,0 +1,122 @@ +#!/usr/bin/env node +// generate-iso3-to-alpha2.mjs — `bun run gen:iso3-to-alpha2`. Offline, no network, no dependency. +// +// Writes library/data/iso3-to-alpha2.json: the alpha-2 code for each of the 242 alpha-3 codes in +// library/data/countries.json, so a country NAME can be localized. Intl.DisplayNames('region') takes +// alpha-2 or UN M49 only -- it does NOT accept alpha-3 -- and our data speaks alpha-3 throughout, so +// without this join every country name is stuck in English. +// +// ★ THIS IS NOT THE RESEARCH MAP. library/scripts/research/out/iso3-to-iso2.json is a different file +// with a different job: the 176-country spine that drives the data FETCHES. Expanding that one changes +// what gets fetched, which is a data-scope decision for the Driver (dx-shepherd, REG242B) and must not +// happen as a side effect of adding country names. This map drives no fetch. The two are deliberately +// not interchangeable, which is why they have different names, different shapes and this paragraph. +// +// ★ IT GRADES ITS OWN OUTPUT AND EXITS NON-ZERO. A generator that writes whatever it derived is a +// generator that will one day write a hole. Coverage, injectivity and the single documented exception +// are asserted here, so a bad refresh of the vendored CLDR cannot land quietly. +import { readFileSync, writeFileSync } from 'node:fs' +import { resolve, dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' + +const REPO = process.env.DOXA_REPO || resolve(dirname(fileURLToPath(import.meta.url)), '..', '..') +const read = (p) => JSON.parse(readFileSync(join(REPO, p), 'utf8')) + +const VENDOR = 'library/vendor/cldr/codeMappings.json' +const OUT = 'library/data/iso3-to-alpha2.json' + +// ── the one exception, and why it is not a fudge ───────────────────────────────────────────────── +// Kosovo has NO ISO 3166-1 assignment, so CLDR's codeMappings cannot carry it and no amount of +// re-downloading will add it. XK is the USER-ASSIGNED code the EU, the IMF, Unicode's own CLDR +// locale data (sr_Cyrl_XK) and every major platform settled on. It is recorded here as a named +// exception with its reason rather than patched into the vendored file, so the vendored bytes stay +// exactly upstream's and the deviation stays visible to the next reader. +const EXCEPTIONS = { + KOS: { alpha2: 'XK', why: 'Kosovo has no ISO 3166-1 assignment; XK is the user-assigned code CLDR itself uses in locale ids (sr_Cyrl_XK).' }, +} + +const cldr = read(VENDOR).supplemental.codeMappings +const countries = read('library/data/countries.json') + +// CLDR is keyed by alpha-2 with an _alpha3 inside; we need the inverse. +const byAlpha3 = new Map() +const cldrCollisions = [] +for (const [alpha2, v] of Object.entries(cldr)) { + const a3 = v && v._alpha3 + if (!a3) continue + if (byAlpha3.has(a3)) cldrCollisions.push(`${a3} claimed by ${byAlpha3.get(a3)} and ${alpha2}`) + else byAlpha3.set(a3, alpha2) +} + +const map = {} +const missing = [] +for (const { value: iso3, label } of countries) { + const fromCldr = byAlpha3.get(iso3) + const exc = EXCEPTIONS[iso3] + if (fromCldr) map[iso3] = fromCldr + else if (exc) map[iso3] = exc.alpha2 + else missing.push(`${iso3} (${label})`) +} + +// ── assertions: the generator refuses to ship a map it cannot defend ──────────────────────────── +let fails = 0 +const ok = (c, m) => { console.log(` ${c ? 'ok ' : 'FAIL'} - ${m}`); if (!c) fails++ } + +ok(countries.length === 242, `the country list holds 242 codes (found ${countries.length})`) +ok(missing.length === 0, missing.length + ? `${missing.length} code(s) have NO alpha-2 and no documented exception: ${missing.join(', ')}` + : 'every code resolved, via CLDR or a documented exception') + +const seen = new Map() +const dupes = [] +for (const [iso3, a2] of Object.entries(map)) { + if (seen.has(a2)) dupes.push(`${a2} claimed by ${seen.get(a2)} and ${iso3}`) + else seen.set(a2, iso3) +} +ok(dupes.length === 0, dupes.length + ? `alpha-2 collisions -- at least one country would take another's name: ${dupes.join('; ')}` + : `all ${Object.keys(map).length} codes map to a DISTINCT alpha-2`) + +ok(Object.entries(map).every(([, a2]) => /^[A-Z]{2}$/.test(a2)), 'every alpha-2 is two uppercase letters') + +// Every exception must still BE one. If CLDR ever assigns KOS, this fires and the entry should go. +for (const [iso3, e] of Object.entries(EXCEPTIONS)) { + ok(!byAlpha3.has(iso3), + `the ${iso3} exception is still needed -- CLDR ${byAlpha3.has(iso3) ? `now assigns it ${byAlpha3.get(iso3)}, so DELETE the exception` : 'still has no assignment for it'}`) +} + +// ── cross-check the research map rather than touching it ──────────────────────────────────────── +// CLDR is an independent source for the 176 values that map already ships. Disagreements are reported, +// never written: that file drives fetches and is not this generator's to edit. +let disagreements = 0 +try { + const research = read('library/scripts/research/out/iso3-to-iso2.json') + for (const [iso3, a2] of Object.entries(research)) { + const c = byAlpha3.get(iso3) + if (c && c !== a2) { console.log(` FAIL - research map says ${iso3} -> ${a2}, CLDR says ${c}`); disagreements++ } + } + ok(disagreements === 0, + `CLDR agrees with all ${Object.keys(research).length} values in the research spine map (reported, never rewritten -- that file drives fetches)`) +} catch (e) { + console.log(` note - research map not readable here (${e.code || e.message}); cross-check skipped`) +} + +if (fails) { + console.log(`\nISO3-TO-ALPHA2: ${fails} FAIL(s) — nothing written`) + process.exit(1) +} + +const cldrVersion = '48.2.2' // keep in step with library/vendor/cldr/README.md +writeFileSync(join(REPO, OUT), JSON.stringify({ + _meta: { + generated_by: 'library/scripts/generate-iso3-to-alpha2.mjs (bun run gen:iso3-to-alpha2)', + purpose: 'alpha-3 -> alpha-2 so Intl.DisplayNames can produce a LOCALIZED country name. Drives no data fetch.', + not_to_be_confused_with: 'library/scripts/research/out/iso3-to-iso2.json — the 176-country research spine that DOES drive fetches', + source: `CLDR cldr-core ${cldrVersion}, vendored at ${VENDOR} (Unicode-3.0)`, + countries: Object.keys(map).length, + exceptions: Object.fromEntries(Object.entries(EXCEPTIONS).map(([k, v]) => [k, `${v.alpha2} — ${v.why}`])), + }, + map, +}, null, 2) + '\n') + +console.log(`\nISO3-TO-ALPHA2: wrote ${OUT} — ${Object.keys(map).length} countries, ${Object.keys(EXCEPTIONS).length} documented exception(s)`) diff --git a/library/utils/countryName.js b/library/utils/countryName.js new file mode 100644 index 000000000..4805a70e2 --- /dev/null +++ b/library/utils/countryName.js @@ -0,0 +1,84 @@ +/** + * countryName.js — a country's name in the reader's language. + * + * Our data speaks ISO 3166-1 ALPHA-3 ("DEU"). Intl.DisplayNames('region') accepts alpha-2 or UN M49 + * and NOT alpha-3, so every country name was stuck in English until the two were joined. The join is + * library/data/iso3-to-alpha2.json, derived from vendored CLDR by generate-iso3-to-alpha2.mjs. + * + * ★ Intl.DisplayNames THROWS on a missing code. `dn.of(undefined)` is a RangeError, not a null return, + * so every path here checks the alpha-2 before asking. That is the single defect this file exists to + * not have: a country absent from the map would otherwise take down whatever rendered it. + * + * ★ AND IT THROWS ON A MALFORMED ONE TOO, which is why the regex guard is not redundant with the + * lookup. dn.of('XYZ') is also a RangeError -- 'structurally invalid' is a different failure from + * 'not found', and only the second returns the input unchanged. + * + * FALLBACK ORDER, each step a real answer rather than a placeholder: + * 1. the localized name from Intl.DisplayNames + * 2. the canonical ENGLISH name from library/data/countries.json — a real name in the wrong language + * beats a bare code for a reader, and it is what our own tables already show + * 3. the alpha-3 code itself, so something identifiable always renders + * + * No i18n framework is required: this reads a locale STRING the caller already has. + */ +import table from '../data/iso3-to-alpha2.json' +import countries from '../data/countries.json' + +const ALPHA2 = table.map +const ENGLISH = new Map(countries.map((c) => [c.value, c.label])) + +/** 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. */ +export function alpha2Of(iso3) { + return iso3 ? ALPHA2[String(iso3).toUpperCase()] : undefined +} + +/** The canonical English name, or undefined. */ +export function englishName(iso3) { + return iso3 ? ENGLISH.get(String(iso3).toUpperCase()) : undefined +} + +// One DisplayNames per locale. Constructing it is not cheap and a country list rebuilds it per row; +// a Map keyed by locale is the whole optimisation. A locale that throws is cached as null so the +// failure costs one construction, not one per call. +const cache = new Map() +function displayNames(locale) { + const key = locale || 'en' + if (cache.has(key)) return cache.get(key) + let dn = null + try { + dn = new Intl.DisplayNames([key], { type: 'region' }) + } catch (_) { + dn = null // an unsupported locale tag, or no Intl.DisplayNames at all + } + cache.set(key, dn) + return dn +} + +/** + * @param {string} iso3 ISO 3166-1 alpha-3, e.g. 'DEU'. Case-insensitive. + * @param {string} [locale] BCP-47 tag, e.g. 'ar'. Defaults to English. + * @returns {string} the country's name in that locale, its English name, or the code. + */ +export function countryName(iso3, locale) { + const code = iso3 ? String(iso3).toUpperCase() : '' + const a2 = ALPHA2[code] + const fallback = ENGLISH.get(code) || code + + // Guard BEFORE asking: dn.of(undefined) and dn.of('XYZ') both throw. + if (!a2 || !/^[A-Z]{2}$/.test(a2)) return fallback + + const dn = displayNames(locale) + if (!dn) return fallback + try { + const name = dn.of(a2) + // An UNKNOWN-but-well-formed region comes back as the input string. That is not a name, so it + // must not win over our English label -- this is the difference between "no translation exists" + // and "the translation is literally 'DE'". + return name && name !== a2 ? name : fallback + } catch (_) { + return fallback + } +} + +export default countryName diff --git a/library/vendor/cldr/LICENSE b/library/vendor/cldr/LICENSE new file mode 100644 index 000000000..f56d93a38 --- /dev/null +++ b/library/vendor/cldr/LICENSE @@ -0,0 +1,41 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 2015-2024 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE 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 OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. + +SPDX-License-Identifier: Unicode-3.0 diff --git a/library/vendor/cldr/README.md b/library/vendor/cldr/README.md new file mode 100644 index 000000000..8c8699add --- /dev/null +++ b/library/vendor/cldr/README.md @@ -0,0 +1,42 @@ +# Vendored CLDR — `codeMappings.json` + +The ISO 3166-1 alpha-2 / alpha-3 / numeric correspondences, used to turn the alpha-3 codes our data +speaks into the alpha-2 codes `Intl.DisplayNames` requires to produce a LOCALIZED country name. + +| | | +|---|---| +| Package | `cldr-core` (unicode-org/cldr-json) | +| Version | **48.2.2** | +| Source | `https://raw.githubusercontent.com/unicode-org/cldr-json/main/cldr-json/cldr-core/supplemental/codeMappings.json` | +| Licence | **Unicode-3.0** — full text in `LICENSE` beside this file | +| Bytes | 35,948 | +| sha256 | `0d1ef50b92c1140e5847d22d96faf1a9c35543b0dedf8e9a2fcb87e4c51b9ed6` | +| Vendored | 2026-09-27 | + +## Why vendored rather than a dependency + +No npm package is added for this. A dependency would pull CLDR's whole supplemental tree, and it would +make the derivation of a shipped data file depend on an install step. The file is 35KB, it is +licensed for redistribution, and vendoring it means `bun run gen:iso3-to-alpha2` reproduces the derived +map OFFLINE — which is the actual point of vendoring, not merely having a copy. + +## What is derived from it + +`library/scripts/generate-iso3-to-alpha2.mjs` joins this file against the 242 alpha-3 codes in +`library/data/countries.json` and writes `library/data/iso3-to-alpha2.json`. The generator asserts its +own output (242 coverage, injectivity, the one documented exception) and exits non-zero if any of it +fails, so a bad refresh cannot land quietly. + +## DO NOT CONFUSE THIS WITH THE RESEARCH MAP + +`library/scripts/research/out/iso3-to-iso2.json` is a DIFFERENT map with a different job: it is the +176-country research spine that drives the data fetches, and expanding it changes what gets fetched — +a data-scope decision that belongs to the Driver, not a side effect of adding country names. The map +derived here is for DISPLAY NAMES ONLY and drives no fetch. CLDR agrees with all 176 values in the +research map, which is a useful independent check on it, but the two files are not interchangeable. + +## Refreshing + +Re-download the URL above, update the version, bytes and sha256 in this table, then run the generator +and let its assertions grade the result. If CLDR ever disagrees with a value in the research map, the +generator says so rather than silently overwriting anything. diff --git a/library/vendor/cldr/codeMappings.json b/library/vendor/cldr/codeMappings.json new file mode 100644 index 000000000..315e1a66d --- /dev/null +++ b/library/vendor/cldr/codeMappings.json @@ -0,0 +1,1934 @@ +{ + "supplemental": { + "version": { + "_unicodeVersion": "16.0.0", + "_cldrVersion": "48" + }, + "codeMappings": { + "AA": { + "_numeric": "958", + "_alpha3": "AAA" + }, + "AC": { + "_alpha3": "ASC" + }, + "AD": { + "_numeric": "020", + "_alpha3": "AND", + "_fips10": "AN" + }, + "AE": { + "_numeric": "784", + "_alpha3": "ARE" + }, + "AF": { + "_numeric": "004", + "_alpha3": "AFG" + }, + "AG": { + "_numeric": "028", + "_alpha3": "ATG", + "_fips10": "AC" + }, + "AI": { + "_numeric": "660", + "_alpha3": "AIA", + "_fips10": "AV" + }, + "AL": { + "_numeric": "008", + "_alpha3": "ALB" + }, + "AM": { + "_numeric": "051", + "_alpha3": "ARM" + }, + "AN": { + "_numeric": "530", + "_alpha3": "ANT", + "_fips10": "NT" + }, + "AO": { + "_numeric": "024", + "_alpha3": "AGO" + }, + "AQ": { + "_numeric": "010", + "_alpha3": "ATA", + "_fips10": "AY" + }, + "AR": { + "_numeric": "032", + "_alpha3": "ARG" + }, + "AS": { + "_numeric": "016", + "_alpha3": "ASM", + "_fips10": "AQ" + }, + "AT": { + "_numeric": "040", + "_alpha3": "AUT", + "_fips10": "AU" + }, + "AU": { + "_numeric": "036", + "_alpha3": "AUS", + "_fips10": "AS" + }, + "AW": { + "_numeric": "533", + "_alpha3": "ABW", + "_fips10": "AA" + }, + "AX": { + "_numeric": "248", + "_alpha3": "ALA" + }, + "AZ": { + "_numeric": "031", + "_alpha3": "AZE", + "_fips10": "AJ" + }, + "BA": { + "_numeric": "070", + "_alpha3": "BIH", + "_fips10": "BK" + }, + "BB": { + "_numeric": "052", + "_alpha3": "BRB" + }, + "BD": { + "_numeric": "050", + "_alpha3": "BGD", + "_fips10": "BG" + }, + "BE": { + "_numeric": "056", + "_alpha3": "BEL" + }, + "BF": { + "_numeric": "854", + "_alpha3": "BFA", + "_fips10": "UV" + }, + "BG": { + "_numeric": "100", + "_alpha3": "BGR", + "_fips10": "BU" + }, + "BH": { + "_numeric": "048", + "_alpha3": "BHR", + "_fips10": "BA" + }, + "BI": { + "_numeric": "108", + "_alpha3": "BDI", + "_fips10": "BY" + }, + "BJ": { + "_numeric": "204", + "_alpha3": "BEN", + "_fips10": "BN" + }, + "BL": { + "_numeric": "652", + "_alpha3": "BLM", + "_fips10": "TB" + }, + "BM": { + "_numeric": "060", + "_alpha3": "BMU", + "_fips10": "BD" + }, + "BN": { + "_numeric": "096", + "_alpha3": "BRN", + "_fips10": "BX" + }, + "BO": { + "_numeric": "068", + "_alpha3": "BOL", + "_fips10": "BL" + }, + "BQ": { + "_numeric": "535", + "_alpha3": "BES" + }, + "BR": { + "_numeric": "076", + "_alpha3": "BRA" + }, + "BS": { + "_numeric": "044", + "_alpha3": "BHS", + "_fips10": "BF" + }, + "BT": { + "_numeric": "064", + "_alpha3": "BTN" + }, + "BU": { + "_numeric": "104", + "_alpha3": "BUR" + }, + "BV": { + "_numeric": "074", + "_alpha3": "BVT" + }, + "BW": { + "_numeric": "072", + "_alpha3": "BWA", + "_fips10": "BC" + }, + "BY": { + "_numeric": "112", + "_alpha3": "BLR", + "_fips10": "BO" + }, + "BZ": { + "_numeric": "084", + "_alpha3": "BLZ", + "_fips10": "BH" + }, + "CA": { + "_numeric": "124", + "_alpha3": "CAN" + }, + "CC": { + "_numeric": "166", + "_alpha3": "CCK", + "_fips10": "CK" + }, + "CD": { + "_numeric": "180", + "_alpha3": "COD", + "_fips10": "CG" + }, + "CF": { + "_numeric": "140", + "_alpha3": "CAF", + "_fips10": "CT" + }, + "CG": { + "_numeric": "178", + "_alpha3": "COG", + "_fips10": "CF" + }, + "CH": { + "_numeric": "756", + "_alpha3": "CHE", + "_fips10": "SZ" + }, + "CI": { + "_numeric": "384", + "_alpha3": "CIV", + "_fips10": "IV" + }, + "CK": { + "_numeric": "184", + "_alpha3": "COK", + "_fips10": "CW" + }, + "CL": { + "_numeric": "152", + "_alpha3": "CHL", + "_fips10": "CI" + }, + "CM": { + "_numeric": "120", + "_alpha3": "CMR" + }, + "CN": { + "_numeric": "156", + "_alpha3": "CHN", + "_fips10": "CH" + }, + "CO": { + "_numeric": "170", + "_alpha3": "COL" + }, + "CP": { + "_alpha3": "CPT" + }, + "CR": { + "_numeric": "188", + "_alpha3": "CRI", + "_fips10": "CS" + }, + "CS": { + "_numeric": "891", + "_alpha3": "SCG", + "_fips10": "YI" + }, + "CU": { + "_numeric": "192", + "_alpha3": "CUB" + }, + "CV": { + "_numeric": "132", + "_alpha3": "CPV" + }, + "CW": { + "_numeric": "531", + "_alpha3": "CUW" + }, + "CX": { + "_numeric": "162", + "_alpha3": "CXR", + "_fips10": "KT" + }, + "CY": { + "_numeric": "196", + "_alpha3": "CYP" + }, + "CZ": { + "_numeric": "203", + "_alpha3": "CZE", + "_fips10": "EZ" + }, + "DD": { + "_numeric": "278", + "_alpha3": "DDR" + }, + "DE": { + "_numeric": "276", + "_alpha3": "DEU", + "_fips10": "GM" + }, + "DG": { + "_alpha3": "DGA" + }, + "DJ": { + "_numeric": "262", + "_alpha3": "DJI" + }, + "DK": { + "_numeric": "208", + "_alpha3": "DNK", + "_fips10": "DA" + }, + "DM": { + "_numeric": "212", + "_alpha3": "DMA", + "_fips10": "DO" + }, + "DO": { + "_numeric": "214", + "_alpha3": "DOM", + "_fips10": "DR" + }, + "DZ": { + "_numeric": "012", + "_alpha3": "DZA", + "_fips10": "AG" + }, + "EA": {}, + "EC": { + "_numeric": "218", + "_alpha3": "ECU" + }, + "EE": { + "_numeric": "233", + "_alpha3": "EST", + "_fips10": "EN" + }, + "EG": { + "_numeric": "818", + "_alpha3": "EGY" + }, + "EH": { + "_numeric": "732", + "_alpha3": "ESH", + "_fips10": "WI" + }, + "ER": { + "_numeric": "232", + "_alpha3": "ERI" + }, + "ES": { + "_numeric": "724", + "_alpha3": "ESP", + "_fips10": "SP" + }, + "ET": { + "_numeric": "231", + "_alpha3": "ETH" + }, + "EU": { + "_numeric": "967", + "_alpha3": "QUU" + }, + "FI": { + "_numeric": "246", + "_alpha3": "FIN" + }, + "FJ": { + "_numeric": "242", + "_alpha3": "FJI" + }, + "FK": { + "_numeric": "238", + "_alpha3": "FLK" + }, + "FM": { + "_numeric": "583", + "_alpha3": "FSM" + }, + "FO": { + "_numeric": "234", + "_alpha3": "FRO" + }, + "FR": { + "_numeric": "250", + "_alpha3": "FRA" + }, + "FX": { + "_numeric": "249", + "_alpha3": "FXX" + }, + "GA": { + "_numeric": "266", + "_alpha3": "GAB", + "_fips10": "GB" + }, + "GB": { + "_numeric": "826", + "_alpha3": "GBR", + "_fips10": "UK" + }, + "GD": { + "_numeric": "308", + "_alpha3": "GRD", + "_fips10": "GJ" + }, + "GE": { + "_numeric": "268", + "_alpha3": "GEO", + "_fips10": "GG" + }, + "GF": { + "_numeric": "254", + "_alpha3": "GUF", + "_fips10": "FG" + }, + "GG": { + "_numeric": "831", + "_alpha3": "GGY", + "_fips10": "GK" + }, + "GH": { + "_numeric": "288", + "_alpha3": "GHA" + }, + "GI": { + "_numeric": "292", + "_alpha3": "GIB" + }, + "GL": { + "_numeric": "304", + "_alpha3": "GRL" + }, + "GM": { + "_numeric": "270", + "_alpha3": "GMB", + "_fips10": "GA" + }, + "GN": { + "_numeric": "324", + "_alpha3": "GIN", + "_fips10": "GV" + }, + "GP": { + "_numeric": "312", + "_alpha3": "GLP" + }, + "GQ": { + "_numeric": "226", + "_alpha3": "GNQ", + "_fips10": "EK" + }, + "GR": { + "_numeric": "300", + "_alpha3": "GRC" + }, + "GS": { + "_numeric": "239", + "_alpha3": "SGS", + "_fips10": "SX" + }, + "GT": { + "_numeric": "320", + "_alpha3": "GTM" + }, + "GU": { + "_numeric": "316", + "_alpha3": "GUM", + "_fips10": "GQ" + }, + "GW": { + "_numeric": "624", + "_alpha3": "GNB", + "_fips10": "PU" + }, + "GY": { + "_numeric": "328", + "_alpha3": "GUY" + }, + "HK": { + "_numeric": "344", + "_alpha3": "HKG" + }, + "HM": { + "_numeric": "334", + "_alpha3": "HMD" + }, + "HN": { + "_numeric": "340", + "_alpha3": "HND", + "_fips10": "HO" + }, + "HR": { + "_numeric": "191", + "_alpha3": "HRV" + }, + "HT": { + "_numeric": "332", + "_alpha3": "HTI", + "_fips10": "HA" + }, + "HU": { + "_numeric": "348", + "_alpha3": "HUN" + }, + "IC": {}, + "ID": { + "_numeric": "360", + "_alpha3": "IDN" + }, + "IE": { + "_numeric": "372", + "_alpha3": "IRL", + "_fips10": "EI" + }, + "IL": { + "_numeric": "376", + "_alpha3": "ISR", + "_fips10": "IS" + }, + "IM": { + "_numeric": "833", + "_alpha3": "IMN" + }, + "IN": { + "_numeric": "356", + "_alpha3": "IND" + }, + "IO": { + "_numeric": "086", + "_alpha3": "IOT" + }, + "IQ": { + "_numeric": "368", + "_alpha3": "IRQ", + "_fips10": "IZ" + }, + "IR": { + "_numeric": "364", + "_alpha3": "IRN" + }, + "IS": { + "_numeric": "352", + "_alpha3": "ISL", + "_fips10": "IC" + }, + "IT": { + "_numeric": "380", + "_alpha3": "ITA" + }, + "JE": { + "_numeric": "832", + "_alpha3": "JEY" + }, + "JM": { + "_numeric": "388", + "_alpha3": "JAM" + }, + "JO": { + "_numeric": "400", + "_alpha3": "JOR" + }, + "JP": { + "_numeric": "392", + "_alpha3": "JPN", + "_fips10": "JA" + }, + "KE": { + "_numeric": "404", + "_alpha3": "KEN" + }, + "KG": { + "_numeric": "417", + "_alpha3": "KGZ" + }, + "KH": { + "_numeric": "116", + "_alpha3": "KHM", + "_fips10": "CB" + }, + "KI": { + "_numeric": "296", + "_alpha3": "KIR", + "_fips10": "KR" + }, + "KM": { + "_numeric": "174", + "_alpha3": "COM", + "_fips10": "CN" + }, + "KN": { + "_numeric": "659", + "_alpha3": "KNA", + "_fips10": "SC" + }, + "KP": { + "_numeric": "408", + "_alpha3": "PRK", + "_fips10": "KN" + }, + "KR": { + "_numeric": "410", + "_alpha3": "KOR", + "_fips10": "KS" + }, + "KW": { + "_numeric": "414", + "_alpha3": "KWT", + "_fips10": "KU" + }, + "KY": { + "_numeric": "136", + "_alpha3": "CYM", + "_fips10": "CJ" + }, + "KZ": { + "_numeric": "398", + "_alpha3": "KAZ" + }, + "LA": { + "_numeric": "418", + "_alpha3": "LAO" + }, + "LB": { + "_numeric": "422", + "_alpha3": "LBN", + "_fips10": "LE" + }, + "LC": { + "_numeric": "662", + "_alpha3": "LCA", + "_fips10": "ST" + }, + "LI": { + "_numeric": "438", + "_alpha3": "LIE", + "_fips10": "LS" + }, + "LK": { + "_numeric": "144", + "_alpha3": "LKA", + "_fips10": "CE" + }, + "LR": { + "_numeric": "430", + "_alpha3": "LBR", + "_fips10": "LI" + }, + "LS": { + "_numeric": "426", + "_alpha3": "LSO", + "_fips10": "LT" + }, + "LT": { + "_numeric": "440", + "_alpha3": "LTU", + "_fips10": "LH" + }, + "LU": { + "_numeric": "442", + "_alpha3": "LUX" + }, + "LV": { + "_numeric": "428", + "_alpha3": "LVA", + "_fips10": "LG" + }, + "LY": { + "_numeric": "434", + "_alpha3": "LBY" + }, + "MA": { + "_numeric": "504", + "_alpha3": "MAR", + "_fips10": "MO" + }, + "MC": { + "_numeric": "492", + "_alpha3": "MCO", + "_fips10": "MN" + }, + "MD": { + "_numeric": "498", + "_alpha3": "MDA" + }, + "ME": { + "_numeric": "499", + "_alpha3": "MNE", + "_fips10": "MJ" + }, + "MF": { + "_numeric": "663", + "_alpha3": "MAF", + "_fips10": "RN" + }, + "MG": { + "_numeric": "450", + "_alpha3": "MDG", + "_fips10": "MA" + }, + "MH": { + "_numeric": "584", + "_alpha3": "MHL", + "_fips10": "RM" + }, + "MK": { + "_numeric": "807", + "_alpha3": "MKD" + }, + "ML": { + "_numeric": "466", + "_alpha3": "MLI" + }, + "MM": { + "_numeric": "104", + "_alpha3": "MMR", + "_fips10": "BM" + }, + "MN": { + "_numeric": "496", + "_alpha3": "MNG", + "_fips10": "MG" + }, + "MO": { + "_numeric": "446", + "_alpha3": "MAC", + "_fips10": "MC" + }, + "MP": { + "_numeric": "580", + "_alpha3": "MNP", + "_fips10": "CQ" + }, + "MQ": { + "_numeric": "474", + "_alpha3": "MTQ", + "_fips10": "MB" + }, + "MR": { + "_numeric": "478", + "_alpha3": "MRT" + }, + "MS": { + "_numeric": "500", + "_alpha3": "MSR", + "_fips10": "MH" + }, + "MT": { + "_numeric": "470", + "_alpha3": "MLT" + }, + "MU": { + "_numeric": "480", + "_alpha3": "MUS", + "_fips10": "MP" + }, + "MV": { + "_numeric": "462", + "_alpha3": "MDV" + }, + "MW": { + "_numeric": "454", + "_alpha3": "MWI", + "_fips10": "MI" + }, + "MX": { + "_numeric": "484", + "_alpha3": "MEX" + }, + "MY": { + "_numeric": "458", + "_alpha3": "MYS" + }, + "MZ": { + "_numeric": "508", + "_alpha3": "MOZ" + }, + "NA": { + "_numeric": "516", + "_alpha3": "NAM", + "_fips10": "WA" + }, + "NC": { + "_numeric": "540", + "_alpha3": "NCL" + }, + "NE": { + "_numeric": "562", + "_alpha3": "NER", + "_fips10": "NG" + }, + "NF": { + "_numeric": "574", + "_alpha3": "NFK" + }, + "NG": { + "_numeric": "566", + "_alpha3": "NGA", + "_fips10": "NI" + }, + "NI": { + "_numeric": "558", + "_alpha3": "NIC", + "_fips10": "NU" + }, + "NL": { + "_numeric": "528", + "_alpha3": "NLD" + }, + "NO": { + "_numeric": "578", + "_alpha3": "NOR" + }, + "NP": { + "_numeric": "524", + "_alpha3": "NPL" + }, + "NR": { + "_numeric": "520", + "_alpha3": "NRU" + }, + "NT": { + "_numeric": "536", + "_alpha3": "NTZ" + }, + "NU": { + "_numeric": "570", + "_alpha3": "NIU", + "_fips10": "NE" + }, + "NZ": { + "_numeric": "554", + "_alpha3": "NZL" + }, + "OM": { + "_numeric": "512", + "_alpha3": "OMN", + "_fips10": "MU" + }, + "PA": { + "_numeric": "591", + "_alpha3": "PAN", + "_fips10": "PM" + }, + "PE": { + "_numeric": "604", + "_alpha3": "PER" + }, + "PF": { + "_numeric": "258", + "_alpha3": "PYF", + "_fips10": "FP" + }, + "PG": { + "_numeric": "598", + "_alpha3": "PNG", + "_fips10": "PP" + }, + "PH": { + "_numeric": "608", + "_alpha3": "PHL", + "_fips10": "RP" + }, + "PK": { + "_numeric": "586", + "_alpha3": "PAK" + }, + "PL": { + "_numeric": "616", + "_alpha3": "POL" + }, + "PM": { + "_numeric": "666", + "_alpha3": "SPM", + "_fips10": "SB" + }, + "PN": { + "_numeric": "612", + "_alpha3": "PCN", + "_fips10": "PC" + }, + "PR": { + "_numeric": "630", + "_alpha3": "PRI", + "_fips10": "RQ" + }, + "PS": { + "_numeric": "275", + "_alpha3": "PSE", + "_fips10": "GZ" + }, + "PT": { + "_numeric": "620", + "_alpha3": "PRT", + "_fips10": "PO" + }, + "PW": { + "_numeric": "585", + "_alpha3": "PLW", + "_fips10": "PS" + }, + "PY": { + "_numeric": "600", + "_alpha3": "PRY", + "_fips10": "PA" + }, + "QA": { + "_numeric": "634", + "_alpha3": "QAT" + }, + "QM": { + "_numeric": "959", + "_alpha3": "QMM" + }, + "QN": { + "_numeric": "960", + "_alpha3": "QNN" + }, + "QO": { + "_numeric": "961", + "_alpha3": "QOO" + }, + "QP": { + "_numeric": "962", + "_alpha3": "QPP" + }, + "QQ": { + "_numeric": "963", + "_alpha3": "QQQ" + }, + "QR": { + "_numeric": "964", + "_alpha3": "QRR" + }, + "QS": { + "_numeric": "965", + "_alpha3": "QSS" + }, + "QT": { + "_numeric": "966", + "_alpha3": "QTT" + }, + "QU": { + "_numeric": "967", + "_alpha3": "QUU" + }, + "QV": { + "_numeric": "968", + "_alpha3": "QVV" + }, + "QW": { + "_numeric": "969", + "_alpha3": "QWW" + }, + "QX": { + "_numeric": "970", + "_alpha3": "QXX" + }, + "QY": { + "_numeric": "971", + "_alpha3": "QYY" + }, + "QZ": { + "_numeric": "972", + "_alpha3": "QZZ" + }, + "RE": { + "_numeric": "638", + "_alpha3": "REU" + }, + "RO": { + "_numeric": "642", + "_alpha3": "ROU" + }, + "RS": { + "_numeric": "688", + "_alpha3": "SRB", + "_fips10": "RB" + }, + "RU": { + "_numeric": "643", + "_alpha3": "RUS", + "_fips10": "RS" + }, + "RW": { + "_numeric": "646", + "_alpha3": "RWA" + }, + "SA": { + "_numeric": "682", + "_alpha3": "SAU" + }, + "SB": { + "_numeric": "090", + "_alpha3": "SLB", + "_fips10": "BP" + }, + "SC": { + "_numeric": "690", + "_alpha3": "SYC", + "_fips10": "SE" + }, + "SD": { + "_numeric": "729", + "_alpha3": "SDN", + "_fips10": "SU" + }, + "SE": { + "_numeric": "752", + "_alpha3": "SWE", + "_fips10": "SW" + }, + "SG": { + "_numeric": "702", + "_alpha3": "SGP", + "_fips10": "SN" + }, + "SH": { + "_numeric": "654", + "_alpha3": "SHN" + }, + "SI": { + "_numeric": "705", + "_alpha3": "SVN" + }, + "SJ": { + "_numeric": "744", + "_alpha3": "SJM", + "_fips10": "SV" + }, + "SK": { + "_numeric": "703", + "_alpha3": "SVK", + "_fips10": "LO" + }, + "SL": { + "_numeric": "694", + "_alpha3": "SLE" + }, + "SM": { + "_numeric": "674", + "_alpha3": "SMR" + }, + "SN": { + "_numeric": "686", + "_alpha3": "SEN", + "_fips10": "SG" + }, + "SO": { + "_numeric": "706", + "_alpha3": "SOM" + }, + "SR": { + "_numeric": "740", + "_alpha3": "SUR", + "_fips10": "NS" + }, + "SS": { + "_numeric": "728", + "_alpha3": "SSD" + }, + "ST": { + "_numeric": "678", + "_alpha3": "STP", + "_fips10": "TP" + }, + "SU": { + "_numeric": "810", + "_alpha3": "SUN" + }, + "SV": { + "_numeric": "222", + "_alpha3": "SLV", + "_fips10": "ES" + }, + "SX": { + "_numeric": "534", + "_alpha3": "SXM" + }, + "SY": { + "_numeric": "760", + "_alpha3": "SYR" + }, + "SZ": { + "_numeric": "748", + "_alpha3": "SWZ", + "_fips10": "WZ" + }, + "TA": { + "_alpha3": "TAA" + }, + "TC": { + "_numeric": "796", + "_alpha3": "TCA", + "_fips10": "TK" + }, + "TD": { + "_numeric": "148", + "_alpha3": "TCD", + "_fips10": "CD" + }, + "TF": { + "_numeric": "260", + "_alpha3": "ATF", + "_fips10": "FS" + }, + "TG": { + "_numeric": "768", + "_alpha3": "TGO", + "_fips10": "TO" + }, + "TH": { + "_numeric": "764", + "_alpha3": "THA" + }, + "TJ": { + "_numeric": "762", + "_alpha3": "TJK", + "_fips10": "TI" + }, + "TK": { + "_numeric": "772", + "_alpha3": "TKL", + "_fips10": "TL" + }, + "TL": { + "_numeric": "626", + "_alpha3": "TLS", + "_fips10": "TT" + }, + "TM": { + "_numeric": "795", + "_alpha3": "TKM", + "_fips10": "TX" + }, + "TN": { + "_numeric": "788", + "_alpha3": "TUN", + "_fips10": "TS" + }, + "TO": { + "_numeric": "776", + "_alpha3": "TON", + "_fips10": "TN" + }, + "TP": { + "_numeric": "626", + "_alpha3": "TMP" + }, + "TR": { + "_numeric": "792", + "_alpha3": "TUR", + "_fips10": "TU" + }, + "TT": { + "_numeric": "780", + "_alpha3": "TTO", + "_fips10": "TD" + }, + "TV": { + "_numeric": "798", + "_alpha3": "TUV" + }, + "TW": { + "_numeric": "158", + "_alpha3": "TWN" + }, + "TZ": { + "_numeric": "834", + "_alpha3": "TZA" + }, + "UA": { + "_numeric": "804", + "_alpha3": "UKR", + "_fips10": "UP" + }, + "UG": { + "_numeric": "800", + "_alpha3": "UGA" + }, + "UM": { + "_numeric": "581", + "_alpha3": "UMI" + }, + "US": { + "_numeric": "840", + "_alpha3": "USA" + }, + "UY": { + "_numeric": "858", + "_alpha3": "URY" + }, + "UZ": { + "_numeric": "860", + "_alpha3": "UZB" + }, + "VA": { + "_numeric": "336", + "_alpha3": "VAT", + "_fips10": "VT" + }, + "VC": { + "_numeric": "670", + "_alpha3": "VCT" + }, + "VE": { + "_numeric": "862", + "_alpha3": "VEN" + }, + "VG": { + "_numeric": "092", + "_alpha3": "VGB", + "_fips10": "VI" + }, + "VI": { + "_numeric": "850", + "_alpha3": "VIR", + "_fips10": "VQ" + }, + "VN": { + "_numeric": "704", + "_alpha3": "VNM", + "_fips10": "VM" + }, + "VU": { + "_numeric": "548", + "_alpha3": "VUT", + "_fips10": "NH" + }, + "WF": { + "_numeric": "876", + "_alpha3": "WLF" + }, + "WS": { + "_numeric": "882", + "_alpha3": "WSM" + }, + "XA": { + "_numeric": "973", + "_alpha3": "XAA" + }, + "XB": { + "_numeric": "974", + "_alpha3": "XBB" + }, + "XC": { + "_numeric": "975", + "_alpha3": "XCC" + }, + "XD": { + "_numeric": "976", + "_alpha3": "XDD" + }, + "XE": { + "_numeric": "977", + "_alpha3": "XEE" + }, + "XF": { + "_numeric": "978", + "_alpha3": "XFF" + }, + "XG": { + "_numeric": "979", + "_alpha3": "XGG" + }, + "XH": { + "_numeric": "980", + "_alpha3": "XHH" + }, + "XI": { + "_numeric": "981", + "_alpha3": "XII" + }, + "XJ": { + "_numeric": "982", + "_alpha3": "XJJ" + }, + "XK": { + "_numeric": "983", + "_alpha3": "XKK" + }, + "XL": { + "_numeric": "984", + "_alpha3": "XLL" + }, + "XM": { + "_numeric": "985", + "_alpha3": "XMM" + }, + "XN": { + "_numeric": "986", + "_alpha3": "XNN" + }, + "XO": { + "_numeric": "987", + "_alpha3": "XOO" + }, + "XP": { + "_numeric": "988", + "_alpha3": "XPP" + }, + "XQ": { + "_numeric": "989", + "_alpha3": "XQQ" + }, + "XR": { + "_numeric": "990", + "_alpha3": "XRR" + }, + "XS": { + "_numeric": "991", + "_alpha3": "XSS" + }, + "XT": { + "_numeric": "992", + "_alpha3": "XTT" + }, + "XU": { + "_numeric": "993", + "_alpha3": "XUU" + }, + "XV": { + "_numeric": "994", + "_alpha3": "XVV" + }, + "XW": { + "_numeric": "995", + "_alpha3": "XWW" + }, + "XX": { + "_numeric": "996", + "_alpha3": "XXX" + }, + "XY": { + "_numeric": "997", + "_alpha3": "XYY" + }, + "XZ": { + "_numeric": "998", + "_alpha3": "XZZ" + }, + "YD": { + "_numeric": "720", + "_alpha3": "YMD" + }, + "YE": { + "_numeric": "887", + "_alpha3": "YEM", + "_fips10": "YM" + }, + "YT": { + "_numeric": "175", + "_alpha3": "MYT", + "_fips10": "MF" + }, + "YU": { + "_numeric": "891", + "_alpha3": "YUG" + }, + "ZA": { + "_numeric": "710", + "_alpha3": "ZAF", + "_fips10": "SF" + }, + "ZM": { + "_numeric": "894", + "_alpha3": "ZMB", + "_fips10": "ZA" + }, + "ZR": { + "_numeric": "180", + "_alpha3": "ZAR" + }, + "ZW": { + "_numeric": "716", + "_alpha3": "ZWE", + "_fips10": "ZI" + }, + "ZZ": { + "_numeric": "999", + "_alpha3": "ZZZ" + }, + "AED": { + "_numeric": "784" + }, + "AFN": { + "_numeric": "971" + }, + "ALL": { + "_numeric": "8" + }, + "AMD": { + "_numeric": "51" + }, + "ANG": { + "_numeric": "532" + }, + "AOA": { + "_numeric": "973" + }, + "ARS": { + "_numeric": "32" + }, + "AUD": { + "_numeric": "36" + }, + "AWG": { + "_numeric": "533" + }, + "AZN": { + "_numeric": "944" + }, + "BAM": { + "_numeric": "977" + }, + "BBD": { + "_numeric": "52" + }, + "BDT": { + "_numeric": "50" + }, + "BGN": { + "_numeric": "975" + }, + "BHD": { + "_numeric": "48" + }, + "BIF": { + "_numeric": "108" + }, + "BMD": { + "_numeric": "60" + }, + "BND": { + "_numeric": "96" + }, + "BOB": { + "_numeric": "68" + }, + "BOV": { + "_numeric": "984" + }, + "BRL": { + "_numeric": "986" + }, + "BSD": { + "_numeric": "44" + }, + "BTN": { + "_numeric": "64" + }, + "BWP": { + "_numeric": "72" + }, + "BYR": { + "_numeric": "974" + }, + "BZD": { + "_numeric": "84" + }, + "CAD": { + "_numeric": "124" + }, + "CDF": { + "_numeric": "976" + }, + "CHE": { + "_numeric": "947" + }, + "CHF": { + "_numeric": "756" + }, + "CHW": { + "_numeric": "948" + }, + "CLF": { + "_numeric": "990" + }, + "CLP": { + "_numeric": "152" + }, + "CNH": { + "_numeric": "156" + }, + "CNY": { + "_numeric": "156" + }, + "COP": { + "_numeric": "170" + }, + "COU": { + "_numeric": "970" + }, + "CRC": { + "_numeric": "188" + }, + "CUC": { + "_numeric": "931" + }, + "CUP": { + "_numeric": "192" + }, + "CVE": { + "_numeric": "132" + }, + "CZK": { + "_numeric": "203" + }, + "DJF": { + "_numeric": "262" + }, + "DKK": { + "_numeric": "208" + }, + "DOP": { + "_numeric": "214" + }, + "DZD": { + "_numeric": "12" + }, + "EGP": { + "_numeric": "818" + }, + "ERN": { + "_numeric": "232" + }, + "ETB": { + "_numeric": "230" + }, + "EUR": { + "_numeric": "978" + }, + "FJD": { + "_numeric": "242" + }, + "FKP": { + "_numeric": "238" + }, + "GBP": { + "_numeric": "826" + }, + "GEL": { + "_numeric": "981" + }, + "GHS": { + "_numeric": "936" + }, + "GIP": { + "_numeric": "292" + }, + "GMD": { + "_numeric": "270" + }, + "GNF": { + "_numeric": "324" + }, + "GTQ": { + "_numeric": "320" + }, + "GYD": { + "_numeric": "328" + }, + "HKD": { + "_numeric": "344" + }, + "HNL": { + "_numeric": "340" + }, + "HRK": { + "_numeric": "191" + }, + "HTG": { + "_numeric": "332" + }, + "HUF": { + "_numeric": "348" + }, + "IDR": { + "_numeric": "360" + }, + "ILS": { + "_numeric": "376" + }, + "INR": { + "_numeric": "356" + }, + "IQD": { + "_numeric": "368" + }, + "IRR": { + "_numeric": "364" + }, + "ISK": { + "_numeric": "352" + }, + "JMD": { + "_numeric": "388" + }, + "JOD": { + "_numeric": "400" + }, + "JPY": { + "_numeric": "392" + }, + "KES": { + "_numeric": "404" + }, + "KGS": { + "_numeric": "417" + }, + "KHR": { + "_numeric": "116" + }, + "KMF": { + "_numeric": "174" + }, + "KPW": { + "_numeric": "408" + }, + "KRW": { + "_numeric": "410" + }, + "KWD": { + "_numeric": "414" + }, + "KYD": { + "_numeric": "136" + }, + "KZT": { + "_numeric": "398" + }, + "LAK": { + "_numeric": "418" + }, + "LBP": { + "_numeric": "422" + }, + "LKR": { + "_numeric": "144" + }, + "LRD": { + "_numeric": "430" + }, + "LSL": { + "_numeric": "426" + }, + "LTL": { + "_numeric": "440" + }, + "LYD": { + "_numeric": "434" + }, + "MAD": { + "_numeric": "504" + }, + "MDL": { + "_numeric": "498" + }, + "MGA": { + "_numeric": "969" + }, + "MKD": { + "_numeric": "807" + }, + "MMK": { + "_numeric": "104" + }, + "MNT": { + "_numeric": "496" + }, + "MOP": { + "_numeric": "446" + }, + "MRO": { + "_numeric": "478" + }, + "MRU": { + "_numeric": "929" + }, + "MUR": { + "_numeric": "480" + }, + "MVR": { + "_numeric": "462" + }, + "MWK": { + "_numeric": "454" + }, + "MXN": { + "_numeric": "484" + }, + "MXV": { + "_numeric": "979" + }, + "MYR": { + "_numeric": "458" + }, + "MZN": { + "_numeric": "943" + }, + "NAD": { + "_numeric": "516" + }, + "NGN": { + "_numeric": "566" + }, + "NIO": { + "_numeric": "558" + }, + "NOK": { + "_numeric": "578" + }, + "NPR": { + "_numeric": "524" + }, + "NZD": { + "_numeric": "554" + }, + "OMR": { + "_numeric": "512" + }, + "PAB": { + "_numeric": "590" + }, + "PEN": { + "_numeric": "604" + }, + "PGK": { + "_numeric": "598" + }, + "PHP": { + "_numeric": "608" + }, + "PKR": { + "_numeric": "586" + }, + "PLN": { + "_numeric": "985" + }, + "PYG": { + "_numeric": "600" + }, + "QAR": { + "_numeric": "634" + }, + "RON": { + "_numeric": "946" + }, + "RSD": { + "_numeric": "941" + }, + "RUB": { + "_numeric": "643" + }, + "RWF": { + "_numeric": "646" + }, + "SAR": { + "_numeric": "682" + }, + "SBD": { + "_numeric": "90" + }, + "SCR": { + "_numeric": "690" + }, + "SDG": { + "_numeric": "938" + }, + "SEK": { + "_numeric": "752" + }, + "SGD": { + "_numeric": "702" + }, + "SHP": { + "_numeric": "654" + }, + "SLL": { + "_numeric": "694" + }, + "SOS": { + "_numeric": "706" + }, + "SRD": { + "_numeric": "968" + }, + "SSP": { + "_numeric": "728" + }, + "STD": { + "_numeric": "678" + }, + "STN": { + "_numeric": "930" + }, + "SYP": { + "_numeric": "760" + }, + "SZL": { + "_numeric": "748" + }, + "THB": { + "_numeric": "764" + }, + "TJS": { + "_numeric": "972" + }, + "TMT": { + "_numeric": "934" + }, + "TND": { + "_numeric": "788" + }, + "TOP": { + "_numeric": "776" + }, + "TRY": { + "_numeric": "949" + }, + "TTD": { + "_numeric": "780" + }, + "TWD": { + "_numeric": "901" + }, + "TZS": { + "_numeric": "834" + }, + "UAH": { + "_numeric": "980" + }, + "UGX": { + "_numeric": "800" + }, + "USD": { + "_numeric": "840" + }, + "USN": { + "_numeric": "997" + }, + "UYI": { + "_numeric": "940" + }, + "UYU": { + "_numeric": "858" + }, + "UYW": { + "_numeric": "927" + }, + "UZS": { + "_numeric": "860" + }, + "VED": { + "_numeric": "926" + }, + "VEF": { + "_numeric": "937" + }, + "VES": { + "_numeric": "928" + }, + "VND": { + "_numeric": "704" + }, + "VUV": { + "_numeric": "548" + }, + "WST": { + "_numeric": "882" + }, + "XAF": { + "_numeric": "950" + }, + "XAG": { + "_numeric": "961" + }, + "XAU": { + "_numeric": "959" + }, + "XBA": { + "_numeric": "955" + }, + "XBB": { + "_numeric": "956" + }, + "XBC": { + "_numeric": "957" + }, + "XBD": { + "_numeric": "958" + }, + "XCD": { + "_numeric": "951" + }, + "XDR": { + "_numeric": "960" + }, + "XOF": { + "_numeric": "952" + }, + "XPD": { + "_numeric": "964" + }, + "XPF": { + "_numeric": "953" + }, + "XPT": { + "_numeric": "962" + }, + "XSU": { + "_numeric": "994" + }, + "XTS": { + "_numeric": "963" + }, + "XUA": { + "_numeric": "965" + }, + "XXX": { + "_numeric": "999" + }, + "YER": { + "_numeric": "886" + }, + "ZAR": { + "_numeric": "710" + }, + "ZMW": { + "_numeric": "967" + } + } + } +} diff --git a/package.json b/package.json index 51df688b5..f44d4bfc8 100644 --- a/package.json +++ b/package.json @@ -236,6 +236,7 @@ "gates:post": "node internal/run-parallel.mjs --label=post -- check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:done-evidence check:script-flags check:backlog-status check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:backlog-refs check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:regions-uses-library check:shadow-css-parses", "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts", "internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs", + "gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs", "library-index": "node internal/generate-library-index.mjs", "lists": "node library/scripts/people-groups/build-lists.mjs", "packet-fixture": "node internal/generate-packet-fixture.mjs", @@ -392,10 +393,9 @@ "check:provider-switch": "the provider switch must actually SWITCH: counts requests BY HOST (not window globals, which stay defined after a swap) and asserts the maplibre run stays within the leaf HTML's own declared api.mapbox.com preloads. Defaults to the upg-100 leaf; pass a URL or set BASE_URL for another. CONDITIONAL: SKIPs when nothing is served.", "check:published": "what readers are SERVED must be what we BUILT. Every other gate measures the local tree, so all of them stay green while a stale publish serves something else — and manufactures bug reports that cannot be reproduced. Compares the sha384 per bundle. SKIPs when the published host is unreachable (a network gate that goes red on flaky wifi gets ignored).", "check:quoted-scripts": "documentation/README-SECTION-3-cli-commands.md QUOTES the scripts block verbatim; it had silently drifted TWICE (a stale bunx cap:sync, and build:unlocked missing check:public-hygiene + check:label-joins). package.json is what RUNS — update the DOC.", - "check:religion-label-not-value": "the library's two RELIGION_FAMILIES sites (useLegendData, useSearch) show religionFamilyLabel() to the reader, while the value a filter or search matches on stays the canonical English family name: a translated label must never become a wire value.", "check:scrim-viewport": "a full-screen SCRIM must cover the VIEWPORT, not just the content pane. A position:fixed;inset:0 scrim is PANE-relative wherever an ancestor sets contain/transform — VerticalTabsLayout sets contain:layout on .vtl-content — so a scrim dimmed 1024x793 @ (256,107) at a 1280x900 viewport and left the 256px rail CLICKABLE behind a modal. A source grep cannot see it: the declaration is correct, the ANCESTOR is the variable. Needs `bun run dev`; browser gate, not in build:unlocked.", "check:scrim-viewport:self-test": "reverts each scrim to plain inset:0 and requires EVERY case to FAIL — a gate that cannot fail is worse than no gate, and this one measures a property that looks fine in a screenshot either way.", - "check:religion-label-not-value": "REGREL: the Religion legend and the search aggregate must show a LOCALIZED family label while the value they filter on stays canonical English -- a translated value matches nothing, which is the language-link bug class. Asserts both halves: the label goes through religionFamilyLabel(), and key/filterKey plus useSearch's key function stay getReligionFamily. Executes religionFamilyLabel's real source against the SHIPPED ar/ and en/ religion.json, so under ar the label differs from the value by measurement. Headless.", + "check:religion-label-not-value": "REGREL: the library's two RELIGION_FAMILIES sites (useLegendData, useSearch) must show a LOCALIZED family label while the value they filter on stays canonical English -- a translated value matches nothing, which is the language-link bug class. Asserts both halves: the label goes through religionFamilyLabel(), and key/filterKey plus useSearch's key function stay getReligionFamily. Executes religionFamilyLabel's real source against the SHIPPED ar/ and en/ religion.json, so under ar the label differs from the value by measurement. Headless.", "check:sfc-parse": "every .vue script block must parse as the BUILD parses it — catches the LIVE-CSS backtick that check:template-literal cannot see (it reads CSS comments only). 0 false positives on 83 files, where 3 lookahead heuristics scored 98 and 136.", "check:shadow-css-parses": "the CSS we assemble as JS STRINGS must parse as CSS — brace balance and declarations stranded outside any rule. check:sfc-parse proves only that the JS parses, so it passed a stylesheet with 9 orphaned declarations and braces at 12 open / 21 close (REGLIB batch 1); nothing else in the tree validates CSS syntax. Reads every useShadowStyles() argument off the @babel/parser AST the build already uses, because three hand-rolled lexers each produced a confident FALSE RED: a /* CSS comment */ read as a declaration, an apostrophe in a .vue prose header opening a phantom string literal, and a regex literal containing a quote. 9 self-tests run inline on every invocation, including the exact batch-1 damage, so it cannot silently stop being able to fail.", "check:shared-reached": "a shared library fix is only as deployed as the last rebuild of EVERY bundle that consumes it. Each bundle ships its own COMPILED copy, so a one-line fix in library/ is live in whichever bundles happened to be rebuilt after it and silently absent from the rest — and every other gate measures ONE leaf, which renders the old behaviour perfectly. Asserts a distinctive marker string per tracked change; consumers are DERIVED from imports, never hardcoded.", @@ -422,6 +422,7 @@ "deploy:dev": "destination + allowlist come from vite.doxa-maps-build-config.json (dropin.dest / dropin.include); DOXA_DROPIN_DEST= overrides the destination", "gallery": "writes public/__gallery/index.html — the ARCHIVED bundle-index gallery, from public/doxa-maps/manifest.json. It is NO LONGER the root page: as of 2026-09-22 `/` mounts in BOTH trees (the built root page is written by `bun run tree`), and the gallery is the opt-in index at /__gallery. Archived, not deleted — the dev server imports renderGallery()/readBuildConfig() from this module.", "internet:adm1": "regenerate data/tables/internet-by-adm1.json (internet use by first-level area; India from NFHS-5 2019-21, CC BY 4.0) from data/internet/ through a strict name crosswalk to the shipped gb-IND-ADM1 boundaries. Fails on an unmatched name, never guesses. Generic rows (iso3, adm1, measure, sex, area, value, source, year) so other plugins and go-int can reuse it.", + "gen:iso3-to-alpha2": "derive library/data/iso3-to-alpha2.json from vendored CLDR (48.2.2, Unicode-3.0) joined against the 242 codes in library/data/countries.json, so Intl.DisplayNames can produce a LOCALIZED country name — it takes alpha-2 and our data speaks alpha-3. Offline, no dependency. GRADES ITS OWN OUTPUT and writes nothing on failure: 242 coverage, injectivity, and KOS -> XK as the one documented exception (Kosovo has no ISO assignment). Cross-checks the 176-country research spine map and REPORTS disagreements without rewriting it — that file drives fetches and is not this generator's to edit.", "library-index": "regenerate documentation/reference-library-index.md — the DERIVED menu of the 84 reusable library pieces an author can import instead of rebuilding. Was UNREACHABLE, and the index did not exist at all: its header promised 'can't drift from the code' while nothing ever ran it.", "lists": "regenerate data/people-groups/lists/.json, the DOXA slugs in each people-group list of library/lists/lists.json, from the IMB CSV and the DOXA snapshot. Re-run after either changes.", "packet-fixture": "regenerate the committed records subset (smallest zone, image_url stripped) that lets CI build a packet at all — out/ is gitignored, so a clean checkout has neither the records cache nor any packet.",