diff --git a/library/i18n/locales/ar/countryPosters.json b/library/i18n/locales/ar/countryPosters.json index 425618c10..b8f3634d2 100644 --- a/library/i18n/locales/ar/countryPosters.json +++ b/library/i18n/locales/ar/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "للهند قسمها الخاص في المقدّمة: عدد الشعوب غير المُبشَّرة فيها {count}، وهو أكثر بكثير من أي بلد آخر، لذا لكل ولاية وإقليم اتحادي فيها ملصقه الخاص.", "indiaStateNoGroups": "لا توجد هنا شعوب غير مُبشَّرة مُدرَجة.", - "indiaItemCount": "لا ولايات ولا أقاليم | ولاية أو إقليم اتحادي واحد | ولايتان أو إقليمان | {n} ولايات وأقاليم اتحادية | {n} ولاية وإقليمًا اتحاديًا | {n} ولاية وإقليم اتحادي" + "indiaItemCount": "لا ولايات ولا أقاليم | ولاية أو إقليم اتحادي واحد | ولايتان أو إقليمان | {n} ولايات وأقاليم اتحادية | {n} ولاية وإقليمًا اتحاديًا | {n} ولاية وإقليم اتحادي", + "stateNames": { + "IN-AN": "جزر أندمان وَ نِكُبَار", + "IN-AP": "أندرا برديش", + "IN-AR": "أروناجل برديش", + "IN-AS": "آسام", + "IN-BR": "بهار", + "IN-CH": "شَنديغار", + "IN-CT": "تشاتيسغار", + "IN-DH": "دادرا وناغار هافيلي ودامان وديو", + "IN-DL": "دلهي", + "IN-GA": "غوا", + "IN-GJ": "كجرات", + "IN-HP": "هماجل برديش", + "IN-HR": "هريانة", + "IN-JH": "جاركند", + "IN-JK": "إقليم جمون وكشمير", + "IN-KA": "كرناتك", + "IN-KL": "كيرلا", + "IN-LA": "لداخ", + "IN-LD": "لكشديب", + "IN-MH": "مهاراشترة", + "IN-ML": "ميكالية", + "IN-MN": "منيبور", + "IN-MP": "مدية برديش", + "IN-MZ": "مِزُورَم", + "IN-NL": "ناغالند", + "IN-OR": "أديشة", + "IN-PB": "بنجاب", + "IN-PY": "بُدُجيري", + "IN-RJ": "راجستان", + "IN-SK": "سِكِم", + "IN-TG": "تلنكانة", + "IN-TN": "تاميل نادو", + "IN-TR": "تريبورة", + "IN-UP": "أتر برديش", + "IN-UT": "أوتاراخند", + "IN-WB": "بنغال الغربية" + } } diff --git a/library/i18n/locales/de/countryPosters.json b/library/i18n/locales/de/countryPosters.json index 66822bd88..37548a896 100644 --- a/library/i18n/locales/de/countryPosters.json +++ b/library/i18n/locales/de/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "Indien hat einen eigenen Abschnitt, ganz oben: Mit {count} unerreichten Volksgruppen, weit mehr als jedes andere Land, hat jeder seiner Bundesstaaten und Unionsterritorien ein eigenes Plakat.", "indiaStateNoGroups": "Hier sind keine unerreichten Volksgruppen verzeichnet.", - "indiaItemCount": "{n} Bundesstaat oder Unionsterritorium | {n} Bundesstaaten und Unionsterritorien" + "indiaItemCount": "{n} Bundesstaat oder Unionsterritorium | {n} Bundesstaaten und Unionsterritorien", + "stateNames": { + "IN-AN": "Andamanen und Nikobaren", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra und Nagar Haveli und Daman und Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu und Kashmir", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Lakshadweep", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Odisha", + "IN-PB": "Punjab", + "IN-PY": "Puducherry", + "IN-RJ": "Rajasthan", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "Westbengalen" + } } diff --git a/library/i18n/locales/en/countryPosters.json b/library/i18n/locales/en/countryPosters.json index acf3da70a..2b0108393 100644 --- a/library/i18n/locales/en/countryPosters.json +++ b/library/i18n/locales/en/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "India has its own section, first: it has {count} unreached people groups, far more than any other country, so each of its states and union territories has its own poster.", "indiaStateNoGroups": "No unreached people groups are listed here.", - "indiaItemCount": "{n} states and union territories | {n} state or union territory | {n} states and union territories" + "indiaItemCount": "{n} states and union territories | {n} state or union territory | {n} states and union territories", + "stateNames": { + "IN-AN": "Andaman and Nicobar Islands", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra and Nagar Haveli and Daman and Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu and Kashmir", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Lakshadweep", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Odisha", + "IN-PB": "Punjab", + "IN-PY": "Puducherry", + "IN-RJ": "Rajasthan", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "West Bengal" + } } diff --git a/library/i18n/locales/es/countryPosters.json b/library/i18n/locales/es/countryPosters.json index 793861c75..934fcfe66 100644 --- a/library/i18n/locales/es/countryPosters.json +++ b/library/i18n/locales/es/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "India tiene su propia sección, la primera: tiene {count} pueblos no alcanzados, muchos más que cualquier otro país, así que cada uno de sus estados y territorios de la unión tiene su propio cartel.", "indiaStateNoGroups": "Aquí no figura ningún pueblo no alcanzado.", - "indiaItemCount": "{n} estado o territorio de la unión | {n} de estados y territorios de la unión | {n} estados y territorios de la unión" + "indiaItemCount": "{n} estado o territorio de la unión | {n} de estados y territorios de la unión | {n} estados y territorios de la unión", + "stateNames": { + "IN-AN": "Islas Andamán y Nicobar", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra y Nagar Haveli y Damán y Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Guyarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu y Cachemira", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Laquedivas", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Orissa", + "IN-PB": "Punyab", + "IN-PY": "Puducherry", + "IN-RJ": "Rajastán", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "Bengala Occidental" + } } diff --git a/library/i18n/locales/fr/countryPosters.json b/library/i18n/locales/fr/countryPosters.json index e03e089ca..d09cf6943 100644 --- a/library/i18n/locales/fr/countryPosters.json +++ b/library/i18n/locales/fr/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "L’Inde a sa propre section, en premier : elle compte {count} peuples non atteints, bien plus que tout autre pays ; chacun de ses États et territoires de l’Union a donc sa propre affiche.", "indiaStateNoGroups": "Aucun peuple non atteint n’est répertorié ici.", - "indiaItemCount": "{n} État ou territoire de l’Union | {n} d’États et territoires de l’Union | {n} États et territoires de l’Union" + "indiaItemCount": "{n} État ou territoire de l’Union | {n} d’États et territoires de l’Union | {n} États et territoires de l’Union", + "stateNames": { + "IN-AN": "Îles Andaman-et-Nicobar", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra et Nagar Haveli et Daman et Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu-et-Cachemire", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Lakshadweep", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Odisha", + "IN-PB": "Pendjab", + "IN-PY": "Territoire de Pondichéry", + "IN-RJ": "Rajasthan", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "Bengale-Occidental" + } } diff --git a/library/i18n/locales/hi/countryPosters.json b/library/i18n/locales/hi/countryPosters.json index baa73d419..913eed77e 100644 --- a/library/i18n/locales/hi/countryPosters.json +++ b/library/i18n/locales/hi/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "भारत का अपना अलग खंड है, सबसे पहले: इसमें {count} अपहुँचे जनसमूह हैं, किसी भी अन्य देश से कहीं अधिक, इसलिए इसके हर राज्य और केंद्र शासित प्रदेश का अपना पोस्टर है।", "indiaStateNoGroups": "यहाँ कोई अपहुँचा जनसमूह सूचीबद्ध नहीं है।", - "indiaItemCount": "{n} राज्य या केंद्र शासित प्रदेश | {n} राज्य और केंद्र शासित प्रदेश" + "indiaItemCount": "{n} राज्य या केंद्र शासित प्रदेश | {n} राज्य और केंद्र शासित प्रदेश", + "stateNames": { + "IN-AN": "अण्डमान और निकोबार द्वीपसमूह", + "IN-AP": "आन्ध्र प्रदेश", + "IN-AR": "अरुणाचल प्रदेश", + "IN-AS": "असम", + "IN-BR": "बिहार", + "IN-CH": "चण्डीगढ़", + "IN-CT": "छत्तीसगढ़", + "IN-DH": "दादरा और नगर हवेली और दमन और दीव", + "IN-DL": "दिल्ली", + "IN-GA": "गोवा", + "IN-GJ": "गुजरात", + "IN-HP": "हिमाचल प्रदेश", + "IN-HR": "हरियाणा", + "IN-JH": "झारखण्ड", + "IN-JK": "जम्मू और कश्मीर", + "IN-KA": "कर्नाटक", + "IN-KL": "केरल", + "IN-LA": "लद्दाख़", + "IN-LD": "लक्षद्वीप", + "IN-MH": "महाराष्ट्र", + "IN-ML": "मेघालय", + "IN-MN": "मणिपुर", + "IN-MP": "मध्य प्रदेश", + "IN-MZ": "मिज़ोरम", + "IN-NL": "नागालैण्ड", + "IN-OR": "ओडिशा", + "IN-PB": "पंजाब", + "IN-PY": "पुदुचेरी", + "IN-RJ": "राजस्थान", + "IN-SK": "सिक्किम", + "IN-TG": "तेलंगाना", + "IN-TN": "तमिल नाडु", + "IN-TR": "त्रिपुरा", + "IN-UP": "उत्तर प्रदेश", + "IN-UT": "उत्तराखण्ड", + "IN-WB": "पश्चिम बंगाल" + } } diff --git a/library/i18n/locales/it/countryPosters.json b/library/i18n/locales/it/countryPosters.json index a21b06082..090389bc5 100644 --- a/library/i18n/locales/it/countryPosters.json +++ b/library/i18n/locales/it/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "L’India ha una sezione tutta sua, la prima: conta {count} popoli non raggiunti, molti più di qualsiasi altro paese, quindi ognuno dei suoi stati e territori dell’Unione ha il proprio manifesto.", "indiaStateNoGroups": "Qui non è elencato alcun popolo non raggiunto.", - "indiaItemCount": "{n} stato o territorio dell’Unione | {n} di stati e territori dell’Unione | {n} stati e territori dell’Unione" + "indiaItemCount": "{n} stato o territorio dell’Unione | {n} di stati e territori dell’Unione | {n} stati e territori dell’Unione", + "stateNames": { + "IN-AN": "isole Andamane e Nicobare", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra e Nagar Haveli e Daman e Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu e Kashmir", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Laccadive", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Orissa", + "IN-PB": "Punjab", + "IN-PY": "Pondicherry", + "IN-RJ": "Rajasthan", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "Bengala Occidentale" + } } diff --git a/library/i18n/locales/pt/countryPosters.json b/library/i18n/locales/pt/countryPosters.json index e43b71685..66501cd1c 100644 --- a/library/i18n/locales/pt/countryPosters.json +++ b/library/i18n/locales/pt/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "A Índia tem a sua própria seção, a primeira: tem {count} povos não alcançados, muito mais do que qualquer outro país, por isso cada um dos seus estados e territórios da união tem o seu próprio cartaz.", "indiaStateNoGroups": "Nenhum povo não alcançado está listado aqui.", - "indiaItemCount": "{n} estado ou território da união | {n} de estados e territórios da união | {n} estados e territórios da união" + "indiaItemCount": "{n} estado ou território da união | {n} de estados e territórios da união | {n} estados e territórios da união", + "stateNames": { + "IN-AN": "Andamão e Nicobar", + "IN-AP": "Andra Pradexe", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadrá e Nagar Aveli e Damão e Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarate", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu e Caxemira", + "IN-KA": "Carnataca", + "IN-KL": "Kerala", + "IN-LA": "Ladaque", + "IN-LD": "Laquedivas", + "IN-MH": "Maarastra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Orissa", + "IN-PB": "Punjab", + "IN-PY": "Puducherry", + "IN-RJ": "Rajastão", + "IN-SK": "Siquim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Utar Pradexe", + "IN-UT": "Utaracanda", + "IN-WB": "Bengala Ocidental" + } } diff --git a/library/i18n/locales/ro/countryPosters.json b/library/i18n/locales/ro/countryPosters.json index 5ccf50fe2..11b0d912f 100644 --- a/library/i18n/locales/ro/countryPosters.json +++ b/library/i18n/locales/ro/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "India are propria secțiune, prima: are {count} popoare neatinse, mult mai multe decât orice altă țară, așa că fiecare dintre statele și teritoriile sale ale Uniunii are propriul afiș.", "indiaStateNoGroups": "Aici nu este listat niciun popor neatins.", - "indiaItemCount": "un stat sau teritoriu al Uniunii | {n} state și teritorii ale Uniunii | {n} de state și teritorii ale Uniunii" + "indiaItemCount": "un stat sau teritoriu al Uniunii | {n} state și teritorii ale Uniunii | {n} de state și teritorii ale Uniunii", + "stateNames": { + "IN-AN": "Insulele Andaman și Nicobar", + "IN-AP": "Andhra Pradesh", + "IN-AR": "Arunachal Pradesh", + "IN-AS": "Assam", + "IN-BR": "Bihar", + "IN-CH": "Teritoriul Unional Chandigarh", + "IN-CT": "Chhattisgarh", + "IN-DH": "Dadra și Nagar Haveli și Daman și Diu", + "IN-DL": "Delhi", + "IN-GA": "Goa", + "IN-GJ": "Gujarat", + "IN-HP": "Himachal Pradesh", + "IN-HR": "Haryana", + "IN-JH": "Jharkhand", + "IN-JK": "Jammu și Cașmir", + "IN-KA": "Karnataka", + "IN-KL": "Kerala", + "IN-LA": "Ladakh", + "IN-LD": "Lakshadweep", + "IN-MH": "Maharashtra", + "IN-ML": "Meghalaya", + "IN-MN": "Manipur", + "IN-MP": "Madhya Pradesh", + "IN-MZ": "Mizoram", + "IN-NL": "Nagaland", + "IN-OR": "Odisha", + "IN-PB": "Punjab", + "IN-PY": "Puducherry", + "IN-RJ": "Rajasthan", + "IN-SK": "Sikkim", + "IN-TG": "Telangana", + "IN-TN": "Tamil Nadu", + "IN-TR": "Tripura", + "IN-UP": "Uttar Pradesh", + "IN-UT": "Uttarakhand", + "IN-WB": "Bengalul de Vest" + } } diff --git a/library/i18n/locales/ru/countryPosters.json b/library/i18n/locales/ru/countryPosters.json index 7ff8cb749..6a944e0ef 100644 --- a/library/i18n/locales/ru/countryPosters.json +++ b/library/i18n/locales/ru/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "У Индии свой раздел, первый: число недостигнутых народов в ней — {count}, намного больше, чем в любой другой стране, поэтому у каждого её штата и союзной территории есть свой плакат.", "indiaStateNoGroups": "Здесь не указано ни одного недостигнутого народа.", - "indiaItemCount": "{n} штат или союзная территория | {n} штата и союзные территории | {n} штатов и союзных территорий | {n} штата и союзной территории" + "indiaItemCount": "{n} штат или союзная территория | {n} штата и союзные территории | {n} штатов и союзных территорий | {n} штата и союзной территории", + "stateNames": { + "IN-AN": "Андаманские и Никобарские острова", + "IN-AP": "Андхра-Прадеш", + "IN-AR": "Аруначал-Прадеш", + "IN-AS": "Ассам", + "IN-BR": "Бихар", + "IN-CH": "Чандигарх", + "IN-CT": "Чхаттисгарх", + "IN-DH": "Дадра и Нагар-Хавели и Даман и Диу", + "IN-DL": "Дели", + "IN-GA": "Гоа", + "IN-GJ": "Гуджарат", + "IN-HP": "Химачал-Прадеш", + "IN-HR": "Харьяна", + "IN-JH": "Джаркханд", + "IN-JK": "Джамму и Кашмир", + "IN-KA": "Карнатака", + "IN-KL": "Керала", + "IN-LA": "Ладакх", + "IN-LD": "Лакшадвип", + "IN-MH": "Махараштра", + "IN-ML": "Мегхалая", + "IN-MN": "Манипур", + "IN-MP": "Мадхья-Прадеш", + "IN-MZ": "Мизорам", + "IN-NL": "Нагаленд", + "IN-OR": "Одиша", + "IN-PB": "Пенджаб", + "IN-PY": "Пондичерри", + "IN-RJ": "Раджастхан", + "IN-SK": "Сикким", + "IN-TG": "Телингана", + "IN-TN": "Тамилнад", + "IN-TR": "Трипура", + "IN-UP": "Уттар-Прадеш", + "IN-UT": "Уттаракханд", + "IN-WB": "Западная Бенгалия" + } } diff --git a/library/i18n/locales/zh/countryPosters.json b/library/i18n/locales/zh/countryPosters.json index 5572a850d..083663880 100644 --- a/library/i18n/locales/zh/countryPosters.json +++ b/library/i18n/locales/zh/countryPosters.json @@ -1,5 +1,43 @@ { "indiaNote": "印度有单独的一栏,排在最前:这里有 {count} 个未得之民族群,远多于任何其他国家,因此它的每个邦和中央直辖区都有自己的海报。", "indiaStateNoGroups": "此处未列出任何未得之民族群。", - "indiaItemCount": "{n} 个邦和中央直辖区" + "indiaItemCount": "{n} 个邦和中央直辖区", + "stateNames": { + "IN-AN": "安达曼-尼科巴群岛", + "IN-AP": "安得拉邦", + "IN-AR": "阿鲁纳恰尔邦", + "IN-AS": "阿萨姆邦", + "IN-BR": "比哈尔邦", + "IN-CH": "昌迪加尔", + "IN-CT": "切蒂斯格尔邦", + "IN-DH": "达德拉-纳加尔哈维利和达曼-第乌", + "IN-DL": "德里", + "IN-GA": "果阿邦", + "IN-GJ": "古吉拉特邦", + "IN-HP": "喜马偕尔邦", + "IN-HR": "哈里亚纳邦", + "IN-JH": "贾坎德邦", + "IN-JK": "查谟和克什米尔", + "IN-KA": "卡纳塔克邦", + "IN-KL": "喀拉拉邦", + "IN-LA": "拉达克", + "IN-LD": "拉克沙群岛", + "IN-MH": "马哈拉施特拉邦", + "IN-ML": "梅加拉亚邦", + "IN-MN": "曼尼普尔邦", + "IN-MP": "中央邦", + "IN-MZ": "米佐拉姆邦", + "IN-NL": "那加兰邦", + "IN-OR": "奥迪沙邦", + "IN-PB": "旁遮普邦", + "IN-PY": "本地治里", + "IN-RJ": "拉贾斯坦邦", + "IN-SK": "锡金邦", + "IN-TG": "特伦甘纳邦", + "IN-TN": "泰米尔纳德邦", + "IN-TR": "特里普拉邦", + "IN-UP": "北方邦", + "IN-UT": "北阿坎德邦", + "IN-WB": "西孟加拉邦" + } } diff --git a/plugin-designs/country-posters/country-poster-wall.vue b/plugin-designs/country-posters/country-poster-wall.vue index e1a53c8af..6de2c4b8f 100644 --- a/plugin-designs/country-posters/country-poster-wall.vue +++ b/plugin-designs/country-posters/country-poster-wall.vue @@ -31,14 +31,14 @@ * The shared wall always sorts sections AND cards by descending count, so the * dense countries lead and the long tail sinks. There is no floor. */ -import { computed, inject, ref, watch } from 'vue' +import { computed, inject, onBeforeUnmount, ref, watch } from 'vue' import PosterWall from '@map/components/poster/PosterWall.vue' import { useOptionalT, useOptionalI18n } from '@map/composables/useOptionalT.js' // A country's name in the reader's language (Intl, joined from our ISO-3 codes). import { countryName } from '@map/utils/countryName.js' import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js' import { getApiBaseUrl } from '@map/api/apiBaseUrl.js' -import { getRuntimeLocale, detectLocale } from '@map/i18n/index.js' +import { getRuntimeLocale, detectLocale, tStatic } from '@map/i18n/index.js' // MOVED to the shared library 2026-09-24: the regions-dashboard poster dropdown is a second // consumer of this same dataset, and RULE 2 puts a dataset with a named second consumer in // library/. Generated by library/scripts/posters/emit-countries.mjs, which now writes there. @@ -108,21 +108,30 @@ try { tRegions = useRegionsI18n().t } catch (_) { /* a host with no i18n reads t // ★ INDIA'S STATES AND UNION TERRITORIES, one poster each, like a country one level down. The table is // fetched (and sha-checked) only when the unfiltered wall is shown; a host's filtered wall never asks for it. -// A failure hides the section rather than showing cards that cannot print. States with no people groups -// listed (Nagaland, Mizoram) are NAMED with a card that says so, never silently left out. +// A failure hides the section rather than showing cards that cannot print, and is retried a bounded number of +// times (the loader drops a failed fetch from its cache, so a retry really fetches again). States with no people +// groups listed (Nagaland, Mizoram) are NAMED with a card that says so, never silently left out. const indiaStates = ref(null) +const STATE_RETRY_MS = [5000, 20000, 60000] +let stateRetry = null +function loadStates(attempt = 0) { + loadIndiaStates(assetsBase.value).then((table) => { indiaStates.value = table.states }).catch(() => { + if (attempt < STATE_RETRY_MS.length && !filtered.value) stateRetry = setTimeout(() => loadStates(attempt + 1), STATE_RETRY_MS[attempt]) + }) +} watch(filtered, (f) => { - if (f || indiaStates.value) return - loadIndiaStates(assetsBase.value).then((table) => { indiaStates.value = table.states }).catch(() => { indiaStates.value = null }) + if (f || indiaStates.value || stateRetry) return + loadStates() }, { immediate: true }) +onBeforeUnmount(() => { clearTimeout(stateRetry) }) const INDIA_REGION = (byIso3.get('IND') || {}).region || 'Asia' const stateItems = computed(() => { const all = indiaStates.value if (filtered.value || !all) return [] const withGroups = statesWithPosters(all).map((st) => ({ - id: st.id, label: st.name, count: st.count, sheet: '3x3', region: INDIA_REGION, indiaState: true, slugs: st.slugs, + id: st.id, iso: st.iso, label: st.name, count: st.count, sheet: '3x3', region: INDIA_REGION, indiaState: true, slugs: st.slugs, })) - const none = all.filter((st) => !st.count).map((st) => ({ id: st.id, label: st.name, count: 0, indiaState: true, noGroups: true, slugs: [] })) + const none = all.filter((st) => !st.count).map((st) => ({ id: st.id, iso: st.iso, label: st.name, count: 0, indiaState: true, noGroups: true, slugs: [] })) return [...withGroups, ...none] }) @@ -130,12 +139,15 @@ const items = computed(() => { const l = wallLocale && (wallLocale.value ?? wallLocale) const locale = (typeof l === 'string' && l) || getRuntimeLocale() || detectLocale() || 'en' const countries = selected.value - // State names stay as the table has them (place names from the data); only country names are localized. - if (/^en\b/i.test(locale)) return [...countries, ...stateItems.value] + // A state's card is named in the reader's language from the catalogue (countryPosters.stateNames, generated from + // Wikidata by scripts/emit-india-state-names.mjs); its printed sheet stays English, like a country's. + const states = /^en\b/i.test(locale) ? stateItems.value + : stateItems.value.map((st) => ({ ...st, label: tStatic(`countryPosters.stateNames.${st.iso}`, locale) || st.label })) + if (/^en\b/i.test(locale)) return [...countries, ...states] return [...countries.map((c) => { const name = countryName(c.iso3, locale) return name && name !== c.iso3 ? { ...c, label: name } : c - }), ...stateItems.value] + }), ...states] }) // ★ EVERY COUNTRY PRINTS ITS PRAYER RESOURCES — the list, the card deck and the packet — through the diff --git a/plugin-designs/country-posters/data/india-state-names.meta.json b/plugin-designs/country-posters/data/india-state-names.meta.json new file mode 100644 index 000000000..bd8998d08 --- /dev/null +++ b/plugin-designs/country-posters/data/india-state-names.meta.json @@ -0,0 +1,44 @@ +{ + "what": "India's 36 states and union territories, named in the 11 UI locales, for the Country Posters wall's card labels.", + "source": "Wikidata (https://www.wikidata.org): labels of the items whose ISO 3166-2 code (P300) matches data/people-groups/india-states.json; dissolved items (P576) excluded.", + "licence": "CC0 1.0: Wikidata structured data is released under CC0 (https://creativecommons.org/publicdomain/zero/1.0/).", + "english": "the state table's own name (the English wall is unchanged); Wikidata's English is only a cross-check", + "retrieved": "2026-09-30", + "regenerate": "node plugin-designs/country-posters/scripts/emit-india-state-names.mjs", + "query": "SELECT ?code ?lang ?label WHERE {\n VALUES ?code { \"IN-AN\" \"IN-AP\" \"IN-AR\" \"IN-AS\" \"IN-BR\" \"IN-CG\" \"IN-CH\" \"IN-DH\" \"IN-DL\" \"IN-GA\" \"IN-GJ\" \"IN-HP\" \"IN-HR\" \"IN-JH\" \"IN-JK\" \"IN-KA\" \"IN-KL\" \"IN-LA\" \"IN-LD\" \"IN-MH\" \"IN-ML\" \"IN-MN\" \"IN-MP\" \"IN-MZ\" \"IN-NL\" \"IN-OD\" \"IN-PB\" \"IN-PY\" \"IN-RJ\" \"IN-SK\" \"IN-TN\" \"IN-TR\" \"IN-TS\" \"IN-UK\" \"IN-UP\" \"IN-WB\" }\n ?item wdt:P300 ?code .\n FILTER NOT EXISTS { ?item wdt:P576 ?dissolved }\n ?item rdfs:label ?label . BIND(LANG(?label) AS ?lang)\n FILTER(?lang IN (\"en\", \"es\", \"fr\", \"pt\", \"de\", \"it\", \"ro\", \"ru\", \"ar\", \"hi\", \"zh-hans\", \"zh-cn\", \"zh\"))\n}", + "codeAliases": { + "IN-CT": "IN-CG", + "IN-OR": "IN-OD", + "IN-TG": "IN-TS", + "IN-UT": "IN-UK" + }, + "reviewedOverrides": [ + "IN-DH zh: \"达德拉-纳加尔哈维利和达曼-第乌\" (Wikidata has only a Traditional-script zh label; converted character by character to the Simplified catalogue script)", + "IN-OR ar: \"أديشة\" (the label is the pre-2011 name Orissa (أريسة); ar.wikipedia's title for the item is أديشة (Odisha))" + ], + "gaps": [], + "ambiguous": [], + "fallbacks": [ + "IN-CH es: \"Chandigarh\" from the same-named item (1 of 1)", + "IN-CH fr: \"Chandigarh\" from the same-named item (1 of 1)", + "IN-CH pt: \"Chandigarh\" from the same-named item (1 of 1)", + "IN-CH de: \"Chandigarh\" from the same-named item (1 of 1)", + "IN-CH it: \"Chandigarh\" from the same-named item (1 of 1)", + "IN-CH ar: \"شَنديغار\" from the same-named item (1 of 1)", + "IN-CH hi: \"चण्डीगढ़\" from the same-named item (1 of 1)", + "IN-CH zh: \"昌迪加尔\" from the same-named item (1 of 1)", + "IN-DL es: \"Delhi\" from the same-named item (preferred)", + "IN-DL fr: \"Delhi\" from the same-named item (preferred)", + "IN-DL pt: \"Delhi\" from the same-named item (preferred)", + "IN-DL de: \"Delhi\" from the same-named item (preferred)", + "IN-DL it: \"Delhi\" from the same-named item (preferred)", + "IN-DL ro: \"Delhi\" from the same-named item (preferred)", + "IN-DL ru: \"Дели\" from the same-named item (preferred)", + "IN-DL ar: \"دلهي\" from the same-named item (preferred)", + "IN-DL hi: \"दिल्ली\" from the same-named item (preferred)", + "IN-DL zh: \"德里\" from the same-named item (preferred)" + ], + "englishMismatches": [ + "IN-DL: table \"Delhi\" vs Wikidata \"National Capital Territory of Delhi\"; same-named labels preferred" + ] +} diff --git a/plugin-designs/country-posters/scripts/check-country-sheet-one-path.mjs b/plugin-designs/country-posters/scripts/check-country-sheet-one-path.mjs index 7201dd09b..bcda80cca 100644 --- a/plugin-designs/country-posters/scripts/check-country-sheet-one-path.mjs +++ b/plugin-designs/country-posters/scripts/check-country-sheet-one-path.mjs @@ -141,9 +141,27 @@ export function armC(H, states, adm1Ind) { return fails } -// ARM E: India is its OWN section, FIRST, counted ONCE. The India country card, the state cards and the none-listed -// cards group together; the section's total is India's own count (not the card sum, which counts 855 twice); on that -// true total it outranks every regional section. PosterWall's default (no sectionTotal) must still be the card sum. +// ARM D: the state cards' localized names cover EXACTLY the table's divisions in every locale (a runtime-built key, +// `countryPosters.stateNames.${iso}`, that the i18n call-site gates cannot see), English is the table's own name, and +// the generated names carry their source licence. +const NAME_LOCALES = ['en', 'es', 'fr', 'pt', 'de', 'it', 'ro', 'ru', 'ar', 'hi', 'zh'] +export function armD(states, areas, meta) { + const fails = [] + const want = new Set((states || []).map((st) => st.iso)) + for (const l of NAME_LOCALES) { + const names = (areas[l] && areas[l].stateNames) || {} + const have = new Set(Object.keys(names)) + const missing = [...want].filter((x) => !have.has(x)), extra = [...have].filter((x) => !want.has(x)) + const empty = Object.entries(names).filter(([, v]) => typeof v !== 'string' || !v.trim()).map(([k]) => k) + if (missing.length || extra.length || empty.length) fails.push(`${l} countryPosters.stateNames: missing [${missing}] extra [${extra}] empty [${empty}]`) + } + const en = (areas.en && areas.en.stateNames) || {} + const drift = (states || []).filter((st) => en[st.iso] !== st.name).map((st) => st.iso) + if (drift.length) fails.push(`English state names differ from the table's: ${drift.join(', ')} (re-run emit-india-state-names.mjs)`) + if (!meta || !/CC0/.test(String(meta.licence || ''))) fails.push('india-state-names.meta.json must record the source licence (CC0)') + return fails +} + // ARM F — A DESKTOP-ONLY CARD ON A PHONE (India): in EACH caller (the wall, the Regions list) its rows REJECT with // poster.phoneLimitAll before any record is fetched, never resolve [] (the print path reads [] as "that list has no // people groups to print", on a card that has 855), and the card shows the same full-block notice. @@ -158,6 +176,9 @@ export function armF(srcs) { return fails } +// ARM E: India is its OWN section, FIRST, counted ONCE. The India country card, the state cards and the none-listed +// cards group together; the section's total is India's own count (not the card sum, which counts 855 twice); on that +// true total it outranks every regional section. PosterWall's default (no sectionTotal) must still be the card sum. export function armE(countries, states, wallSrc, posterWallSrc, H) { const fails = [] if (!/:section-total=/.test(wallSrc)) fails.push('country-poster-wall.vue does not pass :section-total, so India is counted twice') @@ -189,6 +210,9 @@ async function main() { const adm1Ind = JSON.parse(readFileSync(join(ROOT, 'public/dx-maps/assets/boundaries/gb-IND-ADM1.geojson'), 'utf8')) if (states.length < 30 || (adm1Ind.features || []).length < 30) { console.log(`NOT MEASURED: state table ${states.length} / ADM1 ${(adm1Ind.features || []).length} features (floor 30)`); process.exitCode = 75; return } + const areas = Object.fromEntries(NAME_LOCALES.map((l) => [l, JSON.parse(readFileSync(join(ROOT, `library/i18n/locales/${l}/countryPosters.json`), 'utf8'))])) + const meta = JSON.parse(readFileSync(join(ROOT, 'plugin-designs/country-posters/data/india-state-names.meta.json'), 'utf8')) + const files = {} for (const p of listSources(PD)) files[relative(ROOT, p)] = readFileSync(p, 'utf8') @@ -210,6 +234,8 @@ async function main() { ['a packet page becomes a large sheet', () => armB(seriesFor, countries, (it, f) => (it?.iso3 === 'IND' ? '60x96' : f))], ['the wall resolves [] for a phone-blocked card', () => armF({ wall: files[wall].replace("const desktopOnly = () => Promise.reject(keyedError('poster.phoneLimitAll'", "const desktopOnly = () => Promise.resolve([]) || (keyedError('poster.phoneLimitAll'"), regions: REG })], ['the Regions list resolves [] for a phone-blocked card', () => armF({ wall: files[wall], regions: REG.replace("phoneBlocked(item) ? Promise.reject(keyedError('poster.phoneLimitAll'", "phoneBlocked(item) ? Promise.resolve([]) || (keyedError('poster.phoneLimitAll'") })], + ['a locale loses a state name', () => armD(states, { ...areas, ro: { ...areas.ro, stateNames: Object.fromEntries(Object.entries(areas.ro.stateNames).filter(([k]) => k !== 'IN-GJ')) } }, meta)], + ['the names lose their licence line', () => armD(states, areas, { ...meta, licence: '' })], ['a helper that mutates the shared ADM1', () => armC({ ...H, stateGeometry: (z, a, n) => { (a.features || []).forEach((f) => { if (f.properties.shapeName === n) f.properties.listId = z.id }); return H.stateGeometry(z, a, n) } }, states, JSON.parse(JSON.stringify(adm1Ind)))], ] let bad = 0 @@ -228,12 +254,12 @@ async function main() { const callers = [] const E = armE(countries, states, files['plugin-designs/country-posters/country-poster-wall.vue'], readFileSync(join(ROOT, 'library/components/poster/PosterWall.vue'), 'utf8'), H) - const fails = [...armA(files, callers), ...armB(seriesFor, countries, sheetFormatFor), ...armC(H, states, adm1Ind), ...E.fails, ...armF({ wall: files['plugin-designs/country-posters/country-poster-wall.vue'], regions: REG })] + const fails = [...armA(files, callers), ...armB(seriesFor, countries, sheetFormatFor), ...armC(H, states, adm1Ind), ...E.fails, ...armD(states, areas, meta), ...armF({ wall: files['plugin-designs/country-posters/country-poster-wall.vue'], regions: REG })] const missing = [...KNOWN_CALLERS, `${STATE_CALLER}#state`].filter((k) => !callers.includes(k)) if (missing.length) fails.push(`known callers not found calling makeCountrySheet: ${missing.join(', ')}`) if (fails.length) { fails.forEach((f) => console.log(`FAIL ${f}`)); process.exitCode = 1; return } const ind = seriesFor(countries, countries.find((c) => c.iso3 === 'IND')) - console.log(`PASS check:country-sheet-one-path — ${Object.keys(files).length} plugin sources parsed-or-skipped, makeCountrySheet callers: ${callers.join(', ')}; seriesFor over ${countries.length} countries (India ${ind.index} of ${ind.totalLists}); ${H.statesWithPosters(states).length} state posters, series 1..${H.statesWithPosters(states).length}, every outline found; sections ${E.order.slice(0, 3).map(([g, t]) => `${g} ${t}`).join(' > ')}`) + console.log(`PASS check:country-sheet-one-path — ${Object.keys(files).length} plugin sources parsed-or-skipped, makeCountrySheet callers: ${callers.join(', ')}; seriesFor over ${countries.length} countries (India ${ind.index} of ${ind.totalLists}); ${H.statesWithPosters(states).length} state posters, series 1..${H.statesWithPosters(states).length}, every outline found; sections ${E.order.slice(0, 3).map(([g, t]) => `${g} ${t}`).join(' > ')}; state names in ${NAME_LOCALES.length} locales x ${states.length}`) } main().catch((e) => { console.error(`FAIL ${e.stack || e}`); process.exitCode = 1 }) diff --git a/plugin-designs/country-posters/scripts/emit-india-state-names.mjs b/plugin-designs/country-posters/scripts/emit-india-state-names.mjs new file mode 100644 index 000000000..ab99a64c2 --- /dev/null +++ b/plugin-designs/country-posters/scripts/emit-india-state-names.mjs @@ -0,0 +1,134 @@ +#!/usr/bin/env node +// emit-india-state-names.mjs — India's 36 states and union territories named in the 11 UI locales, for the Country +// Posters wall's India section: the CARD labels, the print HUD and the packet/list titles. The printed sheet stays +// English by recorded decision (series.json english_only_note), like every country poster. +// +// SOURCE: Wikidata labels, matched on ISO 3166-2 (P300) against data/people-groups/india-states.json. Wikidata's +// structured data is CC0. The labels are human-edited, not machine translation. Dissolved items (P576) are excluded, +// so a retired code such as the pre-2020 Dadra and Nagar Haveli cannot win. +// English is the TABLE's own name, so the English wall does not change; Wikidata's English is only a cross-check. +// A locale Wikidata has no label for falls back to the English name AND is recorded in the meta file, never silently. +// +// Writes: library/i18n/locales//countryPosters.json -> "stateNames": { "IN-GJ": "…", … } (other keys kept) +// plugin-designs/country-posters/data/india-state-names.meta.json (source, licence, query, date, gaps) +// Regenerate: node plugin-designs/country-posters/scripts/emit-india-state-names.mjs +import { readFileSync, writeFileSync } from 'node:fs' +import { join, dirname } from 'node:path' +import { fileURLToPath } from 'node:url' + +const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..') +const LOCALES = ['en', 'es', 'fr', 'pt', 'de', 'it', 'ro', 'ru', 'ar', 'hi', 'zh'] +const WD_LANG = { zh: ['zh-hans', 'zh-cn', 'zh'] } // the zh catalogue is Simplified +const wdLangs = (l) => WD_LANG[l] || [l] + +// The state table keeps geoBoundaries' ISO codes; ISO 3166-2:IN has since renamed four, and Wikidata's P300 holds +// the CURRENT code. Queried under the current code, keyed back to the table's. +const CODE_ALIAS = { 'IN-CT': 'IN-CG', 'IN-OR': 'IN-OD', 'IN-TG': 'IN-TS', 'IN-UT': 'IN-UK' } +const wdCode = (iso) => CODE_ALIAS[iso] || iso + +// REVIEWED OVERRIDES (hi, ar, zh read by eye, 2026-09-30), each with its evidence. Kept small and explicit: neither +// Wikidata's labels nor its Wikipedia titles are uniformly current (zh's Odisha TITLE is the old Orissa while its +// label is current; ar's Odisha LABEL is the old Orissa while its title is current), so no blanket rule is safe. +const OVERRIDES = { + 'IN-OR': { ar: ['أديشة', "the label is the pre-2011 name Orissa (أريسة); ar.wikipedia's title for the item is أديشة (Odisha)"] }, + 'IN-DH': { zh: ['达德拉-纳加尔哈维利和达曼-第乌', 'Wikidata has only a Traditional-script zh label; converted character by character to the Simplified catalogue script'] }, +} + +const states = JSON.parse(readFileSync(join(ROOT, 'data/people-groups/india-states.json'), 'utf8')).states +const isos = states.map((s) => wdCode(s.iso)).sort() +const langs = [...new Set(LOCALES.flatMap(wdLangs))] +const query = `SELECT ?code ?lang ?label WHERE { + VALUES ?code { ${isos.map((c) => `"${c}"`).join(' ')} } + ?item wdt:P300 ?code . + FILTER NOT EXISTS { ?item wdt:P576 ?dissolved } + ?item rdfs:label ?label . BIND(LANG(?label) AS ?lang) + FILTER(?lang IN (${langs.map((l) => `"${l}"`).join(', ')})) +}` +const res = await fetch('https://query.wikidata.org/sparql?format=json&query=' + encodeURIComponent(query), { + headers: { accept: 'application/sparql-results+json', 'user-agent': 'dx-maps country-posters emit-india-state-names' }, + signal: AbortSignal.timeout(60000), +}) +if (!res.ok) { console.error(`Wikidata ${res.status}`); process.exit(1) } +const rows = (await res.json()).results.bindings +const got = {} // iso -> Wikidata language -> Set(labels) +for (const r of rows) ((got[r.code.value] ||= {})[r.lang.value] ||= new Set()).add(r.label.value) + +// FALLBACK for a language the matched item has no label in (e.g. the "National Capital Territory of Delhi" item): +// the labels of items in India (P17 = Q668) whose English label IS the table's name (the city of Delhi, +// Chandigarh). Used only for the missing languages, and recorded. +async function sameNameLabels(name) { + const q = `SELECT ?lang ?label WHERE { ?item rdfs:label ${JSON.stringify(name)}@en ; wdt:P17 wd:Q668 . + ?item rdfs:label ?label . BIND(LANG(?label) AS ?lang) FILTER(?lang IN (${langs.map((l) => `"${l}"`).join(', ')})) }` + const r = await fetch('https://query.wikidata.org/sparql?format=json&query=' + encodeURIComponent(q), { + headers: { accept: 'application/sparql-results+json', 'user-agent': 'dx-maps country-posters emit-india-state-names' }, + signal: AbortSignal.timeout(60000), + }) + if (!r.ok) throw new Error(`Wikidata ${r.status}`) + const by = {} + for (const b of (await r.json()).results.bindings) { + const m = (by[b.lang.value] ||= new Map()); m.set(b.label.value, (m.get(b.label.value) || 0) + 1) + } + return by // lang -> Map(label -> how many same-named items carry it) +} +const fallbacks = [], overridden = [], unreviewedZh = [] + +const gaps = [], ambiguous = [], englishMismatches = [] +const names = Object.fromEntries(LOCALES.map((l) => [l, {}])) +for (const st of [...states].sort((a, b) => a.iso.localeCompare(b.iso))) { + const wd = got[wdCode(st.iso)] || {} + if (!Object.keys(wd).length) gaps.push(`${st.iso}: no Wikidata item (queried as ${wdCode(st.iso)})`) + let same = null + const wdEn = wd.en && [...wd.en][0] + // The table names the division more briefly than its item ("Delhi" vs "National Capital Territory of Delhi"): then + // the SAME-NAMED item's labels (the city of Delhi) are preferred in every language, so hi and ru match the English. + const preferSame = Boolean(wdEn && wdEn !== st.name) + if (preferSame) englishMismatches.push(`${st.iso}: table "${st.name}" vs Wikidata "${wdEn}"; same-named labels preferred`) + for (const l of LOCALES) { + if (l === 'en') { names.en[st.iso] = st.name; continue } + const ov = OVERRIDES[st.iso] && OVERRIDES[st.iso][l] + if (ov) { names[l][st.iso] = ov[0]; overridden.push(`${st.iso} ${l}: "${ov[0]}" (${ov[1]})`); continue } + if (preferSame) { + same ||= await sameNameLabels(st.name) + const m = wdLangs(l).map((w) => same[w]).find((x) => x && x.size) + if (m) { const [label] = [...m].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0]; names[l][st.iso] = label; fallbacks.push(`${st.iso} ${l}: "${label}" from the same-named item (preferred)`); continue } + } + const src = wdLangs(l).find((w) => wd[w] && wd[w].size) + if (l === 'zh' && src === 'zh') unreviewedZh.push(`${st.iso}: only a plain "zh" label (script unknown: may be Traditional); add a reviewed OVERRIDE`) + const hit = src && wd[src] + if (!hit) { + same ||= await sameNameLabels(st.name) + const m = wdLangs(l).map((w) => same[w]).find((x) => x && x.size) + if (m) { + const [label, n] = [...m].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0] + names[l][st.iso] = label; fallbacks.push(`${st.iso} ${l}: "${label}" from the same-named item (${n} of ${[...m.values()].reduce((a, x) => a + x, 0)})`) + continue + } + names[l][st.iso] = st.name; gaps.push(`${st.iso} ${l}: no label, English used`); continue + } + if (hit.size > 1) ambiguous.push(`${st.iso} ${l}: ${[...hit].join(' | ')}`) + names[l][st.iso] = [...hit].sort()[0] + } +} +for (const l of LOCALES) { + const p = join(ROOT, `library/i18n/locales/${l}/countryPosters.json`) + const area = JSON.parse(readFileSync(p, 'utf8')) + area.stateNames = names[l] + writeFileSync(p, JSON.stringify(area, null, 2) + '\n') +} +const meta = { + what: "India's 36 states and union territories, named in the 11 UI locales, for the Country Posters wall's card labels.", + source: 'Wikidata (https://www.wikidata.org): labels of the items whose ISO 3166-2 code (P300) matches data/people-groups/india-states.json; dissolved items (P576) excluded.', + licence: 'CC0 1.0: Wikidata structured data is released under CC0 (https://creativecommons.org/publicdomain/zero/1.0/).', + english: "the state table's own name (the English wall is unchanged); Wikidata's English is only a cross-check", + retrieved: new Date().toISOString().slice(0, 10), + regenerate: 'node plugin-designs/country-posters/scripts/emit-india-state-names.mjs', + query, + codeAliases: CODE_ALIAS, + reviewedOverrides: overridden, + gaps, ambiguous, fallbacks, englishMismatches, +} +writeFileSync(join(ROOT, 'plugin-designs/country-posters/data/india-state-names.meta.json'), JSON.stringify(meta, null, 2) + '\n') +console.log(`states ${states.length}, Wikidata rows ${rows.length}; gaps ${gaps.length}, ambiguous ${ambiguous.length}, fallbacks ${fallbacks.length}, English mismatches ${englishMismatches.length}`) +for (const x of [...gaps, ...ambiguous, ...fallbacks, ...overridden, ...englishMismatches]) console.log(' ' + x) +// A zh name from a plain "zh" label may be Traditional script in a Simplified catalogue: refuse rather than ship it. +if (unreviewedZh.length) { unreviewedZh.forEach((x) => console.error('FAIL ' + x)); process.exitCode = 1 }